elyxer-1.2.5/0000755000175000017500000000000012117175142012336 5ustar chennochennoelyxer-1.2.5/LICENSE0000644000175000017500000010451312074107030013340 0ustar chennochenno GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. 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 How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software: 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 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 GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: Copyright (C) This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an "about box". You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see . The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read . elyxer-1.2.5/setup.py0000644000175000017500000000377712117175142014066 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20090908 # eLyXer distutils management from distutils.core import setup packages = [ 'elyxer', 'elyxer.bib', 'elyxer.conf', 'elyxer.gen', 'elyxer.io', 'elyxer.main', 'elyxer.maths', 'elyxer.out', 'elyxer.parse', 'elyxer.proc', 'elyxer.ref', 'elyxer.util', 'elyxer.xtra' ] packages = [] setup(name = 'eLyXer', version = '1.2.5', description = 'LyX to HTML converter', long_description = 'eLyXer is a LyX to HTML converter, with a focus on flexibility and elegant output.', author = 'Alex Fernandez', author_email = 'elyxer@gmail.com', url = 'http://elyxer.nongnu.org/', packages = packages, scripts = ['elyxer.py', 'math2html.py', 'loremipsumize.py'], classifiers = [ 'License :: OSI Approved :: GNU General Public License (GPL)', 'Development Status :: 5 - Production/Stable', 'Environment :: Console', 'Operating System :: OS Independent', 'Programming Language :: Python :: 2.4', 'Topic :: Printing', 'Topic :: Text Processing :: Markup :: HTML', 'Topic :: Utilities', 'Topic :: Internet :: WWW/HTTP :: Dynamic Content' ], license = 'GPL version 3 or later', platforms = ['Windows NT/2000/XP', 'Mac OS X', 'GNU/Linux'], ) elyxer-1.2.5/po/0000755000175000017500000000000012074107064012754 5ustar chennochennoelyxer-1.2.5/po/en.po0000644000175000017500000000477212074107030013721 0ustar chennochenno# English translations for PACKAGE package. # eLyXer version 1.0.4 # Released on 2010-10-16 # Contact: Alex Fernández # This file is distributed under the same license as the eLyXer package. # (C) 2010 chenno . # msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "PO-Revision-Date: 2010-10-16 19:04+0200\n" "Last-Translator: chenno \n" "Language-Team: English\n" "Language: en\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=ASCII\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: Subsubsection msgid "Subsubsection" msgstr "Subsubsection" #: figure msgid "figure" msgstr "figure" #: abstract msgid "Abstract" msgstr "Abstract" #: jsmath-warning msgid "Warning: " msgstr "Warning: " #: up msgid "Up" msgstr "Up" #: Book msgid "Book" msgstr "Book" #: jsmath-enable msgid "Please enable JavaScript on your browser." msgstr "Please enable JavaScript on your browser." #: Subsection msgid "Subsection" msgstr "Subsection" #: list-algorithm msgid "List of Algorithms" msgstr "List of Algorithms" #: Appendix msgid "Appendix" msgstr "Appendix" #: index msgid "Index" msgstr "Index" #: bibliography msgid "Bibliography" msgstr "Bibliography" #: float-algorithm msgid "Algorithm " msgstr "Algorithm " #: next msgid "Next" msgstr "Next" #: list-table msgid "List of Tables" msgstr "List of Tables" #: Part msgid "Part" msgstr "Part" #: generated-by msgid "Document generated by " msgstr "Document generated by " #: toc msgid "Table of Contents" msgstr "Table of Contents" #: prev msgid "Prev" msgstr "Prev" #: Section msgid "Section" msgstr "Section" #: Chapter msgid "Chapter" msgstr "Chapter" #: list-tableau msgid "List of Tableaux" msgstr "List of Tableaux" #: generated-on msgid " on " msgstr " on " #: float-tableau msgid "Tableau " msgstr "Tableau " #: Paragraph msgid "Paragraph" msgstr "Paragraph" #: list-figure msgid "List of Figures" msgstr "List of Figures" #: main-page msgid "Main page" msgstr "Main page" #: float-listing msgid "Listing " msgstr "Listing " #: on-page msgid " on page " msgstr " on page " #: nomenclature msgid "Nomenclature" msgstr "Nomenclature" #: float-table msgid "Table " msgstr "Table " #: float-figure msgid "Figure " msgstr "Figure " #: toc-for msgid "Contents for " msgstr "Contents for " #: jsmath-requires msgid " requires JavaScript to correctly process the mathematics on this page. " msgstr " requires JavaScript to correctly process the mathematics on this page. " elyxer-1.2.5/po/nl.po0000644000175000017500000000510712074107030013721 0ustar chennochenno# Dutch translations for PACKAGE package. # eLyXer version 0.42 # Released on 2010-02-15 # Contact: Alex Fernández # This file is distributed under the same license as the eLyXer package. # (C) 2010 Hans Bezemer, Alex Fernández. # msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "PO-Revision-Date: 2010-03-12 21:17+0100\n" "Last-Translator: Hans Bezemer\n" "Language-Team: Dutch\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=ASCII\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: Subsubsection msgid "Subsubsection" msgstr "Subsubsectie" #: figure msgid "figure" msgstr "figuur" #: abstract msgid "Abstract" msgstr "Samenvatting" #: jsmath-warning msgid "Warning: " msgstr "Waarschuwing: " #: up msgid "Up" msgstr "Terug" #: Book msgid "Book" msgstr "Boek" #: jsmath-enable msgid "Please enable JavaScript on your browser." msgstr "Activeer Javascript in uw browser." #: Subsection msgid "Subsection" msgstr "Subsectie" #: list-algorithm msgid "List of Algorithms" msgstr "Lijst van algoritmen" #: index msgid "Index" msgstr "Index" #: bibliography msgid "Bibliography" msgstr "Bibliografie" #: references msgid "References" msgstr "Referenties" #: float-algorithm msgid "Algorithm " msgstr "Algoritme " #: next msgid "Next" msgstr "Volgende" #: list-table msgid "List of Tables" msgstr "Lijst van tabellen" #: Part msgid "Part" msgstr "Deel" #: toc msgid "Table of Contents" msgstr "Inhoudsopgave" #: prev msgid "Prev" msgstr "Vorige" #: Section msgid "Section" msgstr "Sectie" #: Chapter msgid "Chapter" msgstr "Hoofdstuk" #: list-tableau msgid "List of Tableaux" msgstr "Lijst van Tableaux" #: float-tableau msgid "Tableau " msgstr "Tableau " #: Paragraph msgid "Paragraph" msgstr "Paragraaf" #: list-figure msgid "List of Figures" msgstr "Lijst van figuren" #: float-listing msgid "Listing " msgstr "Listing " #: on-page msgid " on page " msgstr " op pagina " #: nomenclature msgid "Nomenclature" msgstr "Verklaring van symbolen" #: float-table msgid "Table " msgstr "Tabel " #: float-figure msgid "Figure " msgstr "Figuur " #: jsmath-requires msgid " requires JavaScript to correctly process the mathematics on this page. " msgstr " om de formules op deze bladzijde correct weer te geven is Javascript benodigd. " #: generated-by msgid "Document generated by " msgstr "Document gegenereerd door " #: generated-on msgid " on " msgstr " op " #: toc-for msgid "Contents for " msgstr "Inhoud van " #: main-page msgid "Main page" msgstr "Hoofdpagina" #: Appendix msgid "Appendix" msgstr "Appendix" elyxer-1.2.5/po/createlocale.sh0000755000175000017500000000171412074107030015732 0ustar chennochenno#!/bin/bash # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # Alex 20100218: create locale file # create executable if test -z "$1" then echo "Usage: ./createlocale.sh my, creates my.po for locale my." exit fi msginit --locale=$1 --input=../src/conf/elyxer.pot elyxer-1.2.5/po/es.po0000644000175000017500000000522712074107030013722 0ustar chennochenno# Spanish translations for eLyXer package # Traducciones al español para el paquete eLyXer. # eLyXer version 0.40 # Released on 2010-01-12 # Contact: Alex Fernández # This file is distributed under the same license as the eLyXer package. # (C) 2010 chenno . # msgid "" msgstr "" "Project-Id-Version: eLyXer 0.40\n" "PO-Revision-Date: 2010-01-12 23:50+0100\n" "Last-Translator: chenno \n" "Language-Team: Spanish\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: Subsubsection msgid "Subsubsection" msgstr "Subsubsección" #: figure msgid "figure" msgstr "figura" #: abstract msgid "Abstract" msgstr "Resumen" #: jsmath-warning msgid "Warning: " msgstr "Aviso: " #: up msgid "Up" msgstr "Arriba" #: Book msgid "Book" msgstr "Libro" #: jsmath-enable msgid "Please enable JavaScript on your browser." msgstr "Por favor, habilite JavaScript en su navegador." #: Subsection msgid "Subsection" msgstr "Subsección" #: list-algorithm msgid "List of Algorithms" msgstr "Índice de algoritmos" #: index msgid "Index" msgstr "Índice alfabético" #: bibliography msgid "Bibliography" msgstr "Bibliografía" #: references msgid "References" msgstr "Referencias" #: float-algorithm msgid "Algorithm " msgstr "Algoritmo " #: next msgid "Next" msgstr "Siguiente" #: list-table msgid "List of Tables" msgstr "Índice de tablas" #: Part msgid "Part" msgstr "Parte" #: toc msgid "Table of Contents" msgstr "Índice general" #: prev msgid "Prev" msgstr "Anterior" #: Section msgid "Section" msgstr "Sección" #: Chapter msgid "Chapter" msgstr "Capítulo" #: list-tableau msgid "List of Tableaux" msgstr "Lista de tablas" #: float-tableau msgid "Tableau " msgstr "Tabla " #: Paragraph msgid "Paragraph" msgstr "Párrafo" #: list-figure msgid "List of Figures" msgstr "Índice de figuras" #: float-listing msgid "Listing " msgstr "Listado " #: on-page msgid " on page " msgstr " en la página " #: nomenclature msgid "Nomenclature" msgstr "Nomenclatura" #: float-table msgid "Table " msgstr "Tabla " #: float-figure msgid "Figure " msgstr "Figura " #: jsmath-requires msgid " requires JavaScript to correctly process the mathematics on this page. " msgstr " requiere JavaScript para procesar las fórmulas matemáticas de la página. " #: generated-by msgid "Document generated by " msgstr "Documento generado con " #: generated-on msgid " on " msgstr " en " #: toc-for msgid "Contents for " msgstr "Contenido de " #: main-page msgid "Main page" msgstr "Página principal" #: Appendix msgid "Appendix" msgstr "Apéndice" elyxer-1.2.5/po/fr.po0000644000175000017500000000515412074107030013721 0ustar chennochenno# French translations for PACKAGE package. # eLyXer version 0.42 # Released on 2010-02-15 # Contact: Alex Fernández # This file is distributed under the same license as the eLyXer package. # (C) 2010 Sara Teinturier, Alex Fernández. # msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "PO-Revision-Date: 2010-02-18 00:13+0100\n" "Last-Translator: Sara Teinturier\n" "Language-Team: French\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" #: Subsubsection msgid "Subsubsection" msgstr "SousSousSection" #: figure msgid "figure" msgstr "Figure" #: abstract msgid "Abstract" msgstr "Résumé" #: jsmath-warning msgid "Warning: " msgstr "Erreur: Javascript est nécessaire pour afficher correctement les fonctionnalités de " #: up msgid "Up" msgstr "Monter d'un niveau" #: Book msgid "Book" msgstr "Livre" #: jsmath-enable msgid "Please enable JavaScript on your browser." msgstr "Merci d'activer JavaScript dans votre navigateur." #: Subsection msgid "Subsection" msgstr "SousSection" #: list-algorithm msgid "List of Algorithms" msgstr "Liste des algorithmes" #: index msgid "Index" msgstr "Index" #: bibliography msgid "Bibliography" msgstr "Bibliographie" #: references msgid "References" msgstr "Références" #: float-algorithm msgid "Algorithm " msgstr "Algorithme " #: next msgid "Next" msgstr "Suivant" #: list-table msgid "List of Tables" msgstr "List des tables" #: Part msgid "Part" msgstr "Partie" #: toc msgid "Table of Contents" msgstr "Table des matières" #: prev msgid "Prev" msgstr "Précédent" #: Section msgid "Section" msgstr "Section" #: Chapter msgid "Chapter" msgstr "Chapitre" #: list-tableau msgid "List of Tableaux" msgstr "Liste des tableaux" #: float-tableau msgid "Tableau " msgstr "Tableau " #: Paragraph msgid "Paragraph" msgstr "Paragraphe" #: list-figure msgid "List of Figures" msgstr "Table des figures" #: float-listing msgid "Listing " msgstr "Listing " #: on-page msgid " on page " msgstr " page " #: nomenclature msgid "Nomenclature" msgstr "Glossaire" #: float-table msgid "Table " msgstr "Table " #: float-figure msgid "Figure " msgstr "Figure " #: jsmath-requires msgid " requires JavaScript to correctly process the mathematics on this page. " msgstr ". " #: generated-by msgid "Document generated by " msgstr "Document generated by " #: generated-on msgid " on " msgstr " le " #: toc-for msgid "Contents for " msgstr "Tables des matières du " #: main-page msgid "Main page" msgstr "Page principale" #: Appendix msgid "Appendix" msgstr "Annexe" elyxer-1.2.5/po/de.po0000644000175000017500000000536512074107030013706 0ustar chennochenno# German translations for eLyXer package # Deutsch. # eLyXer version 0.40 # Released on 2010-01-12 # Contact: Alex Fernández # This file is distributed under the same license as the eLyXer package. # (C) 2010 Uwe Stöhr . # msgid "" msgstr "" "Project-Id-Version: eLyXer 0.40\n" "PO-Revision-Date: 2010-01-12 02:37+0100\n" "Last-Translator: Uwe Stöhr \n" "Language-Team: Deutsch de>\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "POT-Creation-Date: \n" "X-Poedit-Language: German\n" "X-Poedit-Country: GERMANY\n" #: Subsubsection msgid "Subsubsection" msgstr "Unterunterabschnitt" #: figure msgid "figure" msgstr "Abbildung" #: abstract msgid "Abstract" msgstr "Abstract" #: jsmath-warning msgid "Warning: " msgstr "Warnung: " #: up msgid "Up" msgstr "Oben" #: Book msgid "Book" msgstr "Buck" #: jsmath-enable msgid "Please enable JavaScript on your browser." msgstr "Bitte aktivieren Sie JavaScript in Ihrem Browser." #: Subsection msgid "Subsection" msgstr "Unterabschnitt" #: list-algorithm msgid "List of Algorithms" msgstr "Verzeichnis der Algorithmen" #: index msgid "Index" msgstr "Stichwortverzeichnis" #: bibliography msgid "Bibliography" msgstr "Bibliografie" #: references msgid "References" msgstr "Literatur" #: float-algorithm msgid "Algorithm" msgstr "Algorithmus" #: next msgid "Next" msgstr "Weiter" #: list-table msgid "List of Tables" msgstr "Tabellenverzeichnis" #: Part msgid "Part" msgstr "Teil" #: toc msgid "Table of Contents" msgstr "Inhaltsverzeichnis" #: prev msgid "Prev" msgstr "Zurück" #: Section msgid "Section" msgstr "Abschnitt" #: Chapter msgid "Chapter" msgstr "Kapitel" #: list-tableau msgid "List of Tableaux" msgstr "Tabellenverzeichnis" #: float-tableau msgid "Tableau " msgstr "Tabelle" #: Paragraph msgid "Paragraph" msgstr "Paragraph" #: list-figure msgid "List of Figures" msgstr "Abbildungsverzeichnis" #: float-listing msgid "Listing " msgstr "Listing " #: nomenclature msgid "Nomenclature" msgstr "Nomenklatur" #: on-page msgid " on page " msgstr " auf Seite " #: float-table msgid "Table " msgstr "Tabelle" #: float-figure msgid "Figure " msgstr "Abbildung " #: jsmath-requires msgid " requires JavaScript to correctly process the mathematics on this page. " msgstr " Benötigt JavaScript um die Formeln auf dieser Seite darstellen zu können. " #: generated-by msgid "Document generated by " msgstr "Dokument wurde erzeugt von " #: generated-on msgid " on " msgstr " am " #: toc-for msgid "Contents for " msgstr "Inhalt für " #: main-page msgid "Main page" msgstr "Hauptseite" #: Appendix msgid "Appendix" msgstr "Anhang" elyxer-1.2.5/po/ru.po0000644000175000017500000000564512074107030013745 0ustar chennochennomsgid "" msgstr "" "Project-Id-Version: elyxer 1.2.3\n" "PO-Revision-Date: 2011-11-11 16:24+0300\n" "Last-Translator: Vladimir Ermakov \n" "Language-Team: Russian\n" "Language: ru\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" "POT-Creation-Date: \n" # eLyXer internationalization file. # Created on 2011-08-31 # Contact: Alex Fernandez # http://elyxer.nongnu.org/ # This file is distributed under the same license as the eLyXer package. # (C) 2010 Alex Fernandez . # #: Subsubsection msgid "Subsubsection" msgstr "Подподраздел" #: figure msgid "figure" msgstr "рисунок" #: abstract msgid "Abstract" msgstr "Аннотация" #: jsmath-warning msgid "Warning: " msgstr "" #: up msgid "Up" msgstr "Вверх" #: Book msgid "Book" msgstr "" #: references msgid "References" msgstr "Список литературы" #: Subsection msgid "Subsection" msgstr "Подраздел" #: list-algorithm msgid "List of Algorithms" msgstr "Список алгоритмов" #: Appendix msgid "Appendix" msgstr "Приложение" #: index msgid "Index" msgstr "Предметный указатель" #: bibliography msgid "Bibliography" msgstr "Библиография" #: list-table msgid "List of Tables" msgstr "Список таблиц" #: next msgid "Next" msgstr "След." #: float-algorithm msgid "Algorithm " msgstr "Алгоритм" #: Part msgid "Part" msgstr "Часть" #: generated-by msgid "Document generated by " msgstr "" #: toc msgid "Table of Contents" msgstr "Содержание" #: prev msgid "Prev" msgstr "Пред." #: Section msgid "Section" msgstr "Раздел" #: Chapter msgid "Chapter" msgstr "Глава" #: list-tableau msgid "List of Tableaux" msgstr "" #: generated-on msgid " on " msgstr "" #: float-tableau msgid "Tableau " msgstr "" #: Paragraph msgid "Paragraph" msgstr "Абзац" #: list-figure msgid "List of Figures" msgstr "Список рисунков" #: main-page msgid "Main page" msgstr "Главная" #: float-listing msgid "Listing " msgstr "Листинг " #: on-page msgid " on page " msgstr " на странице " #: nomenclature msgid "Nomenclature" msgstr "Список обозначений" #: float-table msgid "Table " msgstr "Таблица " #: float-figure msgid "Figure " msgstr "Рисунок " #: toc-for msgid "Contents for " msgstr "Содержание " #: jsmath-enable msgid "Please enable JavaScript on your browser." msgstr "Пожалуйста включите JavaScript." #: footnotes msgid "Footnotes" msgstr "Список сносок" #: jsmath-requires msgid " requires JavaScript to correctly process the mathematics on this page. " msgstr "Для формул необходим JavaScript." elyxer-1.2.5/po/locale/0000755000175000017500000000000012074107064014213 5ustar chennochennoelyxer-1.2.5/po/locale/nl/0000755000175000017500000000000012074107064014624 5ustar chennochennoelyxer-1.2.5/po/locale/nl/LC_MESSAGES/0000755000175000017500000000000012074107064016411 5ustar chennochennoelyxer-1.2.5/po/locale/nl/LC_MESSAGES/elyxer.mo0000644000175000017500000000376412117174754020300 0ustar chennochenno$<5\01 6H@   '6 ?I N [e)j     P b oz   ! *6? Wa"f     !# $  " on on page requires JavaScript to correctly process the mathematics on this page. AbstractAlgorithm AppendixBibliographyBookChapterContents for Document generated by Figure IndexList of AlgorithmsList of FiguresList of TableauxList of TablesListing Main pageNextNomenclatureParagraphPartPlease enable JavaScript on your browser.PrevReferencesSectionSubsectionSubsubsectionTable Table of ContentsTableau UpWarning: figureProject-Id-Version: PACKAGE VERSION PO-Revision-Date: 2010-03-12 21:17+0100 Last-Translator: Hans Bezemer Language-Team: Dutch MIME-Version: 1.0 Content-Type: text/plain; charset=ASCII Content-Transfer-Encoding: 8bit Plural-Forms: nplurals=2; plural=(n != 1); op op pagina om de formules op deze bladzijde correct weer te geven is Javascript benodigd. SamenvattingAlgoritme AppendixBibliografieBoekHoofdstukInhoud van Document gegenereerd door Figuur IndexLijst van algoritmenLijst van figurenLijst van TableauxLijst van tabellenListing HoofdpaginaVolgendeVerklaring van symbolenParagraafDeelActiveer Javascript in uw browser.VorigeReferentiesSectieSubsectieSubsubsectieTabel InhoudsopgaveTableau TerugWaarschuwing: figuurelyxer-1.2.5/po/locale/fr/0000755000175000017500000000000012074107064014622 5ustar chennochennoelyxer-1.2.5/po/locale/fr/LC_MESSAGES/0000755000175000017500000000000012074107064016407 5ustar chennochennoelyxer-1.2.5/po/locale/fr/LC_MESSAGES/elyxer.mo0000644000175000017500000000402512117174754020265 0ustar chennochenno$<5\01 6H@   '6 ?I N [e)j     ' .<BKd{   1 C O\ dpV !# $  " on on page requires JavaScript to correctly process the mathematics on this page. AbstractAlgorithm AppendixBibliographyBookChapterContents for Document generated by Figure IndexList of AlgorithmsList of FiguresList of TableauxList of TablesListing Main pageNextNomenclatureParagraphPartPlease enable JavaScript on your browser.PrevReferencesSectionSubsectionSubsubsectionTable Table of ContentsTableau UpWarning: figureProject-Id-Version: PACKAGE VERSION PO-Revision-Date: 2010-02-18 00:13+0100 Last-Translator: Sara Teinturier Language-Team: French MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Plural-Forms: nplurals=2; plural=(n > 1); le page . RésuméAlgorithme AnnexeBibliographieLivreChapitreTables des matières du Document generated by Figure IndexListe des algorithmesTable des figuresListe des tableauxList des tablesListing Page principaleSuivantGlossaireParagraphePartieMerci d'activer JavaScript dans votre navigateur.PrécédentRéférencesSectionSousSectionSousSousSectionTable Table des matièresTableau Monter d'un niveauErreur: Javascript est nécessaire pour afficher correctement les fonctionnalités de Figureelyxer-1.2.5/po/locale/es/0000755000175000017500000000000012074107064014622 5ustar chennochennoelyxer-1.2.5/po/locale/es/LC_MESSAGES/0000755000175000017500000000000012074107064016407 5ustar chennochennoelyxer-1.2.5/po/locale/es/LC_MESSAGES/elyxer.mo0000644000175000017500000000402412117174754020264 0ustar chennochenno$<5\01 6H@   '6 ?I N [e)j     M n v    $6? Q [hq/w    !# $  " on on page requires JavaScript to correctly process the mathematics on this page. AbstractAlgorithm AppendixBibliographyBookChapterContents for Document generated by Figure IndexList of AlgorithmsList of FiguresList of TableauxList of TablesListing Main pageNextNomenclatureParagraphPartPlease enable JavaScript on your browser.PrevReferencesSectionSubsectionSubsubsectionTable Table of ContentsTableau UpWarning: figureProject-Id-Version: eLyXer 0.40 PO-Revision-Date: 2010-01-12 23:50+0100 Last-Translator: chenno Language-Team: Spanish MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Plural-Forms: nplurals=2; plural=(n != 1); en en la página requiere JavaScript para procesar las fórmulas matemáticas de la página. ResumenAlgoritmo ApéndiceBibliografíaLibroCapítuloContenido de Documento generado con Figura Índice alfabéticoÍndice de algoritmosÍndice de figurasLista de tablasÍndice de tablasListado Página principalSiguienteNomenclaturaPárrafoPartePor favor, habilite JavaScript en su navegador.AnteriorReferenciasSecciónSubsecciónSubsubsecciónTabla Índice generalTabla ArribaAviso: figuraelyxer-1.2.5/po/locale/de/0000755000175000017500000000000012074107064014603 5ustar chennochennoelyxer-1.2.5/po/locale/de/LC_MESSAGES/0000755000175000017500000000000012074107064016370 5ustar chennochennoelyxer-1.2.5/po/locale/de/LC_MESSAGES/elyxer.mo0000644000175000017500000000421312117174754020245 0ustar chennochenno$<5\01 6H@   &5 >H M Zd)i    up uM    .9Nj   1  ",;OWjr w  !#   "$ on on page requires JavaScript to correctly process the mathematics on this page. AbstractAlgorithmAppendixBibliographyBookChapterContents for Document generated by Figure IndexList of AlgorithmsList of FiguresList of TableauxList of TablesListing Main pageNextNomenclatureParagraphPartPlease enable JavaScript on your browser.PrevReferencesSectionSubsectionSubsubsectionTable Table of ContentsTableau UpWarning: figureProject-Id-Version: eLyXer 0.40 PO-Revision-Date: 2010-01-12 02:37+0100 Last-Translator: Uwe Stöhr Language-Team: Deutsch de> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Plural-Forms: nplurals=2; plural=(n != 1); POT-Creation-Date: X-Poedit-Language: German X-Poedit-Country: GERMANY am auf Seite Benötigt JavaScript um die Formeln auf dieser Seite darstellen zu können. AbstractAlgorithmusAnhangBibliografieBuckKapitelInhalt für Dokument wurde erzeugt von Abbildung StichwortverzeichnisVerzeichnis der AlgorithmenAbbildungsverzeichnisTabellenverzeichnisTabellenverzeichnisListing HauptseiteWeiterNomenklaturParagraphTeilBitte aktivieren Sie JavaScript in Ihrem Browser.ZurückLiteraturAbschnittUnterabschnittUnterunterabschnittTabelleInhaltsverzeichnisTabelleObenWarnung: Abbildungelyxer-1.2.5/po/locale/ru/0000755000175000017500000000000012074107064014641 5ustar chennochennoelyxer-1.2.5/po/locale/ru/LC_MESSAGES/0000755000175000017500000000000012074107064016426 5ustar chennochennoelyxer-1.2.5/po/locale/ru/LC_MESSAGES/elyxer.mo0000644000175000017500000000415112117174754020304 0ustar chennochenno)  H  !. 6D LV\o   )   $69@2$5J cn'!0@ O#Y } 1 ! *: OZ      on page requires JavaScript to correctly process the mathematics on this page. AbstractAlgorithm AppendixBibliographyChapterContents for Figure FootnotesIndexList of AlgorithmsList of FiguresList of TablesListing Main pageNextNomenclatureParagraphPartPlease enable JavaScript on your browser.PrevReferencesSectionSubsectionSubsubsectionTable Table of ContentsUpfigureProject-Id-Version: elyxer 1.2.3 PO-Revision-Date: 2011-11-11 16:24+0300 Last-Translator: Vladimir Ermakov Language-Team: Russian Language: ru MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2); POT-Creation-Date: на странице Для формул необходим JavaScript.АннотацияАлгоритмПриложениеБиблиографияГлаваСодержание Рисунок Список сносокПредметный указательСписок алгоритмовСписок рисунковСписок таблицЛистинг ГлавнаяСлед.Список обозначенийАбзацЧастьПожалуйста включите JavaScript.Пред.Список литературыРазделПодразделПодподразделТаблица СодержаниеВверхрисунокelyxer-1.2.5/po/locale/en/0000755000175000017500000000000012074107064014615 5ustar chennochennoelyxer-1.2.5/po/locale/en/LC_MESSAGES/0000755000175000017500000000000012074107064016402 5ustar chennochennoelyxer-1.2.5/po/locale/en/LC_MESSAGES/elyxer.mo0000644000175000017500000000365012117174754020263 0ustar chennochenno#4/L  Ha ju ~  ! & 3=)Blq y    HA JU ^kp x   )"LQ Y dry !  #  "   on on page requires JavaScript to correctly process the mathematics on this page. AbstractAlgorithm AppendixBibliographyBookChapterContents for Document generated by Figure IndexList of AlgorithmsList of FiguresList of TableauxList of TablesListing Main pageNextNomenclatureParagraphPartPlease enable JavaScript on your browser.PrevSectionSubsectionSubsubsectionTable Table of ContentsTableau UpWarning: figureProject-Id-Version: PACKAGE VERSION PO-Revision-Date: 2010-10-16 19:04+0200 Last-Translator: chenno Language-Team: English Language: en MIME-Version: 1.0 Content-Type: text/plain; charset=ASCII Content-Transfer-Encoding: 8bit Plural-Forms: nplurals=2; plural=(n != 1); on on page requires JavaScript to correctly process the mathematics on this page. AbstractAlgorithm AppendixBibliographyBookChapterContents for Document generated by Figure IndexList of AlgorithmsList of FiguresList of TableauxList of TablesListing Main pageNextNomenclatureParagraphPartPlease enable JavaScript on your browser.PrevSectionSubsectionSubsubsectionTable Table of ContentsTableau UpWarning: figureelyxer-1.2.5/README.md0000644000175000017500000001101712074107030013606 0ustar chennochennoeLyXer -- convert LyX source files to HTML output. Introduction ============ eLyXer converts a LyX source file to a HTML page. Full documentation in HTML format can be found at docs/index.html, or on the web: http://www.nongnu.org/elyxer/ Installation ============ Quick installation guide (for the impatient): * download the latest version from http://www.nongnu.org/elyxer/, * decompress the .zip or .tar.gz * and install it using the provided script install.py as root: # ./install.py or on Windows: > python install.py To install eLyXer first download a compressed version from http://www.nongnu.org/elyxer/ You will also need a recent (> 2.4) version of Python on your target machine. For decompression: open a terminal window in the directory that contains the downloaded file and just write at the command line prompt: $ tar -xzf elyxer-[version].tar.gz Or for the .zip version: $ unzip elyxer-[version].zip where [version] should be something like 0.44; the full name might be something like elyxer-0.44.tar.gz. On Windows or Mac OS X you can unzip the file using the graphical tool of your choice. In any case, a directory called elyxer-[version] should appear, where the installer script install.py can be found (along with this README). The recommended installation procedure is to just run this script. On Linux type as root: # ./install.py and similarly for Mac OS X, while for Windows open a console and type: > python install.py Note the you don't need to write the prompt, # or >; the console will print it for you. Double-clicking on install.py should also work if your Python installation is minimally sane. It will tell you as a result to which directory eLyXer has been installed as a binary, which is be the typical result; in this case eLyXer should be run as follows: $ elyxer.py [input file] [output file] or, on Windows: > elyxer.py [input file] [output file] You can test that it works with the --help option: $ elyxer.py --help or, on Windows: > elyxer.py --help Usage and options should then be shown. LyX Integration =============== To integrate eLyXer with LyX you just have to reconfigure LyX, selecting Tools -> Reconfigure from within LyX. For rather old versions of LyX (< 1.6.2) you may have to copy elyxer.py into the LyX directory, and reconfigure it. Later versions will recognize eLyXer automatically, either if you install it using distutils or as a binary. Usage ===== eLyXer can be invoked from the command line as: $ elyxer.py [source file] [destination file] If the source file is omitted then STDIN is used; likewise, if no destination file is specified eLyXer will output to STDOUT. This allows its use in pipes and other flexible configurations. Examples: $ elyxer.py file.lyx file.html converts file.lyx to file.html. Debug messages are shown. $ cat file.lyx | elyxer.py > file.html converts file.lyx to file.html, as before. This time debug messages are not shown. $ elyxer.py file.lyx | grep "
" | wc counts all blockquote paragraphs. $ elyxer.py file.lyx | wget --no-check-certificate --spider -nv -F -i - checks all external links in a document recursively. (Local links will appear as unresolved, but they can be ignored.) Documentation ============= Documentation about eLyXer, including a user guide and a developer guide, can be found in the docs directory. The project is hosted at Savannah.nongnu.org. Be sure to visit the project home page at: http://www.nongnu.org/elyxer/ License ======= eLyXer is Copyright (C) 2009-2011 Alex Fernández. This program is free software: 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 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 GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . math2html (a subset of eLyXer) Copyright (C) 2009-2011 Alex Fernández Released under the terms of the `2-Clause BSD license'_, in short: Copying and distribution of this file, with or without modification, are permitted in any medium without royalty provided the copyright notice and this notice are preserved. This file is offered as-is, without any warranty. .. _2-Clause BSD license: http://www.spdx.org/licenses/BSD-2-Clause Enjoy! elyxer-1.2.5/run-tests0000755000175000017500000001462512117063046014237 0ustar chennochenno#!/bin/bash # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # Alex 20090319: run all tests # remove result files from previous test runs rm -f "test/*-test.html" rm -f "test/subdir/*-test.html" # first from the current directory echo "Testing eLyXer -- any text below this line signals an error" for file in test/*.lyx; do name=$(dirname "$file")/$(basename "$file" .lyx) ./elyxer.py --quiet --css ../docs/lyx.css "$name.lyx" "$name-test.html" diff -u --ignore-matching-lines="create-date" "$name-good.html" "$name-test.html" done # now a limited subset of tests from within the directory cd test name="with images-1-5" ../elyxer.py --quiet --css=../docs/lyx.css "$name.lyx" "$name-test.html" diff -u --ignore-matching-lines="create-date" "$name-good.html" "$name-test.html" ../elyxer.py --html --quiet --css ../docs/lyx.css "$name.lyx" "$name-html-test.html" diff -u --ignore-matching-lines="create-date" "$name-html-good.html" "$name-html-test.html" ../elyxer.py --quiet --css ../docs/lyx.css --imageformat ".jpg" "$name.lyx" "$name-jpg-test.html" diff -u --ignore-matching-lines="create-date" "$name-jpg-good.html" "$name-jpg-test.html" ../elyxer.py --quiet --css ../docs/lyx.css --noconvert "$name.lyx" "$name-noconvert-test.html" diff -u --ignore-matching-lines="create-date" "$name-noconvert-good.html" "$name-noconvert-test.html" # test --imageformat copy cd copyimages ../../elyxer.py --quiet --css ../../docs/lyx.css --imageformat "copy" "../$name.lyx" "$name-test.html" diff -u --ignore-matching-lines="create-date" "$name-good.html" "$name-test.html" cd .. # directory tests cd subdir name="image-directory" image="mourning.png" rm -f $image ../../elyxer.py --directory .. --quiet --css ../../docs/lyx.css "$name.lyx" "$name-test.html" diff -u --ignore-matching-lines="create-date" "$name-good.html" "$name-test.html" if [ ! -e $image ]; then echo "$image is missing; bad conversion."; fi name="appendix-1-6" cp -f ../$name.lyx . ../../elyxer.py --copyright --directory .. --quiet --css ../../docs/lyx.css "$name.lyx" "$name-test.html" diff -u --ignore-matching-lines="create-date" "$name-good.html" "$name-test.html" cd .. # test TOC generation name="appendix-1-6" ../elyxer.py --quiet --tocfor "$name-test.html" --css ../docs/toc.css --target contents "$name.lyx" "$name-toc-test.html" diff -u --ignore-matching-lines="create-date" "$name-toc-good.html" "$name-toc-test.html" # test --notoclabels name="toc-book" ../elyxer.py --quiet --notoclabels --css ../docs/lyx.css "$name.lyx" "$name-notoclabels-test.html" diff -u --ignore-matching-lines="create-date" "$name-notoclabels-good.html" "$name-notoclabels-test.html" # test raw generation name="helloworld" ../elyxer.py --quiet --raw "$name.lyx" "$name-raw-test.html" diff -u --ignore-matching-lines="create-date" "$name-raw-good.html" "$name-raw-test.html" # test --css and --embedcss name="helloworld" ../elyxer.py --quiet --css "http://elyxer.nongnu.org/lyx.css" --css ../docs/math.css \ --embedcss test.css "$name.lyx" "$name-embedcss-test.html" diff -u --ignore-matching-lines="create-date" "$name-embedcss-good.html" "$name-embedcss-test.html" # test lowmem generation name="index-1-6" ../elyxer.py --quiet --lowmem --css ../docs/lyx.css "$name.lyx" "$name-lowmem-test.html" diff -u --ignore-matching-lines="create-date" "$name-lowmem-good.html" "$name-lowmem-test.html" # test Python 2.4 generation name="index-1-6" type -P python2.4 &> /dev/null if [ $? = 0 ] ; then python2.4 ../elyxer.py --quiet --css ../docs/lyx.css "$name.lyx" "$name-py2.4-test.html" diff -u --ignore-matching-lines="create-date" "$name-good.html" "$name-py2.4-test.html" else echo "python2.4 not found, cannot test it" fi # test stdin + stdout generation name="footnotes-1-6" cat "$name.lyx" | ../elyxer.py --css ../docs/lyx.css > "$name-stdio-test.html" diff -u --ignore-matching-lines="create-date" "$name-good.html" "$name-stdio-test.html" # test --splitpart generation name="index-1-6" testfiles="parts/$name-part-test*.html" rm -f $testfiles ../elyxer.py --quiet --splitpart 1 --css ../../docs/lyx.css "$name.lyx" "parts/$name-part-test.html" for file in $testfiles; do goodname=${file/"-test"/"-good"} diff -u --ignore-matching-lines="create-date" "$goodname" "$file" done # test TOC generation for --splitpart name="index-1-6" ../elyxer.py --quiet --tocfor "$name-part-test.html" --target "contents" --splitpart 1 --css ../../docs/toc.css "$name.lyx" "parts/$name-toc-test.html" diff -u --ignore-matching-lines="create-date" "parts/$name-toc-good.html" "parts/$name-toc-test.html" # test template generation name="helloworld" ../elyxer.py --quiet --template template.html "$name.lyx" "$name-template-test.html" diff -u --ignore-matching-lines="create-date" "$name-template-good.html" "$name-template-test.html" # test math2html result=$(../math2html.py 'N = \frac{\text{number of apples}}{7}') good='N = (number of apples)/(7)' if [ "$result" != "$good" ] ; then echo "Error in math2html: $result != $good" fi # test title with non-ASCII characters, Debian bug 639712 # http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=639712 name="helloworld" ../elyxer.py --quiet --css ../docs/lyx.css --title "By Fernández" "$name.lyx" "$name-test.html" diff -u --ignore-matching-lines="create-date" --ignore-matching-lines="" "$name-good.html" "$name-test.html" # test simultaneous hover and end in footnotes name="footnotes-1-6" ../elyxer.py --quiet --footnotes hover,end,number --css ../docs/lyx.css "$name.lyx" "$name-hover-end-test.html" diff -u --ignore-matching-lines="create-date" "$name-hover-end-good.html" "$name-hover-end-test.html" �����������������������������������������������������������������������������������������������������������elyxer-1.2.5/.gitignore�����������������������������������������������������������������������������0000644�0001750�0001750�00000001110�12117067457�014330� 0����������������������������������������������������������������������������������������������������ustar �chenno��������������������������chenno�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# git-ls-files --others --exclude-from=.git/info/exclude # Lines that start with '#' are comments. # For a project mostly in C, the following would be a good set of # exclude patterns (uncomment them if you want to use them): # *.[oa] *\# *~ *.pyc *.swp *-test.html *-test-*.html po/locale/* test/*.py build/* dist/* samples/* patch/* elyxer.py loremipsumize.py math2html.py setup.py docs/*.html docs/*.css docs/cvs/ docs/MathJax/ docs/jsMath/ config.py elyxer.pot test/copyimages/*.svg test/copyimages/*.png test/copyimages/*.jpg test/copyimages/docs test/subdir/mourning.png forks ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������elyxer-1.2.5/docs/����������������������������������������������������������������������������������0000755�0001750�0001750�00000000000�12117175142�013266� 5����������������������������������������������������������������������������������������������������ustar �chenno��������������������������chenno�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������elyxer-1.2.5/docs/index.lyx�������������������������������������������������������������������������0000644�0001750�0001750�00000030334�12074107030�015127� 0����������������������������������������������������������������������������������������������������ustar �chenno��������������������������chenno�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#LyX 1.6.7 created this file. For more info see http://www.lyx.org/ \lyxformat 345 \begin_document \begin_header \textclass article \begin_preamble % eLyXer -- convert LyX source files to HTML output. % % Copyright (C) 2009-2011 Alex Fernández % % This program is free software: 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 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 % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see <http://www.gnu.org/licenses/>. \end_preamble \use_default_options false \language english \inputencoding auto \font_roman default \font_sans default \font_typewriter default \font_default_family default \font_sc false \font_osf false \font_sf_scale 100 \font_tt_scale 100 \graphics default \paperfontsize default \spacing single \use_hyperref false \papersize default \use_geometry false \use_amsmath 1 \use_esint 1 \cite_engine basic \use_bibtopic false \paperorientation portrait \secnumdepth 3 \tocdepth 3 \paragraph_separation indent \defskip medskip \quotes_language english \papercolumns 1 \papersides 1 \paperpagestyle default \tracking_changes false \output_changes false \author "" \author "" \end_header \begin_body \begin_layout Title \begin_inset Graphics filename elyxer.svg lyxscale 50 \end_inset eLyXer \end_layout \begin_layout Quotation \emph on \begin_inset CommandInset href LatexCommand href name "elixir" target "http://www.wordreference.com/definition/elixir" \end_inset , n: a substance believed to cure all ills. \end_layout \begin_layout Standard eLyXer (pronounced \emph on elixir \emph default ) is a LyX to HTML converter. While there are a ton of such projects all over the web, eLyXer has a clear focus on flexibility and elegant output. \end_layout \begin_layout Standard \begin_inset CommandInset href LatexCommand href name "LyX" target "http://www.lyx.org/" \end_inset is a wonderful text editor which produces beautiful PDF files. Internally it exports documents to LaTeX, and from there to PDF. Sadly there is not an equivalent \begin_inset Quotes eld \end_inset export to HTML \begin_inset Quotes erd \end_inset option\SpecialChar \ldots{} Until now! With eLyXer you can convert your master's thesis, learned article, fascinating novel or love letter to a web page that you can then share, publish on the web or import into other text editors. \end_layout \begin_layout Standard The \begin_inset CommandInset href LatexCommand href name "user guide" target "userguide.html" \end_inset can be accessed online. The \begin_inset CommandInset href LatexCommand href name "developer guide" target "devguide.html" \end_inset is recommended reading for people that want to contribute to the development, especially \begin_inset CommandInset href LatexCommand href name "section 3" target "devguide.html#toc-Section-3" \end_inset . For the mathematically inclined: be sure to visit the \begin_inset CommandInset href LatexCommand href name "Math Showcase" target "math.html" \end_inset . \end_layout \begin_layout Subsection* Requirements \end_layout \begin_layout Standard eLyXer is a standalone tool: it does not require that LyX is installed to run. It can convert documents generated with versions of LyX from 1.5.5 through 2.0 (and probably earlier versions). It requires Python 2.3.4, and should work with versions up to 2.6.1. It has been tested to run on Linux, Mac OS X and Windows. \end_layout \begin_layout Standard Resource usage is minimum. Converting UserGuide.lyx ( \begin_inset Formula $154$ \end_inset pages, about \begin_inset Formula $40000$ \end_inset words) takes less than 15 seconds on my Asus EeePC 1000H, which sports an Intel Atom processor at 1.60 GHz. Memory usage is also quite frugal, remaining at about 35 MB even with in-memory processing. \end_layout \begin_layout Standard The output requires XHTML, CSS2 and Unicode; any CSS2-compatible browser should do. Minimum browser versions for some popular programs are: Microsoft Internet Explorer 7, Mozilla Firefox 3, Safari 3 and Chrome 1. \end_layout \begin_layout Subsection* Usage \end_layout \begin_layout Standard eLyXer is a command line tool written in Python. Installation is done using the included installer; just type at the prompt as root: \end_layout \begin_layout LyX-Code \family typewriter \color blue # \color inherit python install.py \end_layout \begin_layout Standard or, on Windows: \end_layout \begin_layout LyX-Code \family typewriter \color blue > \color inherit Python.exe install.py \end_layout \begin_layout Standard Basic usage is as simple as writing at the command line prompt: \end_layout \begin_layout LyX-Code \family typewriter \color blue $ \color inherit elyxer.py document.lyx page.html \end_layout \begin_layout Standard or, on Windows: \end_layout \begin_layout LyX-Code \family typewriter \color blue > \color inherit elyxer.py document.lyx page.html \end_layout \begin_layout Standard where \family typewriter document.lyx \family default is your LyX document, and \family typewriter page.html \family default is the resulting HTML page. Write \end_layout \begin_layout LyX-Code \family typewriter \color blue $ \color inherit elyxer.py --help \end_layout \begin_layout Standard or see the \begin_inset CommandInset href LatexCommand href name "user guide" target "userguide.html" \end_inset for details. \end_layout \begin_layout Subsection* Downloads \end_layout \begin_layout Standard You can download the latest version from the project's \begin_inset CommandInset href LatexCommand href name "download area" target "https://savannah.nongnu.org/files/?group=elyxer" \end_inset . See the \begin_inset CommandInset href LatexCommand href name "change log" target "changelog.html" \end_inset for information about past versions. \end_layout \begin_layout Standard eLyXer (including this page and all accompanying materials) is free software: you can redistribute it and/or modify it under the terms of the \begin_inset CommandInset href LatexCommand href name "GNU General Public License" target "http://www.gnu.org/licenses/gpl-3.0-standalone.html" \end_inset as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. See the \family typewriter LICENSE \family default file for details. \end_layout \begin_layout Standard math2html (and \family typewriter math.css \family default ) is released without warranties or conditions of any kind under the terms of the \begin_inset CommandInset href LatexCommand href name "Apache License, version 2.0" target "http://www.apache.org/licenses/LICENSE-2.0" \end_inset . \end_layout \begin_layout Subsection* Contact \end_layout \begin_layout Standard You can contact the main developer at \begin_inset CommandInset href LatexCommand href name "elyxer@gmail.com" target "elyxer@gmail.com" type "mailto:" \end_inset ; he really likes getting challenging documents and making eLyXer work with them. Any document sample you send will be treated with the utmost confidentiality. \end_layout \begin_layout Standard The author lingers around official LyX mailing lists and monitors for mentions of eLyXer. You can also \begin_inset CommandInset href LatexCommand href name "join" target "http://lists.nongnu.org/mailman/listinfo/elyxer-users" \end_inset the low-volume \begin_inset CommandInset href LatexCommand href name "mailing list" target "elyxer-users@nongnu.org" type "mailto:" \end_inset , where announcements of new versions are always posted. Bugs can be reported at the \begin_inset CommandInset href LatexCommand href name "Savannah page" target "https://savannah.nongnu.org/bugs/?func=additem&group=elyxer" \end_inset ; features can be requested too. Feature requests that fit in will be added to the \begin_inset CommandInset href LatexCommand href name "wish list" target "userguide.html#sub:Wish-List" \end_inset . \end_layout \begin_layout Subsection* Acknowledgments \end_layout \begin_layout Standard This little project is my little contribution back to the wonderful LyX community, for all these years of fruitful use. \end_layout \begin_layout Standard Thanks to \begin_inset CommandInset href LatexCommand href name "Stevan White" target "http://www.zipcon.net/~swhite/resume/" \end_inset for encouraging me to publish the tool. Thanks also to \begin_inset CommandInset href LatexCommand href name "John D. Cook" target "http://www.johndcook.com/" \end_inset , \begin_inset CommandInset href LatexCommand href name "rikal" target "http://community.jedit.org/?q=node/view/1746" \end_inset , \begin_inset CommandInset href LatexCommand href name "Bradley M. Bell" target "http://www.seanet.com/~bradbell/omhelp/stdfun.htm" \end_inset , \begin_inset CommandInset href LatexCommand href name "Markus Kuhn" target "http://www.cl.cam.ac.uk/~mgk25/ucs/examples/TeX.txt" \end_inset , Jens Nöckel, \begin_inset CommandInset href LatexCommand href name "Günter Milde" target "http://milde.users.sourceforge.net/LUCR/Math/" \end_inset and LyX developers Georg Baum, Uwe Stöhr and Jürgen Spitzmüller for their wonderful lists of TeX commands and Unicode equivalents; to \begin_inset CommandInset href LatexCommand href name "FileFormat.info" target "http://www.fileformat.info/" \end_inset for their complete tables of Unicode characters. More thanks go to Christian Ridderström for helping me out right at the start; to Ignacio García for relentless encouragement; to Abdelrazak Younes, Pavel Sanda, Günter Milde, Olivier Ripoll, José Matos, Iain Mac Donald, Uwe Stöhr for their interesting suggestions. Thanks to Uwe Stöhr, Hans Bezemer, Sara Teinturier, Vladimir Ermakov for their translations. Packagers Sven Hoexter (for Debian) and Uwe Stöhr (on Windows) have helped with their work to make it easy to try it out. Olivier Ripoll, Geremy Condra, Simon South, Jack Desert, \begin_inset CommandInset href LatexCommand href name "John Boik" target "http://www.newearthbiomed.org/" \end_inset , Yan Wong, Jose Ramón Álvarez Sánchez, Günter Milde, Pascal Francq, Marco R. Gazzetta have provided quite interesting patches. Davide P. Cervone has been extremely helpful and responsive about jsMath and MathJax integration, while Paul Hunter has also gone beyond the call of duty with his help integrating \begin_inset CommandInset href LatexCommand href name "MathToWeb" target "http://www.mathtoweb.com/" \end_inset (which unfortunately has not been fruitful yet, due to my lack of skill and certainly not to his lack of interest). \end_layout \begin_layout Standard Thanks to Nikos Alexandris, Joachim Kreimer-de Fries (Osnabryg), Richard Talley, Wolfgang Keller, Murray Eisenberg, Robert Orr, a Linux guy in Singapore , Anders Ekberg, Pavel Sanda, Steve Hastings, Sven Hoexter, Xie Chao, Uwe Stöhr, Jürgen Spitzmüller, Olivier Ripoll, Konrad Hofbauer, Eduardo Grosclaude, Ken, Jens Nöckel, \begin_inset CommandInset href LatexCommand href name "Dr Eberhard W Lisse" target "el@lisse.na" type "mailto:" \end_inset , William Crocker, Sara Teinturier, Hans Bezemer, Jack Desert, Hartmut Haase, Rainer Dorsch, Wolfgang Engelmann, Rodrigo Benenson, Stefano Franchi, Steve Litt, Paul Johnson, Yan Wong, Yaron Goland, Francis Girard, Rene de Zwart, Jose Ramón Álvarez Sánchez, Günter Milde, Axel Jacobs, Tiago Pedro Alves-Ferrei ra, Hoy Loper, Bob Alvarez, Tommaso Cucinotta for their testing and bug reporting. \end_layout \begin_layout Standard A silent \begin_inset Quotes eld \end_inset thank you \begin_inset Quotes erd \end_inset goes to all those who downloaded the tool and silently tested it to their satisfaction (or were not bugged enough to write about it). Thanks to those who have criticized the tool for making eLyXer improve every day, if only to prove you wrong. And finally thanks to all those who have helped and yet I am now forgetting about them, for not hating me for it. \end_layout \end_body \end_document ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������elyxer-1.2.5/docs/math-unicode.html�����������������������������������������������������������������0000644�0001750�0001750�00000114170�12117174756�016547� 0����������������������������������������������������������������������������������������������������ustar �chenno��������������������������chenno�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> <meta name="generator" content="http://www.nongnu.org/elyxer/"/> <meta name="create-date" content="2013-03-10"/> <link rel="stylesheet" href="lyx.css" type="text/css" media="all"/> <title>eLyxer Math Showcase (Unicode edition)

figure elyxer.png eLyXer Math Showcase

Alex Fernández (elyxer@gmail.com)

1 Introduction

This document is intended as a showcase of the mathematical abilities of eLyXer; for more information be sure to visit the main page.

1.1 Versions

There are several versions of this page:
All of them are generated from the same .lyx source file; they should help you decide which rendering options suit you best.
Also available online is the eLyXer translation of the latest LyX’s detailed Math manual, which contains a lot more examples of LyX maths.

2 Typography

Math formulae use a lot of different symbols and fonts.

2.1 Greek Symbols

Greek symbols are very important in equations: φ, π, Ξ. eLyXer offers a complete set in both upper case: Γ…Ω and lower case: αω. Also the AMS italicized upper case: ΓΩ.

2.2 Math Symbols

eLyXer supports the whole set of math symbols in John D. Cook's list: ∃∂∇ ≥ . It can also render a few more:  ∝  × . You also get all symbols from Markus Kuhn's list: ⊙∐.

2.3 Other Symbols

There are other symbols like arrows:  ←  → , or geometrical shapes: , . eLyXer offers limited support for them. You might also want to use financial symbols in formulae: ¥€$.

2.4 Spacing

Equations look good when items are properly separated. The main separation is the Medium Mathematical Space: x = 3. Note: if you are viewing the non-Unicode version math.html of this page then you are in fact seeing midspaces, which are very similar but not exactly the same: (4)/(18) em for medium mathematical spaces versus (1)/(2) en, where 1 em = 2 en. Try out the Unicode version math-unicode.html — and viceversa. You can check out what version this page is in the page title.
The command \raisebox is useful to, surprisingly, raise a little box,
raisedoverloweredand back.
Like \mbox, it puts its content in a text box. It can also be used just for spacing:
BV.
There are other spacing commands: \hspace: a b, protected space: a b, and (at “block level”) \vspace: a b.
There should be 1 cm of vertical space above this paragraph.

2.5 Fonts

By default, letters denote variables and are taken from the \mathnormal font, which is italic, αx + αy = α(x + y), with the exception of upright capital Greek letters, G ≠ Γ.
Function names should be upright: sin(2π), log(x), tanδ.
Mathematical fonts used in equations include Roman (\mathrm), Sans Serif (\mathsf), Typewriter (\mathtt), Bold (\mathbf), SCRIPT (\mathscr), CALLIGRAPHIC (\mathcal), BLACKBOARD BOLD (\mathbb), and Fraktur (\mathfrak). For the latter, some single characters are translated to their Unicode equivalents: , 𝔽, 𝔉.
Regular text in a formula can be achieved via text font commands like \textrm: 5  to 10, via boxes like \mbox (prevents line breaks): 6  is more than 5, or the AMSmath \text macro (scales like math symbols) basesupersub. The content of an mbox is processed in LaTeX text mode. This allows text font commands, e.g. a switch to sans-serif-bold-italic, or the phonetic alphabet: sfbfit, tipa.
Units should be written upright, either with \mathrm or with macros from the units package, e.g. as simple unit, km, with magnitude, 57 km, with fractional unit, 200 kmh, or with a fraction before the units, 32 km, (7)/(16) s.

3 Numeration

Equations can be numbered, like (1↓)
(1) y = x
And also like (2↓).
(2) x = 3
Some equations can be numbered even if they don’t have a label.
(3) x = 2y
Notice that equation (2↑) comes after (1↑).

4 Simple Structures

Let’s now see a few of the simpler structures that eLyXer can output.

4.1 Fractions

A simple fraction:
(1)/(2).
Inlined: (2)/(3).
A big recursive fraction:
(1)/(1 + (1)/(1 + (1)/(1 + 2x)))
A nice fraction: 56. A non-diminishing fraction containing alignments:
(1)/(1 + (1)/(1 + x) × (1)/(1 + x)).
A similar concept is a binomial coefficient: (A + 1B). It can be prettily presented:
AB + 1.
A symbol can be stacked over another using \stackrel: xR → y. Anything can be stacked:
dx > 3limx,  headheels.

4.2 Limits

limx → ∞f(x) should appear as x → ∞ in italics, and «lim» in plain style. In display mode, a limit must appear below the main symbol:
limx → ∞f(x).
Limits are also used in sums and integrals:
i = 1x,  0f(x) dx
where the sum’s limits should appear below (i = 1) and above () the . The placement of the integral limits depends on the document class: LaTeX standard classes place them right to the . Limits are shown to the right in inline formulae: i = 1x and i = 1x.
The placing of limits can be configured with the \limits and \nolimits macros:
limx → ∞f(x),  i = 1x,  0f(x) dx

4.3 Roots

A square root: (3). A more complex root in a fraction:
(1)/(1 + (2)(1)/(1 + (2)) + ((1)/(2))).
eLyXer can also do higher-order roots: 3(x + y). A devilish case mixing everything we have seen so far:
(78((8)/(4)x) + i = 1x)/(s + 5(((78x + 45y) × (Ω))/(sin(x + 1)) + 38 km)).

5 Complex Structures

In this section we will explore arrays and related constructs.

5.1 Arrays

An inline array a b c d is always shown in the same line. In display mode, the array is shown on its own line:
12 2 3 4 × yx
Apart from that the appearance should be the same.

5.2 Brackets

Arrays are separated by variable-size brackets: a b c d a b c d a b c d a b c d ||| a b c d |||which might also differ on right and left a b c d or use the empty opening a b c d or closing: a b c d |||. There are also fixed-size big brackets, e.g. f.

5.3 Cases

Used to switch between several values.
y =  x i = 0,         x + 1  i < 3 
Cases may have more than two rows:
f(x) =  0  x < 0,         ∞  x = 0        0  x > 0 

5.4 Braces

Values can be underbraced or overbraced.
a − b = b + c + d + e.

6 Macros

Now it’s time for user-defined commands (sometimes called “macros”).
Definitions can be added as macros. Then they can be used in formulae: 1(2). They can accept default parameters. Again, useful in formulae: 4(5).
Other definitions from the preamble can be used: 3(4).
Definitions on the fly are also possible: 7(8), and used with different values: a(b).
elyxer-1.2.5/docs/index.html0000644000175000017500000002334112117174761015274 0ustar chennochenno eLyXer

figure elyxer.png eLyXer

elixir, n: a substance believed to cure all ills.
eLyXer (pronounced elixir) is a LyX to HTML converter. While there are a ton of such projects all over the web, eLyXer has a clear focus on flexibility and elegant output.
LyX is a wonderful text editor which produces beautiful PDF files. Internally it exports documents to LaTeX, and from there to PDF. Sadly there is not an equivalent “export to HTML” option… Until now! With eLyXer you can convert your master’s thesis, learned article, fascinating novel or love letter to a web page that you can then share, publish on the web or import into other text editors.
The user guide can be accessed online. The developer guide is recommended reading for people that want to contribute to the development, especially section 3. For the mathematically inclined: be sure to visit the Math Showcase.

Requirements

eLyXer is a standalone tool: it does not require that LyX is installed to run. It can convert documents generated with versions of LyX from 1.5.5 through 2.0 (and probably earlier versions). It requires Python 2.3.4, and should work with versions up to 2.6.1. It has been tested to run on Linux, Mac OS X and Windows.
Resource usage is minimum. Converting UserGuide.lyx (154 pages, about 40000 words) takes less than 15 seconds on my Asus EeePC 1000H, which sports an Intel Atom processor at 1.60 GHz. Memory usage is also quite frugal, remaining at about 35 MB even with in-memory processing.
The output requires XHTML, CSS2 and Unicode; any CSS2-compatible browser should do. Minimum browser versions for some popular programs are: Microsoft Internet Explorer 7, Mozilla Firefox 3, Safari 3 and Chrome 1.

Usage

eLyXer is a command line tool written in Python. Installation is done using the included installer; just type at the prompt as root:
# python install.py
or, on Windows:
> Python.exe install.py
Basic usage is as simple as writing at the command line prompt:
$ elyxer.py document.lyx page.html
or, on Windows:
> elyxer.py document.lyx page.html
where document.lyx is your LyX document, and page.html is the resulting HTML page. Write
$ elyxer.py --help
or see the user guide for details.

Downloads

You can download the latest version 1.2.5, created on 2013-03-10, from the project’s download area. See the change log for information about past versions.
eLyXer (including this page and all accompanying materials) is free software: 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. See the LICENSE file for details.
math2html (and math.css) is released without warranties or conditions of any kind under the terms of the Apache License, version 2.0.

Contact

You can contact the main developer at elyxer@gmail.com; he really likes getting challenging documents and making eLyXer work with them. Any document sample you send will be treated with the utmost confidentiality.
The author lingers around official LyX mailing lists and monitors for mentions of eLyXer. You can also join the low-volume mailing list, where announcements of new versions are always posted. Bugs can be reported at the Savannah page; features can be requested too. Feature requests that fit in will be added to the wish list.

Acknowledgments

This little project is my little contribution back to the wonderful LyX community, for all these years of fruitful use.
Thanks to Stevan White for encouraging me to publish the tool. Thanks also to John D. Cook, rikal, Bradley M. Bell, Markus Kuhn, Jens Nöckel, Günter Milde and LyX developers Georg Baum, Uwe Stöhr and Jürgen Spitzmüller for their wonderful lists of TeX commands and Unicode equivalents; to FileFormat.info for their complete tables of Unicode characters. More thanks go to Christian Ridderström for helping me out right at the start; to Ignacio García for relentless encouragement; to Abdelrazak Younes, Pavel Sanda, Günter Milde, Olivier Ripoll, José Matos, Iain Mac Donald, Uwe Stöhr for their interesting suggestions. Thanks to Uwe Stöhr, Hans Bezemer, Sara Teinturier, Vladimir Ermakov for their translations. Packagers Sven Hoexter (for Debian) and Uwe Stöhr (on Windows) have helped with their work to make it easy to try it out. Olivier Ripoll, Geremy Condra, Simon South, Jack Desert, John Boik, Yan Wong, Jose Ramón Álvarez Sánchez, Günter Milde, Pascal Francq, Marco R. Gazzetta have provided quite interesting patches. Davide P. Cervone has been extremely helpful and responsive about jsMath and MathJax integration, while Paul Hunter has also gone beyond the call of duty with his help integrating MathToWeb (which unfortunately has not been fruitful yet, due to my lack of skill and certainly not to his lack of interest).
Thanks to Nikos Alexandris, Joachim Kreimer-de Fries (Osnabryg), Richard Talley, Wolfgang Keller, Murray Eisenberg, Robert Orr, a Linux guy in Singapore, Anders Ekberg, Pavel Sanda, Steve Hastings, Sven Hoexter, Xie Chao, Uwe Stöhr, Jürgen Spitzmüller, Olivier Ripoll, Konrad Hofbauer, Eduardo Grosclaude, Ken, Jens Nöckel, Dr Eberhard W Lisse, William Crocker, Sara Teinturier, Hans Bezemer, Jack Desert, Hartmut Haase, Rainer Dorsch, Wolfgang Engelmann, Rodrigo Benenson, Stefano Franchi, Steve Litt, Paul Johnson, Yan Wong, Yaron Goland, Francis Girard, Rene de Zwart, Jose Ramón Álvarez Sánchez, Günter Milde, Axel Jacobs, Tiago Pedro Alves-Ferreira, Hoy Loper, Bob Alvarez, Tommaso Cucinotta for their testing and bug reporting.
A silent “thank you” goes to all those who downloaded the tool and silently tested it to their satisfaction (or were not bugged enough to write about it). Thanks to those who have criticized the tool for making eLyXer improve every day, if only to prove you wrong. And finally thanks to all those who have helped and yet I am now forgetting about them, for not hating me for it.
elyxer-1.2.5/docs/math.css0000644000175000017500000001116012117174754014740 0ustar chennochenno/* * math2html: convert LaTeX equations to HTML output. * * Copyright (C) 2009,2010 Alex Fernández * * Released under the terms of the `2-Clause BSD license'_, in short: * Copying and distribution of this file, with or without modification, * are permitted in any medium without royalty provided the copyright * notice and this notice are preserved. * This file is offered as-is, without any warranty. * * .. _2-Clause BSD license: http://www.spdx.org/licenses/BSD-2-Clause * * Based on eLyXer: convert LyX source files to HTML output. * http://elyxer.nongnu.org/ */ /* --end-- * CSS file for LaTeX formulas. */ /* Formulas */ .formula { text-align: center; font-family: "DejaVu Serif", serif; margin: 1.2em 0; } span.formula { white-space: nowrap; } div.formula { padding: 0.5ex; margin-left: auto; margin-right: auto; } /* Basic features */ a.eqnumber { display: inline-block; float: right; clear: right; font-weight: bold; } span.unknown { color: #800000; } span.ignored, span.arraydef { display: none; } .formula i { letter-spacing: 0.1ex; } /* Alignment */ .align-left, .align-l { text-align: left; } .align-right, .align-r { text-align: right; } .align-center, .align-c { text-align: center; } /* Structures */ span.overline, span.bar { text-decoration: overline; } .fraction, .fullfraction { display: inline-block; vertical-align: middle; text-align: center; } .fraction .fraction { font-size: 80%; line-height: 100%; } span.numerator { display: block; } span.denominator { display: block; padding: 0ex; border-top: thin solid; } sup.numerator, sup.unit { font-size: 70%; vertical-align: 80%; } sub.denominator, sub.unit { font-size: 70%; vertical-align: -20%; } span.sqrt { display: inline-block; vertical-align: middle; padding: 0.1ex; } sup.root { font-size: 70%; position: relative; left: 1.4ex; } span.radical { display: inline-block; padding: 0ex; font-size: 150%; vertical-align: top; } span.root { display: inline-block; border-top: thin solid; padding: 0ex; vertical-align: middle; } span.symbol { font-size: 125%; } span.bigsymbol { font-size: 150%; } span.largesymbol { font-size: 175%; } span.hugesymbol { font-size: 200%; } span.scripts { display: inline-table; vertical-align: middle; } .script { display: table-row; text-align: left; line-height: 150%; } span.limits { display: inline-table; vertical-align: middle; } .limit { display: table-row; line-height: 95%; } sup.limit, sub.limit { line-height: 150%; } span.symbolover { display: inline-block; text-align: center; position: relative; float: right; right: 100%; bottom: 0.5em; width: 0px; } span.withsymbol { display: inline-block; } span.symbolunder { display: inline-block; text-align: center; position: relative; float: right; right: 80%; top: 0.3em; width: 0px; } /* Environments */ span.array, span.bracketcases, span.binomial, span.environment { display: inline-table; text-align: center; border-collapse: collapse; margin: 0em; vertical-align: middle; } span.arrayrow, span.binomrow { display: table-row; padding: 0ex; border: 0ex; } span.arraycell, span.bracket, span.case, span.binomcell, span.environmentcell { display: table-cell; padding: 0ex 0.2ex; line-height: 99%; border: 0ex; } /* * CSS file for LaTeX formulas, extra stuff: * binomials, vertical braces, stackrel, fonts and colors. */ /* Inline binomials */ span.binom { display: inline-block; vertical-align: middle; text-align: center; font-size: 80%; } span.binomstack { display: block; padding: 0em; } /* Over- and underbraces */ span.overbrace { border-top: 2pt solid; } span.underbrace { border-bottom: 2pt solid; } /* Stackrel */ span.stackrel { display: inline-block; text-align: center; } span.upstackrel { display: block; padding: 0em; font-size: 80%; line-height: 64%; position: relative; top: 0.15em; } span.downstackrel { display: block; vertical-align: bottom; padding: 0em; } /* Fonts */ span.mathsf, span.textsf { font-style: normal; font-family: sans-serif; } span.mathrm, span.textrm { font-style: normal; font-family: serif; } span.text, span.textnormal { font-style: normal; } span.textipa { color: #008080; } span.fraktur { font-family: "Lucida Blackletter", eufm10, blackletter; } span.blackboard { font-family: Blackboard, msbm10, serif; } span.scriptfont { font-family: "Monotype Corsiva", "Apple Chancery", "URW Chancery L", cursive; font-style: italic; } /* Colors */ span.colorbox { display: inline-block; padding: 5px; } span.fbox { display: inline-block; border: thin solid black; padding: 2px; } span.boxed, span.framebox { display: inline-block; border: thin solid black; padding: 5px; } elyxer-1.2.5/docs/math-googlecharts.html0000644000175000017500000007254512117174760017606 0ustar chennochenno eLyxer Math Showcase (Google Charts edition)

figure elyxer.png eLyXer Math Showcase

Alex Fernández (elyxer@gmail.com)

1 Introduction

This document is intended as a showcase of the mathematical abilities of eLyXer; for more information be sure to visit the main page.

1.1 Versions

There are several versions of this page:
All of them are generated from the same .lyx source file; they should help you decide which rendering options suit you best.
Also available online is the eLyXer translation of the latest LyX’s detailed Math manual, which contains a lot more examples of LyX maths.

2 Typography

Math formulae use a lot of different symbols and fonts.

2.1 Greek Symbols

Greek symbols are very important in equations: \phi, \pi, \Xi. eLyXer offers a complete set in both upper case: \Gamma\ldots\Omega and lower case: \alpha\ldots\omega. Also the AMS italicized upper case: \varGamma\ldots\varOmega.

2.2 Math Symbols

eLyXer supports the whole set of math symbols in John D. Cook's list: \exists\partial\nabla\geq. It can also render a few more: \propto\times. You also get all symbols from Markus Kuhn's list: \bigodot\amalg.

2.3 Other Symbols

There are other symbols like arrows: \leftarrow\rightarrow, or geometrical shapes: \circ, \square. eLyXer offers limited support for them. You might also want to use financial symbols in formulae: \yen\euro\$.

2.4 Spacing

Equations look good when items are properly separated. The main separation is the Medium Mathematical Space: x=3. Note: if you are viewing the non-Unicode version math.html of this page then you are in fact seeing midspaces, which are very similar but not exactly the same: \frac{4}{18}\mathrm{em} for medium mathematical spaces versus \frac{1}{2}\mathrm{en}, where 1\mathrm{em}=2\mathrm{en}. Try out the Unicode version math-unicode.html — and viceversa. You can check out what version this page is in the page title.
The command \raisebox is useful to, surprisingly, raise a little box,

\raisebox{2mm}{raised}over\raisebox{-2mm}{lowered}\textrm{and back}.
Like \mbox, it puts its content in a text box. It can also be used just for spacing:
\raisebox{5mm}{}B^{V}.
There are other spacing commands: \hspace: a\hspace{4mm}b, protected space: a\ b, and (at “block level”) \vspace: a\vspace{1cm}b.
There should be 1 cm of vertical space above this paragraph.

2.5 Fonts

By default, letters denote variables and are taken from the \mathnormal font, which is italic, \alpha x+\alpha y=\alpha(x+y), with the exception of upright capital Greek letters, G\ne\Gamma.
Function names should be upright: \sin(2\pi),\log(x),\tan\delta.
Mathematical fonts used in equations include \mathrm{Roman} (\mathrm), \mathsf{Sans\: Serif} (\mathsf), \mathtt{Typewriter} (\mathtt), \mathbf{Bold} (\mathbf), \mathscr{SCRIPT} (\mathscr), \mathcal{CALLIGRAPHIC} (\mathcal), \mathbb{BLACKBOARD\: BOLD} (\mathbb), and \mathfrak{Fraktur} (\mathfrak). For the latter, some single characters are translated to their Unicode equivalents: \mathscr{F}, \mathbb{F}, \mathfrak{F}.
Regular text in a formula can be achieved via text font commands like \textrm: 5\:\textrm{to}\:10, via boxes like \mbox (prevents line breaks): 6\mbox{ is more than }5, or the AMSmath \text macro (scales like math symbols) \text{base}_{\text{sub}}^{\text{super}}. The content of an mbox is processed in LaTeX text mode. This allows text font commands, e.g. a switch to sans-serif-bold-italic, or the phonetic alphabet: \mbox{\textbf{\textsf{\textbf{\textit{sfbfit}}}}, \textipa{tipa}}.
Units should be written upright, either with \mathrm or with macros from the units package, e.g. as simple unit, \unit{km}, with magnitude, \unit[57]{km}, with fractional unit, \unitfrac[200]{km}{h}, or with a fraction before the units, \unit[\nicefrac{3}{2}]{km}, \unit[\frac{7}{16}]{s}.

3 Numeration

Equations can be numbered, like () And also like (↓). Some equations can be numbered even if they don’t have a label.
Notice that equation () comes after ().

4 Simple Structures

Let’s now see a few of the simpler structures that eLyXer can output.

4.1 Fractions

A simple fraction:

\frac{1}{2}.
Inlined: \frac{2}{3}.
A big recursive fraction:

\frac{1}{\left(1+\left(\frac{1}{1+\left(\frac{1}{1+2x}\lyxlock\right)}\lyxlock\right)\right)}\lyxlock
A nice fraction: \nicefrac{5}{6}. A non-diminishing fraction containing alignments:

\cfrac{1}{1+\left(\cfrac[l]{1}{1+x}\times\cfrac[r]{1}{1+x}\right)}.
A similar concept is a binomial coefficient: \binom{A+1}{B}. It can be prettily presented:

\dbinom{A}{B+1}.
A symbol can be stacked over another using \stackrel: x\stackrel{R}{\rightarrow}y. Anything can be stacked:

d\stackrel{x>3}{\lim}x,\quad\stackrel{\mathrm{head}}{\mathrm{heels}}.

4.2 Limits

\lim_{x\rightarrow\infty}f(x) should appear as x\rightarrow\infty in italics, and «lim» in plain style. In display mode, a limit must appear below the main symbol:

\lim_{x\rightarrow\infty}\lyxlock f(x).
Limits are also used in sums and integrals:

\sum_{i=1}^{\infty}x,\;\int_{0}^{\infty}f(x)\,\mathrm{d}x
where the sum’s limits should appear below (i=1) and above (\infty) the \sum. The placement of the integral limits depends on the document class: LaTeX standard classes place them right to the \int. Limits are shown to the right in inline formulae: \sum_{i=1}^{\infty}x and \intop_{i=1}^{\infty}x.
The placing of limits can be configured with the \limits and \nolimits macros:

\lim\nolimits _{x\rightarrow\infty}\lyxlock f(x),\;\sum\nolimits _{i=1}^{\infty}x,\;\int\limits _{0}^{\infty}f(x)\,\mathrm{d}x

4.3 Roots

A square root: \sqrt{3}. A more complex root in a fraction:

\frac{1}{\left(1+\sqrt{2}\left(\frac{1}{1+\sqrt{2}}\lyxlock\right)+\sqrt{\frac{1}{2}}\right)}\lyxlock.
eLyXer can also do higher-order roots: \sqrt[3]{x+y}. A devilish case mixing everything we have seen so far:

\frac{\sqrt[\nicefrac{7}{8}]{\frac{8}{4}x}+\sum_{i=1}^{\infty}x}{\sqrt[s+5]{\frac{(78x+45y)\times\sqrt{\Omega}}{\sin(x+1)}+\unit[38]{km}}}\lyxlock.

5 Complex Structures

In this section we will explore arrays and related constructs.

5.1 Arrays

An inline array \left[\begin{array}{cc}
a & b\\
c & d\end{array}\right] is always shown in the same line. In display mode, the array is shown on its own line:

\left[\begin{array}{lc}
12 & 2\\
3 & 4\times y^{x}\end{array}\right]
Apart from that the appearance should be the same.

5.2 Brackets

Arrays are separated by variable-size brackets: \left(\begin{array}{cc}
a & b\\
c & d\end{array}\right) \left[\begin{array}{cc}
a & b\\
c & d\end{array}\right] \left\{ \begin{array}{cc}
a & b\\
c & d\end{array}\right\} \left\langle \begin{array}{cc}
a & b\\
c & d\end{array}\right\rangle \left|\begin{array}{cc}
a & b\\
c & d\end{array}\right|which might also differ on right and left \left(\begin{array}{cc}
a & b\\
c & d\end{array}\right) or use the empty opening \left\{ \begin{array}{cc}
a & b\\
c & d\end{array}\right. or closing: \left.\begin{array}{cc}
a & b\\
c & d\end{array}\right|. There are also fixed-size big brackets, e.g. \bigl\langle f\bigr\rangle.

5.3 Cases

Used to switch between several values.

y=\begin{cases}
x & i=0,\\
x+1 & i<3\end{cases}
Cases may have more than two rows:

f(x)=\begin{cases}
0 & x<0,\\
\infty & x=0\\
0 & x>0\end{cases}

5.4 Braces

Values can be underbraced or overbraced.
\underbrace{a-b}=\overbrace{b+c+d+e}.

6 Macros

Now it’s time for user-defined commands (sometimes called “macros”).
Definitions can be added as macros. Then they can be used in formulae: \stupidroot 12. They can accept default parameters. Again, useful in formulae: \defaultroot.
Other definitions from the preamble can be used: \preambleroot{3}{4}.
Definitions on the fly are also possible: \newcommand{\ontheflyroot}[2]{\sqrt[#1]{#2}}\ontheflyroot{7}{8}, and used with different values: \ontheflyroot{a}{b}.
elyxer-1.2.5/docs/math-mathjax-local.html0000644000175000017500000005500112117174760017635 0ustar chennochenno eLyxer Math Showcase (MathJax local edition)

figure elyxer.png eLyXer Math Showcase

Alex Fernández (elyxer@gmail.com)

1 Introduction

This document is intended as a showcase of the mathematical abilities of eLyXer; for more information be sure to visit the main page.

1.1 Versions

There are several versions of this page:
All of them are generated from the same .lyx source file; they should help you decide which rendering options suit you best.
Also available online is the eLyXer translation of the latest LyX’s detailed Math manual, which contains a lot more examples of LyX maths.

2 Typography

Math formulae use a lot of different symbols and fonts.

2.1 Greek Symbols

Greek symbols are very important in equations: , , . eLyXer offers a complete set in both upper case: and lower case: . Also the AMS italicized upper case: .

2.2 Math Symbols

eLyXer supports the whole set of math symbols in John D. Cook's list: . It can also render a few more: . You also get all symbols from Markus Kuhn's list: .

2.3 Other Symbols

There are other symbols like arrows: , or geometrical shapes: , . eLyXer offers limited support for them. You might also want to use financial symbols in formulae: .

2.4 Spacing

Equations look good when items are properly separated. The main separation is the Medium Mathematical Space: . Note: if you are viewing the non-Unicode version math.html of this page then you are in fact seeing midspaces, which are very similar but not exactly the same: for medium mathematical spaces versus , where . Try out the Unicode version math-unicode.html — and viceversa. You can check out what version this page is in the page title.
The command \raisebox is useful to, surprisingly, raise a little box, Like \mbox, it puts its content in a text box. It can also be used just for spacing:
.
There are other spacing commands: \hspace: , protected space: , and (at “block level”) \vspace: .
There should be 1 cm of vertical space above this paragraph.

2.5 Fonts

By default, letters denote variables and are taken from the \mathnormal font, which is italic, , with the exception of upright capital Greek letters, .
Function names should be upright: .
Mathematical fonts used in equations include (\mathrm), (\mathsf), (\mathtt), (\mathbf), (\mathscr), (\mathcal), (\mathbb), and (\mathfrak). For the latter, some single characters are translated to their Unicode equivalents: , , .
Regular text in a formula can be achieved via text font commands like \textrm: , via boxes like \mbox (prevents line breaks): , or the AMSmath \text macro (scales like math symbols) . The content of an mbox is processed in LaTeX text mode. This allows text font commands, e.g. a switch to sans-serif-bold-italic, or the phonetic alphabet: .
Units should be written upright, either with \mathrm or with macros from the units package, e.g. as simple unit, , with magnitude, , with fractional unit, , or with a fraction before the units, , .

3 Numeration

Equations can be numbered, like () And also like (↓). Some equations can be numbered even if they don’t have a label.
Notice that equation () comes after ().

4 Simple Structures

Let’s now see a few of the simpler structures that eLyXer can output.

4.1 Fractions

A simple fraction: Inlined:
A big recursive fraction:
A nice fraction: . A non-diminishing fraction containing alignments:
A similar concept is a binomial coefficient: It can be prettily presented:
A symbol can be stacked over another using \stackrel: . Anything can be stacked:

4.2 Limits

should appear as in italics, and «lim» in plain style. In display mode, a limit must appear below the main symbol:
Limits are also used in sums and integrals: where the sum’s limits should appear below ( ) and above ( ) the . The placement of the integral limits depends on the document class: LaTeX standard classes place them right to the . Limits are shown to the right in inline formulae: and
The placing of limits can be configured with the \limits and \nolimits macros:

4.3 Roots

A square root: A more complex root in a fraction:
eLyXer can also do higher-order roots: . A devilish case mixing everything we have seen so far:

5 Complex Structures

In this section we will explore arrays and related constructs.

5.1 Arrays

An inline array is always shown in the same line. In display mode, the array is shown on its own line: Apart from that the appearance should be the same.

5.2 Brackets

Arrays are separated by variable-size brackets: which might also differ on right and left or use the empty opening or closing: . There are also fixed-size big brackets, e.g. .

5.3 Cases

Used to switch between several values.
Cases may have more than two rows:

5.4 Braces

Values can be underbraced or overbraced.
.

6 Macros

Now it’s time for user-defined commands (sometimes called “macros”).
Definitions can be added as macros. Then they can be used in formulae: . They can accept default parameters. Again, useful in formulae: .
Other definitions from the preamble can be used: .
Definitions on the fly are also possible: , and used with different values: .
elyxer-1.2.5/docs/userguide-frameset.html0000644000175000017500000000031412074107030017743 0ustar chennochenno eLyXer User Guide elyxer-1.2.5/docs/userguide.lyx0000644000175000017500000032612612074107030016023 0ustar chennochenno#LyX 1.6.7 created this file. For more info see http://www.lyx.org/ \lyxformat 345 \begin_document \begin_header \textclass article \begin_preamble % eLyXer -- convert LyX source files to HTML output. % % Copyright (C) 2009-2011 Alex Fernández % % This program is free software: 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 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 % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . \end_preamble \use_default_options false \language english \inputencoding auto \font_roman default \font_sans default \font_typewriter default \font_default_family default \font_sc false \font_osf false \font_sf_scale 100 \font_tt_scale 100 \graphics default \paperfontsize default \spacing single \use_hyperref false \papersize default \use_geometry false \use_amsmath 1 \use_esint 1 \cite_engine basic \use_bibtopic false \paperorientation portrait \secnumdepth 3 \tocdepth 3 \paragraph_separation indent \defskip medskip \quotes_language english \papercolumns 1 \papersides 1 \paperpagestyle default \tracking_changes false \output_changes false \author "" \author "" \end_header \begin_body \begin_layout Title \begin_inset Graphics filename elyxer.svg lyxscale 50 \end_inset eLyXer User Guide \end_layout \begin_layout Author Alex Fernández (elyxer@gmail.com) \end_layout \begin_layout Standard \begin_inset CommandInset toc LatexCommand tableofcontents \end_inset \end_layout \begin_layout Section The Basics \end_layout \begin_layout Quotation \emph on elixir, n: a substance believed to cure all ills \begin_inset CommandInset citation LatexCommand cite key "wordreference-elixir" \end_inset . \end_layout \begin_layout Standard eLyXer (pronounced \emph on elixir \emph default ) is a LyX to HTML converter. While there are a ton of such projects all over the web, eLyXer has a clear focus on flexibility and elegant output. \end_layout \begin_layout Standard eLyXer (including this guide and all accompanying materials) is licensed under the \begin_inset CommandInset href LatexCommand href name "GPL version 3" target "http://www.gnu.org/licenses/gpl-3.0-standalone.html" \end_inset or, at your option, any later version. See the \family typewriter LICENSE \family default file for details. \end_layout \begin_layout Standard Please visit the \begin_inset CommandInset href LatexCommand href name "main page" target "index.html" \end_inset to find out about the latest developments. \end_layout \begin_layout Subsection System Requirements \end_layout \begin_layout Standard eLyXer requires Python 2.4. \begin_inset Formula $x$ \end_inset , and should work with versions up to 2.6. \begin_inset Formula $y$ \end_inset ; it will convert documents generated by LyX 1.5. \begin_inset Formula $x$ \end_inset to 2.0. It has been tested on the most common operating systems: on Mac OS X, Linux and Windows, with and without CygWin. \end_layout \begin_layout Standard Resource usage should be quite frugal; eLyXer runs quite happily on my 1st-gen Asus Eee, with its puny Celeron@570MHz and 512 MB of RAM. It should also be fast -- the Eee can convert ~200 pages of LyX text in just over 50 seconds. Performance is fairly linear: 200 pages take \begin_inset Formula $10\times$ \end_inset as long as 20, so there are no scalability problems. Memory usage stays low even when processing large documents, and conversion can be done on the fly (with \family typewriter --lowmem \family default ) for even lower memory requirements. \end_layout \begin_layout Subsection Installation \end_layout \begin_layout Standard This section looks at how to install eLyXer on your system, assuming that Python 2.4 to 2.6 is already there. \end_layout \begin_layout Subsubsection* Download eLyXer \end_layout \begin_layout Standard First you will need to fetch the official distribution file from the \begin_inset CommandInset href LatexCommand href name "download area" target "https://savannah.nongnu.org/files/?group=elyxer" \end_inset . Now, there is more than one way to install eLyXe, but all of them start by uncompressing the distributed file to a suitable directory. Just write at the command prompt: \end_layout \begin_layout LyX-Code \family typewriter \color blue $ \color inherit tar -xzf elyxer- \emph on [version] \emph default .tar.gz \end_layout \begin_layout Standard Or for the \family typewriter .zip \family default version: \end_layout \begin_layout LyX-Code \family typewriter \color blue $ \color inherit unzip elyxer- \emph on [version] \emph default .zip \end_layout \begin_layout Standard A directory called \family typewriter elyxer \family default should appear, where the main executable file \family typewriter elyxer.py \family default resides. \end_layout \begin_layout Subsubsection* Using the Installer \end_layout \begin_layout Standard An installer is provided in the root directory, called \family typewriter install.py \family default ; it is the recommended way to install eLyXer. To run it just type in a console as root: \end_layout \begin_layout LyX-Code \family typewriter \color blue # \color inherit python install.py \end_layout \begin_layout Standard On Windows you can type (as a regular user): \end_layout \begin_layout LyX-Code \family typewriter \color blue > \color inherit python.exe install.py \end_layout \begin_layout Standard In any case, the script will install eLyXer as a Python script. Now you can check if it was installed successfully: \end_layout \begin_layout LyX-Code \family typewriter \color blue $ \color inherit elyxer.py --help \end_layout \begin_layout Standard A brief help text and the list of command line options should appear. \end_layout \begin_layout Standard The installer will also copy existing translation files to your hard drive so that they can be used from within eLyXer for internationalization. \end_layout \begin_layout Subsubsection* Prepackaged Versions \end_layout \begin_layout Standard The easiest way to install eLyXer is if someone has prepackaged it for your system. Some Linux distributions include eLyXer: \begin_inset CommandInset href LatexCommand href name "Debian squeeze" target "http://packages.debian.org/squeeze/elyxer" \end_inset and \begin_inset CommandInset href LatexCommand href name "Ubuntu Lucid" target "http://packages.ubuntu.com/lucid/elyxer" \end_inset . Installation is done using apt-get or aptitude, for Debian as root: \end_layout \begin_layout LyX-Code \family typewriter \color blue # \color inherit apt-get install elyxer \end_layout \begin_layout Standard or, for Ubuntu: \end_layout \begin_layout LyX-Code \family typewriter \color blue $ \color inherit sudo aptitude install elyxer \end_layout \begin_layout Standard For both Debian and Ubuntu eLyXer needs to be run as \family typewriter "elyxer" \family default : \end_layout \begin_layout LyX-Code \family typewriter \color blue $ \color inherit elyxer --help \end_layout \begin_layout Standard On Windows, the \begin_inset CommandInset href LatexCommand href name "alternate LyX installer" target "http://wiki.lyx.org/Windows/LyXWinInstaller" \end_inset includes eLyXer in the default installation. See \begin_inset CommandInset ref LatexCommand ref reference "sub:LyX-Integration" \end_inset for LyX integration. \end_layout \begin_layout Subsubsection* Manual Installation \end_layout \begin_layout Standard If the installer did not work for you, you can manually install it as a module. On Linux go to the elyxer directory and type, as root: \end_layout \begin_layout LyX-Code \family typewriter \color blue # \color inherit python setup.py install \end_layout \begin_layout Standard On Windows just type: \end_layout \begin_layout LyX-Code \family typewriter \color blue > \color inherit python.exe setup.py install \end_layout \begin_layout Standard On Mac OS X you can use sudo to get the necessary permissions: \end_layout \begin_layout LyX-Code \family typewriter \color blue % \color inherit sudo python setup.py install \end_layout \begin_layout Standard Now you can run eLyXer as a Python script: \end_layout \begin_layout LyX-Code \family typewriter \color blue $ \color inherit elyxer.py --help \end_layout \begin_layout Standard The list of command line options should appear. You can also manually copy the file \family typewriter elyxer.py \family default to a directory found in the execution path (for instance, \family typewriter /usr/bin \family default on Linux or \family typewriter c: \backslash windows \backslash system32 \family default on Windows). \end_layout \begin_layout Subsection Test Drive \end_layout \begin_layout Standard Now you may want to try to convert the user guide: \end_layout \begin_layout LyX-Code \family typewriter \color blue $ \color inherit elyxer.py --css lyx.css --title "eLyXer User Guide" docs/userguide.lyx docs/usergu ide2.html \end_layout \begin_layout Standard It should generate a working web page identical to the one distributed: \end_layout \begin_layout LyX-Code \family typewriter \color blue $ \color inherit diff docs/userguide.html docs/userguide2.html \end_layout \begin_layout Standard The typical output will contain just the changed lines, which in this case should be only the header with the file creation date. An example is shown on listing \begin_inset CommandInset ref LatexCommand ref reference "alg:diff" \end_inset . \end_layout \begin_layout Standard \begin_inset Float algorithm wide false sideways false status open \begin_layout Quotation \family typewriter 7c7 \end_layout \begin_layout Quotation \family typewriter < \end_layout \begin_layout Quotation \family typewriter --- \end_layout \begin_layout Quotation \family typewriter > \end_layout \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout \begin_inset CommandInset label LatexCommand label name "alg:diff" \end_inset Example of \family typewriter diff \family default output for functionally identical HTML files. \end_layout \end_inset \end_layout \end_inset \end_layout \begin_layout Standard If nothing else appears (i.e. both files are functionally equal) then everything is working fine. If you have \family typewriter bash \family default installed, to test that everything \emph on really \emph default works fine you can just run the included tests: \end_layout \begin_layout LyX-Code \family typewriter \color blue $ \color inherit ./run-tests \end_layout \begin_layout Standard It will run a number of test and check the results, so you can see if everything is well. You also need to have installed the command-line tool \family typewriter diff \family default to show differences between two files. \end_layout \begin_layout Subsection Usage \end_layout \begin_layout Standard eLyXer is a standalone command line tool. It can be invoked from the command line as: \end_layout \begin_layout LyX-Code \family typewriter \color blue $ \color inherit elyxer.py [options] [source file] [destination file] \end_layout \begin_layout Standard If the source file is omitted then \family typewriter STDIN \family default is used; likewise, if no destination file is specified eLyXer will output to \family typewriter STDOUT \family default . This allows its use in pipes and other flexible configurations. Some examples: \end_layout \begin_layout LyX-Code \family typewriter \color blue $ \color inherit elyxer.py file.lyx file.html \end_layout \begin_layout Standard converts \family typewriter file.lyx \family default to \family typewriter file.html \family default . Debug messages are shown. \end_layout \begin_layout LyX-Code \family typewriter \color blue $ \color inherit cat file.lyx | elyxer.py > file.html \end_layout \begin_layout Standard converts \family typewriter file.lyx \family default to \family typewriter file.html \family default , as before. This time debug messages are not shown. \end_layout \begin_layout LyX-Code \family typewriter \color blue $ \color inherit elyxer.py file.lyx | grep "
" | wc \end_layout \begin_layout Standard counts all blockquote paragraphs. \end_layout \begin_layout LyX-Code \family typewriter \color blue $ \color inherit elyxer.py file.lyx | wget --no-check-certificate --spider -nv -F -i - \end_layout \begin_layout Standard checks all external links in a document recursively. (Local links will appear as unresolved, but they can be ignored.) \end_layout \begin_layout Subsection Image Processing \end_layout \begin_layout Standard eLyXer does not convert images directly; it uses the \begin_inset CommandInset href LatexCommand href name "ImageMagick" target "http://www.imagemagick.org/" \end_inset package, in particular the \family typewriter convert \family default tool, to create PNG versions of the images embedded in the original LyX documents, and then it inserts links to those PNG images in the resulting HTML pages. If ImageMagick is not installed eLyXer will show an error message and will not try to convert further images. \end_layout \begin_layout Standard HTML pages, unlike PDF documents, do not contain images in the document file; rather they contain pointers to image locations on disk. (Fortunately, LyX documents do not contain images either.) eLyXer will generate pages that point to the same locations as the original images, when they are PNG images, or to the converted versions otherwise. Image types like Encapsulated PostScript cannot be used directly from within pages. \end_layout \begin_layout Standard Image location is fragile. All images should be placed in the same location (and with the same structure) as the original document; and they should all be referenced relatively to the current document. During conversion from within LyX image locations can be lost, since LyX does not do in-place conversion; instead, LyX copies the original file to a temporary directory, converts the file and then copies everything back to a directory ending in \family typewriter .LyXconv \family default . \end_layout \begin_layout Subsection \begin_inset CommandInset label LatexCommand label name "sub:LyX-Integration" \end_inset LyX Integration \end_layout \begin_layout Standard If you used the eLyXer installer LyX will automatically detect it after reconfiguration. Just make sure that you are running LyX 1.6.5 or later, and click on Tools\SpecialChar \menuseparator Reconfi gure. \end_layout \begin_layout Standard LyX should be able to detect if eLyXer was installed as a script, or even if it has been installed from a Linux distribution. In any case you can verify that it has been recognized by LyX by opening Tools\SpecialChar \menuseparator Preferences\SpecialChar \ldots{} , going to External formats\SpecialChar \menuseparator Converters, and finding the converter for \begin_inset Quotes eld \end_inset LyX -> HTML \begin_inset Quotes erd \end_inset . If eLyXer is there, it worked! Now you can convert your documents using View\SpecialChar \menuseparator HTML. Otherwise try to reinstall eLyXer from scratch and then reconfigure LyX. \end_layout \begin_layout Subsubsection* Installing as a Package or as a Module \end_layout \begin_layout Standard Versions of the eLyXer installer prior to 1.2.0 tried to install eLyXer as a module, so it could be run using \family typewriter "python -m elyxer" \family default . This option is deprecated since a module called \family typewriter elyxer \family default would collide with a Python package of the same name, and there are plans to install eLyXer as a proper Python package in the future (probably in the 1.3.0 time frame). In the interim eLyXer is installed only as a script called \family typewriter elyxer.py \family default . \end_layout \begin_layout Standard LyX (starting with versions 2.0.0 and 1.6.9) has been patched to recognize only the script and disregard the module. \end_layout \begin_layout Section Advanced Use \end_layout \begin_layout Standard There are some advanced uses for eLyXer if you want to extract the most of it. \end_layout \begin_layout Subsection Command Line Options \end_layout \begin_layout Standard eLyXer supports a few command line options: \end_layout \begin_layout Description \family typewriter --help \family default : Show command line help. \end_layout \begin_layout Description \family typewriter --quiet \family default : Be quiet and do not output messages (except errors). This way you can avoid the comforting \begin_inset Quotes eld \end_inset Parsing line 1000 \begin_inset Quotes erd \end_inset messages. When STDIN or STDOUT are used (e.g. in a pipeline) \family typewriter --quiet \family default is always enabled. \end_layout \begin_layout Subsubsection* Advanced Options \end_layout \begin_layout Description \family typewriter --debug \family default : Show debug messages. They may help a developer understand your problem. \end_layout \begin_layout Description \family typewriter --version \family default : Show version number and date. Use to check which version you are actually running. \end_layout \begin_layout Description \family typewriter --lyxformat \family default : Return the highest LyX version that eLyXer understands. This parameter is provided to help with \family typewriter lyx2lyx \family default integration, so that this tool knows if it must convert the file to a lower LyX format. \end_layout \begin_layout Subsubsection* Options to Control HTML output \end_layout \begin_layout Description \family typewriter --title \begin_inset space ~ \end_inset \series bold " \series default title \series bold " \family default \series default : Change the title of the generated web page. \end_layout \begin_layout Description \family typewriter --css \begin_inset space ~ \end_inset \series bold " \series default new.css \series bold " \family default \series default : Change default CSS. See section \begin_inset CommandInset ref LatexCommand ref reference "sub:CSS" \end_inset : CSS. \end_layout \begin_layout Description \family typewriter --embedcss \begin_inset space ~ \end_inset \series bold " \series default file.css \series bold " \family default \series default : Embed the styles in \family typewriter file.css \family default into the resulting HTML document. See section \begin_inset CommandInset ref LatexCommand ref reference "sub:CSS" \end_inset : CSS. \end_layout \begin_layout Description \family typewriter --html \family default : Generate HTML 4.0 (instead of XHTML). The resulting pages should be easier to import from certain word processors. See section \begin_inset CommandInset ref LatexCommand ref reference "sub:HTML-Code" \end_inset : HTML code. \end_layout \begin_layout Description \family typewriter --unicode \family default : Restore full Unicode output. Right now switches midspaces to medium mathematical spaces. See also section \begin_inset CommandInset ref LatexCommand ref reference "sub:HTML-Code" \end_inset : HTML code. \end_layout \begin_layout Description \family typewriter --iso885915 \family default : Generate a document using ISO-8859-1 encoding. Again, see section \begin_inset CommandInset ref LatexCommand ref reference "sub:HTML-Code" \end_inset : HTML code. \end_layout \begin_layout Description \family typewriter --nofooter \family default : Omit the footer message \begin_inset Quotes eld \end_inset Document generated by eLyXer \begin_inset Quotes erd \end_inset (shown at the bottom). \end_layout \begin_layout Subsubsection* Options to Control image output \end_layout \begin_layout Description \family typewriter --directory \begin_inset space ~ \end_inset "images_dir" \family default : Look for images in the directory specified. \end_layout \begin_layout Description \family typewriter --destdirectory \begin_inset space ~ \end_inset "dest_dir" \family default : Converted images will end up into this directory. \end_layout \begin_layout Description \family typewriter --imageformat \begin_inset space ~ \end_inset ".extension" \family default : Force the format implied by the extension (e.g. \family typewriter ".jpg" \family default for JPEG) for output images. Use \family typewriter --imageformat "copy" \family default to make images be copied over instead of converted. \end_layout \begin_layout Description \family typewriter --converter \begin_inset space ~ \end_inset \series bold "program" \family default \series default : \family typewriter \family default Use the given program to convert images. Right now the supported converters are: \family typewriter \series bold imagemagick \family default \series default (default), \family typewriter \series bold inkscape \family default \series default and \family typewriter \series bold lyx \family default \series default itself. With \family typewriter --converter inkscape \family default eLyXer picks Inkscape as the image converter (Inkscape uses some non-standard extensions so it might be needed to convert SVG images to PNG); with \family typewriter --converter lyx \family default the new LyX option \family typewriter lyx -C \family default is used. You can also supply your own converter command line, using \family typewriter $input \family default and \family typewriter $output \family default as variables (note the single quotes): \end_layout \begin_layout LyX-Code \family typewriter \color blue $ \color inherit elyxer.py --converter 'lyx -C $input $output' [source file] [destination file] \end_layout \begin_layout Description \family typewriter --noconvert \family default : Use all images in their original location and do not convert anything. Useful when using images which do not convert well, such as SVG files. \end_layout \begin_layout Subsubsection* Options to Control footnote output \end_layout \begin_layout Description \family typewriter --numberfoot \family default : Number all footnotes using numbers: \begin_inset Quotes eld \end_inset [1] \begin_inset Quotes erd \end_inset , instead of the default \begin_inset Quotes eld \end_inset [A] \begin_inset Quotes erd \end_inset . \end_layout \begin_layout Description \family typewriter --symbolfoot \family default : mark footnotes with symbols (*, **, †, ‡\SpecialChar \ldots{} ). \end_layout \begin_layout Description \family typewriter --hoverfoot \family default : show footnotes as hovering text. This is the default position. \end_layout \begin_layout Description \family typewriter --marginfoot \family default : show footnotes with numbers instead of letters. \end_layout \begin_layout Description \family typewriter --endfoot \family default : show footnotes at the end of the page. \end_layout \begin_layout Description \family typewriter --supfoot \family default : use superscript for footnote markers. This is the default style. \end_layout \begin_layout Description \family typewriter --alignfoot \family default : use aligned text for footnote markers, instead of superscript. \end_layout \begin_layout Description \family typewriter --footnotes \begin_inset space ~ \end_inset "options" \family default : specify several footnotes options at the same time, separated with commas. Available options are: "number", "hover", "margin", "end". See section \begin_inset CommandInset ref LatexCommand ref reference "sub:Footnotes" \end_inset : Footnotes. \end_layout \begin_layout Subsubsection* Advanced Options to Control HTML output \end_layout \begin_layout Description \family typewriter --splitpart \begin_inset space ~ \end_inset \series bold " \series default depth \series bold " \family default \series default : Split the resulting webpage at the given depth. See section \begin_inset CommandInset ref LatexCommand ref reference "sub:Segmenting-Pages" \end_inset : Segmenting Pages. \end_layout \begin_layout Description \family typewriter --tocfor \begin_inset space ~ \end_inset \series bold " \series default original.html \series bold " \family default \series default : Generate just a table of contents with links to the original HTML file. See section \begin_inset CommandInset ref LatexCommand ref reference "sub:TOC" \end_inset : TOC. \end_layout \begin_layout Description \family typewriter --target \begin_inset space ~ \end_inset \series bold " \series default frame \series bold " \family default \series default : Add a \family typewriter target \family default attribute to every link in the generated HTML, making all links point to the provided frame. Again, see section \begin_inset CommandInset ref LatexCommand ref reference "sub:TOC" \end_inset : TOC. \end_layout \begin_layout Description \family typewriter --notoclabels \family default : Omit \begin_inset Quotes eld \end_inset Chapter \begin_inset Quotes erd \end_inset , \begin_inset Quotes eld \end_inset Part \begin_inset Quotes erd \end_inset and similar labels from the TOC; just output part numbers (and separate using a period). For instance, a chapter that without this option is labeled \begin_inset Quotes eld \end_inset Chapter 2: Advanced Use \begin_inset Quotes erd \end_inset in the TOC would now become \begin_inset Quotes eld \end_inset 2. Advanced Use \begin_inset Quotes erd \end_inset , as on the PDF. Option adapted from the wish list: \begin_inset CommandInset ref LatexCommand ref reference "sub:Wish-List" \end_inset . \end_layout \begin_layout Description \family typewriter --lowmem \family default : Activate a low memory mode which does not keep the whole document in memory: conversion is done on the fly. Keep in mind that some features as the TOC will be missing from the generated document. \end_layout \begin_layout Description \family typewriter --numberfoot \family default : \family typewriter \family default Label footnotes using numbers, instead of letters. Useful when bibliographical references are not numbered and therefore cannot be confused with footnotes. \end_layout \begin_layout Description \family typewriter --raw \family default : Generate an HTML page without header or footer. \end_layout \begin_layout Description \family typewriter --mathjax \begin_inset space ~ \end_inset \series bold remote \family default \series default : Use the excellent JavaScript library \begin_inset CommandInset href LatexCommand href name "MathJax" target "http://www.mathjax.org/" \end_inset remotely to pretty-print mathematical equations. See section \begin_inset CommandInset ref LatexCommand ref reference "sub:Math" \end_inset . \end_layout \begin_layout Description \family typewriter --mathjax \begin_inset space ~ \end_inset \series bold " \series default URL \series bold " \family default \series default : Use the excellent JavaScript library \begin_inset CommandInset href LatexCommand href name "MathJax" target "http://www.mathjax.org/" \end_inset at the given URL (usually a local URL is used). See also section \begin_inset CommandInset ref LatexCommand ref reference "sub:Math" \end_inset . \end_layout \begin_layout Description \family typewriter --googlecharts \family default : Use \begin_inset CommandInset href LatexCommand href name "Google Charts" target "http://code.google.com/apis/chart/index.html" \end_inset to generate images for every formula. Again, see \begin_inset CommandInset ref LatexCommand ref reference "sub:Math" \end_inset . \end_layout \begin_layout Description \family typewriter --simplemath \family default : Do not generate fancy math structures such as multi-line Unicode brackets or stacked limits. This option is automatically activated when \family typewriter --html \family default is selected; once more see section \begin_inset CommandInset ref LatexCommand ref reference "sub:Math" \end_inset . \end_layout \begin_layout Description \family typewriter --template \begin_inset space ~ \end_inset \series bold " \series default file \series bold " \family default \series default : Use an HTML template. The raw converted document will be placed where \family typewriter \family default appears in the template. Available variables: \family typewriter \family default , \family typewriter \family default , \family typewriter \family default , \family typewriter \family default , \family typewriter \family default , \family typewriter \family default , \family typewriter \family default , \family typewriter \family default , \family typewriter \family default , \family typewriter \family default , \family typewriter \family default , \family typewriter \family default . \end_layout \begin_layout Description \family typewriter --copyright \family default : Include a copyright notice at the bottom. \end_layout \begin_layout Subsubsection* Deprecated Options \end_layout \begin_layout Description \family typewriter --toc \family default : Generate just a table of contents. Use \family typewriter --tocfor \family default instead. \end_layout \begin_layout Description \family typewriter --toctarget \begin_inset space ~ \end_inset \series bold " \series default original.html \series bold " \family default \series default : Generate a table of contents with links to the original HTML file. Use \family typewriter --tocfor \family default instead. \end_layout \begin_layout Description \family typewriter --nocopy \family default : No effect since the copyright notice is now optional, maintained for backwards compatibility. \end_layout \begin_layout Standard When an option accepts an argument it can be added after a space as \family typewriter --target \begin_inset space ~ \end_inset \series bold " \series default frame \series bold " \family default \series default , or with an equals sign as in \family typewriter --target= \series bold " \series default frame \series bold " \family default \series default . The quotes are optional and can be useful if your arguments include e.g. spaces. \end_layout \begin_layout Subsubsection* Adding Options In LyX \end_layout \begin_layout Standard To add one of these options so that it is used from within LyX, you have to modify the converter line. To this effect open Tools\SpecialChar \menuseparator Preferences\SpecialChar \ldots{} , go to External formats\SpecialChar \menuseparator Converters, find the converter for \begin_inset Quotes eld \end_inset LyX -> HTML \begin_inset Quotes erd \end_inset and edit the converter line. It should read something like this: \end_layout \begin_layout LyX-Code \family typewriter elyxer.py --directory $$r $$i $$o \end_layout \begin_layout Standard If you want to generate pure HTML instead of XHTML, change the line to: \end_layout \begin_layout LyX-Code \family typewriter elyxer.py \family default \series bold --html \family typewriter \series default --directory $$r $$i $$o \end_layout \begin_layout Standard And so on. Figure 1 shows what to do to add the \family typewriter --html \family default option: after editing the line and adding the new option, click on \begin_inset Quotes eld \end_inset Modify \begin_inset Quotes erd \end_inset and then \begin_inset Quotes eld \end_inset Save \begin_inset Quotes erd \end_inset or \begin_inset Quotes eld \end_inset Apply \begin_inset Quotes erd \end_inset the changes. \begin_inset Marginal status open \begin_layout Plain Layout You should never remove the \family typewriter $$i $$o \family default at the end, since it is what tells eLyXer where to find the input and output files. \end_layout \end_inset \end_layout \begin_layout Standard \begin_inset Float figure wide false sideways false status open \begin_layout Plain Layout \align center \begin_inset Graphics filename converters.png \end_inset \end_layout \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout eLyXer converter in LyX 1.6.5. \end_layout \end_inset \end_layout \begin_layout Plain Layout \end_layout \end_inset \end_layout \begin_layout Standard LyX 1.6.5 supports a new \begin_inset Quotes eld \end_inset extra flag \begin_inset Quotes erd \end_inset line; however, at this moment it does not work with eLyXer. \end_layout \begin_layout Subsection CSS \begin_inset CommandInset label LatexCommand label name "sub:CSS" \end_inset \end_layout \begin_layout Standard HTML output, as generated, can fall short in certain situations. Some CSS wizardry can go a long way to customize eLyXer. \end_layout \begin_layout Standard eLyXer tags most elements with the type so you can later modify them using a CSS. The default HTML header is similar to listing \begin_inset CommandInset ref LatexCommand ref reference "alg:CSS" \end_inset , so the default remote CSS file is used. \end_layout \begin_layout Standard \begin_inset Float algorithm wide false sideways false status open \begin_layout Quotation \family typewriter \end_layout \begin_layout Quotation \family typewriter [...] \end_layout \begin_layout Quotation \family typewriter \series bold \end_layout \begin_layout Quotation \family typewriter Your title here \end_layout \begin_layout Quotation \family typewriter \end_layout \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout \begin_inset CommandInset label LatexCommand label name "alg:CSS" \end_inset CSS link automatically added to HTML \end_layout \end_inset \end_layout \end_inset \end_layout \begin_layout Standard This sample CSS file is published on nongnu.org and distributed along with the scripts, \family typewriter docs/lyx.css \family default . (You may have found that your document shows minor changes in its appearance with time -- this is the reason. The main author regularly publishes a new, updated version of \family typewriter lyx.css \family default on nongnu.org, and all documents using it automatically appear with the changes. Backwards compatibility is maintained as much as possible.) \end_layout \begin_layout Standard To give your document a customized appearance (or for pages to be accessible offline) you probably will want to use your own CSS file; to use it first copy it to the directory where your document resides (e.g. renaming it to \family typewriter custom.css \family default ), and customize as needed. Then run \family typewriter elyxer.py \family default with the following option: \end_layout \begin_layout LyX-Code \family typewriter \color blue $ \color inherit elyxer.py --css=custom.css document.lyx page.html \end_layout \begin_layout Standard This will make the generated \family typewriter page.html \family default use your \family typewriter custom.css \family default file. The \family typewriter `=' \family default sign between the constant \family typewriter `--css' \family default and the name of the CSS file is optional. More than one \family typewriter --css \family default option can be added if you want several CSS files to be used in the header. \end_layout \begin_layout Standard Sometimes the styles in a CSS are needed in the HTML document (for offline viewing, or to distribute as stand-alone pages). For these uses there is the option \family typewriter --embedcss \family default : the styles contained in the CSS file passed as an argument will be embedded in the resulting HTML document. For instance: \end_layout \begin_layout LyX-Code \family typewriter \color blue $ \color inherit elyxer.py --embedcss custom.css document.lyx page.html \end_layout \begin_layout Standard This command generates a document \family typewriter page.html \family default where the styles in \family typewriter custom.css \family default are embedded. The CSS to embed must be a file, not a remote URL. Listing \begin_inset CommandInset ref LatexCommand ref reference "alg:embed-CSS" \end_inset shows the resulting HTML header for a test CSS with just one style, \family typewriter div.Standard \family default . Note that the remote CSS is still added by default; to avoid it just add an option with an empty CSS file, \family typewriter --css="" \family default . \end_layout \begin_layout Standard \begin_inset Float algorithm wide false sideways false status open \begin_layout Quotation \family typewriter \end_layout \begin_layout Quotation \family typewriter [...] \end_layout \begin_layout Quotation \family typewriter \end_layout \begin_layout Quotation \family typewriter \end_layout \begin_layout Quotation \family typewriter \series bold \end_layout \begin_layout Quotation \family typewriter Your title here \end_layout \begin_layout Quotation \family typewriter \end_layout \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout \begin_inset CommandInset label LatexCommand label name "alg:embed-CSS" \end_inset CSS embedded into the HTML \end_layout \end_inset \end_layout \end_inset \end_layout \begin_layout Standard As with the \family typewriter --css \family default option, several \family typewriter --embedcss \family default options can be added to embed more than one file. \end_layout \begin_layout Standard The CSS file for eLyXer uses some CSS2 features for math structures (fractions, arrays). This makes the output incompatible with older browsers; it requires Microsoft Internet Explorer 7, Firefox 3, Safari 3 or Chrome 1. Check the \begin_inset CommandInset href LatexCommand href name "Math Showcase" target "math.html" \end_inset to see if your browser can render eLyXer output correctly. \end_layout \begin_layout Subsection Title \end_layout \begin_layout Standard By default the generated web pages have the title \begin_inset Quotes eld \end_inset Converted Document \begin_inset Quotes erd \end_inset . If a PDF title is found then it is used instead. The proper LyX title (a paragraph of type \begin_inset Quotes eld \end_inset Title \begin_inset Quotes erd \end_inset embedded in the text) will also be used if found. But when \family typewriter --lowmem \family default is in use eLyXer does not try to get the proper title, since it may be found in the middle of the document or not be present at all; scanning for it would mean doing two passes, one to look for the title in all the document and another to output the web page, and \family typewriter --lowmem \family default implies on-the-fly conversion to save memory. \end_layout \begin_layout Standard You can change the title of the generated web page with the \family typewriter --title \family default option: \end_layout \begin_layout LyX-Code \family typewriter \color blue $ \color inherit elyxer.py --title "My Beautiful Document" document.lyx page.html \end_layout \begin_layout Subsection Table Of Contents \begin_inset CommandInset label LatexCommand label name "sub:TOC" \end_inset \end_layout \begin_layout Standard A table of contents (or TOC) can be generated for every converted LyX document. You can optionally also add a target frame to every link. The trick is to combine both options to generate a TOC that links to the original document on a different frame. For example, if the original page is called \family typewriter page.html \family default and you generated it with this command: \end_layout \begin_layout LyX-Code \family typewriter \color blue $ \color inherit elyxer.py document.lyx page.html \end_layout \begin_layout Standard you can generate the TOC linking to this page, and at the same time point it to frame \family typewriter contents \family default : \end_layout \begin_layout LyX-Code \family typewriter \color blue $ \color inherit elyxer.py --tocfor page.html --target contents document.lyx page-toc.html \end_layout \begin_layout Standard Then you can put it all together with a simple frameset generated manually. Just remember to place the original document in the frame called \family typewriter contents \family default . \end_layout \begin_layout Standard \begin_inset Float algorithm wide false sideways false status open \begin_layout Plain Layout \family typewriter \end_layout \begin_layout Plain Layout \family typewriter \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \end_layout \begin_layout Plain Layout \family typewriter \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \end_layout \begin_layout Plain Layout \family typewriter \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \end_layout \begin_layout Plain Layout \family typewriter \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \end_layout \begin_layout Plain Layout \family typewriter \end_layout \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout \begin_inset CommandInset label LatexCommand label name "alg:frameset" \end_inset An example frameset for TOC navegation \end_layout \end_inset \end_layout \end_inset \end_layout \begin_layout Standard TOC generation accepts the same options as normal document conversion. For example, if you follow these instructions literally you will notice that the TOC has very wide margins and looks a bit weird; that is because it is using the default CSS. A special CSS file for TOC files is provided in \family typewriter docs/toc.css \family default , so better results should be obtained with the \family typewriter --css \family default option: \end_layout \begin_layout LyX-Code \family typewriter \color blue $ \color inherit elyxer.py --tocfor page.html --css docs/toc.css --target contents document.lyx page-toc.html \end_layout \begin_layout Standard With a little bit of practice you will be able to generate useful (and nice looking) TOC files. You can see an example for the \begin_inset CommandInset href LatexCommand href name "user guide" target "userguide-frameset.html" \end_inset (if you are not already looking at it). \end_layout \begin_layout Subsection Segmenting Pages \begin_inset CommandInset label LatexCommand label name "sub:Segmenting-Pages" \end_inset \end_layout \begin_layout Standard Quite often you don't want a huge monolithic page, but a set of linked pages. To do so you can use the \family typewriter --splitpart \family default option, specifying the level at which eLyXer should split pages. For instance: \end_layout \begin_layout LyX-Code \family typewriter \color blue $ \color inherit elyxer.py --splitpart 1 document.lyx output.html \end_layout \begin_layout Standard will split \family typewriter document.lyx \family default into pages at level 1, using \family typewriter output.html \family default as the root page. Each page will get a number that starts with \family typewriter output \family default and ends with \family typewriter .html \family default , with a suffix that depends on the page -- \family typewriter output-2.html \family default will correspond to the second split part. \end_layout \begin_layout Standard The level corresponding to 1 depends on the document class: books will be split at chapters, but articles will get a section per page. And so on with lower levels. \end_layout \begin_layout Subsection HTML Code \begin_inset CommandInset label LatexCommand label name "sub:HTML-Code" \end_inset \end_layout \begin_layout Standard The HTML code generated is technically XHTML Transitional, version 1.0 \begin_inset CommandInset citation LatexCommand cite key "xhtml" \end_inset , using UTF-8 encoding. Some programs have (in this day and age) trouble importing XHTML, notably some popular word processors. To work around this problem and provide more flexible output in general you can output HTML 4.0: \end_layout \begin_layout LyX-Code \family typewriter \color blue $ \color inherit elyxer.py --html document.lyx page-to-import.html \end_layout \begin_layout Standard Again, technically the code generated is HTML 4.01 Transitional \begin_inset CommandInset citation LatexCommand cite key "html-401" \end_inset using UTF-8 encoding. Both versions should pass the W3C tests \begin_inset CommandInset citation LatexCommand cite key "w3c-validator" \end_inset . If your particular web page doesn't pass the tests, then it is a bug and it will be treated as such. \end_layout \begin_layout Standard The \family typewriter --html \family default option also activates the \family typewriter --simplemath \family default option; see section \begin_inset CommandInset ref LatexCommand ref reference "sub:Math" \end_inset : Math for details. \end_layout \begin_layout Subsubsection* Character Encodings \end_layout \begin_layout Standard For better browser compatibility, medium mathematical spaces are substituted in the output with midspaces -- improving the output for some popular browsers. If you want your mathematical spaces back, just use the \family typewriter --unicode \family default option: \end_layout \begin_layout LyX-Code \family typewriter \color blue $ \color inherit elyxer.py --unicode document.lyx page-to-import.html \end_layout \begin_layout Standard Check out the \begin_inset CommandInset href LatexCommand href name "Math Showcase with Unicode" target "math-unicode.html" \end_inset to see the results. In the future other non-Unicode substitutions might be used. \end_layout \begin_layout Standard In case you want to use the ISO-8859-15 encoding in your generated document, you can add the \family typewriter --iso885915 \family default option: \end_layout \begin_layout LyX-Code \family typewriter \color blue $ \color inherit elyxer.py --iso885915 document.lyx page.html \end_layout \begin_layout Standard This will make eLyXer output a document with all non-ASCII characters encoded as \family typewriter   \family default , \family typewriter   \family default and so on. This encoding is similar to ISO-8859-1, also called Latin-1, but including the Euro sign. The \begin_inset CommandInset href LatexCommand href name "Math Showcase (ISO-8859-15 edition)" target "math-iso885915.html" \end_inset has been generated using this option. \end_layout \begin_layout Standard Both encoding options can be combined with \family typewriter --html \family default at will. \end_layout \begin_layout Subsection Internationalization \end_layout \begin_layout Standard eLyXer is distributed along with a few translation files. They are automatically regenerated every time \family typewriter make \family default is run, and reside in the folder \family typewriter po/ \family default . Internationalization is done using GNU \family typewriter gettext \family default , so every locale is identified by a two-letter code (such as \begin_inset Quotes eld \end_inset en \begin_inset Quotes erd \end_inset for English and \begin_inset Quotes eld \end_inset es \begin_inset Quotes erd \end_inset for Spanish). There are two kinds of files: the text \family typewriter .po \family default file (which can be found in \family typewriter po/my.po \family default for locale \begin_inset Quotes eld \end_inset my \begin_inset Quotes erd \end_inset ), and the binary \family typewriter .mo \family default file (found in \family typewriter po/my/elyxer.po \family default ). \end_layout \begin_layout Standard For internationalization to work properly, Linux distributors should take all binary \family typewriter .mo \family default files and place them in the directory corresponding to locale files, which we will call \family typewriter $localedir \family default . As \begin_inset CommandInset href LatexCommand href name "the Python gettext page" target "http://docs.python.org/library/gettext.html" \end_inset explains, this is distribution-dependent: for example on Debian \family typewriter $localedir \family default is \family typewriter /usr/share/locale \family default , so for locale \begin_inset Quotes eld \end_inset es \begin_inset Quotes erd \end_inset the correct route would be \end_layout \begin_layout LyX-Code \family typewriter /usr/share/locale/es/LC_MESSAGES/elyxer.mo \end_layout \begin_layout Standard Windows distributors on the other hand should place files in \family typewriter %PYTHONHOME% \backslash share \backslash locale \family default , for example for locale \begin_inset Quotes eld \end_inset es \begin_inset Quotes erd \end_inset on a machine where Python is in \family typewriter C: \backslash python \family default : \end_layout \begin_layout LyX-Code \family typewriter C: \backslash python \backslash share \backslash locale \backslash es \backslash LC_MESSAGES \backslash elyxer.mo \end_layout \begin_layout Standard To generate a new translation file (we will use \begin_inset Quotes eld \end_inset my \begin_inset Quotes erd \end_inset as an example locale here, corresponding to Burmese): you need to have the GNU \family typewriter gettext \family default package installed. Then go to the directory where elyxer.pot resides: \end_layout \begin_layout LyX-Code \family typewriter \color blue $ \color inherit cd src/conf \end_layout \begin_layout Standard and generate a \family typewriter .po \family default file for your locale: \end_layout \begin_layout LyX-Code \family typewriter \color blue $ \color inherit msginit --output-file=my.po --locale=my \end_layout \begin_layout Standard Then move the file to the \family typewriter po/ \family default directory: \end_layout \begin_layout LyX-Code \family typewriter \color blue $ \color inherit mv my.po ../../po/ \end_layout \begin_layout Standard and start translating it to Burmese! Once you are done run make from the root directory: \end_layout \begin_layout LyX-Code \family typewriter \color blue $ \color inherit ./make \end_layout \begin_layout Standard and it will generate the file \family typewriter po/my/elyxer.mo \family default . Finally, place this file in \end_layout \begin_layout LyX-Code \family typewriter $localedir/my/LC_MESSAGES/elyxer.mo \end_layout \begin_layout Standard and you are done. \end_layout \begin_layout Subsection Math \begin_inset CommandInset label LatexCommand label name "sub:Math" \end_inset \end_layout \begin_layout Standard Math equations are an important part of what takes LyX apart from other editors, since it supports the full LaTeX feature set -- that is, about everything under the sun. Unfortunately, math support is hard to get right. Many developers are focusing on MathML, but at the time of this writing (Q2 2010) support on some common browsers is still missing. \end_layout \begin_layout Standard eLyXer follows its usual minimalistic approach and doesn't try to be everything to everybody -- instead, it supports out of the box a set of usual constructs (fraction, square root) and tries to simulate others (binomial, overbrace). See the \begin_inset CommandInset href LatexCommand href name "Math showcase" target "math.html" \end_inset for yourself and learn what eLyXer supports and what not. \end_layout \begin_layout Standard For more sophisticated math equations there are a couple of advanced features. \end_layout \begin_layout Subsubsection* MathJax \end_layout \begin_layout Standard The first option is to use \begin_inset CommandInset href LatexCommand href name "MathJax" target "http://www.mathjax.org/" \end_inset , which is as simple as using the option \family typewriter --mathjax \family default : \end_layout \begin_layout LyX-Code \family typewriter \color blue $ \color inherit elyxer.py --mathjax \family default \series bold remote \family typewriter \series default math.lyx math- \family default mathjax-remote \family typewriter .html \end_layout \begin_layout Standard The \family typewriter \series bold remote \family default \series default argument tells MathJax to access the MathJax library remotely on the MathJax CDN. (You should always comply with their \begin_inset CommandInset href LatexCommand href name "terms of service" target "http://www.mathjax.org/download/mathjax-cdn-terms-of-service/" \end_inset .) See the \begin_inset CommandInset href LatexCommand href name "Math showcase (MathJax remote edition)" target "math-mathjax-remote.html" \end_inset to check the results. \end_layout \begin_layout Standard In case you need to go outside the terms of service, or you want the content to be accessible offline, you can always use a local copy of MathJax. Just use the URL of the repository as an argument to the \family typewriter --mathjax \family default option: \end_layout \begin_layout LyX-Code \family typewriter \color blue $ \color inherit elyxer.py --mathjax MathJax/ math.lyx math- \family default mathjax-local \family typewriter .html \end_layout \begin_layout Standard This way eLyXer uses the given URL (in the example \family typewriter MathJax/ \family default ) to load MathJax from and set it up. Although some code needs to be hosted on the same site as the pages, MathJax uses a feature called web-fonts which can be downloaded from a public server; this is quite easier to host. See the \begin_inset CommandInset href LatexCommand href name "Math showcase (MathJax edition)" target "math-mathjax.html" \end_inset to see how MathJax fares with eLyXer. \end_layout \begin_layout Standard Something to note is that MathJax is a JavaScript library; all rendering is done client-side by the user's browser. This has quite a few advantages: \end_layout \begin_layout Itemize Math processing on the server is quite light; equations are basically surrounded by a special tag and left in TeX form. \end_layout \begin_layout Itemize For developers: integration of these libraries is very easy. It took just a few days to integrate both libraries with eLyXer. \end_layout \begin_layout Itemize MathJax is improving all the time thanks to the efforts of Davide P. Cervone and the rest of the developer team; eLyXer and its users reap the benefits readily. \end_layout \begin_layout Itemize The client browser already knows its abilities, and can choose the rendering method it considers to be the best. MathJax can even choose between MathML and HTML+CSS \emph on at page rendering time \emph default , showing MathML on fancier browsers and simpler HTML where it is not available. \end_layout \begin_layout Standard It also brings some disadvantages: \end_layout \begin_layout Itemize With the \family typewriter remote \family default argument, JavaScript code resides at \begin_inset CommandInset href LatexCommand href name "a remote server" target "http://cdn.mathjax.org/" \end_inset and your users will need online access to view the maths. \end_layout \begin_layout Itemize If MathJax is accessed locally you need to also host the code for MathJax. (Web fonts used in MathJax can at least be hosted elsewhere, so publishers do not need to also host the fonts package, but this hasn't still been used in eLyXer.) \end_layout \begin_layout Itemize And of course it takes some time to render everything on the client, which can degrade the user experience on older machines. \end_layout \begin_layout Standard Publishers should carefully consider pros and cons before deciding what to use. \end_layout \begin_layout Subsubsection* Google Charts \end_layout \begin_layout Standard \begin_inset CommandInset href LatexCommand href name "Google Charts" target "http://code.google.com/apis/chart/index.html" \end_inset is an online service which generates images that contain charts and other stuff; it can also generate TeX formulas. eLyXer can use it using the option \family typewriter --googlecharts \family default : \end_layout \begin_layout LyX-Code \family typewriter \color blue $ \color inherit elyxer.py --googlecharts math.lyx math-googlecharts.html \end_layout \begin_layout Standard There are some limitations to Google Charts: no macros, formulas cannot exceed 200 characters, and the supported command set is limited (commands in text mode, for instance, are out of bounds). Also, generated images can be hard to align vertically -- by default they are middle-aligned, but some small characters or superscripted formulas can look weird. But this option can be a quick&dirty way of showing math for older or unsupport ed browsers. \end_layout \begin_layout Subsubsection* Brackets and Limits \end_layout \begin_layout Standard Fancy math structures are generated by default: arrays and binomials are surrounded by multi-line Unicode brackets, limits in display mode are stacked above / below the symbol, and so on. When the option \family typewriter --simplemath \family default is used eLyXer avoids such structures and just outputs enlarged regular symbols. It is also included in the \family typewriter --html \family default option. \end_layout \begin_layout Standard Check out the \begin_inset CommandInset href LatexCommand href name "Math showcase (HTML edition)" target "math-html.html" \end_inset to see the results. \end_layout \begin_layout Subsection Footnotes \begin_inset CommandInset label LatexCommand label name "sub:Footnotes" \end_inset \end_layout \begin_layout Standard Footnote generation is surprisingly hard to get right in an HTML document. eLyXer has a fairly complete set of command line options to customize how footnotes are generated. Here we will use the aggregated option \family typewriter --footnotes "options" \family default which can be used to specify any combination, but they can be turned on independently using \family typewriter --\SpecialChar \ldots{} foot \family default . For instance: \family typewriter --footnotes number,margin \family default is equivalent to \family typewriter --numberfoot --marginfoot \family default . \end_layout \begin_layout Subsubsection* Markers \end_layout \begin_layout Standard The footnote is attached to a point of the text (the \emph on referring \emph default text) which is usually marked by a bit of text. The default behavior for the marker is to use a superscript letter surrounded by square brackets, in blue: \color blue \begin_inset Formula $^{\text{[A]}}$ \end_inset \color inherit . The text can be changed to aligned text with \family typewriter --footnotes align \family default : \color blue [A] \color inherit , so markers are not mistaken with other superscript constructs such as exponents (like \begin_inset Formula $e^{a}$ \end_inset ). \end_layout \begin_layout Standard Markers can also be converted to numbers using \family typewriter --footnotes number \family default : \color blue \begin_inset Formula $^{\text{[1]}}$ \end_inset . \color inherit Or, they can be switched over to symbols using \family typewriter --footnotes symbol \family default : \color blue * \color inherit . Available symbols are rotated from this sequence: * ** † ‡ § §§ ¶ ¶¶ # ##. All options can be combined. For instance, symbol markers look best when shown aligned; \family typewriter --footnotes align,symbol \family default will show aligned symbolic markers such as \color blue * \color inherit or \color blue † \color inherit . \end_layout \begin_layout Subsubsection* Position \end_layout \begin_layout Standard Footnotes are supposed to appear at the foot of the page, but that is not always possible or practical in web pages. Huge pages make scrolling up and down quite uncomfortable, and remove the immediacy of having the note in the same page as the referring text. \end_layout \begin_layout Standard There are a few alternatives: use the margin, show hovering text, or link to the note at the bottom of the page. eLyXer can use all three. \family typewriter --footnotes margin \family default will place the notes at the margin, just as margin notes but with the addition of the footnote marker. While \family typewriter --footnotes hover \family default will show hovering text when the mouse is placed on the marker; this is the default behavior. Note that hovering notes are converted into margin notes when printing. \end_layout \begin_layout Standard When footnotes are shown at the end of the page with \family typewriter --footnotes end \family default , footnote markers turn into links. The actual footnote at the end then contains a link back to the marker. \end_layout \begin_layout Standard The most interesting part is that these three options can be combined at will: \family typewriter --footnotes margin,hover,end \family default will show footnotes at the three possible locations. The most practical combination is probably \family typewriter --footnotes hover,end \family default , which will show notes as hovering text and also at the end of the page. Note however that in this case notes will be printed twice (at the margin instead of hovering and at the end). \end_layout \begin_layout Section Work in Progress \end_layout \begin_layout Standard As you can see eLyXer is a mature and tried package, but it has some rough edges. \end_layout \begin_layout Subsection Known Issues \end_layout \begin_layout Standard The following issues (including bugs and missing features) are acknowledged. Some of them should be solved soon; others may take longer. \end_layout \begin_layout Enumerate On Mac OS X the output of a message with Unicode characters may cause an error. Workaround: run \family typewriter elyxer.py \family default with the \family typewriter --quiet \family default option. \end_layout \begin_layout Enumerate Some phonetic alphabet symbols are not well supported -- if generated with LyX they only appear in a different color: \begin_inset Formula $\text{\textipa{[sample]}}$ \end_inset . \begin_inset Note Note status open \begin_layout Plain Layout This happens only in the HTML file converted with eLyXer, not from within LyX. \end_layout \end_inset \begin_inset Note Comment status open \begin_layout Plain Layout By the way, the previous note (and this one) should not appear on the HTML. \end_layout \end_inset \end_layout \begin_layout Enumerate Multi-column layouts are lost. This one is almost impossible to get right in CSS, so there are no plans to even try. \end_layout \begin_layout Enumerate Many BibTeX styles are missing. (They are quite trivial to add though.) \end_layout \begin_layout Enumerate ERT (bare TeX code) is ignored. \end_layout \begin_layout Enumerate Many AMS environments (like \family typewriter alignat \family default , \family typewriter gather \family default \SpecialChar \ldots{} ) are not working or look strange -- some non-AMS environments too. \end_layout \begin_layout Enumerate Images are never scaled above their nominal resolution. This is seldom needed if at all, so there are no plans to change it; if people really need the feature just let the author know so it can be added as an option. \end_layout \begin_layout Subsection Wish List \begin_inset CommandInset label LatexCommand label name "sub:Wish-List" \end_inset \end_layout \begin_layout Standard The following features have been requested by users; specific people are referenced by a couple of initials so they can recognize themselves while keeping some anonymity. (If you prefer that your initials do not to appear here at all just let me know.) \end_layout \begin_layout Standard Queued features will be added at the next big release -- the priority for each feature will be set by the number of users requesting it and date requested. Pending features need some assessment. Those marked as too complex have been evaluated as requiring too much work, but the decision might be reversed if there are enough people interested or a simple way to implement them is found. Once done, features are marked with the first release where they appear. \end_layout \begin_layout Standard \begin_inset Tabular \begin_inset Text \begin_layout Plain Layout Feature \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Date \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Users \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Status \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Understand \backslash setcounter{section}{1} \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 2010-05-15 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout JB \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 1.1.0 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \family roman \series medium \shape up \size normal \emph off \bar no \noun off \color none Option to turn off title prefixes in TOC \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \family roman \series medium \shape up \size normal \emph off \bar no \noun off \color none 2010-07-10 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout YG \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 1.1.0 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Use BibLaTeX with eLyXer \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 2010-09-14 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout PJ, WE \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Pending \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Render change tracking: "Show changes in output" \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 2010-09-18 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout YG \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 1.1.0 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Option for footnotes at the margin \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 2010-09-21 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout A \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 1.1.0 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Output SVG as \family typewriter \family default tags ( \begin_inset CommandInset ref LatexCommand ref reference "sub:Output-SVG-as" \end_inset ) \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 2010-09-22 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout YG \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Pending \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout EPUB output format ( \begin_inset CommandInset ref LatexCommand ref reference "sub:EPUB-output-format" \end_inset ) \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 2010-09-23 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout MJ, MG \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Too complex \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Option for footnotes at the end of each section \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 2010-09-23 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout MJ \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 1.1.0 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Add more controls for image conversion ( \begin_inset CommandInset ref LatexCommand ref reference "sub:More-controls-for" \end_inset ) \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 2010-10-02 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout WE \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 1.1.0 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Support for format 401 (Insert Horizontal Line) \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 2010-10-06 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout US \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 1.1.2 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Parse contents of ERTs \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 2010-10-06 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout US, JW \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 1.2.0 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Correct scaling of tables with relative sizes (e.g. \family typewriter %col \family default ) \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 2010-10-09 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout US \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Pending \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout BibTeX: parse math formulas inside BibTeX files \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 2010-10-16 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout JA \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 1.1.1 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout BibTeX: display \family typewriter \backslash url{} \family default as an URL \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 2010-10-16 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout JA \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 1.1.1 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Do not label bibliography items in comments \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 2010-10-21 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout JA \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Pending \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Unit tests should warn if ImageMagick not installed \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 2010-10-24 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout JA \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Pending \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Unit tests should run fine without PNG conversion tools \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 2010-10-30 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout JA \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Pending \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Option \family typewriter --imageformat copy \family default to avoid converting images \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 2010-11-12 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout JD \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 1.1.1 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Option to embed the CSS in the HTML file \begin_inset CommandInset ref LatexCommand ref reference "sub:CSS-controls" \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 2010-11-23 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout GM, JA \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 1.1.1 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Display sub- and superscript aligned vertically (as in integrals) \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 2010-11-23 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout GM \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 1.1.1 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Use Unicode large characters for sums, integrals, matrices\SpecialChar \ldots{} \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 2010-12-07 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout GM \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 1.1.2 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Do not number captions in code listings \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 2010-12-08 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout DC \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 1.2.0 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Support brushes for \begin_inset CommandInset href LatexCommand href name "SyntaxHighlighter" target "http://alexgorbatchev.com/SyntaxHighlighter/manual/api/autoloader.html" \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 2010-12-10 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout DC \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Pending \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Generate formula images using Google Charts \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 2011-01-07 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout ET \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 1.2.1 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Output reference arrows as CSS pseudo-elements \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 2011-01-12 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout GM \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Pending \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Include part names in \family typewriter --splitpart \family default navigation header \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 2011-01-15 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout AJ \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 1.2.1 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Merge options \family typewriter --toc \family default and \family typewriter --toctarget \family default into \family typewriter --tocfor \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 2010-01-17 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout JA \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 1.2.1 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Make \family typewriter --splitpart \family default and \family typewriter --tocfor \family default work together \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 2010-01-17 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout JA, TP \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 1.2.1 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Generate named references (equivalent to \family typewriter \backslash nameref \family default ) \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 2011-01-19 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout TP \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 1.2.1 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Do not generate entries when index or nomenclature are missing \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 2011-01-19 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout TP \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Queued \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Do not output unknown commands in red except in \family typewriter --debug \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 2011-02-22 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout JA \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Queued \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Output equations as images \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 2011-05-31 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout GK \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Pending \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Parse modules for custom Flex CharStyles \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 2011-06-08 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout MG \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Pending \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Convert several files with a single command \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 2011-06-01 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout PF \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Pending \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Export slides as HTML5 presentation \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 2011-06-28 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout RK \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Pending \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Add an option to remove navigation bars \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 2011-06-29 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout AH \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Pending \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Support for External Material: PDF, Date \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 2011-10-22 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout MI \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Pending \end_layout \end_inset \end_inset \end_layout \begin_layout Standard Some features require further explanations. \end_layout \begin_layout Subsubsection* EPUB output format \begin_inset CommandInset label LatexCommand label name "sub:EPUB-output-format" \end_inset \end_layout \begin_layout Standard The EPUB management package \begin_inset CommandInset href LatexCommand href name "calibre" target "http://calibre-ebook.com/user_manual/conversion.html" \end_inset does not output valid EPUB documents when converted from eLyXer HTML files, at least according to the \begin_inset CommandInset href LatexCommand href name "Threepress validator" target "http://threepress.org/document/epub-validate" \end_inset . \end_layout \begin_layout Standard This is a complex feature request; calibre does minimal formatting in its EPUB conversion, so making it generate valid EPUB documents requires changing deeply how eLyXer outputs XHTML. Lots of help would be needed to get this working. \end_layout \begin_layout Standard That said, EPUB readers are often much less strict than the official format and they readily accept eLyXer output. Just convert your LyX document to HTML using eLyXer, and then import the resulting HTML document into your EPUB reader. Let us know how it goes for you. \end_layout \begin_layout Subsubsection* Output SVG as \family typewriter \family default tags \begin_inset CommandInset label LatexCommand label name "sub:Output-SVG-as" \end_inset \end_layout \begin_layout Standard This feature would be most welcome from the part of the author. Unfortunately, Firefox alone from the major browsers refuses to render \family typewriter \family default tags correctly for SVG. According to \begin_inset CommandInset href LatexCommand href name "bug #276431" target "https://bugzilla.mozilla.org/show_bug.cgi?id=276431" \end_inset , this was fixed on 2010-09-08, so the next version should do the right thing; at that point this feature will be queued for inclusion. \end_layout \begin_layout Standard You can check out how your browser does with SVG images with this \begin_inset CommandInset href LatexCommand href name "SVG test page" target "svg/svg-test.html" \end_inset . \end_layout \begin_layout Subsubsection* More controls for image conversion \begin_inset CommandInset label LatexCommand label name "sub:More-controls-for" \end_inset \end_layout \begin_layout Standard eLyXer uses ImageMagick to convert images. Some images (in EPS format, for example) do have blank borders, or they come in varied sizes. It would be nice to remove blank borders and have some kind of unified resolution in the conversion, which would be passed to ImageMagick. \end_layout \begin_layout Standard As of 1.1.0, the improvements include using \family typewriter ps:use-cropbox=true \family default in ImageMagick for PostScript and EPS images. Unified resolution has not been added as it might collide with picture density, but suggestions are welcome. \end_layout \begin_layout Subsubsection* CSS controls \begin_inset CommandInset label LatexCommand label name "sub:CSS-controls" \end_inset \end_layout \begin_layout Standard Proposed by JRAS on the elyxer-users mailing list, the following is a direct quote of \begin_inset CommandInset href LatexCommand href name "his message" target "http://www.mail-archive.com/elyxer-users@nongnu.org/msg00194.html" \end_inset . \end_layout \begin_layout Standard \begin_inset Quotes eld \end_inset [\SpecialChar \ldots{} ]A mixed solution for CSS styles: \end_layout \begin_layout Enumerate The essential minimum css for math formatting (a compacted version of a \family typewriter math.css \family default subset) included directly inside HTML head. \end_layout \begin_layout Enumerate Then a call to download the on-line full CSS, that can repeat the minimum already included \family typewriter math.css \family default (from item 1) plus some other styles. The default can be changed by \family typewriter --css \family default command line option. \end_layout \begin_layout Enumerate A new option ( \family typewriter --addcss \family default ) to add another CSS defined by the user. For example, to only redefine some styles from the default, etc. \end_layout \begin_layout Standard The styles should be included in that order (using the "cascading" property). Item 1 is fixed in every HTML file. Item 2 is always added and by default pointing to the eLyXer on-line css, but it can be changed by option \family typewriter --css \family default to another url or file. Item 3 is optional and its url would be added after the other two items, only if the \family typewriter --addcss \family default option was used in conversion. \begin_inset Quotes erd \end_inset \end_layout \begin_layout Standard As of 1.1.1, an option \family typewriter --embedcss \family default has been added which allows embedding one or more custom CSS files into the resulting HTML document. Also, \family typewriter --css \family default can be repeated as many times as desired to use several CSS files. \end_layout \begin_layout Subsection Contact Information \end_layout \begin_layout Standard If your problem does not appear in the above list, please let the author know; you can find him at \begin_inset CommandInset href LatexCommand href name "elyxer@gmail.com" target "mailto:elyxer@gmail.com" type "mailto:" \end_inset . In the words of Rich Talley: \begin_inset Quotes eld \end_inset the tool's author really likes getting challenging documents and making eLyXer work with them \begin_inset Quotes erd \end_inset . You can send your sample documents and we will try to make eLyXer convert them acceptably. Any documents sent will be treated with the utmost confidentiality. \end_layout \begin_layout Standard You can also join the \begin_inset CommandInset href LatexCommand href name "mailing list" target "http://lists.nongnu.org/mailman/listinfo/elyxer-users" \end_inset to discuss any information related to eLyXer. The author monitors the official LyX lists for mentions of eLyXer. Bugs can also be reported at the \begin_inset CommandInset href LatexCommand href name "Savannah page" target "https://savannah.nongnu.org/bugs/?func=additem&group=elyxer" \end_inset . \end_layout \begin_layout Subsection Extending eLyXer \end_layout \begin_layout Standard eLyXer should now support most LyX features; but sometimes it will ignore a command, sometimes it will signal it, and it might even refuse to work with certain documents. What can you do if eLyXer does not work with your LyX file? Worry not! Its flexible approach to processing allows anyone to write support for the missing commands. \end_layout \begin_layout Standard eLyXer is written in Python so that it does not need to be compiled; its code is interpreted on the fly. See the accompanying \begin_inset CommandInset href LatexCommand href name "developer guide" target "devguide.html" \end_inset to learn how to extend eLyXer for your own purposes. If you know how to program in Python it should not be difficult to support other LyX features. If you don't your best bet is to ask the author. \end_layout \begin_layout Section FAQ \end_layout \begin_layout Description Q: What versions of LyX are supported? \end_layout \begin_layout Description A: The tool should work with all LyX versions from 1.5.5 to the latest and greatest. It has been tested on Linux, Mac OS X and Windows. \end_layout \begin_layout Description Q: There are indeed \emph on a ton \emph default of similar projects over the web. Why add another one? \end_layout \begin_layout Description A: The four tools supported by LyX (tex4ht, hevea, tth and latex2html) gave inferior results in 2009, and were quite inflexible. The author found the need for a good converter, while at the same time acknowledging the difficulty of the problem. \end_layout \begin_layout Description Q: Speaking of that: why build a LyX to HTML converter, instead of a more generic LaTeX to HTML converter? \end_layout \begin_layout Description A: The problem space is quite simplified, and therefore progress is much faster. To make it even easier eLyXer has historically centered on the subset of LyX functionality that is useful to most LyX users, leaving the rest for a later stage. Nowadays eLyXer aims to support the full LyX feature set. \end_layout \begin_layout Description Q: What can we expect from the tool in the future? \end_layout \begin_layout Description A: eLyXer should fulfill the needs of 99% of LyX users in the short term. It has also learned a couple of tricks of its own such as page segmenting. Eventually it could be distributed along with LyX as part of the standard installer. \end_layout \begin_layout Description Q: Why did you leave out my favorite feature \emph on \emph default ? \end_layout \begin_layout Description A: In short, because nobody asked for it. Every feature which has been requested (either to me personally or to the list) has been tended to, unless it was too far out or I forgot about it. At this point of development every missing LyX feature will be considered a high priority item for the next version, if at all possible to implement. \end_layout \begin_layout Description Q: My document changed its appearance without my intervention. Was it black magic, elves or what? \end_layout \begin_layout Description A: It probably uses the online CSS file, which is regularly updated. See section \begin_inset CommandInset ref LatexCommand ref reference "sub:CSS" \end_inset for details. \end_layout \begin_layout Description Q: Why use an online CSS, instead of placing the CSS file in the same directory as the converted file? \end_layout \begin_layout Description A: There were pros and cons. An online CSS resource allowed me to update it for everyone at the same time, but might make it more difficult for people without an internet connectio n; local CSS files are more flexible but can also be confusing to novice users. In the end the online solution was preferred, with the \family typewriter --css \family default option as a fallback. \end_layout \begin_layout Description Q: My MathJax pages are not rendering correctly; equations are silently ignored. \end_layout \begin_layout Description A: Check that MathJax is installed on the same server as your pages; for security reasons the browser's \begin_inset Quotes eld \end_inset same-origin \begin_inset Quotes erd \end_inset policy mandates that JavaScript can only be loaded from the same site as the original page. Also make sure that JavaScript is enabled on the browser. \end_layout \begin_layout Description Q: How can I disable hovering notes? Isn't there a \family typewriter --nohover \family default option? \end_layout \begin_layout Description A: It can be done using \family typewriter --footnotes margin \family default . This will disable hovering text but keep footnotes in the margin. \end_layout \begin_layout Description Q: I found a bug, what should I do? \end_layout \begin_layout Description A: Just send it to the author at \begin_inset CommandInset href LatexCommand href name "elyxer@gmail.com" target "mailto:elyxer@gmail.com" type "mailto:" \end_inset . You can also report it to the \begin_inset CommandInset href LatexCommand href name "Savannah interface" target "https://savannah.nongnu.org/bugs/?func=additem&group=elyxer" \end_inset . \end_layout \begin_layout Bibliography \begin_inset CommandInset bibitem LatexCommand bibitem key "wordreference-elixir" \end_inset WordReference.com: \begin_inset Quotes eld \end_inset definition of elixir \begin_inset Quotes erd \end_inset , accessed March 2009. \begin_inset Flex URL status collapsed \begin_layout Plain Layout http://www.wordreference.com/definition/elixir \end_layout \end_inset \end_layout \begin_layout Bibliography \begin_inset CommandInset bibitem LatexCommand bibitem key "xhtml" \end_inset W3C: \begin_inset Quotes eld \end_inset XHTML™ 1.0 The Extensible HyperText Markup Language (Second Edition) \begin_inset Quotes erd \end_inset , revised 1 August 2002. \begin_inset Flex URL status collapsed \begin_layout Plain Layout http://www.w3.org/TR/xhtml1/ \end_layout \end_inset \end_layout \begin_layout Bibliography \begin_inset CommandInset bibitem LatexCommand bibitem key "html-401" \end_inset W3C: \begin_inset Quotes eld \end_inset HTML 4.01 Specification \begin_inset Quotes erd \end_inset , 24 December 1999. \begin_inset Flex URL status collapsed \begin_layout Plain Layout http://www.w3.org/TR/REC-html40/ \end_layout \end_inset \end_layout \begin_layout Bibliography \begin_inset CommandInset bibitem LatexCommand bibitem key "w3c-validator" \end_inset W3C: \begin_inset Quotes eld \end_inset Markup Validation Service \begin_inset Quotes erd \end_inset , accessed March 2009. \begin_inset Flex URL status collapsed \begin_layout Plain Layout http://validator.w3.org/ \end_layout \end_inset \end_layout \end_body \end_document elyxer-1.2.5/docs/pipeline.png0000644000175000017500000001312712074107030015576 0ustar chennochennoPNG  IHDR%bKGD1 pHYsdd vpAga6IDATxyxT@LSZB E  "BP@@AAيd"aP-,E#V}_ET(ńr?~;3l7s2ޙy,w{3s=M4 DD0DZ*DCbR "RBDJE]h(YZP89}زh蚘%C%/سZP80yZX?DCbR "RBDJ1TH) )P!"*DCbR "RBDJ1TH) )P!"*DCO?U&F6kgMn?Oicl.?/<%^=uk`8S'`Wcͭ^'L~hʸ[iQgٳ4MVDE5kex~ׁ9s -Y[7&7ҀiӀɓDyˁ)S1c hgfk~n+VHm*࣏G6oN&Nyش ؾ(_qxvwr%::x֮F9x1_8sF@AС/y4- */oGu]uk-)SW^ʖ99!nV7޽#۷Sv,̜ $'fʷـ}jU ?(h*\8xP13Q?Yn,&?{{ ;XQhp˗i&n߲Z?2R-㸔)~YOk>`s5ĉءi:hE+д(:?k͜i;k+hښ5vku]M+UqoU+#umߢǏ/zVq ~L>}t4w}`NiSѢ_q;lm/;>~dqq I>x+W/Ja]`2ϯSKjTKYzhN8ZXNЯ,?upYE-*J'&Fag̐uJƎUW~rRݏ?J7ӟx-Z5zU}8 Ԫ0xu7lsn.в[]vm]u CBڷ7drE)op_Uu2\vZzʕٳY`ǧOȐܱccLӲ޶{IX׮xU`. |dM&ξ)p@*6ț.!\V ڥRc*[׼MVL I-TH) )P!"*DCbR "RBDJ1TH) )eig͚] '@׮F,*W]""RBDJ1TH) )P!"*DCbR "RBDJ1TH) )P!"*D%O}p*pѵ O] % ہKF-YP!,*e@&FOk@c*DCbR "RBDJ1TH) )P!"*DCbR "RBDJ1TH) )P!"L}7۷5DŽ @v60>iFow8p4Mθ׸ѵ$2Mܺ8-OӀQ$X7yHJ ~fΔ#:ScYYӦ]K2+ӄ?+_pPSO-u` 'GnGGGQQ{,ЭЦ 0oD:-M>p')/G/Lƌ22{,_gfh׮3fyy+VHŝ,՗I4 @n<>x><h0i^ uqԯS' D=oв%opܷ{??\ϗV[J P*ߖ11@^(0}l6-+^n /@Z/LRСе+@ll_B`y[s8qdg{>}%r2P;wMGҥZD}KYzhN{Vw},'O~[g,yi٨,LL3be\c~֭]I۶@.rfzՂc1PrE)op 9wsٵj`.}l;x^m/p=sc?#oeIwTϗݬ FׄxaR @zǎ;v]+"c1TPnxL'҃"RBDJ1TH) )P!"*DCbR "RBDJYrr~卮]jt (X2T7s|5'0j,* ȅ̇c*DCbR "RBDJ1TH) )P!"*DCbR "RBDJ1TH) )P!"*DCbR "RBDJ1TH) )P!"*DCbR "RBDJ1TH) )P!"*DCbR "RBDJ1TH) )P!"*D&iBd5 Cv6j/F&+P5 C] ,] ԩctmBOǎ?]0TH́|}{kzt‚5I`*~T;GH`k+@ҭpѵ]]]1TH%CZݺ>jt-c =x衢=BaA`Lkaс=bROYYF\6Rq^Sc}l eF=bR/52~ѝ7b 0rkk'.֔>|ӄJr!w[Z9&&P]|&T,1D?,Z+gtMu2 X7j ciBL^rs?5P=5+ק=xC%?4lHX 8vLxB#|/yaR%K榻x[9nk W5&f2tJd>0)ФU7CKEa6&|l&As̖t.̝+ǣ\Wȑ@>OQr$sDЯ0{6KjTהݟo%/X!KLG KeBox.w 9.A`/uU 'Bʔ}V_7 ܼ)/\̙#LT`bvm_oV2TBPժu@jmٺGq\w>sc.m rZM.mʮPgIר!Z&M_Er/;-t<8/gq#PLsk476L8*Un{ų=*!]y-]ɓe|c\;qs4ܼ 9bt9^&5UZs[ȶ[7|Ykfd_{ѝˁO>퓩/~`vM*6^Jz%6~IjGFEUIef9(1/OE2^gP``Na{7bb|^ ᓘ(c2`xg?(k;SҚ/eˀ?s ̮'5i"c;˷g^0p Ыs?(XgKhw|ԪY#鎼 /ȷܯ L ~`C)2g[#8*Tc2~} TWٻΊ}7Nu={iƹ+kԐVRi@Ԡ뛸[弩&9߼Y=bE`s:y1uℴcc / 98;+K S r;"B۶I𭷀+m``YMFRߗ1I7feʘ7ny~,9Yn.]ܟ"]SSsVvNO@ٱL2rW_ϟ.;έlDڵq?AΡ:a5jՀߖ>+J(~5}_)0{hHH@+V_.%EZG /"_ݟiu2b:i*ѣ[Ic RSeP ߷]Ҳ=RRB=v\<-|y[+ a|+]SSTJdOW r2ZgRSV[isn"Ǻ|]a΅ѳ,IB=9[HԬ)~A[yMi͟/MpoP[ѷ/p\vOZ._23]{灕of| =oRzYiϛ Vrn$-YL}L*[KS|FY -M9Bd=o ')J7Թ 8(ɞzO)Ba *v箨-\zOq=:dFII\箨-\zOF~=%&A:=ho{F4soByϛ |oG+;+/ؾ]Z+qq;TҶ;܍aV]y"IocݺorΘ! 2 k?׆ @VE?Pih6[&SR k/eIo'vr/=ȋprz:  {gʷ7XCƍ].e"R-I^kaz:-N/E7\eZ[MO& =;0&1|!hR!v&'y:kr "7‬&\~B_^"R{H) )P!"*DCbR "RBDJ1TH) )v@3%tEXtdate:create2009-11-19T00:47:59+01:00q%tEXtdate:modify2009-11-19T00:47:59+01:00uBtEXtsvg:base-urifile:///home/chenno/projects/elyxer/docs/pipeline.svgDIENDB`elyxer-1.2.5/docs/elyxer.png0000644000175000017500000010234312074107030015300 0ustar chennochennoPNG  IHDR_nbKGD X pHYsdd vpAgIDATx}w|iջdɽWt 5!$@H $! ͗PrC rS$Z l{%]q|Z gvfvvy9(Gr!q>r!ӅC9!-rC9[0r`90n#ra"G9øEs!qC}nv۷ottttttJRT… .\̜9s̙sᣍ~@x<x^{5oxcqM7X,xӦM6m_׿50}ӧ!b{o xgy Rp8l6f qؿBP(<3>8]N%X,:uԩSzAhrFٶT*J,^xOӟ{rÍ,}w}z5׈jZV B“W6&D|^>>[nݺu89C:rNQz^೟g?Y3f̘1Cl+Zbz„ &Lo߾}M0\`׾}k^X#ɖ͛7o<`֭[n=ݣCnpPYYYYYyG3> // @@"qF0N,8Q"ljjjjj:묳:ԟo9|#8|ÇE-3-8dIr'[5838Cw99hxㆍ6nn馛nr(#GGqA%fk׮]_$r =p8,Rm."JٳgϞ ̝;wܹms#q ̕ :eZ[[[[[E5믿?ݣCM{ pǎ;vH_/wp`0 ?NG^{}rxqD=BDI:Xexȗ9p,{99|Ks=sb3qx,ǀD2LAV@JR Dqat9ʋ0N5M ywySH$' )gKޠjI!O[t\. CP8}{6dlgȮ]v\r%\r n&nx'H|#W >H>^]۲USؽ{ݻ}s瀫ꪫ:ݣs7s4b2K:N$Ï;-r?9kNh}+_W\p\pV=CP0Ę%x<uH$8tFC ņXAWJljh :@5B<O8_AorDqŸ%@Νc$w$Dwwq{87Fc]+sk7F{--@0lLħFv`}60uqK$@ɖ?ªHėL9o B^/eL9L$B!Z~gNdr8> @3NMa8Csx``OwOwOg$"z[oN;ZZzz\.Z ==N{tp:=@Fcx"8F^Q6ɨ7v֖0aByy~>-mqca?Hr<"})/ 1/2T5fIY%H(X%>(~O\O||>ut w77w> KK+\n7f3{`Lz=i4)P4 `$8mOTV \yg6L~Lt==OvZ( H&c1"HzA{&@h j]PzBҳ8xqK 87567 bx" X,FN,Z4uje%0yrUUa!`Lǚ ? vdb_yE8)AP(J">RZ P(J$7onoVZaȑ~sp^PRRTK~]p՗_>e PPp~7FjTlEcјD>QYOvRbjG"776+WnDxW+_.ILZVI9[irU;zW;Z46 'Vضs"($ .; -) I.ٞ@cAUؒ?4ЬJ%/ZK rV՚@QQQ"~. kp2}D?ڵ֭;vtwC]qt"h(Iq̀Vk4׋9hb`65K/KEaґĵk| o܉ʀYKK`J2+٬k4@UJ%I0iD2IR<hFDbd2-Blk˾JR߫V[{7v`-+w Mm#=Շw:?=UW ɚ YNsDS?Z +*****F}-[}ZZfϮΊ8Rl7Xĉ'N*2l`<d a[`-0 9뮻ɌFcx}q @_Sgח ee!p۳\7L ,P"cbDUWs@_/ ^lTj5:0w~|艏1n .ᅣQvrªU{V\ӫ,,<'%>(G?oF<jl z!.nǭ.]|~`Ŋ+{/뮛>">}iʄ\t(&l b1zaA`fc'_G^O5F r*L:G'd2k׬YBbŋ/ 5W׿h<<ˆqK555555믽k/7ܱhX` ʉU JKm6,G(lB*4^N8>Ea7&eBPXeg"KPr 1z p:~߸Esc悂+>. Ri4aFfh4juxp  7pu3fU4X7FgR-;%%:ߏ 0޳g&薽 ^@ uPzQ]Uէ?կĉf*@کD'MM>D4_׬ M;= p$֖-U^-ȆrcȾcǮ]==d|Km%?yoV{ϣu T$a={zz)/z j.ۏYFlϦΙ3sfi)pyg]SYnX/jjk'LN22f/NG7H"Àӹe˻JtD.W_?V[,v;`6N8 bdkVrDˣ\nO3355TWrz0ɽ,y71A2fS}am:;r/TjupIf̸jihZ|$ |>_4JI+**(3;omBQPd JRT|xmׯXZl08aoX Z^PM'Es䕀^_RRUED' +ަ={#Gx}3f~jq4q'9̂-[P(;Z O8;4D<HdF__kDKx1*c,O-3W"ql4L|`EnXwyɫd/~fL&`Ui2Z`ܹ_sʹiuz2e9sn%R5{WI{er"^$x4tBu5%<6/PbyrT׮_xǀ/&`ڴ|#,Xz玖fS/[;?)N {kى!kabx9aq}^Ri zEŋ}}vZr\ٳYawtwG痉ٖ7})EE…WT+%l{͙S_L#~PU^~?js} ݗZ":m9sPM&EJpx}嗁w |O~~~&Ӌ7< }rc{IE",`0Ղ &y72y 4Kx|!ό+,r4|'m):o8nߗCbK/zdE""9[l;kP^p$J(ɃHھ]BtGmt>_Kˁ"b4y@/.N OmA&˟xڱcZ`˯XUNr(Ljlۓ8$E}rfiVUYcdKL\͈` DPUzad+Yg{WB޻>,ӱl#IRFE#;sY()"8УuFQoAo'R6n|MRY/׭{5 xϱd<hf]pF|8 ѱtق`¿ujbih9Sz2G% <ާ:(GG ue(*cKL@$r,Ejm6%#o|@XvÆtK~\_~2V/o6LNT__P^Eh2F"n|@w7 qΝPRl6W]OWy]x]۷*pHsݔ!~ 孒Iz1BE.)).XrI 's޼y^]N#"A```ݺ_WZ pnL)_p0$N2L&`(-$G}X\}}D|3:ٿ͋o*QZ*prǣ(?(c(vhj/;=&B7V:XR \哟Iʷ3oXq^:q\$HZNG=7(WoojsfΤ:]&fϟ:8%KN9碋(~1s:ɶ:8Hb8,RJdOq(0x,lv՘A {z$UJHuڱc: D"lS*5RY&wTE0u+O>  &ΙL@4j4g\6⓯#8xu0zx$⳥Y,6ĉ@__ooKKLFJZ{@?DJ"dpe/5])"_ VQU*P,>uۺW:/v8"rL-`ʔ"/o tz@omfssڵԸna3#͊%GXΝQ٪+|*+{!I[JdcN71=67wu9@⨱ >0P\&`0kkº:1vM;8 }tÆ'뮻ʩSPRGA_TE[{;vVfR`WXZ,WTdL@^y9>%HQ,ٹCCTvlLuȑ@xJ}|A&zTU}<]q7ڇ] t:E 3OZZIih:֖꫁l4~:lG͛Q|3^;}:pphLR\"Pb)Jںy3wȆ ںe &n"-[xܽGKZģUHz0 ,Ued߿mp={„f}T`Ҥ)Svؾ}ӦnԔ~ .¡u6ShTd2si%%?yf'L+*Uh#GF'AeZMha`vv (_HP 9(|?otf{'Ϝ}NMg>̚UZdɇ_ ;:$F{z3\X'Ϛum@OOwwK =5:75ҋ.jhniq(JS=? @'L&2Uj,8o}Kx&'PsswuIu. ?ȑ  Ob1)14xi!m `XZ֮4iR ~ ꫧwsΩpALώw㜹?1xqmן{48^ cpyٵkE;˓e5{zm_>{vx7F4 uu+Wگ~4665h~rP^^V\~UW}{O}kywݻWBA}m={eFhmݴTw<>wu.׶mk*̙W\h4_ԑZ(bH6p8`0dظnᦦXlz=LՁV/XCK|o[7( ÆqKk*;&M,(s'OِHbCC޽۷o$Jԏ:U9Ef;㌯|j L҆ ZظaPP@ѱe VӎÏ7MM}mFCJ%Gňh2i4dHIBlm=r$6n\k$@@]7PEQFwr 0"*c@8|HlRS Js$(Tc*BA6چ8xpa  (>@a2Io=ZOjz n _N⊥K*=>+(u*x]v٢E RWT9eݺ={ہUvlkBg/ r`T'*ahtwG"@oogg4J )V#"J}K];٬坂lwt(J%WTZsz.gO~̸!p8 ;iR)6*Ѩ̚E&a'\3mR #‹/Ry"A6,ʢqpR TW:$Q*EؔFѐhT"dp8"Jٽ.$SUuPX%'BqJ/BJ>kyT!Kz>kp0YBd8q2Gb1}I T )jMU~M&p/~v-,X|S~'9Bx{/֯߿or`۶ë=J= Jnj/ >}˴bm<( >cQ ۠ /F#"X 0&&I (DT 72`  Ӧ>0sf~>`it [>rٳu+wt $S\v ^r  â$>VJTRQx Wju:l|j5*P\\Zj0-/z{~'7o‚`PJ|,*"t:ry"Et[UU0sfYم<'G^w;;Kׯ`۟SdTV>JT&"e.tf~^O·onu}>RiB"~h4 //?_%O Iq9Z-NfJEq( `ggPTBmoomP0Iz1JˮJGU>E3"RaƬrQ6$ZhT!Z6*Idɮ7&O6nEEڿxزeffh)L&c1tn'U2.W_/I%.䱪S(P[A 55uuf30{y0s9yy驆,:4 v  B()``NP(ZjԪ 74Og9dopz W__0HHfQ*ɓb0 j5e )DR' j4B!z}RT0 E۾{vn3ibMCKO r+|n`׮ěBQ(x\F?Y 5p8 o>ݣz^x lFXLp:Is損#Fi11j+@Q%PIecf'AGGk/kϞ;)LǁŽlljȬ`#$*VD@8];+Wٹ! ?&BCL!" '@wwGG O*<;gXu# ,)-ٵkhT~[LLulZ-5~>^=kOKLH^CGuum<ҥ_DiHdω!H x, ~xnj_yDyG?NTUVĘ'N*{9ۉ8.m`v SQ B}0^dVFYfU!4I@t|1ft>J%_X$b$h&2"BoIYU%ekkK xd\^b֮]b 'On]ORʜ h}{$AS*ǶZ-ۻ曁 .hhE18M5͛z Wz/ єnFLMW%BRX鮻A1_oϼ 2g9A^?}{_g>N2PPihx|۶F/ ӠP'GIIi()"77{-7 o8_Z|=5xgd(ϴ_cyQ R8GDDŽ( ,9J0F/ -J3E]۶ TT?ϦOn_N-[6n<\Q*M&^n@'O;ڵ-_<ҥwTT8& Ru  2zaT#FBQ[ 8&ӝwm8Ip#m|9?TPhӦ/Y:Qj[,ƶ> .rZT@AAq^O*\2 dZVL74$Dj5BP@XrD^bjMl:y8}=tCN*ቜ`,KmBeN  1 /?"(/2EBDz=6 vSbfY;J'4~dR>|U5?[3i#M| ׿z۾ TTLzhӛZ2PXRTR̤*2b0k$PVr=_رM9i\Z{@2cbHm}4 %1zn*6@ l~Z-ep@磔.A|DtVB^[*P* I62%A":@A U|:y>؋G,AJeDT;R^^Yi0&"fhŠ{zC!੧x. `ƌ3v5(i<ġF"ΝnYg6^_Twliۿ{/} | /x ^OKӛ"}{熆~ʭ[FOp 7l>qr0sfU~W'+TORgSU3}_;+X*<>X2E! @jٴZ``/NA Ϫ4KDR"H$,WGIU%! RYF2I*'-(µIR '(*HU9ABVKN^f 8CG"dZhQZm;TxUJJJJt:!ɳ`pX=}` ??H4 SUV-\HFOzAC/WqJJ %Kv]:q2&5=Aw:OJ8p#'H9ƫ$g4vwl9BەJ 3v Y5|]  T;v]G6)RyS%d}t@߁~ʰ`FkJ԰La)T[tD*1r聁P$&"t"@n)$S&{dD+g"Z8KR%@2 QJ|&HZ"@ ǁPHHbaɯ;yOvZ$PPP\l0nEȚ9]]_>e׿/[v]"s$/m66;zJR&qn|+5J,LJu޽$9&hTyWZ5DPGT#;E|| .4?8`45YPA\6@s:[ZK.O T$N?-%>NPFi dcbgYH$u MXlLP, TD`*%^)%@X"#M.踉K"PNlMgN!$g65<Թ"^d԰FF =D+O06[^HIЉݻd@ƙ0N9]o߲ebɨ*,4)=YqzcDP=P*H9~(UrB*FC.KD\ɤqih &^1NǍPJJVoqϋֶm`4mJ 46D BdvldfG}3\ Ι^̦ `@`-Gְ75?2*hLiiyHHWI"epdmfŢVSj pLț6_tjuuT@mCCN'[K}xCDJll߿wߒ-[S>;v{G:$9KIy95xD%~PZJ, vMy  U?XBiDp?M ~` Q'87yR@IɊ5Ւ$w?p DJK'Oa;:LIUؤ!5IH/B;dKg@dnxTOPJ[(D&K<$Ad:/a; S|9U(JޟcmTsu{ PmڨڂA47*S٤!@b8X2: hnܺ4૯n닊J"zb(RJlTeW*dYY$Iңb0h BtV+ U|}]JUPl|,!21TJWTeAe $T.i`7D#g NR؊<:' OF5zhȟI2a0t;)R!NdddI ==ԎHH,ѵ81 ZFTTTWSYf*T_:;NXm>s>F/6;s {9QJeEi?>_El:sv Iy$}{AZVFD@Smy=*5m4(YU8B3DRdB!U~L{eRY"[H2I&@MGBa6j5Zttju^lStHZN @ns{~qr}1IQ6KK:;'M8_B~L0p^oX\Z({R?D8|!c$ IhҔiDj4 \bJ|lz'*K V*bNh繐j4JĞ)%dN6iJpߧ`;JR<^T*-XHE"4j%G^U<^T(L6L7?  Kw0r'?TN ."k(Dc̉L<*Hq r! JI׋WS y4AGKŒ+4%D5ĒIH_\.RWG,r> ddxhQTeh4_I It_89%'4X hnnj2щ%k}h ܩϓVKϪ5+k!YJPL$V9rxd5b` l3o߫>tSXC8sܹ4řc0h&'M*i&',J@ydp륪!΋E7GVeF"HB@(DK ;bT y(\QRIi?4e ӕRXI(TE%B(T%l\D}K:/pRɃT49#K-ORN|&B^τGi=%gyy: ($6*P3q$|f/1{;x<ce4z{C!a ;-_tnNDǑ~,DVS}EzstY#5e8`0M jmo~3mM4DE,Qqݥf|H#$=yGj"P(lOW5<`RNnl`c{ 'vԼSx< %FJ:* 9^-U*T9U*)5,sNUǤIV<1Ye@/%TL 8N0UU6""? b!I$+&>}rqv>n7IB"'$@~ޥrgiJ=?,#uNI`.h8(HBVL$nڲe?iij{A{* όVj3yDTa'"Y:X.GMڀj 91Q*8ZRAu:D(xVXLxh(Cի)BΓbjK( 񥄗}:eȽ,tDC#cI/l7,ҁD|Lrp _BN2A\4rUZlHU'aM7D\c(G/t0Z-9J+V<T?ko߼()۫iY$~ vǶL<Z#].%OkKi,FUV6iWRR^NKxs3RD~Ng2Q|"DJB^lė:AK|3R,R9P<]-Z2/oɍ bI&+v6-$@&}SCn4 FC2#9];S#֥*/{}Z2c-t:K*-2SJJHjiz.ZF#ߧRYPOkΛF7oӟ/{H/*yp]6 &KANxY,qcd#OSHǪn(DҺR MRﱔ4ӥ-1&]!ᴍ 382|}+)O/֠OH#pB`0śTzLCdBFB: VVr[ʽ{ ?*1Rl0)ҿ=SA94*>qƍ}G5i<ѨVϞ-p< /] ;2?F6}Pz< FKτ;zER9Fcc=WYᣉ@^ ەXiJ RQAuV$B^hqwma%2wX,)DJ-*H"Vyt:A:-Y ?$kbω`2鴣ߝFX(HA_*Rĉ{g~\, UEvVYF`XbɖpPА-ˏ̽ h,*@HRe44l@cYgu$NR%%FwK8ҥhqUe;bة {z߱Ty]rY~hVBD"ҏT@5ZKK?a2i4v `x8^x"7h!̈́ɬ*Ht A^ c|(%%[JE>EeE?6-z2`P#jJ-m h?};,'p(セ1ADJ$wcv`'zƩkEE9rQDRE!+`dqHX2eܦ'Ɨzq:Z-OZہ P6FdpE9M%H~@r=xkkI=NXHRtLldbjkt"XHt:=㱥UV⋀^WRRU iZNq(䁜)_X,`0PCFla6F٬5?cÇNNWT 8Dª7K^MqVU z<ҥZM9UUz=Ida*1:W`vq3K_8L,Yd[ @6Czf!L&S(D}*>'tY>__KS>pz}Qi #r"}uqhI$@Yu OMj6fA=#Դ2hB )3`t:b2YkV T`#'.u?vu:*uri~x8liiy ȑ;j?ni`@jj|>"&GU(Dd~ImP<+_>C*!& S(rr'L0hVj)m%T Xk# e`B$Y !¯JDx\Η$H&nBJKȴnk'ʺq#EV*IEDZ"nN;#o-*|Yu-553g<`AAUUmmm]v" |iJp̜Iq~ TRUbq>?vfsYىd:Dcxbd"DE#ܷ{`u̵׺\j5p?meeݟ[V+TB6S9<*+kjF`'_JEeL&Q .`Pt5yA4e #?ݝPq :T;x< eEu25TEy7:;>>K~逩^\>89^ӈZtS.X(r$d vvw[;.L៩~쟤7$<#ҚF"c~rHU{loip/⭷\py@II~P$ \w(Fs|BhQ9m#[N?%pn6{K^MX(m"AeZ/]fޟwzz#G={:;{$a`"O.V% @&' --@4g? I"|DO&MIJ4Z-`v;0}̙f3@yZ- d [J %pD,f`Lz}SbD 2)7olI뼬(H\B-/O9p}Q,B {Mk/l|G;kFAɳfz= ]xRm(,u Ӓ|, Jņiaȝ&%\nj0z0FJ|ttum~w={zG3oEN!ذa޶6`Φƞn"YU˩w DƍN:=$IPrȶakWGǪU R C]ڨ8|h^{hmA pV@yUUF#I^옪Ȼ54@iiYNTWqW6ljez^r: GU)lDK.tK! #s+WbKZJ or$TVJ3g8טWJ-zfauO&¨fKŵu31[$\t[jŋUr2Mq>paUƍ#ѨѨEcҥT';M,2"Bi@Ԯ4a18ON-Cj H؋ӯAD'I&KyJ|]]pÛ.<|1Ό<sΙ6M,N'rAAa`@$@iIg; С3hޠT*RACzzl )SiO)i0ş\1I0UU*[[Rw72k֜9V+x [JaljPȄjG/Re\6KHxS)%+B);tI$@aaQNG6Pv<^:b^΅PY2TDB I=l{$HV!co/ Xp3Ϥ N5b ++kC^07XRDtL 0 T*Rْ&i~JPg9HW==D4k;'}Wx߳ /GB08448ʕ?P*zDJJK' L^wwv]Kہbry:`DRՏX|(Ǜؾ}ŏ=xxg[,D%I~8MdDK|KcBSSOvZEH6B~BcF3 yq@N _4YF*5m#0WM{ >55f-Xp,h{JIq~vIdhhOnJN4&rg41F l?'vLؾRp* csZ~lLjp`I2z5Zb:FHx)vW(h$˜VӧSRYQ{"%wزԃ'o~SS#4={v ׬q+!:! $h4xU]8%C*u=g8Yt%Vs]7mS،$?燎gSXxH2~:_$^75Ӧ{ɈQ'M9Ng*~?tM 7߃RQEpO# YT:r x3e0Q eeTh2^.{.SJK]8Y@$y<=/'c„S`ɏl\:]& g̡C==\v;U>Ldqj2އBC`0(BBb]IrRK]/]‡"#E& Tdj?Y’K*1WnfIKIӦLvl>0 Q^zEԁO5TR6Gk>;2"yyBq )?!эFi [Z n1+--"p:} P=ɶ>jK,WIFMG7n|s{4A'qϞe˞zh?e@2I u:!4!B!S`8& 0k0ejjtK)*, k!AjuK|I=_x2jt9^hRh%KV˯xMM=*,0+l}m!./! FjbTﱨDɋt DE18HpX*@M 90Y\wnRR2G0.AKjk9UU?80m 7qo]K>%I|PyS&x?UEE',~2Q$EM6s}ܹf3tRh$7{RPas*f1 /y4!ǒW(CF**lGG{{8  PZZZRsAxzYVtd`s!Abbft*FÒ?1p- @f?X0 `ʔ9sK./} 0O@gmu[԰|NǮ]O>@4>bOϞ=[Tn`0$Rl&۞NG̑oյwxa p8j Z-{{)0yǎwZ[Lh:u:n*x6_i)l~ʿ-uwXhʶn| (-\**@.lp`a'ѦV+l6MExs?j2!†(H364f3UTh I˶! FEuk` #I1?JP(:S(W X Y/E=+=d2[cמyX!ipY4z=%ld0)BҜI^JmCM Hi(x}j-uƷDFC //۵cӟ.ՕI3/,-R*>J :;ID0 RRbO'W@2Ҁ]cǕ>1BM/(=^__ooWrĉWW"MD%U-v[N Vat:ZWU @M IDeeZ-e 9Mf .((,s!3Kiy*ytTl6Tde%|`9ϧ;%75F)Ӆ{q_bi sx {zIp)Kn2~憻,'Vqzڀ^OnشiMp]6Evzz]K'T0SG f:2h+us:6:\M/Jp0.6" c^{DeLd0gpDrbd㔼VJY(Jaƌ'._\q1j8t:nMoJJ,ڹsF cR'h@JEejJr D:A* )`D}9RbsS0`kJ7 dv«Jٹi;;wֲeb'W=\YcDTTSL⥑>nL5Rl媶j˥.0ֶn]Gw!G|3dDό|R*IsFIuum^Db2E"c;,5 iixTqb,) )t @TiqWS3a> [PqI"xSonO?hO1"&LX1kVs}qbD/h9_ⷿ ф}~~7mHu9epb{0v@8gO(vHe0Rɽr/S$U{Es Fܗ^\8*ǁΎzޔ {}}]] F#Kσ|U*N60y8^IՕ:rpR| k׶ڦ:lQ(Hh|o"[}餶՜k)nWH [Z_ճ{En/*ߗfR#![j`gg B􍊊*VGD\܀$3)$BAvSMƷd^+8oRT.'٪&L>s_1󥗞xxeo~s@{vgjN?tH&hh0lF#_[k6Fwi"R5f*tؘ'"3^  xrښɓ.eM]8Z2=eG "LUYq3ŨtZ-RR=.WkkOb˯_Lq#W\t)޾`}@7IsOtbdAA2V Px B9t|&<&'Y^_ R4J{mm]gV%[wo>/nQ '@[*Uy@E>_?XA5Vr2ߚ)S[s'wկ`zu#cHL,ÔN)MfsQ 64XNGHٛ+CdOZomm@oΝl")綱kjjoO=V)#b63?~:qF&N>7<M{hfwW2ifi^bV1K(((*R)CmDBZLzF<'u4'%{_s$$Bg dTP({|~>z{{zb1{)xG̹xɑ}B9T0NrԜ'? |snoӟ+W>? x\Llr3[U&XJ2 47Q̘QXt"ud:ommkh\\V*1r"L?gFVKe,&$T\Rmx6ML blSsG&*#mm@WlGRՍFϿ.70|p5ӧ;@MM^ތ_w+=6̘̙p!l19溧ԌFʵM$HӑK98,lU|J|RA Cx|wP)/Wn/g|S-N;2Zf.{Gᢋ x{vׁ޾tHNt"d)%nQlrhC%m.6HP\. *񉭀TRRY>n:͖=a.R5=9TrTz6eLp[Iv=~UZf+~Lp饟{g./brJGn طoښ'NL̙$2qlv;U:fJTwI)Hj3(:RsYpST^$/59mD?"dqw::(0zma ),|]o|yep,p̩;QfϾjή.@d$gV2mE"=kٜfj)_<D"dA M=l*g3$(*Zq7󟓄*-x<Ν/@0#ȽY" DŽ 4)=Y!!|>_j5OZ\KNQ;&8s'LF*() 8|xRJR(D01Ll{qg{(@To<IS*oOtົ;:q`ݺիC!P(.+_.kL&;9'lc NN8Fc+<46C7 |Nunsj@*{zdL|oD^/PJxߗ~f |0.ߟ{nM  RэghDQvh .30 }j8|]nu&K-^ÿ=3K_~:kɒS~$vK}+wZD׮Ofxx" u:t;L;9 )qR\EػKKqfH z$p=0gT6mk+` s3ޟUUyyӎ2\{p]7LD#UISc'/A᱈G S__(+>}޼3y763̆t[`vJ> hFF_0x@ t|ُmKv9poo/|xBӟ_߱gHd; $mmKEE60y) 0u*j)$9W!2<؎M|ݱx@8 45ZBlֶlf 8Hb[fJe,sM(..- jX BA8NQ\rq;8ߟH(`4Je~~c#־ PR<{p0pS6>H$(+7~/X._Dc%̟E|+?|T⬫;.7y y>nyݞdTFOq_ /]{^N`֎W_}=-[u\@;H&'NI"ˤksȶiJnJ%׃ *6@2pUUW +*IqZhh(('>6`"\ԧիW^F8^[Xs*omYg.Y|hzzdžիہw}^N nl8MFWxׁөD2]]5Œ)IDATOc#47a @(|G%Qֳ^VMޠј̀Ţ9$UVVk}PVf?tn|΁Kի6nܺu۶LG&cUyJJop%?ħ>$r_z閛/صOSJIc%%Βb٠x룏>M+V<r![E٬T{B…3ft7TTqƩq@sHA, @o]7I]6M0e PR2gYgQt_E99!->?d9Ç9!-rC9[0r`90n#ra"G9øEs!qC9!-rC9[0r&dk8%tEXtdate:create2009-08-31T01:36:31+02:00p+T%tEXtdate:modify2009-08-31T01:36:31+02:00@tEXtsvg:base-urifile:///home/chenno/projects/elyxer/docs/elyxer.svg|)IENDB`elyxer-1.2.5/docs/math-html.html0000644000175000017500000007715712117174760016075 0ustar chennochenno eLyxer Math Showcase (HTML edition)

figure elyxer.png eLyXer Math Showcase

Alex Fernández (elyxer@gmail.com)

1 Introduction

This document is intended as a showcase of the mathematical abilities of eLyXer; for more information be sure to visit the main page.

1.1 Versions

There are several versions of this page:
All of them are generated from the same .lyx source file; they should help you decide which rendering options suit you best.
Also available online is the eLyXer translation of the latest LyX’s detailed Math manual, which contains a lot more examples of LyX maths.

2 Typography

Math formulae use a lot of different symbols and fonts.

2.1 Greek Symbols

Greek symbols are very important in equations: φ, π, Ξ. eLyXer offers a complete set in both upper case: Γ…Ω and lower case: αω. Also the AMS italicized upper case: ΓΩ.

2.2 Math Symbols

eLyXer supports the whole set of math symbols in John D. Cook's list: ∃∂∇ ≥ . It can also render a few more:  ∝  × . You also get all symbols from Markus Kuhn's list: ⊙∐.

2.3 Other Symbols

There are other symbols like arrows:  ←  → , or geometrical shapes: , . eLyXer offers limited support for them. You might also want to use financial symbols in formulae: ¥€$.

2.4 Spacing

Equations look good when items are properly separated. The main separation is the Medium Mathematical Space: x = 3. Note: if you are viewing the non-Unicode version math.html of this page then you are in fact seeing midspaces, which are very similar but not exactly the same: (4)/(18) em for medium mathematical spaces versus (1)/(2) en, where 1 em = 2 en. Try out the Unicode version math-unicode.html — and viceversa. You can check out what version this page is in the page title.
The command \raisebox is useful to, surprisingly, raise a little box,
raisedoverloweredand back.
Like \mbox, it puts its content in a text box. It can also be used just for spacing:
BV.
There are other spacing commands: \hspace: a b, protected space: a b, and (at “block level”) \vspace: a b.
There should be 1 cm of vertical space above this paragraph.

2.5 Fonts

By default, letters denote variables and are taken from the \mathnormal font, which is italic, αx + αy = α(x + y), with the exception of upright capital Greek letters, G ≠ Γ.
Function names should be upright: sin(2π), log(x), tanδ.
Mathematical fonts used in equations include Roman (\mathrm), Sans Serif (\mathsf), Typewriter (\mathtt), Bold (\mathbf), SCRIPT (\mathscr), CALLIGRAPHIC (\mathcal), BLACKBOARD BOLD (\mathbb), and Fraktur (\mathfrak). For the latter, some single characters are translated to their Unicode equivalents: , 𝔽, 𝔉.
Regular text in a formula can be achieved via text font commands like \textrm: 5  to 10, via boxes like \mbox (prevents line breaks): 6  is more than 5, or the AMSmath \text macro (scales like math symbols) basesubsuper. The content of an mbox is processed in LaTeX text mode. This allows text font commands, e.g. a switch to sans-serif-bold-italic, or the phonetic alphabet: sfbfit, tipa.
Units should be written upright, either with \mathrm or with macros from the units package, e.g. as simple unit, km, with magnitude, 57 km, with fractional unit, 200 kmh, or with a fraction before the units, 32 km, (7)/(16) s.

3 Numeration

Equations can be numbered, like (1↓)
(1) y = x
And also like (2↓).
(2) x = 3
Some equations can be numbered even if they don’t have a label.
(3) x = 2y
Notice that equation (2↑) comes after (1↑).

4 Simple Structures

Let’s now see a few of the simpler structures that eLyXer can output.

4.1 Fractions

A simple fraction:
(1)/(2).
Inlined: (2)/(3).
A big recursive fraction:
(1)/((1 + ((1)/(1 + ((1)/(1 + 2x))))))
A nice fraction: 56. A non-diminishing fraction containing alignments:
(1)/(1 + ((1)/(1 + x) × (1)/(1 + x))).
A similar concept is a binomial coefficient: (A + 1B). It can be prettily presented:
(AB + 1).
A symbol can be stacked over another using \stackrel: xR → y. Anything can be stacked:
dx > 3limx,  headheels.

4.2 Limits

limx → ∞f(x) should appear as x → ∞ in italics, and «lim» in plain style. In display mode, a limit must appear below the main symbol:
limx → ∞f(x).
Limits are also used in sums and integrals:
i = 1x,  0f(x) dx
where the sum’s limits should appear below (i = 1) and above () the . The placement of the integral limits depends on the document class: LaTeX standard classes place them right to the . Limits are shown to the right in inline formulae: i = 1x and i = 1x.
The placing of limits can be configured with the \limits and \nolimits macros:
limx → ∞f(x),  i = 1x,  0f(x) dx

4.3 Roots

A square root: (3). A more complex root in a fraction:
(1)/((1 + (2)((1)/(1 + (2))) + ((1)/(2)))).
eLyXer can also do higher-order roots: 3(x + y). A devilish case mixing everything we have seen so far:
(78((8)/(4)x) + i = 1x)/(s + 5(((78x + 45y) × (Ω))/(sin(x + 1)) + 38 km)).

5 Complex Structures

In this section we will explore arrays and related constructs.

5.1 Arrays

An inline array [ a b c d ] is always shown in the same line. In display mode, the array is shown on its own line:
[ 12 2 3 4 × yx ]
Apart from that the appearance should be the same.

5.2 Brackets

Arrays are separated by variable-size brackets: ( a b c d ) [ a b c d ] { a b c d } a b c d | a b c d |which might also differ on right and left ( a b c d ) or use the empty opening { a b c d or closing: a b c d |. There are also fixed-size big brackets, e.g. f.

5.3 Cases

Used to switch between several values.
y =  x i = 0,         x + 1  i < 3 
Cases may have more than two rows:
f(x) =  0  x < 0,         ∞  x = 0        0  x > 0 

5.4 Braces

Values can be underbraced or overbraced.
a − b = b + c + d + e.

6 Macros

Now it’s time for user-defined commands (sometimes called “macros”).
Definitions can be added as macros. Then they can be used in formulae: 1(2). They can accept default parameters. Again, useful in formulae: 4(5).
Other definitions from the preamble can be used: 3(4).
Definitions on the fly are also possible: 7(8), and used with different values: a(b).
elyxer-1.2.5/docs/toc.css0000644000175000017500000000101412074107030014552 0ustar chennochenno/* * Styles for lyx TOC. */ body { font: small sans-serif; background: #f9f9f9; color: black; margin: 0; padding: 0; } #globalWrapper { font-size: 115%; margin: 5px 20px 5px 20px; padding: 0px; background: #ffffff; line-height: 1.5em; overflow: hidden; } a { text-decoration: none; color: #0030c0; background: none; } a:visited { color: #603090; } a:active { color: #ffa000; } a:hover { text-decoration: underline; } div.tocindent { padding: 0 0 0 2em; } div.toc { margin: 0.5em 0; font-size: 0.95em; } elyxer-1.2.5/docs/container.svg0000644000175000017500000003147612074107030015775 0ustar chennochenno image/svg+xml Container parser output contents LyX HTML elyxer-1.2.5/docs/math-mathjax.html0000644000175000017500000005456212117174760016560 0ustar chennochenno eLyxer Math Showcase (MathJax remote edition)

figure elyxer.png eLyXer Math Showcase

Alex Fernández (elyxer@gmail.com)

1 Introduction

This document is intended as a showcase of the mathematical abilities of eLyXer; for more information be sure to visit the main page.

1.1 Versions

There are several versions of this page:
All of them are generated from the same .lyx source file; they should help you decide which rendering options suit you best.
Also available online is the eLyXer translation of the latest LyX’s detailed Math manual, which contains a lot more examples of LyX maths.

2 Typography

Math formulae use a lot of different symbols and fonts.

2.1 Greek Symbols

Greek symbols are very important in equations: , , . eLyXer offers a complete set in both upper case: and lower case: . Also the AMS italicized upper case: .

2.2 Math Symbols

eLyXer supports the whole set of math symbols in John D. Cook's list: . It can also render a few more: . You also get all symbols from Markus Kuhn's list: .

2.3 Other Symbols

There are other symbols like arrows: , or geometrical shapes: , . eLyXer offers limited support for them. You might also want to use financial symbols in formulae: .

2.4 Spacing

Equations look good when items are properly separated. The main separation is the Medium Mathematical Space: . Note: if you are viewing the non-Unicode version math.html of this page then you are in fact seeing midspaces, which are very similar but not exactly the same: for medium mathematical spaces versus , where . Try out the Unicode version math-unicode.html — and viceversa. You can check out what version this page is in the page title.
The command \raisebox is useful to, surprisingly, raise a little box, Like \mbox, it puts its content in a text box. It can also be used just for spacing:
.
There are other spacing commands: \hspace: , protected space: , and (at “block level”) \vspace: .
There should be 1 cm of vertical space above this paragraph.

2.5 Fonts

By default, letters denote variables and are taken from the \mathnormal font, which is italic, , with the exception of upright capital Greek letters, .
Function names should be upright: .
Mathematical fonts used in equations include (\mathrm), (\mathsf), (\mathtt), (\mathbf), (\mathscr), (\mathcal), (\mathbb), and (\mathfrak). For the latter, some single characters are translated to their Unicode equivalents: , , .
Regular text in a formula can be achieved via text font commands like \textrm: , via boxes like \mbox (prevents line breaks): , or the AMSmath \text macro (scales like math symbols) . The content of an mbox is processed in LaTeX text mode. This allows text font commands, e.g. a switch to sans-serif-bold-italic, or the phonetic alphabet: .
Units should be written upright, either with \mathrm or with macros from the units package, e.g. as simple unit, , with magnitude, , with fractional unit, , or with a fraction before the units, , .

3 Numeration

Equations can be numbered, like () And also like (↓). Some equations can be numbered even if they don’t have a label.
Notice that equation () comes after ().

4 Simple Structures

Let’s now see a few of the simpler structures that eLyXer can output.

4.1 Fractions

A simple fraction: Inlined:
A big recursive fraction:
A nice fraction: . A non-diminishing fraction containing alignments:
A similar concept is a binomial coefficient: It can be prettily presented:
A symbol can be stacked over another using \stackrel: . Anything can be stacked:

4.2 Limits

should appear as in italics, and «lim» in plain style. In display mode, a limit must appear below the main symbol:
Limits are also used in sums and integrals: where the sum’s limits should appear below ( ) and above ( ) the . The placement of the integral limits depends on the document class: LaTeX standard classes place them right to the . Limits are shown to the right in inline formulae: and
The placing of limits can be configured with the \limits and \nolimits macros:

4.3 Roots

A square root: A more complex root in a fraction:
eLyXer can also do higher-order roots: . A devilish case mixing everything we have seen so far:

5 Complex Structures

In this section we will explore arrays and related constructs.

5.1 Arrays

An inline array is always shown in the same line. In display mode, the array is shown on its own line: Apart from that the appearance should be the same.

5.2 Brackets

Arrays are separated by variable-size brackets: which might also differ on right and left or use the empty opening or closing: . There are also fixed-size big brackets, e.g. .

5.3 Cases

Used to switch between several values.
Cases may have more than two rows:

5.4 Braces

Values can be underbraced or overbraced.
.

6 Macros

Now it’s time for user-defined commands (sometimes called “macros”).
Definitions can be added as macros. Then they can be used in formulae: . They can accept default parameters. Again, useful in formulae: .
Other definitions from the preamble can be used: .
Definitions on the fly are also possible: , and used with different values: .
elyxer-1.2.5/docs/changelog.lyx0000644000175000017500000025727112117175137015775 0ustar chennochenno#LyX 2.0 created this file. For more info see http://www.lyx.org/ \lyxformat 413 \begin_document \begin_header \textclass article \begin_preamble % eLyXer -- convert LyX source files to HTML output. % % Copyright (C) 2009-2011 Alex Fernández % % This program is free software: 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 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 % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . \usepackage{mathrsfs} \usepackage{mathabx} \renewcommand{\varGamma}{\Gamma} \renewcommand{\varOmega}{\Omega} \usepackage{color} \usepackage[gennarrow]{eurosym} \usepackage{upgreek} \end_preamble \use_default_options false \maintain_unincluded_children false \language english \language_package default \inputencoding auto \fontencoding global \font_roman default \font_sans default \font_typewriter default \font_default_family default \use_non_tex_fonts false \font_sc false \font_osf false \font_sf_scale 100 \font_tt_scale 100 \graphics default \default_output_format default \output_sync 0 \bibtex_command default \index_command default \paperfontsize default \spacing single \use_hyperref false \papersize default \use_geometry false \use_amsmath 1 \use_esint 1 \use_mhchem 1 \use_mathdots 1 \cite_engine basic \use_bibtopic false \use_indices false \paperorientation portrait \suppress_date false \use_refstyle 0 \index Index \shortcut idx \color #008000 \end_index \secnumdepth 3 \tocdepth 3 \paragraph_separation indent \paragraph_indentation default \quotes_language english \papercolumns 1 \papersides 1 \paperpagestyle default \tracking_changes false \output_changes false \html_math_output 0 \html_css_as_file 0 \html_be_strict false \end_header \begin_body \begin_layout Title \begin_inset Graphics filename elyxer.svg lyxscale 50 \end_inset eLyXer Changelog \end_layout \begin_layout Standard This document lists all public versions, the date they were released on and the changes they contain. For more information about eLyXer visit the \begin_inset CommandInset href LatexCommand href name "main page" target "index.html" \end_inset . \end_layout \begin_layout Itemize 1.2.5 (2013-01-11): \end_layout \begin_deeper \begin_layout Itemize Solved a bug in the previous release: José Ramón's fix was not properly applied in the executable \family typewriter elyxer.py \family default . Sorry about that. \end_layout \end_deeper \begin_layout Itemize 1.2.4 (2013-01-10): \end_layout \begin_deeper \begin_layout Itemize Implemented generic converters, and \family typewriter lyx -C \family default as an image converter (thanks, Tommaso!). \end_layout \begin_layout Itemize Implemented command \family typewriter \backslash today \family default : \begin_inset ERT status open \begin_layout Plain Layout \backslash today \end_layout \end_inset . \end_layout \begin_layout Itemize Added a Russian translation (thanks, Vladimir!). \end_layout \begin_layout Itemize Solved a bug when parsing a BibTeX entry with a trailing comma (thanks, Bob!). \end_layout \begin_layout Itemize BibTeX: correctly use booktitle instead of journal in an \family typewriter @inproceedings \family default entry (thanks, Pascal!). \end_layout \begin_layout Itemize Expose language information as additional markup (using the \family typewriter lang \family default attribute in HTML). \end_layout \begin_layout Itemize Fix by Guenter Milde for \family typewriter math2html \family default under Python 3.0. \end_layout \begin_layout Itemize Convert em-dash only when surrounded by spaces (thanks, Robert). \end_layout \begin_layout Itemize Fix by José Ramón Álvarez Sánchez of problem in simultaneous use of \family typewriter hover \family default and \family typewriter end \family default options for footnotes (thanks, Tim!). \end_layout \end_deeper \begin_layout Itemize 1.2.3 (2011-08-31): \end_layout \begin_deeper \begin_layout Itemize Changed the license for math2html from Apache v2 to FreeBSD 2-clause license, to better suit integration with DocUtils. \end_layout \begin_layout Itemize Removed a false positive error which appeared during the tests: \begin_inset Quotes eld \end_inset * No title in \begin_inset Quotes erd \end_inset . \end_layout \begin_layout Itemize Added most commands in Günter Milde's excellent \begin_inset CommandInset href LatexCommand href name "list" target "http://milde.users.sourceforge.net/LUCR/Math/" \end_inset of Unicode to LaTeX commands, except categories mathaccent, mathfence, mathradical, mathover and mathunder. Examples: \family typewriter \backslash hash as \family default \family typewriter \begin_inset Formula $\hash$ \end_inset , \backslash smalltriangleleft \family default as \begin_inset Formula $\smalltriangleleft$ \end_inset . \end_layout \begin_layout Itemize Deprecated option \family typewriter --jsmath \family default , users are encouraged to use \family typewriter --mathjax \family default instead. \end_layout \begin_layout Itemize Added argument \family typewriter --mathjax remote \family default to access the MathJax CDN instead of hit a local copy. Changed the Math showcase to work \begin_inset CommandInset href LatexCommand href name "remotely" target "math-mathjax.html" \end_inset by default. \end_layout \begin_layout Itemize Solved \begin_inset CommandInset href LatexCommand href name "Debian bug 639712" target "http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=639712" \end_inset : eLyXer didn't accept Unicode characters in \family typewriter --title \family default option, added test. \end_layout \begin_layout Itemize Solved \begin_inset CommandInset href LatexCommand href name "Savannah bug 33961" target "https://savannah.nongnu.org/bugs/index.php?33961" \end_inset : eLyXer didn't support sub- or superscript insets as used in LyX 2.0, added test. \end_layout \begin_layout Itemize Solved installation problem when \family typewriter $PATH \family default contains a directory which does not exist; the eLyXer binary was created with the same name as said directory. Now \family typewriter install.py \family default should just ignore the directory. (Thanks, Jack!) \end_layout \end_deeper \begin_layout Itemize 1.2.2 (2011-06-12): \end_layout \begin_deeper \begin_layout Itemize Bug in description: when a (non-empty) ERT is the first element of a description , use it as first word and make it bold. \end_layout \begin_layout Itemize Proper support for \backslash scriptstyle and \backslash scriptscriptstyle: \begin_inset Formula ${\scriptstyle \text{script}},{\scriptscriptstyle \text{scriptscript}}$ \end_inset . \end_layout \begin_layout Itemize \begin_inset CommandInset href LatexCommand href name "Bug #33156" target "https://savannah.nongnu.org/bugs/index.php?33156" \end_inset : CSS specification as in \family typewriter --css=lyx.css \family default was not working, solved now. \end_layout \begin_layout Itemize Support for \family typewriter \backslash noindent \family default and \family typewriter \backslash centering \family default in ERTs. \end_layout \begin_layout Itemize Ignore BibTeX entries which are not publication entries. Show a debug message for non-referenced entries. \end_layout \begin_layout Itemize Understand command \family typewriter \backslash & \family default in BibTeX files. \end_layout \begin_layout Itemize Bumped Lyx format supported ( \family typewriter --lyxformat \family default ) to 413 (LyX 2.0.0). \end_layout \begin_layout Itemize Solved error when parsing display formulas generated with LyX 2.0: \family typewriter "Formula beginning \backslash begin_inset Formula is unknown" \family default (thanks, Pascal!). Added test case. \end_layout \begin_layout Itemize Added a bunch of new symbols, including \family typewriter \backslash textsection \family default \begin_inset ERT status open \begin_layout Plain Layout \backslash textsection \end_layout \end_inset , \family typewriter \backslash textemdash \family default \begin_inset ERT status open \begin_layout Plain Layout \backslash textemdash \end_layout \end_inset or \family typewriter \backslash v{z} \family default \begin_inset ERT status open \begin_layout Plain Layout \backslash v{z} \end_layout \end_inset (thanks again, Pascal!). \end_layout \begin_layout Itemize Changed output characters for English quotes, from Unicode “ and ‘ to HTML entities \family typewriter “ \family default and \family typewriter ‘ \family default (thanks, Marco!). \end_layout \begin_layout Itemize Make Flex styles in titles work (thanks, Tiago!). \end_layout \begin_layout Itemize Make custom Flex CharStyles work: generate HTML spans of the same class as the Flex type (thanks again, Marco!). \end_layout \end_deeper \begin_layout Itemize 1.2.1 (2011-03-07): \end_layout \begin_deeper \begin_layout Itemize Wish list: support for formatted references (showing the part name and number) and named references (showing the part title, equivalent to \family typewriter \backslash nameref \family default ). \end_layout \begin_layout Itemize Wish list: include part titles in \family typewriter --splitpart \family default navigation header. \end_layout \begin_layout Itemize Changed literal for previous page in \family typewriter --splitpart \family default : now it's \begin_inset Quotes eld \end_inset Prev \begin_inset Quotes erd \end_inset instead of \begin_inset Quotes eld \end_inset Previous \begin_inset Quotes erd \end_inset . \end_layout \begin_layout Itemize Bug in \family typewriter --notoclabels \family default : removed the \begin_inset Quotes eld \end_inset . \begin_inset Quotes erd \end_inset after the part number but before the title shown in the TOC. \begin_inset Quotes eld \end_inset 5. \begin_inset space \quad{} \end_inset How to Make Friends \begin_inset Quotes erd \end_inset is now \begin_inset Quotes eld \end_inset 5 \begin_inset space \quad{} \end_inset How to Make Friends \begin_inset Quotes erd \end_inset (thanks, José Ramón!). \end_layout \begin_layout Itemize Allow \family typewriter math2html \family default to be invoked using parameters (like \family typewriter --debug \family default ). \end_layout \begin_layout Itemize Bugs in ERT parsing: brackets \family typewriter {} \family default are not parsed correctly across different ERTs. The TeX parser was being thrown off by escaped brackets as in \family typewriter { \backslash { \backslash }} \family default , added test. Comments are ignored now. \end_layout \begin_layout Itemize Solved conflict in CSS between \family typewriter .script \family default (used to properly layout super- and subscripts) and \family typewriter span.script \family default (used for the script-type \family typewriter \backslash mathscr \family default and \family typewriter \backslash mathcal \family default fonts). Changed the latter to \family typewriter span.scriptfont \family default , forcing an incompatible but unavoidable change in the CSS. \end_layout \begin_layout Itemize Forced \family typewriter span.scriptfont \family default to be shown as italic so it's properly displayed on Firefox. \end_layout \begin_layout Itemize Wish list: new option \family typewriter --googlecharts \family default adds support for formula images generated using Google Charts. \end_layout \begin_layout Itemize Wish list: merged options \family typewriter --toc \family default and \family typewriter --toctarget \family default into \family typewriter --tocfor \family default . \end_layout \begin_layout Itemize Wish list: options \family typewriter --splitpart \family default and \family typewriter --tocfor \family default (previously \family typewriter --toc \family default ) now work together. Also: the separate TOC has a link to the main page. \end_layout \begin_layout Itemize Bug in \family typewriter --splitpart \family default combined with \family typewriter --notoclabels \family default : unnumbered parts displayed an ugly colon as in \begin_inset Quotes eld \end_inset Next : Section \begin_inset Quotes erd \end_inset , now removed (thanks, José Ramón!). \end_layout \begin_layout Itemize Modified the spacing in formulas so that words in the mathnormal font now appear separated, as a product of variables. \end_layout \begin_layout Itemize Do not show limit symbols such as \begin_inset Formula $\sum$ \end_inset or \begin_inset Formula $\int$ \end_inset in a larger font than the rest for inline formulas. \end_layout \begin_layout Itemize Added support for \backslash textcircled: \begin_inset Formula $\textcircled w$ \end_inset . \end_layout \end_deeper \begin_layout Itemize 1.2.0 (2011-01-30): \end_layout \begin_deeper \begin_layout Itemize Bumped LyX version support to 410. \end_layout \begin_layout Itemize Correctly create big brackets for environments with odd alignments such as matrix (thanks, Günther!). \end_layout \begin_layout Itemize Create and use big brackets for fractions and other structures, if needed. \end_layout \begin_layout Itemize Added option \family typewriter --simplemath \family default to avoid fancy math structures: do not \emph on \emph default generate multi-line Unicode brackets or stacked limits. \end_layout \begin_layout Itemize eLyXer is now a proper Python package, instead of just a coalesced script \family typewriter elyxer.py \family default containing everything. However only the script is installed right now. \end_layout \begin_layout Itemize Interpret TeXCode (previously known as Evil Red Text) as TeX commands and formulas. \end_layout \begin_layout Itemize Support for TeX commands \family typewriter \backslash textvisiblespace \family default , \family typewriter \backslash AmS \family default , \family typewriter \backslash parbox \family default , \family typewriter \backslash tag \family default , \family typewriter \backslash rule \family default , and more: \begin_inset ERT status open \begin_layout Plain Layout \backslash textvisiblespace \end_layout \end_inset , \begin_inset ERT status open \begin_layout Plain Layout \backslash AmS \end_layout \end_inset . \end_layout \begin_layout Itemize Support for \family typewriter \backslash Game \family default : \family roman \series medium \shape up \size normal \emph off \bar no \noun off \color none \begin_inset Formula $\Game$ \end_inset . \end_layout \begin_layout Itemize Changed the navigation header for \family typewriter --splitpart \family default so that the left and right spans overflow (thanks, Axel!). \end_layout \begin_layout Itemize Bug in \family typewriter --notoclabels \family default : labels such as \begin_inset Quotes eld \end_inset Figure \begin_inset Quotes erd \end_inset should be omitted in the TOC, but not in captions (thanks again, Axel!). \end_layout \begin_layout Itemize Bug in \family typewriter --splitpart \family default : empty navigation links caused the header to look unbalanced, fixed now with a non-breaking space. Also, up link in the main page used to point to itself; now it's an empty link (more thanks, Axel!). \end_layout \begin_layout Itemize Support for \family typewriter \backslash limits \family default and \family typewriter \backslash nolimits \family default : control if the last symbol should show limits above or below the symbol or not. \end_layout \begin_layout Itemize Bug in \family typewriter \backslash vspace \family default : add the vertical space after the command, not before; or at least try to. \end_layout \begin_layout Itemize Bug in \family typewriter \backslash raisebox \family default : parse and display the contents as text mode. \end_layout \begin_layout Itemize Wish list: do not number captions in code listings. \end_layout \begin_layout Itemize Do not install as a module (to run as \family typewriter python -m elyxer \family default ) but only as a script (to run as \family typewriter elyxer.py \family default ). \end_layout \end_deeper \begin_layout Itemize 1.1.2 (2010-12-23): \end_layout \begin_deeper \begin_layout Itemize Wish list: display large Unicode symbols for sums and integrals in display mode. \end_layout \begin_layout Itemize Also in display mode, place limits for commands that take them above or below the symbol, instead of to the right. \end_layout \begin_layout Itemize Support for new Flex insets: Code, MenuItem, Noun, Strong; new Argument, Phantom and line (ruler) insets; new style \family typewriter \backslash strikeout \family default ; new LaTeX commands \family typewriter \backslash href \family default , \family typewriter \backslash newline \family default . \end_layout \begin_layout Itemize BibTeX: apply a combining function only to the following character, not to the next word. \end_layout \begin_layout Itemize Added reference format for \family typewriter vpageref \family default ( \begin_inset Quotes eld \end_inset on page # \begin_inset Quotes erd \end_inset ). \end_layout \begin_layout Itemize Improved math macro parsing: optional parameters, literal parameters, single-let ter parameters, parameter defaults with operations. \end_layout \begin_layout Itemize Display math cases, full-sized binomials ( \family typewriter \backslash dbinom \family default ) and array brackets using Unicode bracket pieces. \end_layout \begin_layout Itemize Change all table-type elements in formulas to spans and do the formatting in the CSS, to generate valid XHTML. \end_layout \begin_layout Itemize Support graceful degradation of fractions and roots when the CSS is not present. \end_layout \begin_layout Itemize Adjusted roots to insert the root power inside the radical symbol. \end_layout \begin_layout Itemize Adjusted nice fractions ( \begin_inset Formula $\nicefrac{3}{4}$ \end_inset ) to improve their appearance. \end_layout \begin_layout Itemize Support for all upright Greek letters: \begin_inset Formula $\upmu$ \end_inset , \begin_inset Formula $\uptau$ \end_inset . \end_layout \end_deeper \begin_layout Itemize 1.1.1 (2010-12-13): \end_layout \begin_deeper \begin_layout Itemize Wish list: understand \family typewriter \backslash url{} \family default in BibTeX files. \end_layout \begin_layout Itemize Wish list: parse math formulas in BibTeX files. \end_layout \begin_layout Itemize Improved support for dotless i and j as \family typewriter \backslash imath \family default and \family typewriter \backslash jmath \family default : \begin_inset Formula $\imath$ \end_inset , \begin_inset Formula $\jmath$ \end_inset . \end_layout \begin_layout Itemize Solved bug when parsing a quoted string inside a BibTeX file containing a comma. \end_layout \begin_layout Itemize Added math environments \family typewriter equation* \family default and \family typewriter matrix \family default . \end_layout \begin_layout Itemize Do not break inline formulas at whitespace (thanks, José Ramón!). \end_layout \begin_layout Itemize Break up the CSS into pieces, and generate an independent \family typewriter math.css \family default for use within \family typewriter math2html.py \family default . \end_layout \begin_layout Itemize Ignore hyphens in option names, so e.g. \family typewriter --split-part \family default is equivalent to \family typewriter --splitpart \family default . \end_layout \begin_layout Itemize Changed \family typewriter --forceformat \family default to \family typewriter --imageformat \family default (kept the old option for backwards compatibility). \end_layout \begin_layout Itemize Wish list: added \family typewriter --imageformat "copy" \family default to just copy images instead of converting them. \end_layout \begin_layout Itemize Wish list: added option \family typewriter --embedcss "file.css" \family default to embed the CSS styles in \family typewriter file.css \family default into the resulting HTML. \end_layout \begin_layout Itemize Wish list: more than one \family typewriter --css \family default options can be added to use several CSS files. \end_layout \begin_layout Itemize Wish list: display sub- and superscript aligned vertically (as in integrals). \end_layout \end_deeper \begin_layout Itemize 1.1.0 (2010-11-23): \end_layout \begin_deeper \begin_layout Itemize Wish list: understand \family typewriter \backslash setcounter \family default in the preamble to set the number of the first Chapter or Section. \end_layout \begin_layout Itemize Generate a new \family typewriter math2html.py \family default file with an API to convert raw LaTeX code to HTML, and a command line utility. \end_layout \begin_layout Itemize Wish list: new option \family typewriter --notoclabels \family default to omit part labels in the TOC. \end_layout \begin_layout Itemize Wish list: make \begin_inset Quotes eld \end_inset show changes in the output \begin_inset Quotes erd \end_inset work for change tracking. \end_layout \begin_layout Itemize Solve an existing issue with Description and List layouts: correct splitting of first words when intermixing styles. \end_layout \begin_layout Itemize Show decorations using Unicode combining characters, whenever possible. \end_layout \begin_layout Itemize Support for \family typewriter \backslash dddot \family default : \begin_inset Formula $\dddot{o}$ \end_inset (with combining character) and \family typewriter \backslash widehat \family default : \begin_inset Formula $\widehat{abc}$ \end_inset (with character on top). \end_layout \begin_layout Itemize Wish list: add several options for \begin_inset CommandInset href LatexCommand href name "footnote generation" target "userguide.html#sub:Footnotes" \end_inset (align markers instead of using superscript, place markers at the bottom of the page, use symbols for markers\SpecialChar \ldots{} ). Also added a generic \family typewriter --footnotes \family default option to aggregate them all. \end_layout \begin_layout Itemize Wish list: use \family typewriter ps:use-cropbox=true \family default in ImageMagick for PostScript and EPS images. \end_layout \begin_layout Itemize Support for dotless i and j: \begin_inset Formula $\text{ı}$ \end_inset , \begin_inset Formula $\text{ȷ}$ \end_inset . \end_layout \end_deeper \begin_layout Itemize 1.0.4 (2010-10-29): \end_layout \begin_deeper \begin_layout Itemize Solved \begin_inset CommandInset href LatexCommand href name "bug #31342" target "https://savannah.nongnu.org/bugs/index.php?31342" \end_inset : detect appendices as they appear instead of looking at the containing layout. \end_layout \begin_layout Itemize Also reported in \begin_inset CommandInset href LatexCommand href name "bug #31342" target "https://savannah.nongnu.org/bugs/index.php?31342" \end_inset : set part name to \begin_inset Quotes eld \end_inset Appendix A-Z \begin_inset Quotes erd \end_inset in the TOC for appendices, instead of showing them as regular chapters or sections. \end_layout \begin_layout Itemize Also reported in \begin_inset CommandInset href LatexCommand href name "bug #31342" target "https://savannah.nongnu.org/bugs/index.php?31342" \end_inset : number parts and books using roman numerals, as in \begin_inset Quotes eld \end_inset Part I \begin_inset Quotes erd \end_inset or \begin_inset Quotes eld \end_inset Book IV \begin_inset Quotes erd \end_inset . \end_layout \begin_layout Itemize Fixed bug due to wrapped float placement not being mandatory anymore, despite what \family typewriter EmbeddedObjects.lyx \family default says (thanks, Hans!). \end_layout \begin_layout Itemize Solved \begin_inset CommandInset href LatexCommand href name "bug #31351" target "https://savannah.nongnu.org/bugs/index.php?31351" \end_inset : do not number (or add to the TOC) any document parts inside comments. \end_layout \begin_layout Itemize Also in \begin_inset CommandInset href LatexCommand href name "bug #31351" target "https://savannah.nongnu.org/bugs/index.php?31351" \end_inset : the bibliography should be added to the TOC if so configured (and not inside a comment), and split into its own page with \family typewriter --splitpart \family default . \end_layout \begin_layout Itemize Also in \begin_inset CommandInset href LatexCommand href name "bug #31351" target "https://savannah.nongnu.org/bugs/index.php?31351" \end_inset : show the bibliography in regular size, not smaller than the main text as before. \end_layout \begin_layout Itemize Changed header from \begin_inset Quotes eld \end_inset Bibliography \begin_inset Quotes erd \end_inset to \begin_inset Quotes eld \end_inset References \begin_inset Quotes erd \end_inset for document classes other than book and report. \end_layout \begin_layout Itemize Solved \begin_inset CommandInset href LatexCommand href name "bug #31414" target "https://savannah.nongnu.org/bugs/index.php?31414" \end_inset : bootstrap creation of \family typewriter conf/config.py \family default . \end_layout \begin_layout Itemize Also in \begin_inset CommandInset href LatexCommand href name "bug #31414" target "https://savannah.nongnu.org/bugs/index.php?31414" \end_inset : remodeled unit tests to try out Python 2.4 only if present, and to remove test files from previous runs. \end_layout \begin_layout Itemize Show the \begin_inset Quotes eld \end_inset Abstract \begin_inset Quotes erd \end_inset header only for the first Abstract layout (thanks, Yaron!). \end_layout \begin_layout Itemize Do not separate consecutive Abstract paragraphs, and display the abstract in slightly smaller font size. \end_layout \begin_layout Itemize Solved \begin_inset CommandInset href LatexCommand href name "bug #31345" target "https://savannah.nongnu.org/bugs/index.php?31345" \end_inset : ignore preamble and comments in BibTeX files. Use string definitions ( \family typewriter @string \family default ) in other entries. \end_layout \begin_layout Itemize Also in \begin_inset CommandInset href LatexCommand href name "bug #31345" target "https://savannah.nongnu.org/bugs/index.php?31345" \end_inset : avoid endless loops for undesired characters in BibTeX entries. \end_layout \begin_layout Itemize Support for \family typewriter \backslash fbox \family default , \family typewriter \backslash boxed \family default , \family typewriter \backslash framebox \family default and \family typewriter \backslash fcolorbox \family default : \begin_inset Formula $\fbox{\ensuremath{fbox}}$ \end_inset , \begin_inset Formula $\boxed{boxed}$ \end_inset , \begin_inset Formula $\framebox[25mm][l]{framebox}$ \end_inset . \end_layout \end_deeper \begin_layout Itemize 1.0.3 (2010-10-15): \end_layout \begin_deeper \begin_layout Itemize Do not hide errors when parsing child documents. \end_layout \begin_layout Itemize Correctly convert documents even when images are not found. \end_layout \begin_layout Itemize Do not center the content in figure or table floats by default. \end_layout \begin_layout Itemize Correctly convert child documents even when inserted in layouts. \end_layout \begin_layout Itemize Generate navigation bars for first page created with \family typewriter --splitpart \family default . \end_layout \begin_layout Itemize Added wishlist to the user guide to keep track of requested features. \end_layout \begin_layout Itemize Solved \begin_inset CommandInset href LatexCommand href name "bug #31243" target "https://savannah.nongnu.org/bugs/index.php?31243" \end_inset : spaces and comments in formulas (command definitions, empty formulas\SpecialChar \ldots{} ). \end_layout \begin_layout Itemize Also reported in \begin_inset CommandInset href LatexCommand href name "bug #31243" target "https://savannah.nongnu.org/bugs/index.php?31243" \end_inset : do not add numbering twice to child documents, and ignore child documents in comments. \end_layout \begin_layout Itemize Added support for \family typewriter \backslash stackrel \family default : \begin_inset Formula $x\stackrel{R}{\rightarrow}y$ \end_inset (thanks, José Ramón!). \end_layout \begin_layout Itemize Added a lot of escaped characters to BibTeX parsing: \family typewriter \backslash ~n \family default , \family typewriter \backslash '{ \backslash i} \family default \SpecialChar \ldots{} Also added a field \family typewriter note \family default to all BibTeX styles. \end_layout \begin_layout Itemize Show all references (even those not cited) in the bibliography if configured to do so. \end_layout \begin_layout Itemize Understand relative sizes (e.g. \family typewriter 10col% \family default ) in spaces (thanks, Uwe!). \end_layout \end_deeper \begin_layout Itemize 1.0.2 (2010-09-20): \end_layout \begin_deeper \begin_layout Itemize Updated \begin_inset CommandInset href LatexCommand href name "MathJax" target "http://www.mathjax.org/" \end_inset to version 1.0.1 -- no changes to eLyXer documents are necessary. \end_layout \begin_layout Itemize Added option \family typewriter --noconvert \family default to use images in their original formats, and avoid converting images altogether. \end_layout \begin_layout Itemize Output \family typewriter \family default tags for SVG images. Size information is not used as it causes problems on Firefox. \end_layout \begin_layout Itemize BibTeX: include \family typewriter booktitle \family default tag for the \family typewriter @incollection \family default format. \end_layout \begin_layout Itemize BibTex: added a tag \family typewriter \family default around all bibliographical cites, so they can be e.g. superscripted. \end_layout \begin_layout Itemize Show footnotes as hovering text instead of as marginal notes. Make the default footnote marker a bluish superscript letter in brackets: \begin_inset Foot status open \begin_layout Plain Layout like this \end_layout \end_inset . \end_layout \begin_layout Itemize Updated \family typewriter --lyxformat \family default to 398 (2.0alpha5); added warning if document version is bigger than that. \end_layout \begin_layout Itemize Support for \family typewriter \backslash textless \family default and \family typewriter \backslash textgreater \family default : \begin_inset Formula $\textless$ \end_inset , \begin_inset Formula $\textgreater$ \end_inset . \end_layout \begin_layout Itemize Added adjustments for better printing to default CSS. \end_layout \begin_layout Itemize Added languages \begin_inset Quotes eld \end_inset british \begin_inset Quotes erd \end_inset and \begin_inset Quotes eld \end_inset american \begin_inset Quotes erd \end_inset (which translate to plain English). \end_layout \begin_layout Itemize Avoid extracting indexes out of the containing layout if there is anything else in there (thanks, Amy!). This bug caused some content to be lost (e.g. child documents) if they were inside the same layout as e.g. an alphabetical index. \end_layout \end_deeper \begin_layout Itemize 1.0.1 (2010-09-01): \end_layout \begin_deeper \begin_layout Itemize BibTeX: more robust parsing, specifically: correctly parse entries separated by commas. Support all TeX commands already available in math formulae. \end_layout \begin_layout Itemize Support for \family typewriter \backslash textasciitilde \family default : \begin_inset Formula $\textasciitilde$ \end_inset , \family typewriter \backslash textasciicircum \family default : \begin_inset Formula $\textasciicircum$ \end_inset and a few other \family typewriter \backslash text\SpecialChar \ldots{} \family default symbols. Also, \family typewriter \backslash textrm \family default , \family typewriter \backslash textsf \family default and \family typewriter \backslash textnormal \family default should be working now in equations: \begin_inset Formula $a+\textrm{roman}+\textsf{sans-serif}+\textnormal{normal}+b$ \end_inset . \end_layout \begin_layout Itemize Improved support for custom horizontal and vertical spaces; absolute measures can now be used. \end_layout \begin_layout Itemize Support for sizes in table columns, figures and boxes. \end_layout \begin_layout Itemize Solved bug in \family typewriter --nofooter \family default which required a dummy argument (thanks, Yan!). \end_layout \begin_layout Itemize Corrected box styling: \family typewriter
\family default is now indeed frameless, while \family typewriter
\family default no longer has a double border. \end_layout \begin_layout Itemize Solved bug in text handling which separated consecutive centered lines with a space. \end_layout \begin_layout Itemize Basic support for LyX change tracking. \end_layout \end_deeper \begin_layout Itemize 1.0.0 (2010-07-21): \end_layout \begin_deeper \begin_layout Itemize Replicate the navigation bar for \family typewriter --splitpart \family default at the bottom of pages. Use translated strings for \begin_inset Quotes eld \end_inset Previous \begin_inset Quotes erd \end_inset , \begin_inset Quotes eld \end_inset Up \begin_inset Quotes erd \end_inset and \begin_inset Quotes eld \end_inset Next \begin_inset Quotes erd \end_inset links. Also added an explanatory text to the \begin_inset Quotes eld \end_inset up \begin_inset Quotes erd \end_inset link in the navigation bar, as in: \begin_inset Quotes eld \end_inset Up: Chapter 1 \begin_inset Quotes erd \end_inset . \end_layout \begin_layout Itemize Added partial table of contents to pages generated with \family typewriter --splitpart \family default . \end_layout \begin_layout Itemize Dependency cleanup between code modules. \end_layout \begin_layout Itemize Child documents of type \begin_inset Quotes eld \end_inset verbatim input \begin_inset Quotes erd \end_inset are now correctly converted on versions of Python built without universal newline support. \end_layout \begin_layout Itemize Include Index and Nomenclature in the Table of Contents. \end_layout \begin_layout Itemize When an Index, TOC, List of Figures\SpecialChar \ldots{} and the like is embedded in another layout, do not follow the style of the layout (thanks, Yaron!). \end_layout \begin_layout Itemize Solved a couple of XHTML validation errors: removed asterisks (*) in anchor names, avoid empty rows in arrays or case statements. \end_layout \begin_layout Itemize Make index entries work in Descriptions. Also, mixed styles should work again within Descriptions. \end_layout \begin_layout Itemize Group certain layouts together, such as Quote and Quotation. \end_layout \begin_layout Itemize Improved output for algorithms: do not run lines together, and do not separate other lines with double space. \end_layout \begin_layout Itemize List of algorithms does now correctly extract the text from the caption. \end_layout \begin_layout Itemize Increased line height for h2 in the main CSS (thanks, Wolfgang!). \end_layout \begin_layout Itemize Better color support in formulas: \family typewriter \backslash color \family default , \family typewriter \backslash textcolor \family default , \family typewriter \backslash colorbox \family default . \begin_inset Formula ${\color{blue}blue}$ \end_inset , \begin_inset Formula $\colorbox{yellow}{\color{blue}blue}$ \end_inset . \end_layout \begin_layout Itemize Formulas and formula labels are not colored by default. \end_layout \begin_layout Itemize Improved Index output: there is only one anchor for each entry, and entries are not shown in italics. \end_layout \begin_layout Itemize Allow hierarchical index entries, of the form \begin_inset Quotes eld \end_inset Main ! Secondary ! Final \begin_inset Quotes erd \end_inset . \end_layout \end_deeper \begin_layout Itemize 0.99 (2010-06-24): \end_layout \begin_deeper \begin_layout Itemize Added \family typewriter --splitpart \family default to online help (thanks, Sven!). \end_layout \begin_layout Itemize Restored compatibility with Python 2.4 (lost in 0.98 by mistake), added test to ensure it does not happen again. \end_layout \begin_layout Itemize BibTeX: improved template definitions for Vancouver style. \end_layout \begin_layout Itemize BibTeX: better parsing of braces (in templates) and quotes (in \family typewriter .bib \family default files). Nested braces in templates are supported. \end_layout \begin_layout Itemize BibTeX: variable citing styles. Enclose cites in brackets instead of using superscripts. \end_layout \begin_layout Itemize BibTeX: export all BibTeX variables in \family typewriter bib-\SpecialChar \ldots{} \family default spans. \end_layout \begin_layout Itemize BibTeX: limited author parsing, support for surname abbreviations as in style \emph on alpha \emph default . \end_layout \begin_layout Itemize BibTeX: use the \family typewriter file \family default tag to show a link to the local file. \end_layout \begin_layout Itemize Added \family typewriter \backslash oint \family default and friends as a bigsymbol: \begin_inset Formula $\oint x\text{·}dx$ \end_inset . \end_layout \begin_layout Itemize Support for \family typewriter \backslash officialeuro \family default : \begin_inset Formula $\officialeuro$ \end_inset . \end_layout \begin_layout Itemize Fix captions in lists of figures which use standard layouts (thanks, Hans!). \end_layout \begin_layout Itemize Added option \family typewriter --template \family default to use an HTML template and substitute \family typewriter \family default , \family typewriter \family default \SpecialChar \ldots{} \end_layout \begin_layout Itemize Added option \family typewriter --copyright \family default to add a copyright notice at the bottom (no longer generated by default). Deprecated old option \family typewriter --nocopy \family default . \end_layout \begin_layout Itemize Added support for including files as a code listing. \end_layout \end_deeper \begin_layout Itemize 0.98 (2010-05-13): \end_layout \begin_deeper \begin_layout Itemize MathJax: workaround bug in MSIE, that causes it to fail to render anything. \end_layout \begin_layout Itemize Add a margin to LyX-Code. Also improve line break separation inside LyX-Code. \end_layout \begin_layout Itemize Coalesce Python code: use relative paths when importing (thanks, Jack!). \end_layout \begin_layout Itemize Experimental installation script. \end_layout \begin_layout Itemize Avoid postprocessing child documents twice (thanks, Rainer!). \end_layout \begin_layout Itemize Solved bug when loading images from child documents in subdirectories (thanks, Rainer!). \end_layout \begin_layout Itemize Solved bug in image scaling when only one dimension is set (thanks, Wolfgang!). \end_layout \begin_layout Itemize Corrected issue with one-liner \family typewriter \backslash lstset \family default (thanks again, Rainer!). \end_layout \begin_layout Itemize Improved lists of figures, tables and algorithms: use short title, better labeling of floats. \end_layout \begin_layout Itemize Solved weird bug in float numbering when a chapter has only one layout. \end_layout \begin_layout Itemize Added \family typewriter \backslash diagup \family default and \family typewriter \backslash diagdown \family default : \begin_inset Formula $\diagup$ \end_inset , \begin_inset Formula $\diagdown$ \end_inset . \end_layout \begin_layout Itemize First public release of option \family typewriter --splitpart [level] \family default : split resulting web page at the given level. \end_layout \begin_layout Itemize Support for macros, both in LyX macro inset and as \family typewriter \backslash newcommand \family default . \end_layout \begin_layout Itemize Added URLs to most BibTeX formats. \end_layout \begin_layout Itemize Added BibTeX style \begin_inset Quotes eld \end_inset vancouver \begin_inset Quotes erd \end_inset for articles (thanks, John!). \end_layout \begin_layout Itemize Added a footer detailing eLyXer version and conversion date; it can be turned off with \family typewriter --nofooter \family default . \end_layout \end_deeper \begin_layout Itemize 0.43 (2010-04-10): \end_layout \begin_deeper \begin_layout Itemize Many BibTeX improvements: new style \emph on abbrvnat \emph default , conditional formatting, look up types in lowercase, understand \begin_inset Quotes eld \end_inset -- \begin_inset Quotes erd \end_inset as dash. \end_layout \begin_layout Itemize Added options for mathematical equations: \family typewriter --jsmath \family default to use \begin_inset CommandInset href LatexCommand href name "jsMath" target "math-jsmath.html" \end_inset and \family typewriter --mathjax \family default to use \begin_inset CommandInset href LatexCommand href name "MathJax" target "math-jsmath.html" \end_inset . \end_layout \begin_layout Itemize Added command help to \family typewriter loremipsumize.py \family default so it can be used outside of eLyXer. \end_layout \begin_layout Itemize Include internationalization files in \family typewriter .zip \family default file. \end_layout \begin_layout Itemize Solved bug in table parsing: separate different plain layouts (thanks, Sara!). \end_layout \begin_layout Itemize eLyXer compressed files now contain a single directory called \family typewriter elyxer-$VERSION \family default , instead of just \family typewriter elyxer \family default . \end_layout \begin_layout Itemize Added italicized uppercase Greek letters: \begin_inset Formula $\varGamma\varOmega$ \end_inset . De-italicized regular uppercase Greek letters: \begin_inset Formula $\Gamma\Omega$ \end_inset . \end_layout \end_deeper \begin_layout Itemize 0.42 (2010-03-17): \end_layout \begin_deeper \begin_layout Itemize Changed author everywhere to the real name, to avoid any copyleft uncertainties. \end_layout \begin_layout Itemize Remove hook in the main text ( \color green [D→] \color inherit ) from margin notes. \end_layout \begin_layout Itemize Do not crash when BibTeX files are not found, just show an error. \end_layout \begin_layout Itemize Added support for some IPA characters, including \begin_inset Formula $\textcrh$ \end_inset . Better parsing of \family typewriter \backslash textipa \family default text. \end_layout \begin_layout Itemize Added option \family typewriter --numberfoot \family default to label footnotes with numbers instead of letters. \end_layout \begin_layout Itemize Solved bug in assignment of default formatting to references (thanks, Hans!). \end_layout \begin_layout Itemize Added option \family typewriter --raw \family default to output raw HTML without header or footer. \end_layout \begin_layout Itemize Added French and Dutch translations. \end_layout \begin_layout Itemize Solved indenting problem for lists: only the first line was being indented. \end_layout \end_deeper \begin_layout Itemize 0.41 (2010-02-11): \end_layout \begin_deeper \begin_layout Itemize Select the translation based on document language. \end_layout \begin_layout Itemize Added em-dash --- such as in this sentence, \begin_inset Formula $\blacksquare$ \end_inset , \family typewriter \backslash textup \family default . \end_layout \begin_layout Itemize Added option \family typewriter --converter inkscape \family default to use Inkscape as SVG converter. \end_layout \begin_layout Itemize Solved bug when numbering unordered unique parts such as Part* (thanks, Geremy!). \end_layout \begin_layout Itemize Show error instead of crashing when included document does not exist. \end_layout \begin_layout Itemize Support for all box styles. In CSS: switched to \family typewriter outline-style \family default instead of \family typewriter border \family default for boxes. \end_layout \begin_layout Itemize Support for vertical space insets. \end_layout \begin_layout Itemize Support for references inside paragraphs and formatted references. \end_layout \begin_layout Itemize Listings are now converted using \family typewriter
\family default
 tags, instead of 
\family typewriter

\family default
.
 They are also justified left.
\end_layout

\begin_layout Itemize
Solved bug that prevented numbered listings to appear numbered (thanks,
 Sam!).
\end_layout

\begin_layout Itemize
Support for generic Flex insets, incuding 
\family typewriter
Flex CharStyle:MenuItem
\family default
.
\end_layout

\begin_layout Itemize
All 
\family typewriter
 
\family default
 entities are now generated as the Unicode U+00A0 character.
\end_layout

\begin_layout Itemize
New option 
\family typewriter
--iso885915
\family default
 to generate a document with ISO-8859-15 encoding.
\end_layout

\begin_layout Itemize
Support for Sam Liddicott's 
\begin_inset CommandInset href
LatexCommand href
name "Newfangle module"
target "http://repo.or.cz/w/newfangle.git/blob_plain/master:/www/docs/newfangle.html"

\end_inset

 for literate programming.
\end_layout

\begin_layout Itemize
Updated the developer guide for potential contributors; added link from
 the main page.
\end_layout

\begin_layout Itemize
Support for 
\family typewriter

\backslash
underbrace
\family default
 and 
\family typewriter

\backslash
overbrace
\family default
 (as bars and without sub/superscripts).
\end_layout

\end_deeper
\begin_layout Itemize
0.40 (2010-01-19):
\end_layout

\begin_deeper
\begin_layout Itemize
Faster (about 25%) BibTeX file parsing.
\end_layout

\begin_layout Itemize
Show version number after a crash.
\end_layout

\begin_layout Itemize
Imported Jens Nöckel's contributed list of LaTeX to Unicode mappings: 
\begin_inset Formula $\divideontimes$
\end_inset

, 
\begin_inset Formula $\backepsilon$
\end_inset

 and many more.
\end_layout

\begin_layout Itemize
Added support for compressed documents (Document\SpecialChar \menuseparator
Compressed).
\end_layout

\begin_layout Itemize
Added configurable alignment support for equation environments (thanks,
 Jens!).
 Multiple labels per formula are correctly processed.
\end_layout

\begin_layout Itemize
Added a couple of note insets for Tufte document classes, appearing as side
 notes without a reference (thanks, Joachim!).
\end_layout

\begin_layout Itemize
Support for escaped characters in BibTeX files, added German umlauts for
 starters.
\end_layout

\begin_layout Itemize
Support for internationalization using GNU gettext files.
 Added Spanish and German translations in the 
\family typewriter
po/
\family default
 folder.
\end_layout

\begin_layout Itemize
Support for verbatim includes.
\end_layout

\end_deeper
\begin_layout Itemize
0.39 (2009-12-20):
\end_layout

\begin_deeper
\begin_layout Itemize
Avoid oversized images on IE6.
\end_layout

\begin_layout Itemize
Solved several crashes with the LyX documentation (thanks, Uwe!).
\end_layout

\begin_layout Itemize
Created script to lorem-ipsumize texts, found in 
\family typewriter
src/loremipsumize.py
\family default
.
\end_layout

\begin_layout Itemize
Solved some issues with BibTeX parsing; now it should work with most real-world
 files (thanks, Ken!).
 Also improved error reporting and implemented a new way of line-by-line
 parsing from file, activated with 
\family typewriter
--lowmem
\family default
.
\end_layout

\begin_layout Itemize
Support for binomial coefficients: 
\begin_inset Formula $\binom{A}{B}$
\end_inset

.
 Ignore commands 
\family typewriter

\backslash
leftroot
\family default
, 
\family typewriter

\backslash
uproot
\family default
.
 Generic support for variable commands in math mode.
\end_layout

\begin_layout Itemize
Support for omitted aligned brackets: 
\begin_inset Formula $\left.right\right)$
\end_inset

 (thanks, Jens!).
\end_layout

\begin_layout Itemize
Solved bug with image conversion from directories (thanks, Olivier!).
\end_layout

\end_deeper
\begin_layout Itemize
0.38 (2009-12-03):
\end_layout

\begin_deeper
\begin_layout Itemize
Resized all logos in the documentation.
\end_layout

\begin_layout Itemize
Solved bug in paragraph indentation that indented all formula spans and
 elements.
\end_layout

\begin_layout Itemize
Solved a couple of bugs in image scaling: wraps with images, images in figures.
\end_layout

\begin_layout Itemize
Solved bug in TOC generation: article-class documents had their TOC depth
 off-by-one.
\end_layout

\begin_layout Itemize
Solved bug with listings inserted in documents using LyX 1.6, and improved
 their looks.
\end_layout

\begin_layout Itemize
Slight font size reduction on Firefox, and huge reduction on some other
 proprietary browsers.
 Now global font size specification is done using percents.
\end_layout

\begin_layout Itemize
New commands: 
\family typewriter

\backslash
gtrless
\family default
: 
\begin_inset Formula $\gtrless$
\end_inset

, 
\family typewriter

\backslash
complement
\family default
: 
\begin_inset Formula $\complement$
\end_inset

, 
\family typewriter

\backslash
measuredangle
\family default
: 
\begin_inset Formula $\measuredangle$
\end_inset

, 
\family typewriter

\backslash
sphericalangle
\family default
: 
\begin_inset Formula $\sphericalangle$
\end_inset

, 
\family typewriter

\backslash
nmid
\family default
: 
\begin_inset Formula $\nmid$
\end_inset

, 
\family typewriter

\backslash
circeq
\family default
: 
\begin_inset Formula $\circeq$
\end_inset

, 
\family typewriter

\backslash
lessgtr
\family default
: 
\begin_inset Formula $\lessgtr$
\end_inset

, 
\family typewriter

\backslash
nparallel
\family default
: 
\begin_inset Formula $\nparallel$
\end_inset

.
\end_layout

\end_deeper
\begin_layout Itemize
0.37 (2009-11-30):
\end_layout

\begin_deeper
\begin_layout Itemize
Further improvements in float manipulation: figures enclosing other figures
 have their own tweaked CSS class (thanks, Olivier).
\end_layout

\begin_layout Itemize
PNG and JPEG images are not rescaled anymore, and never shown above their
 maximum size.
 Width and height are set using CSS properties.
\end_layout

\begin_layout Itemize
TOC generation for unordered entries (like 
\family typewriter
Section*
\family default
) and entries inserted in other layouts.
 Max TOC depth and max numbering depth are honored.
 Also solved bug in tagging of unordered parts.
\end_layout

\begin_layout Itemize
Implemented indented paragraphs when specified in the document.
\end_layout

\begin_layout Itemize
Horizontal fill is now shown as a fixed-width space.
\end_layout

\begin_layout Itemize
Simplified postprocessing code.
 Inclusion of child documents is now done inside a Standard layout.
\end_layout

\begin_layout Itemize
Support for commands 
\family typewriter

\backslash
varkappa
\family default
: 
\begin_inset Formula $\varkappa$
\end_inset

, 
\family typewriter

\backslash
varnothing
\family default
: 
\begin_inset Formula $\varnothing$
\end_inset

, 
\family typewriter

\backslash
mathring
\family default
: 
\begin_inset Formula $\mathring{A}$
\end_inset

, 
\family typewriter

\backslash
backprime
\family default
: 
\begin_inset Formula $\backprime$
\end_inset

, 
\family typewriter

\backslash
notin
\family default
: 
\begin_inset Formula $\notin$
\end_inset

, 
\family typewriter

\backslash
hfill
\family default
: 
\begin_inset Formula $\hfill$
\end_inset

, 
\family typewriter

\backslash
circledR
\family default
: 
\begin_inset Formula $\circledR$
\end_inset

, 
\family typewriter

\backslash
hslash
\family default
: 
\begin_inset Formula $\hslash$
\end_inset

.
\end_layout

\begin_layout Itemize
New option 
\family typewriter
--splitpart
\family default
 to split the output in multiple pages, one page per part; needs more tweaking.
\end_layout

\end_deeper
\begin_layout Itemize
0.36 (2009-11-19):
\end_layout

\begin_deeper
\begin_layout Itemize
New in-memory processing of a document before file output, activated by
 default.
 It includes: TOC generation (TOC entries admit typefaces, colors, weights,
 spaces, short titles but restrict most other content), sequential numbering
 to bibliography entries, lists of floats (figures, tables, algorithms),
 correct labeling of references and use of the embedded title as HTML title.
\end_layout

\begin_layout Itemize
New option 
\family typewriter
--lowmem
\family default
 to do one-pass filtering only, to preserve memory (keeping the old behavior).
\end_layout

\begin_layout Itemize
Updated the 
\begin_inset CommandInset href
LatexCommand href
name "developer guide"
target "devguide.html"

\end_inset

.
\end_layout

\begin_layout Itemize
Change the postprocessing of equation labels so that only one anchor is
 used for the whole equation.
\end_layout

\begin_layout Itemize
Added 
\family typewriter

\backslash
mathscr
\family default
 and a few script fonts: 
\begin_inset Formula $\mathscr{hello}$
\end_inset

.
 Added several characters for math script (
\family typewriter

\backslash
mathscr
\family default
), fraktur (
\family typewriter

\backslash
mathfrak
\family default
) and blackboard (
\family typewriter

\backslash
mathbb
\family default
) fonts, and implemented the translation to Unicode chars: 
\begin_inset Formula $\mathscr{F}$
\end_inset

, 
\begin_inset Formula $\mathfrak{F}$
\end_inset

, 
\begin_inset Formula $\mathbb{F}$
\end_inset

.
\end_layout

\begin_layout Itemize
New math commands: 
\family typewriter

\backslash
dfrac
\family default
, implemented as 
\family typewriter

\backslash
cfrac
\family default
; 
\family typewriter

\backslash
c
\family default
 for cedilla, already implemented as characters and now as decoration: 
\begin_inset Formula $\c{G}$
\end_inset

; thick space 
\family typewriter

\backslash
;
\family default
 and quotes 
\family typewriter
"
\family default
: 
\begin_inset Formula $"\;"$
\end_inset

; 
\family typewriter

\backslash
hspace
\family default
 for horizontal space and 
\family typewriter

\backslash
vspace
\family default
 for vertical space; and a few size commands: 
\family typewriter

\backslash
big
\family default
, 
\family typewriter

\backslash
Big
\family default
, 
\family typewriter

\backslash
bigg
\family default
, 
\family typewriter

\backslash
Bigg
\family default
, 
\family typewriter

\backslash
middle
\family default
.
\end_layout

\begin_layout Itemize
Added a 
\family typewriter
parent
\family default
 attribute to every 
\family typewriter
Container
\family default
, for easier processing.
\end_layout

\begin_layout Itemize
Image conversion and display: process width and height in an image if both
 are present; use % width of image within a float to scale the float; set
 max scaling of images to 100% with 
\family typewriter
max-width
\family default
 CSS attribute.
 (Thanks, Olivier and Uwe.)
\end_layout

\begin_layout Itemize
Subfloats are numbered (a), (b) (instead of 
\begin_inset Formula $x.y$
\end_inset

a, 
\begin_inset Formula $x.y$
\end_inset

b).
\end_layout

\begin_layout Itemize
Convert all pathnames for image conversion using 
\family typewriter
sys.getfilesystemencoding()
\family default
.
\end_layout

\end_deeper
\begin_layout Itemize
0.35 (2009-11-05):
\end_layout

\begin_deeper
\begin_layout Itemize
Added new characters: 
\family typewriter

\backslash
checkmark
\family default
 
\begin_inset Formula $\checkmark$
\end_inset

, 
\family typewriter

\backslash
blacklozenge
\family default
 
\begin_inset Formula $\blacklozenge$
\end_inset

, 
\family typewriter

\backslash
nexists
\family default
 
\begin_inset Formula $\nexists$
\end_inset

, 
\family typewriter

\backslash
mathcircumflex
\family default
 
\begin_inset Formula $\mathcircumflex$
\end_inset

.
\end_layout

\begin_layout Itemize
Updated all documentation to LyX 1.6.
\end_layout

\begin_layout Itemize
Solved CSS validation error in 
\family typewriter
table.align
\family default
 (thanks, Olivier).
\end_layout

\begin_layout Itemize
Solved XHTML validation error in greyed out note, removing useless 
\family typewriter
div
\family default
s.
\end_layout

\begin_layout Itemize
Add a space after a fraction and before the units: 
\begin_inset Formula $\unit[\nicefrac{3}{2}]{km}$
\end_inset

, 
\begin_inset Formula $\unit[\frac{7}{16}]{s}$
\end_inset

.
\end_layout

\begin_layout Itemize
Corrected display of float within a float (thanks again, Olivier!).
\end_layout

\begin_layout Itemize
Modified the meaning of 
\family typewriter
--toc
\family default
 to be an on/off switch; the old behavior is now under 
\family typewriter
--toctarget
\family default
.
\end_layout

\begin_layout Itemize
Changed the 2009-11-05 option 
\family typewriter
--cutpart
\family default
 to 
\family typewriter
--splitpart
\family default
: new option to split the output file in parts.
 Not yet working correctly (for instance, links are not redirected).
\end_layout

\begin_layout Itemize
eLyXer now understands and processes new Graphics options: 
\family typewriter
width 50col%
\family default
, 
\family typewriter
height 50theight%
\family default
 and friends (thanks, Uwe).
\end_layout

\begin_layout Itemize
PDF images are cropped before conversion to PNG (thanks, Uwe).
\end_layout

\begin_layout Itemize
Included child documents can be inserted using firstline and lastline (as
 seen in 
\family typewriter
EmbeddedObjects.lyx
\family default
).
\end_layout

\end_deeper
\begin_layout Itemize
0.34 (2009-10-28):
\end_layout

\begin_deeper
\begin_layout Itemize
Support for child document inclusion (Insert\SpecialChar \menuseparator
File\SpecialChar \menuseparator
Child Document\SpecialChar \ldots{}
).
\end_layout

\begin_layout Itemize
Avoid generating images on different directories (relative paths starting
 with 
\family typewriter
../
\family default
).
\end_layout

\begin_layout Itemize
Added 
\family typewriter

\backslash
maltese
\family default
 
\begin_inset Formula $\maltese$
\end_inset

 and financial symbols $, €, ¥.
\end_layout

\begin_layout Itemize
Removed annoying message 
\begin_inset Quotes eld
\end_inset

Unexpected end of bracket
\begin_inset Quotes erd
\end_inset

 when parsing empty brackets.
\end_layout

\begin_layout Itemize
Support for 
\family typewriter

\backslash
raisebox
\family default
.
\end_layout

\begin_layout Itemize
Created new structure of 
\family typewriter
Writer
\family default
s, preparing for document segmentation and TOC generation.
\end_layout

\end_deeper
\begin_layout Itemize
0.33 (2009-10-19):
\end_layout

\begin_deeper
\begin_layout Itemize
New TOC generation process based on an already-generated HTML document,
 not ready for prime time yet.
\end_layout

\begin_layout Itemize
Adapted 
\family typewriter
--help
\family default
 option so that it shows the executable file as invoked (
\family typewriter
elyxer.py
\family default
, 
\family typewriter
elyxer
\family default
 or whatever).
 Expanded online help from this command.
\end_layout

\begin_layout Itemize
Support for new text commands 
\family typewriter

\backslash
textsf
\family default
, 
\family typewriter

\backslash
texttt
\family default
, 
\family typewriter

\backslash
textit
\family default
, 
\family typewriter

\backslash
textbf
\family default
, 
\family typewriter

\backslash
textsl
\family default
, 
\family typewriter

\backslash
textsc
\family default
.
\end_layout

\begin_layout Itemize
Properly parse all text commands 
\family typewriter

\backslash
text\SpecialChar \ldots{}

\family default
, including 
\family typewriter

\backslash
textipa
\family default
.
\end_layout

\begin_layout Itemize
Support for 
\family typewriter

\backslash
cfrac
\family default
.
 Now regular 
\family typewriter

\backslash
frac
\family default
 shows embedded formulas smaller.
\end_layout

\begin_layout Itemize
Do not number equations containing 
\family typewriter
*
\family default
, like in 
\family typewriter

\backslash
begin{align*}
\family default
.
 (Once more, thanks Uwe.)
\end_layout

\begin_layout Itemize
Properly align equations for AMS align environment.
 Other environments are parsed but not necessarily honored.
\end_layout

\begin_layout Itemize
Correctly distinguish 
\family typewriter

\backslash
epsilon
\family default
 
\begin_inset Formula $\epsilon$
\end_inset

 from 
\family typewriter

\backslash
varepsilon
\family default
 
\begin_inset Formula $\varepsilon$
\end_inset

.
\end_layout

\begin_layout Itemize
Added TeX-to-Unicode mappings from 
\begin_inset CommandInset href
LatexCommand href
name "Markus Kuhn"
target "http://www.cl.cam.ac.uk/~mgk25/ucs/examples/TeX.txt"

\end_inset

.
\end_layout

\begin_layout Itemize
Support for 
\family typewriter

\backslash
unitfrac
\family default
.
\end_layout

\begin_layout Itemize
Added 
\family typewriter

\backslash
dots
\family default
: 
\begin_inset Formula $\dots$
\end_inset

.
\end_layout

\end_deeper
\begin_layout Itemize
0.32 (2009-10-05):
\end_layout

\begin_deeper
\begin_layout Itemize
Fixed unit processing.
 Now units appear separated by a space after the number.
\end_layout

\begin_layout Itemize
Repaired use of 
\family typewriter
AlphaCommand
\family default
s.
 Decorations so defined in the configuration file appear again as a single
 symbol: 
\begin_inset Formula $\hat{a}$
\end_inset

.
\end_layout

\begin_layout Itemize
Added option 
\family typewriter
--lyxformat
\family default
 to return the highest LyX format that eLyXer understands.
 Should help when integrating with 
\family typewriter
lyx2lyx
\family default
.
\end_layout

\begin_layout Itemize
Improved TOC (table of contents) generation.
 Modified option 
\family typewriter
--toc
\family default
 to accept an URL, and documented it.
\end_layout

\begin_layout Itemize
Added option 
\family typewriter
--target
\family default
 to add a target frame to every link.
\end_layout

\begin_layout Itemize
Corrected equation numbering error: now all 
\family typewriter

\backslash
begin{equation}\SpecialChar \ldots{}

\backslash
end{equation}
\family default
 formulae are numbered.
 (Thanks once more, Uwe.)
\end_layout

\end_deeper
\begin_layout Itemize
0.31 (2009-09-27):
\end_layout

\begin_deeper
\begin_layout Itemize
Modified image parsing code to remove dependency on Python 2.5, expurging
 
\family typewriter
os.SEEK_CUR
\family default
.
\end_layout

\begin_layout Itemize
Removed the ill-fated 
\family typewriter
elyxerconv.py
\family default
 library file (but kept 
\family typewriter
io/convert.py
\family default
), see 
\begin_inset CommandInset href
LatexCommand href
name "lyx-devel thread"
target "http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg154647.html"

\end_inset

.
 Now the file 
\family typewriter
elyxer.py
\family default
 itself can be installed as a library, and run as a module with 
\family typewriter
python -m
\family default
.; see also 
\begin_inset CommandInset href
LatexCommand href
name "lyx-devel thread"
target "http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg154749.html"

\end_inset

.
\end_layout

\begin_layout Itemize
eLyXer was added to the Python Package Index (
\begin_inset CommandInset href
LatexCommand href
name "PyPI"
target "http://pypi.python.org/pypi"

\end_inset

) starting with 0.30.
 Now it should be automatically registered for each release.
\end_layout

\begin_layout Itemize
Updated documentation (
\begin_inset CommandInset href
LatexCommand href
name "user guide"
target "userguide.html"

\end_inset

, 
\family typewriter
README
\family default
 file) with details of distutils installation.
\end_layout

\begin_layout Itemize
Modified single string 
\family typewriter
Container
\family default
s (
\family typewriter
StringContainer
\family default
, 
\family typewriter
Constant
\family default
) so that they appear as empty 
\family typewriter
Container
\family default
s -- should speed up postprocessing.
\end_layout

\begin_layout Itemize
Solved bug when parsing BibTeX files with incorrect lines.
\end_layout

\begin_layout Itemize
Modified postprocessing to correctly process lists within tables.
\end_layout

\begin_layout Itemize
In the process refactored postprocessing completely: now instead of unconditiona
l postprocessor stages, each stage can add a postprocessing hook.
 Should be faster -- but is indeed a bit slower.
\end_layout

\end_deeper
\begin_layout Itemize
0.30 (2009-09-13):
\end_layout

\begin_deeper
\begin_layout Itemize
Removed most comments from the final distributed file 
\family typewriter
elyxer.py
\family default
.
\end_layout

\begin_layout Itemize
Added 
\begin_inset CommandInset href
LatexCommand href
name "distutils"
target "http://docs.python.org/distutils/index.html"

\end_inset

 support for cross-platform distribution.
 The library 
\family typewriter
elyxerconv
\family default
 is added to local Python libraries.
\end_layout

\begin_layout Itemize
Added command line option 
\family typewriter
--forceformat
\family default
: force eLyXer to convert all images to the given output format.
\end_layout

\begin_layout Itemize
Switched all options in command line help to quotes: 
\family typewriter
--title
\begin_inset space ~
\end_inset


\series bold
<
\series default
title
\series bold
>
\family default
\series default
 is now 
\family typewriter
--title
\begin_inset space ~
\end_inset


\series bold
"
\series default
title
\series bold
"
\family default
\series default
.
\end_layout

\begin_layout Itemize
Solved bug reported by Uwe Stöhr when reading Windows BibTeX file generated
 by JabRef.
 Now eLyXer tries several encodings for each file, initially UTF-8 and Cp1252.
\end_layout

\begin_layout Itemize
Another bug, also reported by Uwe Stöhr, in branch selection.
 Added test 
\family typewriter
branches.lyx
\family default
.
\end_layout

\end_deeper
\begin_layout Itemize
0.29 (2009-09-08):
\end_layout

\begin_deeper
\begin_layout Itemize
Preliminary support for BibTeX.
 Configurable output styles (albeit cumbersome and quite primitive).
\end_layout

\begin_layout Itemize
Added new cite commands 
\family typewriter
citep
\family default
, 
\family typewriter
citet
\family default
, 
\family typewriter
citealt
\family default
; and reference command 
\family typewriter
prettyref
\family default
.
\end_layout

\begin_layout Itemize
A couple of new math commands: 
\family typewriter

\backslash
ldots
\family default
, 
\family typewriter

\backslash
qquad
\family default
.
\end_layout

\end_deeper
\begin_layout Itemize
0.28 (2009-09-05):
\end_layout

\begin_deeper
\begin_layout Itemize
Various fixes related to Windows integration.
\end_layout

\begin_layout Itemize
Documented integration with LyX in the user guide.
\end_layout

\end_deeper
\begin_layout Itemize
0.27 (2009-06-17):
\end_layout

\begin_deeper
\begin_layout Itemize
Units without the magnitude (the number) are working.
\end_layout

\begin_layout Itemize
Complex roots now working, added to the math showcase.
\end_layout

\begin_layout Itemize
Leave JPEG images untransformed instead of converting them to PNG (or at
 least transform them to JPEG).
 Read JPEG image sizes.
\end_layout

\begin_layout Itemize
More flexible configuration options for lists of values.
\end_layout

\begin_layout Itemize
Added 
\family typewriter
--destdirectory
\family default
 option to convert images into.
\end_layout

\begin_layout Itemize
Image conversion from a different directory (or even with absolute paths)
 should work now.
\end_layout

\begin_layout Itemize
Changed the whole infrastructure for formulae parsing.
 More structured parsing should now be possible, e.g.
 square brackets are first-class citizens.
\end_layout

\begin_layout Itemize
Implemented nice fractions: 
\begin_inset Formula $\nicefrac{7}{8}$
\end_inset

.
\end_layout

\begin_layout Itemize
Redid basic typography: default font is now sans-serif, which looks better
 on your average browser.
 Formulae have a bit more space around.
\end_layout

\begin_layout Itemize
Imported the complete symbol list from the 
\family typewriter
unicodesymbols
\family default
 file in LyX.
\end_layout

\end_deeper
\begin_layout Itemize
0.26 (2009-06-10):
\end_layout

\begin_deeper
\begin_layout Itemize
Added a lot of new LaTeX commands, both for Unicode symbols and for math
 functions.
\end_layout

\begin_layout Itemize
New mechanism to include new lists of 
\begin_inset Quotes eld
\end_inset

command:Unicode
\begin_inset Quotes erd
\end_inset

 equivalents.
\end_layout

\begin_layout Itemize
New decoration command 
\family typewriter

\backslash
overrightarrow
\family default
, to show a long arrow above some text.
\end_layout

\begin_layout Itemize
Solved bug: 
\family typewriter
--directory
\family default
 option was not working.
 A new test for this option added.
\end_layout

\end_deeper
\begin_layout Itemize
0.25 (2009-06-08):
\end_layout

\begin_deeper
\begin_layout Itemize
Added new characters: German dash separator, a few arrows, horizontal ellipsis.
\end_layout

\begin_layout Itemize
Automatic insertion of release date in the changelog upon version release.
\end_layout

\begin_layout Itemize
New formula commands: phantom text (for spacing), mbox (literal text).
\end_layout

\begin_layout Itemize
Solved two bugs in URLs: make FlexURLs point to the link in their contents,
 and do not show 
\begin_inset Quotes eld
\end_inset

mailto:
\begin_inset Quotes erd
\end_inset

 in email links.
\end_layout

\begin_layout Itemize
Properly display Date layouts as 
\family typewriter

\family default . \end_layout \begin_layout Itemize Display a FATAL error (and terminate) when trying to read beyond the end of the document. \end_layout \begin_layout Itemize Cross-platform support for newlines. Besides the Unix \family typewriter \backslash n \family default , now supports Windows ( \family typewriter \backslash r \backslash n \family default ) and Mac OS X ( \family typewriter \backslash r \family default ) newlines. \end_layout \begin_layout Itemize Support for \family typewriter \backslash unit \family default command, showing units for a magnitude. \end_layout \begin_layout Itemize New format for formulae (instead of \family typewriter $\SpecialChar \ldots{} $ \family default or \family typewriter \backslash [\SpecialChar \ldots{} \backslash ] \family default ): \family typewriter \backslash command{\SpecialChar \ldots{} } \family default . \end_layout \end_deeper \begin_layout Itemize 0.24 (2009-06-02): \end_layout \begin_deeper \begin_layout Itemize Show sum and integral limits correctly in Konqueror, Safari and Chrome. \end_layout \begin_layout Itemize Also show roots and arrays correctly in those browsers. Larger radical symbol looks better. \end_layout \begin_layout Itemize Added \begin_inset CommandInset href LatexCommand href name "Math Showcase" target "math.html" \end_inset to test on \begin_inset CommandInset href LatexCommand href name "browsershots.org" target "http://browsershots.org/" \end_inset . \end_layout \begin_layout Itemize Substituted medium mathematical spaces with midspaces for better browser compatibility. \end_layout \begin_layout Itemize Added \family typewriter --unicode \family default option to switch on full Unicode output; right now only re-adds medium mathematical spaces. \end_layout \begin_layout Itemize Included all Greek letters, upper and lower case; and common math symbols. \end_layout \begin_layout Itemize Make title from command line option prevail over PDF title. \end_layout \begin_layout Itemize Specified minimum browser versions in the user guide and in the requirements. \end_layout \begin_layout Itemize Documented option \family typewriter --directory \family default (it existed already but was not in the docs). \end_layout \begin_layout Itemize Option \family typewriter --toc \family default can generate a Table Of Contents. Not documented because it is only a start for bigger things. \end_layout \begin_layout Itemize Repaired configuration export to \family typewriter base.cfg \family default : now all objects in \family typewriter config.py \family default are automatically exported. \end_layout \end_deeper \begin_layout Itemize 0.23 (2009-05-24): \end_layout \begin_deeper \begin_layout Itemize Corrected numbering and appearance of subfloats. \end_layout \begin_layout Itemize Plain layouts are not reflected in HTML output. \end_layout \begin_layout Itemize Unified table parsing, moved table starts to configuration file. \end_layout \begin_layout Itemize Use unicode output in debug and error messages. \end_layout \begin_layout Itemize Automated testing now shows unified diff, to show the file that doesn't pass the tests. \end_layout \begin_layout Itemize Finally got UTF-8 output right (hopefully). \end_layout \begin_layout Itemize Display floats with tables properly aligned, and on a white background. Listings are working too. \end_layout \begin_layout Itemize Show warning when document is created with LyX 1.4. \begin_inset Formula $x$ \end_inset . \end_layout \begin_layout Itemize Transform \family typewriter \backslash newpage \family default to an empty paragraph. \end_layout \begin_layout Itemize Standard layouts can be \family typewriter
\family default or nothing at all, generating valid XHTML. \end_layout \begin_layout Itemize Added nomenclature commands for 1.5. \begin_inset Formula $x$ \end_inset . \end_layout \begin_layout Itemize Got Index and nomenclature working again, added test file so they don't break anymore. \end_layout \end_deeper \begin_layout Itemize 0.22 (2009-05-15): \end_layout \begin_deeper \begin_layout Itemize Modified user guide to explain \family typewriter --html \family default option. \end_layout \begin_layout Itemize Solved a few bugs manifested when exporting to HTML 4.0 with \family typewriter --html \family default . \end_layout \begin_layout Itemize More configurable containers: quote types, barred text, boxes, info insets\SpecialChar \ldots{} \end_layout \begin_layout Itemize Added note on the main page about slow mirrors and latest versions. \end_layout \begin_layout Itemize Standard layouts can now be translated to \family typewriter
\family default or to \family typewriter \family default , depending on the context. \end_layout \begin_layout Itemize Command endings can be deduced from starts in configuration file. \end_layout \begin_layout Itemize A bunch of new math symbols: nu, angle brackets. \end_layout \begin_layout Itemize Generalized big brackets of several types. Consolidated parameter parsing in formulas. \end_layout \begin_layout Itemize Equation numbering is working. \end_layout \begin_layout Itemize Unknown commands are shown in red: \begin_inset Formula $\unknown$ \end_inset . \end_layout \end_deeper \begin_layout Itemize 0.21 (2009-05-11): \end_layout \begin_deeper \begin_layout Itemize Command line option \family typewriter --html \family default to export to HTML 4.0. \end_layout \begin_layout Itemize Container endings are now configurable from the main config file. \end_layout \begin_layout Itemize Styles can be mixed and matched at will (like \family typewriter typewriter \series bold bold \color blue in blue \family default \series default \color inherit ). \end_layout \begin_layout Itemize All constant strings (such as \begin_inset Quotes eld \end_inset Table of contents \begin_inset Quotes erd \end_inset ) should now be configurable. \end_layout \begin_layout Itemize Added a few more colors: \color green green \color inherit , \color magenta magenta \color inherit , \color cyan cyan \color inherit , \color yellow yellow \color inherit , \color white white \color inherit (those two were yellow and white). \end_layout \end_deeper \begin_layout Itemize 0.20 (2009-05-09): \end_layout \begin_deeper \begin_layout Itemize Command line option \family typewriter --version \family default to show the current version number and date. \end_layout \begin_layout Itemize Release date is now automatically added to the configuration. \end_layout \begin_layout Itemize Preliminary support for inset boxes. \end_layout \begin_layout Itemize Support for numbered listings. \end_layout \begin_layout Itemize Added \family typewriter \family default tag for \family typewriter Content-Type \family default , to ease importing into word processors. \end_layout \begin_layout Itemize Automated version generation, taking version number and date from config, and updating current version in the main page. \end_layout \end_deeper \begin_layout Itemize 0.19 (2009-05-07): \end_layout \begin_deeper \begin_layout Itemize More powerful configuration file manipulation: export to generic config and Python files. \end_layout \begin_layout Itemize Start lines for every parsed structure can now be configured in the global \family typewriter base.cfg \family default file. \end_layout \begin_layout Itemize New Info types \family typewriter package \family default and \family typewriter textclass \family default . \end_layout \begin_layout Itemize New formula symbols: up and down arrows, long double arrows, Gamma and Upsilon, mu, backslash. \end_layout \begin_layout Itemize Show line number and current line for generic errors. \end_layout \begin_layout Itemize Listings and document abstracts are displayed properly. \end_layout \end_deeper \begin_layout Itemize 0.18 (2009-05-04): \end_layout \begin_deeper \begin_layout Itemize Wrap floats are separated by a bit of space (two exes, actually) from the text. \end_layout \begin_layout Itemize Solved bug when running without any arguments. \end_layout \begin_layout Itemize Main executable file is now changed from \family typewriter elyxer \family default to \family typewriter elyxer.py \family default , to prevent problems on platforms that require the extension; main source file has changed from \family typewriter elyxer.py \family default to \family typewriter principal.py \family default , to avoid confusion. \end_layout \begin_layout Itemize Moved all parsing code to the new package \family typewriter parse \family default , and configuration files to package \family typewriter conf \family default . \end_layout \begin_layout Itemize All configuration is now read from (and written to) plain text files. \end_layout \end_deeper \begin_layout Itemize 0.17 (2009-04-27): \end_layout \begin_deeper \begin_layout Itemize Alignment of table cells is now respected, both horizontally and vertically. \end_layout \begin_layout Itemize Wrap floats are actually floated left or right. \end_layout \begin_layout Itemize Correctly interpret symbols in formulae: \begin_inset Formula $!$ \end_inset , \begin_inset Formula $;$ \end_inset , \begin_inset Formula $\leq$ \end_inset , \begin_inset Formula $\geq$ \end_inset , \begin_inset Formula $\neq,$ \end_inset \begin_inset Formula $\in$ \end_inset , \begin_inset Formula $\ddots$ \end_inset , and a few spaces. \end_layout \begin_layout Itemize In formulae, \family typewriter \backslash displaystyle \family default and friends are ignored. \end_layout \begin_layout Itemize Square roots are again displayed correctly, and even better than before! \end_layout \begin_layout Itemize Cases are working (not perfect: with a bar instead of a bracket, but working). \end_layout \end_deeper \begin_layout Itemize 0.16 (2009-04-22): \end_layout \begin_deeper \begin_layout Itemize Document date is shown centered. \end_layout \begin_layout Itemize Special rows in a longtable are properly ignored. \end_layout \begin_layout Itemize Multicolumn cells are properly interpreted. \end_layout \begin_layout Itemize Sums and integral limits are properly displayed with respect to the symbol: \begin_inset Formula $\sum_{i=1}^{\infty}$ \end_inset . \end_layout \end_deeper \begin_layout Itemize 0.15 (2009-04-19): \end_layout \begin_deeper \begin_layout Itemize Info insets (containing shortcuts) are now interpreted and shown. \end_layout \begin_layout Itemize LyX-Code is interpreted as a \family typewriter
\family default
 tag.
\end_layout

\begin_layout Itemize
Reorganized code into a few packages.
\end_layout

\begin_layout Itemize
Line numbers are not shown for utility classes.
\end_layout

\begin_layout Itemize
Floats (figures, tables and algorithms) are now numbered.
\end_layout

\begin_layout Itemize
Float links point to the start of the table or figure, not to the caption.
\end_layout

\end_deeper
\begin_layout Itemize
0.14 (2009-04-13):
\end_layout

\begin_deeper
\begin_layout Itemize
Deeper layouts (of any kind, not just in lists) are now supported.
\end_layout

\begin_layout Itemize
Appendices are numbered correctly (as A, B, C\SpecialChar \ldots{}
).
\end_layout

\begin_layout Itemize
Sections in deeper layouts are numbered correctly too.
\end_layout

\begin_layout Itemize
Double dash does not catch Unix-style options: --css is not converted --
 while the version with spaces is.
\end_layout

\begin_layout Itemize
Corrected serious bug in formula parsing affecting inline arrays.
\end_layout

\begin_layout Itemize
Arrays with vertical alignment are correctly parsed.
\end_layout

\end_deeper
\begin_layout Itemize
0.13 (2009-04-12):
\end_layout

\begin_deeper
\begin_layout Itemize
Lists are correctly displayed, instead of one list per item.
\end_layout

\begin_layout Itemize
Lists can contain nested layouts.
\end_layout

\begin_layout Itemize

\family typewriter
List
\family default
 layouts (not to mistake with 
\family typewriter
Enumerate
\family default
 or 
\family typewriter
Itemize
\family default
 lists) are processed correctly.
\end_layout

\begin_layout Itemize
Changelog moved to separate document.
\end_layout

\begin_layout Itemize
Read image sizes correctly on big-endian architectures (e.g.
 Mac OS X on PowerPC).
\end_layout

\begin_layout Itemize
Numeration of chapters, sections\SpecialChar \ldots{}
 is working.
\end_layout

\begin_layout Itemize
Error messages now show the line where they happen.
\end_layout

\end_deeper
\begin_layout Itemize
0.12 (2009-04-05):
\end_layout

\begin_deeper
\begin_layout Itemize
Arrays are parsed correctly and displayed acceptably.
\end_layout

\begin_layout Itemize
Numbers and units are correctly separated.
\end_layout

\begin_layout Itemize
Text decorations (such as 
\begin_inset Formula $\hat{a}$
\end_inset

) are shown in line.
\end_layout

\begin_layout Itemize
Variables are italicized.
\end_layout

\begin_layout Itemize
Notes and comments are not output at all, greyed-out notes are shown in
 grey.
\end_layout

\begin_layout Itemize
LyX guides parse completely.
\end_layout

\end_deeper
\begin_layout Itemize
0.11 (2009-03-27):
\end_layout

\begin_deeper
\begin_layout Itemize
Arrays are at least well parsed (but still show wrong).
\end_layout

\begin_layout Itemize
Integrals and sums appear as large characters.
\end_layout

\begin_layout Itemize
Appendices are separated from the main document.
\end_layout

\begin_layout Itemize
The bibliography appears separated with a title.
\end_layout

\begin_layout Itemize
Floats appear centered on-screen.
\end_layout

\end_deeper
\begin_layout Itemize
0.10 (2009-03-23):
\end_layout

\begin_deeper
\begin_layout Itemize
Better handling of footnotes and margin notes: not overlapping and with
 a reference in the text.
\end_layout

\begin_layout Itemize
Better parsing of first word in a Description.
\end_layout

\begin_layout Itemize
Short titles are ignored.
\end_layout

\begin_layout Itemize
Added a few font families for equations.
 Not that they display too well\SpecialChar \ldots{}

\end_layout

\end_deeper
\begin_layout Itemize
0.9 (2009-03-21):
\end_layout

\begin_deeper
\begin_layout Itemize
Better formula parsing (including line breaks).
 Supports a few math fonts.
\end_layout

\begin_layout Itemize
Supports menu separator, text with bar, nomenclature and many more quote
 types.
\end_layout

\begin_layout Itemize
Single configuration file 
\family typewriter
general.py
\family default
.
\end_layout

\begin_layout Itemize
Layout of type Space is not shown.
\end_layout

\begin_layout Itemize
Supports branches.
 Inactive branches are not shown.
\end_layout

\begin_layout Itemize
New symbols: greek letters, shapes: bullet, right triangle.
\end_layout

\begin_layout Itemize
Added support for new style (1.6.
\begin_inset Formula $x$
\end_inset

) index entries.
\end_layout

\begin_layout Itemize
From LyX documentation: 
\family typewriter
UserGuide.lyx
\family default
 is now working (except for some math functions).
\end_layout

\end_deeper
\begin_layout Itemize
0.8 (2009-03-20):
\end_layout

\begin_deeper
\begin_layout Itemize
Can be run from other directories than the one with the document.
\end_layout

\begin_layout Itemize
Tables have light grey separations.
 Table spacing is now better adjusted.
\end_layout

\begin_layout Itemize
Descriptions appear with the first word in bold), but only within the first
 text style.
 Changing style in the middle of a word may distract the algorithm.
\end_layout

\begin_layout Itemize
Added support for Lyx notes (not rendered in the HTML), margin notes, pretty
 quotes ‘’, weird spaces.
\end_layout

\begin_layout Itemize
Added support for new style (1.6.
\begin_inset Formula $x$
\end_inset

) hyperlinks, labels and references, TOC, index.
\end_layout

\begin_layout Itemize
Uses PDF title if present.
\end_layout

\begin_layout Itemize
From LyX documentation: 
\family typewriter
Intro.lyx
\family default
 is now working.
\end_layout

\end_deeper
\begin_layout Itemize
0.7 (2009-03-16):
\end_layout

\begin_deeper
\begin_layout Itemize
Images referenced by absolute path are converted to relative PNGs.
\end_layout

\begin_layout Itemize
Range of supported quotes is greater.
 Unknown quotes are now marked as errors but do not make the tool fail.
\end_layout

\begin_layout Itemize
Default CSS is always on 
\begin_inset CommandInset href
LatexCommand href
name "nongnu.org"
target "http://www.nongnu.org/elyxer/lyx.css"

\end_inset

, it can be changed via command line option 
\family typewriter
--css
\family default
.
\end_layout

\begin_layout Itemize
Reinstated layout classes for unknown types.
\end_layout

\begin_layout Itemize
Updated documentation to include how to run on Windows.
\end_layout

\begin_layout Itemize
Added meta generator tag to all pages.
\end_layout

\begin_layout Itemize
Added option 
\family typewriter
--title
\family default
 to change the default page title.
\end_layout

\begin_layout Itemize
Phonetic symbols appear in dark cyan: 
\begin_inset Formula $\text{\textipa{[sample]}}$
\end_inset

.
\end_layout

\begin_layout Itemize
Lots of small fixes and improvements to correctly parse the official LyX
 guides (
\family typewriter
UserGuide.lyx
\family default
, 
\family typewriter
EmbeddedObjects.lyx
\family default
 and 
\family typewriter
Math.lyx
\family default
).
\end_layout

\end_deeper
\begin_layout Itemize
0.6 (2009-03-15):
\end_layout

\begin_deeper
\begin_layout Itemize
Added Flex URLs, Flex code.
\end_layout

\begin_layout Itemize
Works with Python 2.3.5, but not yet Mac OS X terminal.
\end_layout

\begin_layout Itemize
Alignment now works right (and center and left).
\end_layout

\begin_layout Itemize
Modified license files to comply with Savannah policies.
\end_layout

\begin_layout Itemize
Added index page and logo.
\end_layout

\end_deeper
\begin_layout Itemize
0.5 (2009-03-14):
\end_layout

\begin_deeper
\begin_layout Itemize
Inset parameters are all parsed correctly (including spaces in image paths).
\end_layout

\begin_layout Itemize
Formulae and tables should work again (including complex formatting).
\end_layout

\begin_layout Itemize
Modified to (mostly) run under Python 2.3.5 (Mac OS X Tiger).
\end_layout

\begin_layout Itemize
Processes layouts ending in `*' (like `Section*').
\end_layout

\begin_layout Itemize
Runtime options for help and to disable the copyright notice, debug, quietness.
\end_layout

\begin_layout Itemize
Accepts scaling for images.
\end_layout

\begin_layout Itemize
Nested lists working.
\end_layout

\end_deeper
\begin_layout Itemize
0.4 (2009-03-12):
\end_layout

\begin_deeper
\begin_layout Itemize
When images do not exist warns but does not fail.
\end_layout

\begin_layout Itemize
Author and title containing tags are properly processed.
\end_layout

\begin_layout Itemize
Slanted text translated to italics.
\end_layout

\begin_layout Itemize
Title no longer necessary to have a working document.
\end_layout

\begin_layout Itemize
ERT is ignored.
 Status line (open/collapsed) is ignored.
\end_layout

\begin_layout Itemize
Supports footnotes, newlines, bibitem entries and citations.
\end_layout

\begin_layout Itemize
Dev guide includes a 
\family typewriter
Container
\family default
 tutorial.
\end_layout

\end_deeper
\begin_layout Itemize
0.3 (2009-03-11): Now works with generic Insets.
\end_layout

\begin_layout Itemize
0.2 (2009-03-11): ImageMagick is not required anymore.
\end_layout

\begin_layout Itemize
0.1 (2009-03-10): first public version.
\end_layout

\end_body
\end_document
elyxer-1.2.5/docs/parse tree.svg0000644000175000017500000005140612074107030016040 0ustar  chennochenno


  
    
      
    
    
      
    
    
      
    
    
      
    
    
  
  
  
    
      
        image/svg+xml
        
      
    
  
  
    
      
      \begin_inset
    
    
      
      Graphics
    
    
      
      Text
    
    
      
      LatexCommand
    
    
      
      Inset
    
    
      
      label
    
    
      
      ref
    
    
    
    
    
    
      
      Image
    
    
      
      Reference
    
    
      
      Label
    
    
    
    
    
    
    
      
      InsetText
    
    
  

elyxer-1.2.5/docs/upload.sh0000755000175000017500000000241212074107030015101 0ustar  chennochenno#!/bin/bash

#   eLyXer -- convert LyX source files to HTML output.
#
#   Copyright (C) 2009 Alex Fernández
#
#   This program is free software: 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 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
#   GNU General Public License for more details.
#
#   You should have received a copy of the GNU General Public License
#   along with this program.  If not, see .

# Alex 20090315: upload generated documentation to Savannah CVS

# download current docs
mkdir cvs
cd cvs
#rm -Rf elyxer
#cvs -z3 -d:ext:alexfernandez@cvs.savannah.nongnu.org:/web/elyxer co elyxer
cvs  -z3 -d:ext:alexfernandez@cvs.savannah.nongnu.org:/web/elyxer update elyxer
# overwrite with current docs
cp ../*.html elyxer/
cp ../*.png elyxer/
cp ../*.css elyxer/
# remove MathJaX and jsMath (comment if they are updated)
#rm -Rf elyxer/MathJax
#rm -Rf elyxer/jsMath
# commit
cd elyxer
cvs commit -m "Automatic upload"

elyxer-1.2.5/docs/lyx.css0000644000175000017500000003751612117174754014640 0ustar  chennochenno/*
*   eLyXer -- convert LyX source files to HTML output.
*
*   Copyright (C) 2009-2010 Alex Fernández
*
*   This program is free software: 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 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
*   GNU General Public License for more details.
*
*   You should have received a copy of the GNU General Public License
*   along with this program.  If not, see http://www.gnu.org/licenses/.
*/
/* --end--
* Global CSS file for LyX documents.
*/

body {
	font: 90% sans-serif;
	background: #f9f9f9;
	color: black;
	margin: 0;
	padding: 0;
}

#globalWrapper {
	margin: 10px 5%;
	padding: 20px;
	background: #ffffff;
	line-height: 1.5em;
}

/* Basic styles */
a {
	text-decoration: none;
	background: none;
}
a:link {
	color: #0030c0;
}
a:visited {
	color: #603090;
}
a:active {
	color: #ffa000;
}
a:hover {
	text-decoration: underline;
}
h1 {
	margin-top: 1em;
	line-height: 1.5em;
}
h1.Part {
	text-align: center;
}
h1.Part- {
	text-align: center;
}
sup {
	font-size: 0.75em;
	line-height: 0.5em;
	vertical-align: text-top;
}
sub {
	font-size: 0.75em;
	line-height: 0.5em;
	vertical-align: text-bottom;
}
div.Standard {
	margin: 1em 0;
}
div.Unindented {
	margin: 0;
}
div.Indented {
	text-indent: 30pt;
	margin: 0;
}
div.Indented * {
	text-indent: 0pt;
}
p.dir {
	float: right;
}
p.printindex {
	font-size: 0.90em;
}
a.printindex {
	color: black;
}
table {
	display: inline-table;
	text-align: center;
	border-collapse: collapse;
	margin-top: 1em;
	margin-bottom: 1em;
}
tr.header {
	border-bottom: thin solid #c0c0c0;
	background: #ffffff;
	font-weight: bold;
}
td {
	padding: 1ex;
	border: thin solid #f0f0f0;
}
td div.Standard {
	margin: 0ex;
	padding: 0ex;
}
div.caption div.Standard, div.table div.Standard {
	margin: 0ex;
	padding: 0ex;
}
td.numeric {
	text-align: right;
}
td.empty {
	text-align: center;
}
div.right {
	text-align: right;
}
div.center {
	text-align: center;
	margin-left: auto;
	margin-right: auto;
}
p.biblio {
}
div.Paragraph, div.Paragraph- {
	font-weight: bold;
	font-size: 103%;
}
span.versalitas, span.noun {
	font-variant: small-caps;
}
span.sans {
	font-family: sans-serif;
}
span.code {
	font-family: monospace;
}
div.Plain {
	display: inline;
	width: auto;
}
h2 {
	line-height: 1.4em;
}
span.Description-entry {
	font-weight: bold;
}
span.List-entry {
	display: inline-block;
	width: 25%;
	vertical-align: text-top;
}
span.List-contents {
	display: inline-block;
	width: 75%;
	vertical-align: text-top;
}
div.Space {
	display: none;
}
span.appendix {
	display: none;
}
h1.biblio {
}
span.greyedout {
	color: #808080;
}
div.Description, div.List, li {
	margin: 1em 0;
}
li.nested {
	list-style-type: none;
}
span.Info {
	background: #f0f0f0;
	border: thin solid #c0c0c0;
}
pre {
	padding: 0em;
	margin: 0em;
	width: auto;
	font-family: monospace;
	line-height: 1.5em;
}
pre.LyX-Code {
	margin: 0.5em 3em;
}
a.Label {
	text-decoration: none;
	color: #000000;
}
span.phantom {
	color: #ffffff;
}
a.biblioentry {
	color: black;
}
span.menuitem {
	font-size: 105%;
}
span.normal {
	font-style: normal;
}
div.PlainVisible {
	width: auto;
}
div.indexgroup {
	margin-left: 2em;
}
span.strong {
	font-weight: bold;
}

/* Figures and Tables */
img.embedded {
	width: 100%;
	_width: auto;
}
div.float {
	margin-top: 1ex;
	margin-bottom: 1ex;
	text-align: center;
}
span.float {
	margin-top: 1ex;
	margin-bottom: 1ex;
	text-align: center;
}
div.figure {
	display: inline-block;
	text-align: left;
	padding: 1ex;
	margin-left: auto;
	margin-right: auto;
	border: thin solid #c0c0c0;
}
div.table {
	display: inline-block;
	text-align: left;
	padding: 1ex;
	margin-left: auto;
	margin-right: auto;
	border: thin solid #c0c0c0;
}
div.algorithm {
	display: inline-block;
	text-align: left;
	padding: 1ex;
	margin-left: auto;
	margin-right: auto;
	border: thin solid #c0c0c0;
}
div.caption {
	text-align: center;
	font-family: sans-serif;
	margin-left: auto;
	margin-right: auto;
	padding: 0.5ex;
}
img.figure {
	width: 100%;
	_width: auto;
}
div.multifigure {
	padding: 1ex;
	width: 100%;
}
div.multitable {
	display: inline-block;
	padding: 1ex;
	margin-left: auto;
	margin-right: auto;
	border: thin solid #c0c0c0;
}
div.multialgorithm {
	display: inline-block;
	padding: 1ex;
	margin-left: auto;
	margin-right: auto;
	border: thin solid #c0c0c0;
}
div.wrap-l, div.wrap-o, div.wrap-i {
	margin: 2ex;
	float: left;
}
div.wrap-r {
	margin: 2ex;
	float: right;
}
div.listing {
	display: inline-block;
	text-align: left;
	margin-left: auto;
	margin-right: auto;
	padding: 0.5ex;
	border: thin solid #c0c0c0;
}
span.number-left {
	float: left;
	background: #f0f0f0;
	width: 3em;
	text-align: right;
	margin-right: 1em;
}
span.number-right {
	float: right;
	background: #f0f0f0;
	width: 3em;
	text-align: right;
	margin-left: 1em;
}

/* Header */
h1.title {
	text-align: center;
}
h2.author {
	text-align: center;
}
h2.Date {
	text-align: center;
}
div.abstract {
	margin: 1em 3em;
	text-align: left;
	font-size: 0.95em;
}
p.abstract-message {
	text-align: center;
	font-weight: bold;
}
div.tocheader {
	margin: 1em 0;
	font-size: large;
}
a.toc {
	color: black;
}
div.tocindent {
	padding: 0 0 0 2em;
}
div.toc {
	margin: 0.5em 0;
	font-size: 0.95em;
}
div.fulltoc {
	padding: 1em;
}
div.warning {
	font-size: 120%;
	color:#cc0000;
}
div.Institute {
	text-align: center;
}
/*
* Extras: colors, footnotes, boxes, spaces...
*/

/* Raw colors */
span.red {
	color: #c00000;
}
span.blue {
	color: #0000c0;
}
span.green {
	color: #00c000;
}
span.magenta {
	color: #c000c0;
}
span.cyan {
	color: #00c0c0;
}
span.yellow {
	color: #c0c000;
}
span.white {
	color: #ffffff;
}

/* Footnotes */
span.SupFootMarker {
	color: #0030c0;
	font-size: 0.75em;
	line-height: 0.5em;
	vertical-align: text-top;
}
span.AlignFootMarker {
	color: #0030c0;
}
div.EndFoot {
	margin: 0.2ex;
	background: #ffffff;
	padding: 0.5ex;
	font-size: small;
	font-weight: normal;
	line-height: 1.5em;
	text-align: left;
}
span.MarginFoot {
	float: right;
	clear: right;
	margin: 0.2ex;
	border: thin solid #c0c0c0;
	background: #ffffff;
	width: 30%;
	padding: 0.5ex;
	font-size: small;
	font-weight: normal;
	line-height: 1.5em;
	text-align: left;
}
span.HoverFoot {
	margin: 0.2ex;
	border: thin solid #c0c0c0;
	background: #ffffff;
	padding: 0.5ex;
	font-size: small;
	font-weight: normal;
	line-height: 1.5em;
	text-align: left;
}
span.FootOuter .HoverFoot {
	display: none;
	position: absolute;
}
span.FootOuter:hover .HoverFoot {
	display: inline;
	float: none;
}
span.Marginal {
	float: right;
	clear: right;
	margin: 0.2ex;
	border: thin solid #c0c0c0;
	background: #ffffff;
	width: 30%;
	padding: 0.5ex;
	font-size: small;
	font-weight: normal;
	line-height: 1.5em;
	text-align: left;
}
span.Note {
	display: none;
}

/* Boxes */
div.framed {
	outline-style: solid;
}
div.frameless {
}
div.Frameless {
}
div.Boxed {
	outline-width: thin;
	outline-style: solid;
}
div.Framed {
	outline-width: thin;
	outline-style: solid;
	line-height: 200%;
}
div.Doublebox {
	outline-style: double;
}
div.Shadowbox {
	outline-style: outset;
}
div.Shaded {
	outline-style: inset;
}
div.ovalbox {
	outline-style: groove;
}
div.Ovalbox {
	outline-style: ridge;
}
hr.line {
	display: inline-block;
}

/* Spaces */
span.hspace {
	display: inline-block;
}
span.vspace {
	display: inline-block;
	vertical-align: text-top;
}
span.hfill {
	display: inline-block;
	margin-left: auto;
	margin-right: auto;
	min-width: 20mm;
	background: #fff0f0;
}
div.defskip {
	display: block;
	height: 1em;
}
div.smallskip {
	display: block;
	height: 0.5em;
}
div.medskip {
	display: block;
	height: 1em;
}
div.bigskip {
	display: block;
	height: 2em;
}
div.vfill {
	display: block;
	height: 30em;
}

/* Sizes */
span.scriptstyle {
	font-size: 0.75em;
}
span.scriptscriptstyle {
	font-size: 0.60em;
}

/* Chunks */
div.chunk {
	width: auto;
}
span.chunkleft span.chunkright {
	font-style: normal;
}
span.chunkdecl {
	font-style: italic;
	padding: 0em 2em;
}
span.chunkref {
	font-style: italic;
}

/* Split Part Navigation */
div.splitheader {
	margin: 0em;
	padding: 0.1em;
	text-align: center;
	background: #f9f9f9;
	overflow: auto;
}
span.next {
	float: right;
	width: 30%;
	text-align: right;
}
span.up {
	display: inline-block;
	width: 30%;
	text-align: center;
}
span.prev {
	float: left;
	width: 30%;
	text-align: left;
}
hr.footer {
	margin-top: 2em;
}
div.footer {
	font-size: 0.90em;
	margin: 1em 0;
}

/* Change Tracking */
span.inserted {
	color: #0000ff;
}
span.deleted {
	color: #ff0000;
	text-decoration: line-through;
}

/* Google Charts */
img.chart {
	vertical-align: middle;
}
/* --end--
* CSS file for LaTeX formulas.
*/

/* Formulas */
.formula {
	text-align: center;
	font-family: "DejaVu Serif", serif;
	margin: 1.2em 0;
}
span.formula {
	white-space: nowrap;
}
div.formula {
	padding: 0.5ex;
	margin-left: auto;
	margin-right: auto;
}

/* Basic features */
a.eqnumber {
	display: inline-block;
	float: right;
	clear: right;
	font-weight: bold;
}
span.unknown {
	color: #800000;
}
span.ignored, span.arraydef {
	display: none;
}
.formula i {
	letter-spacing: 0.1ex;
}

/* Alignment */
.align-left, .align-l {
	text-align: left;
}
.align-right, .align-r {
	text-align: right;
}
.align-center, .align-c {
	text-align: center;
}

/* Structures */
span.overline, span.bar {
	text-decoration: overline;
}
.fraction, .fullfraction {
	display: inline-block;
	vertical-align: middle;
	text-align: center;
}
.fraction .fraction {
	font-size: 80%;
	line-height: 100%;
}
span.numerator {
	display: block;
}
span.denominator {
	display: block;
	padding: 0ex;
	border-top: thin solid;
}
sup.numerator, sup.unit {
	font-size: 70%;
	vertical-align: 80%;
}
sub.denominator, sub.unit {
	font-size: 70%;
	vertical-align: -20%;
}
span.sqrt {
	display: inline-block;
	vertical-align: middle;
	padding: 0.1ex;
}
sup.root {
	font-size: 70%;
	position: relative;
	left: 1.4ex;
}
span.radical {
	display: inline-block;
	padding: 0ex;
	font-size: 150%;
	vertical-align: top;
}
span.root {
	display: inline-block;
	border-top: thin solid;
	padding: 0ex;
	vertical-align: middle;
}
span.symbol {
	font-size: 125%;
}
span.bigsymbol {
	font-size: 150%;
}
span.largesymbol {
	font-size: 175%;
}
span.hugesymbol {
	font-size: 200%;
}
span.scripts {
	display: inline-table;
	vertical-align: middle;
}
.script {
	display: table-row;
	text-align: left;
	line-height: 150%;
}
span.limits {
	display: inline-table;
	vertical-align: middle;
}
.limit {
	display: table-row;
	line-height: 95%;
}
sup.limit, sub.limit {
	line-height: 150%;
}
span.symbolover {
	display: inline-block;
	text-align: center;
	position: relative;
	float: right;
	right: 100%;
	bottom: 0.5em;
	width: 0px;
}
span.withsymbol {
	display: inline-block;
}
span.symbolunder {
	display: inline-block;
	text-align: center;
	position: relative;
	float: right;
	right: 80%;
	top: 0.3em;
	width: 0px;
}

/* Environments */
span.array, span.bracketcases, span.binomial, span.environment {
	display: inline-table;
	text-align: center;
	border-collapse: collapse;
	margin: 0em;
	vertical-align: middle;
}
span.arrayrow, span.binomrow {
	display: table-row;
	padding: 0ex;
	border: 0ex;
}
span.arraycell, span.bracket, span.case, span.binomcell, span.environmentcell {
	display: table-cell;
	padding: 0ex 0.2ex;
	line-height: 99%;
	border: 0ex;
}
/*
* CSS file for LaTeX formulas, extra stuff:
* binomials, vertical braces, stackrel, fonts and colors.
*/

/* Inline binomials */
span.binom {
	display: inline-block;
	vertical-align: middle;
	text-align: center;
	font-size: 80%;
}
span.binomstack {
	display: block;
	padding: 0em;
}

/* Over- and underbraces */
span.overbrace {
	border-top: 2pt solid;
}
span.underbrace {
	border-bottom: 2pt solid;
}

/* Stackrel */
span.stackrel {
	display: inline-block;
	text-align: center;
}
span.upstackrel {
	display: block;
	padding: 0em;
	font-size: 80%;
	line-height: 64%;
	position: relative;
	top: 0.15em;

}
span.downstackrel {
	display: block;
	vertical-align: bottom;
	padding: 0em;
}

/* Fonts */
span.mathsf, span.textsf {
	font-style: normal;
	font-family: sans-serif;
}
span.mathrm, span.textrm {
	font-style: normal;
	font-family: serif;
}
span.text, span.textnormal {
	font-style: normal;
}
span.textipa {
	color: #008080;
}
span.fraktur {
	font-family: "Lucida Blackletter", eufm10, blackletter;
}
span.blackboard {
	font-family: Blackboard, msbm10, serif;
}
span.scriptfont {
	font-family: "Monotype Corsiva", "Apple Chancery", "URW Chancery L", cursive;
	font-style: italic;
}

/* Colors */
span.colorbox {
	display: inline-block;
	padding: 5px;
}
span.fbox {
	display: inline-block;
	border: thin solid black;
	padding: 2px;
}
span.boxed, span.framebox {
	display: inline-block;
	border: thin solid black;
	padding: 5px;
}

/*
* Obsolete definitions, kept for backwards compatibility.
*/

/* Footnotes */
span.FootMarker {
	color: #0030c0;
	font-size: 0.75em;
	line-height: 0.5em;
	vertical-align: text-top;
}
span.Foot {
	margin: 0.2ex;
	border: thin solid #c0c0c0;
	background: #ffffff;
	padding: 0.5ex;
	font-size: small;
	font-weight: normal;
	line-height: 1.5em;
	text-align: left;
}
span.FootOuter .Foot {
	display: none;
	position: absolute;
}
span.FootOuter:hover .Foot {
	display: inline;
	float: none;
}

/* Dotted box */
span.dotted {
	border-top: thin dotted;
}

/* Obsolete aligned structures */
span.numerator-l {
	display: block;
	text-align: left;
}
span.numerator-r {
	display: block;
	text-align: right;
}
span.numeratorl {
	display: block;
	text-align: left;
}
span.numeratorr {
	display: block;
	text-align: right;
}
span.framebox- {
	display: inline-block;
	border: thin solid black;
	text-align: center;
	padding: 5px;
}
span.framebox-l {
	display: inline-block;
	border: thin solid black;
	text-align: left;
	padding: 5px;
}
span.framebox-r {
	display: inline-block;
	border: thin solid black;
	text-align: right;
	padding: 5px;
}
td.formula-l {
	text-align: left;
	padding: 0.2ex;
	border: 0ex;
}
td.formula-c {
	text-align: center;
	padding: 0.2ex;
	border: 0ex;
}
td.formula-r {
	text-align: right;
	padding: 0.2ex;
	border: 0ex;
}

/* Obsolete limits */
sub.bigsymbol {
	display: table-row;
	text-align: left;
	line-height: 150%;
}
sup.bigsymbol {
	display: table-row;
	text-align: left;
	line-height: 150%;
}

/* Obsolete cases */
table.cases {
	display: inline-block;
	text-align: center;
	border-collapse: collapse;
	margin: 0.2em;
	border-left: thin solid;
	vertical-align: middle;
}
table.cases tr td {
	padding-left: 1ex;
	padding-right: 1em;
}

/* Obsolete binomials */
span.fullbinom {
	display: inline-block;
	vertical-align: middle;
	text-align: center;
}
span.upbinom {
	display: block;
	padding: 0em;
}
span.downbinom {
	display: block;
	padding: 0em;
}

/* Obsolete environments */
table.formula {
	display: inline-block;
	text-align: center;
	border-collapse: collapse;
	margin: 0em;
	vertical-align: middle;
}
td.formula {
	padding: 0.2ex;
	border: 0ex;
}
table.environment {
	display: inline-block;
	text-align: right;
	margin: 0;
	vertical-align: middle;
}
table.environment tr td {
	padding: 0 1em;
}
/*
* CSS section for print.
*/
@media print {
body {
	font: 90% serif;
	background: #ffffff;
	color: black;
	margin: 0;
	padding: 0;
}
#globalWrapper {
	width: 100%;
	margin: 0px;
	padding: 0px;
	background: #ffffff;
	line-height: 1.5em;
}
span.FootOuter .Foot {
	display: block;
	position: relative;
	float: right;
	clear: right;
	margin: 0.2ex;
	border: thin solid #c0c0c0;
	background: #ffffff;
	width: 30%;
	padding: 0.5ex;
	font-size: small;
	font-weight: normal;
	line-height: 1.5em;
	text-align: left;
}
span.FootOuter .HoverFoot {
	display: block;
	position: relative;
	float: right;
	clear: right;
	margin: 0.2ex;
	border: thin solid #c0c0c0;
	background: #ffffff;
	width: 30%;
	padding: 0.5ex;
	font-size: small;
	font-weight: normal;
	line-height: 1.5em;
	text-align: left;
}
a:visited {
	color: #0030c0;
}
/* end of print CSS */
}
elyxer-1.2.5/docs/pipeline.svg0000644000175000017500000002656712074107030015625 0ustar  chennochenno


  
    
      
    
    
      
    
    
      
    
    
      
    
    
  
  
  
    
      
        image/svg+xml
        
      
    
  
  
    
    
      
      elyxer
    
    
      
      LyX file
    
    
      
      singleHTML file
    
    
      
      
      
      multipleHTML files
    
    
    
      
      elyxer --splitpart
    
    
    
  

elyxer-1.2.5/docs/math.lyx0000644000175000017500000005212112074107030014747 0ustar  chennochenno#LyX 1.6.7 created this file. For more info see http://www.lyx.org/
\lyxformat 345
\begin_document
\begin_header
\textclass article
\begin_preamble
%   eLyXer -- convert LyX source files to HTML output.
%
%   Copyright (C) 2009-2011 Alex Fernández
%
%   This program is free software: 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 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
%   GNU General Public License for more details.
%
%   You should have received a copy of the GNU General Public License
%   along with this program.  If not, see .

% DO NOT ALTER THIS PREAMBLE!!!
%
% This preamble is designed to ensure that the User's Guide prints
% out as advertised. If you mess with this preamble,
% parts of the User's Guide may not print out as expected.  If you
% have problems LaTeXing this file, please contact 
% the documentation team
% email: lyx-docs@lists.lyx.org

\usepackage{ifpdf} % part of the hyperref bundle
\ifpdf % if pdflatex is used

 % set fonts for nicer pdf view
 \IfFileExists{lmodern.sty}{\usepackage{lmodern}}{}

\fi % end if pdflatex is used

% for correct jump positions whe clicking on a link to a float
\usepackage[figure]{hypcap}


% redefine the \LyX macro for PDF bookmarks
\def\LyX{\texorpdfstring{%
  L\kern-.1667em\lower.25em\hbox{Y}\kern-.125emX\@}
  {LyX}}


% test macro with two arguments
\newcommand{\preambleroot}[2]{\sqrt[#1]{#2}}

% redefine the greyed out note

\usepackage{mathrsfs}
\usepackage{eurosym}
\end_preamble
\options intoc,bibtotoc,idxtotoc,BCOR7mm,tablecaptionabove
\use_default_options false
\language english
\inputencoding utf8
\font_roman default
\font_sans default
\font_typewriter default
\font_default_family default
\font_sc false
\font_osf false
\font_sf_scale 100
\font_tt_scale 100

\graphics default
\paperfontsize 12
\spacing single
\use_hyperref true
\pdf_title "eLyXer Math Showcase"
\pdf_author "Alex Fernández"
\pdf_subject "The amazing all-time-wonder eLyXer Math Showcase"
\pdf_keywords "LyX"
\pdf_bookmarks true
\pdf_bookmarksnumbered false
\pdf_bookmarksopen false
\pdf_bookmarksopenlevel 1
\pdf_breaklinks false
\pdf_pdfborder false
\pdf_colorlinks false
\pdf_backref false
\pdf_pdfusetitle true
\papersize default
\use_geometry false
\use_amsmath 1
\use_esint 0
\cite_engine basic
\use_bibtopic false
\paperorientation portrait
\branch Pregunta
\selected 1
\color #00ff00
\end_branch
\branch Respuesta
\selected 0
\color #aa55ff
\end_branch
\secnumdepth 3
\tocdepth 3
\paragraph_separation indent
\defskip medskip
\quotes_language english
\papercolumns 1
\papersides 2
\paperpagestyle default
\tracking_changes false
\output_changes false
\author "" 
\author "" 
\end_header

\begin_body

\begin_layout Title
\begin_inset Graphics
	filename elyxer.svg
	lyxscale 50

\end_inset

eLyXer Math Showcase
\end_layout

\begin_layout Author
Alex Fernández (elyxer@gmail.com)
\end_layout

\begin_layout Standard
\begin_inset CommandInset toc
LatexCommand tableofcontents

\end_inset


\end_layout

\begin_layout Section
Introduction
\end_layout

\begin_layout Standard
This document is intended as a showcase of the mathematical abilities of
 eLyXer; for more information be sure to visit the 
\begin_inset CommandInset href
LatexCommand href
name "main page"
target "index.html"

\end_inset

.
\end_layout

\begin_layout Subsection
Versions
\end_layout

\begin_layout Standard
There are several versions of this page:
\end_layout

\begin_layout Itemize
A 
\begin_inset CommandInset href
LatexCommand href
name "non-Unicode version"
target "math.html"

\end_inset

 of this page with midspaces.
\end_layout

\begin_layout Itemize
A 
\begin_inset CommandInset href
LatexCommand href
name "Unicode version"
target "math-unicode.html"

\end_inset

 with mathematical spaces (generated with 
\family typewriter
--unicode
\family default
).
\end_layout

\begin_layout Itemize
An 
\begin_inset CommandInset href
LatexCommand href
name "ISO-8859-15 version"
target "math-iso885915.html"

\end_inset

 (generated with 
\family typewriter
--iso885915
\family default
).
\end_layout

\begin_layout Itemize
An 
\begin_inset CommandInset href
LatexCommand href
name "HTML version"
target "math-html.html"

\end_inset

 (generated with 
\family typewriter
--html
\family default
).
\end_layout

\begin_layout Itemize
A 
\begin_inset CommandInset href
LatexCommand href
name "MathJax remote version"
target "math-mathjax.html"

\end_inset

 with 
\begin_inset CommandInset href
LatexCommand href
name "MathJax"
target "http://www.mathjax.org/"

\end_inset

 (generated with 
\family typewriter
--mathjax remote
\family default
).
\end_layout

\begin_layout Itemize
A 
\begin_inset CommandInset href
LatexCommand href
name "MathJax local version"
target "math-mathjax-local.html"

\end_inset

 with 
\begin_inset CommandInset href
LatexCommand href
name "MathJax"
target "http://www.mathjax.org/"

\end_inset

 (generated with 
\family typewriter
--mathjax
\family default
 and a local URL).
\end_layout

\begin_layout Itemize
A 
\begin_inset CommandInset href
LatexCommand href
name "Google Charts version"
target "math-googlecharts.html"

\end_inset

 with 
\begin_inset CommandInset href
LatexCommand href
name "Google Charts"
target "http://code.google.com/apis/chart/index.html"

\end_inset

 (generated with 
\family typewriter
--googlecharts
\family default
).
\end_layout

\begin_layout Standard
All of them are generated from the same 
\family typewriter
.lyx
\family default
 source file; they should help you decide which rendering options suit you
 best.
\end_layout

\begin_layout Standard
Also available online is the eLyXer translation of the latest 
\begin_inset CommandInset href
LatexCommand href
name "LyX’s detailed Math manual"
target "http://elyxer.nongnu.org/lyx/Math.html"

\end_inset

, which contains a lot more examples of LyX maths.
\end_layout

\begin_layout Section
Typography
\end_layout

\begin_layout Standard
Math formulae use a lot of different symbols and fonts.
\end_layout

\begin_layout Subsection
Greek Symbols
\end_layout

\begin_layout Standard
Greek symbols are very important in equations: 
\begin_inset Formula $\phi$
\end_inset

, 
\begin_inset Formula $\pi$
\end_inset

, 
\begin_inset Formula $\Xi$
\end_inset

.
 eLyXer offers a complete set in both upper case: 
\begin_inset Formula $\Gamma\ldots\Omega$
\end_inset

 and lower case: 
\begin_inset Formula $\alpha\ldots\omega$
\end_inset

.
 Also the AMS italicized upper case: 
\begin_inset Formula $\varGamma\ldots\varOmega$
\end_inset

.
\end_layout

\begin_layout Subsection
Math Symbols
\end_layout

\begin_layout Standard
eLyXer supports the whole set of math symbols in 
\begin_inset CommandInset href
LatexCommand href
name "John D. Cook's list"
target "http://www.johndcook.com/math_symbols.html"

\end_inset

: 
\begin_inset Formula $\exists\partial\nabla\geq$
\end_inset

.
 It can also render a few more: 
\begin_inset Formula $\propto\times$
\end_inset

.
\begin_inset Note Note
status collapsed

\begin_layout Plain Layout
The 
\backslash
propto symbol is rendered as 
\begin_inset Formula $\mu$
\end_inset

 in the LyX 1.6.8 window.
 LyX bug?
\end_layout

\end_inset

 You also get all symbols from 
\begin_inset CommandInset href
LatexCommand href
name "Markus Kuhn's list"
target "http://www.cl.cam.ac.uk/~mgk25/ucs/examples/TeX.txt"

\end_inset

: 
\begin_inset Formula $\bigodot\amalg$
\end_inset

.
\end_layout

\begin_layout Subsection
Other Symbols
\end_layout

\begin_layout Standard
There are other symbols like arrows: 
\begin_inset Formula $\leftarrow\rightarrow$
\end_inset

, or geometrical shapes: 
\begin_inset Formula $\circ$
\end_inset

, 
\begin_inset Formula $\square$
\end_inset

.
 eLyXer offers limited support for them.
 You might also want to use financial symbols in formulae: 
\begin_inset Formula $\yen\euro\$$
\end_inset

.
\end_layout

\begin_layout Subsection
Spacing
\end_layout

\begin_layout Standard
Equations look good when items are properly separated.
 The main separation is the Medium Mathematical Space: 
\begin_inset Formula $x=3$
\end_inset

.
 
\begin_inset Note Greyedout
status open

\begin_layout Plain Layout
Note: if you are viewing the non-Unicode version 
\begin_inset Flex URL
status collapsed

\begin_layout Plain Layout

math.html
\end_layout

\end_inset

 of this page then you are in fact seeing midspaces, which are very similar
 but not exactly the same: 
\begin_inset Formula $\frac{4}{18}\mathrm{em}$
\end_inset

 for medium mathematical spaces versus 
\begin_inset Formula $\frac{1}{2}\mathrm{en}$
\end_inset

, where 
\begin_inset Formula $1\mathrm{em}=2\mathrm{en}$
\end_inset

.
 Try out the Unicode version 
\begin_inset Flex URL
status collapsed

\begin_layout Plain Layout

math-unicode.html
\end_layout

\end_inset

 -- and viceversa.
 You can check out what version this page is in the page title.
\end_layout

\end_inset


\end_layout

\begin_layout Standard
The command 
\family typewriter

\backslash
raisebox
\family default
 is useful to, surprisingly, raise a little box, 
\begin_inset Formula \[
\raisebox{2mm}{raised}over\raisebox{-2mm}{lowered}\textrm{and back}.\]

\end_inset

Like 
\family typewriter

\backslash
mbox
\family default
, it puts its content in a text box.
 It can also be used just for spacing:
\begin_inset Newline newline
\end_inset

 
\begin_inset Formula $\raisebox{5mm}{}B^{V}$
\end_inset

.
\end_layout

\begin_layout Standard
There are other spacing commands: 
\family typewriter

\backslash
hspace
\family default
: 
\begin_inset Formula $a\hspace{4mm}b$
\end_inset

, protected space: 
\begin_inset Formula $a\ b$
\end_inset

, and (at 
\begin_inset Quotes eld
\end_inset

block level
\begin_inset Quotes erd
\end_inset

)
\family typewriter
 
\backslash
vspace
\family default
: 
\begin_inset Formula $a\vspace{1cm}b$
\end_inset

.
\end_layout

\begin_layout Standard
There should be 1
\begin_inset space ~
\end_inset

cm of vertical space above this paragraph.
\end_layout

\begin_layout Subsection
Fonts
\end_layout

\begin_layout Standard
By default, letters denote variables and are taken from the 
\family typewriter

\backslash
mathnormal
\family default
 font, which is italic, 
\begin_inset Formula $\alpha x+\alpha y=\alpha(x+y)$
\end_inset

, with the exception of upright capital Greek letters, 
\begin_inset Formula $G\ne\Gamma$
\end_inset

.
\end_layout

\begin_layout Standard
Function names should be upright: 
\begin_inset Formula $\sin(2\pi),\log(x),\tan\delta$
\end_inset

.
\end_layout

\begin_layout Standard
Mathematical fonts used in equations include 
\begin_inset Formula $\mathrm{Roman}$
\end_inset

 (
\family typewriter

\backslash
mathrm
\family default
), 
\begin_inset Formula $\mathsf{Sans\: Serif}$
\end_inset

 (
\family typewriter

\backslash
mathsf
\family default
), 
\begin_inset Formula $\mathtt{Typewriter}$
\end_inset

 (
\family typewriter

\backslash
mathtt
\family default
), 
\begin_inset Formula $\mathbf{Bold}$
\end_inset

 (
\family typewriter

\backslash
mathbf
\family default
), 
\begin_inset Formula $\mathscr{SCRIPT}$
\end_inset

 (
\family typewriter

\backslash
mathscr
\family default
), 
\begin_inset Formula $\mathcal{CALLIGRAPHIC}$
\end_inset

 (
\family typewriter

\backslash
mathcal
\family default
), 
\begin_inset Formula $\mathbb{BLACKBOARD\: BOLD}$
\end_inset

 (
\family typewriter
\noun on

\backslash

\noun default
mathbb
\family default
), and 
\begin_inset Formula $\mathfrak{Fraktur}$
\end_inset

 (
\family typewriter

\backslash
mathfrak
\family default
).
 For the latter, some single characters are translated to their Unicode
 equivalents: 
\begin_inset Formula $\mathscr{F}$
\end_inset

, 
\begin_inset Formula $\mathbb{F}$
\end_inset

, 
\begin_inset Formula $\mathfrak{F}$
\end_inset

.
\end_layout

\begin_layout Standard
Regular text in a formula can be achieved via text font commands like 
\family typewriter

\backslash
textrm
\family default
: 
\begin_inset Formula $5\:\textrm{to}\:10$
\end_inset

, via boxes like 
\backslash
mbox (prevents line breaks): 
\begin_inset Formula $6\mbox{ is more than }5$
\end_inset

, or the AMSmath 
\family typewriter

\backslash
text
\family default
 macro (scales like math symbols) 
\begin_inset Formula $\text{base}_{\text{sub}}^{\text{super}}$
\end_inset

.
 The content of an mbox is processed in LaTeX text mode.
 This allows text font commands, e.g.
 a switch to 
\family sans
\series bold
\shape italic
sans-serif-bold-italic
\family default
\series default
\shape default
, or the phonetic alphabet: 
\begin_inset Formula $\mbox{\textbf{\textsf{\textbf{\textit{sfbfit}}}}, \textipa{tipa}}$
\end_inset

.
\end_layout

\begin_layout Standard
Units should be written upright, either with 
\family typewriter

\backslash
mathrm
\family default
 or with macros from the 
\family typewriter
units
\family default
 package, e.g.
 as simple unit, 
\begin_inset Formula $\unit{km}$
\end_inset

, with magnitude, 
\begin_inset Formula $\unit[57]{km}$
\end_inset

, with fractional unit, 
\begin_inset Formula $\unitfrac[200]{km}{h}$
\end_inset

, or with a fraction before the units, 
\begin_inset Formula $\unit[\nicefrac{3}{2}]{km}$
\end_inset

, 
\begin_inset Formula $\unit[\frac{7}{16}]{s}$
\end_inset

.
\end_layout

\begin_layout Section
Numeration
\end_layout

\begin_layout Standard
Equations can be numbered, like (
\begin_inset CommandInset ref
LatexCommand ref
reference "eq:first"

\end_inset

) 
\begin_inset Formula \begin{equation}
y=x\label{eq:first}\end{equation}

\end_inset

 And also like 
\begin_inset CommandInset ref
LatexCommand eqref
reference "eq:second"

\end_inset

.
 
\begin_inset Formula \begin{equation}
x=3\label{eq:second}\end{equation}

\end_inset

 Some equations can be numbered even if they don't have a label.
\end_layout

\begin_layout Standard
\begin_inset Formula \begin{equation}
x=2y\end{equation}

\end_inset

 Notice that equation (
\begin_inset CommandInset ref
LatexCommand ref
reference "eq:second"

\end_inset

) comes after (
\begin_inset CommandInset ref
LatexCommand ref
reference "eq:first"

\end_inset

).
\end_layout

\begin_layout Section
Simple Structures
\end_layout

\begin_layout Standard
Let's now see a few of the simpler structures that eLyXer can output.
\end_layout

\begin_layout Subsection
Fractions
\end_layout

\begin_layout Standard
A simple fraction: 
\begin_inset Formula \[
\frac{1}{2}.\]

\end_inset

Inlined: 
\begin_inset Formula $\frac{2}{3}.$
\end_inset


\end_layout

\begin_layout Standard
A big recursive fraction: 
\begin_inset Formula \[
\frac{1}{\left(1+\left(\frac{1}{1+\left(\frac{1}{1+2x}\lyxlock\right)}\lyxlock\right)\right)}\lyxlock\]

\end_inset


\end_layout

\begin_layout Standard
A nice fraction: 
\begin_inset Formula $\nicefrac{5}{6}$
\end_inset

.
 A non-diminishing fraction containing alignments:
\begin_inset Formula \[
\cfrac{1}{1+\left(\cfrac[l]{1}{1+x}\times\cfrac[r]{1}{1+x}\right)}.\]

\end_inset


\end_layout

\begin_layout Standard
A similar concept is a binomial coefficient: 
\begin_inset Formula $\binom{A+1}{B}.$
\end_inset

 It can be prettily presented: 
\begin_inset Formula \[
\dbinom{A}{B+1}.\]

\end_inset


\end_layout

\begin_layout Standard
A symbol can be stacked over another using 
\family typewriter

\backslash
stackrel
\family default
: 
\begin_inset Formula $x\stackrel{R}{\rightarrow}y$
\end_inset

.
 Anything can be stacked: 
\begin_inset Formula \[
d\stackrel{x>3}{\lim}x,\quad\stackrel{\mathrm{head}}{\mathrm{heels}}.\]

\end_inset


\end_layout

\begin_layout Subsection
Limits
\end_layout

\begin_layout Standard
\begin_inset Formula $\lim_{x\rightarrow\infty}f(x)$
\end_inset

 should appear as 
\begin_inset Formula $x\rightarrow\infty$
\end_inset

 in italics, and 
\begin_inset Quotes fld
\end_inset

lim
\begin_inset Quotes frd
\end_inset

 in plain style.
 In display mode, a limit must appear below the main symbol: 
\begin_inset Formula \[
\lim_{x\rightarrow\infty}\lyxlock f(x).\]

\end_inset


\end_layout

\begin_layout Standard
Limits are also used in sums and integrals: 
\begin_inset Formula \[
\sum_{i=1}^{\infty}x,\;\int_{0}^{\infty}f(x)\,\mathrm{d}x\]

\end_inset

where the sum's limits should appear below (
\begin_inset Formula $i=1$
\end_inset

) and above (
\begin_inset Formula $\infty$
\end_inset

) the 
\begin_inset Formula $\sum$
\end_inset

.
 The placement of the integral limits depends on the document class: LaTeX
 standard classes place them right to the 
\begin_inset Formula $\int$
\end_inset

.
 Limits are shown to the right in inline formulae: 
\begin_inset Formula $\sum_{i=1}^{\infty}x$
\end_inset

 and 
\begin_inset Formula $\intop_{i=1}^{\infty}x.$
\end_inset


\end_layout

\begin_layout Standard
The placing of limits can be configured with the 
\family typewriter

\backslash
limits
\family default
 and 
\family typewriter

\backslash
nolimits
\family default
 macros: 
\begin_inset Formula \[
\lim\nolimits _{x\rightarrow\infty}\lyxlock f(x),\;\sum\nolimits _{i=1}^{\infty}x,\;\int\limits _{0}^{\infty}f(x)\,\mathrm{d}x\]

\end_inset


\end_layout

\begin_layout Subsection
Roots
\end_layout

\begin_layout Standard
A square root: 
\begin_inset Formula $\sqrt{3}.$
\end_inset

 A more complex root in a fraction:
\begin_inset Formula \[
\frac{1}{\left(1+\sqrt{2}\left(\frac{1}{1+\sqrt{2}}\lyxlock\right)+\sqrt{\frac{1}{2}}\right)}\lyxlock.\]

\end_inset


\end_layout

\begin_layout Standard
eLyXer can also do higher-order roots: 
\begin_inset Formula $\sqrt[3]{x+y}$
\end_inset

.
 A devilish case mixing everything we have seen so far:
\begin_inset Formula \[
\frac{\sqrt[\nicefrac{7}{8}]{\frac{8}{4}x}+\sum_{i=1}^{\infty}x}{\sqrt[s+5]{\frac{(78x+45y)\times\sqrt{\Omega}}{\sin(x+1)}+\unit[38]{km}}}\lyxlock.\]

\end_inset


\end_layout

\begin_layout Section
Complex Structures
\end_layout

\begin_layout Standard
In this section we will explore arrays and related constructs.
\end_layout

\begin_layout Subsection
Arrays
\end_layout

\begin_layout Standard
An inline array 
\begin_inset Formula $\left[\begin{array}{cc}
a & b\\
c & d\end{array}\right]$
\end_inset

 is always shown in the same line.
 In display mode, the array is shown on its own line: 
\begin_inset Formula \[
\left[\begin{array}{lc}
12 & 2\\
3 & 4\times y^{x}\end{array}\right]\]

\end_inset

Apart from that the appearance should be the same.
\end_layout

\begin_layout Subsection
Brackets
\end_layout

\begin_layout Standard
Arrays are separated by variable-size brackets: 
\begin_inset Formula $\left(\begin{array}{cc}
a & b\\
c & d\end{array}\right)$
\end_inset

 
\begin_inset Formula $\left[\begin{array}{cc}
a & b\\
c & d\end{array}\right]$
\end_inset

 
\begin_inset Formula $\left\{ \begin{array}{cc}
a & b\\
c & d\end{array}\right\} $
\end_inset

 
\begin_inset Formula $\left\langle \begin{array}{cc}
a & b\\
c & d\end{array}\right\rangle $
\end_inset

 
\begin_inset Formula $\left|\begin{array}{cc}
a & b\\
c & d\end{array}\right|$
\end_inset

which might also differ on right and left 
\begin_inset Formula $\left(\begin{array}{cc}
a & b\\
c & d\end{array}\right)$
\end_inset

 or use the empty opening 
\begin_inset Formula $\left\{ \begin{array}{cc}
a & b\\
c & d\end{array}\right.$
\end_inset

 or closing: 
\begin_inset Formula $\left.\begin{array}{cc}
a & b\\
c & d\end{array}\right|$
\end_inset

.
 There are also fixed-size big brackets, e.g.
 
\begin_inset Formula $\bigl\langle f\bigr\rangle$
\end_inset

.
\end_layout

\begin_layout Subsection
Cases
\end_layout

\begin_layout Standard
Used to switch between several values.
\end_layout

\begin_layout Standard
\begin_inset Formula \[
y=\begin{cases}
x & i=0,\\
x+1 & i<3\end{cases}\]

\end_inset


\end_layout

\begin_layout Standard
Cases may have more than two rows:
\end_layout

\begin_layout Standard
\begin_inset Formula \[
f(x)=\begin{cases}
0 & x<0,\\
\infty & x=0\\
0 & x>0\end{cases}\]

\end_inset


\end_layout

\begin_layout Subsection
Braces
\end_layout

\begin_layout Standard
Values can be underbraced or overbraced.
\end_layout

\begin_layout Standard
\begin_inset Formula $\underbrace{a-b}=\overbrace{b+c+d+e}$
\end_inset

.
\end_layout

\begin_layout Section
Macros
\end_layout

\begin_layout Standard
Now it's time for user-defined commands (sometimes called 
\begin_inset Quotes eld
\end_inset

macros
\begin_inset Quotes erd
\end_inset

).
\end_layout

\begin_layout Standard
Definitions can be added as macros
\begin_inset FormulaMacro
\newcommand{\stupidroot}[2]{\sqrt[#1]{#2}}
{\sqrt[#1]{#2}}
\end_inset

.
 Then they can be used in formulae: 
\begin_inset Formula $\stupidroot 12$
\end_inset

.
 They can accept default parameters
\begin_inset FormulaMacro
\newcommand{\defaultroot}[2][4][5]{\sqrt[#1]{#2}}
{#1\sqrt{#2}}
\end_inset

.
 Again, useful in formulae: 
\begin_inset Formula $\defaultroot$
\end_inset

.
\end_layout

\begin_layout Standard
Other definitions from the preamble can be used: 
\begin_inset Formula $\preambleroot{3}{4}$
\end_inset

.
\end_layout

\begin_layout Standard
Definitions on the fly are also possible: 
\begin_inset Formula $\newcommand{\ontheflyroot}[2]{\sqrt[#1]{#2}}\ontheflyroot{7}{8}$
\end_inset

, and used with different values: 
\begin_inset Formula $\ontheflyroot{a}{b}$
\end_inset

.
\end_layout

\end_body
\end_document
elyxer-1.2.5/docs/userguide-toc.html0000644000175000017500000001655512117174755016760 0ustar  chennochenno







Converted document


elyxer-1.2.5/docs/userguide.html0000644000175000017500000023450512117174754016171 0ustar chennochenno eLyXer User Guide

figure elyxer.png eLyXer User Guide

Alex Fernández (elyxer@gmail.com)

Table of Contents

1 The Basics

elixir, n: a substance believed to cure all ills[1].
eLyXer (pronounced elixir) is a LyX to HTML converter. While there are a ton of such projects all over the web, eLyXer has a clear focus on flexibility and elegant output.
eLyXer (including this guide and all accompanying materials) is licensed under the GPL version 3 or, at your option, any later version. See the LICENSE file for details.
Please visit the main page to find out about the latest developments.

1.1 System Requirements

eLyXer requires Python 2.4.x, and should work with versions up to 2.6.y; it will convert documents generated by LyX 1.5.x to 2.0. It has been tested on the most common operating systems: on Mac OS X, Linux and Windows, with and without CygWin.
Resource usage should be quite frugal; eLyXer runs quite happily on my 1st-gen Asus Eee, with its puny Celeron@570MHz and 512 MB of RAM. It should also be fast — the Eee can convert ~200 pages of LyX text in just over 50 seconds. Performance is fairly linear: 200 pages take 10 ×  as long as 20, so there are no scalability problems. Memory usage stays low even when processing large documents, and conversion can be done on the fly (with --lowmem) for even lower memory requirements.

1.2 Installation

This section looks at how to install eLyXer on your system, assuming that Python 2.4 to 2.6 is already there.

Download eLyXer

First you will need to fetch the official distribution file from the download area. Now, there is more than one way to install eLyXe, but all of them start by uncompressing the distributed file to a suitable directory. Just write at the command prompt:
$ tar -xzf elyxer-[version].tar.gz
Or for the .zip version:
$ unzip elyxer-[version].zip
A directory called elyxer should appear, where the main executable file elyxer.py resides.

Using the Installer

An installer is provided in the root directory, called install.py; it is the recommended way to install eLyXer. To run it just type in a console as root:
# python install.py
On Windows you can type (as a regular user):
> python.exe install.py
In any case, the script will install eLyXer as a Python script. Now you can check if it was installed successfully:
$ elyxer.py --help
A brief help text and the list of command line options should appear.
The installer will also copy existing translation files to your hard drive so that they can be used from within eLyXer for internationalization.

Prepackaged Versions

The easiest way to install eLyXer is if someone has prepackaged it for your system. Some Linux distributions include eLyXer: Debian squeeze and Ubuntu Lucid. Installation is done using apt-get or aptitude, for Debian as root:
# apt-get install elyxer
or, for Ubuntu:
$ sudo aptitude install elyxer
For both Debian and Ubuntu eLyXer needs to be run as "elyxer":
$ elyxer --help
On Windows, the alternate LyX installer includes eLyXer in the default installation. See 1.6↓ for LyX integration.

Manual Installation

If the installer did not work for you, you can manually install it as a module. On Linux go to the elyxer directory and type, as root:
# python setup.py install
On Windows just type:
> python.exe setup.py install
On Mac OS X you can use sudo to get the necessary permissions:
% sudo python setup.py install
Now you can run eLyXer as a Python script:
$ elyxer.py --help
The list of command line options should appear. You can also manually copy the file elyxer.py to a directory found in the execution path (for instance, /usr/bin on Linux or c:\windows\system32 on Windows).

1.3 Test Drive

Now you may want to try to convert the user guide:
$ elyxer.py --css lyx.css --title "eLyXer User Guide" docs/userguide.lyx docs/userguide2.html
It should generate a working web page identical to the one distributed:
$ diff docs/userguide.html docs/userguide2.html
The typical output will contain just the changed lines, which in this case should be only the header with the file creation date. An example is shown on listing 1↓.
7c7
< <meta name="create-date" content="2009-09-11"/>
---
> <meta name="create-date" content="2009-09-12"/>
Algorithm 1 Example of diff output for functionally identical HTML files.
If nothing else appears (i.e. both files are functionally equal) then everything is working fine. If you have bash installed, to test that everything really works fine you can just run the included tests:
$ ./run-tests
It will run a number of test and check the results, so you can see if everything is well. You also need to have installed the command-line tool diff to show differences between two files.

1.4 Usage

eLyXer is a standalone command line tool. It can be invoked from the command line as:
$ elyxer.py [options] [source file] [destination file]
If the source file is omitted then STDIN is used; likewise, if no destination file is specified eLyXer will output to STDOUT. This allows its use in pipes and other flexible configurations. Some examples:
$ elyxer.py file.lyx file.html
converts file.lyx to file.html. Debug messages are shown.
$ cat file.lyx | elyxer.py > file.html
converts file.lyx to file.html, as before. This time debug messages are not shown.
$ elyxer.py file.lyx | grep "<blockquote>" | wc
counts all blockquote paragraphs.
$ elyxer.py file.lyx | wget --no-check-certificate --spider -nv -F -i -
checks all external links in a document recursively. (Local links will appear as unresolved, but they can be ignored.)

1.5 Image Processing

eLyXer does not convert images directly; it uses the ImageMagick package, in particular the convert tool, to create PNG versions of the images embedded in the original LyX documents, and then it inserts links to those PNG images in the resulting HTML pages. If ImageMagick is not installed eLyXer will show an error message and will not try to convert further images.
HTML pages, unlike PDF documents, do not contain images in the document file; rather they contain pointers to image locations on disk. (Fortunately, LyX documents do not contain images either.) eLyXer will generate pages that point to the same locations as the original images, when they are PNG images, or to the converted versions otherwise. Image types like Encapsulated PostScript cannot be used directly from within pages.
Image location is fragile. All images should be placed in the same location (and with the same structure) as the original document; and they should all be referenced relatively to the current document. During conversion from within LyX image locations can be lost, since LyX does not do in-place conversion; instead, LyX copies the original file to a temporary directory, converts the file and then copies everything back to a directory ending in .LyXconv.

1.6 LyX Integration

If you used the eLyXer installer LyX will automatically detect it after reconfiguration. Just make sure that you are running LyX 1.6.5 or later, and click on Tools ▷ Reconfigure.
LyX should be able to detect if eLyXer was installed as a script, or even if it has been installed from a Linux distribution. In any case you can verify that it has been recognized by LyX by opening Tools ▷ Preferences…, going to External formats ▷ Converters, and finding the converter for “LyX -> HTML”. If eLyXer is there, it worked! Now you can convert your documents using View ▷ HTML. Otherwise try to reinstall eLyXer from scratch and then reconfigure LyX.

Installing as a Package or as a Module

Versions of the eLyXer installer prior to 1.2.0 tried to install eLyXer as a module, so it could be run using "python -m elyxer". This option is deprecated since a module called elyxer would collide with a Python package of the same name, and there are plans to install eLyXer as a proper Python package in the future (probably in the 1.3.0 time frame). In the interim eLyXer is installed only as a script called elyxer.py.
LyX (starting with versions 2.0.0 and 1.6.9) has been patched to recognize only the script and disregard the module.

2 Advanced Use

There are some advanced uses for eLyXer if you want to extract the most of it.

2.1 Command Line Options

eLyXer supports a few command line options:
--help: Show command line help.
--quiet: Be quiet and do not output messages (except errors). This way you can avoid the comforting “Parsing line 1000” messages. When STDIN or STDOUT are used (e.g. in a pipeline) --quiet is always enabled.

Advanced Options

--debug: Show debug messages. They may help a developer understand your problem.
--version: Show version number and date. Use to check which version you are actually running.
--lyxformat: Return the highest LyX version that eLyXer understands. This parameter is provided to help with lyx2lyx integration, so that this tool knows if it must convert the file to a lower LyX format.

Options to Control HTML output

--title "title": Change the title of the generated web page.
--css "new.css": Change default CSS. See section 2.2↓: CSS.
--embedcss "file.css": Embed the styles in file.css into the resulting HTML document. See section 2.2↓: CSS.
--html: Generate HTML 4.0 (instead of XHTML). The resulting pages should be easier to import from certain word processors. See section 2.6↓: HTML code.
--unicode: Restore full Unicode output. Right now switches midspaces to medium mathematical spaces. See also section 2.6↓: HTML code.
--iso885915: Generate a document using ISO-8859-1 encoding. Again, see section 2.6↓: HTML code.
--nofooter: Omit the footer message “Document generated by eLyXer” (shown at the bottom).

Options to Control image output

--directory "images_dir": Look for images in the directory specified.
--destdirectory "dest_dir": Converted images will end up into this directory.
--imageformat ".extension": Force the format implied by the extension (e.g. ".jpg" for JPEG) for output images. Use --imageformat "copy" to make images be copied over instead of converted.
--converter "program":Use the given program to convert images. Right now the supported converters are: imagemagick (default), inkscape and lyx itself. With --converter inkscape eLyXer picks Inkscape as the image converter (Inkscape uses some non-standard extensions so it might be needed to convert SVG images to PNG); with --converter lyx the new LyX option lyx -C is used. You can also supply your own converter command line, using $input and $output as variables (note the single quotes):
$ elyxer.py --converter ’lyx -C $input $output’ [source file] [destination file]
--noconvert: Use all images in their original location and do not convert anything. Useful when using images which do not convert well, such as SVG files.

Options to Control footnote output

--numberfoot: Number all footnotes using numbers: “[1]”, instead of the default “[A]”.
--symbolfoot: mark footnotes with symbols (*, **, †, ‡…).
--hoverfoot: show footnotes as hovering text. This is the default position.
--marginfoot: show footnotes with numbers instead of letters.
--endfoot: show footnotes at the end of the page.
--supfoot: use superscript for footnote markers. This is the default style.
--alignfoot: use aligned text for footnote markers, instead of superscript.
--footnotes "options": specify several footnotes options at the same time, separated with commas. Available options are: "number", "hover", "margin", "end". See section 2.9↓: Footnotes.

Advanced Options to Control HTML output

--splitpart "depth": Split the resulting webpage at the given depth. See section 2.5↓: Segmenting Pages.
--tocfor "original.html": Generate just a table of contents with links to the original HTML file. See section 2.4↓: TOC.
--target "frame": Add a target attribute to every link in the generated HTML, making all links point to the provided frame. Again, see section 2.4↓: TOC.
--notoclabels: Omit “Chapter”, “Part” and similar labels from the TOC; just output part numbers (and separate using a period). For instance, a chapter that without this option is labeled “Chapter 2: Advanced Use” in the TOC would now become “2. Advanced Use”, as on the PDF. Option adapted from the wish list: 3.2↓.
--lowmem: Activate a low memory mode which does not keep the whole document in memory: conversion is done on the fly. Keep in mind that some features as the TOC will be missing from the generated document.
--numberfoot:Label footnotes using numbers, instead of letters. Useful when bibliographical references are not numbered and therefore cannot be confused with footnotes.
--raw: Generate an HTML page without header or footer.
--mathjax remote: Use the excellent JavaScript library MathJax remotely to pretty-print mathematical equations. See section 2.8↓.
--mathjax "URL": Use the excellent JavaScript library MathJax at the given URL (usually a local URL is used). See also section 2.8↓.
--googlecharts: Use Google Charts to generate images for every formula. Again, see 2.8↓.
--simplemath: Do not generate fancy math structures such as multi-line Unicode brackets or stacked limits. This option is automatically activated when --html is selected; once more see section 2.8↓.
--template "file": Use an HTML template. The raw converted document will be placed where <!--$content--> appears in the template. Available variables: <!--$content-->, <!--$title-->, <!--$author-->, <!--$encoding-->, <!--$css-->, <!--$navigation-->, <!--$year-->, <!--$date-->, <!--$datetime-->, <!--$version-->, <!--$script-->, <!--$mathjax-->.
--copyright: Include a copyright notice at the bottom.

Deprecated Options

--toc: Generate just a table of contents. Use --tocfor instead.
--toctarget "original.html": Generate a table of contents with links to the original HTML file. Use --tocfor instead.
--nocopy: No effect since the copyright notice is now optional, maintained for backwards compatibility.
When an option accepts an argument it can be added after a space as --target "frame", or with an equals sign as in --target="frame". The quotes are optional and can be useful if your arguments include e.g. spaces.

Adding Options In LyX

To add one of these options so that it is used from within LyX, you have to modify the converter line. To this effect open Tools ▷ Preferences…, go to External formats ▷ Converters, find the converter for “LyX -> HTML” and edit the converter line. It should read something like this:
elyxer.py --directory $$r $$i $$o
If you want to generate pure HTML instead of XHTML, change the line to:
elyxer.py --html --directory $$r $$i $$o
And so on. Figure 1 shows what to do to add the --html option: after editing the line and adding the new option, click on “Modify” and then “Save” or “Apply” the changes. You should never remove the $$i $$o at the end, since it is what tells eLyXer where to find the input and output files.
figure converters.png
Figure 1 eLyXer converter in LyX 1.6.5.
LyX 1.6.5 supports a new “extra flag” line; however, at this moment it does not work with eLyXer.

2.2 CSS

HTML output, as generated, can fall short in certain situations. Some CSS wizardry can go a long way to customize eLyXer.
eLyXer tags most elements with the type so you can later modify them using a CSS. The default HTML header is similar to listing 2↓, so the default remote CSS file is used.
<head>
[...]
<link rel="stylesheet" href="http://elyxer.nongnu.org/lyx.css" type="text/css" media="all"/>
<title>Your title here</title>
</head>
Algorithm 2 CSS link automatically added to HTML
This sample CSS file is published on nongnu.org and distributed along with the scripts, docs/lyx.css. (You may have found that your document shows minor changes in its appearance with time — this is the reason. The main author regularly publishes a new, updated version of lyx.css on nongnu.org, and all documents using it automatically appear with the changes. Backwards compatibility is maintained as much as possible.)
To give your document a customized appearance (or for pages to be accessible offline) you probably will want to use your own CSS file; to use it first copy it to the directory where your document resides (e.g. renaming it to custom.css), and customize as needed. Then run elyxer.py with the following option:
$ elyxer.py --css=custom.css document.lyx page.html
This will make the generated page.html use your custom.css file. The ‘=’ sign between the constant ‘--css’ and the name of the CSS file is optional. More than one --css option can be added if you want several CSS files to be used in the header.
Sometimes the styles in a CSS are needed in the HTML document (for offline viewing, or to distribute as stand-alone pages). For these uses there is the option --embedcss: the styles contained in the CSS file passed as an argument will be embedded in the resulting HTML document. For instance:
$ elyxer.py --embedcss custom.css document.lyx page.html
This command generates a document page.html where the styles in custom.css are embedded. The CSS to embed must be a file, not a remote URL. Listing 3↓ shows the resulting HTML header for a test CSS with just one style, div.Standard. Note that the remote CSS is still added by default; to avoid it just add an option with an empty CSS file, --css="".
<head>
[...]
<head>
<link rel="stylesheet" href="http://elyxer.nongnu.org/lyx.css" type="text/css" media="all"/>
<style type="text/css">
<!--
/* Embedded CSS */
div.Standard {
  background: #909090;
}
-->
</style>
<title>Your title here</title>
</head>
Algorithm 3 CSS embedded into the HTML
As with the --css option, several --embedcss options can be added to embed more than one file.
The CSS file for eLyXer uses some CSS2 features for math structures (fractions, arrays). This makes the output incompatible with older browsers; it requires Microsoft Internet Explorer 7, Firefox 3, Safari 3 or Chrome 1. Check the Math Showcase to see if your browser can render eLyXer output correctly.

2.3 Title

By default the generated web pages have the title “Converted Document”. If a PDF title is found then it is used instead. The proper LyX title (a paragraph of type “Title” embedded in the text) will also be used if found. But when --lowmem is in use eLyXer does not try to get the proper title, since it may be found in the middle of the document or not be present at all; scanning for it would mean doing two passes, one to look for the title in all the document and another to output the web page, and --lowmem implies on-the-fly conversion to save memory.
You can change the title of the generated web page with the --title option:
$ elyxer.py --title "My Beautiful Document" document.lyx page.html

2.4 Table Of Contents

A table of contents (or TOC) can be generated for every converted LyX document. You can optionally also add a target frame to every link. The trick is to combine both options to generate a TOC that links to the original document on a different frame. For example, if the original page is called page.html and you generated it with this command:
$ elyxer.py document.lyx page.html
you can generate the TOC linking to this page, and at the same time point it to frame contents:
$ elyxer.py --tocfor page.html --target contents document.lyx page-toc.html
Then you can put it all together with a simple frameset generated manually. Just remember to place the original document in the frame called contents.
<html>
  <frameset cols="30%,70%">
    <frame name="toc" src="page-toc.html" />
    <frame name="contents" src="page.html" />
  </frameset>
</html>
Algorithm 4 An example frameset for TOC navegation
TOC generation accepts the same options as normal document conversion. For example, if you follow these instructions literally you will notice that the TOC has very wide margins and looks a bit weird; that is because it is using the default CSS. A special CSS file for TOC files is provided in docs/toc.css, so better results should be obtained with the --css option:
$ elyxer.py --tocfor page.html --css docs/toc.css --target contents document.lyx page-toc.html
With a little bit of practice you will be able to generate useful (and nice looking) TOC files. You can see an example for the user guide (if you are not already looking at it).

2.5 Segmenting Pages

Quite often you don’t want a huge monolithic page, but a set of linked pages. To do so you can use the --splitpart option, specifying the level at which eLyXer should split pages. For instance:
$ elyxer.py --splitpart 1 document.lyx output.html
will split document.lyx into pages at level 1, using output.html as the root page. Each page will get a number that starts with output and ends with .html, with a suffix that depends on the page — output-2.html will correspond to the second split part.
The level corresponding to 1 depends on the document class: books will be split at chapters, but articles will get a section per page. And so on with lower levels.

2.6 HTML Code

The HTML code generated is technically XHTML Transitional, version 1.0 [2], using UTF-8 encoding. Some programs have (in this day and age) trouble importing XHTML, notably some popular word processors. To work around this problem and provide more flexible output in general you can output HTML 4.0:
$ elyxer.py --html document.lyx page-to-import.html
Again, technically the code generated is HTML 4.01 Transitional [3] using UTF-8 encoding. Both versions should pass the W3C tests [4]. If your particular web page doesn’t pass the tests, then it is a bug and it will be treated as such.
The --html option also activates the --simplemath option; see section 2.8↓: Math for details.

Character Encodings

For better browser compatibility, medium mathematical spaces are substituted in the output with midspaces — improving the output for some popular browsers. If you want your mathematical spaces back, just use the --unicode option:
$ elyxer.py --unicode document.lyx page-to-import.html
Check out the Math Showcase with Unicode to see the results. In the future other non-Unicode substitutions might be used.
In case you want to use the ISO-8859-15 encoding in your generated document, you can add the --iso885915 option:
$ elyxer.py --iso885915 document.lyx page.html
This will make eLyXer output a document with all non-ASCII characters encoded as &nbsp;, &#x2005; and so on. This encoding is similar to ISO-8859-1, also called Latin-1, but including the Euro sign. The Math Showcase (ISO-8859-15 edition) has been generated using this option.
Both encoding options can be combined with --html at will.

2.7 Internationalization

eLyXer is distributed along with a few translation files. They are automatically regenerated every time make is run, and reside in the folder po/. Internationalization is done using GNU gettext, so every locale is identified by a two-letter code (such as “en” for English and “es” for Spanish). There are two kinds of files: the text .po file (which can be found in po/my.po for locale “my”), and the binary .mo file (found in po/my/elyxer.po).
For internationalization to work properly, Linux distributors should take all binary .mo files and place them in the directory corresponding to locale files, which we will call $localedir. As the Python gettext page explains, this is distribution-dependent: for example on Debian $localedir is /usr/share/locale, so for locale “es” the correct route would be
/usr/share/locale/es/LC_MESSAGES/elyxer.mo
Windows distributors on the other hand should place files in %PYTHONHOME%\share\locale, for example for locale “es” on a machine where Python is in C:\python:
C:\python\share\locale\es\LC_MESSAGES\elyxer.mo
To generate a new translation file (we will use “my” as an example locale here, corresponding to Burmese): you need to have the GNU gettext package installed. Then go to the directory where elyxer.pot resides:
$ cd src/conf
and generate a .po file for your locale:
$ msginit --output-file=my.po --locale=my
Then move the file to the po/ directory:
$ mv my.po ../../po/
and start translating it to Burmese! Once you are done run make from the root directory:
$ ./make
and it will generate the file po/my/elyxer.mo. Finally, place this file in
$localedir/my/LC_MESSAGES/elyxer.mo
and you are done.

2.8 Math

Math equations are an important part of what takes LyX apart from other editors, since it supports the full LaTeX feature set — that is, about everything under the sun. Unfortunately, math support is hard to get right. Many developers are focusing on MathML, but at the time of this writing (Q2 2010) support on some common browsers is still missing.
eLyXer follows its usual minimalistic approach and doesn’t try to be everything to everybody — instead, it supports out of the box a set of usual constructs (fraction, square root) and tries to simulate others (binomial, overbrace). See the Math showcase for yourself and learn what eLyXer supports and what not.
For more sophisticated math equations there are a couple of advanced features.

MathJax

The first option is to use MathJax, which is as simple as using the option --mathjax:
$ elyxer.py --mathjax remote math.lyx math-mathjax-remote.html
The remote argument tells MathJax to access the MathJax library remotely on the MathJax CDN. (You should always comply with their terms of service.) See the Math showcase (MathJax remote edition) to check the results.
In case you need to go outside the terms of service, or you want the content to be accessible offline, you can always use a local copy of MathJax. Just use the URL of the repository as an argument to the --mathjax option:
$ elyxer.py --mathjax MathJax/ math.lyx math-mathjax-local.html
This way eLyXer uses the given URL (in the example MathJax/) to load MathJax from and set it up. Although some code needs to be hosted on the same site as the pages, MathJax uses a feature called web-fonts which can be downloaded from a public server; this is quite easier to host. See the Math showcase (MathJax edition) to see how MathJax fares with eLyXer.
Something to note is that MathJax is a JavaScript library; all rendering is done client-side by the user’s browser. This has quite a few advantages:
  • Math processing on the server is quite light; equations are basically surrounded by a special tag and left in TeX form.
  • For developers: integration of these libraries is very easy. It took just a few days to integrate both libraries with eLyXer.
  • MathJax is improving all the time thanks to the efforts of Davide P. Cervone and the rest of the developer team; eLyXer and its users reap the benefits readily.
  • The client browser already knows its abilities, and can choose the rendering method it considers to be the best. MathJax can even choose between MathML and HTML+CSS at page rendering time, showing MathML on fancier browsers and simpler HTML where it is not available.
It also brings some disadvantages:
  • With the remote argument, JavaScript code resides at a remote server and your users will need online access to view the maths.
  • If MathJax is accessed locally you need to also host the code for MathJax. (Web fonts used in MathJax can at least be hosted elsewhere, so publishers do not need to also host the fonts package, but this hasn’t still been used in eLyXer.)
  • And of course it takes some time to render everything on the client, which can degrade the user experience on older machines.
Publishers should carefully consider pros and cons before deciding what to use.

Google Charts

Google Charts is an online service which generates images that contain charts and other stuff; it can also generate TeX formulas. eLyXer can use it using the option --googlecharts:
$ elyxer.py --googlecharts math.lyx math-googlecharts.html
There are some limitations to Google Charts: no macros, formulas cannot exceed 200 characters, and the supported command set is limited (commands in text mode, for instance, are out of bounds). Also, generated images can be hard to align vertically — by default they are middle-aligned, but some small characters or superscripted formulas can look weird. But this option can be a quick&dirty way of showing math for older or unsupported browsers.

Brackets and Limits

Fancy math structures are generated by default: arrays and binomials are surrounded by multi-line Unicode brackets, limits in display mode are stacked above / below the symbol, and so on. When the option --simplemath is used eLyXer avoids such structures and just outputs enlarged regular symbols. It is also included in the --html option.
Check out the Math showcase (HTML edition) to see the results.

2.9 Footnotes

Footnote generation is surprisingly hard to get right in an HTML document. eLyXer has a fairly complete set of command line options to customize how footnotes are generated. Here we will use the aggregated option --footnotes "options" which can be used to specify any combination, but they can be turned on independently using --…foot. For instance: --footnotes number,margin is equivalent to --numberfoot --marginfoot.

Markers

The footnote is attached to a point of the text (the referring text) which is usually marked by a bit of text. The default behavior for the marker is to use a superscript letter surrounded by square brackets, in blue: [A]. The text can be changed to aligned text with --footnotes align: [A], so markers are not mistaken with other superscript constructs such as exponents (like ea).
Markers can also be converted to numbers using --footnotes number: [1]. Or, they can be switched over to symbols using --footnotes symbol: *. Available symbols are rotated from this sequence: * ** † ‡ § §§ ¶ ¶¶ # ##. All options can be combined. For instance, symbol markers look best when shown aligned; --footnotes align,symbol will show aligned symbolic markers such as * or .

Position

Footnotes are supposed to appear at the foot of the page, but that is not always possible or practical in web pages. Huge pages make scrolling up and down quite uncomfortable, and remove the immediacy of having the note in the same page as the referring text.
There are a few alternatives: use the margin, show hovering text, or link to the note at the bottom of the page. eLyXer can use all three. --footnotes margin will place the notes at the margin, just as margin notes but with the addition of the footnote marker. While --footnotes hover will show hovering text when the mouse is placed on the marker; this is the default behavior. Note that hovering notes are converted into margin notes when printing.
When footnotes are shown at the end of the page with --footnotes end, footnote markers turn into links. The actual footnote at the end then contains a link back to the marker.
The most interesting part is that these three options can be combined at will: --footnotes margin,hover,end will show footnotes at the three possible locations. The most practical combination is probably --footnotes hover,end, which will show notes as hovering text and also at the end of the page. Note however that in this case notes will be printed twice (at the margin instead of hovering and at the end).

3 Work in Progress

As you can see eLyXer is a mature and tried package, but it has some rough edges.

3.1 Known Issues

The following issues (including bugs and missing features) are acknowledged. Some of them should be solved soon; others may take longer.
  1. On Mac OS X the output of a message with Unicode characters may cause an error. Workaround: run elyxer.py with the --quiet option.
  2. Some phonetic alphabet symbols are not well supported — if generated with LyX they only appear in a different color: [sample].
  3. Multi-column layouts are lost. This one is almost impossible to get right in CSS, so there are no plans to even try.
  4. Many BibTeX styles are missing. (They are quite trivial to add though.)
  5. ERT (bare TeX code) is ignored.
  6. Many AMS environments (like alignat, gather…) are not working or look strange — some non-AMS environments too.
  7. Images are never scaled above their nominal resolution. This is seldom needed if at all, so there are no plans to change it; if people really need the feature just let the author know so it can be added as an option.

3.2 Wish List

The following features have been requested by users; specific people are referenced by a couple of initials so they can recognize themselves while keeping some anonymity. (If you prefer that your initials do not to appear here at all just let me know.)
Queued features will be added at the next big release — the priority for each feature will be set by the number of users requesting it and date requested. Pending features need some assessment. Those marked as too complex have been evaluated as requiring too much work, but the decision might be reversed if there are enough people interested or a simple way to implement them is found. Once done, features are marked with the first release where they appear.
Feature Date Users Status
Understand \setcounter{section}{1} 2010-05-15 JB 1.1.0
Option to turn off title prefixes in TOC 2010-07-10 YG 1.1.0
Use BibLaTeX with eLyXer 2010-09-14 PJ, WE Pending
Render change tracking: "Show changes in output" 2010-09-18 YG 1.1.0
Option for footnotes at the margin 2010-09-21 A 1.1.0
Output SVG as <img> tags (20↓) 2010-09-22 YG Pending
EPUB output format (19↓) 2010-09-23 MJ, MG Too complex
Option for footnotes at the end of each section 2010-09-23 MJ 1.1.0
Add more controls for image conversion (21↓) 2010-10-02 WE 1.1.0
Support for format 401 (Insert Horizontal Line) 2010-10-06 US 1.1.2
Parse contents of ERTs 2010-10-06 US, JW 1.2.0
Correct scaling of tables with relative sizes (e.g. %col) 2010-10-09 US Pending
BibTeX: parse math formulas inside BibTeX files 2010-10-16 JA 1.1.1
BibTeX: display \url{} as an URL 2010-10-16 JA 1.1.1
Do not label bibliography items in comments 2010-10-21 JA Pending
Unit tests should warn if ImageMagick not installed 2010-10-24 JA Pending
Unit tests should run fine without PNG conversion tools 2010-10-30 JA Pending
Option --imageformat copy to avoid converting images 2010-11-12 JD 1.1.1
Option to embed the CSS in the HTML file22↓ 2010-11-23 GM, JA 1.1.1
Display sub- and superscript aligned vertically (as in integrals) 2010-11-23 GM 1.1.1
Use Unicode large characters for sums, integrals, matrices… 2010-12-07 GM 1.1.2
Do not number captions in code listings 2010-12-08 DC 1.2.0
Support brushes for SyntaxHighlighter 2010-12-10 DC Pending
Generate formula images using Google Charts 2011-01-07 ET 1.2.1
Output reference arrows as CSS pseudo-elements 2011-01-12 GM Pending
Include part names in --splitpart navigation header 2011-01-15 AJ 1.2.1
Merge options --toc and --toctarget into --tocfor 2010-01-17 JA 1.2.1
Make --splitpart and --tocfor work together 2010-01-17 JA, TP 1.2.1
Generate named references (equivalent to \nameref) 2011-01-19 TP 1.2.1
Do not generate entries when index or nomenclature are missing 2011-01-19 TP Queued
Do not output unknown commands in red except in --debug 2011-02-22 JA Queued
Output equations as images 2011-05-31 GK Pending
Parse modules for custom Flex CharStyles 2011-06-08 MG Pending
Convert several files with a single command 2011-06-01 PF Pending
Export slides as HTML5 presentation 2011-06-28 RK Pending
Add an option to remove navigation bars 2011-06-29 AH Pending
Support for External Material: PDF, Date 2011-10-22 MI Pending
Some features require further explanations.

EPUB output format

The EPUB management package calibre does not output valid EPUB documents when converted from eLyXer HTML files, at least according to the Threepress validator.
This is a complex feature request; calibre does minimal formatting in its EPUB conversion, so making it generate valid EPUB documents requires changing deeply how eLyXer outputs XHTML. Lots of help would be needed to get this working.
That said, EPUB readers are often much less strict than the official format and they readily accept eLyXer output. Just convert your LyX document to HTML using eLyXer, and then import the resulting HTML document into your EPUB reader. Let us know how it goes for you.

Output SVG as <img> tags

This feature would be most welcome from the part of the author. Unfortunately, Firefox alone from the major browsers refuses to render <img> tags correctly for SVG. According to bug #276431, this was fixed on 2010-09-08, so the next version should do the right thing; at that point this feature will be queued for inclusion.
You can check out how your browser does with SVG images with this SVG test page.

More controls for image conversion

eLyXer uses ImageMagick to convert images. Some images (in EPS format, for example) do have blank borders, or they come in varied sizes. It would be nice to remove blank borders and have some kind of unified resolution in the conversion, which would be passed to ImageMagick.
As of 1.1.0, the improvements include using ps:use-cropbox=true in ImageMagick for PostScript and EPS images. Unified resolution has not been added as it might collide with picture density, but suggestions are welcome.

CSS controls

Proposed by JRAS on the elyxer-users mailing list, the following is a direct quote of his message.
“[…]A mixed solution for CSS styles:
  1. The essential minimum css for math formatting (a compacted version of a math.css subset) included directly inside HTML head.
  2. Then a call to download the on-line full CSS, that can repeat the minimum already included math.css (from item 1) plus some other styles. The default can be changed by --css command line option.
  3. A new option (--addcss) to add another CSS defined by the user. For example, to only redefine some styles from the default, etc.
The styles should be included in that order (using the "cascading" property). Item 1 is fixed in every HTML file. Item 2 is always added and by default pointing to the eLyXer on-line css, but it can be changed by option --css to another url or file. Item 3 is optional and its url would be added after the other two items, only if the --addcss option was used in conversion.”
As of 1.1.1, an option --embedcss has been added which allows embedding one or more custom CSS files into the resulting HTML document. Also, --css can be repeated as many times as desired to use several CSS files.

3.3 Contact Information

If your problem does not appear in the above list, please let the author know; you can find him at elyxer@gmail.com. In the words of Rich Talley: “the tool’s author really likes getting challenging documents and making eLyXer work with them”. You can send your sample documents and we will try to make eLyXer convert them acceptably. Any documents sent will be treated with the utmost confidentiality.
You can also join the mailing list to discuss any information related to eLyXer. The author monitors the official LyX lists for mentions of eLyXer. Bugs can also be reported at the Savannah page.

3.4 Extending eLyXer

eLyXer should now support most LyX features; but sometimes it will ignore a command, sometimes it will signal it, and it might even refuse to work with certain documents. What can you do if eLyXer does not work with your LyX file? Worry not! Its flexible approach to processing allows anyone to write support for the missing commands.
eLyXer is written in Python so that it does not need to be compiled; its code is interpreted on the fly. See the accompanying developer guide to learn how to extend eLyXer for your own purposes. If you know how to program in Python it should not be difficult to support other LyX features. If you don’t your best bet is to ask the author.

4 FAQ

Q: What versions of LyX are supported?
A: The tool should work with all LyX versions from 1.5.5 to the latest and greatest. It has been tested on Linux, Mac OS X and Windows.
Q: There are indeed a ton of similar projects over the web. Why add another one?
A: The four tools supported by LyX (tex4ht, hevea, tth and latex2html) gave inferior results in 2009, and were quite inflexible. The author found the need for a good converter, while at the same time acknowledging the difficulty of the problem.
Q: Speaking of that: why build a LyX to HTML converter, instead of a more generic LaTeX to HTML converter?
A: The problem space is quite simplified, and therefore progress is much faster. To make it even easier eLyXer has historically centered on the subset of LyX functionality that is useful to most LyX users, leaving the rest for a later stage. Nowadays eLyXer aims to support the full LyX feature set.
Q: What can we expect from the tool in the future?
A: eLyXer should fulfill the needs of 99% of LyX users in the short term. It has also learned a couple of tricks of its own such as page segmenting. Eventually it could be distributed along with LyX as part of the standard installer.
Q: Why did you leave out my favorite feature <insert random LyX command here>?
A: In short, because nobody asked for it. Every feature which has been requested (either to me personally or to the list) has been tended to, unless it was too far out or I forgot about it. At this point of development every missing LyX feature will be considered a high priority item for the next version, if at all possible to implement.
Q: My document changed its appearance without my intervention. Was it black magic, elves or what?
A: It probably uses the online CSS file, which is regularly updated. See section 2.2↑ for details.
Q: Why use an online CSS, instead of placing the CSS file in the same directory as the converted file?
A: There were pros and cons. An online CSS resource allowed me to update it for everyone at the same time, but might make it more difficult for people without an internet connection; local CSS files are more flexible but can also be confusing to novice users. In the end the online solution was preferred, with the --css option as a fallback.
Q: My MathJax pages are not rendering correctly; equations are silently ignored.
A: Check that MathJax is installed on the same server as your pages; for security reasons the browser’s “same-origin” policy mandates that JavaScript can only be loaded from the same site as the original page. Also make sure that JavaScript is enabled on the browser.
Q: How can I disable hovering notes? Isn’t there a --nohover option?
A: It can be done using --footnotes margin. This will disable hovering text but keep footnotes in the margin.
Q: I found a bug, what should I do?
A: Just send it to the author at elyxer@gmail.com. You can also report it to the Savannah interface.

References

[1] WordReference.com: “definition of elixir”, accessed March 2009. http://www.wordreference.com/definition/elixir

[2] W3C: “XHTML™ 1.0 The Extensible HyperText Markup Language (Second Edition)”, revised 1 August 2002. http://www.w3.org/TR/xhtml1/

[3] W3C: “HTML 4.01 Specification”, 24 December 1999. http://www.w3.org/TR/REC-html40/

[4] W3C: “Markup Validation Service”, accessed March 2009. http://validator.w3.org/

elyxer-1.2.5/docs/math.html0000644000175000017500000011417412117174756015127 0ustar chennochenno eLyxer Math Showcase (non-Unicode edition)

figure elyxer.png eLyXer Math Showcase

Alex Fernández (elyxer@gmail.com)

1 Introduction

This document is intended as a showcase of the mathematical abilities of eLyXer; for more information be sure to visit the main page.

1.1 Versions

There are several versions of this page:
All of them are generated from the same .lyx source file; they should help you decide which rendering options suit you best.
Also available online is the eLyXer translation of the latest LyX’s detailed Math manual, which contains a lot more examples of LyX maths.

2 Typography

Math formulae use a lot of different symbols and fonts.

2.1 Greek Symbols

Greek symbols are very important in equations: φ, π, Ξ. eLyXer offers a complete set in both upper case: Γ…Ω and lower case: αω. Also the AMS italicized upper case: ΓΩ.

2.2 Math Symbols

eLyXer supports the whole set of math symbols in John D. Cook's list: ∃∂∇ ≥ . It can also render a few more:  ∝  × . You also get all symbols from Markus Kuhn's list: ⊙∐.

2.3 Other Symbols

There are other symbols like arrows:  ←  → , or geometrical shapes: , . eLyXer offers limited support for them. You might also want to use financial symbols in formulae: ¥€$.

2.4 Spacing

Equations look good when items are properly separated. The main separation is the Medium Mathematical Space: x = 3. Note: if you are viewing the non-Unicode version math.html of this page then you are in fact seeing midspaces, which are very similar but not exactly the same: (4)/(18) em for medium mathematical spaces versus (1)/(2) en, where 1 em = 2 en. Try out the Unicode version math-unicode.html — and viceversa. You can check out what version this page is in the page title.
The command \raisebox is useful to, surprisingly, raise a little box,
raisedoverloweredand back.
Like \mbox, it puts its content in a text box. It can also be used just for spacing:
BV.
There are other spacing commands: \hspace: a b, protected space: a b, and (at “block level”) \vspace: a b.
There should be 1 cm of vertical space above this paragraph.

2.5 Fonts

By default, letters denote variables and are taken from the \mathnormal font, which is italic, αx + αy = α(x + y), with the exception of upright capital Greek letters, G ≠ Γ.
Function names should be upright: sin(2π), log(x), tanδ.
Mathematical fonts used in equations include Roman (\mathrm), Sans Serif (\mathsf), Typewriter (\mathtt), Bold (\mathbf), SCRIPT (\mathscr), CALLIGRAPHIC (\mathcal), BLACKBOARD BOLD (\mathbb), and Fraktur (\mathfrak). For the latter, some single characters are translated to their Unicode equivalents: , 𝔽, 𝔉.
Regular text in a formula can be achieved via text font commands like \textrm: 5  to 10, via boxes like \mbox (prevents line breaks): 6  is more than 5, or the AMSmath \text macro (scales like math symbols) basesupersub. The content of an mbox is processed in LaTeX text mode. This allows text font commands, e.g. a switch to sans-serif-bold-italic, or the phonetic alphabet: sfbfit, tipa.
Units should be written upright, either with \mathrm or with macros from the units package, e.g. as simple unit, km, with magnitude, 57 km, with fractional unit, 200 kmh, or with a fraction before the units, 32 km, (7)/(16) s.

3 Numeration

Equations can be numbered, like (1↓)
(1) y = x
And also like (2↓).
(2) x = 3
Some equations can be numbered even if they don’t have a label.
(3) x = 2y
Notice that equation (2↑) comes after (1↑).

4 Simple Structures

Let’s now see a few of the simpler structures that eLyXer can output.

4.1 Fractions

A simple fraction:
(1)/(2).
Inlined: (2)/(3).
A big recursive fraction:
(1)/(1 + (1)/(1 + (1)/(1 + 2x)))
A nice fraction: 56. A non-diminishing fraction containing alignments:
(1)/(1 + (1)/(1 + x) × (1)/(1 + x)).
A similar concept is a binomial coefficient: (A + 1B). It can be prettily presented:
AB + 1.
A symbol can be stacked over another using \stackrel: xR → y. Anything can be stacked:
dx > 3limx,  headheels.

4.2 Limits

limx → ∞f(x) should appear as x → ∞ in italics, and «lim» in plain style. In display mode, a limit must appear below the main symbol:
limx → ∞f(x).
Limits are also used in sums and integrals:
i = 1x,  0f(x) dx
where the sum’s limits should appear below (i = 1) and above () the . The placement of the integral limits depends on the document class: LaTeX standard classes place them right to the . Limits are shown to the right in inline formulae: i = 1x and i = 1x.
The placing of limits can be configured with the \limits and \nolimits macros:
limx → ∞f(x),  i = 1x,  0f(x) dx

4.3 Roots

A square root: (3). A more complex root in a fraction:
(1)/(1 + (2)(1)/(1 + (2)) + ((1)/(2))).
eLyXer can also do higher-order roots: 3(x + y). A devilish case mixing everything we have seen so far:
(78((8)/(4)x) + i = 1x)/(s + 5(((78x + 45y) × (Ω))/(sin(x + 1)) + 38 km)).

5 Complex Structures

In this section we will explore arrays and related constructs.

5.1 Arrays

An inline array a b c d is always shown in the same line. In display mode, the array is shown on its own line:
12 2 3 4 × yx
Apart from that the appearance should be the same.

5.2 Brackets

Arrays are separated by variable-size brackets: a b c d a b c d a b c d a b c d ||| a b c d |||which might also differ on right and left a b c d or use the empty opening a b c d or closing: a b c d |||. There are also fixed-size big brackets, e.g. f.

5.3 Cases

Used to switch between several values.
y =  x i = 0,         x + 1  i < 3 
Cases may have more than two rows:
f(x) =  0  x < 0,         ∞  x = 0        0  x > 0 

5.4 Braces

Values can be underbraced or overbraced.
a − b = b + c + d + e.

6 Macros

Now it’s time for user-defined commands (sometimes called “macros”).
Definitions can be added as macros. Then they can be used in formulae: 1(2). They can accept default parameters. Again, useful in formulae: 4(5).
Other definitions from the preamble can be used: 3(4).
Definitions on the fly are also possible: 7(8), and used with different values: a(b).
elyxer-1.2.5/docs/converters.png0000644000175000017500000016106512074107030016170 0ustar chennochennoPNG  IHDR-F6|sRGB pHYs  tIME ,܆J IDATxwXSW7 ʒ=d8@-"ZD'.AQ@TsZAAT* ZJ+*Qd+1e>499ܛk8nߌ"@ $)Ti() B!BmxD!zt:FitSPrr@IB/`:iHt&5c20V69l`B!by؍Id+ޑ9+@h|vhp@_L xx!BKW (b\*L@lP$Ň$-w]z{b2j25MВE!W$UVP4Dq MJK#l6(t.Rs@,|S.(r|'5%ͭWo[O}SIQUUFvSz8C!$+{^~ؘ')қPv興e@ )lJh^Vh0e4q<`e/;PwrabIt@P]]o>Jz l6?!BIW^ڪ5k4Eߗd_#iDR/.2(.&A⫝̸Tڡ[E݀ZO`\H(1FMMYOQIɔH+*J}=|HMơB!$d髫9:*((H1#j"o*8t?s[dI.">>;m*Ax@0? (*3JTXT' %(KKAl˗'N(BmF VWW++ed Zmv ))#xfl\RnSt0X@]o&l`0]s!RSvVN^.OGG_ 5:ʏ\tDk&al6 l 0˜ؿҘR,iY\$| 4`Ё)li` ZW))ϞןSbujd@@ƅv_wmq*/@&yo^yWc FX‚͘m @؛,_ΐ]<~0rWĨ/jYзo^}7mN_3~\{#Y- C%& ^&<=nn⇟v}7uΓGӭA\3>E;PI>;Ξ<0NUUe3e8GÂwї~󡴞j5g9q]f16,v;}Aں΋WhiworLIqa/'WN!:ҷotLhP 1]I#㈈ KćqLQO>·W*I5>E:Ƥ]VNqQ2~fuq UǿҀ/D%];`7ONVw޻mXN;q*뗣/fb6X&U>~ӕ'"/>‚n*f9Q7níxÿ>wtu._:x9q]oء˒U ZsԹqw;{aUUeyiiC0R$IzV MJ`2Y,i< FC@H$y|>ɀO ,ćQbTP} \T&.+ @L< $1B%B.·~>QVZ zo ozsBX%f I/Jz!#+;zJ/_r—{JɰdX^=wK`|- Z;t ˭&JyL0S%+P?ݾ寧v-쵨2rnϒqB*7]@@2bH \> 4fH3S$> <6!.Sފ~&9Yl2@oOglWRUY.C>!yU9sv`bIg;z]Vzwޗ>v*eA~~O oݜOE6ו-O="={YG>O)Z;i`4> @@W"0Z~uUnzy©Qzt<,}Wbir6FD5#Dø0>guK5\l. g2AFFڍ QcH<!ԉQ[aw_p*qYoLcs+"<$ָN7e<&qҟ6x55STwk?VȣMT~]P3J%22SM~ޯw7]]KOO@ ZPM1՚ޡhM|G!#ʥߊGOKMh>~޾e:Т߀AO$Wߊuj]Oμu1WAK.]|j0b>_PPpG ɀʚÀ x~~PTen">\ƨvQQ^|>0 +J|n܊jCGY!Թhob¿ TًɞAf-&N_Z7&~WnG_ۼ6 8t&U&!UKΓ^Rs {6Q4VT&RdEkҙ4&0{q♫V }ɩc `>iio!лi*쾌!{FI TT@t:9eeo=J+疫iQ#"p \aV6AŃTsXf⿷LyW*h!#R:FQMGﲤXZOTKLiD?Hly9Jw*՚US2rb!I*WPRVQ3! V/&ٓ#++EtF "7555..ݻԈS>  r3_*Rh @4>j\Q^}#/MU#fTU ߦfW2m&͑0$测cD~ ׆(/{uTnv7== CZ_YY^TT]=ÇQSf\,)cCp0HLI.Rg6qW$RV8$sX & *+yx|kiCFXKcV$Wā r2z<S%M:A޹*1LUU Uӻ̇q#RRsRin}DKuIB$*_ fg=;6QZqa.VUcbffn#B!$ѳo>R/`J˪i?"}"J:ab*9G ƃZ8mWUU >`02,4B!ƚ2""jFSD٧R3?/  z]hh| PT}LB!hˆS>·AlIσgTUB!c*y @lu*h!B&6`\]xWB!jM!r]A\0B!PA#l&l6·!B>&&jB1> !B`|B!P0Bva!BB!Ƈ!BC!j'B!>0> !B]`|B!P0Bva!BB!Ƈ!BC!j'r,j |<!$D+ŇP }qϟǃBHb|Ix|3a!$h|&>^>B!j?xB!U V.·!B+f?ƇсGpy@h˒͘hIII$hcǎ+++:tHղ"o !BT3.S~ѢEwܩ=z3e``gB!>KLJ; (KKK+++{񪫫KKKɃByח,((pwwr労ٳlr;v۷͛={-֞:uʕ+K$I޽{Ϟ=YYY4r>>aaa111zzzu.\`_U̦E^xqҤI|G߾}{ҥ\.wݺu 6x jVjK֚{]F;yKz [n hjaÆm۶_¶mvǏ{zzzܹseee>>>ukĈΥ)((Pbii ֭kO `BuPm?<𫉳`hhH=544S.?\zpxƍ )))vvvL&sn]EEE]]nyJJʨQDKtrB}+gRQQׯ_SO߼y&r9rV|>_SS~99oN>Y{KHHHSBYk7o$yyy[[e˖%''sSN Xrenn&wﮥr#G7k?ϟsesssjP9B!fmֲ`7[[[ѧԕͰŋX,a WCBǎO<),d0={ׯKJJfΜ9f&/F6mZ~~rB}2>ew5Or& 111u<ٳg%M`X۷o߾}{tB!ɇK"B 6YB!ćk@}C!׮Qp> !B_si!2> B!$:e|·!BHćkl 8:k6 >lxiA$+>~Yt[<1_MH\LY@jjZ?S 1DwV!al0F$TkhhBQ$I۳X,Zy/͆zƟ|M[88P3$yqf;yƱ㧨qy?S7o;#!Mi軛3>ê:ݨzߝBCuf7:f3gو*}aO622b2:::zw^F4005.I.\0tP& fffp&ǎSEEeƍurrQrrr+++{!Z(%%ߝŒ7~Pzo{8~Po51^=jƟwn@zFfSq_9e/:9xKlmƟ<)M}wz<///kmTTw'Pf?ao!Ց01322݋ 88G}M&~~~۶m;wn\\\ɓ'PVVFUhJM Ǝv! <|RRٳE }N]o-t|%ZQ^]O)--VRաCkj㧼֯6_UUeE N:qwu8aZMxb:Ww'^s|>_VVf;.s8rxB"65>lW1?Iuu5x>77k׮wސKKKpppHOO"~G;;;nذ\]]w]BSCFFFGG_ݹsٳرc$Ih41TUY,ֿ)&=7\VT-\G[ @XMKSz@ѩ,Ԅqc]a9bԕ+< gۥ?6]kA޼yd2UUUwXﮑ?lKuq~;tut8͝d;OHF4>Ym τ ;wn=zXzy %%eԨQիW& j\sgO>uvv{{:#CTEEeŊbFkX]~Y?+C=6ddd@FV- EnĥLaI+inn^YyQN u䙡V1֫w'BUEWFk~s7kV2dLJ (Ϟ=2997om޼1;;ccc M4-\0,,,...""Dʂ.+T/yd?x*?67k4ng0_ii/v j4*Dk>vmH2vΧ$u7v /\#&2RSޤ}FW/~t(Fp+su[%WUVIIIɰlD}u$;>lٲe...AAAO>}޽{W^ |>ҤIgΜ),,$b=<}BdƇ*Zy8PкϟǃB_ !o!P%B!ډH0C!jC"a_!B/B!:;C!j'dyyʕ+ KAAA;m$Y,V  E!$?lũ'O޽۷oM^G;55522R>w$''.vCxB = v٘AΉ'455pWUUy8CELKh7Q4>Y2ᶙ022p8A'x7%%%VVVAAAz>3gάYm$I޽{Ϟ=YYY4rvyܹscff ݯ\"--={@6MF~j=}wJJƍ]]1fp!$y5B- ova 6l̘1&M211ϫmذaO]II wB 5q ~kO7XC?EM81###66 _u۶m{qrrΈ㏳g{۷RKKab`Æ JJJ%%%b/]ddd4p[8qB~|>p8]vœ!P-/yxڑh0:.my?OсNxx8F333[zuttիW222zMUSQQYbFR())))FS"_t:]CCCꩡavvU;wȑ#fffW^e2x6#B$xϞ=P!V<OMMMxbAA˭;QVV%kddd$$$)xQ***k7oԄ溺LNN͛EEE7ovttáAђDKߟVK.Q k؈vXVg1Ŀz|fKRSS9Ξ={VNKKr'~!x"$SVV1cƌ3Μ9ŋ''QFijj:::]ÇiiiVew-v999/_677?r䈘f]lYrrr\\?0wF[ϟ4iҙ3g `Xx26WWĨ(H1rHBfff\\~qqq;&Ii񻨫O>[n]fMzz:EYXXxzz֭vZ PRR-~˗!I 7mڴbŊw)**ڵ lBĉ,--O>] ___6mڴ|]]]www* [x)rppSY[[HCCR^^>((hՙzzzx26eeeeeeS##ZO>MI/>ʕ+]kŊϟwssrJhhh|||BBB݋_~hc `hh=~x<-j~혣%?Ň5;233Aaa#G,k݅7oi$)kbm߾=''秦nܸ j\Qݿk={_~ILL,X_~=sL<;3f:uJGFFNgϞZxcnjLƍ҄$ɟYOOOJJW^{{Ϛ5k6?~-5>./:uJKKKFF޾){(z]F]paСL&S__?22*Ν2d433ÇPXXnݺ#G 6Vs999}􁚨/UUaPfC3zk.734yT%$I>JJ}~+[.0> /4ߊ9޼y$B|oՑcƌVSS{yxxx b%Iрzs$d%%%ooo0a󝜜D/2RzIrwwOHHsqq\xmC|}}Ml2www__cǎEFFIKKS XjUVVV`޼ycƌ9t?-CJ\\eV :yyߘ Ld2e2^$&M8jh[*â qr !jF@II%Æ }Makkkggׂ}_~,[,۷o57ohBVVV-Κ5WX׻;&W^t-5eܫW)9=z0W>9>?* 0> EJJs!C Ƌ/z[yjͮ!jy’SF=}7/_ST\L=h\2H~|XJJ̙3 ֭[|& BFڵJ9&++;bĈʾ}6l ##!1?Od^~(-f9"/'?^_U*##oy􌲲i<16\Bć1k$g>,==}Сcƌ9{aÆ>ԺRHս}vklfxo/ymWɯR45554_%>Jt/vqViUQ#G\x g-L6MHl|؆ FyqwSSS z{{rR:uIf l(6j^EyYUէrF /үOQF)*2L[AE8hz%$/Ij*CӧOn 䔔.]Jy UhjħO9xcB9ٙoSS^*|$ɼ_>yWߗR;P .kbb"Zb_~Ν !m۶s988x{{gddcoBaxG'.M6FE֛޿ҥ$jݕ[zzz 4n?H%<v+B·5ջHԩI֖~UUUC ޽;R円٢[SW^55s޽ãGWi !j{3>L. MIUȺ$9>LZZzʔ)۷o… O>566o~5U555+yݼyh͎ssiVZ}.]j^/_쐐aIjj*ٳgOiii666MZHgXMyShѿyWW/{X,֨Q$''7~'OPM|m}:|5ު? $<ߝ;wO~gϞ.YDSSS^^vٲeqqq?ܹsE6Z'Mt̙B X,,J&&&&&&FEE@b#G6ԤO>[n]f @ Xhgk׮]bECC 1RSS###񒓓[k˗/i_|y-))){{{a—444Z EWxH·a|X& ݻn:;;r}}֭^ [x)rppռ p-((hՙzzzV2FLYYYYYYȨ)VXqy77+W'$$]*׏=:qD v Z*((DGG?Ki`` z۷.]rX;v,]tƌs̩7jredWW׳g߿?88<>>~ɒ%T'O14.jUnh̙r''gϞ0dȐ[$)J_rǢEEEE7nٳn5 ^xqҤI|Hj0<|&> `ٶ6Cq8=zPïF[ݻ7$$Ӄ_xd2SRRߢ?ޣGђ}QY]4[l2e/rԮGCoXXg-/cǎmzpRZu> X;a̛7oDG%%%^^^PZZhr{xx\|ȑ#$I.YDII&L0|''Z{IrwwOHHsqq/<P j5WH*2!"1!;;'@ `0'?x`ٍ0 ;}AƇ &pٸjF۵kW@@ʎ1}6lв|J!E^$?>,**$p+++)) 39!1YYYɑ${펶{666 CRa}0ɞ-h M5&?CEBR·IY[l+++EK>}ȈdPQ:uJKKKFF޾VWǎZlܸ*\z3$I~7!!!uBa|XI',)**rpp twwf֞{nzzp_ رc:㓑f͊6y٫Wf͚B6ah|&>^>>U]]y<ñڵ+Ҿ}?p?^4&r~ZTT=ztʔ)x!jc89ćkl ?OjIjjjΝ;r䈦իWL&Rݵ焭u嬬w),hf:}4?~ C!p>s`lda5&]YY͛76o蘝MTw9a+1Q&رc\ߟVK.5˗l6[4j055ٳn崴4FpY\]]cccl(YLPP|&/ :N,I'Mt̙B X,,RݵD6ҥKSkH"&&&&&&RWk9&}ٺu5kE,,,<==V^v+Zh~/_˦JLL|eTTr̙3+**._,YYYy1 !Z :N,}0aBfff5僂V^!oQkYZZ:[[KWWZWZK45|<$p8bZXbnnn$ILJ]O׏==l4?Btt<,T*SLxxٳUufccs a7n!#BKΡ3Ƈ5)^~}KFFF9 ׯ_Ϝ9S-//FFFvM'l>|(,,\lٕ+W\pg55AO0QoFOYOOOJJW^{N9~]5kikkm~q[[[j|D*%i4څ d2###ɓ'׺^gx.(L.]ҙ3glmmCk~m֚n_ⱲEjjZIMMgj!$ɕt$|N_[|Xky`$i(Mx>z۷o7mMCرcӦM'N3gNoܸaaa!Z҂D*ٹPC qF&l;]B4Y̤Iϝ;ϟo#>SG{)ÇqO[ܛ|EΎ?/_8-LJLמw^.]8$ICiJۻw},--֯_+ &RUUUoϟCTjٰakIIpP[*5zS={fhhxN> IDATϟ7=sL['M'B#ć 0}K 4mqoJJ+/jhjjH$a-+''4%⥤5Jx󠗗pڵk~zAAO?ToZqf-HR@4 wQCX2x$FCd1ͻ~z~~3gMkZ#J:|En~q֣EWR? 9tXmUU B;a3=!`Ǯ=xQHjpsGѺu97HL1ccc PXXnݺ#G߻wns99Z)ZHYRpk|}}œd1ڿ%j=a>Ĥ_5G],+/QE+Ç'~;t`B௿uFu_(=x0a;1\_gLoݙ>'C*׉pDRo1ϟsess#G$d%%%ooo0a󝜜D/2RzIjY"Fs8uuuժ###njcmmZWNE`Cbty6mDnjB#̇iqcG_ 11L UVVv'殷Z}}{_ #ϭq֣5FzMkMY){p)ûv҉>&C6*׉MS"iӴ-[{رȰ0P`` AV*..NeTgiiY7qF-QQQ;wtqqy?(:W,ѱxƌRRRx!J:HcDG$I?ǍEɢ]_yF{ CL4mxko צL\h|&> ^cW9ׯ_ٻlYWEӠX۷o߾Xj޼y% ͚5WX׻;&W^M"ftegg(wu}\·Po<{kKJ YYJo= j))oobމ' ɡs0:!C0/^V޿ٳg7Z\:|F7vOQRR} #--eb=A6`3;'N̽=o¨wOu5UmM`0:]n5aJ@ snt=:k.*X4j߾}6l<'q֩i.JRn񖓓6q@e`ӜYwMrhF-'˟MDØ#<6jD֍i zŎFWC#IʼnTecc3`<Iv{>`h9(** N_7qߝj+| ԷqCN1u|XFƨꚸzkt=:&33N?Bt++N97sF\>*!駟(-^~P0]e$]vu]JJĉx!P5 3dee&w9DØ0`BEGI*w($lnndIO<166.++!ʞݻk׮P33gϞս!!Dw>J|/^k-3W; U|Et^ jnVXmӳgZniicZe\]]w ;w.3F!I|c5qPy?vF h4h j%SJd޽RCURSSyBu:_I|X^aO[[t5'RK /_ WA_O߿޼*.]j˗/lvHH$55ٳn崴4 Np[\]]ccc[ AhެhMtD[S-//_rPWWwqq)((էg^|_zFj0zS[&,[n]f v@ Xhgk׮]b=4e˗/o\LѥcbbZZǭn/^Ó'O})))ӦMѣ_zG=׮]-QF}!jˏI? Ѧà{ƭ[3//o۶mѥmddєUH\paAAСC}}}@)+++++ 61ʊ+Ο?vʕ;~ѣG'N=l4cBttpY[[>}zРAӋ/>ʕ+JhgϞ*8qBSS3++KKKKXgĈ4޽{Ԥ׵k-Zt)d2={VQQ㰶8aA!𐶆6 j i`06o޼yfaɜ9s@d<(ޥK&O,;w>Hرc>>>)))K,ٲeKSNݻwٳ'++K__ӓF1p;vjkkm~q[[[j|dll|ɕ+W8p@tLR WΟ?C;wN>&O/ɓ'3V:3f._@dd}saǭGDDQin444~())QǏ?x`ذaݺuJ ݯ\"--={@6M3gάYm͚5yyy&&&@mǁ3DNH$>YֺKu=>~ٻt5DImM6ED(FQ)R(ݕJV7V*!k}vbZեtCQiYg6fyf93Ϝs/,..%Jzxxܺu޽{/vuu\+>>رc'O3f̝;w<<<ڰ:::QQQ˗/~v.Y\b]]]ϟ?rGlA͜93,,%[l\n"-ȈdSy֭[ǎ[n]o6{1ٳg/\}?~-vAƍ&M077z*6333޽o߾R{S!;k,aw<|X9""_YXX,ZNP(t:=<<\UUܼ}Z566ppp7[mIITYYYGG/cKbcc)S9r$33="(**z +ѩ㹒ltVXXaÆb=~A / ;;4F5kV9?apn]`AMMMnn՝;w&Ms߽{wڵ#,--^oB_|r\\ޔ)SˆWHV\ֶj}:{l@ׇI V{ Ї؟|ltttmm-ͮ /@ N&&&ӧOVYYܹswUSStڵ7n444܌]&}ƆG=!wsGxɌ3RSSKKKn``] 4SVV~W/_<==`W{qf_~B"&Om۶ׯ_z5<<_366p8w޽y&6t_UUU-GbUtuu_xq) 쎀@͇C\&a}X;b@L˗k׮MNN驩BRRR|PSSSTTjlltvv133KJJ.//?=z=5=y {;  Fhhhrr2J511z̙׮][xq/ZoeX΅x bqlddtСYfasWƍ TUUFؠɓ'Xr|+ 쎀̇ B?LuH^z؈]jii6gnnnmm+WO~ biiDR1ƍb[܊t 6qB3j * &ann>o<└.W?v mڴiā#x nVIIi˗/?w\IIIvv6J;w:w/^433J,--/^M|bY7n|N߹s'ϕy8Ab|YQF،?^[[Դx([tƍBCCO:"iooߺuk&&&ĨW!GGGsssccc---b^CӍgtAѢ]\\*++x>+V(}to6bkk_/YDIIٳ<[]a!bĊaÆϝ;7$$///{paq}&U y&B,׍%K8 A}T<D@Q>Wsss!1'0o_XXW_}kdX ήnذap24`>L, p~I~w`0*yyy'ND=IǝSOEEŋ'NPWWZ[[oݺfb.^9#H<A<|L&'$$% WUUYYY WpLѮofo~0z U\p'eddd=%.//f0X&*&L ۾}6^n;vS}||lrʼkG;KԉE0zXBfMMM===555mѣGvI 0B \~}VVVRR҃ >y$??̙3c!`]]Ç_~( OeeeOWMUva>L߯7__7o466nܸ1++L&S(ˆ ɓ'+VS3HJF---=~CadJJ}8gO%Ŵ4 !C566 CuItҥYfIII3&##+|eϳX-߶m_c#S̯z t՞0-0 )|%;vɓtNTTT@@ VZų͛7eBB•+W~jWW^0222..˗/vqq gΜynSP䈈]]ݨyhͅ?~WĂƘ1_ΘӧM{[!XI!:tPllo||H QYYܹs(wڅQ]v-11ƍ AAA<777B K쁾>ƆG=!w 88LdƌÇ700HNNfWH${{ӧOK Xhjnnhllhloh,Ql\? OϦprޠY\b'K9t7v&%4/.ۿ]83uu/ yӒ~{Zdmya+%k?\x7/? |"%%\<]MMMQQB,)))"""''|=z=V}5=ySd[[v/'2d*jbb".Mh46maa +biyvԂW,_tt.m'}3jB֭MgzJJ#6wdiiz ![v}^nW#LMfٜ?#.ӮΚ9C]MU&0А㏿_>R^^N|3HXNNN:::wqqR!KKK'''*ZPP0tPbqUWWO2/qss;|pGGM|qB ތd^t)..ݽ8vjjjzxxY p녳c|t=pvK~AT8x7g!$H.1MͯBZZS-M͆|kn2x7HDu0u )dCCCI$ҥK뵵vuԩ?SVV,&&fĉ[noĄN/Y/qtt477oiiJLL$n̯|^:nllWF޴itv pi244 +~W D:~YzEDaB쏑|={**[gGk#j=SR'8袅 <-]]|CJ\Kr<|'dddW[[YQQg)))GGiӦ >ٳg#{{,b_|֖1rH؄;/իW bmmZJ DL:K +q$-%XGUsW:aP(&Cã2J<9344P640$b5o4PäEng|o̙%%%/~ݻGvDK0ޞGτ0biVWj*+/YD,]FZZzw7`$Bk#˖~7b>D"1 Pfwtt`x#BDDڿdd̙{!C>''Ȉx$`0).KPZZzƭxĈcxڸðLp}أG}X011p8w鋷4iR_SSz%%b "3_m=ɓtcH$ȑ#a]SΠ ii)S%Po!,B&}X/(+9 IDATDWFS~)>>~$ WUUYYY Wp~}X__驡!))G '//wݿ_.6_!N֯_u!CL6p׮]K< IQQ_!w.<xb/^*//f0 L0!,,lVVVl6{ݺuFFF^^^رcn3#rʼOu3c]]̙3>SYY5}w*++Ottt8N]]]JJInn7|#' +.. 1I&ݻwK<kGSSSOOOMM sMIIIII m'oogee%%%=x𠨨'OϜ91=62ï_w}}sNmm7n` ,X`aa{Outt}off&))k.le'3}?l`ևu QRR200000iժU,߾}Ez Y |N:RVV6bww`aNϞ=3fDLII100 JJJ9vikkkl|%~8{-[C@~=$ HyyyZZZ˖-Cؤv;{AEEb&yYFL$--`kkWVV][eF##644eeeʮ\2&&L&X={ϯ^211?~|]XlllDDDssG}oߺ>Lv󁘈)''gС aCPtzxxB۷N!TRR"%%UVVcKbcc)S9r$33=EGGЪlVXXaÆb!w 6)|3_|r\\ޔ)S°˻?޽{ƌsA*s׮]X`g???UUU, >As0d  *((pvv/% ʵkoܸAR¸777c p[ڡC<ø((( \Daʌ3f̘QWWc``?;;;kii盙˓z g 6x!TSS7w#]Ff!ޗX܋9g_'ȅxڵktzjjSilltvv133KJJ.//%GX4QF<궶6xJ0];T*Ą+L&^d2W^/A>>Ç-,,dee31B\EE!RQQ644xzzb!fy,mw#W^566bⶴt{I [[[{ʕӧ8qḻ+**#,--T*"#fܸq77":bcccL=!B ތdfddϛ7OEE8%%˕SPDDDUUܹs333~o8])o9;;/{E)((X[[oܸѣGt:}Νؽk֬ٱcG^^^UU֭[sssdaBo޼;ыn[] S0uͨQmll---MMMyS9uTFFƟ)++m3qĭ[9:dܼ*111 ytqh4ZttM숷Cvr@77Z55%K?<Q.GL&gggÒ7l`hh(## noo_`Akkqzz:DRWW ޼ywܹtRϖևnR'h"B {f\Ѹ|Z%ݝ͌T<D@Q>Wssst:o0Oa޼ye^<1L/!;&,.߱n|ԷbA{{;ŋZ@̜9SRR/~ݻDpA.`}Xonٲ˻"81qI @"ߏ3gN_Kllݻ ?>~]&`3Y+aÆg~K.=1qI`bb"//pܹoaee5iҤ~D}A@,s0糳N:s挺g444zNIe2P%I$GgZ7sСϟO2eͫWp8Rl_;9bRSSjjj[NFG|m@LOO/++SSS۳gO8')v`). ,GM;ۡC᪪@??޵/ipǎ;wȑ#[XX(:1tަ&777e /I"Y":)5JӺ,\P]]244w hGp2 jjjrssܹ3i$<Ԑ02NEP _$tLqu8q"1w/i0_p႓ɓ'Om۶7n̟?{ԨQV@ϫrsر۶mstt`` T~ɏ$8wL55ON-ǯ}H3ϐrvv&^Ė|X,a mmmuVSSS``5kǀ0)̖&(MKƌںk} =NBט pxbE.ĕ+Ԁ"u֬/^\~KZgABSRRZ|ϝ;WRRMRΝ.:q ˹s…Νklllooy~[QQ ! ?ؼ>}#G?lm}!=?|N%)SGbj/A_w!*>>߮]8ڵkf͚JRBRk_;H4s)))ϟ?1bTooodz(3~*((m۶ӧGNMM+ȏ?޵KJZ`Llv&il| ͥ]C߼Y|{cO-]`X8^ rs}Xgxq#/_.^8f??pWK###o߾} ,rrrQQQQQQ/NP cs~==|mmB${￿XXo}}&MR3fKX>mzCS_[ɰlsahևs|*ZRRb W^=gK TƍS:{۷_ 2*;sۦYOlھ}gc#qQSiiIa:AD\&Xm,r;os"#??6ss/_jhh899s]Ҏ|^a\z\ZZיm'bc*HvttrWWU`jk[ӏ̘9ɓMii%y/k&?~rq-9w{nm=.7xa~e555RRR؎|^p8gϖ,_>ARRbSR NwÆ)#G`6^r5k.~ِV}V_}}R%˗O H˖M8w!AQ? $ٳ%99kIHn( 䒓ۗsNh\ySӥ.ϼIS:q?Hj /b@4 >nH,(}M\ujj!ĞD"[75d#^-;~'&UZZf4=*˷#`&?>KaF= l9{r-72~`nVR3W~[[Y=wdvݧHK+ٴi`f~eE|*`zn̙ѩ>}ݻwz葾~X~`PήVVjll'xύܹS[[ƍ! XXX޽;)) !B*~Dfjd={Fa0t@@m\\\YYq{:ydBimm Ϟ=e˖&kkD%%%|cu 90 jocvE$D"& &!!g|͔)S9hKr8R }X7F%''ߥ+++))EEEE=<Kf̘ZZZ:|p~F޽{XaÆ?/;;6[l)((زe  jz4ea` /5Af-,,Fggg33 #44499JC7ۙ3g7ݴiUaևEyyy)Vhhhfl=qwwWTTGYZZ:99QTLfFFyTTTSRRƎ hllD)++z{{1={,^6.--dݻNḊa}=bmmOb={:uTFFFrr,VsMFEGGTVV ڧ ڹs'QԩSC 1cԩS544~.$$$0pǏGFFr ? a@4 02uԉ'bO >\@y|tO2 H74N|y%qwwwww`7oḊX@X,Vkkkbb"qi|ɸAȯ#>ķ2ύM} .}:t(Bt `>L<ևIÐz%`LFt)TTT+255WRRQt z:CA&vԏxFץpԨQ"Ţ[$iȑ AXa%?sѣGKKK?СC;t)===)))ee={^ti֬YRRRcƌ@uvvihhHKKO2;Zl+-p8FFFgΜևZ#a/_e||cNJJ݂ÇG}D(>$ xIEEB9x(wd ϗaA,և 377ʕ+ӧO?qDZp8^jllܵkBEJoݺ5##XqssۺukVV֋/_ba„ aaa۷oFuyyyf7X,g1l62 CC}F?44D"-]^[[ͭGcQFHKK[ZZ677zIݻzux׮]gڵ f RpZ oogee%%%=x𠨨pQ=<{l'''8=M0&?~ e555\DOOO<}41koܸijxɌ3RSSKKKn``ǏTWW寭%mٲ`˖-ab?LX$]hl6+llltvv133KJJᮋR!2d*jbb֓'O޼y3m4555SSSl >88vӦM¬  aRև!HAp\yrS,Ǽǚ5k9KfaiiDR ʯq&yҥRwwb~ѼDJJJ`[Ώ?ŷp8...vvvQQQ3fػwo@@ _RIϞ=WD:u*###99YVV+iooߺui4ZttKee} ;wvQ &!!`?~<222??D C?$χ1UQQ:u*{ѱzÇ?{Aŋ(-ޫfcwwwwww챁10@&6`jmmMLL$.iiiQ`ЃAXa= ?vbZ&=w6p$2c999CP(;n/)&>L?֭KϾz>sfXa>>7+1ejjZ__4aDaAL&Y0¾srwT۸i E=D9r䀏~DabA, 9&--lل?ˍ32&%2lȑrέxvWSO\5~ 27w_Qy2}G,uAAfد-[*+LG6mp-//k|Pk.iUB˗O(-dkjN`>L, aZZÆ *,#vtt6B%'ێA2%"uΜ/jclڨQ/=j:ypR}iiIرӧk;Vrwv$GG 2wǎYX#;wuɓB^\*CNZ֏[^KHX8WB0 ð1&x7@^pǕ:ݷW 5,,ȑÇB4c ҼycBׯ?zڴiWW?{ԩݧafKqu.o-LiiIIIDkkǹs 7o @H0&:~Y; Fݽo,%?XcǍ'O'O(f q߳JVxGG;n`cǎOcʣG|H&𒊊 rAQ$___8%S0 <~Ν"#c7G,y4ÇƏW2E=<|E[ͭinnKL\RdvbǏOVfiRR/˫&() !:::߽ʢe„ aaa۷oFuyyyf7X,) ѣG6opS>L< aͳg۷oŋ+e**s^uvLL\XPyT n>7kvQPJJAJJ`۶m!c``qF777IIɔ$MMMM=x𠢢FJJaeeUYYYZZg ɓ'2dSDDDDLW^upp(**RWWϟ?~^^޸q$@0%螽=FrZ>~{IGG'*** `VG4P੺c%%%gΜIKK U\\\޽{GR80D / Ǜ6m FC{l'''8=M>LΝ;bGrիWǍ÷IHH`0222Ǐχs@Oqe$EHEEeԩ'NĞ::::::7>|gϺ-^xץqS33<qwwwww`7oḊB0X?WXDk`>L,ׇ a$^B}^'p8vvv2221lv{; 999CP(;ṅ0th4.>>>=}ߊ=p} SSz%% "/0F3QFEDD}GsC"F s}$8p`Ǐ?tPɓ'#@ vvv򊊊5D H$O?)//,''GԩSzzzRRR{v6ZZZG abaC]|ߖǎ;ydeee@@dd$q#Z[[t:ƍ>~Bݻw۷o߻wرcAAA/^,**8Sl<8~*+++ sB<X `~~i̘1]U ĂX#NNNW\>}'m`mmqG;wzzq׮][ٹps566;&L}j^n4`<|vvvwWرc'۹2 ABzK}}}7oiø8(^z)NinnΆ `>L,e>J".]Z__憍INNްaCHHHwԨQ666͚zzzjjj߿WPP۶mӧOG\~}VVVRR҃xΆ?~\]]~^ɓ'5OIIIII >GTWWwׯ_>U/͛7/==}ԩثiVV8Qa}ćad$5H.Lr8{6222쬨سgZ!eeϿ{իW&MO=}Mccƍd2Ba0߿Ƕ﫪:;;ML}ڵ7n444k`aC 1 <Yo׮]555+V]ֆu5.ìd*jbb O3gvttdgg_v @|xatQ^^^JjjjzxxYḻ+**#,--TjKKKߚ_Yf1bÆ =l\Z-:~#[:o…;n8,TͭN9 ޥ ۰L&3##|޼y***)))]~$Ҥ۴iPX0&`}]Y[[wkA.M:99aN?eee'nݺ׉Optt uqq֜9sH$%bȑ_:w &&&t:}ɒ%xyKKUbb/ Ys<,xtccn$hM6qY?+V:tg8Ḋ0OכTH_ AݛK8pF\_q GPGO?tosss{KKKEa޼y΂7c2}7@3+C?a@ֻ_%WQ!6%g,=11mP~3gJJJtY.:^~}ݣGv% yq+C/)CR>133322")9HGFF?~\NNnΜ9ݻw2FzD@ SSz%%OZ[s8mm;wZ&M"`tD"9rɓ'C_0~+C#?a 80 jocvjF`=A5AH$<]`>$ xIEEB9x w8s{ K8;߇#vw3n8))C.X޽{p?C1/ @L0!,,lXfF6n:###nh4x۷>2`… gΜY̙3>>>YYYZZZ&&&pR?C1 : $흙~ob?gjJiS )E$%D\"[B!ܯk$.Kv7ʒBW*eia40s>ϙs^sιЇ>yD---744|Q'(ŗPӦMݻA߿/zvx=***֬Ysq|QA> ϟ?rHP(l׮s9RNNn߾}7o\f… ?[r"bXǏ777g:UB_~i޼ŶmۄBçLSGurJ+}޽իH hkkӇxԨQ'O2{>?/;_("={v۶mNZ鴟P(ܽ{w@@ذaMF0􌌌,**"Ǐ|ӓ|ӦM+W0`1c!333=====ٳgӧOoժ ׭[?Qpp޽{<+W._|ƍƍ?.NBBݻw'M$^ı|%"ziyy[JJJ_5d) r[hiӦl)CJY(6믿^r⣤[TMFG,H֥K==QFp®].]vZ5ʼnTXXX^'$$+""68jԨpWW׃nܸR j۶իW\ѧOnPΐ'dgggggyٳgĉ_3?>eʔ͛73%FFFݺubII2iߐ{B]#c%+cR"*ίB‚Bph V6v諸3xQB|{mK6ݕ|wKB3x7dϗ G~ CȇȆx>ambC> - IDAT;B> @& d0@> @& à(ܧ1wjirBp¥QWoܿN +*(`ECu=e[Ч;a;6}it9grIn%40#݋ޤw1\OO_oZ|Vy9 P~v7χ+O<Zm/]6ڽw߬nѲG~C΀>?/YPH_];qКUwwDt(歔:'I.]ݾW- ݛ44f`CH PCb0|8\ 4\)goE)^~sEffm,̚~E`S'hkiׇMBD%R+NѤ3 ee#fhkkQI)u55I^XPҿzaШijhhkiIԄyKD͚}736 LDlk)tu&l6ysSS]? @6ND))͛QJjW)t9WDoB H?QͿz aբ!`gq[-uNPXPPe[0 B棼|En^+Ղ|@5]I&G4ŷkN3՝:555fY6d^n&M++/533u +.uaf*deLDq |>_4 wە.nˣ'9o~|I%1rm<E`ux$4fص`!? @6d0@> @6à1 C#@$9-"|+FF}°E6 03顾Cy)736vl)h+P6ilua2|la<4X 3."*ILLTQQٺu+b(00%ə3g*(^a77L,M6k׮]parr2 ɓ'Ϛ5 )S"##(#'''f7o|ɓ'l6-譥eѹsgӧϝ;|g̟??999""BagΜ9}t99}o~͚56m 566FsISȑ#׬Y\$Ǐ{xxss0􌌌,**"Ǐ|ӓ|ӦM+W0`1cVP|xʪ#ۗ3&\2tPכC@> @.]1!:TCCCill,IHH(++C[A|^ibbDٽ{wqsb0(E7 #QQQqQх vuҥ,Ե}utttTܑ#GFDDB$V ͡6pD06y%|˒bKŅ)|ĉ/^x-2ѭ[ׯ_pkP<_zJ-+0[[[cccs8" 3f\|9N0+&&FUU@/MN>K.<_@[F̥ɀ &0:~;w͛7mv޼ywF30Fm۶'qsh\|I:wܶm[qƍ'>zjj*aiiY?5@%~0$vO|=? 3nݺ~|c}rttbn   F;@7s4@|IzOC9}4vOc>F;@}c|4f;q/l|4f8 Cȇa2|l  ȇa SPH:vُ@W ђ}_hB!@ 60""n+|gȇa!ca\.aX_T^U}\"|>eINy3uwti߱{awPXZV&s|||U|:¾~W}|9DԻw;v|ߪ@&ċ񈏎4icr쭛77i¸}mg#urX_ŋJJɸjjj.^EE[ǎhR &p~=|c>K\b஝;m\K玖-zHJ7Jb|8\.z_5aK'.}{~7CD9s,leͺKֶQWo0Ŧc]EDsrzQ=cw&"Px~m:9 yp8sk[K {cu֛:Qbb}uT(/͛7ضm=ϟ?rHѐڵ 9۷o޽{/_R:~y.se*<tR===EEž}xhҤ蒥xmIeee"z9cǎr)kKx]SU;wȇAQZZjaRP^^TAA/8?l  wo˗.u޹wh+QL%9͓φ&c8y&ps'gL޾s}Jv7k=@Dbʫ3 ihΒݻ_^r7n(322?~KOOOWW1cx{{{yy/Z^׭[?|:!!!gϞyfrr)S藮[o߿=zԩS!B0'Oٳ_~yM;6ׯ߱c֭[+V^D!?~ԩx]]ѣG:'NyK]bŊOlK3O>Dm۶ RfͪHiz 0hԄ%~ZXXxK3ksEN2ѲZSC ȱ@ ;<߽><; $cǙJO8@_Ҥ9$,m۶oޣG##cOuEOO/22<8tP "ڸqWڷo?a„VlٲѣG|:۷oԩݻO:UPPPDķDvZkkk55 &I\K3g-[tSjUN:44t&&&Cъo gϞuۛmݺ˫ҍdΜ9dii٩Sk9rӒؼy3mٲԩS˥T/Dz;oȇAcExayy1D%f͌fYY ly گυ BsÇ2))}m[gc>2558c5E޽{>ZtiJJSQQQq)WVV;wnLLܹsEU)UYXXT5[f^XYY &*#oy]դk|⯥2oڊl߾[CbEGGϯ!Aff&hтyۢEONKr8˗/g̘1gRf J@|4f N{~M\%5E:--۷o ?JIIy̵H@"^zСg.//lUR7L>tuuH[MIx~<66Vb !|}}KJ!:::D2o_z'~-2l0浜Wjjr)kfU}e%^C> ;3?o;_L8::***=oJJJ~ekʒֶZSUk݇1I":mc=zۣNY(yyL`&L{gv;>>>Ǐg\(z{{{xx[U1<>cOے>,..f^zwRʥ&U}i%ozϗݛ=waI pℱ'g>]z5Gw4鵱YAnv:EI"=svb͙8''@_oaS4S_nTs"ݲ-:5|LӧW=0׶D9#G(((߿[nҥgb,Y]KKy;nܸ>} 8p׮]UM[PcKKKZ,^l֬Y޽СCU?Ml3l0`@aaa="""X,V_Mfkk0v5kH_zKoذaĉD4gΜ}I)TUJX>W 1׸ΠJS(]/* E45 wر{}9jNji5b_dUXe&U}KJx'iiqȇ41>p׮]# iX}P t-UUUؑ+++;OON27@=|@UӘ; lI333j&&&;6*hIzL,x0"<!bDnp\s0(F*F@ckaqģ0y%|.a Ә;a h0 gd0@> @F d0)($ P;w7ȇ+xvȇ4`xVt2"a2|l  #ȇaYZXgBayyBͦ% -\uF̤O8fff8!@;6UgȤɃyGΩo/]x0"262>'Ddhh6ɇ?øeyC~YD46[O^Dԥ[ofk[K {Μ0ӦcN;B?"G vqug]]BMLLx9%&øAc2x?"`?е <oɲU4"wh{͚6Nne^:Ґн&DTՈ?px҅ϟ>e]Q44f`w\.0h 15mi'0uVC8){"Ҳ#L5r 􈨤W+++KБE rt "3-ZE]M{V@}|ijhhkiI:Lz:`Ê[b$kjj¼PTPrي6ռͪ155e sۖ-ͱ? *99!8;9۰P0ly|e@-s9FUbV-IX# ÐFMjjbb?" +sqϦ|>?4lh|‚ܼ-ۂٖ8rߙYo],25hJ%OcGx5V0۱Ys33Snݨ4l9 8&Lvx( `~ﴥQrsl BD C> n9jkV-߹ʼ>}XUzOxz|Z(GzSS'1ofdh(p0:A}d¿***⟿ؾ3m`4 @"v0<_6eRii䩾9:CB$@KHE ^0o6@C|d`@dCaȇ4(Oc>F;Yȇ4L;w8&  d0@> @F d0@> @Fm)h  0hlːd0@> @6d0@> @6àKNyu[w G =ɋfy 5§1w|scff߹etaИguUUGn\XX4oɢRlldTPMo4lȇAm{pΝ6_bȲUӧNRVg獍>=礩1wF2ux>1#>M Ͽx9j1LWҷGp8D;wN]֬XZV cmku Sl:v?pإQD4gO+W3{gn" 7ݦې BK {cu֛:Ts>dYUo3g/ rؽ뎠Pfۃt{ڬdѸzxzt~j@#7/==¢x<-[_qdخ?u8hߖ/]x=s^+`7W|>%y0Dt,'twڻ SfpQLyuFtq󴶵vVU .LNne^:ҐнDQ;l:s򘦦ƂD ]ydx&D4g|:uDD1bocO@wD@_lq6D4h`cǙ){"$IWgObjLVUUfR?Cz(++gҬhGD%%<"ğ nޚ,wyPT2{֌-͉h萁{٨jݱkfào<2 ۵}T^^>{,CC}"jC򽙱qVfh0#C \pGwӑbSS&zO]CSS\QHSCC[K:m"~l6y&3>P?v>L̜1*à FAAqϯmzѹk7⟿la\IKD))T--MѸ,ph>T\\ԫS}F혷 >픈(_DJi+"lm!Ξ &-s+'77(8lYU5٨N:0hfϸKD2!=Nj{|wK/ la2|l  ȇa2|l  ȇa2|l  ȇ|'A!ah:hgG24a5^Ocrȇ|OBPwLȇa|4j j0 aO3R$[ZXgbbaG?}☙WuX>-ʇqhhDU2VͧOo־a~3|Z'&&ՠ/K\f'l0Ok[{m҅ף;.]ݾW- ݛ!鳡[~5&t,'twڻ=G1}]{..^bt%__g$vo޺Ы_ff=%)9Eww ;gdO'Nv6պ/S/\642ڥc之}tra.&!Rg/f>=?"R]$6lphƆy 8AD.]abpx9&_~}B###CCM6~ΝD ֽ{l,@,K(:aʰoi3M2ѲyۡD~dIf\ [0'"KF_PP"w`CDOKK?~\ .Z07gqmX݉Z|tG鳸~<`?е ~ɲU4) Ⱦ.XCw>Xdńct՗{:`,kˬ9 ߿=062{y<މ1]1?!{Ws[SeE?_Qzcwq˄}/Yz]rJ"jҤIll,DI2]]]PO? 0@W0"YCf^(*(?5q=pRUf?d͚Qn^))}DgݶnNx.1,,Zb5$lW[6D2z>Zy;n֭Z 8~9t1svr?WzcZҼ~<ش*J:_묊J"262z>;/?S]M{W׾P(7ogݻgee|r"bٟ>9NgsTfvvG[g?^JJnanFDl.m߲Ѧ};mFƻ¢3>ULaB+K7g+Q\$ӭ_"f5onZT׸ѫ6E++)s]O킄5D4ǩ.32559hҼ!G?y(+KG}z#Cb{#^_D헍:v&f~a+1'Ż5??^GG~g77hiiQVV>eff2@wŪ {ZԟL ‚ܼ$bѴmZx~9|u~()O@s^ccø+V2xH ?oQTTnEX Mܺ}gEnC9N &- VjoM#>G;gIUBCJ5+)qʪy#NOOW⡋t2n”ko ]DI'tϿ~lEvv]txR"RV6'1+0Q]]Ν;DݱcGl)/ 3|U*rUMM >sp8_=M4̧CM2s-4Ӷkμ99zF#*/ Ovve9f,Zk!aX\۶Ԩf~~.3nrh>_4Q*۱ HNN\ß=z45ۀ~{jg]9|[4lmerTEI6V_:KR]$6&ŲlJ_Owͺ #"gkWv`SVZ&//U$tee%-gs~?~Ɨ& NXXXpQF1M<߿C۶m –ReKcIrdff*z=KwyG>F7s_LAп_߃ǎUnɓg^z)p?vDYS^0wV=6[k;e9`OGiodd(~F__3gϟ<~D(._,iKK9Ts8Yqϳ*}KVw6t r]׈g[HqiYqȇAcgۃvm\ڬ˄ uؿ۴f}% e5r! ?}zR\ ;4IM2tT]]ݾZ8}׭@Ø?Na}gr:1{"V.a_~@@MuS:#]hدa~fթfjC7WWST{tXYdXudf!d0iBDNvF#8 ʐ d0@> @F d0@> @Fm)h  0hːd0@> @6daOcRJ> 7ZɇL! Laa|L  ȇa|L  ȇa|L<Ʈ zsYi{,r#K|U>,Qtl0F"7a|Laa|L  #VrrrFFN***_TP(rrrXmP|>?_(q&p/_{JT\f=fz_7[}@İ!ޓl6Yڟ>q̴nGK>glmm"0??.eկ$7/gL u͂ѣ01iԉ<ȵ`<]zJiڦ ]iiI]^ش^v]nޠӭ; ͬ7+L,þNiI^AL̡Wՠ6/ TǫGj[^PVҷׯ4򖔔9ғfЯ mܵsWwѲ˖,~򴨨XUUuѿ&F߻DYsm,#~?IDs|''"w99V-3,B\wt6;TU?4x Ocɱ2"b͞c`h\Zu҉_*:Ɍ~ğ͌vX_v%/^5mΦcߍ>$7'+'78ߺ}+mnj˱XU7nׇy{4x;6mXՑ/G{'meٚ:`Í+(puYOQA.\}ghJri=%"Pۡxild?)>o;?G$,.)ʒ46..#[zx!EEFD ԥ[Jr=;u~l!+:b?G_clY1u>ٻMǮ$(u[[@x֝[7475Ҍ}ucǎt]Zoaz&o߽2]ʥz+y2Ɩ/3knr%9^'驡~,C=*]hzo޿pIqA- ? -["/,?A|/Yz]1%706޳}Gx7/==~ͭMꪊvcb5uBNA&Jrgc=WVV:)sX}}r^]NO<3fpөO90/u 31i6uܹ ubhO'YTIDM5LM **߱X/LML dg֋]Inn޻wwxZKSÑ3=_ٳX-#D:)͖{"E s5 f]g ]|"336VsfM?{"s:M TTT(++|**M?FWWg'y ?^rT[r> B?9ØDoh`l@׻'&jT֦\  SR#f-^xZZZ*ihe%^VFj~^NUkjf{P XYY٫ז-275nk;ɹ0?ݻkjl\yŋ JŮ"ڱc޽qcffeOKy%JBPHl6[NrXe eB°# r**OtuHF\^^>{,{LIvN.5k8+34CG׮dҬُ^? rs%䔉>b~}YKa͌toݼnl2c.3sy99%l:w nZ(jSRQf滲24QV,vi)J_^A6@Wu8TRRTRR$(/%"uMuuIm eaK˻ux[_v%/^$8;;9y,[+ve<"%"UUU&Diy^X?ĩ36 ԩS״Iugy䝝ۖv#EijQJJj&DID%JJ=;|g-뢣}F>ۻ¢[ Y=_R( JDdٺձc{tWdfeE]ʲ]s%6--]NN"'=B&ǎf׹N6mTŦ逿P زe?j 31h2޽344\Ӷkμ99zFc-.wxto=}w%%l/M;+~|yYiNvfֻZv릫g,PVV/a(s g*q}z祢& rޥtrUՏ?O ñigץBE ?MRXu駣g( ߥQmDE5@еKAT_v%=  YaQ1h޼\A~nW0JJJLL?tM?zsyusqsVP^^~v'}]/ Œd&b/.7;37;SD H,^I\U@'2&g zVԗ{1Kף]Iڛן}˼y.OX(Z VvZR\T+雓U> yȨ"i's풛J|{c@mjx{ ;b{Qa~r"3gX+)7Vv>gw[;)|zw@ lم}oܧeEϟӀ.sK<7·2Ѩv@*^!D<8D.q,8%.q9ajKG!>x_p |2XF]|T #~ C|*z>^:a3gLqxD<">a|sp/Enl0""<q-oa %eW'x<@-vxWk#>:b 9c y<>G|p9pp0t>8\qsIDATN#yCyȇn'ɇG|@v>xD|~ .Lf'(x|"" .MD\gj3ݛ-5_LerNX[^nV"0Dy* image/svg+xml elyxer-1.2.5/docs/svg/svg-test.html0000644000175000017500000000331712074107030016524 0ustar chennochenno SVG Test

SVG Test

1: Object with size. Object with size information equal to the SVG.
2: Object with half size. Object with size information half the SVG.
3: Object without size. Object without size information.
4: Img with size Img with size information equal to the SVG.
5: Img with half size Img with size information half the SVG.
6: Img without size Img without size information.
elyxer-1.2.5/docs/elyxer.svg0000644000175000017500000015524512074107030015324 0ustar chennochenno image/svg+xml elyxer-1.2.5/docs/parse tree.png0000644000175000017500000002715512074107030016031 0ustar chennochennoPNG  IHDR|bKGD1 pHYsdd vpAgH-HIDATxytT>gXBdYBdY"b~Q[l%AAYde)* 7ܭV~T Uhay<;mrCf3's޹Nfy]=vDDD$(<# """ƒ8 """(<# """ƒ8 """(<# """ƒ8 """Tr"ΝΜq.ƒ؂@Ӧn$nۥQxڴq$/;<# """ƒ8 """(<# """ƒ8y$f֮q$Ĺs]  E p119@R%'ƌq"l!"""(<# """ƒb|./\_r""RuWt{?/Ӂ-c~""IA\ \M]*) 5[H8fM`=~ ԭ H<o۬p"'#HI㱯gd V>2 u L6oON45v,sCɓOK6liS`l^z0k,Ã ej|9~=PWb {ogxK,ee,`0YY@n1 .а!֬a?ΙMss  7+V|ݻ:zzzn//YL P׬]"!ψ؂dfNc {'V۽/*3goOO>q殻Q/:eKяSk~=>lLlc~0m[{Ɯ9co=k̢E%{ܒ$Mc5&7ט'4ȑ=T 1e'}VGԦWo`jMKRz WEU8}pм9aCv*hEYy e?ρ@>E=_ߞ6[KZ5Ο=_t4p-IJr~Yŋ..Θ1ԩ-DJ-f{\ .{ta)S&M_?^="-1'RJ^=`?OC,]V?#ɓ)/^w7w(D™:LJJK.]b-B9.erժe Y;Q@)6F ǁm}IIuvL o9s8ud,w䧟_m0)k޼۸8`ժ[б#k,;w8ebu4h^s|`@`JnϚ `t 'AZ恼<[|˰t)f5G۝??y'p%;N 7b{|P>kת٢,,\בABSYG{8Tσ 5[# """ƒ8 """(<#)w9-/JAQDĢ ׮|x;)ϟ'EˋHQ$nɞ,'XKr9!\>(\ylNOU]2ȡ Y`ξ)G.HQxvk\YA.z {7Ű,Pp \.%+Y32W@wڵ } };WUpW=ѥ lI6ud""*e iE/>n풉H Hxt9`>Q#JKS{(?~ o4i^ <0ED$Ty1BaVoivi1.Zp!p{ԅVDDGE9s4Ǟ1X!%qd"".ʉ<`6dgO?%krd""na2Zj  t !DD4"7tl~˖qHi))8HPC8~',‹s>}(K&""Kegsӧ.paf,""K%.K&֡`8t)""O}Dvr2p]\"{  A7ݺM},_4lvDDDJN!ܙ4T'u׹]2!a?7xࡇ[o10Ź]qF NP&"C= L2P6x1?o1"IJr$Ę1n@DBߏÇ.fZ`@^^ٞvx1J`>+ cH7<̙\qEdV9Ѳ=@L m[ɓ }iil|~C| g:C77\;eYS# DD yE ;ذY曁9bw)[:ZVZD(-ΟEo-::4á/PxS9G| g+Q6?,yR*\GěUQpվj٬O9z.G|^R229%u=#풉?C@b"o_ YUVH)ޡC~/gަOG1={reXS{%K?֭>}|ϟd?},ԩVy;&L;0`H״)M]2T]ǥ,UrrZ5k6ƾ>v,~h}^ܹ@˖@۶S 'z`PoR`,>ϟ.^FG>`_c,?8rQ͛u8 in? {/л7< \ӻ70t(in.0s&@B鵖r1u1پ=kw;w+ԭkLt1o13`1ԨarߥKƤdLJt`ʕ<-1gM7S1 Iεz1^},^\T:_rlnbc23}ok7̙/ƴicu?;zϟ?wms{{zŊlZc|ۿѥ1ݺ9<`V.,UO8sAKn,[foXΞ5fѢ>)R`V5o*޽Mr ~;|%~kز  <0x)keUI/_E֮ey׮8agv!C \lΪy$=[? f9w~sSxKv6wobbs~ZpU > ^lGip ,aٽۮyصMIV-PuǡuknH#Sk/Ə}h)oJ=⡇tl?/fG4cr`zV-OKc59?>k3ݛᣴ:*➓۾UzuVZqreoK@ǎmCm0>[ޏ[cڜ8@fEN'<{qP>_#9g |t_sre>pעE8xO%=I۶1@>ڵL.bHC+ux~{h̾ޢ?̂ևо}@VR :Wݺ55dQg@Nnk׎ꈖ}wPj5eb"'4׃Oᇁ=ESlほf9q>GyX_USM5}yHytY!`mQ#4-X8s&= S}Ϟ@zĉn]%].0jotq)1^7kHpTVHI]f kxή޻w{G#k0Uޏeɿ8NU\tqϩzu6ň;4Jĉ;Qk D޷akogF[D~y0XkX7ѣ甿%…DxR.\ """""">BA"[Z\LCVËb""$uEDD"p48_@8{`9q½DD$S q#燘HKڶu$Dz:;KRxPqqv35Nfu.H?ڷs$Dr%lFƾ} ˖q#8S D|<;TQ2"DD)r&!?!bph5 K'""@ᡜQC0lx1CDj*pۥ ,IOx,pPY!b>v,[<{gF3B!BDD)<+qԜ9v.H[hT ]x,]9RVx8rޗǿ8!Cs~Vr/RR씒,\Xp5m8UP U 6kgo?K'R6z:wt˖&\v /u|7e ϳy3k2lKx{q`l^=+Tj[,Lj#h()V9cg;I8%7DUl,?5:ux{Nq3в%/^ \= gу/.d? {/лN > |3k%*T`̙@n.MHX R"V1?g`m".sU{gn5hǏ}f&>UPebPIu^Yk$Ξewxx0KLyw$~U\׀~{>%1 !ESR֫!3s'?ش E}ع o֭< VOתo{ !mGMw/k4hypX[u]{<\8\wXc-:!$(ko$M4yR[MFoĴil:!".11Pb ~Kn~MNf߇\^o҄6t8~I{-$o{MX۶a oV%&#'eEkrY!#ϦNeSnNxu={|$n p>y[ǎ|{OK.]b E`9g&lW5V<&-ͮ10N޾gU2y2QCĨQ m<|8Uv ElտX 7on?~8`ժ=+y=%cAVx{߾[ovt48X͟[nG?ao[NσālX=G~Z!B>ڒ9m9f 32GViK'""CA*1c32]1cFNi""$(4`'d;!bLK'""N(:vtƒƍ,q Ç3D}p!#)Xq3;6ڵc3X@۶:H8Rxd&bP1f S\PF"ѣ!a.ppv];5.H !iS.Q1x0Deo""Cv6¦MvXZv|W)SxЬvM\g^"IN5 x#vBÆnXDSxr\fXfM3pВlcGDp{k5Х ays`Jv8 Lʚ'`{  G>lQ2_q!CZ2"~+ays7X1q"Я0e {ԇSYBkSW`Ю\kA#eD"JDh_ѧ0y2k""._f6l`'д)B׮y @jnXDc1nB"/p`^~K`3۶W34=4'X?.wzu]w p}w?VAn,LL cԯϪtqfbNޮG@oԭvD$2W.:i6)품}N""iUMqDADDDQxG5v)lwsa٬;{Frt(")v xaPԬ͵{l̇Nn{{ycu3f^cޘm1߯1]s1W_m̚5}+'sɘcjeȑϩkWC^YY;:߭u+a$$pߤIԮm̻s1}dLz`CD$(}kdhՊnYkpRx]US'6c}욊-[kK<h ƢeK)"AADʌ>o~<{7CŖ-\w9}K@Ŋ@F M\T)?K ʕ Z}Ծ='Ab6^ne-ZV[.;." "V hߞo/*mcl-8uk.`U ?Ӧ])ƒ5o[Vk*laش X8{ԱG}nG.&$D$l4hw۷]ַla'mۀ?,`NvIDBjDDSDDxGÆ\ `@HNWbvy(.TN0t(_``z}s͝fO?uٹO"R.M :v)c\Iwo`X` `E {* }ժf1Zo;Ձ~VCADʥc/֯jvZW1JYiтkX*NH`mEl,? v5U LZo՜9 Sp'W^aH-fÆ=<Э;ǚǁeˀÇKV1_P@c?ä-*US*Tm֍g~_'#m7aCkn.k@~#?'уn].WB0v9LN侔~}`Hn4i;)_~ɜd8 " ;w͛۷ժov>q8t(<W׮dIիCȈqj~bmOw}^{'#Nk``sW""t?L`.nۥ*wgz>1o9/>X9Pk0Y,_J%0t8gtTRVǎ'%W%?Q}o䓲;qaRDʝªU ?ys5Y`8^>kbc}٧b\^?ặbW~lо+Wr`^?8ؑrP>Q'dETo'` ">Jߘ1(< """eNADDDQxGDDDqDADDD<"jO_vIĉJd yzD$bt[nB$BDDDQxGDDDqDADDDQxGDDD ""aQ 5RD\x1킊HP8 """(<# """ƒ8 """(<# """ƒ8 """(<# """ƒ8 """g_ ^ޫ%tEXtdate:create2009-08-31T01:36:31+02:00p+T%tEXtdate:modify2009-08-31T01:36:31+02:00FtEXtsvg:base-urifile:///home/chenno/projects/elyxer/docs/parse%20tree.svgM^.IENDB`elyxer-1.2.5/docs/math-iso885915.html0000644000175000017500000011764212117174757016427 0ustar chennochenno eLyxer Math Showcase (ISO-8859-15 edition)

figure elyxer.png eLyXer Math Showcase

Alex Fernández (elyxer@gmail.com)

1 Introduction

This document is intended as a showcase of the mathematical abilities of eLyXer; for more information be sure to visit the main page.

1.1 Versions

There are several versions of this page:
All of them are generated from the same .lyx source file; they should help you decide which rendering options suit you best.
Also available online is the eLyXer translation of the latest LyX’s detailed Math manual, which contains a lot more examples of LyX maths.

2 Typography

Math formulae use a lot of different symbols and fonts.

2.1 Greek Symbols

Greek symbols are very important in equations: φ, π, Ξ. eLyXer offers a complete set in both upper case: Γ…Ω and lower case: αω. Also the AMS italicized upper case: ΓΩ.

2.2 Math Symbols

eLyXer supports the whole set of math symbols in John D. Cook's list: ∃∂∇ ≥ . It can also render a few more:  ∝  × . You also get all symbols from Markus Kuhn's list: ⊙∐.

2.3 Other Symbols

There are other symbols like arrows:  ←  → , or geometrical shapes: , . eLyXer offers limited support for them. You might also want to use financial symbols in formulae: ¥€$.

2.4 Spacing

Equations look good when items are properly separated. The main separation is the Medium Mathematical Space: x = 3. Note: if you are viewing the non-Unicode version math.html of this page then you are in fact seeing midspaces, which are very similar but not exactly the same: (4)/(18) em for medium mathematical spaces versus (1)/(2) en, where 1 em = 2 en. Try out the Unicode version math-unicode.html — and viceversa. You can check out what version this page is in the page title.
The command \raisebox is useful to, surprisingly, raise a little box,
raisedoverloweredand back.
Like \mbox, it puts its content in a text box. It can also be used just for spacing:
BV.
There are other spacing commands: \hspace: a b, protected space: a b, and (at “block level”) \vspace: a b.
There should be 1 cm of vertical space above this paragraph.

2.5 Fonts

By default, letters denote variables and are taken from the \mathnormal font, which is italic, αx + αy = α(x + y), with the exception of upright capital Greek letters, G ≠ Γ.
Function names should be upright: sin(2π), log(x), tanδ.
Mathematical fonts used in equations include Roman (\mathrm), Sans Serif (\mathsf), Typewriter (\mathtt), Bold (\mathbf), SCRIPT (\mathscr), CALLIGRAPHIC (\mathcal), BLACKBOARD BOLD (\mathbb), and Fraktur (\mathfrak). For the latter, some single characters are translated to their Unicode equivalents: , 𝔽, 𝔉.
Regular text in a formula can be achieved via text font commands like \textrm: 5  to 10, via boxes like \mbox (prevents line breaks): 6  is more than 5, or the AMSmath \text macro (scales like math symbols) basesupersub. The content of an mbox is processed in LaTeX text mode. This allows text font commands, e.g. a switch to sans-serif-bold-italic, or the phonetic alphabet: sfbfit, tipa.
Units should be written upright, either with \mathrm or with macros from the units package, e.g. as simple unit, km, with magnitude, 57 km, with fractional unit, 200 kmh, or with a fraction before the units, 32 km, (7)/(16) s.

3 Numeration

Equations can be numbered, like (1↓)
(1) y = x
And also like (2↓).
(2) x = 3
Some equations can be numbered even if they don’t have a label.
(3) x = 2y
Notice that equation (2↑) comes after (1↑).

4 Simple Structures

Let’s now see a few of the simpler structures that eLyXer can output.

4.1 Fractions

A simple fraction:
(1)/(2).
Inlined: (2)/(3).
A big recursive fraction:
(1)/(1 + (1)/(1 + (1)/(1 + 2x)))
A nice fraction: 56. A non-diminishing fraction containing alignments:
(1)/(1 + (1)/(1 + x) × (1)/(1 + x)).
A similar concept is a binomial coefficient: (A + 1B). It can be prettily presented:
AB + 1.
A symbol can be stacked over another using \stackrel: xR → y. Anything can be stacked:
dx > 3limx,  headheels.

4.2 Limits

limx → ∞f(x) should appear as x → ∞ in italics, and «lim» in plain style. In display mode, a limit must appear below the main symbol:
limx → ∞f(x).
Limits are also used in sums and integrals:
i = 1x,  0f(x) dx
where the sum’s limits should appear below (i = 1) and above () the . The placement of the integral limits depends on the document class: LaTeX standard classes place them right to the . Limits are shown to the right in inline formulae: i = 1x and i = 1x.
The placing of limits can be configured with the \limits and \nolimits macros:
limx → ∞f(x),  i = 1x,  0f(x) dx

4.3 Roots

A square root: (3). A more complex root in a fraction:
(1)/(1 + (2)(1)/(1 + (2)) + ((1)/(2))).
eLyXer can also do higher-order roots: 3(x + y). A devilish case mixing everything we have seen so far:
(78((8)/(4)x) + i = 1x)/(s + 5(((78x + 45y) × (Ω))/(sin(x + 1)) + 38 km)).

5 Complex Structures

In this section we will explore arrays and related constructs.

5.1 Arrays

An inline array a b c d is always shown in the same line. In display mode, the array is shown on its own line:
12 2 3 4 × yx
Apart from that the appearance should be the same.

5.2 Brackets

Arrays are separated by variable-size brackets: a b c d a b c d a b c d a b c d ||| a b c d |||which might also differ on right and left a b c d or use the empty opening a b c d or closing: a b c d |||. There are also fixed-size big brackets, e.g. f.

5.3 Cases

Used to switch between several values.
y =  x i = 0,         x + 1  i < 3 
Cases may have more than two rows:
f(x) =  0  x < 0,         ∞  x = 0        0  x > 0 

5.4 Braces

Values can be underbraced or overbraced.
a − b = b + c + d + e.

6 Macros

Now it’s time for user-defined commands (sometimes called “macros”).
Definitions can be added as macros. Then they can be used in formulae: 1(2). They can accept default parameters. Again, useful in formulae: 4(5).
Other definitions from the preamble can be used: 3(4).
Definitions on the fly are also possible: 7(8), and used with different values: a(b).
elyxer-1.2.5/docs/container.png0000644000175000017500000001225212074107030015751 0ustar chennochennoPNG  IHDRM7bKGD1 pHYsdd vpAgMIDATx{pTgcRx(⥌"ScVED!S(DZPGGUGĢ[ VBH(%9I!yn=N\o۞A$ TBhB oRe*Kv9b|HN7$HJ{IcH4$ծ4zt!+I9Mp@hB"*֮u]jZ3U@ ~gEhpriҽڕMl/) $ "48#l-[3}Wx&zFrs*裥_LikB1C5wGh"isg $]x1HݺJJnƏzO~+ خ]}WXؙА?>Ə,vtv2A &uh_; !C={|"4[:ᄺ]*-&3vh>wԪUcI4ywX#lw5)=fgK]$uT8o`{S'o|cO)epi6;߆ĩ>Lzqk}W\M= ֝;$Xawut啾I.&RUWK.]Iz~?<ɆDJζsgzQEh",\hw>㍔,l%ZeaذA: U@ҺrihUUq#oUs}YgH_iF\HKc$-B8!4 Mp@hB&8 4 Mp@hB&8 4]ʤqiӤ W_:Hڶ(m[[Gݻ>}뮳e+WJO?-M.JގOHғOJ/ { -W_o*76$k'XMmhTH۾=&OO[RLRwA˃ 3s6]U. R{zut.+(6kTTcǧ-$/Fx ^gVV8L:PiNi&ۥ_?k6TVJm/O=U ֭۫mϱmEE6FƷ]$i"֭?}| ä5k,4v | cbwpwX~4D\JKJvI/JG۲eˤ 7mJ۷ѩu_'téoդIf˗Śѣal̙ҵJ#UWKb6o(ٹ-ѡaSnf͒{wzϟx@c8q>&iFDm~1]8Du`_4=Mp@hB&8 4a{HWH-fmd {t%ֱ!4#wOΝ}޲{4 z1яΓ7GgFɾ+R O>P|)\R S6g8_o1i={^fϖyG:o:v]]]+u Di`&NRU_t LI1wAl"͝[wޢEv 6PX^4|tiWBClU4]wo~ZzT줓 >w@BPضM1\2iv$"RZR92.X~~ԭjEf8d;w٪J9SZBS] )"#bך5E}B)WQEh"ddH{K]QEh"< e\J*SNJGN4z*͈۹S:xiXߕ$}Wd98 4 Mp@hB4:'#åN={ڐY yӜ=ۺz9gO!/O;f|^4N^=q3y˖I&:#GZ SJf{ :t4`3ΨQaYgӏ>j{ާtusm^_n++m];)?_ζ+ӥRرCz Vwo7J!y-/;|eSEc6bbF6ôiȑRaKZK'`S5**ݻ]{tҁtemn~yyCp &hmNm+vΝ=XgeI$Ͷn<6fӧWƬMsۗ^;^|Q꫺IC$)HnX,vn=4JJ+.pz꫃} h:.:tV6]Ѷۨlg9vls}{LlG m`V5Ə[o j[n iR{ysdg7 k<ߵ  (-WAni rN䓥?_ןa{:0h)Y#I?w{GK6}7Opl̙wUb1i8i֬q7MIl7ǁ=%i;/YP`UU6]U%M.1B81 O榿FVVC?زe҄ 6pffx/:I|PwޢE-6˞=O-3w/bpBPyy펫_]snbFH5cϚe;MOj)$i;uq1c̙ҵJcO9Ŗ[XoTwfo }ne=gm.GݹsX/W]e{ݵ|UH&Ssuc־MBvv=\"׾d?mw r!K<9~}`X ;SI[gmVW[`\YcYSFfc'=pAg1ѦgͲ n,Ӿ$},+6ls}L)%B[QBFqp}J޷Uwvv*)/c>pxS@K#4 QY)[ fXFU"8)-[QEh3ΰ!2ʤ/) ;]*6c ߕ qU_*Z%]|ukֹs8? .Tzm] !z+ߧVڶo1o}w~Гk;7w5&ZFHug+С'軺޽~@K!4_H \R"eٷ⧃LS;w=<"-YbCIx~z;v0z8} Q{B3Vf϶a +q}>㩨H:s}WDy~I_~)uq95ylJMChFHv6ڵoו&O18B3b΢U͈;@&8 4 Mp@hB&8 4 M$=S}?BIen/wHҌҲe6YIO>rTQ!}4uY^.NX!=3jTfnt)i҂ҫ۶Gcx|:'TA1 ,ȦMCix[f~ƦkŤ)S; O7bh 4#.١J99-[lOĦeeRVV8L:P}7 D+22=^֭?}䑾9D܌!Mg87Ӻ}=_~YYv_\pPZTڵKz};'9ztÅ MA]xe]}ᥰЂ?=M*9sC w);۞O$ ,-_n?z4lX9͈9DKxf4pxM$[HŤ~|W(&^Ҟ= {&8 4 Mp@hB;$UT$}t+I_- .}:M I4dۈ߄&<̔{/5Kvׇc!C۶R.f.]|W`͈; W|W.!+@H)>D M bڵ]k$i,{wgjӧ4 A@I{.~n(\)'mۤwZ D\vaE?zzI  ͗_z^{h9h矯{?Ie@;)O:ɽݥݻ]vzK2e'҈vsA"G\D*)XĽ ۫|y.*>F i"-;vHJm= J?a|_}{)'րvhʔhK&Rܹ+]+rsϷYYڿ=wߕxCz eLyxer Developer Guide

figure elyxer.png eLyXer Developer Guide

Alex Fernández (elyxer@gmail.com)

1 The Basics

This document should help you get started if you want to understand how eLyXer works, and maybe extending its functionality. The package (including this guide and all accompanying materials) is licensed under the GPL version 3 or, at your option, any later version. See the LICENSE file for details. Also visit the main page to find out about the latest developments.
In this first section we will outline how eLyXer performs the basic tasks. Next section will be devoted to more arcane matters. The third section explains how to contribute to eLyXer, while the fourth one deals with future planned extensions. The fifth section includes things that will probably not be implemented. Finally there is a FAQ that contains answers to questions asked privately and on the lyx-devel list [7].

1.1 Getting eLyXer

If you are interested in eLyXer from a developer perspective the first thing to do is fetch the code. It is included in the standard distribution, so just navigate to the src/ folder and take a look at the .py Python code files.
For more serious use, or if your distribution did not carry the source code, or perhaps to get the latest copy of the code: you need to install the tool git, created by Linus Torvalds (of Linux fame) [8]. You will also need to have Python installed; versions at or above 2.4 should be fine [9]. The code is hosted in Savannah [1], a GNU project for hosting non-GNU projects. So first you have to fetch the code:
$ git clone git://git.sv.gnu.org/elyxer.git
You should see some output similar to this:
Initialized empty Git repository in /home/user/install/elyxer/.git/
remote: Counting objects: 528, done.
remote: Compressing objects: 100% (157/157), done.
remote: Total 528 (delta 371), reused 528 (delta 371)
Receiving objects: 100% (528/528), 150.00 KiB | 140 KiB/s, done.
Resolving deltas: 100% (371/371), done. 
Now enter the directory that git has created.
$ cd elyxer
Your first task is to create the main executable file:
$ ./make
The build system for eLyXer will compile it for you, and even run some basic tests. (We will see later on section 3.1↓ how this “compilation” is done.) Now you can try it out:
$ cd docs/
$ ../elyxer.py devguide.lyx devguide2.html
You have just created your first eLyXer page! The result is in devguide2.html; to view it in Firefox:
$ firefox-bin devguide2.html
If you want to debug eLyXer then it is better to run it from the source code folder, instead of the compiled version. For this you need to make just a small change, instead of elyxer.py run src/principal.py:
$ ../src/principal.py --debug devguide.lyx devguide2.html
and you will see the internal debug messages.
Note for Windows developers: on Windows eLyXer needs to be invoked using the Python executable, and of course changing the slashes to backward-slashes:
> Python ..\elyxer.py devguide.lyx devguide2.html
or for the source code version:
> Python ..\src\elyxer.py devguide.lyx devguide2.html
If you want to install the created version you just have to run the provided install script as root:
# ./install
Once eLyXer has been installed it can be invoked as any other Unix command:
$ elyxer.py devguide.lyx devguide3.html
In the rest of this section we will delve a little bit into how eLyXer works.

1.2Containers

The basic code artifact (or ‘class’ in Python talk) is the Container, located in the gen package (file src/gen/Container.py). Its responsibility is to take a bit of LyX code and generate working HTML code. This includes (with the aid of some helper classes): reading from file a few lines, converting it to HTML, and writing the lines back to a second file.
The following figure 1↓ shows how a Container works. Each type of Container should have a parser and an output, and a list of contents. The parser object receives LyX input and produces a list of contents that is stored in the Container. The output object then converts those contents to a portion of valid HTML code.
figure container.png
Figure 1 Container structure.
Two important class attributes of a Container are:
  • start: a string of text containing the LyX command that we are about to process;
  • and ending, which is used on some Containers to determine when to stop parsing.
A class called ContainerFactory has the responsibility of creating the appropriate containers, as the strings in their start attributes are found.
The basic method of a Container is:
  • process(): called after parsing the LyX text and before outputting the HTML result. Here the Container can alter its contents as needed, once everything has been read and before it is output.
Now we will see each subordinate class in detail.

1.3Parsers

The package parse contains almost all parsing code; it has been isolated on purpose so that LyX format changes can be tackled just by changing the code in that directory.
A Parser has two main methods: parseheader() and parse().
parseheader(): parses the first line and returns the contents as a list of words. This method is common for all Parsers. For example, for the command ’\\emph on’ the Parser will return a list [’\\emph’,’on’]. This list will end up in the Container as an attribute header.
parse(): parses all the remaining lines of the command. They will end up in the Container as an attribute contents. This method depends on the particular Parser employed.
Basic Parsers reside in the file parser.py. Among them are the following usual classes:
LoneCommand: parses a single line containing a LyX command.
BoundedParser: reads until it finds the ending. For each line found within, the BoundedParser will call the ContainerFactory to recursively parse its contents. The parser then returns everything found inside as a list.

1.4 Outputs

Common outputs reside in output.py. They have just one method:
gethtml(): processes the contents of a Container and returns a list with file lines. Carriage returns \n must be added manually at the desired points; eLyXer will just merge all lines and write them to file.
Outputs do not however inherit from a common class; all you need is an object with a method gethtml(self,container) that processes the Container’s contents (as a list attribute). An output can also use all attributes of a Container to do their job.

1.5 Tutorial: Adding Your Own Container

If you want to add your own Container to the processing you do not need to modify all these files. You just need to create your own source file that includes the Container, the Parser and the output (or reuse existing ones). Once it is added to the types in the ContainerFactory eLyXer will happily start matching it against LyX commands as they are parsed.
There are good examples of parsing commands in just one file in image.py and formula.py. But let us build our own container BibitemInset here. We want to parse the LyX command in listing 1↓. In the resulting HTML we will generate an anchor: a single tag <a name="mykey"> with fixed text "[ref]".
\begin_inset CommandInset bibitem
LatexCommand bibitem
key "mykey"
\end_inset
Algorithm 1 The LyX command to parse.
We will call the Container BibitemInset, and it will process precisely the inset that we have here. We will place the class in bibitem.py. So this file starts as shown in listing 2↓.
class BibitemInset(Container):
  "An inset containing a bibitem command"
  
  start = ’\\begin_inset CommandInset bibitem’
  ending = ’\\end_inset’
Algorithm 2 Class definition for BibitemInset.
We can use the parser for a bounded command with start and ending, BoundedParser. For the output we will generate a single HTML tag <a>, so the TagOutput() is appropriate. Finally we will set the breaklines attribute to False, so that the output shows the tag in the same line as the contents: <a …>[ref]</a>. Listing 3↓ shows the constructor.
  def __init__(self):
    self.parser = BoundedParser()
    self.output = TagOutput()
    self.tag = ’a’
    self.breaklines = False
Algorithm 3 Constructor for BibitemInset.
The BoundedParser will automatically parse the header and the contents. In the process() method we will discard the first line with the LatexCommand, and place the key from the second line as link destination. The class StringContainer holds string constants; in our case we will have to isolate the key by splitting the string around the double quote ", and then access the anchor with the same name. The contents will be set to the fixed string [ref]. The result is shown in listing 4↓.
  def process(self):
    #skip first line
    del self.contents[0]
    # parse second line: fixed string
    string = self.contents[0]
    # split around the "
    key = string.contents[0].split(’"’)[1]
    # make tag and contents
    self.tag = ’a name="’ + key + ’"’
    string.contents[0] = ’[ref] ’
Algorithm 4 Processing for BibitemInset.
And then we have to add the new class to the types parsed by the ContainerFactory; this has to be done outside the class definition. The complete file is shown in listing 5↓.
from parser import *
from output import *
from container import *
  
class BibitemInset(Container):
  "An inset containing a bibitem command"
  
  start = ’\\begin_inset CommandInset bibitem’
  ending = ’\\end_inset’
  
  def __init__(self):
    self.parser = BoundedParser()
    self.output = TagOutput()
    self.breaklines = False
  
  def process(self):
    #skip first line
    del self.contents[0]
    # parse second line: fixed string
    string = self.contents[0]
    # split around the "
    key = string.contents[0].split(’"’)[1]
    # make tag and contents
    self.tag = ’a name="’ + key + ’"’
    string.contents[0] = ’[ref] ’
  
ContainerFactory.types.append(BibitemInset)
Algorithm 5 Full listing for BibitemInset.
The end result of processing the command in listing 1↑ is a valid anchor:
<a name="mykey">[ref] </a>
The final touch is to make sure that the class is run, importing it in the file gen/factory.py, as shown in listing 6↓. This ensures that the ContainerFactory will know what to do when it finds an element that corresponds to the BibitemInset.

from structure import *
from bibitem import *
from container import *
Algorithm 6 Importing the BibitemInset from the factory file.
Now this Container is not too refined: the link text is fixed, and we need to do additional processing on the bibitem entry to show consecutive numbers. The approach is not very flexible either: e.g. anchor text is fixed. But in less than 20 lines we have parsed a new LyX command and have outputted valid, working XHTML code. The actual code is a bit different but follows the same principles; it can be found in src/bib/biblio.py: in the classes BiblioCite and BiblioEntry, and it processes bibliography entries and citations (with all our missing bits) in about 50 lines.

2 Advanced Features

This section tackles other, more complex features; all of them are included in current versions.

2.1 Parse Tree

On initialization of the ContainerFactory, a ParseTree is created to quickly pass each incoming LyX command to the appropriate containers, which are created on demand. For example, when the ContainerFactory finds a command:
\\emph on
it will create and initialize an EmphaticText object. The ParseTree works with words: it creates a tree where each keyword has its own node. At that node there may be a leaf, which is a Container class, and/or additional branches that point to other nodes. If the tree finds a Container leaf at the last node then it has found the right point; otherwise it must backtrack to the last node with a Container leaf.
Figure 2↓ shows a piece of the actual parse tree. You can see how if the string to parse is \begin_inset LatexCommand, at the node for the second keyword LatexCommand there is no leaf, just two more branches label and ref. In this case the ParseTree would backtrack to begin_inset, and choose the generic Inset.
figure parse tree.png
Figure 2 Portion of the parse tree.
Parsing is much faster this way, but there are disadvantages; for one, parsing can only be done using whole words and not prefixes. SGML tags (such as <lyxtabular>) pose particular problems: sometimes they may appear with attributes (as in <lyxtabular version="3">), and in this case the starting word is <lyxtabular without the trailing ’>’ character. So the parse tree removes any trailing ’>’, and the start string would be just <lyxtabular; this way both starting words <lyxtabular> and <lyxtabular are recognized.

2.2 Postprocessors

Some post-processing of the resulting HTML page can make the results look much better. The main stage in the postprocessing pipeline inserts a title “Bibliography” before the first bibliographical entry. But more can be added to alter the result. As eLyXer parses a LyX document it automatically numbers all chapters and sections. This is also done in the postprocessor.
The package post contains most postprocessing code, although some postprocessors are located in the classes of their containers for easy access.

2.3 Mathematical Formulae

Formulae in LyX are rendered beautifully into TeX and PDF documents. For HTML the conversion is not so simple. There are basically three options:
  • render the formula as an image (GIF or PNG), then import the image;
  • export a specific language called MathML
  • or render using a variety of Unicode characters, HTML and CSS wizardry [2].
eLyXer employs the third technique, with varied results. Basic fractions and square roots should be rendered fine, albeit at the moment there may be some issues pending. Complex fractions with several levels do not come out right. (But see subsection 2.4↓.)

2.4 MathML

There are two options in place to generate MathML, as suggested by Günther Milne and Abdelrazak Younes [4, 5]. Both rely on some JavaScript page manipulations, and they need to be hosted on the same server as the documents. MathJax is less mature but it has grown faster so it has become the preferred option.
To use this last option in your own pages you just have to add the --mathjax option:
$ elyxer.py --mathjax ./MathJax math.lyx math.html
You will notice that the --mathjax option requires an argument: the directory where MathJax resides. MathJax needs to live on your server; after downloading the package, deploy it to your server and give the installation directory as an argument to --mathjax.
In principle you might think of using some external installation of MathJax to avoid downloading it and serving it from your server, e.g. from Savannah:
$ elyxer.py --mathjax http://elyxer.nongnu.org/MathJax/ math.lyx math.html
This approach may not work on certain browsers for two reasons: JavaScript loaded from a different site may not work, and WebFonts are also subject to this same-origin policy. If you have made it work it would be great to hear about it.

2.5 Baskets

eLyXer supports a few distinct modes of operation. In each incarnation the tasks to do are quite different:
  • A pure filter: read from disk and write to disk each Container, keeping no context in memory.
  • In-memory processing: read a complete file, process it and write it all to disk.
  • TOC generation: output just a table of contents for a LyX document.
  • Split document generation: separates each chapter, section or subsection in a different file.
How can it do so many different tasks without changing a lot of code? The answer is in the file gen/basket.py. A Basket is an object that keeps Containers. Once a batch is ready, the Basket outputs them to disk or to some other Basket, but it may decide to just wait a little longer.
The basic Basket is the WriterBasket: it writes everything that it gets to disk immediately and then forgets about it. Some bits of state are kept around, like for example which biliography entries have been found so far, but the bulk of the memory is released.
Another more complex object is the TOCBasket: it checks if the Container is worthy to appear in a TOC, and otherwise just discards it. For chapters, sections and so on it converts them to TOC entries and outputs them to disk.
The MemoryBasket does most of its work in memory: it stores all Containers until they have all been read, then does some further processing on them and outputs an improved version of the document, at the cost of using quite more memory. This allows us for example to generate a list of figures or to set consecutive labels for bibliography entries (instead of just numbering them as they appear in the text).
The most complex kind of Basket is the SplittingBasket: it writes each document part to a separate file, choosing what parts to split depending on the configuration passed in the --splitpart option. By default it creates a TOC at the top of each page.

2.6 Hybrid Functions

Math processing is very configurable; most of it is based on configuration options found in src/conf/base.cfg. Parsing can be done using a few simple functions: commands (contained in [FormulaConfig.commands]) output some content and don’t have any parameters, while one-parameter functions (in [FormulaConfig.onefunctions]) take exactly one parameter and output an HTML tag. Thus, the definition for \bar is:
\bar:span class="bar"
Whenever eLyXer finds the command it parses a parameter, then outputs the tag <span class="bar"> surrounding the parameter. For instance: e.g. \bar{38} becomes <span class="bar">38</span> in the output. Decorating functions (in [FormulaConfig.decoratingfunctions]) place a symbol from in the definition above the parameter, and so on.
Such simple processing is not always enough; there is a generic mechanism for producing complex output from a number of parameters. They are called hybrid functions.
Each definition for a hybrid function contains: parser definition, output definition and a number of function tags. The parser definition tells eLyXer what to parse. Hybrid functions can have any number of optional parameters, denoted as [$p]; mandatory parameters are shown as {$p}. Each parameter consists of the symbol $ followed by a letter or number: $0, $p.
The output definition contains regular text, plus parameters and functions. Each function consists of the letter f plus a number, such as f0; and each is associated with a tagged HTML element. These function tags are the last part of the definition. Presently there can be as many as 10 function tags (from f0 to f9).
Let us see a simple example, equivalent to the above formula — a one-parameter, one-tag hybrid function:
\fun:[{$p},f0{$p},span class="fun"]
The only function tag f0 generates the HTML tag <span class="fun">. Whenever eLyXer finds \fun in a math formula, it will parse one parameter and put it into $p. Then it will generate f0{$p}, i.e. apply the tag <span class="fun">. Putting it all together: \fun{38} becomes <span class="fun">38</span>.
Parameters can be parsed as a literal, in which case eLyXer will take everything between the brackets without parsing it. Literal parameters can be used within a tag definition. A real life hybrid function with literal parameters:
\raisebox:[{$p!}{$1},f0{$1},span class="raisebox" style="vertical-align: $p;"]
In this case there are two mandatory parameters, the first one literal and the second one a regular TeX expression. The output is just one function tag, in this case using the first mandatory parameter. For instance, \raisebox{3cm}{5} would generate:
<span class="raisebox" style="vertical-align: 3cm;">5</span>
The parameter $p is parsed as 3cm, which is not parsed further.
Hybrid functions are easy to configure once you get the hang of it. Adding new TeX commands, even complex ones, becomes simply a matter of configuration.

3 Developing and Contributing

This chapter will show you how to further develop eLyXer and how to contribute your own code.

3.1 Distribution

You will notice that in the src/ folder there are several Python files, while in the main directory there is just a big one called elyxer.py. The reason is that before distributing the source code is coalesced and placed on the main directory, so that users can run it without worrying about libraries, directories and the such. (They need of course to have Python 2.5 installed.) And the weapon is a little Python script called coalesce.py that does the dirty job of parsing dependencies and inserting them into the main file. There is also a make Bash script that takes care of permissions and generates the documentation. Just type
$ ./make
at the prompt. This coalesces all code and configuration into elyxer.py. It is a primitive way perhaps to generate the “binary” (ok, not really a binary but a distributable Python file), but it works great.
The make script also runs all of the included tests to check that no functionality has been lost from one release to the next. These tests can also be run independently using the run-tests script:
$ ./run-tests
They are used to verify that no functionality is lost from one version to the next — although issues can certainly slip undetected if there is no test for them.
At the moment there is no way to do this packaging on non-Unix operating systems with a single script, e.g. a Windows .bat script. However the steps themselves are trivial.

3.2 Debugging

Code problems are quite difficult to debug using the full elyxer.py file. It is much better to use the uncoalesced version instead, since it is quite modular and neatly divided. To do so you just need to locate the file src/principal.py and run that instead of elyxer.py. For example, if you are in the docs/ directory and you want to convert math.lyx you can run eLyXer as:
$ ../src/principal.py math.lyx math.html
For extra debugging information you can activate the --debug option:
$ ../src/principal.py --debug math.lyx math.html
This will make any traces more meaningful and will let you follow the code much more easily.

3.3 Configuration

The make script does not just construct a single .py file from all sources; it is also used to extract the configuration in human-readable form and create a Python file which is then coalesced with all the rest. The original configuration file (the one you should modify) is called base.cfg, while the resulting Python file is called config.py.
The original configuration file uses this format:
[ContainerConfig.startendings]
\begin_deeper:\end_deeper
\begin_inset:\end_inset
\begin_layout:\end_layout
where each section header is enclosed in square brackets; it contains an object name and a section name. In the example above the object is called ContainerConfig, while the section is called startendings. Inside each section there are a number of key:value pairs separated by a colon; the key is used to reference the value in other Python code.
To create config.py go to the src/ folder and type:
$ ./exportconfig py
This will create all configuration objects to be used inside your Python code, where each section will become an object attribute containing a map. For instance, to access the first value above \end_deeper you would write in your Python code:
ContainerConfig.startendings[’\begin_deeper’]
Each section can contain as many values as needed.

3.4 License

eLyXer is published under the GPL, version 3 or later [3]. This basically means that you can modify the code and distribute the result as desired, as long as you publish your modifications under the same license. But consult a lawyer if you want an authoritative opinion.

3.5 Contributions

All contributions will be published under this same license, so if you send them this way you implicitly give your consent. An explicit license grant would be even better and may be required for larger contributions.
Please send any suggestions, patches, ideas and whatever else related to development to the mailing list. (Alternatively you may contact elyxer@gmail.com privately.) If you are willing to create a patch and submit it, you should patch against the proper sources in src/ and send it to the list. This will make everyone’s lives better than if you patch against elyxer.py.
The first external patches have started arriving during late 2009 and early 2010 (provided by Olivier Ripoll, Geremy Condra and Simon South). You can join in the fun!

4 Roadmap

You can see what user features are planned for the near feature in the wish list.
After the release of eLyXer 1.0, the goal is full LyX document support; any deviation from the output of LyX on e.g. PDF will be considered as bugs. (Keep in mind that some deviations arise in an inherent limitation in the design of eLyXer, and these will logically not be considered as bugs.)
For eLyXer 1.3.0 there are plans to convert it into a proper Python package so it can be installed using full source code (and not a coalesced script elyxer.py that contains everything). Also, once ERTs are parsed, eLyXer might be extended for 1.3.0 to translate generic LaTeX documents.
All this within the usual constraints: day job, family, etc.

5 Discarded Bits

Some features suggested for eLyXer have been discarded; they do not fit with the design of eLyXer or are too much effort for the proposed gains.

5.1 Spellchecking

LyX can use a spellchecker to verify the words used. However it is not interactive so you may forget to run it before generating a version. It is possible to integrate eLyXer with a spellchecker and verify the spelling before generating the HTML, but it is not clear that it can be done cleanly.

5.2 URL Checking

Another fun possibility is to make eLyXer check all the external URLs embedded in the document. However the Python facilities for URL checking are not very mature, at least with Python 2.5: some of them do not return errors, others throw complex exceptions that have to be parsed… It is far easier to just create the HTML page and use wget (or a similar tool) to recursively check all links in the page.

5.3 Use of lyx2lyx Framework

Abdelrazak Younes suggests using the lyx2lyx framework, which after all already knows about LyX formats [5]. It is an interesting suggestion, but one that for now does not fit well with the design of eLyXer: a standalone tool to convert between two formats, or as Kernighan and Plauger put it, a standalone filter [6]. Long-term maintenance might result a bit heavier with this approach though, especially if LyX changes to a different file format in the future.

6 FAQ

Q: I don’t like how your tool outputs my document, what can I do?
A: First make sure that you are using the proper CSS file, i.e. copy the existing docs/lyx.css file to your web page directory. Next try to customize the CSS file to your liking; it is a flexible approach that requires no code changes. Then try changing the code (and submitting the patch back).
Q: How is the code maintained?
A: It is kept in a git repository on Savannah. Patches in git format are welcome (but keep in mind that my knowledge of git is even shallower than my Python skills).
Q: I found a bug, what should I do?
A: Just report it to the Savannah interface, to the mailing list or directly to the main author.

Nomenclature

class A self-contained piece of code that hosts attributes (values) and methods (functions).
filter A type of program that reads from a file and writes to another file, keeping in memory only what is needed short term.
TOC Table of contents

References

[1] Free Software Foundation, Inc.: eLyXer summary. https://savannah.nongnu.org/projects/elyxer/

[2] S White: “Math in HTML with CSS”, accessed March 2009. http://www.zipcon.net/~swhite/docs/math/math.html

[3] R S Stallman et al: “GNU GENERAL PUBLIC LICENSE” version 3, 20070629. http://www.gnu.org/copyleft/gpl.html

[4] G Milde: “Re: eLyXer: LyX to HTML converter”, message to list lyx-devel, 20090309. http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg148627.html

[5] A Younes: “Re: eLyXer: LyX to HTML converter”, message to list lyx-devel, 20090309. http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg148634.html

[6] B W Kernighan, P J Plauger: “Software Tools”, ed. Addison-Wesley Professional 1976, p. 35.

[7] Various authors: “lyx-devel mailing list”, accessed November 2009. http://www.mail-archive.com/lyx-devel@lists.lyx.org/

[8] S Chacon: “Git — Download”, accessed November 2009. http://git-scm.com/download

[9] Python community: “Download Python”, accessed November 2009. http://www.python.org/download/

elyxer-1.2.5/docs/devguide.lyx0000644000175000017500000017172212074107030015623 0ustar chennochenno#LyX 1.6.7 created this file. For more info see http://www.lyx.org/ \lyxformat 345 \begin_document \begin_header \textclass article \begin_preamble % eLyXer -- convert LyX source files to HTML output. % % Copyright (C) 2009-2011 Alex Fernández % % This program is free software: 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 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 % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . \end_preamble \use_default_options false \language english \inputencoding auto \font_roman default \font_sans default \font_typewriter default \font_default_family default \font_sc false \font_osf false \font_sf_scale 100 \font_tt_scale 100 \graphics default \paperfontsize default \spacing single \use_hyperref false \papersize default \use_geometry false \use_amsmath 1 \use_esint 1 \cite_engine basic \use_bibtopic false \paperorientation portrait \secnumdepth 3 \tocdepth 3 \paragraph_separation indent \defskip medskip \quotes_language english \papercolumns 1 \papersides 1 \paperpagestyle default \tracking_changes false \output_changes false \author "" \author "" \end_header \begin_body \begin_layout Title \begin_inset Graphics filename elyxer.svg lyxscale 50 \end_inset eLyXer Developer Guide \end_layout \begin_layout Author Alex Fernández (elyxer@gmail.com) \end_layout \begin_layout Standard \begin_inset CommandInset toc LatexCommand tableofcontents \end_inset \end_layout \begin_layout Section The Basics \end_layout \begin_layout Standard This document should help you get started if you want to understand how eLyXer works, and maybe extending its functionality. The package (including this guide and all accompanying materials) is licensed under the \begin_inset CommandInset href LatexCommand href name "GPL version 3" target "http://www.gnu.org/licenses/gpl-3.0-standalone.html" \end_inset or, at your option, any later version. See the \family typewriter LICENSE \family default file for details. Also visit the \begin_inset CommandInset href LatexCommand href name "main page" target "index.html" \end_inset to find out about the latest developments. \end_layout \begin_layout Standard In this first section we will outline how eLyXer performs the basic tasks. Next section will be devoted to more arcane matters. The third section explains how to contribute to eLyXer, while the fourth one deals with future planned extensions. The fifth section includes things that will probably \emph on not \emph default be implemented. Finally there is a FAQ that contains answers to questions asked privately and on the lyx-devel list \begin_inset CommandInset citation LatexCommand cite key "lyx-devel" \end_inset . \end_layout \begin_layout Subsection Getting eLyXer \end_layout \begin_layout Standard If you are interested in eLyXer from a developer perspective the first thing to do is fetch the code. It is included in the standard distribution, so just navigate to the \family typewriter src/ \family default folder and take a look at the \family typewriter .py \family default Python code files. \end_layout \begin_layout Standard For more serious use, or if your distribution did not carry the source code, or perhaps to get the latest copy of the code: you need to install the tool \family typewriter git \family default , created by Linus Torvalds (of Linux fame) \begin_inset CommandInset citation LatexCommand cite key "git-download" \end_inset . You will also need to have Python installed; versions at or above 2.4 should be fine \begin_inset CommandInset citation LatexCommand cite key "python-download" \end_inset . The code is hosted in Savannah \begin_inset CommandInset citation LatexCommand cite key "savannah-elyxer" \end_inset , a GNU project for hosting non-GNU projects. So first you have to fetch the code: \end_layout \begin_layout LyX-Code \color blue $ \color inherit git clone git://git.sv.gnu.org/elyxer.git \end_layout \begin_layout Standard You should see some output similar to this: \end_layout \begin_layout LyX-Code Initialized empty Git repository in /home/user/install/elyxer/.git/ \end_layout \begin_layout LyX-Code remote: Counting objects: 528, done. \end_layout \begin_layout LyX-Code remote: Compressing objects: 100% (157/157), done. \end_layout \begin_layout LyX-Code remote: Total 528 (delta 371), reused 528 (delta 371) \end_layout \begin_layout LyX-Code Receiving objects: 100% (528/528), 150.00 KiB | 140 KiB/s, done. \end_layout \begin_layout LyX-Code Resolving deltas: 100% (371/371), done. \end_layout \begin_layout Standard Now enter the directory that \family typewriter git \family default has created. \end_layout \begin_layout LyX-Code \color blue $ \color inherit cd elyxer \end_layout \begin_layout Standard Your first task is to create the main executable file: \end_layout \begin_layout LyX-Code \color blue $ \color inherit ./make \end_layout \begin_layout Standard The build system for eLyXer will compile it for you, and even run some basic tests. (We will see later on section \begin_inset CommandInset ref LatexCommand ref reference "sub:Distribution" \end_inset how this \begin_inset Quotes eld \end_inset compilation \begin_inset Quotes erd \end_inset is done.) Now you can try it out: \end_layout \begin_layout LyX-Code \color blue $ \color inherit cd docs/ \end_layout \begin_layout LyX-Code \color blue $ \color inherit ../elyxer.py devguide.lyx devguide2.html \end_layout \begin_layout Standard You have just created your first eLyXer page! The result is in \family typewriter devguide2.html \family default ; to view it in Firefox: \end_layout \begin_layout LyX-Code \color blue $ \color inherit firefox-bin devguide2.html \end_layout \begin_layout Standard If you want to debug eLyXer then it is better to run it from the source code folder, instead of the compiled version. For this you need to make just a small change, instead of \family typewriter elyxer.py \family default run \family typewriter src/principal.py \family default : \end_layout \begin_layout LyX-Code \color blue $ \color inherit ../src/principal.py --debug devguide.lyx devguide2.html \end_layout \begin_layout Standard and you will see the internal debug messages. \end_layout \begin_layout Standard Note for Windows developers: on Windows eLyXer needs to be invoked using the Python executable, and of course changing the slashes to backward-slashes: \end_layout \begin_layout LyX-Code \color blue > \color inherit Python .. \backslash elyxer.py devguide.lyx devguide2.html \end_layout \begin_layout Standard or for the source code version: \end_layout \begin_layout LyX-Code \color blue > \color inherit Python .. \backslash src \backslash elyxer.py devguide.lyx devguide2.html \end_layout \begin_layout Standard If you want to install the created version you just have to run the provided install script as root: \end_layout \begin_layout LyX-Code \color blue # \color inherit ./install \end_layout \begin_layout Standard Once eLyXer has been installed it can be invoked as any other Unix command: \end_layout \begin_layout LyX-Code \color blue $ \color inherit elyxer.py devguide.lyx devguide3.html \end_layout \begin_layout Standard In the rest of this section we will delve a little bit into how eLyXer works. \end_layout \begin_layout Subsection \family typewriter Container \family default s \end_layout \begin_layout Standard The basic code artifact (or `class \begin_inset CommandInset nomenclature LatexCommand nomenclature symbol "class" description "A self-contained piece of code that hosts attributes (values) and methods (functions)." \end_inset ' in Python talk) is the \family typewriter Container \family default , located in the \family typewriter gen \family default package (file \family typewriter src/gen/Container.py \family default ). Its responsibility is to take a bit of LyX code and generate working HTML code. This includes (with the aid of some helper classes): reading from file a few lines, converting it to HTML, and writing the lines back to a second file. \end_layout \begin_layout Standard The following figure \begin_inset CommandInset ref LatexCommand ref reference "fig:Container-structure" \end_inset shows how a \family typewriter Container \family default works. Each type of \family typewriter Container \family default should have a \family typewriter parser \family default and an \family typewriter output \family default , and a list of \family typewriter contents \family default . The \family typewriter parser \family default object receives LyX input and produces a list of \family typewriter contents \family default that is stored in the \family typewriter Container \family default . The \family typewriter output \family default object then converts those \family typewriter contents \family default to a portion of valid HTML code. \end_layout \begin_layout Standard \begin_inset Float figure wide false sideways false status open \begin_layout Plain Layout \align center \begin_inset Graphics filename container.svg \end_inset \end_layout \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout \begin_inset CommandInset label LatexCommand label name "fig:Container-structure" \end_inset Container structure. \end_layout \end_inset \end_layout \end_inset \end_layout \begin_layout Standard Two important class attributes of a \family typewriter Container \family default are: \end_layout \begin_layout Itemize \family typewriter start \family default : a string of text containing the LyX command that we are about to process; \end_layout \begin_layout Itemize and \family typewriter ending \family default , which is used on some \family typewriter Container \family default s to determine when to stop parsing. \end_layout \begin_layout Standard A class called \family typewriter ContainerFactory \family default has the responsibility of creating the appropriate containers, as the strings in their \family typewriter start \family default attributes are found. \end_layout \begin_layout Standard The basic method of a \family typewriter Container \family default is: \end_layout \begin_layout Itemize \family typewriter process() \family default : called after parsing the LyX text and before outputting the HTML result. Here the \family typewriter Container \family default can alter its \family typewriter contents \family default as needed, once everything has been read and before it is output. \end_layout \begin_layout Standard Now we will see each subordinate class in detail. \end_layout \begin_layout Subsection \family typewriter Parser \family default s \end_layout \begin_layout Standard The package \family typewriter parse \family default contains almost all parsing code; it has been isolated on purpose so that LyX format changes can be tackled just by changing the code in that directory. \end_layout \begin_layout Standard A \family typewriter Parser \family default has two main methods: \family typewriter parseheader() \family default and \family typewriter parse() \family default . \end_layout \begin_layout Description \family typewriter parseheader() \family default : parses the first line and returns the contents as a list of words. This method is common for all \family typewriter Parser \family default s. For example, for the command \family typewriter ' \backslash \backslash emph on' \family default the \family typewriter Parser \family default will return a list \family typewriter [' \backslash \backslash emph','on'] \family default . This list will end up in the \family typewriter Container \family default as an attribute \family typewriter header \family default . \end_layout \begin_layout Description \family typewriter parse() \family default : parses all the remaining lines of the command. They will end up in the \family typewriter Container \family default as an attribute \family typewriter contents \family default . This method depends on the particular \family typewriter Parser \family default employed. \end_layout \begin_layout Standard Basic \family typewriter Parser \family default s reside in the file \family typewriter parser.py \family default . Among them are the following usual classes: \end_layout \begin_layout Description \family typewriter LoneCommand \family default : parses a single line containing a LyX command. \end_layout \begin_layout Description \family typewriter BoundedParser \family default : reads until it finds the \family typewriter ending \family default . For each line found within, the \family typewriter BoundedParser \family default will call the \family typewriter ContainerFactory \family default to recursively parse its contents. The parser then returns everything found inside as a list. \end_layout \begin_layout Subsection Outputs \end_layout \begin_layout Standard Common outputs reside in \family typewriter output.py \family default . They have just one method: \end_layout \begin_layout Description \family typewriter gethtml() \family default : processes the contents of a \family typewriter Container \family default and returns a list with file lines. Carriage returns \family typewriter \backslash n \family default must be added manually at the desired points; eLyXer will just merge all lines and write them to file. \end_layout \begin_layout Standard Outputs do not however inherit from a common class; all you need is an object with a method \family typewriter gethtml(self,container) \family default that processes the \family typewriter Container \family default 's \family typewriter contents \family default (as a list attribute). An output can also use all attributes of a \family typewriter Container \family default to do their job. \end_layout \begin_layout Subsection Tutorial: Adding Your Own \family typewriter Container \end_layout \begin_layout Standard If you want to add your own \family typewriter Container \family default to the processing you do not need to modify all these files. You just need to create your own source file that includes the \family typewriter Container \family default , the \family typewriter Parser \family default and the \family typewriter output \family default (or reuse existing ones). Once it is added to the \family typewriter types \family default in the \family typewriter ContainerFactory \family default eLyXer will happily start matching it against LyX commands as they are parsed. \end_layout \begin_layout Standard There are good examples of parsing commands in just one file in \family typewriter image.py \family default and \family typewriter formula.py \family default . But let us build our own container \family typewriter BibitemInset \family default here. We want to parse the LyX command in listing \begin_inset CommandInset ref LatexCommand ref reference "alg:bibitem-command" \end_inset . In the resulting HTML we will generate an anchor: a single tag \family typewriter \family default with fixed text \family typewriter "[ref]" \family default . \end_layout \begin_layout Standard \begin_inset Float algorithm wide false sideways false status open \begin_layout Quotation \family typewriter \backslash begin_inset CommandInset bibitem \end_layout \begin_layout Quotation \family typewriter LatexCommand bibitem \end_layout \begin_layout Quotation \family typewriter key "mykey" \end_layout \begin_layout Quotation \family typewriter \backslash end_inset \end_layout \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout \begin_inset CommandInset label LatexCommand label name "alg:bibitem-command" \end_inset The LyX command to parse. \end_layout \end_inset \end_layout \end_inset \end_layout \begin_layout Standard We will call the \family typewriter Container \family default \family typewriter BibitemInset \family default , and it will process precisely the inset that we have here. We will place the class in \family typewriter bibitem.py \family default . So this file starts as shown in listing \begin_inset CommandInset ref LatexCommand ref reference "alg:bibitem-class" \end_inset . \end_layout \begin_layout Standard \begin_inset Float algorithm wide false sideways false status open \begin_layout Quotation \family typewriter class BibitemInset(Container): \end_layout \begin_layout Quotation \family typewriter \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset "An inset containing a bibitem command" \end_layout \begin_layout Quotation \family typewriter \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \end_layout \begin_layout Quotation \family typewriter \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset start = ' \backslash \backslash begin_inset CommandInset bibitem' \end_layout \begin_layout Quotation \family typewriter \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset ending = ' \backslash \backslash end_inset' \end_layout \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout \begin_inset CommandInset label LatexCommand label name "alg:bibitem-class" \end_inset Class definition for \family typewriter BibitemInset \family default . \end_layout \end_inset \end_layout \end_inset \end_layout \begin_layout Standard We can use the parser for a bounded command with start and ending, \family typewriter BoundedParser \family default . For the output we will generate a single HTML tag \family typewriter \family default , so the \family typewriter TagOutput() \family default is appropriate. Finally we will set the \family typewriter breaklines \family default attribute to \family typewriter False \family default , so that the output shows the tag in the same line as the contents: \family typewriter [ref] \family default . Listing \begin_inset CommandInset ref LatexCommand ref reference "alg:bibitem-init" \end_inset shows the constructor. \end_layout \begin_layout Standard \begin_inset Float algorithm wide false sideways false status open \begin_layout Quotation \family typewriter \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset def __init__(self): \end_layout \begin_layout Quotation \family typewriter \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset self.parser = BoundedParser() \end_layout \begin_layout Quotation \family typewriter \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset self.output = TagOutput() \end_layout \begin_layout Quotation \family typewriter \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset self.tag = 'a' \end_layout \begin_layout Quotation \family typewriter \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset self.breaklines = False \end_layout \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout \begin_inset CommandInset label LatexCommand label name "alg:bibitem-init" \end_inset Constructor for \family typewriter BibitemInset \family default . \end_layout \end_inset \end_layout \end_inset \end_layout \begin_layout Standard The \family typewriter BoundedParser \family default will automatically parse the header and the contents. In the \family typewriter process() \family default method we will discard the first line with the \family typewriter LatexCommand \family default , and place the key from the second line as link destination. The class \family typewriter StringContainer \family default holds string constants; in our case we will have to isolate the key by splitting the string around the double quote \family typewriter " \family default , and then access the anchor with the same name. The contents will be set to the fixed string \family typewriter [ref] \family default . The result is shown in listing \begin_inset CommandInset ref LatexCommand ref reference "alg:bibitem-process" \end_inset . \end_layout \begin_layout Standard \begin_inset Float algorithm wide false sideways false status open \begin_layout Quotation \family typewriter \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset def process(self): \end_layout \begin_layout Quotation \family typewriter \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset #skip first line \end_layout \begin_layout Quotation \family typewriter \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset del self.contents[0] \end_layout \begin_layout Quotation \family typewriter \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset # parse second line: fixed string \end_layout \begin_layout Quotation \family typewriter \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset string = self.contents[0] \end_layout \begin_layout Quotation \family typewriter \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset # split around the " \end_layout \begin_layout Quotation \family typewriter \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset key = string.contents[0].split('"')[1] \end_layout \begin_layout Quotation \family typewriter \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset # make tag and contents \end_layout \begin_layout Quotation \family typewriter \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset self.tag = 'a name="' + key + '"' \end_layout \begin_layout Quotation \family typewriter \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset string.contents[0] = '[ref] ' \end_layout \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout \begin_inset CommandInset label LatexCommand label name "alg:bibitem-process" \end_inset Processing for \family typewriter BibitemInset \family default . \end_layout \end_inset \end_layout \end_inset \end_layout \begin_layout Standard And then we have to add the new class to the types parsed by the \family typewriter ContainerFactory \family default ; this has to be done outside the class definition. The complete file is shown in listing \begin_inset CommandInset ref LatexCommand ref reference "alg:bibitem-complete" \end_inset . \end_layout \begin_layout Standard \begin_inset Float algorithm wide false sideways false status open \begin_layout Quotation \family typewriter from parser import * \end_layout \begin_layout Quotation \family typewriter from output import * \end_layout \begin_layout Quotation \family typewriter from container import * \end_layout \begin_layout Quotation \family typewriter \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \end_layout \begin_layout Quotation \family typewriter class BibitemInset(Container): \end_layout \begin_layout Quotation \family typewriter \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset "An inset containing a bibitem command" \end_layout \begin_layout Quotation \family typewriter \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \end_layout \begin_layout Quotation \family typewriter \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset start = ' \backslash \backslash begin_inset CommandInset bibitem' \end_layout \begin_layout Quotation \family typewriter \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset ending = ' \backslash \backslash end_inset' \end_layout \begin_layout Quotation \family typewriter \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \end_layout \begin_layout Quotation \family typewriter \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset def __init__(self): \end_layout \begin_layout Quotation \family typewriter \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset self.parser = BoundedParser() \end_layout \begin_layout Quotation \family typewriter \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset self.output = TagOutput() \end_layout \begin_layout Quotation \family typewriter \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset self.breaklines = False \end_layout \begin_layout Quotation \family typewriter \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \end_layout \begin_layout Quotation \family typewriter \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset def process(self): \end_layout \begin_layout Quotation \family typewriter \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset #skip first line \end_layout \begin_layout Quotation \family typewriter \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset del self.contents[0] \end_layout \begin_layout Quotation \family typewriter \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset # parse second line: fixed string \end_layout \begin_layout Quotation \family typewriter \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset string = self.contents[0] \end_layout \begin_layout Quotation \family typewriter \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset # split around the " \end_layout \begin_layout Quotation \family typewriter \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset key = string.contents[0].split('"')[1] \end_layout \begin_layout Quotation \family typewriter \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset # make tag and contents \end_layout \begin_layout Quotation \family typewriter \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset self.tag = 'a name="' + key + '"' \end_layout \begin_layout Quotation \family typewriter \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset string.contents[0] = '[ref] ' \end_layout \begin_layout Quotation \family typewriter \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \end_layout \begin_layout Quotation \family typewriter ContainerFactory.types.append(BibitemInset) \end_layout \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout \begin_inset CommandInset label LatexCommand label name "alg:bibitem-complete" \end_inset Full listing for \family typewriter BibitemInset \family default . \end_layout \end_inset \end_layout \end_inset \end_layout \begin_layout Standard The end result of processing the command in listing \begin_inset CommandInset ref LatexCommand ref reference "alg:bibitem-command" \end_inset is a valid anchor: \end_layout \begin_layout Quotation \family typewriter [ref] \end_layout \begin_layout Standard The final touch is to make sure that the class is run, importing it in the file \family typewriter gen/factory.py \family default , as shown in listing \begin_inset CommandInset ref LatexCommand ref reference "alg:bibitem-include" \end_inset . This ensures that the \family typewriter ContainerFactory \family default will know what to do when it finds an element that corresponds to the \family typewriter BibitemInset \family default . \end_layout \begin_layout Standard \begin_inset Float algorithm wide false sideways false status open \begin_layout Quotation \family typewriter \SpecialChar \ldots{} \end_layout \begin_layout Quotation \family typewriter from structure import * \end_layout \begin_layout Quotation \family typewriter \series bold from bibitem import * \end_layout \begin_layout Quotation \family typewriter from container import * \end_layout \begin_layout Quotation \family typewriter \SpecialChar \ldots{} \end_layout \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout \begin_inset CommandInset label LatexCommand label name "alg:bibitem-include" \end_inset Importing the \family typewriter BibitemInset \family default from the factory file. \end_layout \end_inset \end_layout \end_inset \end_layout \begin_layout Standard Now this \series bold Container \series default is not too refined: the link text is fixed, and we need to do additional processing on the bibitem entry to show consecutive numbers. The approach is not very flexible either: e.g. anchor text is fixed. But in less than 20 lines we have parsed a new LyX command and have outputted valid, working XHTML code. The actual code is a bit different but follows the same principles; it can be found in \family typewriter src/bib/biblio.py \family default : in the classes \family typewriter BiblioCite \family default and \family typewriter BiblioEntry \family default , and it processes bibliography entries and citations (with all our missing bits) in about 50 lines. \end_layout \begin_layout Section Advanced Features \end_layout \begin_layout Standard This section tackles other, more complex features; all of them are included in current versions. \end_layout \begin_layout Subsection Parse Tree \begin_inset CommandInset label LatexCommand label name "sub:Parse-Tree" \end_inset \end_layout \begin_layout Standard On initialization of the \family typewriter ContainerFactory \family default , a \family typewriter ParseTree \family default is created to quickly pass each incoming LyX command to the appropriate containers, which are created on demand. For example, when the \family typewriter ContainerFactory \family default finds a command: \end_layout \begin_layout Quotation \family typewriter \backslash \backslash emph on \end_layout \begin_layout Standard it will create and initialize an \family typewriter EmphaticText \family default object. The \family typewriter ParseTree \family default works with words: it creates a tree where each keyword has its own node. At that node there may be a leaf, which is a \family typewriter Container \family default class, and/or additional branches that point to other nodes. If the tree finds a \family typewriter Container \family default leaf at the last node then it has found the right point; otherwise it must backtrack to the last node with a \family typewriter Container \family default leaf. \end_layout \begin_layout Standard Figure \begin_inset CommandInset ref LatexCommand ref reference "fig:parsetree" \end_inset shows a piece of the actual parse tree. You can see how if the string to parse is \family typewriter \backslash begin_inset LatexCommand \family default , at the node for the second keyword \family typewriter LatexCommand \family default there is no leaf, just two more branches \family typewriter label \family default and \family typewriter ref \family default . In this case the \family typewriter ParseTree \family default would backtrack to \family typewriter begin_inset \family default , and choose the generic \family typewriter Inset \family default . \end_layout \begin_layout Standard \begin_inset Float figure wide false sideways false status open \begin_layout Plain Layout \align center \begin_inset Graphics filename parse tree.svg \end_inset \end_layout \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout \begin_inset CommandInset label LatexCommand label name "fig:parsetree" \end_inset Portion of the parse tree. \end_layout \end_inset \end_layout \end_inset \end_layout \begin_layout Standard Parsing is much faster this way, but there are disadvantages; for one, parsing can only be done using whole words and not prefixes. SGML tags (such as \family typewriter \family default ) pose particular problems: sometimes they may appear with attributes (as in \family typewriter \family default ), and in this case the starting word is \family typewriter ' \family default character. So the parse tree removes any trailing \family typewriter '>' \family default , and the start string would be just \family typewriter \family default and \family typewriter \family default surrounding the parameter. For instance: e.g. \family typewriter \backslash bar{38} \family default becomes \family typewriter 38 \family default in the output. Decorating functions (in \family typewriter [FormulaConfig.decoratingfunctions] \family default ) place a symbol from in the definition above the parameter, and so on. \end_layout \begin_layout Standard Such simple processing is not always enough; there is a generic mechanism for producing complex output from a number of parameters. They are called hybrid functions. \end_layout \begin_layout Standard Each definition for a hybrid function contains: parser definition, output definition and a number of function tags. The parser definition tells eLyXer what to parse. Hybrid functions can have any number of optional parameters, denoted as \family typewriter [$p] \family default ; mandatory parameters are shown as \family typewriter {$p} \family default . Each parameter consists of the symbol \family typewriter $ \family default followed by a letter or number: \family typewriter $0 \family default , \family typewriter $p \family default . \end_layout \begin_layout Standard The output definition contains regular text, plus parameters and functions. Each function consists of the letter \family typewriter f \family default plus a number, such as \family typewriter f0 \family default ; and each is associated with a tagged HTML element. These function tags are the last part of the definition. Presently there can be as many as 10 function tags (from \family typewriter f0 \family default to \family typewriter f9 \family default ). \end_layout \begin_layout Standard Let us see a simple example, equivalent to the above formula -- a one-parameter, one-tag hybrid function: \end_layout \begin_layout Standard \begin_inset listings inline false status open \begin_layout Plain Layout \backslash fun:[{$p},f0{$p},span class="fun"] \end_layout \end_inset \end_layout \begin_layout Standard The only function tag \family typewriter f0 \family default generates the HTML tag \family typewriter \family default . Whenever eLyXer finds \family typewriter \backslash fun \family default in a math formula, it will parse one parameter and put it into \family typewriter $p \family default . Then it will generate \family typewriter f0{$p} \family default , i.e. apply the tag \family typewriter \family default . Putting it all together: \family typewriter \backslash fun{38} \family default becomes \family typewriter 38 \family default . \end_layout \begin_layout Standard Parameters can be parsed as a literal, in which case eLyXer will take everything between the brackets without parsing it. Literal parameters can be used within a tag definition. A real life hybrid function with literal parameters: \end_layout \begin_layout Standard \begin_inset listings inline false status open \begin_layout Plain Layout \backslash raisebox:[{$p!}{$1},f0{$1},span class="raisebox" style="vertical-align: $p;"] \end_layout \end_inset \end_layout \begin_layout Standard In this case there are two mandatory parameters, the first one literal and the second one a regular TeX expression. The output is just one function tag, in this case using the first mandatory parameter. For instance, \family typewriter \backslash raisebox{3cm}{5} \family default would generate: \end_layout \begin_layout Standard \begin_inset listings inline false status open \begin_layout Plain Layout 5 \end_layout \end_inset \end_layout \begin_layout Standard The parameter \family typewriter $p \family default is parsed as \family typewriter 3cm \family default , which is not parsed further. \end_layout \begin_layout Standard Hybrid functions are easy to configure once you get the hang of it. Adding new TeX commands, even complex ones, becomes simply a matter of configuration. \end_layout \begin_layout Section Developing and Contributing \end_layout \begin_layout Standard This chapter will show you how to further develop eLyXer and how to contribute your own code. \end_layout \begin_layout Subsection Distribution \begin_inset CommandInset label LatexCommand label name "sub:Distribution" \end_inset \end_layout \begin_layout Standard You will notice that in the \family typewriter src/ \family default folder there are several Python files, while in the main directory there is just a big one called \family typewriter elyxer.py \family default . The reason is that before distributing the source code is coalesced and placed on the main directory, so that users can run it without worrying about libraries, directories and the such. (They need of course to have Python 2.5 installed.) And the weapon is a little Python script called \family typewriter coalesce.py \family default that does the dirty job of parsing dependencies and inserting them into the main file. There is also a \family typewriter make \family default Bash script that takes care of permissions and generates the documentation. Just type \end_layout \begin_layout Quotation \family typewriter \color blue $ \color inherit ./make \end_layout \begin_layout Standard at the prompt. This coalesces all code and configuration into \family typewriter elyxer.py \family default . It is a primitive way perhaps to generate the \begin_inset Quotes eld \end_inset binary \begin_inset Quotes erd \end_inset (ok, not really a binary but a distributable Python file), but it works great. \end_layout \begin_layout Standard The \family typewriter make \family default script also runs all of the included tests to check that no functionality has been lost from one release to the next. These tests can also be run independently using the run-tests script: \end_layout \begin_layout Quotation \family typewriter \color blue $ \color inherit ./run-tests \end_layout \begin_layout Standard They are used to verify that no functionality is lost from one version to the next -- although issues can certainly slip undetected if there is no test for them. \end_layout \begin_layout Standard At the moment there is no way to do this packaging on non-Unix operating systems with a single script, e.g. a Windows \family typewriter .bat \family default script. However the steps themselves are trivial. \end_layout \begin_layout Subsection Debugging \end_layout \begin_layout Standard Code problems are quite difficult to debug using the full \family typewriter elyxer.py \family default file. It is much better to use the uncoalesced version instead, since it is quite modular and neatly divided. To do so you just need to locate the file \family typewriter src/principal.py \family default and run that instead of \family typewriter elyxer.py \family default . For example, if you are in the \family typewriter docs/ \family default directory and you want to convert \family typewriter math.lyx \family default you can run eLyXer as: \end_layout \begin_layout Quotation \family typewriter \color blue $ \color inherit ../src/principal.py math.lyx math.html \end_layout \begin_layout Standard For extra debugging information you can activate the --debug option: \end_layout \begin_layout Quotation \family typewriter \color blue $ \color inherit ../src/principal.py --debug math.lyx math.html \end_layout \begin_layout Standard This will make any traces more meaningful and will let you follow the code much more easily. \end_layout \begin_layout Subsection Configuration \begin_inset CommandInset label LatexCommand label name "sub:Configuration" \end_inset \end_layout \begin_layout Standard The make script does not just construct a single \family typewriter .py \family default file from all sources; it is also used to extract the configuration in human-readable form and create a Python file which is then coalesced with all the rest. The original configuration file (the one you should modify) is called \family typewriter base.cfg \family default , while the resulting Python file is called \family typewriter config.py \family default . \end_layout \begin_layout Standard The original configuration file uses this format: \end_layout \begin_layout Standard \begin_inset listings inline false status open \begin_layout Plain Layout [ContainerConfig.startendings] \end_layout \begin_layout Plain Layout \backslash begin_deeper: \backslash end_deeper \end_layout \begin_layout Plain Layout \backslash begin_inset: \backslash end_inset \end_layout \begin_layout Plain Layout \backslash begin_layout: \backslash end_layout \end_layout \end_inset \end_layout \begin_layout Standard where each section header is enclosed in square brackets; it contains an object name and a section name. In the example above the object is called \family typewriter ContainerConfig \family default , while the section is called \family typewriter startendings \family default . Inside each section there are a number of \family typewriter key:value \family default pairs separated by a colon; the key is used to reference the value in other Python code. \end_layout \begin_layout Standard To create \family typewriter config.py \family default go to the \family typewriter src/ \family default folder and type: \end_layout \begin_layout Quotation \family typewriter \color blue $ \color inherit ./exportconfig py \end_layout \begin_layout Standard This will create all configuration objects to be used inside your Python code, where each section will become an object attribute containing a map. For instance, to access the first value above \family typewriter \backslash end_deeper \family default you would write in your Python code: \end_layout \begin_layout Quotation \family typewriter ContainerConfig.startendings[' \backslash begin_deeper'] \end_layout \begin_layout Standard Each section can contain as many values as needed. \end_layout \begin_layout Subsection License \end_layout \begin_layout Standard eLyXer is published under the GPL, version 3 or later \begin_inset CommandInset citation LatexCommand cite key "stallman-gplv3" \end_inset . This basically means that you can modify the code and distribute the result as desired, as long as you publish your modifications under the same license. But consult a lawyer if you want an authoritative opinion. \end_layout \begin_layout Subsection Contributions \end_layout \begin_layout Standard All contributions will be published under this same license, so if you send them this way you implicitly give your consent. An explicit license grant would be even better and may be required for larger contributions. \end_layout \begin_layout Standard Please send any suggestions, patches, ideas and whatever else related to development to the \begin_inset CommandInset href LatexCommand href name "mailing list" target "elyxer-users@nongnu.org" type "mailto:" \end_inset . (Alternatively you may contact \begin_inset CommandInset href LatexCommand href name "elyxer@gmail.com" target "elyxer@gmail.com" type "mailto:" \end_inset privately.) If you are willing to create a patch and submit it, you should patch against the proper sources in \family typewriter src/ \family default and send it to the list. This will make everyone's lives better than if you patch against \family typewriter elyxer.py \family default . \end_layout \begin_layout Standard The first external patches have started arriving during late 2009 and early 2010 (provided by Olivier Ripoll, Geremy Condra and Simon South). You can join in the fun! \end_layout \begin_layout Section Roadmap \end_layout \begin_layout Standard You can see what user features are planned for the near feature in the \begin_inset CommandInset href LatexCommand href name "wish list" target "userguide.html#sub:Wish-List" \end_inset . \end_layout \begin_layout Standard After the release of eLyXer 1.0, the goal is full LyX document support; any deviation from the output of LyX on e.g. PDF will be considered as bugs. (Keep in mind that some deviations arise in an inherent limitation in the design of eLyXer, and these will logically not be considered as bugs.) \end_layout \begin_layout Standard For eLyXer 1.3.0 there are plans to convert it into a proper Python package so it can be installed using full source code (and not a coalesced script \family typewriter elyxer.py \family default that contains everything). Also, once ERTs are parsed, eLyXer might be extended for 1.3.0 to translate generic LaTeX documents. \end_layout \begin_layout Standard All this within the usual constraints: day job, family, etc. \end_layout \begin_layout Section Discarded Bits \end_layout \begin_layout Standard Some features suggested for eLyXer have been discarded; they do not fit with the design of eLyXer or are too much effort for the proposed gains. \end_layout \begin_layout Subsection Spellchecking \end_layout \begin_layout Standard LyX can use a spellchecker to verify the words used. However it is not interactive so you may forget to run it before generating a version. It is possible to integrate eLyXer with a spellchecker and verify the spelling before generating the HTML, but it is not clear that it can be done cleanly. \end_layout \begin_layout Subsection URL Checking \end_layout \begin_layout Standard Another fun possibility is to make eLyXer check all the external URLs embedded in the document. However the Python facilities for URL checking are not very mature, at least with Python 2.5: some of them do not return errors, others throw complex exceptions that have to be parsed\SpecialChar \ldots{} It is far easier to just create the HTML page and use wget (or a similar tool) to recursively check all links in the page. \end_layout \begin_layout Subsection Use of \family typewriter lyx2lyx \family default Framework \end_layout \begin_layout Standard Abdelrazak Younes suggests using the \family typewriter lyx2lyx \family default framework, which after all already knows about LyX formats \begin_inset CommandInset citation LatexCommand cite key "younes-elyxer" \end_inset . It is an interesting suggestion, but one that for now does not fit well with the design of eLyXer: a standalone tool to convert between two formats, or as Kernighan and Plauger put it, a standalone \emph on filter \emph default \begin_inset CommandInset citation LatexCommand cite key "kernighan-filters" \end_inset . Long-term maintenance might result a bit heavier with this approach though, especially if LyX changes to a different file format in the future. \end_layout \begin_layout Section FAQ \end_layout \begin_layout Description Q: I don't like how your tool outputs my document, what can I do? \end_layout \begin_layout Description A: First make sure that you are using the proper CSS file, i.e. copy the existing \family typewriter docs/lyx.css \family default file to your web page directory. Next try to customize the CSS file to your liking; it is a flexible approach that requires no code changes. Then try changing the code (and submitting the patch back). \end_layout \begin_layout Description Q: How is the code maintained? \end_layout \begin_layout Description A: It is kept in a \family typewriter git \family default repository \begin_inset CommandInset href LatexCommand href name "on Savannah" target "http://git.savannah.gnu.org/cgit/elyxer.git/" \end_inset . Patches in \family typewriter git \family default format are welcome (but keep in mind that my knowledge of \family typewriter git \family default is even shallower than my Python skills). \end_layout \begin_layout Description Q: I found a bug, what should I do? \end_layout \begin_layout Description A: Just report it to the \begin_inset CommandInset href LatexCommand href name "Savannah interface" target "https://savannah.nongnu.org/bugs/?func=additem&group=elyxer" \end_inset , to the \begin_inset CommandInset href LatexCommand href name "mailing list" target "elyxer-users@nongnu.org" type "mailto:" \end_inset or directly to the \begin_inset CommandInset href LatexCommand href name "main author" target "mailto:elyxer@gmail.com" type "mailto:" \end_inset . \end_layout \begin_layout Standard \begin_inset CommandInset nomencl_print LatexCommand printnomenclature \end_inset \end_layout \begin_layout Bibliography \begin_inset CommandInset bibitem LatexCommand bibitem key "savannah-elyxer" \end_inset Free Software Foundation, Inc.: eLyXer summary. \begin_inset Flex URL status collapsed \begin_layout Plain Layout https://savannah.nongnu.org/projects/elyxer/ \end_layout \end_inset \end_layout \begin_layout Bibliography \begin_inset CommandInset bibitem LatexCommand bibitem key "white-math" \end_inset S White: \begin_inset Quotes eld \end_inset Math in HTML with CSS \begin_inset Quotes erd \end_inset , accessed March 2009. \begin_inset Flex URL status collapsed \begin_layout Plain Layout http://www.zipcon.net/~swhite/docs/math/math.html \end_layout \end_inset \end_layout \begin_layout Bibliography \begin_inset CommandInset bibitem LatexCommand bibitem key "stallman-gplv3" \end_inset R S Stallman \emph on et al \emph default : \begin_inset Quotes eld \end_inset GNU GENERAL PUBLIC LICENSE \begin_inset Quotes erd \end_inset version 3, 20070629. \begin_inset Flex URL status collapsed \begin_layout Plain Layout http://www.gnu.org/copyleft/gpl.html \end_layout \end_inset \end_layout \begin_layout Bibliography \begin_inset CommandInset bibitem LatexCommand bibitem key "milde-mathml" \end_inset G Milde: \begin_inset Quotes eld \end_inset Re: eLyXer: LyX to HTML converter \begin_inset Quotes erd \end_inset , message to list \emph on lyx-devel \emph default , 20090309. \begin_inset Flex URL status collapsed \begin_layout Plain Layout http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg148627.html \end_layout \end_inset \end_layout \begin_layout Bibliography \begin_inset CommandInset bibitem LatexCommand bibitem key "younes-elyxer" \end_inset A Younes: \begin_inset Quotes eld \end_inset Re: eLyXer: LyX to HTML converter \begin_inset Quotes erd \end_inset , message to list \emph on lyx-devel \emph default , 20090309. \begin_inset Flex URL status collapsed \begin_layout Plain Layout http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg148634.html \end_layout \end_inset \end_layout \begin_layout Bibliography \begin_inset CommandInset bibitem LatexCommand bibitem key "kernighan-filters" \end_inset B W Kernighan, P J Plauger: \begin_inset Quotes eld \end_inset Software Tools \begin_inset Quotes erd \end_inset , ed. Addison-Wesley Professional 1976, p. 35. \end_layout \begin_layout Bibliography \begin_inset CommandInset bibitem LatexCommand bibitem key "lyx-devel" \end_inset Various authors: \begin_inset Quotes eld \end_inset lyx-devel mailing list \begin_inset Quotes erd \end_inset , accessed November 2009. \begin_inset Flex URL status collapsed \begin_layout Plain Layout http://www.mail-archive.com/lyx-devel@lists.lyx.org/ \end_layout \end_inset \end_layout \begin_layout Bibliography \begin_inset CommandInset bibitem LatexCommand bibitem key "git-download" \end_inset S Chacon: \begin_inset Quotes eld \end_inset Git -- Download \begin_inset Quotes erd \end_inset , accessed November 2009. \begin_inset Flex URL status collapsed \begin_layout Plain Layout http://git-scm.com/download \end_layout \end_inset \end_layout \begin_layout Bibliography \begin_inset CommandInset bibitem LatexCommand bibitem key "python-download" \end_inset Python community: \begin_inset Quotes eld \end_inset Download Python \begin_inset Quotes erd \end_inset , accessed November 2009. \begin_inset Flex URL status collapsed \begin_layout Plain Layout http://www.python.org/download/ \end_layout \end_inset \end_layout \end_body \end_document elyxer-1.2.5/docs/changelog.html0000644000175000017500000016477512117175137016133 0ustar chennochenno eLyXer changelog

figure elyxer.png eLyXer Changelog

This document lists all public versions, the date they were released on and the changes they contain. For more information about eLyXer visit the main page.
  • 1.2.5 (2013-01-11):
    • Solved a bug in the previous release: José Ramón’s fix was not properly applied in the executable elyxer.py. Sorry about that.
  • 1.2.4 (2013-01-10):
    • Implemented generic converters, and lyx -C as an image converter (thanks, Tommaso!).
    • Implemented command \today: Mar 10, 2013.
    • Added a Russian translation (thanks, Vladimir!).
    • Solved a bug when parsing a BibTeX entry with a trailing comma (thanks, Bob!).
    • BibTeX: correctly use booktitle instead of journal in an @inproceedings entry (thanks, Pascal!).
    • Expose language information as additional markup (using the lang attribute in HTML).
    • Fix by Guenter Milde for math2html under Python 3.0.
    • Convert em-dash only when surrounded by spaces (thanks, Robert).
    • Fix by José Ramón Álvarez Sánchez of problem in simultaneous use of hover and end options for footnotes (thanks, Tim!).
  • 1.2.3 (2011-08-31):
    • Changed the license for math2html from Apache v2 to FreeBSD 2-clause license, to better suit integration with DocUtils.
    • Removed a false positive error which appeared during the tests: “* No title in”.
    • Added most commands in Günter Milde’s excellent list of Unicode to LaTeX commands, except categories mathaccent, mathfence, mathradical, mathover and mathunder. Examples: \hash as  ⋕ , \smalltriangleleft as .
    • Deprecated option --jsmath, users are encouraged to use --mathjax instead.
    • Added argument --mathjax remote to access the MathJax CDN instead of hit a local copy. Changed the Math showcase to work remotely by default.
    • Solved Debian bug 639712: eLyXer didn’t accept Unicode characters in --title option, added test.
    • Solved Savannah bug 33961: eLyXer didn’t support sub- or superscript insets as used in LyX 2.0, added test.
    • Solved installation problem when $PATH contains a directory which does not exist; the eLyXer binary was created with the same name as said directory. Now install.py should just ignore the directory. (Thanks, Jack!)
  • 1.2.2 (2011-06-12):
    • Bug in description: when a (non-empty) ERT is the first element of a description, use it as first word and make it bold.
    • Proper support for \scriptstyle and \scriptscriptstyle: script, scriptscript.
    • Bug #33156: CSS specification as in --css=lyx.css was not working, solved now.
    • Support for \noindent and \centering in ERTs.
    • Ignore BibTeX entries which are not publication entries. Show a debug message for non-referenced entries.
    • Understand command \& in BibTeX files.
    • Bumped Lyx format supported (--lyxformat) to 413 (LyX 2.0.0).
    • Solved error when parsing display formulas generated with LyX 2.0: "Formula beginning \begin_inset Formula is unknown" (thanks, Pascal!). Added test case.
    • Added a bunch of new symbols, including \textsection §, \textemdash — or \v{z} ž (thanks again, Pascal!).
    • Changed output characters for English quotes, from Unicode “ and ‘ to HTML entities &ldquo; and &lsquo; (thanks, Marco!).
    • Make Flex styles in titles work (thanks, Tiago!).
    • Make custom Flex CharStyles work: generate HTML spans of the same class as the Flex type (thanks again, Marco!).
  • 1.2.1 (2011-03-07):
    • Wish list: support for formatted references (showing the part name and number) and named references (showing the part title, equivalent to \nameref).
    • Wish list: include part titles in --splitpart navigation header.
    • Changed literal for previous page in --splitpart: now it’s “Prev” instead of “Previous”.
    • Bug in --notoclabels: removed the “.” after the part number but before the title shown in the TOC. “5. How to Make Friends” is now “5 How to Make Friends” (thanks, José Ramón!).
    • Allow math2html to be invoked using parameters (like --debug).
    • Bugs in ERT parsing: brackets {} are not parsed correctly across different ERTs. The TeX parser was being thrown off by escaped brackets as in {\{\}}, added test. Comments are ignored now.
    • Solved conflict in CSS between .script (used to properly layout super- and subscripts) and span.script (used for the script-type \mathscr and \mathcal fonts). Changed the latter to span.scriptfont, forcing an incompatible but unavoidable change in the CSS.
    • Forced span.scriptfont to be shown as italic so it’s properly displayed on Firefox.
    • Wish list: new option --googlecharts adds support for formula images generated using Google Charts.
    • Wish list: merged options --toc and --toctarget into --tocfor.
    • Wish list: options --splitpart and --tocfor (previously --toc) now work together. Also: the separate TOC has a link to the main page.
    • Bug in --splitpart combined with --notoclabels: unnumbered parts displayed an ugly colon as in “Next : Section”, now removed (thanks, José Ramón!).
    • Modified the spacing in formulas so that words in the mathnormal font now appear separated, as a product of variables.
    • Do not show limit symbols such as or in a larger font than the rest for inline formulas.
    • Added support for \textcircled: w⃝.
  • 1.2.0 (2011-01-30):
    • Bumped LyX version support to 410.
    • Correctly create big brackets for environments with odd alignments such as matrix (thanks, Günther!).
    • Create and use big brackets for fractions and other structures, if needed.
    • Added option --simplemath to avoid fancy math structures: do not generate multi-line Unicode brackets or stacked limits.
    • eLyXer is now a proper Python package, instead of just a coalesced script elyxer.py containing everything. However only the script is installed right now.
    • Interpret TeXCode (previously known as Evil Red Text) as TeX commands and formulas.
    • Support for TeX commands \textvisiblespace, \AmS, \parbox, \tag, \rule, and more: , AmS.
    • Support for \Game: .
    • Changed the navigation header for --splitpart so that the left and right spans overflow (thanks, Axel!).
    • Bug in --notoclabels: labels such as “Figure” should be omitted in the TOC, but not in captions (thanks again, Axel!).
    • Bug in --splitpart: empty navigation links caused the header to look unbalanced, fixed now with a non-breaking space. Also, up link in the main page used to point to itself; now it’s an empty link (more thanks, Axel!).
    • Support for \limits and \nolimits: control if the last symbol should show limits above or below the symbol or not.
    • Bug in \vspace: add the vertical space after the command, not before; or at least try to.
    • Bug in \raisebox: parse and display the contents as text mode.
    • Wish list: do not number captions in code listings.
    • Do not install as a module (to run as python -m elyxer) but only as a script (to run as elyxer.py).
  • 1.1.2 (2010-12-23):
    • Wish list: display large Unicode symbols for sums and integrals in display mode.
    • Also in display mode, place limits for commands that take them above or below the symbol, instead of to the right.
    • Support for new Flex insets: Code, MenuItem, Noun, Strong; new Argument, Phantom and line (ruler) insets; new style \strikeout; new LaTeX commands \href, \newline.
    • BibTeX: apply a combining function only to the following character, not to the next word.
    • Added reference format for vpageref (“on page #”).
    • Improved math macro parsing: optional parameters, literal parameters, single-letter parameters, parameter defaults with operations.
    • Display math cases, full-sized binomials (\dbinom) and array brackets using Unicode bracket pieces.
    • Change all table-type elements in formulas to spans and do the formatting in the CSS, to generate valid XHTML.
    • Support graceful degradation of fractions and roots when the CSS is not present.
    • Adjusted roots to insert the root power inside the radical symbol.
    • Adjusted nice fractions (34) to improve their appearance.
    • Support for all upright Greek letters: μ, τ.
  • 1.1.1 (2010-12-13):
    • Wish list: understand \url{} in BibTeX files.
    • Wish list: parse math formulas in BibTeX files.
    • Improved support for dotless i and j as \imath and \jmath: ı, ȷ.
    • Solved bug when parsing a quoted string inside a BibTeX file containing a comma.
    • Added math environments equation* and matrix.
    • Do not break inline formulas at whitespace (thanks, José Ramón!).
    • Break up the CSS into pieces, and generate an independent math.css for use within math2html.py.
    • Ignore hyphens in option names, so e.g. --split-part is equivalent to --splitpart.
    • Changed --forceformat to --imageformat (kept the old option for backwards compatibility).
    • Wish list: added --imageformat "copy" to just copy images instead of converting them.
    • Wish list: added option --embedcss "file.css" to embed the CSS styles in file.css into the resulting HTML.
    • Wish list: more than one --css options can be added to use several CSS files.
    • Wish list: display sub- and superscript aligned vertically (as in integrals).
  • 1.1.0 (2010-11-23):
    • Wish list: understand \setcounter in the preamble to set the number of the first Chapter or Section.
    • Generate a new math2html.py file with an API to convert raw LaTeX code to HTML, and a command line utility.
    • Wish list: new option --notoclabels to omit part labels in the TOC.
    • Wish list: make “show changes in the output” work for change tracking.
    • Solve an existing issue with Description and List layouts: correct splitting of first words when intermixing styles.
    • Show decorations using Unicode combining characters, whenever possible.
    • Support for \dddot: o⃛ (with combining character) and \widehat: ^abc (with character on top).
    • Wish list: add several options for footnote generation (align markers instead of using superscript, place markers at the bottom of the page, use symbols for markers…). Also added a generic --footnotes option to aggregate them all.
    • Wish list: use ps:use-cropbox=true in ImageMagick for PostScript and EPS images.
    • Support for dotless i and j: ı, ȷ.
  • 1.0.4 (2010-10-29):
    • Solved bug #31342: detect appendices as they appear instead of looking at the containing layout.
    • Also reported in bug #31342: set part name to “Appendix A-Z” in the TOC for appendices, instead of showing them as regular chapters or sections.
    • Also reported in bug #31342: number parts and books using roman numerals, as in “Part I” or “Book IV”.
    • Fixed bug due to wrapped float placement not being mandatory anymore, despite what EmbeddedObjects.lyx says (thanks, Hans!).
    • Solved bug #31351: do not number (or add to the TOC) any document parts inside comments.
    • Also in bug #31351: the bibliography should be added to the TOC if so configured (and not inside a comment), and split into its own page with --splitpart.
    • Also in bug #31351: show the bibliography in regular size, not smaller than the main text as before.
    • Changed header from “Bibliography” to “References” for document classes other than book and report.
    • Solved bug #31414: bootstrap creation of conf/config.py.
    • Also in bug #31414: remodeled unit tests to try out Python 2.4 only if present, and to remove test files from previous runs.
    • Show the “Abstract” header only for the first Abstract layout (thanks, Yaron!).
    • Do not separate consecutive Abstract paragraphs, and display the abstract in slightly smaller font size.
    • Solved bug #31345: ignore preamble and comments in BibTeX files. Use string definitions (@string) in other entries.
    • Also in bug #31345: avoid endless loops for undesired characters in BibTeX entries.
    • Support for \fbox, \boxed, \framebox and \fcolorbox: fbox, boxed, framebox.
  • 1.0.3 (2010-10-15):
    • Do not hide errors when parsing child documents.
    • Correctly convert documents even when images are not found.
    • Do not center the content in figure or table floats by default.
    • Correctly convert child documents even when inserted in layouts.
    • Generate navigation bars for first page created with --splitpart.
    • Added wishlist to the user guide to keep track of requested features.
    • Solved bug #31243: spaces and comments in formulas (command definitions, empty formulas…).
    • Also reported in bug #31243: do not add numbering twice to child documents, and ignore child documents in comments.
    • Added support for \stackrel: xR → y (thanks, José Ramón!).
    • Added a lot of escaped characters to BibTeX parsing: \~n, \’{\i}… Also added a field note to all BibTeX styles.
    • Show all references (even those not cited) in the bibliography if configured to do so.
    • Understand relative sizes (e.g. 10col%) in spaces (thanks, Uwe!).
  • 1.0.2 (2010-09-20):
    • Updated MathJax to version 1.0.1 — no changes to eLyXer documents are necessary.
    • Added option --noconvert to use images in their original formats, and avoid converting images altogether.
    • Output <object> tags for SVG images. Size information is not used as it causes problems on Firefox.
    • BibTeX: include booktitle tag for the @incollection format.
    • BibTex: added a tag <span class="bibcites"> around all bibliographical cites, so they can be e.g. superscripted.
    • Show footnotes as hovering text instead of as marginal notes. Make the default footnote marker a bluish superscript letter in brackets:  [A]  [A] like this.
    • Updated --lyxformat to 398 (2.0alpha5); added warning if document version is bigger than that.
    • Support for \textless and \textgreater: <, >.
    • Added adjustments for better printing to default CSS.
    • Added languages “british” and “american” (which translate to plain English).
    • Avoid extracting indexes out of the containing layout if there is anything else in there (thanks, Amy!). This bug caused some content to be lost (e.g. child documents) if they were inside the same layout as e.g. an alphabetical index.
  • 1.0.1 (2010-09-01):
    • BibTeX: more robust parsing, specifically: correctly parse entries separated by commas. Support all TeX commands already available in math formulae.
    • Support for \textasciitilde: ~, \textasciicircum: ^ and a few other \text… symbols. Also, \textrm, \textsf and \textnormal should be working now in equations: a + roman + sans-serif + normal + b.
    • Improved support for custom horizontal and vertical spaces; absolute measures can now be used.
    • Support for sizes in table columns, figures and boxes.
    • Solved bug in --nofooter which required a dummy argument (thanks, Yan!).
    • Corrected box styling: <div class="Frameless"> is now indeed frameless, while <div class="Framed"> no longer has a double border.
    • Solved bug in text handling which separated consecutive centered lines with a space.
    • Basic support for LyX change tracking.
  • 1.0.0 (2010-07-21):
    • Replicate the navigation bar for --splitpart at the bottom of pages. Use translated strings for “Previous”, “Up” and “Next” links. Also added an explanatory text to the “up” link in the navigation bar, as in: “Up: Chapter 1”.
    • Added partial table of contents to pages generated with --splitpart.
    • Dependency cleanup between code modules.
    • Child documents of type “verbatim input” are now correctly converted on versions of Python built without universal newline support.
    • Include Index and Nomenclature in the Table of Contents.
    • When an Index, TOC, List of Figures… and the like is embedded in another layout, do not follow the style of the layout (thanks, Yaron!).
    • Solved a couple of XHTML validation errors: removed asterisks (*) in anchor names, avoid empty rows in arrays or case statements.
    • Make index entries work in Descriptions. Also, mixed styles should work again within Descriptions.
    • Group certain layouts together, such as Quote and Quotation.
    • Improved output for algorithms: do not run lines together, and do not separate other lines with double space.
    • List of algorithms does now correctly extract the text from the caption.
    • Increased line height for h2 in the main CSS (thanks, Wolfgang!).
    • Better color support in formulas: \color, \textcolor, \colorbox. blue, blue.
    • Formulas and formula labels are not colored by default.
    • Improved Index output: there is only one anchor for each entry, and entries are not shown in italics.
    • Allow hierarchical index entries, of the form “Main ! Secondary ! Final”.
  • 0.99 (2010-06-24):
    • Added --splitpart to online help (thanks, Sven!).
    • Restored compatibility with Python 2.4 (lost in 0.98 by mistake), added test to ensure it does not happen again.
    • BibTeX: improved template definitions for Vancouver style.
    • BibTeX: better parsing of braces (in templates) and quotes (in .bib files). Nested braces in templates are supported.
    • BibTeX: variable citing styles. Enclose cites in brackets instead of using superscripts.
    • BibTeX: export all BibTeX variables in bib-… spans.
    • BibTeX: limited author parsing, support for surname abbreviations as in style alpha.
    • BibTeX: use the file tag to show a link to the local file.
    • Added \oint and friends as a bigsymbol: x·dx.
    • Support for \officialeuro: .
    • Fix captions in lists of figures which use standard layouts (thanks, Hans!).
    • Added option --template to use an HTML template and substitute <!--$content-->, <!--$title-->
    • Added option --copyright to add a copyright notice at the bottom (no longer generated by default). Deprecated old option --nocopy.
    • Added support for including files as a code listing.
  • 0.98 (2010-05-13):
    • MathJax: workaround bug in MSIE, that causes it to fail to render anything.
    • Add a margin to LyX-Code. Also improve line break separation inside LyX-Code.
    • Coalesce Python code: use relative paths when importing (thanks, Jack!).
    • Experimental installation script.
    • Avoid postprocessing child documents twice (thanks, Rainer!).
    • Solved bug when loading images from child documents in subdirectories (thanks, Rainer!).
    • Solved bug in image scaling when only one dimension is set (thanks, Wolfgang!).
    • Corrected issue with one-liner \lstset (thanks again, Rainer!).
    • Improved lists of figures, tables and algorithms: use short title, better labeling of floats.
    • Solved weird bug in float numbering when a chapter has only one layout.
    • Added \diagup and \diagdown: , .
    • First public release of option --splitpart [level]: split resulting web page at the given level.
    • Support for macros, both in LyX macro inset and as \newcommand.
    • Added URLs to most BibTeX formats.
    • Added BibTeX style “vancouver” for articles (thanks, John!).
    • Added a footer detailing eLyXer version and conversion date; it can be turned off with --nofooter.
  • 0.43 (2010-04-10):
    • Many BibTeX improvements: new style abbrvnat, conditional formatting, look up types in lowercase, understand “--” as dash.
    • Added options for mathematical equations: --jsmath to use jsMath and --mathjax to use MathJax.
    • Added command help to loremipsumize.py so it can be used outside of eLyXer.
    • Include internationalization files in .zip file.
    • Solved bug in table parsing: separate different plain layouts (thanks, Sara!).
    • eLyXer compressed files now contain a single directory called elyxer-$VERSION, instead of just elyxer.
    • Added italicized uppercase Greek letters: ΓΩ. De-italicized regular uppercase Greek letters: ΓΩ.
  • 0.42 (2010-03-17):
    • Changed author everywhere to the real name, to avoid any copyleft uncertainties.
    • Remove hook in the main text ([D→]) from margin notes.
    • Do not crash when BibTeX files are not found, just show an error.
    • Added support for some IPA characters, including ħ. Better parsing of \textipa text.
    • Added option --numberfoot to label footnotes with numbers instead of letters.
    • Solved bug in assignment of default formatting to references (thanks, Hans!).
    • Added option --raw to output raw HTML without header or footer.
    • Added French and Dutch translations.
    • Solved indenting problem for lists: only the first line was being indented.
  • 0.41 (2010-02-11):
    • Select the translation based on document language.
    • Added em-dash — such as in this sentence, , \textup.
    • Added option --converter inkscape to use Inkscape as SVG converter.
    • Solved bug when numbering unordered unique parts such as Part* (thanks, Geremy!).
    • Show error instead of crashing when included document does not exist.
    • Support for all box styles. In CSS: switched to outline-style instead of border for boxes.
    • Support for vertical space insets.
    • Support for references inside paragraphs and formatted references.
    • Listings are now converted using <pre> tags, instead of <code>. They are also justified left.
    • Solved bug that prevented numbered listings to appear numbered (thanks, Sam!).
    • Support for generic Flex insets, incuding Flex CharStyle:MenuItem.
    • All &nbsp; entities are now generated as the Unicode U+00A0 character.
    • New option --iso885915 to generate a document with ISO-8859-15 encoding.
    • Support for Sam Liddicott’s Newfangle module for literate programming.
    • Updated the developer guide for potential contributors; added link from the main page.
    • Support for \underbrace and \overbrace (as bars and without sub/superscripts).
  • 0.40 (2010-01-19):
    • Faster (about 25%) BibTeX file parsing.
    • Show version number after a crash.
    • Imported Jens Nöckel’s contributed list of LaTeX to Unicode mappings: , and many more.
    • Added support for compressed documents (Document ▷ Compressed).
    • Added configurable alignment support for equation environments (thanks, Jens!). Multiple labels per formula are correctly processed.
    • Added a couple of note insets for Tufte document classes, appearing as side notes without a reference (thanks, Joachim!).
    • Support for escaped characters in BibTeX files, added German umlauts for starters.
    • Support for internationalization using GNU gettext files. Added Spanish and German translations in the po/ folder.
    • Support for verbatim includes.
  • 0.39 (2009-12-20):
    • Avoid oversized images on IE6.
    • Solved several crashes with the LyX documentation (thanks, Uwe!).
    • Created script to lorem-ipsumize texts, found in src/loremipsumize.py.
    • Solved some issues with BibTeX parsing; now it should work with most real-world files (thanks, Ken!). Also improved error reporting and implemented a new way of line-by-line parsing from file, activated with --lowmem.
    • Support for binomial coefficients: (AB). Ignore commands \leftroot, \uproot. Generic support for variable commands in math mode.
    • Support for omitted aligned brackets: right) (thanks, Jens!).
    • Solved bug with image conversion from directories (thanks, Olivier!).
  • 0.38 (2009-12-03):
    • Resized all logos in the documentation.
    • Solved bug in paragraph indentation that indented all formula spans and elements.
    • Solved a couple of bugs in image scaling: wraps with images, images in figures.
    • Solved bug in TOC generation: article-class documents had their TOC depth off-by-one.
    • Solved bug with listings inserted in documents using LyX 1.6, and improved their looks.
    • Slight font size reduction on Firefox, and huge reduction on some other proprietary browsers. Now global font size specification is done using percents.
    • New commands: \gtrless: , \complement: , \measuredangle: , \sphericalangle: , \nmid: , \circeq: , \lessgtr: , \nparallel: .
  • 0.37 (2009-11-30):
    • Further improvements in float manipulation: figures enclosing other figures have their own tweaked CSS class (thanks, Olivier).
    • PNG and JPEG images are not rescaled anymore, and never shown above their maximum size. Width and height are set using CSS properties.
    • TOC generation for unordered entries (like Section*) and entries inserted in other layouts. Max TOC depth and max numbering depth are honored. Also solved bug in tagging of unordered parts.
    • Implemented indented paragraphs when specified in the document.
    • Horizontal fill is now shown as a fixed-width space.
    • Simplified postprocessing code. Inclusion of child documents is now done inside a Standard layout.
    • Support for commands \varkappa: ϰ, \varnothing: , \mathring: , \backprime: , \notin: , \hfill: , \circledR: ®, \hslash: .
    • New option --splitpart to split the output in multiple pages, one page per part; needs more tweaking.
  • 0.36 (2009-11-19):
    • New in-memory processing of a document before file output, activated by default. It includes: TOC generation (TOC entries admit typefaces, colors, weights, spaces, short titles but restrict most other content), sequential numbering to bibliography entries, lists of floats (figures, tables, algorithms), correct labeling of references and use of the embedded title as HTML title.
    • New option --lowmem to do one-pass filtering only, to preserve memory (keeping the old behavior).
    • Updated the developer guide.
    • Change the postprocessing of equation labels so that only one anchor is used for the whole equation.
    • Added \mathscr and a few script fonts: hello. Added several characters for math script (\mathscr), fraktur (\mathfrak) and blackboard (\mathbb) fonts, and implemented the translation to Unicode chars: , 𝔉, 𝔽.
    • New math commands: \dfrac, implemented as \cfrac; \c for cedilla, already implemented as characters and now as decoration: ; thick space \; and quotes ": " "; \hspace for horizontal space and \vspace for vertical space; and a few size commands: \big, \Big, \bigg, \Bigg, \middle.
    • Added a parent attribute to every Container, for easier processing.
    • Image conversion and display: process width and height in an image if both are present; use % width of image within a float to scale the float; set max scaling of images to 100% with max-width CSS attribute. (Thanks, Olivier and Uwe.)
    • Subfloats are numbered (a), (b) (instead of x.ya, x.yb).
    • Convert all pathnames for image conversion using sys.getfilesystemencoding().
  • 0.35 (2009-11-05):
    • Added new characters: \checkmark , \blacklozenge , \nexists , \mathcircumflex ^.
    • Updated all documentation to LyX 1.6.
    • Solved CSS validation error in table.align (thanks, Olivier).
    • Solved XHTML validation error in greyed out note, removing useless divs.
    • Add a space after a fraction and before the units: 32 km, (7)/(16) s.
    • Corrected display of float within a float (thanks again, Olivier!).
    • Modified the meaning of --toc to be an on/off switch; the old behavior is now under --toctarget.
    • Changed the 2009-11-05 option --cutpart to --splitpart: new option to split the output file in parts. Not yet working correctly (for instance, links are not redirected).
    • eLyXer now understands and processes new Graphics options: width 50col%, height 50theight% and friends (thanks, Uwe).
    • PDF images are cropped before conversion to PNG (thanks, Uwe).
    • Included child documents can be inserted using firstline and lastline (as seen in EmbeddedObjects.lyx).
  • 0.34 (2009-10-28):
    • Support for child document inclusion (Insert ▷ File ▷ Child Document…).
    • Avoid generating images on different directories (relative paths starting with ../).
    • Added \maltese and financial symbols $, €, ¥.
    • Removed annoying message “Unexpected end of bracket” when parsing empty brackets.
    • Support for \raisebox.
    • Created new structure of Writers, preparing for document segmentation and TOC generation.
  • 0.33 (2009-10-19):
    • New TOC generation process based on an already-generated HTML document, not ready for prime time yet.
    • Adapted --help option so that it shows the executable file as invoked (elyxer.py, elyxer or whatever). Expanded online help from this command.
    • Support for new text commands \textsf, \texttt, \textit, \textbf, \textsl, \textsc.
    • Properly parse all text commands \text…, including \textipa.
    • Support for \cfrac. Now regular \frac shows embedded formulas smaller.
    • Do not number equations containing *, like in \begin{align*}. (Once more, thanks Uwe.)
    • Properly align equations for AMS align environment. Other environments are parsed but not necessarily honored.
    • Correctly distinguish \epsilon ϵ from \varepsilon ε.
    • Added TeX-to-Unicode mappings from Markus Kuhn.
    • Support for \unitfrac.
    • Added \dots: .
  • 0.32 (2009-10-05):
    • Fixed unit processing. Now units appear separated by a space after the number.
    • Repaired use of AlphaCommands. Decorations so defined in the configuration file appear again as a single symbol: .
    • Added option --lyxformat to return the highest LyX format that eLyXer understands. Should help when integrating with lyx2lyx.
    • Improved TOC (table of contents) generation. Modified option --toc to accept an URL, and documented it.
    • Added option --target to add a target frame to every link.
    • Corrected equation numbering error: now all \begin{equation}…\end{equation} formulae are numbered. (Thanks once more, Uwe.)
  • 0.31 (2009-09-27):
    • Modified image parsing code to remove dependency on Python 2.5, expurging os.SEEK_CUR.
    • Removed the ill-fated elyxerconv.py library file (but kept io/convert.py), see lyx-devel thread. Now the file elyxer.py itself can be installed as a library, and run as a module with python -m.; see also lyx-devel thread.
    • eLyXer was added to the Python Package Index (PyPI) starting with 0.30. Now it should be automatically registered for each release.
    • Updated documentation (user guide, README file) with details of distutils installation.
    • Modified single string Containers (StringContainer, Constant) so that they appear as empty Containers — should speed up postprocessing.
    • Solved bug when parsing BibTeX files with incorrect lines.
    • Modified postprocessing to correctly process lists within tables.
    • In the process refactored postprocessing completely: now instead of unconditional postprocessor stages, each stage can add a postprocessing hook. Should be faster — but is indeed a bit slower.
  • 0.30 (2009-09-13):
    • Removed most comments from the final distributed file elyxer.py.
    • Added distutils support for cross-platform distribution. The library elyxerconv is added to local Python libraries.
    • Added command line option --forceformat: force eLyXer to convert all images to the given output format.
    • Switched all options in command line help to quotes: --title <title> is now --title "title".
    • Solved bug reported by Uwe Stöhr when reading Windows BibTeX file generated by JabRef. Now eLyXer tries several encodings for each file, initially UTF-8 and Cp1252.
    • Another bug, also reported by Uwe Stöhr, in branch selection. Added test branches.lyx.
  • 0.29 (2009-09-08):
    • Preliminary support for BibTeX. Configurable output styles (albeit cumbersome and quite primitive).
    • Added new cite commands citep, citet, citealt; and reference command prettyref.
    • A couple of new math commands: \ldots, \qquad.
  • 0.28 (2009-09-05):
    • Various fixes related to Windows integration.
    • Documented integration with LyX in the user guide.
  • 0.27 (2009-06-17):
    • Units without the magnitude (the number) are working.
    • Complex roots now working, added to the math showcase.
    • Leave JPEG images untransformed instead of converting them to PNG (or at least transform them to JPEG). Read JPEG image sizes.
    • More flexible configuration options for lists of values.
    • Added --destdirectory option to convert images into.
    • Image conversion from a different directory (or even with absolute paths) should work now.
    • Changed the whole infrastructure for formulae parsing. More structured parsing should now be possible, e.g. square brackets are first-class citizens.
    • Implemented nice fractions: 78.
    • Redid basic typography: default font is now sans-serif, which looks better on your average browser. Formulae have a bit more space around.
    • Imported the complete symbol list from the unicodesymbols file in LyX.
  • 0.26 (2009-06-10):
    • Added a lot of new LaTeX commands, both for Unicode symbols and for math functions.
    • New mechanism to include new lists of “command:Unicode” equivalents.
    • New decoration command \overrightarrow, to show a long arrow above some text.
    • Solved bug: --directory option was not working. A new test for this option added.
  • 0.25 (2009-06-08):
    • Added new characters: German dash separator, a few arrows, horizontal ellipsis.
    • Automatic insertion of release date in the changelog upon version release.
    • New formula commands: phantom text (for spacing), mbox (literal text).
    • Solved two bugs in URLs: make FlexURLs point to the link in their contents, and do not show “mailto:” in email links.
    • Properly display Date layouts as <h2>.
    • Display a FATAL error (and terminate) when trying to read beyond the end of the document.
    • Cross-platform support for newlines. Besides the Unix \n, now supports Windows (\r\n) and Mac OS X (\r) newlines.
    • Support for \unit command, showing units for a magnitude.
    • New format for formulae (instead of $…$ or \[…\]): \command{…}.
  • 0.24 (2009-06-02):
    • Show sum and integral limits correctly in Konqueror, Safari and Chrome.
    • Also show roots and arrays correctly in those browsers. Larger radical symbol looks better.
    • Added Math Showcase to test on browsershots.org.
    • Substituted medium mathematical spaces with midspaces for better browser compatibility.
    • Added --unicode option to switch on full Unicode output; right now only re-adds medium mathematical spaces.
    • Included all Greek letters, upper and lower case; and common math symbols.
    • Make title from command line option prevail over PDF title.
    • Specified minimum browser versions in the user guide and in the requirements.
    • Documented option --directory (it existed already but was not in the docs).
    • Option --toc can generate a Table Of Contents. Not documented because it is only a start for bigger things.
    • Repaired configuration export to base.cfg: now all objects in config.py are automatically exported.
  • 0.23 (2009-05-24):
    • Corrected numbering and appearance of subfloats.
    • Plain layouts are not reflected in HTML output.
    • Unified table parsing, moved table starts to configuration file.
    • Use unicode output in debug and error messages.
    • Automated testing now shows unified diff, to show the file that doesn’t pass the tests.
    • Finally got UTF-8 output right (hopefully).
    • Display floats with tables properly aligned, and on a white background. Listings are working too.
    • Show warning when document is created with LyX 1.4.x.
    • Transform \newpage to an empty paragraph.
    • Standard layouts can be <div> or nothing at all, generating valid XHTML.
    • Added nomenclature commands for 1.5.x.
    • Got Index and nomenclature working again, added test file so they don’t break anymore.
  • 0.22 (2009-05-15):
    • Modified user guide to explain --html option.
    • Solved a few bugs manifested when exporting to HTML 4.0 with --html.
    • More configurable containers: quote types, barred text, boxes, info insets…
    • Added note on the main page about slow mirrors and latest versions.
    • Standard layouts can now be translated to <div> or to <span>, depending on the context.
    • Command endings can be deduced from starts in configuration file.
    • A bunch of new math symbols: nu, angle brackets.
    • Generalized big brackets of several types. Consolidated parameter parsing in formulas.
    • Equation numbering is working.
    • Unknown commands are shown in red: \unknown.
  • 0.21 (2009-05-11):
    • Command line option --html to export to HTML 4.0.
    • Container endings are now configurable from the main config file.
    • Styles can be mixed and matched at will (like typewriter bold in blue).
    • All constant strings (such as “Table of contents”) should now be configurable.
    • Added a few more colors: green, magenta, cyan, yellow, white (those two were yellow and white).
  • 0.20 (2009-05-09):
    • Command line option --version to show the current version number and date.
    • Release date is now automatically added to the configuration.
    • Preliminary support for inset boxes.
    • Support for numbered listings.
    • Added <meta> tag for Content-Type, to ease importing into word processors.
    • Automated version generation, taking version number and date from config, and updating current version in the main page.
  • 0.19 (2009-05-07):
    • More powerful configuration file manipulation: export to generic config and Python files.
    • Start lines for every parsed structure can now be configured in the global base.cfg file.
    • New Info types package and textclass.
    • New formula symbols: up and down arrows, long double arrows, Gamma and Upsilon, mu, backslash.
    • Show line number and current line for generic errors.
    • Listings and document abstracts are displayed properly.
  • 0.18 (2009-05-04):
    • Wrap floats are separated by a bit of space (two exes, actually) from the text.
    • Solved bug when running without any arguments.
    • Main executable file is now changed from elyxer to elyxer.py, to prevent problems on platforms that require the extension; main source file has changed from elyxer.py to principal.py, to avoid confusion.
    • Moved all parsing code to the new package parse, and configuration files to package conf.
    • All configuration is now read from (and written to) plain text files.
  • 0.17 (2009-04-27):
    • Alignment of table cells is now respected, both horizontally and vertically.
    • Wrap floats are actually floated left or right.
    • Correctly interpret symbols in formulae: !, ;,  ≤ ,  ≥ ,  ≠ ,   ∈ , , and a few spaces.
    • In formulae, \displaystyle and friends are ignored.
    • Square roots are again displayed correctly, and even better than before!
    • Cases are working (not perfect: with a bar instead of a bracket, but working).
  • 0.16 (2009-04-22):
    • Document date is shown centered.
    • Special rows in a longtable are properly ignored.
    • Multicolumn cells are properly interpreted.
    • Sums and integral limits are properly displayed with respect to the symbol: i = 1.
  • 0.15 (2009-04-19):
    • Info insets (containing shortcuts) are now interpreted and shown.
    • LyX-Code is interpreted as a <pre> tag.
    • Reorganized code into a few packages.
    • Line numbers are not shown for utility classes.
    • Floats (figures, tables and algorithms) are now numbered.
    • Float links point to the start of the table or figure, not to the caption.
  • 0.14 (2009-04-13):
    • Deeper layouts (of any kind, not just in lists) are now supported.
    • Appendices are numbered correctly (as A, B, C…).
    • Sections in deeper layouts are numbered correctly too.
    • Double dash does not catch Unix-style options: --css is not converted -- while the version with spaces is.
    • Corrected serious bug in formula parsing affecting inline arrays.
    • Arrays with vertical alignment are correctly parsed.
  • 0.13 (2009-04-12):
    • Lists are correctly displayed, instead of one list per item.
    • Lists can contain nested layouts.
    • List layouts (not to mistake with Enumerate or Itemize lists) are processed correctly.
    • Changelog moved to separate document.
    • Read image sizes correctly on big-endian architectures (e.g. Mac OS X on PowerPC).
    • Numeration of chapters, sections… is working.
    • Error messages now show the line where they happen.
  • 0.12 (2009-04-05):
    • Arrays are parsed correctly and displayed acceptably.
    • Numbers and units are correctly separated.
    • Text decorations (such as ) are shown in line.
    • Variables are italicized.
    • Notes and comments are not output at all, greyed-out notes are shown in grey.
    • LyX guides parse completely.
  • 0.11 (2009-03-27):
    • Arrays are at least well parsed (but still show wrong).
    • Integrals and sums appear as large characters.
    • Appendices are separated from the main document.
    • The bibliography appears separated with a title.
    • Floats appear centered on-screen.
  • 0.10 (2009-03-23):
    • Better handling of footnotes and margin notes: not overlapping and with a reference in the text.
    • Better parsing of first word in a Description.
    • Short titles are ignored.
    • Added a few font families for equations. Not that they display too well…
  • 0.9 (2009-03-21):
    • Better formula parsing (including line breaks). Supports a few math fonts.
    • Supports menu separator, text with bar, nomenclature and many more quote types.
    • Single configuration file general.py.
    • Layout of type Space is not shown.
    • Supports branches. Inactive branches are not shown.
    • New symbols: greek letters, shapes: bullet, right triangle.
    • Added support for new style (1.6.x) index entries.
    • From LyX documentation: UserGuide.lyx is now working (except for some math functions).
  • 0.8 (2009-03-20):
    • Can be run from other directories than the one with the document.
    • Tables have light grey separations. Table spacing is now better adjusted.
    • Descriptions appear with the first word in bold), but only within the first text style. Changing style in the middle of a word may distract the algorithm.
    • Added support for Lyx notes (not rendered in the HTML), margin notes, pretty quotes ‘’, weird spaces.
    • Added support for new style (1.6.x) hyperlinks, labels and references, TOC, index.
    • Uses PDF title if present.
    • From LyX documentation: Intro.lyx is now working.
  • 0.7 (2009-03-16):
    • Images referenced by absolute path are converted to relative PNGs.
    • Range of supported quotes is greater. Unknown quotes are now marked as errors but do not make the tool fail.
    • Default CSS is always on nongnu.org, it can be changed via command line option --css.
    • Reinstated layout classes for unknown types.
    • Updated documentation to include how to run on Windows.
    • Added meta generator tag to all pages.
    • Added option --title to change the default page title.
    • Phonetic symbols appear in dark cyan: [sample].
    • Lots of small fixes and improvements to correctly parse the official LyX guides (UserGuide.lyx, EmbeddedObjects.lyx and Math.lyx).
  • 0.6 (2009-03-15):
    • Added Flex URLs, Flex code.
    • Works with Python 2.3.5, but not yet Mac OS X terminal.
    • Alignment now works right (and center and left).
    • Modified license files to comply with Savannah policies.
    • Added index page and logo.
  • 0.5 (2009-03-14):
    • Inset parameters are all parsed correctly (including spaces in image paths).
    • Formulae and tables should work again (including complex formatting).
    • Modified to (mostly) run under Python 2.3.5 (Mac OS X Tiger).
    • Processes layouts ending in ‘*’ (like ‘Section*’).
    • Runtime options for help and to disable the copyright notice, debug, quietness.
    • Accepts scaling for images.
    • Nested lists working.
  • 0.4 (2009-03-12):
    • When images do not exist warns but does not fail.
    • Author and title containing tags are properly processed.
    • Slanted text translated to italics.
    • Title no longer necessary to have a working document.
    • ERT is ignored. Status line (open/collapsed) is ignored.
    • Supports footnotes, newlines, bibitem entries and citations.
    • Dev guide includes a Container tutorial.
  • 0.3 (2009-03-11): Now works with generic Insets.
  • 0.2 (2009-03-11): ImageMagick is not required anymore.
  • 0.1 (2009-03-10): first public version.
elyxer-1.2.5/install.py0000755000175000017500000001074712074107030014363 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20100411 # eLyXer multi-platform installation import platform import sys import os import shutil import gettext class Installer(object): "The eLyXer installer." elyxer = 'elyxer.py' separators = {'Linux':':', 'Windows':';', 'Darwin':':'} preferredstarts = ['/usr/bin', 'c:\\windows\\system', '/usr/local/bin'] def error(self, string): "Print an error string." self.show(string, sys.stderr) def show(self, message, channel = sys.stdout): "Show a message out of a channel" channel.write(message + '\n') def usage(self): "Show usage and requirements." self.error('Usage: python install.py') self.error('Requirements: Python version 2.3 and above, Python 3 not supported.') exit() def copybin(self): "Check permissions, try to copy binary file to any system path." for path in self.sortpaths(): try: shutil.copy2(Installer.elyxer, path) self.show('eLyXer installed as a binary in ' + path) self.show('Please run as "elyxer.py [options] input.lyx output.html" to use it') return except IOError: pass self.error('eLyXer not installed') def sortpaths(self): "Sort the environment variable PATH, place those containing 'python' first." "Remove a dot directory." system = platform.system() if not system in Installer.separators: self.error('Unknown operating system ' + system + '; aborting') self.usage() separator = Installer.separators[system] paths = os.environ['PATH'].split(separator) withpython = [] preferred = [] rest = [] while len(paths) > 0: path = paths.pop() if 'python' in path.lower(): withpython.append(path) elif self.ispreferred(path): preferred.append(path) elif path != '.': rest.append(path + '/') return withpython + preferred + rest def ispreferred(self, path): "Find out if the path starts with one of the preferred paths." for preferredstart in Installer.preferredstarts: if path.lower().startswith(preferredstart): return True return False def installmodule(self): "Install eLyXer as a module." return if not self.checkpermissions('install as a Python module'): return sys.argv.append('install') import setup self.show('eLyXer installed as a module.') self.show('You can also run eLyXer as "python -m elyxer [options] input.lyx output.html"') def installtranslations(self): "Install the translation files." destination = gettext.bindtextdomain('elyxer') self.copy('po/locale', destination) def copy(self, source, destination): "Recursively copy a file or directory into another." if not self.checkpermissions('install translation modules'): return if os.path.isfile(source): shutil.copy2(source, destination) return if not os.path.exists(destination): shutil.copytree(source, destination) return for filename in os.listdir(source): self.copy(os.path.join(source, filename), os.path.join(destination, filename)) def checkpermissions(self, purpose): "Check if the user has permissions as root to do something." if platform.system() == 'Linux': if os.getuid() != 0: self.error('Need to be root to ' + purpose) return False return True def checkversion(self): "Check the current version." version = platform.python_version_tuple() if int(version[0]) != 2: self.error('Invalid Python version ' + version[0] + '.' + version[1]) self.usage() if int(version[1]) < 3: self.usage() self.copybin() if int(version[1]) > 3: self.installmodule() self.installtranslations() Installer().checkversion() elyxer-1.2.5/gpl-3.0-standalone.html0000644000175000017500000010764212074107030016435 0ustar chennochenno GNU General Public License - GNU Project - Free Software Foundation (FSF)

GNU GENERAL PUBLIC LICENSE

Version 3, 29 June 2007

Copyright © 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

How to Apply These Terms to Your New Programs

If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms.

To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the “copyright” line and a pointer to where the full notice is found.

    <one line to give the program's name and a brief idea of what it does.>
    Copyright (C) <year>  <name of author>

    This program is free software: 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 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
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

Also add information on how to contact you by electronic and paper mail.

If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode:

    <program>  Copyright (C) <year>  <name of author>
    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
    This is free software, and you are welcome to redistribute it
    under certain conditions; type `show c' for details.

The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an “about box”.

You should also get your employer (if you work as a programmer) or school, if any, to sign a “copyright disclaimer” for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see <http://www.gnu.org/licenses/>.

The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read <http://www.gnu.org/philosophy/why-not-lgpl.html>.

elyxer-1.2.5/math2html.py0000755000175000017500000054343012117174754014634 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # math2html: convert LaTeX equations to HTML output. # # Copyright (C) 2009-2011 Alex Fernández # # Released under the terms of the `2-Clause BSD license'_, in short: # Copying and distribution of this file, with or without modification, # are permitted in any medium without royalty provided the copyright # notice and this notice are preserved. # This file is offered as-is, without any warranty. # # .. _2-Clause BSD license: http://www.spdx.org/licenses/BSD-2-Clause # Based on eLyXer: convert LyX source files to HTML output. # http://elyxer.nongnu.org/ # --end-- # Alex 20101110 # eLyXer standalone formula conversion to HTML. import sys class Trace(object): "A tracing class" debugmode = False quietmode = False showlinesmode = False prefix = None def debug(cls, message): "Show a debug message" if not Trace.debugmode or Trace.quietmode: return Trace.show(message, sys.stdout) def message(cls, message): "Show a trace message" if Trace.quietmode: return if Trace.prefix and Trace.showlinesmode: message = Trace.prefix + message Trace.show(message, sys.stdout) def error(cls, message): "Show an error message" message = '* ' + message if Trace.prefix and Trace.showlinesmode: message = Trace.prefix + message Trace.show(message, sys.stderr) def fatal(cls, message): "Show an error message and terminate" Trace.error('FATAL: ' + message) exit(-1) def show(cls, message, channel): "Show a message out of a channel" if sys.version_info < (3,0): message = message.encode('utf-8') channel.write(message + '\n') debug = classmethod(debug) message = classmethod(message) error = classmethod(error) fatal = classmethod(fatal) show = classmethod(show) import os.path import sys class BibStylesConfig(object): "Configuration class from elyxer.config file" abbrvnat = { u'@article':u'$authors. $title. $journal,{ {$volume:}$pages,} $month $year.{ doi: $doi.}{ URL $url.}{ $note.}', u'cite':u'$surname($year)', u'default':u'$authors. $title. $publisher, $year.{ URL $url.}{ $note.}', } alpha = { u'@article':u'$authors. $title.{ $journal{, {$volume}{($number)}}{: $pages}{, $year}.}{ $url.}{ $filename.}{ $note.}', u'cite':u'$Sur$YY', u'default':u'$authors. $title.{ $journal,} $year.{ $url.}{ $filename.}{ $note.}', } authordate2 = { u'@article':u'$authors. $year. $title. $journal, $volume($number), $pages.{ URL $url.}{ $note.}', u'@book':u'$authors. $year. $title. $publisher.{ URL $url.}{ $note.}', u'cite':u'$surname, $year', u'default':u'$authors. $year. $title. $publisher.{ URL $url.}{ $note.}', } default = { u'@article':u'$authors: “$title”, $journal,{ pp. $pages,} $year.{ URL $url.}{ $note.}', u'@book':u'{$authors: }$title{ ($editor, ed.)}.{{ $publisher,} $year.}{ URL $url.}{ $note.}', u'@booklet':u'$authors: $title.{{ $publisher,} $year.}{ URL $url.}{ $note.}', u'@conference':u'$authors: “$title”, $journal,{ pp. $pages,} $year.{ URL $url.}{ $note.}', u'@inbook':u'$authors: $title.{{ $publisher,} $year.}{ URL $url.}{ $note.}', u'@incollection':u'$authors: $title{ in $booktitle{ ($editor, ed.)}}.{{ $publisher,} $year.}{ URL $url.}{ $note.}', u'@inproceedings':u'$authors: “$title”, $booktitle,{ pp. $pages,} $year.{ URL $url.}{ $note.}', u'@manual':u'$authors: $title.{{ $publisher,} $year.}{ URL $url.}{ $note.}', u'@mastersthesis':u'$authors: $title.{{ $publisher,} $year.}{ URL $url.}{ $note.}', u'@misc':u'$authors: $title.{{ $publisher,}{ $howpublished,} $year.}{ URL $url.}{ $note.}', u'@phdthesis':u'$authors: $title.{{ $publisher,} $year.}{ URL $url.}{ $note.}', u'@proceedings':u'$authors: “$title”, $journal,{ pp. $pages,} $year.{ URL $url.}{ $note.}', u'@techreport':u'$authors: $title, $year.{ URL $url.}{ $note.}', u'@unpublished':u'$authors: “$title”, $journal, $year.{ URL $url.}{ $note.}', u'cite':u'$index', u'default':u'$authors: $title.{{ $publisher,} $year.}{ URL $url.}{ $note.}', } defaulttags = { u'YY':u'??', u'authors':u'', u'surname':u'', } ieeetr = { u'@article':u'$authors, “$title”, $journal, vol. $volume, no. $number, pp. $pages, $year.{ URL $url.}{ $note.}', u'@book':u'$authors, $title. $publisher, $year.{ URL $url.}{ $note.}', u'cite':u'$index', u'default':u'$authors, “$title”. $year.{ URL $url.}{ $note.}', } plain = { u'@article':u'$authors. $title.{ $journal{, {$volume}{($number)}}{:$pages}{, $year}.}{ URL $url.}{ $note.}', u'@book':u'$authors. $title. $publisher,{ $month} $year.{ URL $url.}{ $note.}', u'@incollection':u'$authors. $title.{ In $booktitle {($editor, ed.)}.} $publisher,{ $month} $year.{ URL $url.}{ $note.}', u'@inproceedings':u'$authors. $title. { $booktitle{, {$volume}{($number)}}{:$pages}{, $year}.}{ URL $url.}{ $note.}', u'cite':u'$index', u'default':u'{$authors. }$title.{{ $publisher,} $year.}{ URL $url.}{ $note.}', } vancouver = { u'@article':u'$authors. $title. $journal, $year{;{$volume}{($number)}{:$pages}}.{ URL: $url.}{ $note.}', u'@book':u'$authors. $title. {$publisher, }$year.{ URL: $url.}{ $note.}', u'cite':u'$index', u'default':u'$authors. $title; {$publisher, }$year.{ $howpublished.}{ URL: $url.}{ $note.}', } class BibTeXConfig(object): "Configuration class from elyxer.config file" replaced = { u'--':u'—', u'..':u'.', } class ContainerConfig(object): "Configuration class from elyxer.config file" endings = { u'Align':u'\\end_layout', u'BarredText':u'\\bar', u'BoldText':u'\\series', u'Cell':u'':u'>', } html = { u'/>':u'>', } iso885915 = { u' ':u' ', u' ':u' ', u' ':u' ', } nonunicode = { u' ':u' ', } class FormulaConfig(object): "Configuration class from elyxer.config file" alphacommands = { u'\\AA':u'Å', u'\\AE':u'Æ', u'\\AmS':u'AmS', u'\\Angstroem':u'Å', u'\\DH':u'Ð', u'\\Koppa':u'Ϟ', u'\\L':u'Ł', u'\\Micro':u'µ', u'\\O':u'Ø', u'\\OE':u'Œ', u'\\Sampi':u'Ϡ', u'\\Stigma':u'Ϛ', u'\\TH':u'Þ', u'\\aa':u'å', u'\\ae':u'æ', u'\\alpha':u'α', u'\\beta':u'β', u'\\delta':u'δ', u'\\dh':u'ð', u'\\digamma':u'ϝ', u'\\epsilon':u'ϵ', u'\\eta':u'η', u'\\eth':u'ð', u'\\gamma':u'γ', u'\\i':u'ı', u'\\imath':u'ı', u'\\iota':u'ι', u'\\j':u'ȷ', u'\\jmath':u'ȷ', u'\\kappa':u'κ', u'\\koppa':u'ϟ', u'\\l':u'ł', u'\\lambda':u'λ', u'\\mu':u'μ', u'\\nu':u'ν', u'\\o':u'ø', u'\\oe':u'œ', u'\\omega':u'ω', u'\\phi':u'φ', u'\\pi':u'π', u'\\psi':u'ψ', u'\\rho':u'ρ', u'\\sampi':u'ϡ', u'\\sigma':u'σ', u'\\ss':u'ß', u'\\stigma':u'ϛ', u'\\tau':u'τ', u'\\tcohm':u'Ω', u'\\textcrh':u'ħ', u'\\th':u'þ', u'\\theta':u'θ', u'\\upsilon':u'υ', u'\\varDelta':u'∆', u'\\varGamma':u'Γ', u'\\varLambda':u'Λ', u'\\varOmega':u'Ω', u'\\varPhi':u'Φ', u'\\varPi':u'Π', u'\\varPsi':u'Ψ', u'\\varSigma':u'Σ', u'\\varTheta':u'Θ', u'\\varUpsilon':u'Υ', u'\\varXi':u'Ξ', u'\\varbeta':u'ϐ', u'\\varepsilon':u'ε', u'\\varkappa':u'ϰ', u'\\varphi':u'φ', u'\\varpi':u'ϖ', u'\\varrho':u'ϱ', u'\\varsigma':u'ς', u'\\vartheta':u'ϑ', u'\\xi':u'ξ', u'\\zeta':u'ζ', } array = { u'begin':u'\\begin', u'cellseparator':u'&', u'end':u'\\end', u'rowseparator':u'\\\\', } bigbrackets = { u'(':[u'⎛',u'⎜',u'⎝',], u')':[u'⎞',u'⎟',u'⎠',], u'[':[u'⎡',u'⎢',u'⎣',], u']':[u'⎤',u'⎥',u'⎦',], u'{':[u'⎧',u'⎪',u'⎨',u'⎩',], u'|':[u'|',], u'}':[u'⎫',u'⎪',u'⎬',u'⎭',], u'∥':[u'∥',], } bigsymbols = { u'∑':[u'⎲',u'⎳',], u'∫':[u'⌠',u'⌡',], } bracketcommands = { u'\\left':u'span class="symbol"', u'\\left.':u'', u'\\middle':u'span class="symbol"', u'\\right':u'span class="symbol"', u'\\right.':u'', } combiningfunctions = { u'\\"':u'̈', u'\\\'':u'́', u'\\^':u'̂', u'\\`':u'̀', u'\\acute':u'́', u'\\bar':u'̄', u'\\breve':u'̆', u'\\c':u'̧', u'\\check':u'̌', u'\\dddot':u'⃛', u'\\ddot':u'̈', u'\\dot':u'̇', u'\\grave':u'̀', u'\\hat':u'̂', u'\\mathring':u'̊', u'\\overleftarrow':u'⃖', u'\\overrightarrow':u'⃗', u'\\r':u'̊', u'\\s':u'̩', u'\\textcircled':u'⃝', u'\\textsubring':u'̥', u'\\tilde':u'̃', u'\\v':u'̌', u'\\vec':u'⃗', u'\\~':u'̃', } commands = { u'\\ ':u' ', u'\\!':u'', u'\\#':u'#', u'\\$':u'$', u'\\%':u'%', u'\\&':u'&', u'\\,':u' ', u'\\:':u' ', u'\\;':u' ', u'\\AC':u'∿', u'\\APLcomment':u'⍝', u'\\APLdownarrowbox':u'⍗', u'\\APLinput':u'⍞', u'\\APLinv':u'⌹', u'\\APLleftarrowbox':u'⍇', u'\\APLlog':u'⍟', u'\\APLrightarrowbox':u'⍈', u'\\APLuparrowbox':u'⍐', u'\\Box':u'□', u'\\Bumpeq':u'≎', u'\\CIRCLE':u'●', u'\\Cap':u'⋒', u'\\CapitalDifferentialD':u'ⅅ', u'\\CheckedBox':u'☑', u'\\Circle':u'○', u'\\Coloneqq':u'⩴', u'\\ComplexI':u'ⅈ', u'\\ComplexJ':u'ⅉ', u'\\Corresponds':u'≙', u'\\Cup':u'⋓', u'\\Delta':u'Δ', u'\\Diamond':u'◇', u'\\Diamondblack':u'◆', u'\\Diamonddot':u'⟐', u'\\DifferentialD':u'ⅆ', u'\\Downarrow':u'⇓', u'\\EUR':u'€', u'\\Euler':u'ℇ', u'\\ExponetialE':u'ⅇ', u'\\Finv':u'Ⅎ', u'\\Game':u'⅁', u'\\Gamma':u'Γ', u'\\Im':u'ℑ', u'\\Join':u'⨝', u'\\LEFTCIRCLE':u'◖', u'\\LEFTcircle':u'◐', u'\\LHD':u'◀', u'\\Lambda':u'Λ', u'\\Lbag':u'⟅', u'\\Leftarrow':u'⇐', u'\\Lleftarrow':u'⇚', u'\\Longleftarrow':u'⟸', u'\\Longleftrightarrow':u'⟺', u'\\Longrightarrow':u'⟹', u'\\Lparen':u'⦅', u'\\Lsh':u'↰', u'\\Mapsfrom':u'⇐|', u'\\Mapsto':u'|⇒', u'\\Omega':u'Ω', u'\\P':u'¶', u'\\Phi':u'Φ', u'\\Pi':u'Π', u'\\Pr':u'Pr', u'\\Psi':u'Ψ', u'\\Qoppa':u'Ϙ', u'\\RHD':u'▶', u'\\RIGHTCIRCLE':u'◗', u'\\RIGHTcircle':u'◑', u'\\Rbag':u'⟆', u'\\Re':u'ℜ', u'\\Rparen':u'⦆', u'\\Rrightarrow':u'⇛', u'\\Rsh':u'↱', u'\\S':u'§', u'\\Sigma':u'Σ', u'\\Square':u'☐', u'\\Subset':u'⋐', u'\\Sun':u'☉', u'\\Supset':u'⋑', u'\\Theta':u'Θ', u'\\Uparrow':u'⇑', u'\\Updownarrow':u'⇕', u'\\Upsilon':u'Υ', u'\\Vdash':u'⊩', u'\\Vert':u'∥', u'\\Vvdash':u'⊪', u'\\XBox':u'☒', u'\\Xi':u'Ξ', u'\\Yup':u'⅄', u'\\\\':u'
', u'\\_':u'_', u'\\aleph':u'ℵ', u'\\amalg':u'∐', u'\\anchor':u'⚓', u'\\angle':u'∠', u'\\aquarius':u'♒', u'\\arccos':u'arccos', u'\\arcsin':u'arcsin', u'\\arctan':u'arctan', u'\\arg':u'arg', u'\\aries':u'♈', u'\\arrowbullet':u'➢', u'\\ast':u'∗', u'\\asymp':u'≍', u'\\backepsilon':u'∍', u'\\backprime':u'‵', u'\\backsimeq':u'⋍', u'\\backslash':u'\\', u'\\ballotx':u'✗', u'\\barwedge':u'⊼', u'\\because':u'∵', u'\\beth':u'ℶ', u'\\between':u'≬', u'\\bigcap':u'∩', u'\\bigcirc':u'○', u'\\bigcup':u'∪', u'\\bigodot':u'⊙', u'\\bigoplus':u'⊕', u'\\bigotimes':u'⊗', u'\\bigsqcup':u'⊔', u'\\bigstar':u'★', u'\\bigtriangledown':u'▽', u'\\bigtriangleup':u'△', u'\\biguplus':u'⊎', u'\\bigvee':u'∨', u'\\bigwedge':u'∧', u'\\biohazard':u'☣', u'\\blacklozenge':u'⧫', u'\\blacksmiley':u'☻', u'\\blacksquare':u'■', u'\\blacktriangle':u'▲', u'\\blacktriangledown':u'▼', u'\\blacktriangleleft':u'◂', u'\\blacktriangleright':u'▶', u'\\blacktriangleup':u'▴', u'\\bot':u'⊥', u'\\bowtie':u'⋈', u'\\box':u'▫', u'\\boxast':u'⧆', u'\\boxbar':u'◫', u'\\boxbox':u'⧈', u'\\boxbslash':u'⧅', u'\\boxcircle':u'⧇', u'\\boxdot':u'⊡', u'\\boxminus':u'⊟', u'\\boxplus':u'⊞', u'\\boxslash':u'⧄', u'\\boxtimes':u'⊠', u'\\bullet':u'•', u'\\bumpeq':u'≏', u'\\cancer':u'♋', u'\\cap':u'∩', u'\\capricornus':u'♑', u'\\cat':u'⁀', u'\\cdot':u'⋅', u'\\cdots':u'⋯', u'\\cent':u'¢', u'\\centerdot':u'∙', u'\\checkmark':u'✓', u'\\chi':u'χ', u'\\circ':u'○', u'\\circeq':u'≗', u'\\circlearrowleft':u'↺', u'\\circlearrowright':u'↻', u'\\circledR':u'®', u'\\circledast':u'⊛', u'\\circledbslash':u'⦸', u'\\circledcirc':u'⊚', u'\\circleddash':u'⊝', u'\\circledgtr':u'⧁', u'\\circledless':u'⧀', u'\\clubsuit':u'♣', u'\\coloneqq':u'≔', u'\\complement':u'∁', u'\\cong':u'≅', u'\\coprod':u'∐', u'\\copyright':u'©', u'\\cos':u'cos', u'\\cosh':u'cosh', u'\\cot':u'cot', u'\\coth':u'coth', u'\\csc':u'csc', u'\\cup':u'∪', u'\\curlyvee':u'⋎', u'\\curlywedge':u'⋏', u'\\curvearrowleft':u'↶', u'\\curvearrowright':u'↷', u'\\dag':u'†', u'\\dagger':u'†', u'\\daleth':u'ℸ', u'\\dashleftarrow':u'⇠', u'\\dashv':u'⊣', u'\\ddag':u'‡', u'\\ddagger':u'‡', u'\\ddots':u'⋱', u'\\deg':u'deg', u'\\det':u'det', u'\\diagdown':u'╲', u'\\diagup':u'╱', u'\\diameter':u'⌀', u'\\diamond':u'◇', u'\\diamondsuit':u'♦', u'\\dim':u'dim', u'\\div':u'÷', u'\\divideontimes':u'⋇', u'\\dotdiv':u'∸', u'\\doteq':u'≐', u'\\doteqdot':u'≑', u'\\dotplus':u'∔', u'\\dots':u'…', u'\\doublebarwedge':u'⌆', u'\\downarrow':u'↓', u'\\downdownarrows':u'⇊', u'\\downharpoonleft':u'⇃', u'\\downharpoonright':u'⇂', u'\\dsub':u'⩤', u'\\earth':u'♁', u'\\eighthnote':u'♪', u'\\ell':u'ℓ', u'\\emptyset':u'∅', u'\\eqcirc':u'≖', u'\\eqcolon':u'≕', u'\\eqsim':u'≂', u'\\euro':u'€', u'\\exists':u'∃', u'\\exp':u'exp', u'\\fallingdotseq':u'≒', u'\\fcmp':u'⨾', u'\\female':u'♀', u'\\flat':u'♭', u'\\forall':u'∀', u'\\fourth':u'⁗', u'\\frown':u'⌢', u'\\frownie':u'☹', u'\\gcd':u'gcd', u'\\gemini':u'♊', u'\\geq)':u'≥', u'\\geqq':u'≧', u'\\geqslant':u'≥', u'\\gets':u'←', u'\\gg':u'≫', u'\\ggg':u'⋙', u'\\gimel':u'ℷ', u'\\gneqq':u'≩', u'\\gnsim':u'⋧', u'\\gtrdot':u'⋗', u'\\gtreqless':u'⋚', u'\\gtreqqless':u'⪌', u'\\gtrless':u'≷', u'\\gtrsim':u'≳', u'\\guillemotleft':u'«', u'\\guillemotright':u'»', u'\\hbar':u'ℏ', u'\\heartsuit':u'♥', u'\\hfill':u' ', u'\\hom':u'hom', u'\\hookleftarrow':u'↩', u'\\hookrightarrow':u'↪', u'\\hslash':u'ℏ', u'\\idotsint':u'∫⋯∫', u'\\iiint':u'', u'\\iint':u'', u'\\imath':u'ı', u'\\inf':u'inf', u'\\infty':u'∞', u'\\intercal':u'⊺', u'\\interleave':u'⫴', u'\\invamp':u'⅋', u'\\invneg':u'⌐', u'\\jmath':u'ȷ', u'\\jupiter':u'♃', u'\\ker':u'ker', u'\\land':u'∧', u'\\landupint':u'', u'\\lang':u'⟪', u'\\langle':u'⟨', u'\\lblot':u'⦉', u'\\lbrace':u'{', u'\\lbrace)':u'{', u'\\lbrack':u'[', u'\\lceil':u'⌈', u'\\ldots':u'…', u'\\leadsto':u'⇝', u'\\leftarrow)':u'←', u'\\leftarrowtail':u'↢', u'\\leftarrowtobar':u'⇤', u'\\leftharpoondown':u'↽', u'\\leftharpoonup':u'↼', u'\\leftleftarrows':u'⇇', u'\\leftleftharpoons':u'⥢', u'\\leftmoon':u'☾', u'\\leftrightarrow':u'↔', u'\\leftrightarrows':u'⇆', u'\\leftrightharpoons':u'⇋', u'\\leftthreetimes':u'⋋', u'\\leo':u'♌', u'\\leq)':u'≤', u'\\leqq':u'≦', u'\\leqslant':u'≤', u'\\lessdot':u'⋖', u'\\lesseqgtr':u'⋛', u'\\lesseqqgtr':u'⪋', u'\\lessgtr':u'≶', u'\\lesssim':u'≲', u'\\lfloor':u'⌊', u'\\lg':u'lg', u'\\lgroup':u'⟮', u'\\lhd':u'⊲', u'\\libra':u'♎', u'\\lightning':u'↯', u'\\limg':u'⦇', u'\\liminf':u'liminf', u'\\limsup':u'limsup', u'\\ll':u'≪', u'\\llbracket':u'⟦', u'\\llcorner':u'⌞', u'\\lll':u'⋘', u'\\ln':u'ln', u'\\lneqq':u'≨', u'\\lnot':u'¬', u'\\lnsim':u'⋦', u'\\log':u'log', u'\\longleftarrow':u'⟵', u'\\longleftrightarrow':u'⟷', u'\\longmapsto':u'⟼', u'\\longrightarrow':u'⟶', u'\\looparrowleft':u'↫', u'\\looparrowright':u'↬', u'\\lor':u'∨', u'\\lozenge':u'◊', u'\\lrcorner':u'⌟', u'\\ltimes':u'⋉', u'\\lyxlock':u'', u'\\male':u'♂', u'\\maltese':u'✠', u'\\mapsfrom':u'↤', u'\\mapsto':u'↦', u'\\mathcircumflex':u'^', u'\\max':u'max', u'\\measuredangle':u'∡', u'\\medbullet':u'⚫', u'\\medcirc':u'⚪', u'\\mercury':u'☿', u'\\mho':u'℧', u'\\mid':u'∣', u'\\min':u'min', u'\\models':u'⊨', u'\\mp':u'∓', u'\\multimap':u'⊸', u'\\nLeftarrow':u'⇍', u'\\nLeftrightarrow':u'⇎', u'\\nRightarrow':u'⇏', u'\\nVDash':u'⊯', u'\\nabla':u'∇', u'\\napprox':u'≉', u'\\natural':u'♮', u'\\ncong':u'≇', u'\\nearrow':u'↗', u'\\neg':u'¬', u'\\neg)':u'¬', u'\\neptune':u'♆', u'\\nequiv':u'≢', u'\\newline':u'
', u'\\nexists':u'∄', u'\\ngeqslant':u'≱', u'\\ngtr':u'≯', u'\\ngtrless':u'≹', u'\\ni':u'∋', u'\\ni)':u'∋', u'\\nleftarrow':u'↚', u'\\nleftrightarrow':u'↮', u'\\nleqslant':u'≰', u'\\nless':u'≮', u'\\nlessgtr':u'≸', u'\\nmid':u'∤', u'\\nolimits':u'', u'\\nonumber':u'', u'\\not':u'¬', u'\\not<':u'≮', u'\\not=':u'≠', u'\\not>':u'≯', u'\\notbackslash':u'⍀', u'\\notin':u'∉', u'\\notni':u'∌', u'\\notslash':u'⌿', u'\\nparallel':u'∦', u'\\nprec':u'⊀', u'\\nrightarrow':u'↛', u'\\nsim':u'≁', u'\\nsimeq':u'≄', u'\\nsqsubset':u'⊏̸', u'\\nsubseteq':u'⊈', u'\\nsucc':u'⊁', u'\\nsucccurlyeq':u'⋡', u'\\nsupset':u'⊅', u'\\nsupseteq':u'⊉', u'\\ntriangleleft':u'⋪', u'\\ntrianglelefteq':u'⋬', u'\\ntriangleright':u'⋫', u'\\ntrianglerighteq':u'⋭', u'\\nvDash':u'⊭', u'\\nvdash':u'⊬', u'\\nwarrow':u'↖', u'\\odot':u'⊙', u'\\officialeuro':u'€', u'\\oiiint':u'', u'\\oiint':u'', u'\\oint':u'', u'\\ointclockwise':u'', u'\\ointctrclockwise':u'', u'\\ominus':u'⊖', u'\\oplus':u'⊕', u'\\oslash':u'⊘', u'\\otimes':u'⊗', u'\\owns':u'∋', u'\\parallel':u'∥', u'\\partial':u'∂', u'\\pencil':u'✎', u'\\perp':u'⊥', u'\\pisces':u'♓', u'\\pitchfork':u'⋔', u'\\pluto':u'♇', u'\\pm':u'±', u'\\pointer':u'➪', u'\\pointright':u'☞', u'\\pounds':u'£', u'\\prec':u'≺', u'\\preccurlyeq':u'≼', u'\\preceq':u'≼', u'\\precsim':u'≾', u'\\prime':u'′', u'\\prompto':u'∝', u'\\qoppa':u'ϙ', u'\\qquad':u' ', u'\\quad':u' ', u'\\quarternote':u'♩', u'\\radiation':u'☢', u'\\rang':u'⟫', u'\\rangle':u'⟩', u'\\rblot':u'⦊', u'\\rbrace':u'}', u'\\rbrace)':u'}', u'\\rbrack':u']', u'\\rceil':u'⌉', u'\\recycle':u'♻', u'\\rfloor':u'⌋', u'\\rgroup':u'⟯', u'\\rhd':u'⊳', u'\\rightangle':u'∟', u'\\rightarrow)':u'→', u'\\rightarrowtail':u'↣', u'\\rightarrowtobar':u'⇥', u'\\rightharpoondown':u'⇁', u'\\rightharpoonup':u'⇀', u'\\rightharpooondown':u'⇁', u'\\rightharpooonup':u'⇀', u'\\rightleftarrows':u'⇄', u'\\rightleftharpoons':u'⇌', u'\\rightmoon':u'☽', u'\\rightrightarrows':u'⇉', u'\\rightrightharpoons':u'⥤', u'\\rightthreetimes':u'⋌', u'\\rimg':u'⦈', u'\\risingdotseq':u'≓', u'\\rrbracket':u'⟧', u'\\rsub':u'⩥', u'\\rtimes':u'⋊', u'\\sagittarius':u'♐', u'\\saturn':u'♄', u'\\scorpio':u'♏', u'\\searrow':u'↘', u'\\sec':u'sec', u'\\second':u'″', u'\\setminus':u'∖', u'\\sharp':u'♯', u'\\simeq':u'≃', u'\\sin':u'sin', u'\\sinh':u'sinh', u'\\sixteenthnote':u'♬', u'\\skull':u'☠', u'\\slash':u'∕', u'\\smallsetminus':u'∖', u'\\smalltriangledown':u'▿', u'\\smalltriangleleft':u'◃', u'\\smalltriangleright':u'▹', u'\\smalltriangleup':u'▵', u'\\smile':u'⌣', u'\\smiley':u'☺', u'\\spadesuit':u'♠', u'\\spddot':u'¨', u'\\sphat':u'', u'\\sphericalangle':u'∢', u'\\spot':u'⦁', u'\\sptilde':u'~', u'\\sqcap':u'⊓', u'\\sqcup':u'⊔', u'\\sqsubset':u'⊏', u'\\sqsubseteq':u'⊑', u'\\sqsupset':u'⊐', u'\\sqsupseteq':u'⊒', u'\\square':u'□', u'\\sslash':u'⫽', u'\\star':u'⋆', u'\\steaming':u'☕', u'\\subseteqq':u'⫅', u'\\subsetneqq':u'⫋', u'\\succ':u'≻', u'\\succcurlyeq':u'≽', u'\\succeq':u'≽', u'\\succnsim':u'⋩', u'\\succsim':u'≿', u'\\sun':u'☼', u'\\sup':u'sup', u'\\supseteqq':u'⫆', u'\\supsetneqq':u'⫌', u'\\surd':u'√', u'\\swarrow':u'↙', u'\\swords':u'⚔', u'\\talloblong':u'⫾', u'\\tan':u'tan', u'\\tanh':u'tanh', u'\\taurus':u'♉', u'\\textasciicircum':u'^', u'\\textasciitilde':u'~', u'\\textbackslash':u'\\', u'\\textcopyright':u'©\'', u'\\textdegree':u'°', u'\\textellipsis':u'…', u'\\textemdash':u'—', u'\\textendash':u'—', u'\\texteuro':u'€', u'\\textgreater':u'>', u'\\textless':u'<', u'\\textordfeminine':u'ª', u'\\textordmasculine':u'º', u'\\textquotedblleft':u'“', u'\\textquotedblright':u'”', u'\\textquoteright':u'’', u'\\textregistered':u'®', u'\\textrightarrow':u'→', u'\\textsection':u'§', u'\\texttrademark':u'™', u'\\texttwosuperior':u'²', u'\\textvisiblespace':u' ', u'\\therefore':u'∴', u'\\third':u'‴', u'\\top':u'⊤', u'\\triangle':u'△', u'\\triangleleft':u'⊲', u'\\trianglelefteq':u'⊴', u'\\triangleq':u'≜', u'\\triangleright':u'▷', u'\\trianglerighteq':u'⊵', u'\\twoheadleftarrow':u'↞', u'\\twoheadrightarrow':u'↠', u'\\twonotes':u'♫', u'\\udot':u'⊍', u'\\ulcorner':u'⌜', u'\\unlhd':u'⊴', u'\\unrhd':u'⊵', u'\\unrhl':u'⊵', u'\\uparrow':u'↑', u'\\updownarrow':u'↕', u'\\upharpoonleft':u'↿', u'\\upharpoonright':u'↾', u'\\uplus':u'⊎', u'\\upuparrows':u'⇈', u'\\uranus':u'♅', u'\\urcorner':u'⌝', u'\\vDash':u'⊨', u'\\varclubsuit':u'♧', u'\\vardiamondsuit':u'♦', u'\\varheartsuit':u'♥', u'\\varnothing':u'∅', u'\\varspadesuit':u'♤', u'\\vdash':u'⊢', u'\\vdots':u'⋮', u'\\vee':u'∨', u'\\vee)':u'∨', u'\\veebar':u'⊻', u'\\vert':u'∣', u'\\virgo':u'♍', u'\\warning':u'⚠', u'\\wasylozenge':u'⌑', u'\\wedge':u'∧', u'\\wedge)':u'∧', u'\\wp':u'℘', u'\\wr':u'≀', u'\\yen':u'¥', u'\\yinyang':u'☯', u'\\{':u'{', u'\\|':u'∥', u'\\}':u'}', } decoratedcommand = { } decoratingfunctions = { u'\\overleftarrow':u'⟵', u'\\overrightarrow':u'⟶', u'\\widehat':u'^', } endings = { u'bracket':u'}', u'complex':u'\\]', u'endafter':u'}', u'endbefore':u'\\end{', u'squarebracket':u']', } environments = { u'align':[u'r',u'l',], u'eqnarray':[u'r',u'c',u'l',], u'gathered':[u'l',u'l',], } fontfunctions = { u'\\boldsymbol':u'b', u'\\mathbb':u'span class="blackboard"', u'\\mathbb{A}':u'𝔸', u'\\mathbb{B}':u'𝔹', u'\\mathbb{C}':u'ℂ', u'\\mathbb{D}':u'𝔻', u'\\mathbb{E}':u'𝔼', u'\\mathbb{F}':u'𝔽', u'\\mathbb{G}':u'𝔾', u'\\mathbb{H}':u'ℍ', u'\\mathbb{J}':u'𝕁', u'\\mathbb{K}':u'𝕂', u'\\mathbb{L}':u'𝕃', u'\\mathbb{N}':u'ℕ', u'\\mathbb{O}':u'𝕆', u'\\mathbb{P}':u'ℙ', u'\\mathbb{Q}':u'ℚ', u'\\mathbb{R}':u'ℝ', u'\\mathbb{S}':u'𝕊', u'\\mathbb{T}':u'𝕋', u'\\mathbb{W}':u'𝕎', u'\\mathbb{Z}':u'ℤ', u'\\mathbf':u'b', u'\\mathcal':u'span class="scriptfont"', u'\\mathcal{B}':u'ℬ', u'\\mathcal{E}':u'ℰ', u'\\mathcal{F}':u'ℱ', u'\\mathcal{H}':u'ℋ', u'\\mathcal{I}':u'ℐ', u'\\mathcal{L}':u'ℒ', u'\\mathcal{M}':u'ℳ', u'\\mathcal{R}':u'ℛ', u'\\mathfrak':u'span class="fraktur"', u'\\mathfrak{C}':u'ℭ', u'\\mathfrak{F}':u'𝔉', u'\\mathfrak{H}':u'ℌ', u'\\mathfrak{I}':u'ℑ', u'\\mathfrak{R}':u'ℜ', u'\\mathfrak{Z}':u'ℨ', u'\\mathit':u'i', u'\\mathring{A}':u'Å', u'\\mathring{U}':u'Ů', u'\\mathring{a}':u'å', u'\\mathring{u}':u'ů', u'\\mathring{w}':u'ẘ', u'\\mathring{y}':u'ẙ', u'\\mathrm':u'span class="mathrm"', u'\\mathscr':u'span class="scriptfont"', u'\\mathscr{B}':u'ℬ', u'\\mathscr{E}':u'ℰ', u'\\mathscr{F}':u'ℱ', u'\\mathscr{H}':u'ℋ', u'\\mathscr{I}':u'ℐ', u'\\mathscr{L}':u'ℒ', u'\\mathscr{M}':u'ℳ', u'\\mathscr{R}':u'ℛ', u'\\mathsf':u'span class="mathsf"', u'\\mathtt':u'tt', } hybridfunctions = { u'\\addcontentsline':[u'{$p!}{$q!}{$r!}',u'f0{}',u'ignored',], u'\\addtocontents':[u'{$p!}{$q!}',u'f0{}',u'ignored',], u'\\backmatter':[u'',u'f0{}',u'ignored',], u'\\binom':[u'{$1}{$2}',u'f2{(}f0{f1{$1}f1{$2}}f2{)}',u'span class="binom"',u'span class="binomstack"',u'span class="bigsymbol"',], u'\\boxed':[u'{$1}',u'f0{$1}',u'span class="boxed"',], u'\\cfrac':[u'[$p!]{$1}{$2}',u'f0{f3{(}f1{$1}f3{)/(}f2{$2}f3{)}}',u'span class="fullfraction"',u'span class="numerator align-$p"',u'span class="denominator"',u'span class="ignored"',], u'\\color':[u'{$p!}{$1}',u'f0{$1}',u'span style="color: $p;"',], u'\\colorbox':[u'{$p!}{$1}',u'f0{$1}',u'span class="colorbox" style="background: $p;"',], u'\\dbinom':[u'{$1}{$2}',u'(f0{f1{f2{$1}}f1{f2{ }}f1{f2{$2}}})',u'span class="binomial"',u'span class="binomrow"',u'span class="binomcell"',], u'\\dfrac':[u'{$1}{$2}',u'f0{f3{(}f1{$1}f3{)/(}f2{$2}f3{)}}',u'span class="fullfraction"',u'span class="numerator"',u'span class="denominator"',u'span class="ignored"',], u'\\displaystyle':[u'{$1}',u'f0{$1}',u'span class="displaystyle"',], u'\\fancyfoot':[u'[$p!]{$q!}',u'f0{}',u'ignored',], u'\\fancyhead':[u'[$p!]{$q!}',u'f0{}',u'ignored',], u'\\fbox':[u'{$1}',u'f0{$1}',u'span class="fbox"',], u'\\fboxrule':[u'{$p!}',u'f0{}',u'ignored',], u'\\fboxsep':[u'{$p!}',u'f0{}',u'ignored',], u'\\fcolorbox':[u'{$p!}{$q!}{$1}',u'f0{$1}',u'span class="boxed" style="border-color: $p; background: $q;"',], u'\\frac':[u'{$1}{$2}',u'f0{f3{(}f1{$1}f3{)/(}f2{$2}f3{)}}',u'span class="fraction"',u'span class="numerator"',u'span class="denominator"',u'span class="ignored"',], u'\\framebox':[u'[$p!][$q!]{$1}',u'f0{$1}',u'span class="framebox align-$q" style="width: $p;"',], u'\\frontmatter':[u'',u'f0{}',u'ignored',], u'\\href':[u'[$o]{$u!}{$t!}',u'f0{$t}',u'a href="$u"',], u'\\hspace':[u'{$p!}',u'f0{ }',u'span class="hspace" style="width: $p;"',], u'\\leftroot':[u'{$p!}',u'f0{ }',u'span class="leftroot" style="width: $p;px"',], u'\\mainmatter':[u'',u'f0{}',u'ignored',], u'\\markboth':[u'{$p!}{$q!}',u'f0{}',u'ignored',], u'\\markright':[u'{$p!}',u'f0{}',u'ignored',], u'\\nicefrac':[u'{$1}{$2}',u'f0{f1{$1}⁄f2{$2}}',u'span class="fraction"',u'sup class="numerator"',u'sub class="denominator"',u'span class="ignored"',], u'\\parbox':[u'[$p!]{$w!}{$1}',u'f0{1}',u'div class="Boxed" style="width: $w;"',], u'\\raisebox':[u'{$p!}{$1}',u'f0{$1.font}',u'span class="raisebox" style="vertical-align: $p;"',], u'\\renewenvironment':[u'{$1!}{$2!}{$3!}',u'',], u'\\rule':[u'[$v!]{$w!}{$h!}',u'f0/',u'hr class="line" style="width: $w; height: $h;"',], u'\\scriptscriptstyle':[u'{$1}',u'f0{$1}',u'span class="scriptscriptstyle"',], u'\\scriptstyle':[u'{$1}',u'f0{$1}',u'span class="scriptstyle"',], u'\\sqrt':[u'[$0]{$1}',u'f0{f1{$0}f2{√}f4{(}f3{$1}f4{)}}',u'span class="sqrt"',u'sup class="root"',u'span class="radical"',u'span class="root"',u'span class="ignored"',], u'\\stackrel':[u'{$1}{$2}',u'f0{f1{$1}f2{$2}}',u'span class="stackrel"',u'span class="upstackrel"',u'span class="downstackrel"',], u'\\tbinom':[u'{$1}{$2}',u'(f0{f1{f2{$1}}f1{f2{ }}f1{f2{$2}}})',u'span class="binomial"',u'span class="binomrow"',u'span class="binomcell"',], u'\\textcolor':[u'{$p!}{$1}',u'f0{$1}',u'span style="color: $p;"',], u'\\textstyle':[u'{$1}',u'f0{$1}',u'span class="textstyle"',], u'\\thispagestyle':[u'{$p!}',u'f0{}',u'ignored',], u'\\unit':[u'[$0]{$1}',u'$0f0{$1.font}',u'span class="unit"',], u'\\unitfrac':[u'[$0]{$1}{$2}',u'$0f0{f1{$1.font}⁄f2{$2.font}}',u'span class="fraction"',u'sup class="unit"',u'sub class="unit"',], u'\\uproot':[u'{$p!}',u'f0{ }',u'span class="uproot" style="width: $p;px"',], u'\\url':[u'{$u!}',u'f0{$u}',u'a href="$u"',], u'\\vspace':[u'{$p!}',u'f0{ }',u'span class="vspace" style="height: $p;"',], } hybridsizes = { u'\\binom':u'$1+$2', u'\\cfrac':u'$1+$2', u'\\dbinom':u'$1+$2+1', u'\\dfrac':u'$1+$2', u'\\frac':u'$1+$2', u'\\tbinom':u'$1+$2+1', } labelfunctions = { u'\\label':u'a name="#"', } limitcommands = { u'\\biginterleave':u'⫼', u'\\bigsqcap':u'⨅', u'\\fint':u'⨏', u'\\iiiint':u'⨌', u'\\int':u'∫', u'\\intop':u'∫', u'\\lim':u'lim', u'\\prod':u'∏', u'\\smallint':u'∫', u'\\sqint':u'⨖', u'\\sum':u'∑', u'\\varointclockwise':u'∲', u'\\varprod':u'⨉', u'\\zcmp':u'⨟', u'\\zhide':u'⧹', u'\\zpipe':u'⨠', u'\\zproject':u'⨡', } misccommands = { u'\\limits':u'LimitPreviousCommand', u'\\newcommand':u'MacroDefinition', u'\\renewcommand':u'MacroDefinition', u'\\setcounter':u'SetCounterFunction', u'\\tag':u'FormulaTag', u'\\tag*':u'FormulaTag', u'\\today':u'TodayCommand', } modified = { u'\n':u'', u' ':u'', u'$':u'', u'&':u' ', u'\'':u'’', u'+':u' + ', u',':u', ', u'-':u' − ', u'/':u' ⁄ ', u'<':u' < ', u'=':u' = ', u'>':u' > ', u'@':u'', u'~':u'', } onefunctions = { u'\\Big':u'span class="bigsymbol"', u'\\Bigg':u'span class="hugesymbol"', u'\\bar':u'span class="bar"', u'\\begin{array}':u'span class="arraydef"', u'\\big':u'span class="symbol"', u'\\bigg':u'span class="largesymbol"', u'\\bigl':u'span class="bigsymbol"', u'\\bigr':u'span class="bigsymbol"', u'\\centering':u'span class="align-center"', u'\\ensuremath':u'span class="ensuremath"', u'\\hphantom':u'span class="phantom"', u'\\noindent':u'span class="noindent"', u'\\overbrace':u'span class="overbrace"', u'\\overline':u'span class="overline"', u'\\phantom':u'span class="phantom"', u'\\underbrace':u'span class="underbrace"', u'\\underline':u'u', u'\\vphantom':u'span class="phantom"', } spacedcommands = { u'\\Bot':u'⫫', u'\\Doteq':u'≑', u'\\DownArrowBar':u'⤓', u'\\DownLeftTeeVector':u'⥞', u'\\DownLeftVectorBar':u'⥖', u'\\DownRightTeeVector':u'⥟', u'\\DownRightVectorBar':u'⥗', u'\\Equal':u'⩵', u'\\LeftArrowBar':u'⇤', u'\\LeftDownTeeVector':u'⥡', u'\\LeftDownVectorBar':u'⥙', u'\\LeftTeeVector':u'⥚', u'\\LeftTriangleBar':u'⧏', u'\\LeftUpTeeVector':u'⥠', u'\\LeftUpVectorBar':u'⥘', u'\\LeftVectorBar':u'⥒', u'\\Leftrightarrow':u'⇔', u'\\Longmapsfrom':u'⟽', u'\\Longmapsto':u'⟾', u'\\MapsDown':u'↧', u'\\MapsUp':u'↥', u'\\Nearrow':u'⇗', u'\\NestedGreaterGreater':u'⪢', u'\\NestedLessLess':u'⪡', u'\\NotGreaterLess':u'≹', u'\\NotGreaterTilde':u'≵', u'\\NotLessTilde':u'≴', u'\\Nwarrow':u'⇖', u'\\Proportion':u'∷', u'\\RightArrowBar':u'⇥', u'\\RightDownTeeVector':u'⥝', u'\\RightDownVectorBar':u'⥕', u'\\RightTeeVector':u'⥛', u'\\RightTriangleBar':u'⧐', u'\\RightUpTeeVector':u'⥜', u'\\RightUpVectorBar':u'⥔', u'\\RightVectorBar':u'⥓', u'\\Rightarrow':u'⇒', u'\\Same':u'⩶', u'\\Searrow':u'⇘', u'\\Swarrow':u'⇙', u'\\Top':u'⫪', u'\\UpArrowBar':u'⤒', u'\\VDash':u'⊫', u'\\approx':u'≈', u'\\approxeq':u'≊', u'\\backsim':u'∽', u'\\barin':u'⋶', u'\\barleftharpoon':u'⥫', u'\\barrightharpoon':u'⥭', u'\\bij':u'⤖', u'\\coloneq':u'≔', u'\\corresponds':u'≙', u'\\curlyeqprec':u'⋞', u'\\curlyeqsucc':u'⋟', u'\\dashrightarrow':u'⇢', u'\\dlsh':u'↲', u'\\downdownharpoons':u'⥥', u'\\downuparrows':u'⇵', u'\\downupharpoons':u'⥯', u'\\drsh':u'↳', u'\\eqslantgtr':u'⪖', u'\\eqslantless':u'⪕', u'\\equiv':u'≡', u'\\ffun':u'⇻', u'\\finj':u'⤕', u'\\ge':u'≥', u'\\geq':u'≥', u'\\ggcurly':u'⪼', u'\\gnapprox':u'⪊', u'\\gneq':u'⪈', u'\\gtrapprox':u'⪆', u'\\hash':u'⋕', u'\\iddots':u'⋰', u'\\implies':u' ⇒ ', u'\\in':u'∈', u'\\le':u'≤', u'\\leftarrow':u'←', u'\\leftarrowtriangle':u'⇽', u'\\leftbarharpoon':u'⥪', u'\\leftrightarrowtriangle':u'⇿', u'\\leftrightharpoon':u'⥊', u'\\leftrightharpoondown':u'⥐', u'\\leftrightharpoonup':u'⥎', u'\\leftrightsquigarrow':u'↭', u'\\leftslice':u'⪦', u'\\leftsquigarrow':u'⇜', u'\\leftupdownharpoon':u'⥑', u'\\leq':u'≤', u'\\lessapprox':u'⪅', u'\\llcurly':u'⪻', u'\\lnapprox':u'⪉', u'\\lneq':u'⪇', u'\\longmapsfrom':u'⟻', u'\\multimapboth':u'⧟', u'\\multimapdotbothA':u'⊶', u'\\multimapdotbothB':u'⊷', u'\\multimapinv':u'⟜', u'\\nVdash':u'⊮', u'\\ne':u'≠', u'\\neq':u'≠', u'\\ngeq':u'≱', u'\\nleq':u'≰', u'\\nni':u'∌', u'\\not\\in':u'∉', u'\\notasymp':u'≭', u'\\npreceq':u'⋠', u'\\nsqsubseteq':u'⋢', u'\\nsqsupseteq':u'⋣', u'\\nsubset':u'⊄', u'\\nsucceq':u'⋡', u'\\pfun':u'⇸', u'\\pinj':u'⤔', u'\\precapprox':u'⪷', u'\\preceqq':u'⪳', u'\\precnapprox':u'⪹', u'\\precnsim':u'⋨', u'\\propto':u'∝', u'\\psur':u'⤀', u'\\rightarrow':u'→', u'\\rightarrowtriangle':u'⇾', u'\\rightbarharpoon':u'⥬', u'\\rightleftharpoon':u'⥋', u'\\rightslice':u'⪧', u'\\rightsquigarrow':u'⇝', u'\\rightupdownharpoon':u'⥏', u'\\sim':u'~', u'\\strictfi':u'⥼', u'\\strictif':u'⥽', u'\\subset':u'⊂', u'\\subseteq':u'⊆', u'\\subsetneq':u'⊊', u'\\succapprox':u'⪸', u'\\succeqq':u'⪴', u'\\succnapprox':u'⪺', u'\\supset':u'⊃', u'\\supseteq':u'⊇', u'\\supsetneq':u'⊋', u'\\times':u'×', u'\\to':u'→', u'\\updownarrows':u'⇅', u'\\updownharpoons':u'⥮', u'\\upupharpoons':u'⥣', u'\\vartriangleleft':u'⊲', u'\\vartriangleright':u'⊳', } starts = { u'beginafter':u'}', u'beginbefore':u'\\begin{', u'bracket':u'{', u'command':u'\\', u'comment':u'%', u'complex':u'\\[', u'simple':u'$', u'squarebracket':u'[', u'unnumbered':u'*', } symbolfunctions = { u'^':u'sup', u'_':u'sub', } textfunctions = { u'\\mbox':u'span class="mbox"', u'\\text':u'span class="text"', u'\\textbf':u'b', u'\\textipa':u'span class="textipa"', u'\\textit':u'i', u'\\textnormal':u'span class="textnormal"', u'\\textrm':u'span class="textrm"', u'\\textsc':u'span class="versalitas"', u'\\textsf':u'span class="textsf"', u'\\textsl':u'i', u'\\texttt':u'tt', u'\\textup':u'span class="normal"', } unmodified = { u'characters':[u'.',u'*',u'€',u'(',u')',u'[',u']',u':',u'·',u'!',u';',u'|',u'§',u'"',], } urls = { u'googlecharts':u'http://chart.googleapis.com/chart?cht=tx&chl=', } class GeneralConfig(object): "Configuration class from elyxer.config file" version = { u'date':u'2013-03-10', u'lyxformat':u'413', u'number':u'1.2.5', } class HeaderConfig(object): "Configuration class from elyxer.config file" parameters = { u'beginpreamble':u'\\begin_preamble', u'branch':u'\\branch', u'documentclass':u'\\textclass', u'endbranch':u'\\end_branch', u'endpreamble':u'\\end_preamble', u'language':u'\\language', u'lstset':u'\\lstset', u'outputchanges':u'\\output_changes', u'paragraphseparation':u'\\paragraph_separation', u'pdftitle':u'\\pdf_title', u'secnumdepth':u'\\secnumdepth', u'tocdepth':u'\\tocdepth', } styles = { u'article':[u'article',u'aastex',u'aapaper',u'acmsiggraph',u'sigplanconf',u'achemso',u'amsart',u'apa',u'arab-article',u'armenian-article',u'article-beamer',u'chess',u'dtk',u'elsarticle',u'heb-article',u'IEEEtran',u'iopart',u'kluwer',u'scrarticle-beamer',u'scrartcl',u'extarticle',u'paper',u'mwart',u'revtex4',u'spie',u'svglobal3',u'ltugboat',u'agu-dtd',u'jgrga',u'agums',u'entcs',u'egs',u'ijmpc',u'ijmpd',u'singlecol-new',u'doublecol-new',u'isprs',u'tarticle',u'jsarticle',u'jarticle',u'jss',u'literate-article',u'siamltex',u'cl2emult',u'llncs',u'svglobal',u'svjog',u'svprobth',], u'book':[u'book',u'amsbook',u'scrbook',u'extbook',u'tufte-book',u'report',u'extreport',u'scrreprt',u'memoir',u'tbook',u'jsbook',u'jbook',u'mwbk',u'svmono',u'svmult',u'treport',u'jreport',u'mwrep',], } class ImageConfig(object): "Configuration class from elyxer.config file" converters = { u'imagemagick':u'convert[ -density $scale][ -define $format:use-cropbox=true] "$input" "$output"', u'inkscape':u'inkscape "$input" --export-png="$output"', u'lyx':u'lyx -C "$input" "$output"', } cropboxformats = { u'.eps':u'ps', u'.pdf':u'pdf', u'.ps':u'ps', } formats = { u'default':u'.png', u'vector':[u'.svg',u'.eps',], } class LayoutConfig(object): "Configuration class from elyxer.config file" groupable = { u'allowed':[u'StringContainer',u'Constant',u'TaggedText',u'Align',u'TextFamily',u'EmphaticText',u'VersalitasText',u'BarredText',u'SizeText',u'ColorText',u'LangLine',u'Formula',], } class NewfangleConfig(object): "Configuration class from elyxer.config file" constants = { u'chunkref':u'chunkref{', u'endcommand':u'}', u'endmark':u'>', u'startcommand':u'\\', u'startmark':u'=<', } class NumberingConfig(object): "Configuration class from elyxer.config file" layouts = { u'ordered':[u'Chapter',u'Section',u'Subsection',u'Subsubsection',u'Paragraph',], u'roman':[u'Part',u'Book',], } sequence = { u'symbols':[u'*',u'**',u'†',u'‡',u'§',u'§§',u'¶',u'¶¶',u'#',u'##',], } class StyleConfig(object): "Configuration class from elyxer.config file" hspaces = { u'\\enskip{}':u' ', u'\\hfill{}':u' ', u'\\hspace*{\\fill}':u' ', u'\\hspace*{}':u'', u'\\hspace{}':u' ', u'\\negthinspace{}':u'', u'\\qquad{}':u'  ', u'\\quad{}':u' ', u'\\space{}':u' ', u'\\thinspace{}':u' ', u'~':u' ', } quotes = { u'ald':u'»', u'als':u'›', u'ard':u'«', u'ars':u'‹', u'eld':u'“', u'els':u'‘', u'erd':u'”', u'ers':u'’', u'fld':u'«', u'fls':u'‹', u'frd':u'»', u'frs':u'›', u'gld':u'„', u'gls':u'‚', u'grd':u'“', u'grs':u'‘', u'pld':u'„', u'pls':u'‚', u'prd':u'”', u'prs':u'’', u'sld':u'”', u'srd':u'”', } referenceformats = { u'eqref':u'(@↕)', u'formatted':u'¶↕', u'nameref':u'$↕', u'pageref':u'#↕', u'ref':u'@↕', u'vpageref':u'on-page#↕', u'vref':u'@on-page#↕', } size = { u'ignoredtexts':[u'col',u'text',u'line',u'page',u'theight',u'pheight',], } vspaces = { u'bigskip':u'
', u'defskip':u'
', u'medskip':u'
', u'smallskip':u'
', u'vfill':u'
', } class TOCConfig(object): "Configuration class from elyxer.config file" extractplain = { u'allowed':[u'StringContainer',u'Constant',u'TaggedText',u'Align',u'TextFamily',u'EmphaticText',u'VersalitasText',u'BarredText',u'SizeText',u'ColorText',u'LangLine',u'Formula',], u'cloned':[u'',], u'extracted':[u'',], } extracttitle = { u'allowed':[u'StringContainer',u'Constant',u'Space',], u'cloned':[u'TextFamily',u'EmphaticText',u'VersalitasText',u'BarredText',u'SizeText',u'ColorText',u'LangLine',u'Formula',], u'extracted':[u'PlainLayout',u'TaggedText',u'Align',u'Caption',u'StandardLayout',u'FlexInset',], } class TagConfig(object): "Configuration class from elyxer.config file" barred = { u'under':u'u', } family = { u'sans':u'span class="sans"', u'typewriter':u'tt', } flex = { u'CharStyle:Code':u'span class="code"', u'CharStyle:MenuItem':u'span class="menuitem"', u'Code':u'span class="code"', u'MenuItem':u'span class="menuitem"', u'Noun':u'span class="noun"', u'Strong':u'span class="strong"', } group = { u'layouts':[u'Quotation',u'Quote',], } layouts = { u'Center':u'div', u'Chapter':u'h?', u'Date':u'h2', u'Paragraph':u'div', u'Part':u'h1', u'Quotation':u'blockquote', u'Quote':u'blockquote', u'Section':u'h?', u'Subsection':u'h?', u'Subsubsection':u'h?', } listitems = { u'Enumerate':u'ol', u'Itemize':u'ul', } notes = { u'Comment':u'', u'Greyedout':u'span class="greyedout"', u'Note':u'', } script = { u'subscript':u'sub', u'superscript':u'sup', } shaped = { u'italic':u'i', u'slanted':u'i', u'smallcaps':u'span class="versalitas"', } class TranslationConfig(object): "Configuration class from elyxer.config file" constants = { u'Appendix':u'Appendix', u'Book':u'Book', u'Chapter':u'Chapter', u'Paragraph':u'Paragraph', u'Part':u'Part', u'Section':u'Section', u'Subsection':u'Subsection', u'Subsubsection':u'Subsubsection', u'abstract':u'Abstract', u'bibliography':u'Bibliography', u'figure':u'figure', u'float-algorithm':u'Algorithm ', u'float-figure':u'Figure ', u'float-listing':u'Listing ', u'float-table':u'Table ', u'float-tableau':u'Tableau ', u'footnotes':u'Footnotes', u'generated-by':u'Document generated by ', u'generated-on':u' on ', u'index':u'Index', u'jsmath-enable':u'Please enable JavaScript on your browser.', u'jsmath-requires':u' requires JavaScript to correctly process the mathematics on this page. ', u'jsmath-warning':u'Warning: ', u'list-algorithm':u'List of Algorithms', u'list-figure':u'List of Figures', u'list-table':u'List of Tables', u'list-tableau':u'List of Tableaux', u'main-page':u'Main page', u'next':u'Next', u'nomenclature':u'Nomenclature', u'on-page':u' on page ', u'prev':u'Prev', u'references':u'References', u'toc':u'Table of Contents', u'toc-for':u'Contents for ', u'up':u'Up', } languages = { u'american':u'en', u'british':u'en', u'deutsch':u'de', u'dutch':u'nl', u'english':u'en', u'french':u'fr', u'ngerman':u'de', u'russian':u'ru', u'spanish':u'es', } class CommandLineParser(object): "A parser for runtime options" def __init__(self, options): self.options = options def parseoptions(self, args): "Parse command line options" if len(args) == 0: return None while len(args) > 0 and args[0].startswith('--'): key, value = self.readoption(args) if not key: return 'Option ' + value + ' not recognized' if not value: return 'Option ' + key + ' needs a value' setattr(self.options, key, value) return None def readoption(self, args): "Read the key and value for an option" arg = args[0][2:] del args[0] if '=' in arg: key = self.readequalskey(arg, args) else: key = arg.replace('-', '') if not hasattr(self.options, key): return None, key current = getattr(self.options, key) if isinstance(current, bool): return key, True # read value if len(args) == 0: return key, None if args[0].startswith('"'): initial = args[0] del args[0] return key, self.readquoted(args, initial) value = args[0].decode('utf-8') del args[0] if isinstance(current, list): current.append(value) return key, current return key, value def readquoted(self, args, initial): "Read a value between quotes" Trace.error('Oops') value = initial[1:] while len(args) > 0 and not args[0].endswith('"') and not args[0].startswith('--'): Trace.error('Appending ' + args[0]) value += ' ' + args[0] del args[0] if len(args) == 0 or args[0].startswith('--'): return None value += ' ' + args[0:-1] return value def readequalskey(self, arg, args): "Read a key using equals" split = arg.split('=', 1) key = split[0] value = split[1] args.insert(0, value) return key class Options(object): "A set of runtime options" instance = None location = None nocopy = False copyright = False debug = False quiet = False version = False hardversion = False versiondate = False html = False help = False showlines = True unicode = False iso885915 = False css = [] title = None directory = None destdirectory = None toc = False toctarget = '' tocfor = None forceformat = None lyxformat = False target = None splitpart = None memory = True lowmem = False nobib = False converter = 'imagemagick' raw = False jsmath = None mathjax = None nofooter = False simplemath = False template = None noconvert = False notoclabels = False letterfoot = True numberfoot = False symbolfoot = False hoverfoot = True marginfoot = False endfoot = False supfoot = True alignfoot = False footnotes = None imageformat = None copyimages = False googlecharts = False embedcss = [] branches = dict() def parseoptions(self, args): "Parse command line options" Options.location = args[0] del args[0] parser = CommandLineParser(Options) result = parser.parseoptions(args) if result: Trace.error(result) self.usage() self.processoptions() def processoptions(self): "Process all options parsed." if Options.help: self.usage() if Options.version: self.showversion() if Options.hardversion: self.showhardversion() if Options.versiondate: self.showversiondate() if Options.lyxformat: self.showlyxformat() if Options.splitpart: try: Options.splitpart = int(Options.splitpart) if Options.splitpart <= 0: Trace.error('--splitpart requires a number bigger than zero') self.usage() except: Trace.error('--splitpart needs a numeric argument, not ' + Options.splitpart) self.usage() if Options.lowmem or Options.toc or Options.tocfor: Options.memory = False self.parsefootnotes() if Options.forceformat and not Options.imageformat: Options.imageformat = Options.forceformat if Options.imageformat == 'copy': Options.copyimages = True if Options.css == []: Options.css = ['http://elyxer.nongnu.org/lyx.css'] if Options.html: Options.simplemath = True if Options.toc and not Options.tocfor: Trace.error('Option --toc is deprecated; use --tocfor "page" instead') Options.tocfor = Options.toctarget if Options.nocopy: Trace.error('Option --nocopy is deprecated; it is no longer needed') if Options.jsmath: Trace.error('Option --jsmath is deprecated; use --mathjax instead') # set in Trace if necessary for param in dir(Trace): if param.endswith('mode'): setattr(Trace, param, getattr(self, param[:-4])) def usage(self): "Show correct usage" Trace.error('Usage: ' + os.path.basename(Options.location) + ' [options] [filein] [fileout]') Trace.error('Convert LyX input file "filein" to HTML file "fileout".') Trace.error('If filein (or fileout) is not given use standard input (or output).') Trace.error('Main program of the eLyXer package (http://elyxer.nongnu.org/).') self.showoptions() def parsefootnotes(self): "Parse footnotes options." if not Options.footnotes: return Options.marginfoot = False Options.letterfoot = False Options.hoverfoot = False options = Options.footnotes.split(',') for option in options: footoption = option + 'foot' if hasattr(Options, footoption): setattr(Options, footoption, True) else: Trace.error('Unknown footnotes option: ' + option) if not Options.endfoot and not Options.marginfoot and not Options.hoverfoot: Options.hoverfoot = True if not Options.numberfoot and not Options.symbolfoot: Options.letterfoot = True def showoptions(self): "Show all possible options" Trace.error(' Common options:') Trace.error(' --help: show this online help') Trace.error(' --quiet: disables all runtime messages') Trace.error('') Trace.error(' Advanced options:') Trace.error(' --debug: enable debugging messages (for developers)') Trace.error(' --version: show version number and release date') Trace.error(' --lyxformat: return the highest LyX version supported') Trace.error(' Options for HTML output:') Trace.error(' --title "title": set the generated page title') Trace.error(' --css "file.css": use a custom CSS file') Trace.error(' --embedcss "file.css": embed styles from a CSS file into the output') Trace.error(' --html: output HTML 4.0 instead of the default XHTML') Trace.error(' --unicode: full Unicode output') Trace.error(' --iso885915: output a document with ISO-8859-15 encoding') Trace.error(' --nofooter: remove the footer "generated by eLyXer"') Trace.error(' --simplemath: do not generate fancy math constructions') Trace.error(' Options for image output:') Trace.error(' --directory "img_dir": look for images in the specified directory') Trace.error(' --destdirectory "dest": put converted images into this directory') Trace.error(' --imageformat ".ext": image output format, or "copy" to copy images') Trace.error(' --noconvert: do not convert images, use in original locations') Trace.error(' --converter "inkscape": use an alternative program to convert images') Trace.error(' Options for footnote display:') Trace.error(' --numberfoot: mark footnotes with numbers instead of letters') Trace.error(' --symbolfoot: mark footnotes with symbols (*, **...)') Trace.error(' --hoverfoot: show footnotes as hovering text (default)') Trace.error(' --marginfoot: show footnotes on the page margin') Trace.error(' --endfoot: show footnotes at the end of the page') Trace.error(' --supfoot: use superscript for footnote markers (default)') Trace.error(' --alignfoot: use aligned text for footnote markers') Trace.error(' --footnotes "options": specify several comma-separated footnotes options') Trace.error(' Available options are: "number", "symbol", "hover", "margin", "end",') Trace.error(' "sup", "align"') Trace.error(' Advanced output options:') Trace.error(' --splitpart "depth": split the resulting webpage at the given depth') Trace.error(' --tocfor "page": generate a TOC that points to the given page') Trace.error(' --target "frame": make all links point to the given frame') Trace.error(' --notoclabels: omit the part labels in the TOC, such as Chapter') Trace.error(' --lowmem: do the conversion on the fly (conserve memory)') Trace.error(' --raw: generate HTML without header or footer.') Trace.error(' --mathjax remote: use MathJax remotely to display equations') Trace.error(' --mathjax "URL": use MathJax from the given URL to display equations') Trace.error(' --googlecharts: use Google Charts to generate formula images') Trace.error(' --template "file": use a template, put everything in ') Trace.error(' --copyright: add a copyright notice at the bottom') Trace.error(' Deprecated options:') Trace.error(' --toc: (deprecated) create a table of contents') Trace.error(' --toctarget "page": (deprecated) generate a TOC for the given page') Trace.error(' --nocopy: (deprecated) maintained for backwards compatibility') Trace.error(' --jsmath "URL": use jsMath from the given URL to display equations') sys.exit() def showversion(self): "Return the current eLyXer version string" string = 'eLyXer version ' + GeneralConfig.version['number'] string += ' (' + GeneralConfig.version['date'] + ')' Trace.error(string) sys.exit() def showhardversion(self): "Return just the version string" Trace.message(GeneralConfig.version['number']) sys.exit() def showversiondate(self): "Return just the version dte" Trace.message(GeneralConfig.version['date']) sys.exit() def showlyxformat(self): "Return just the lyxformat parameter" Trace.message(GeneralConfig.version['lyxformat']) sys.exit() class BranchOptions(object): "A set of options for a branch" def __init__(self, name): self.name = name self.options = {'color':'#ffffff'} def set(self, key, value): "Set a branch option" if not key.startswith(ContainerConfig.string['startcommand']): Trace.error('Invalid branch option ' + key) return key = key.replace(ContainerConfig.string['startcommand'], '') self.options[key] = value def isselected(self): "Return if the branch is selected" if not 'selected' in self.options: return False return self.options['selected'] == '1' def __unicode__(self): "String representation" return 'options for ' + self.name + ': ' + unicode(self.options) import urllib class Cloner(object): "An object used to clone other objects." def clone(cls, original): "Return an exact copy of an object." "The original object must have an empty constructor." return cls.create(original.__class__) def create(cls, type): "Create an object of a given class." clone = type.__new__(type) clone.__init__() return clone clone = classmethod(clone) create = classmethod(create) class ContainerExtractor(object): "A class to extract certain containers." def __init__(self, config): "The config parameter is a map containing three lists: allowed, copied and extracted." "Each of the three is a list of class names for containers." "Allowed containers are included as is into the result." "Cloned containers are cloned and placed into the result." "Extracted containers are looked into." "All other containers are silently ignored." self.allowed = config['allowed'] self.cloned = config['cloned'] self.extracted = config['extracted'] def extract(self, container): "Extract a group of selected containers from elyxer.a container." list = [] locate = lambda c: c.__class__.__name__ in self.allowed + self.cloned recursive = lambda c: c.__class__.__name__ in self.extracted process = lambda c: self.process(c, list) container.recursivesearch(locate, recursive, process) return list def process(self, container, list): "Add allowed containers, clone cloned containers and add the clone." name = container.__class__.__name__ if name in self.allowed: list.append(container) elif name in self.cloned: list.append(self.safeclone(container)) else: Trace.error('Unknown container class ' + name) def safeclone(self, container): "Return a new container with contents only in a safe list, recursively." clone = Cloner.clone(container) clone.output = container.output clone.contents = self.extract(container) return clone class Parser(object): "A generic parser" def __init__(self): self.begin = 0 self.parameters = dict() def parseheader(self, reader): "Parse the header" header = reader.currentline().split() reader.nextline() self.begin = reader.linenumber return header def parseparameter(self, reader): "Parse a parameter" if reader.currentline().strip().startswith('<'): key, value = self.parsexml(reader) self.parameters[key] = value return split = reader.currentline().strip().split(' ', 1) reader.nextline() if len(split) == 0: return key = split[0] if len(split) == 1: self.parameters[key] = True return if not '"' in split[1]: self.parameters[key] = split[1].strip() return doublesplit = split[1].split('"') self.parameters[key] = doublesplit[1] def parsexml(self, reader): "Parse a parameter in xml form: " strip = reader.currentline().strip() reader.nextline() if not strip.endswith('>'): Trace.error('XML parameter ' + strip + ' should be <...>') split = strip[1:-1].split() if len(split) == 0: Trace.error('Empty XML parameter <>') return None, None key = split[0] del split[0] if len(split) == 0: return key, dict() attrs = dict() for attr in split: if not '=' in attr: Trace.error('Erroneous attribute for ' + key + ': ' + attr) attr += '="0"' parts = attr.split('=') attrkey = parts[0] value = parts[1].split('"')[1] attrs[attrkey] = value return key, attrs def parseending(self, reader, process): "Parse until the current ending is found" if not self.ending: Trace.error('No ending for ' + unicode(self)) return while not reader.currentline().startswith(self.ending): process() def parsecontainer(self, reader, contents): container = self.factory.createcontainer(reader) if container: container.parent = self.parent contents.append(container) def __unicode__(self): "Return a description" return self.__class__.__name__ + ' (' + unicode(self.begin) + ')' class LoneCommand(Parser): "A parser for just one command line" def parse(self,reader): "Read nothing" return [] class TextParser(Parser): "A parser for a command and a bit of text" stack = [] def __init__(self, container): Parser.__init__(self) self.ending = None if container.__class__.__name__ in ContainerConfig.endings: self.ending = ContainerConfig.endings[container.__class__.__name__] self.endings = [] def parse(self, reader): "Parse lines as long as they are text" TextParser.stack.append(self.ending) self.endings = TextParser.stack + [ContainerConfig.endings['Layout'], ContainerConfig.endings['Inset'], self.ending] contents = [] while not self.isending(reader): self.parsecontainer(reader, contents) return contents def isending(self, reader): "Check if text is ending" current = reader.currentline().split() if len(current) == 0: return False if current[0] in self.endings: if current[0] in TextParser.stack: TextParser.stack.remove(current[0]) else: TextParser.stack = [] return True return False class ExcludingParser(Parser): "A parser that excludes the final line" def parse(self, reader): "Parse everything up to (and excluding) the final line" contents = [] self.parseending(reader, lambda: self.parsecontainer(reader, contents)) return contents class BoundedParser(ExcludingParser): "A parser bound by a final line" def parse(self, reader): "Parse everything, including the final line" contents = ExcludingParser.parse(self, reader) # skip last line reader.nextline() return contents class BoundedDummy(Parser): "A bound parser that ignores everything" def parse(self, reader): "Parse the contents of the container" self.parseending(reader, lambda: reader.nextline()) # skip last line reader.nextline() return [] class StringParser(Parser): "Parses just a string" def parseheader(self, reader): "Do nothing, just take note" self.begin = reader.linenumber + 1 return [] def parse(self, reader): "Parse a single line" contents = reader.currentline() reader.nextline() return contents class InsetParser(BoundedParser): "Parses a LyX inset" def parse(self, reader): "Parse inset parameters into a dictionary" startcommand = ContainerConfig.string['startcommand'] while reader.currentline() != '' and not reader.currentline().startswith(startcommand): self.parseparameter(reader) return BoundedParser.parse(self, reader) class ContainerOutput(object): "The generic HTML output for a container." def gethtml(self, container): "Show an error." Trace.error('gethtml() not implemented for ' + unicode(self)) def isempty(self): "Decide if the output is empty: by default, not empty." return False class EmptyOutput(ContainerOutput): def gethtml(self, container): "Return empty HTML code." return [] def isempty(self): "This output is particularly empty." return True class FixedOutput(ContainerOutput): "Fixed output" def gethtml(self, container): "Return constant HTML code" return container.html class ContentsOutput(ContainerOutput): "Outputs the contents converted to HTML" def gethtml(self, container): "Return the HTML code" html = [] if container.contents == None: return html for element in container.contents: if not hasattr(element, 'gethtml'): Trace.error('No html in ' + element.__class__.__name__ + ': ' + unicode(element)) return html html += element.gethtml() return html class TaggedOutput(ContentsOutput): "Outputs an HTML tag surrounding the contents." tag = None breaklines = False empty = False def settag(self, tag, breaklines=False, empty=False): "Set the value for the tag and other attributes." self.tag = tag if breaklines: self.breaklines = breaklines if empty: self.empty = empty return self def setbreaklines(self, breaklines): "Set the value for breaklines." self.breaklines = breaklines return self def gethtml(self, container): "Return the HTML code." if self.empty: return [self.selfclosing(container)] html = [self.open(container)] html += ContentsOutput.gethtml(self, container) html.append(self.close(container)) return html def open(self, container): "Get opening line." if not self.checktag(): return '' open = '<' + self.tag + '>' if self.breaklines: return open + '\n' return open def close(self, container): "Get closing line." if not self.checktag(): return '' close = '' if self.breaklines: return '\n' + close + '\n' return close def selfclosing(self, container): "Get self-closing line." if not self.checktag(): return '' selfclosing = '<' + self.tag + '/>' if self.breaklines: return selfclosing + '\n' return selfclosing def checktag(self): "Check that the tag is valid." if not self.tag: Trace.error('No tag in ' + unicode(container)) return False if self.tag == '': return False return True class FilteredOutput(ContentsOutput): "Returns the output in the contents, but filtered:" "some strings are replaced by others." def __init__(self): "Initialize the filters." self.filters = [] def addfilter(self, original, replacement): "Add a new filter: replace the original by the replacement." self.filters.append((original, replacement)) def gethtml(self, container): "Return the HTML code" result = [] html = ContentsOutput.gethtml(self, container) for line in html: result.append(self.filter(line)) return result def filter(self, line): "Filter a single line with all available filters." for original, replacement in self.filters: if original in line: line = line.replace(original, replacement) return line class StringOutput(ContainerOutput): "Returns a bare string as output" def gethtml(self, container): "Return a bare string" return [container.string] import sys import codecs class LineReader(object): "Reads a file line by line" def __init__(self, filename): if isinstance(filename, file): self.file = filename else: self.file = codecs.open(filename, 'rU', 'utf-8') self.linenumber = 1 self.lastline = None self.current = None self.mustread = True self.depleted = False try: self.readline() except UnicodeDecodeError: # try compressed file import gzip self.file = gzip.open(filename, 'rb') self.readline() def setstart(self, firstline): "Set the first line to read." for i in range(firstline): self.file.readline() self.linenumber = firstline def setend(self, lastline): "Set the last line to read." self.lastline = lastline def currentline(self): "Get the current line" if self.mustread: self.readline() return self.current def nextline(self): "Go to next line" if self.depleted: Trace.fatal('Read beyond file end') self.mustread = True def readline(self): "Read a line from elyxer.file" self.current = self.file.readline() if not isinstance(self.file, codecs.StreamReaderWriter): self.current = self.current.decode('utf-8') if len(self.current) == 0: self.depleted = True self.current = self.current.rstrip('\n\r') self.linenumber += 1 self.mustread = False Trace.prefix = 'Line ' + unicode(self.linenumber) + ': ' if self.linenumber % 1000 == 0: Trace.message('Parsing') def finished(self): "Find out if the file is finished" if self.lastline and self.linenumber == self.lastline: return True if self.mustread: self.readline() return self.depleted def close(self): self.file.close() class LineWriter(object): "Writes a file as a series of lists" file = False def __init__(self, filename): if isinstance(filename, file): self.file = filename self.filename = None else: self.filename = filename def write(self, strings): "Write a list of strings" for string in strings: if not isinstance(string, basestring): Trace.error('Not a string: ' + unicode(string) + ' in ' + unicode(strings)) return self.writestring(string) def writestring(self, string): "Write a string" if not self.file: self.file = codecs.open(self.filename, 'w', "utf-8") if self.file == sys.stdout and sys.version_info < (3,0): string = string.encode('utf-8') self.file.write(string) def writeline(self, line): "Write a line to file" self.writestring(line + '\n') def close(self): self.file.close() class Globable(object): """A bit of text which can be globbed (lumped together in bits). Methods current(), skipcurrent(), checkfor() and isout() have to be implemented by subclasses.""" leavepending = False def __init__(self): self.endinglist = EndingList() def checkbytemark(self): "Check for a Unicode byte mark and skip it." if self.finished(): return if ord(self.current()) == 0xfeff: self.skipcurrent() def isout(self): "Find out if we are out of the position yet." Trace.error('Unimplemented isout()') return True def current(self): "Return the current character." Trace.error('Unimplemented current()') return '' def checkfor(self, string): "Check for the given string in the current position." Trace.error('Unimplemented checkfor()') return False def finished(self): "Find out if the current text has finished." if self.isout(): if not self.leavepending: self.endinglist.checkpending() return True return self.endinglist.checkin(self) def skipcurrent(self): "Return the current character and skip it." Trace.error('Unimplemented skipcurrent()') return '' def glob(self, currentcheck): "Glob a bit of text that satisfies a check on the current char." glob = '' while not self.finished() and currentcheck(): glob += self.skipcurrent() return glob def globalpha(self): "Glob a bit of alpha text" return self.glob(lambda: self.current().isalpha()) def globnumber(self): "Glob a row of digits." return self.glob(lambda: self.current().isdigit()) def isidentifier(self): "Return if the current character is alphanumeric or _." if self.current().isalnum() or self.current() == '_': return True return False def globidentifier(self): "Glob alphanumeric and _ symbols." return self.glob(self.isidentifier) def isvalue(self): "Return if the current character is a value character:" "not a bracket or a space." if self.current().isspace(): return False if self.current() in '{}()': return False return True def globvalue(self): "Glob a value: any symbols but brackets." return self.glob(self.isvalue) def skipspace(self): "Skip all whitespace at current position." return self.glob(lambda: self.current().isspace()) def globincluding(self, magicchar): "Glob a bit of text up to (including) the magic char." glob = self.glob(lambda: self.current() != magicchar) + magicchar self.skip(magicchar) return glob def globexcluding(self, excluded): "Glob a bit of text up until (excluding) any excluded character." return self.glob(lambda: self.current() not in excluded) def pushending(self, ending, optional = False): "Push a new ending to the bottom" self.endinglist.add(ending, optional) def popending(self, expected = None): "Pop the ending found at the current position" if self.isout() and self.leavepending: return expected ending = self.endinglist.pop(self) if expected and expected != ending: Trace.error('Expected ending ' + expected + ', got ' + ending) self.skip(ending) return ending def nextending(self): "Return the next ending in the queue." nextending = self.endinglist.findending(self) if not nextending: return None return nextending.ending class EndingList(object): "A list of position endings" def __init__(self): self.endings = [] def add(self, ending, optional = False): "Add a new ending to the list" self.endings.append(PositionEnding(ending, optional)) def pickpending(self, pos): "Pick any pending endings from a parse position." self.endings += pos.endinglist.endings def checkin(self, pos): "Search for an ending" if self.findending(pos): return True return False def pop(self, pos): "Remove the ending at the current position" if pos.isout(): Trace.error('No ending out of bounds') return '' ending = self.findending(pos) if not ending: Trace.error('No ending at ' + pos.current()) return '' for each in reversed(self.endings): self.endings.remove(each) if each == ending: return each.ending elif not each.optional: Trace.error('Removed non-optional ending ' + each) Trace.error('No endings left') return '' def findending(self, pos): "Find the ending at the current position" if len(self.endings) == 0: return None for index, ending in enumerate(reversed(self.endings)): if ending.checkin(pos): return ending if not ending.optional: return None return None def checkpending(self): "Check if there are any pending endings" if len(self.endings) != 0: Trace.error('Pending ' + unicode(self) + ' left open') def __unicode__(self): "Printable representation" string = 'endings [' for ending in self.endings: string += unicode(ending) + ',' if len(self.endings) > 0: string = string[:-1] return string + ']' class PositionEnding(object): "An ending for a parsing position" def __init__(self, ending, optional): self.ending = ending self.optional = optional def checkin(self, pos): "Check for the ending" return pos.checkfor(self.ending) def __unicode__(self): "Printable representation" string = 'Ending ' + self.ending if self.optional: string += ' (optional)' return string class Position(Globable): """A position in a text to parse. Including those in Globable, functions to implement by subclasses are: skip(), identifier(), extract(), isout() and current().""" def __init__(self): Globable.__init__(self) def skip(self, string): "Skip a string" Trace.error('Unimplemented skip()') def identifier(self): "Return an identifier for the current position." Trace.error('Unimplemented identifier()') return 'Error' def extract(self, length): "Extract the next string of the given length, or None if not enough text," "without advancing the parse position." Trace.error('Unimplemented extract()') return None def checkfor(self, string): "Check for a string at the given position." return string == self.extract(len(string)) def checkforlower(self, string): "Check for a string in lower case." extracted = self.extract(len(string)) if not extracted: return False return string.lower() == self.extract(len(string)).lower() def skipcurrent(self): "Return the current character and skip it." current = self.current() self.skip(current) return current def next(self): "Advance the position and return the next character." self.skipcurrent() return self.current() def checkskip(self, string): "Check for a string at the given position; if there, skip it" if not self.checkfor(string): return False self.skip(string) return True def error(self, message): "Show an error message and the position identifier." Trace.error(message + ': ' + self.identifier()) class TextPosition(Position): "A parse position based on a raw text." def __init__(self, text): "Create the position from elyxer.some text." Position.__init__(self) self.pos = 0 self.text = text self.checkbytemark() def skip(self, string): "Skip a string of characters." self.pos += len(string) def identifier(self): "Return a sample of the remaining text." length = 30 if self.pos + length > len(self.text): length = len(self.text) - self.pos return '*' + self.text[self.pos:self.pos + length] + '*' def isout(self): "Find out if we are out of the text yet." return self.pos >= len(self.text) def current(self): "Return the current character, assuming we are not out." return self.text[self.pos] def extract(self, length): "Extract the next string of the given length, or None if not enough text." if self.pos + length > len(self.text): return None return self.text[self.pos : self.pos + length] class FilePosition(Position): "A parse position based on an underlying file." def __init__(self, filename): "Create the position from a file." Position.__init__(self) self.reader = LineReader(filename) self.pos = 0 self.checkbytemark() def skip(self, string): "Skip a string of characters." length = len(string) while self.pos + length > len(self.reader.currentline()): length -= len(self.reader.currentline()) - self.pos + 1 self.nextline() self.pos += length def currentline(self): "Get the current line of the underlying file." return self.reader.currentline() def nextline(self): "Go to the next line." self.reader.nextline() self.pos = 0 def linenumber(self): "Return the line number of the file." return self.reader.linenumber + 1 def identifier(self): "Return the current line and line number in the file." before = self.reader.currentline()[:self.pos - 1] after = self.reader.currentline()[self.pos:] return 'line ' + unicode(self.getlinenumber()) + ': ' + before + '*' + after def isout(self): "Find out if we are out of the text yet." if self.pos > len(self.reader.currentline()): if self.pos > len(self.reader.currentline()) + 1: Trace.error('Out of the line ' + self.reader.currentline() + ': ' + unicode(self.pos)) self.nextline() return self.reader.finished() def current(self): "Return the current character, assuming we are not out." if self.pos == len(self.reader.currentline()): return '\n' if self.pos > len(self.reader.currentline()): Trace.error('Out of the line ' + self.reader.currentline() + ': ' + unicode(self.pos)) return '*' return self.reader.currentline()[self.pos] def extract(self, length): "Extract the next string of the given length, or None if not enough text." if self.pos + length > len(self.reader.currentline()): return None return self.reader.currentline()[self.pos : self.pos + length] class Container(object): "A container for text and objects in a lyx file" partkey = None parent = None begin = None def __init__(self): self.contents = list() def process(self): "Process contents" pass def gethtml(self): "Get the resulting HTML" html = self.output.gethtml(self) if isinstance(html, basestring): Trace.error('Raw string ' + html) html = [html] return self.escapeall(html) def escapeall(self, lines): "Escape all lines in an array according to the output options." result = [] for line in lines: if Options.html: line = self.escape(line, EscapeConfig.html) if Options.iso885915: line = self.escape(line, EscapeConfig.iso885915) line = self.escapeentities(line) elif not Options.unicode: line = self.escape(line, EscapeConfig.nonunicode) result.append(line) return result def escape(self, line, replacements = EscapeConfig.entities): "Escape a line with replacements from elyxer.a map" pieces = replacements.keys() # do them in order pieces.sort() for piece in pieces: if piece in line: line = line.replace(piece, replacements[piece]) return line def escapeentities(self, line): "Escape all Unicode characters to HTML entities." result = '' pos = TextPosition(line) while not pos.finished(): if ord(pos.current()) > 128: codepoint = hex(ord(pos.current())) if codepoint == '0xd835': codepoint = hex(ord(pos.next()) + 0xf800) result += '&#' + codepoint[1:] + ';' else: result += pos.current() pos.skipcurrent() return result def searchall(self, type): "Search for all embedded containers of a given type" list = [] self.searchprocess(type, lambda container: list.append(container)) return list def searchremove(self, type): "Search for all containers of a type and remove them" list = self.searchall(type) for container in list: container.parent.contents.remove(container) return list def searchprocess(self, type, process): "Search for elements of a given type and process them" self.locateprocess(lambda container: isinstance(container, type), process) def locateprocess(self, locate, process): "Search for all embedded containers and process them" for container in self.contents: container.locateprocess(locate, process) if locate(container): process(container) def recursivesearch(self, locate, recursive, process): "Perform a recursive search in the container." for container in self.contents: if recursive(container): container.recursivesearch(locate, recursive, process) if locate(container): process(container) def extracttext(self): "Extract all text from elyxer.allowed containers." result = '' constants = ContainerExtractor(ContainerConfig.extracttext).extract(self) for constant in constants: result += constant.string return result def group(self, index, group, isingroup): "Group some adjoining elements into a group" if index >= len(self.contents): return if hasattr(self.contents[index], 'grouped'): return while index < len(self.contents) and isingroup(self.contents[index]): self.contents[index].grouped = True group.contents.append(self.contents[index]) self.contents.pop(index) self.contents.insert(index, group) def remove(self, index): "Remove a container but leave its contents" container = self.contents[index] self.contents.pop(index) while len(container.contents) > 0: self.contents.insert(index, container.contents.pop()) def tree(self, level = 0): "Show in a tree" Trace.debug(" " * level + unicode(self)) for container in self.contents: container.tree(level + 1) def getparameter(self, name): "Get the value of a parameter, if present." if not name in self.parameters: return None return self.parameters[name] def getparameterlist(self, name): "Get the value of a comma-separated parameter as a list." paramtext = self.getparameter(name) if not paramtext: return [] return paramtext.split(',') def hasemptyoutput(self): "Check if the parent's output is empty." current = self.parent while current: if current.output.isempty(): return True current = current.parent return False def __unicode__(self): "Get a description" if not self.begin: return self.__class__.__name__ return self.__class__.__name__ + '@' + unicode(self.begin) class BlackBox(Container): "A container that does not output anything" def __init__(self): self.parser = LoneCommand() self.output = EmptyOutput() self.contents = [] class LyXFormat(BlackBox): "Read the lyxformat command" def process(self): "Show warning if version < 276" version = int(self.header[1]) if version < 276: Trace.error('Warning: unsupported old format version ' + str(version)) if version > int(GeneralConfig.version['lyxformat']): Trace.error('Warning: unsupported new format version ' + str(version)) class StringContainer(Container): "A container for a single string" parsed = None def __init__(self): self.parser = StringParser() self.output = StringOutput() self.string = '' def process(self): "Replace special chars from elyxer.the contents." if self.parsed: self.string = self.replacespecial(self.parsed) self.parsed = None def replacespecial(self, line): "Replace all special chars from elyxer.a line" replaced = self.escape(line, EscapeConfig.entities) replaced = self.changeline(replaced) if ContainerConfig.string['startcommand'] in replaced and len(replaced) > 1: # unprocessed commands if self.begin: message = 'Unknown command at ' + unicode(self.begin) + ': ' else: message = 'Unknown command: ' Trace.error(message + replaced.strip()) return replaced def changeline(self, line): line = self.escape(line, EscapeConfig.chars) if not ContainerConfig.string['startcommand'] in line: return line line = self.escape(line, EscapeConfig.commands) return line def extracttext(self): "Return all text." return self.string def __unicode__(self): "Return a printable representation." result = 'StringContainer' if self.begin: result += '@' + unicode(self.begin) ellipsis = '...' if len(self.string.strip()) <= 15: ellipsis = '' return result + ' (' + self.string.strip()[:15] + ellipsis + ')' class Constant(StringContainer): "A constant string" def __init__(self, text): self.contents = [] self.string = text self.output = StringOutput() def __unicode__(self): return 'Constant: ' + self.string class TaggedText(Container): "Text inside a tag" output = None def __init__(self): self.parser = TextParser(self) self.output = TaggedOutput() def complete(self, contents, tag, breaklines=False): "Complete the tagged text and return it" self.contents = contents self.output.tag = tag self.output.breaklines = breaklines return self def constant(self, text, tag, breaklines=False): "Complete the tagged text with a constant" constant = Constant(text) return self.complete([constant], tag, breaklines) def __unicode__(self): "Return a printable representation." if not hasattr(self.output, 'tag'): return 'Emtpy tagged text' if not self.output.tag: return 'Tagged ' return 'Tagged <' + self.output.tag + '>' class DocumentParameters(object): "Global parameters for the document." pdftitle = None indentstandard = False tocdepth = 10 startinglevel = 0 maxdepth = 10 language = None bibliography = None outputchanges = False displaymode = False class FormulaParser(Parser): "Parses a formula" def parseheader(self, reader): "See if the formula is inlined" self.begin = reader.linenumber + 1 type = self.parsetype(reader) if not type: reader.nextline() type = self.parsetype(reader) if not type: Trace.error('Unknown formula type in ' + reader.currentline().strip()) return ['unknown'] return [type] def parsetype(self, reader): "Get the formula type from the first line." if reader.currentline().find(FormulaConfig.starts['simple']) >= 0: return 'inline' if reader.currentline().find(FormulaConfig.starts['complex']) >= 0: return 'block' if reader.currentline().find(FormulaConfig.starts['unnumbered']) >= 0: return 'block' if reader.currentline().find(FormulaConfig.starts['beginbefore']) >= 0: return 'numbered' return None def parse(self, reader): "Parse the formula until the end" formula = self.parseformula(reader) while not reader.currentline().startswith(self.ending): stripped = reader.currentline().strip() if len(stripped) > 0: Trace.error('Unparsed formula line ' + stripped) reader.nextline() reader.nextline() return formula def parseformula(self, reader): "Parse the formula contents" simple = FormulaConfig.starts['simple'] if simple in reader.currentline(): rest = reader.currentline().split(simple, 1)[1] if simple in rest: # formula is $...$ return self.parsesingleliner(reader, simple, simple) # formula is multiline $...$ return self.parsemultiliner(reader, simple, simple) if FormulaConfig.starts['complex'] in reader.currentline(): # formula of the form \[...\] return self.parsemultiliner(reader, FormulaConfig.starts['complex'], FormulaConfig.endings['complex']) beginbefore = FormulaConfig.starts['beginbefore'] beginafter = FormulaConfig.starts['beginafter'] if beginbefore in reader.currentline(): if reader.currentline().strip().endswith(beginafter): current = reader.currentline().strip() endsplit = current.split(beginbefore)[1].split(beginafter) startpiece = beginbefore + endsplit[0] + beginafter endbefore = FormulaConfig.endings['endbefore'] endafter = FormulaConfig.endings['endafter'] endpiece = endbefore + endsplit[0] + endafter return startpiece + self.parsemultiliner(reader, startpiece, endpiece) + endpiece Trace.error('Missing ' + beginafter + ' in ' + reader.currentline()) return '' begincommand = FormulaConfig.starts['command'] beginbracket = FormulaConfig.starts['bracket'] if begincommand in reader.currentline() and beginbracket in reader.currentline(): endbracket = FormulaConfig.endings['bracket'] return self.parsemultiliner(reader, beginbracket, endbracket) Trace.error('Formula beginning ' + reader.currentline() + ' is unknown') return '' def parsesingleliner(self, reader, start, ending): "Parse a formula in one line" line = reader.currentline().strip() if not start in line: Trace.error('Line ' + line + ' does not contain formula start ' + start) return '' if not line.endswith(ending): Trace.error('Formula ' + line + ' does not end with ' + ending) return '' index = line.index(start) rest = line[index + len(start):-len(ending)] reader.nextline() return rest def parsemultiliner(self, reader, start, ending): "Parse a formula in multiple lines" formula = '' line = reader.currentline() if not start in line: Trace.error('Line ' + line.strip() + ' does not contain formula start ' + start) return '' index = line.index(start) line = line[index + len(start):].strip() while not line.endswith(ending): formula += line + '\n' reader.nextline() line = reader.currentline() formula += line[:-len(ending)] reader.nextline() return formula class MacroParser(FormulaParser): "A parser for a formula macro." def parseheader(self, reader): "See if the formula is inlined" self.begin = reader.linenumber + 1 return ['inline'] def parse(self, reader): "Parse the formula until the end" formula = self.parsemultiliner(reader, self.parent.start, self.ending) reader.nextline() return formula class FormulaBit(Container): "A bit of a formula" type = None size = 1 original = '' def __init__(self): "The formula bit type can be 'alpha', 'number', 'font'." self.contents = [] self.output = ContentsOutput() def setfactory(self, factory): "Set the internal formula factory." self.factory = factory return self def add(self, bit): "Add any kind of formula bit already processed" self.contents.append(bit) self.original += bit.original bit.parent = self def skiporiginal(self, string, pos): "Skip a string and add it to the original formula" self.original += string if not pos.checkskip(string): Trace.error('String ' + string + ' not at ' + pos.identifier()) def computesize(self): "Compute the size of the bit as the max of the sizes of all contents." if len(self.contents) == 0: return 1 self.size = max([element.size for element in self.contents]) return self.size def clone(self): "Return a copy of itself." return self.factory.parseformula(self.original) def __unicode__(self): "Get a string representation" return self.__class__.__name__ + ' read in ' + self.original class TaggedBit(FormulaBit): "A tagged string in a formula" def constant(self, constant, tag): "Set the constant and the tag" self.output = TaggedOutput().settag(tag) self.add(FormulaConstant(constant)) return self def complete(self, contents, tag, breaklines = False): "Set the constant and the tag" self.contents = contents self.output = TaggedOutput().settag(tag, breaklines) return self def selfcomplete(self, tag): "Set the self-closing tag, no contents (as in
)." self.output = TaggedOutput().settag(tag, empty = True) return self class FormulaConstant(Constant): "A constant string in a formula" def __init__(self, string): "Set the constant string" Constant.__init__(self, string) self.original = string self.size = 1 self.type = None def computesize(self): "Compute the size of the constant: always 1." return self.size def clone(self): "Return a copy of itself." return FormulaConstant(self.original) def __unicode__(self): "Return a printable representation." return 'Formula constant: ' + self.string class RawText(FormulaBit): "A bit of text inside a formula" def detect(self, pos): "Detect a bit of raw text" return pos.current().isalpha() def parsebit(self, pos): "Parse alphabetic text" alpha = pos.globalpha() self.add(FormulaConstant(alpha)) self.type = 'alpha' class FormulaSymbol(FormulaBit): "A symbol inside a formula" modified = FormulaConfig.modified unmodified = FormulaConfig.unmodified['characters'] def detect(self, pos): "Detect a symbol" if pos.current() in FormulaSymbol.unmodified: return True if pos.current() in FormulaSymbol.modified: return True return False def parsebit(self, pos): "Parse the symbol" if pos.current() in FormulaSymbol.unmodified: self.addsymbol(pos.current(), pos) return if pos.current() in FormulaSymbol.modified: self.addsymbol(FormulaSymbol.modified[pos.current()], pos) return Trace.error('Symbol ' + pos.current() + ' not found') def addsymbol(self, symbol, pos): "Add a symbol" self.skiporiginal(pos.current(), pos) self.contents.append(FormulaConstant(symbol)) class FormulaNumber(FormulaBit): "A string of digits in a formula" def detect(self, pos): "Detect a digit" return pos.current().isdigit() def parsebit(self, pos): "Parse a bunch of digits" digits = pos.glob(lambda: pos.current().isdigit()) self.add(FormulaConstant(digits)) self.type = 'number' class Comment(FormulaBit): "A LaTeX comment: % to the end of the line." start = FormulaConfig.starts['comment'] def detect(self, pos): "Detect the %." return pos.current() == self.start def parsebit(self, pos): "Parse to the end of the line." self.original += pos.globincluding('\n') class WhiteSpace(FormulaBit): "Some white space inside a formula." def detect(self, pos): "Detect the white space." return pos.current().isspace() def parsebit(self, pos): "Parse all whitespace." self.original += pos.skipspace() def __unicode__(self): "Return a printable representation." return 'Whitespace: *' + self.original + '*' class Bracket(FormulaBit): "A {} bracket inside a formula" start = FormulaConfig.starts['bracket'] ending = FormulaConfig.endings['bracket'] def __init__(self): "Create a (possibly literal) new bracket" FormulaBit.__init__(self) self.inner = None def detect(self, pos): "Detect the start of a bracket" return pos.checkfor(self.start) def parsebit(self, pos): "Parse the bracket" self.parsecomplete(pos, self.innerformula) return self def parsetext(self, pos): "Parse a text bracket" self.parsecomplete(pos, self.innertext) return self def parseliteral(self, pos): "Parse a literal bracket" self.parsecomplete(pos, self.innerliteral) return self def parsecomplete(self, pos, innerparser): "Parse the start and end marks" if not pos.checkfor(self.start): Trace.error('Bracket should start with ' + self.start + ' at ' + pos.identifier()) return None self.skiporiginal(self.start, pos) pos.pushending(self.ending) innerparser(pos) self.original += pos.popending(self.ending) self.computesize() def innerformula(self, pos): "Parse a whole formula inside the bracket" while not pos.finished(): self.add(self.factory.parseany(pos)) def innertext(self, pos): "Parse some text inside the bracket, following textual rules." specialchars = FormulaConfig.symbolfunctions.keys() specialchars.append(FormulaConfig.starts['command']) specialchars.append(FormulaConfig.starts['bracket']) specialchars.append(Comment.start) while not pos.finished(): if pos.current() in specialchars: self.add(self.factory.parseany(pos)) if pos.checkskip(' '): self.original += ' ' else: self.add(FormulaConstant(pos.skipcurrent())) def innerliteral(self, pos): "Parse a literal inside the bracket, which does not generate HTML." self.literal = '' while not pos.finished() and not pos.current() == self.ending: if pos.current() == self.start: self.parseliteral(pos) else: self.literal += pos.skipcurrent() self.original += self.literal class SquareBracket(Bracket): "A [] bracket inside a formula" start = FormulaConfig.starts['squarebracket'] ending = FormulaConfig.endings['squarebracket'] def clone(self): "Return a new square bracket with the same contents." bracket = SquareBracket() bracket.contents = self.contents return bracket class MathsProcessor(object): "A processor for a maths construction inside the FormulaProcessor." def process(self, contents, index): "Process an element inside a formula." Trace.error('Unimplemented process() in ' + unicode(self)) def __unicode__(self): "Return a printable description." return 'Maths processor ' + self.__class__.__name__ class FormulaProcessor(object): "A processor specifically for formulas." processors = [] def process(self, bit): "Process the contents of every formula bit, recursively." self.processcontents(bit) self.processinsides(bit) self.traversewhole(bit) def processcontents(self, bit): "Process the contents of a formula bit." if not isinstance(bit, FormulaBit): return bit.process() for element in bit.contents: self.processcontents(element) def processinsides(self, bit): "Process the insides (limits, brackets) in a formula bit." if not isinstance(bit, FormulaBit): return for index, element in enumerate(bit.contents): for processor in self.processors: processor.process(bit.contents, index) # continue with recursive processing self.processinsides(element) def traversewhole(self, formula): "Traverse over the contents to alter variables and space units." last = None for bit, contents in self.traverse(formula): if bit.type == 'alpha': self.italicize(bit, contents) elif bit.type == 'font' and last and last.type == 'number': bit.contents.insert(0, FormulaConstant(u' ')) last = bit def traverse(self, bit): "Traverse a formula and yield a flattened structure of (bit, list) pairs." for element in bit.contents: if hasattr(element, 'type') and element.type: yield (element, bit.contents) elif isinstance(element, FormulaBit): for pair in self.traverse(element): yield pair def italicize(self, bit, contents): "Italicize the given bit of text." index = contents.index(bit) contents[index] = TaggedBit().complete([bit], 'i') class Formula(Container): "A LaTeX formula" def __init__(self): self.parser = FormulaParser() self.output = TaggedOutput().settag('span class="formula"') def process(self): "Convert the formula to tags" if self.header[0] == 'inline': DocumentParameters.displaymode = False else: DocumentParameters.displaymode = True self.output.settag('div class="formula"', True) if Options.jsmath: self.jsmath() elif Options.mathjax: self.mathjax() elif Options.googlecharts: self.googlecharts() else: self.classic() def jsmath(self): "Make the contents for jsMath." if self.header[0] != 'inline': self.output = TaggedOutput().settag('div class="math"') else: self.output = TaggedOutput().settag('span class="math"') self.contents = [Constant(self.parsed)] def mathjax(self): "Make the contents for MathJax." self.output.tag = 'span class="MathJax_Preview"' tag = 'script type="math/tex' if self.header[0] != 'inline': tag += ';mode=display' self.contents = [TaggedText().constant(self.parsed, tag + '"', True)] def googlecharts(self): "Make the contents using Google Charts http://code.google.com/apis/chart/." url = FormulaConfig.urls['googlecharts'] + urllib.quote_plus(self.parsed) img = '' + self.parsed + '' self.contents = [Constant(img)] def classic(self): "Make the contents using classic output generation with XHTML and CSS." whole = FormulaFactory().parseformula(self.parsed) FormulaProcessor().process(whole) whole.parent = self self.contents = [whole] def parse(self, pos): "Parse using a parse position instead of self.parser." if pos.checkskip('$$'): self.parsedollarblock(pos) elif pos.checkskip('$'): self.parsedollarinline(pos) elif pos.checkskip('\\('): self.parseinlineto(pos, '\\)') elif pos.checkskip('\\['): self.parseblockto(pos, '\\]') else: pos.error('Unparseable formula') self.process() return self def parsedollarinline(self, pos): "Parse a $...$ formula." self.header = ['inline'] self.parsedollar(pos) def parsedollarblock(self, pos): "Parse a $$...$$ formula." self.header = ['block'] self.parsedollar(pos) if not pos.checkskip('$'): pos.error('Formula should be $$...$$, but last $ is missing.') def parsedollar(self, pos): "Parse to the next $." pos.pushending('$') self.parsed = pos.globexcluding('$') pos.popending('$') def parseinlineto(self, pos, limit): "Parse a \\(...\\) formula." self.header = ['inline'] self.parseupto(pos, limit) def parseblockto(self, pos, limit): "Parse a \\[...\\] formula." self.header = ['block'] self.parseupto(pos, limit) def parseupto(self, pos, limit): "Parse a formula that ends with the given command." pos.pushending(limit) self.parsed = pos.glob(lambda: True) pos.popending(limit) def __unicode__(self): "Return a printable representation." if self.partkey and self.partkey.number: return 'Formula (' + self.partkey.number + ')' return 'Unnumbered formula' class WholeFormula(FormulaBit): "Parse a whole formula" def detect(self, pos): "Not outside the formula is enough." return not pos.finished() def parsebit(self, pos): "Parse with any formula bit" while not pos.finished(): self.add(self.factory.parseany(pos)) class FormulaFactory(object): "Construct bits of formula" # bit types will be appended later types = [FormulaSymbol, RawText, FormulaNumber, Bracket, Comment, WhiteSpace] skippedtypes = [Comment, WhiteSpace] defining = False def __init__(self): "Initialize the map of instances." self.instances = dict() def detecttype(self, type, pos): "Detect a bit of a given type." if pos.finished(): return False return self.instance(type).detect(pos) def instance(self, type): "Get an instance of the given type." if not type in self.instances or not self.instances[type]: self.instances[type] = self.create(type) return self.instances[type] def create(self, type): "Create a new formula bit of the given type." return Cloner.create(type).setfactory(self) def clearskipped(self, pos): "Clear any skipped types." while not pos.finished(): if not self.skipany(pos): return return def skipany(self, pos): "Skip any skipped types." for type in self.skippedtypes: if self.instance(type).detect(pos): return self.parsetype(type, pos) return None def parseany(self, pos): "Parse any formula bit at the current location." for type in self.types + self.skippedtypes: if self.detecttype(type, pos): return self.parsetype(type, pos) Trace.error('Unrecognized formula at ' + pos.identifier()) return FormulaConstant(pos.skipcurrent()) def parsetype(self, type, pos): "Parse the given type and return it." bit = self.instance(type) self.instances[type] = None returnedbit = bit.parsebit(pos) if returnedbit: return returnedbit.setfactory(self) return bit def parseformula(self, formula): "Parse a string of text that contains a whole formula." pos = TextPosition(formula) whole = self.create(WholeFormula) if whole.detect(pos): whole.parsebit(pos) return whole # no formula found if not pos.finished(): Trace.error('Unknown formula at: ' + pos.identifier()) whole.add(TaggedBit().constant(formula, 'span class="unknown"')) return whole import unicodedata import gettext class Translator(object): "Reads the configuration file and tries to find a translation." "Otherwise falls back to the messages in the config file." instance = None def translate(cls, key): "Get the translated message for a key." return cls.instance.getmessage(key) translate = classmethod(translate) def __init__(self): self.translation = None self.first = True def findtranslation(self): "Find the translation for the document language." self.langcodes = None if not DocumentParameters.language: Trace.error('No language in document') return if not DocumentParameters.language in TranslationConfig.languages: Trace.error('Unknown language ' + DocumentParameters.language) return if TranslationConfig.languages[DocumentParameters.language] == 'en': return langcodes = [TranslationConfig.languages[DocumentParameters.language]] try: self.translation = gettext.translation('elyxer', None, langcodes) except IOError: Trace.error('No translation for ' + unicode(langcodes)) def getmessage(self, key): "Get the translated message for the given key." if self.first: self.findtranslation() self.first = False message = self.getuntranslated(key) if not self.translation: return message try: message = self.translation.ugettext(message) except IOError: pass return message def getuntranslated(self, key): "Get the untranslated message." if not key in TranslationConfig.constants: Trace.error('Cannot translate ' + key) return key return TranslationConfig.constants[key] Translator.instance = Translator() class NumberCounter(object): "A counter for numbers (by default)." "The type can be changed to return letters, roman numbers..." name = None value = None mode = None master = None letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' symbols = NumberingConfig.sequence['symbols'] romannumerals = [ ('M', 1000), ('CM', 900), ('D', 500), ('CD', 400), ('C', 100), ('XC', 90), ('L', 50), ('XL', 40), ('X', 10), ('IX', 9), ('V', 5), ('IV', 4), ('I', 1) ] def __init__(self, name): "Give a name to the counter." self.name = name def setmode(self, mode): "Set the counter mode. Can be changed at runtime." self.mode = mode return self def init(self, value): "Set an initial value." self.value = value def gettext(self): "Get the next value as a text string." return unicode(self.value) def getletter(self): "Get the next value as a letter." return self.getsequence(self.letters) def getsymbol(self): "Get the next value as a symbol." return self.getsequence(self.symbols) def getsequence(self, sequence): "Get the next value from elyxer.a sequence." return sequence[(self.value - 1) % len(sequence)] def getroman(self): "Get the next value as a roman number." result = '' number = self.value for numeral, value in self.romannumerals: if number >= value: result += numeral * (number / value) number = number % value return result def getvalue(self): "Get the current value as configured in the current mode." if not self.mode or self.mode in ['text', '1']: return self.gettext() if self.mode == 'A': return self.getletter() if self.mode == 'a': return self.getletter().lower() if self.mode == 'I': return self.getroman() if self.mode == '*': return self.getsymbol() Trace.error('Unknown counter mode ' + self.mode) return self.gettext() def getnext(self): "Increase the current value and get the next value as configured." if not self.value: self.value = 0 self.value += 1 return self.getvalue() def reset(self): "Reset the counter." self.value = 0 def __unicode__(self): "Return a printable representation." result = 'Counter ' + self.name if self.mode: result += ' in mode ' + self.mode return result class DependentCounter(NumberCounter): "A counter which depends on another one (the master)." def setmaster(self, master): "Set the master counter." self.master = master self.last = self.master.getvalue() return self def getnext(self): "Increase or, if the master counter has changed, restart." if self.last != self.master.getvalue(): self.reset() value = NumberCounter.getnext(self) self.last = self.master.getvalue() return value def getvalue(self): "Get the value of the combined counter: master.dependent." return self.master.getvalue() + '.' + NumberCounter.getvalue(self) class NumberGenerator(object): "A number generator for unique sequences and hierarchical structures. Used in:" " * ordered part numbers: Chapter 3, Section 5.3." " * unique part numbers: Footnote 15, Bibliography cite [15]." " * chaptered part numbers: Figure 3.15, Equation (8.3)." " * unique roman part numbers: Part I, Book IV." chaptered = None generator = None romanlayouts = [x.lower() for x in NumberingConfig.layouts['roman']] orderedlayouts = [x.lower() for x in NumberingConfig.layouts['ordered']] counters = dict() appendix = None def deasterisk(self, type): "Remove the possible asterisk in a layout type." return type.replace('*', '') def isunique(self, type): "Find out if the layout type corresponds to a unique part." return self.isroman(type) def isroman(self, type): "Find out if the layout type should have roman numeration." return self.deasterisk(type).lower() in self.romanlayouts def isinordered(self, type): "Find out if the layout type corresponds to an (un)ordered part." return self.deasterisk(type).lower() in self.orderedlayouts def isnumbered(self, type): "Find out if the type for a layout corresponds to a numbered layout." if '*' in type: return False if self.isroman(type): return True if not self.isinordered(type): return False if self.getlevel(type) > DocumentParameters.maxdepth: return False return True def isunordered(self, type): "Find out if the type contains an asterisk, basically." return '*' in type def getlevel(self, type): "Get the level that corresponds to a layout type." if self.isunique(type): return 0 if not self.isinordered(type): Trace.error('Unknown layout type ' + type) return 0 type = self.deasterisk(type).lower() level = self.orderedlayouts.index(type) + 1 return level - DocumentParameters.startinglevel def getparttype(self, type): "Obtain the type for the part: without the asterisk, " "and switched to Appendix if necessary." if NumberGenerator.appendix and self.getlevel(type) == 1: return 'Appendix' return self.deasterisk(type) def generate(self, type): "Generate a number for a layout type." "Unique part types such as Part or Book generate roman numbers: Part I." "Ordered part types return dot-separated tuples: Chapter 5, Subsection 2.3.5." "Everything else generates unique numbers: Bibliography [1]." "Each invocation results in a new number." return self.getcounter(type).getnext() def getcounter(self, type): "Get the counter for the given type." type = type.lower() if not type in self.counters: self.counters[type] = self.create(type) return self.counters[type] def create(self, type): "Create a counter for the given type." if self.isnumbered(type) and self.getlevel(type) > 1: index = self.orderedlayouts.index(type) above = self.orderedlayouts[index - 1] master = self.getcounter(above) return self.createdependent(type, master) counter = NumberCounter(type) if self.isroman(type): counter.setmode('I') return counter def getdependentcounter(self, type, master): "Get (or create) a counter of the given type that depends on another." if not type in self.counters or not self.counters[type].master: self.counters[type] = self.createdependent(type, master) return self.counters[type] def createdependent(self, type, master): "Create a dependent counter given the master." return DependentCounter(type).setmaster(master) def startappendix(self): "Start appendices here." firsttype = self.orderedlayouts[DocumentParameters.startinglevel] counter = self.getcounter(firsttype) counter.setmode('A').reset() NumberGenerator.appendix = True class ChapteredGenerator(NumberGenerator): "Generate chaptered numbers, as in Chapter.Number." "Used in equations, figures: Equation (5.3), figure 8.15." def generate(self, type): "Generate a number which goes with first-level numbers (chapters). " "For the article classes a unique number is generated." if DocumentParameters.startinglevel > 0: return NumberGenerator.generator.generate(type) chapter = self.getcounter('Chapter') return self.getdependentcounter(type, chapter).getnext() NumberGenerator.chaptered = ChapteredGenerator() NumberGenerator.generator = NumberGenerator() class ContainerSize(object): "The size of a container." width = None height = None maxwidth = None maxheight = None scale = None def set(self, width = None, height = None): "Set the proper size with width and height." self.setvalue('width', width) self.setvalue('height', height) return self def setmax(self, maxwidth = None, maxheight = None): "Set max width and/or height." self.setvalue('maxwidth', maxwidth) self.setvalue('maxheight', maxheight) return self def readparameters(self, container): "Read some size parameters off a container." self.setparameter(container, 'width') self.setparameter(container, 'height') self.setparameter(container, 'scale') self.checkvalidheight(container) return self def setparameter(self, container, name): "Read a size parameter off a container, and set it if present." value = container.getparameter(name) self.setvalue(name, value) def setvalue(self, name, value): "Set the value of a parameter name, only if it's valid." value = self.processparameter(value) if value: setattr(self, name, value) def checkvalidheight(self, container): "Check if the height parameter is valid; otherwise erase it." heightspecial = container.getparameter('height_special') if self.height and self.extractnumber(self.height) == '1' and heightspecial == 'totalheight': self.height = None def processparameter(self, value): "Do the full processing on a parameter." if not value: return None if self.extractnumber(value) == '0': return None for ignored in StyleConfig.size['ignoredtexts']: if ignored in value: value = value.replace(ignored, '') return value def extractnumber(self, text): "Extract the first number in the given text." result = '' decimal = False for char in text: if char.isdigit(): result += char elif char == '.' and not decimal: result += char decimal = True else: return result return result def checkimage(self, width, height): "Check image dimensions, set them if possible." if width: self.maxwidth = unicode(width) + 'px' if self.scale and not self.width: self.width = self.scalevalue(width) if height: self.maxheight = unicode(height) + 'px' if self.scale and not self.height: self.height = self.scalevalue(height) if self.width and not self.height: self.height = 'auto' if self.height and not self.width: self.width = 'auto' def scalevalue(self, value): "Scale the value according to the image scale and return it as unicode." scaled = value * int(self.scale) / 100 return unicode(int(scaled)) + 'px' def removepercentwidth(self): "Remove percent width if present, to set it at the figure level." if not self.width: return None if not '%' in self.width: return None width = self.width self.width = None if self.height == 'auto': self.height = None return width def addstyle(self, container): "Add the proper style attribute to the output tag." if not isinstance(container.output, TaggedOutput): Trace.error('No tag to add style, in ' + unicode(container)) if not self.width and not self.height and not self.maxwidth and not self.maxheight: # nothing to see here; move along return tag = ' style="' tag += self.styleparameter('width') tag += self.styleparameter('maxwidth') tag += self.styleparameter('height') tag += self.styleparameter('maxheight') if tag[-1] == ' ': tag = tag[:-1] tag += '"' container.output.tag += tag def styleparameter(self, name): "Get the style for a single parameter." value = getattr(self, name) if value: return name.replace('max', 'max-') + ': ' + value + '; ' return '' class QuoteContainer(Container): "A container for a pretty quote" def __init__(self): self.parser = BoundedParser() self.output = FixedOutput() def process(self): "Process contents" self.type = self.header[2] if not self.type in StyleConfig.quotes: Trace.error('Quote type ' + self.type + ' not found') self.html = ['"'] return self.html = [StyleConfig.quotes[self.type]] class LyXLine(Container): "A Lyx line" def __init__(self): self.parser = LoneCommand() self.output = FixedOutput() def process(self): self.html = ['
'] class EmphaticText(TaggedText): "Text with emphatic mode" def process(self): self.output.tag = 'i' class ShapedText(TaggedText): "Text shaped (italic, slanted)" def process(self): self.type = self.header[1] if not self.type in TagConfig.shaped: Trace.error('Unrecognized shape ' + self.header[1]) self.output.tag = 'span' return self.output.tag = TagConfig.shaped[self.type] class VersalitasText(TaggedText): "Text in versalitas" def process(self): self.output.tag = 'span class="versalitas"' class ColorText(TaggedText): "Colored text" def process(self): self.color = self.header[1] self.output.tag = 'span class="' + self.color + '"' class SizeText(TaggedText): "Sized text" def process(self): self.size = self.header[1] self.output.tag = 'span class="' + self.size + '"' class BoldText(TaggedText): "Bold text" def process(self): self.output.tag = 'b' class TextFamily(TaggedText): "A bit of text from elyxer.a different family" def process(self): "Parse the type of family" self.type = self.header[1] if not self.type in TagConfig.family: Trace.error('Unrecognized family ' + type) self.output.tag = 'span' return self.output.tag = TagConfig.family[self.type] class Hfill(TaggedText): "Horizontall fill" def process(self): self.output.tag = 'span class="hfill"' class BarredText(TaggedText): "Text with a bar somewhere" def process(self): "Parse the type of bar" self.type = self.header[1] if not self.type in TagConfig.barred: Trace.error('Unknown bar type ' + self.type) self.output.tag = 'span' return self.output.tag = TagConfig.barred[self.type] class LangLine(TaggedText): "A line with language information" def process(self): "Only generate a span with lang info when the language is recognized." lang = self.header[1] if not lang in TranslationConfig.languages: self.output = ContentsOutput() return isolang = TranslationConfig.languages[lang] self.output = TaggedOutput().settag('span lang="' + isolang + '"', False) class InsetLength(BlackBox): "A length measure inside an inset." def process(self): self.length = self.header[1] class Space(Container): "A space of several types" def __init__(self): self.parser = InsetParser() self.output = FixedOutput() def process(self): self.type = self.header[2] if self.type not in StyleConfig.hspaces: Trace.error('Unknown space type ' + self.type) self.html = [' '] return self.html = [StyleConfig.hspaces[self.type]] length = self.getlength() if not length: return self.output = TaggedOutput().settag('span class="hspace"', False) ContainerSize().set(length).addstyle(self) def getlength(self): "Get the space length from elyxer.the contents or parameters." if len(self.contents) == 0 or not isinstance(self.contents[0], InsetLength): return None return self.contents[0].length class VerticalSpace(Container): "An inset that contains a vertical space." def __init__(self): self.parser = InsetParser() self.output = FixedOutput() def process(self): "Set the correct tag" self.type = self.header[2] if self.type not in StyleConfig.vspaces: self.output = TaggedOutput().settag('div class="vspace" style="height: ' + self.type + ';"', True) return self.html = [StyleConfig.vspaces[self.type]] class Align(Container): "Bit of aligned text" def __init__(self): self.parser = ExcludingParser() self.output = TaggedOutput().setbreaklines(True) def process(self): self.output.tag = 'div class="' + self.header[1] + '"' class Newline(Container): "A newline" def __init__(self): self.parser = LoneCommand() self.output = FixedOutput() def process(self): "Process contents" self.html = ['
\n'] class NewPage(Newline): "A new page" def process(self): "Process contents" self.html = ['


\n

\n'] class Separator(Container): "A separator string which is not extracted by extracttext()." def __init__(self, constant): self.output = FixedOutput() self.contents = [] self.html = [constant] class StrikeOut(TaggedText): "Striken out text." def process(self): "Set the output tag to strike." self.output.tag = 'strike' class StartAppendix(BlackBox): "Mark to start an appendix here." "From this point on, all chapters become appendices." def process(self): "Activate the special numbering scheme for appendices, using letters." NumberGenerator.generator.startappendix() class Link(Container): "A link to another part of the document" anchor = None url = None type = None page = None target = None destination = None title = None def __init__(self): "Initialize the link, add target if configured." self.contents = [] self.parser = InsetParser() self.output = LinkOutput() if Options.target: self.target = Options.target def complete(self, text, anchor = None, url = None, type = None, title = None): "Complete the link." self.contents = [Constant(text)] if anchor: self.anchor = anchor if url: self.url = url if type: self.type = type if title: self.title = title return self def computedestination(self): "Use the destination link to fill in the destination URL." if not self.destination: return self.url = '' if self.destination.anchor: self.url = '#' + self.destination.anchor if self.destination.page: self.url = self.destination.page + self.url def setmutualdestination(self, destination): "Set another link as destination, and set its destination to this one." self.destination = destination destination.destination = self def __unicode__(self): "Return a printable representation." result = 'Link' if self.anchor: result += ' #' + self.anchor if self.url: result += ' to ' + self.url return result class URL(Link): "A clickable URL" def process(self): "Read URL from elyxer.parameters" target = self.escape(self.getparameter('target')) self.url = target type = self.getparameter('type') if type: self.url = self.escape(type) + target name = self.getparameter('name') if not name: name = target self.contents = [Constant(name)] class FlexURL(URL): "A flexible URL" def process(self): "Read URL from elyxer.contents" self.url = self.extracttext() class LinkOutput(ContainerOutput): "A link pointing to some destination" "Or an anchor (destination)" def gethtml(self, link): "Get the HTML code for the link" type = link.__class__.__name__ if link.type: type = link.type tag = 'a class="' + type + '"' if link.anchor: tag += ' name="' + link.anchor + '"' if link.destination: link.computedestination() if link.url: tag += ' href="' + link.url + '"' if link.target: tag += ' target="' + link.target + '"' if link.title: tag += ' title="' + link.title + '"' return TaggedOutput().settag(tag).gethtml(link) class Postprocessor(object): "Postprocess a container keeping some context" stages = [] def __init__(self): self.stages = StageDict(Postprocessor.stages, self) self.current = None self.last = None def postprocess(self, next): "Postprocess a container and its contents." self.postrecursive(self.current) result = self.postcurrent(next) self.last = self.current self.current = next return result def postrecursive(self, container): "Postprocess the container contents recursively" if not hasattr(container, 'contents'): return if len(container.contents) == 0: return if hasattr(container, 'postprocess'): if not container.postprocess: return postprocessor = Postprocessor() contents = [] for element in container.contents: post = postprocessor.postprocess(element) if post: contents.append(post) # two rounds to empty the pipeline for i in range(2): post = postprocessor.postprocess(None) if post: contents.append(post) container.contents = contents def postcurrent(self, next): "Postprocess the current element taking into account next and last." stage = self.stages.getstage(self.current) if not stage: return self.current return stage.postprocess(self.last, self.current, next) class StageDict(object): "A dictionary of stages corresponding to classes" def __init__(self, classes, postprocessor): "Instantiate an element from elyxer.each class and store as a dictionary" instances = self.instantiate(classes, postprocessor) self.stagedict = dict([(x.processedclass, x) for x in instances]) def instantiate(self, classes, postprocessor): "Instantiate an element from elyxer.each class" stages = [x.__new__(x) for x in classes] for element in stages: element.__init__() element.postprocessor = postprocessor return stages def getstage(self, element): "Get the stage for a given element, if the type is in the dict" if not element.__class__ in self.stagedict: return None return self.stagedict[element.__class__] class Label(Link): "A label to be referenced" names = dict() lastlayout = None def __init__(self): Link.__init__(self) self.lastnumbered = None def process(self): "Process a label container." key = self.getparameter('name') self.create(' ', key) self.lastnumbered = Label.lastlayout def create(self, text, key, type = 'Label'): "Create the label for a given key." self.key = key self.complete(text, anchor = key, type = type) Label.names[key] = self if key in Reference.references: for reference in Reference.references[key]: reference.destination = self return self def findpartkey(self): "Get the part key for the latest numbered container seen." numbered = self.numbered(self) if numbered and numbered.partkey: return numbered.partkey return '' def numbered(self, container): "Get the numbered container for the label." if container.partkey: return container if not container.parent: if self.lastnumbered: return self.lastnumbered return None return self.numbered(container.parent) def __unicode__(self): "Return a printable representation." if not hasattr(self, 'key'): return 'Unnamed label' return 'Label ' + self.key class Reference(Link): "A reference to a label." references = dict() key = 'none' def process(self): "Read the reference and set the arrow." self.key = self.getparameter('reference') if self.key in Label.names: self.direction = u'↑' label = Label.names[self.key] else: self.direction = u'↓' label = Label().complete(' ', self.key, 'preref') self.destination = label self.formatcontents() if not self.key in Reference.references: Reference.references[self.key] = [] Reference.references[self.key].append(self) def formatcontents(self): "Format the reference contents." formatkey = self.getparameter('LatexCommand') if not formatkey: formatkey = 'ref' self.formatted = u'↕' if formatkey in StyleConfig.referenceformats: self.formatted = StyleConfig.referenceformats[formatkey] else: Trace.error('Unknown reference format ' + formatkey) self.replace(u'↕', self.direction) self.replace('#', '1') self.replace('on-page', Translator.translate('on-page')) partkey = self.destination.findpartkey() # only if partkey and partkey.number are not null, send partkey.number self.replace('@', partkey and partkey.number) self.replace(u'¶', partkey and partkey.tocentry) if not '$' in self.formatted or not partkey or not partkey.titlecontents: # there is a $ left, but it should go away on preprocessing self.contents = [Constant(self.formatted)] return pieces = self.formatted.split('$') self.contents = [Constant(pieces[0])] for piece in pieces[1:]: self.contents += partkey.titlecontents self.contents.append(Constant(piece)) def replace(self, key, value): "Replace a key in the format template with a value." if not key in self.formatted: return if not value: value = '' self.formatted = self.formatted.replace(key, value) def __unicode__(self): "Return a printable representation." return 'Reference ' + self.key class FormulaCommand(FormulaBit): "A LaTeX command inside a formula" types = [] start = FormulaConfig.starts['command'] commandmap = None def detect(self, pos): "Find the current command." return pos.checkfor(FormulaCommand.start) def parsebit(self, pos): "Parse the command." command = self.extractcommand(pos) bit = self.parsewithcommand(command, pos) if bit: return bit if command.startswith('\\up') or command.startswith('\\Up'): upgreek = self.parseupgreek(command, pos) if upgreek: return upgreek if not self.factory.defining: Trace.error('Unknown command ' + command) self.output = TaggedOutput().settag('span class="unknown"') self.add(FormulaConstant(command)) return None def parsewithcommand(self, command, pos): "Parse the command type once we have the command." for type in FormulaCommand.types: if command in type.commandmap: return self.parsecommandtype(command, type, pos) return None def parsecommandtype(self, command, type, pos): "Parse a given command type." bit = self.factory.create(type) bit.setcommand(command) returned = bit.parsebit(pos) if returned: return returned return bit def extractcommand(self, pos): "Extract the command from elyxer.the current position." if not pos.checkskip(FormulaCommand.start): pos.error('Missing command start ' + FormulaCommand.start) return if pos.finished(): return self.emptycommand(pos) if pos.current().isalpha(): # alpha command command = FormulaCommand.start + pos.globalpha() # skip mark of short command pos.checkskip('*') return command # symbol command return FormulaCommand.start + pos.skipcurrent() def emptycommand(self, pos): """Check for an empty command: look for command disguised as ending. Special case against '{ \{ \} }' situation.""" command = '' if not pos.isout(): ending = pos.nextending() if ending and pos.checkskip(ending): command = ending return FormulaCommand.start + command def parseupgreek(self, command, pos): "Parse the Greek \\up command.." if len(command) < 4: return None if command.startswith('\\up'): upcommand = '\\' + command[3:] elif pos.checkskip('\\Up'): upcommand = '\\' + command[3:4].upper() + command[4:] else: Trace.error('Impossible upgreek command: ' + command) return upgreek = self.parsewithcommand(upcommand, pos) if upgreek: upgreek.type = 'font' return upgreek class CommandBit(FormulaCommand): "A formula bit that includes a command" def setcommand(self, command): "Set the command in the bit" self.command = command if self.commandmap: self.original += command self.translated = self.commandmap[self.command] def parseparameter(self, pos): "Parse a parameter at the current position" self.factory.clearskipped(pos) if pos.finished(): return None parameter = self.factory.parseany(pos) self.add(parameter) return parameter def parsesquare(self, pos): "Parse a square bracket" self.factory.clearskipped(pos) if not self.factory.detecttype(SquareBracket, pos): return None bracket = self.factory.parsetype(SquareBracket, pos) self.add(bracket) return bracket def parseliteral(self, pos): "Parse a literal bracket." self.factory.clearskipped(pos) if not self.factory.detecttype(Bracket, pos): if not pos.isvalue(): Trace.error('No literal parameter found at: ' + pos.identifier()) return None return pos.globvalue() bracket = Bracket().setfactory(self.factory) self.add(bracket.parseliteral(pos)) return bracket.literal def parsesquareliteral(self, pos): "Parse a square bracket literally." self.factory.clearskipped(pos) if not self.factory.detecttype(SquareBracket, pos): return None bracket = SquareBracket().setfactory(self.factory) self.add(bracket.parseliteral(pos)) return bracket.literal def parsetext(self, pos): "Parse a text parameter." self.factory.clearskipped(pos) if not self.factory.detecttype(Bracket, pos): Trace.error('No text parameter for ' + self.command) return None bracket = Bracket().setfactory(self.factory).parsetext(pos) self.add(bracket) return bracket class EmptyCommand(CommandBit): "An empty command (without parameters)" commandmap = FormulaConfig.commands def parsebit(self, pos): "Parse a command without parameters" self.contents = [FormulaConstant(self.translated)] class SpacedCommand(CommandBit): "An empty command which should have math spacing in formulas." commandmap = FormulaConfig.spacedcommands def parsebit(self, pos): "Place as contents the command translated and spaced." self.contents = [FormulaConstant(u' ' + self.translated + u' ')] class AlphaCommand(EmptyCommand): "A command without paramters whose result is alphabetical" commandmap = FormulaConfig.alphacommands def parsebit(self, pos): "Parse the command and set type to alpha" EmptyCommand.parsebit(self, pos) self.type = 'alpha' class OneParamFunction(CommandBit): "A function of one parameter" commandmap = FormulaConfig.onefunctions simplified = False def parsebit(self, pos): "Parse a function with one parameter" self.output = TaggedOutput().settag(self.translated) self.parseparameter(pos) self.simplifyifpossible() def simplifyifpossible(self): "Try to simplify to a single character." if self.original in self.commandmap: self.output = FixedOutput() self.html = [self.commandmap[self.original]] self.simplified = True class SymbolFunction(CommandBit): "Find a function which is represented by a symbol (like _ or ^)" commandmap = FormulaConfig.symbolfunctions def detect(self, pos): "Find the symbol" return pos.current() in SymbolFunction.commandmap def parsebit(self, pos): "Parse the symbol" self.setcommand(pos.current()) pos.skip(self.command) self.output = TaggedOutput().settag(self.translated) self.parseparameter(pos) class TextFunction(CommandBit): "A function where parameters are read as text." commandmap = FormulaConfig.textfunctions def parsebit(self, pos): "Parse a text parameter" self.output = TaggedOutput().settag(self.translated) self.parsetext(pos) def process(self): "Set the type to font" self.type = 'font' class LabelFunction(CommandBit): "A function that acts as a label" commandmap = FormulaConfig.labelfunctions def parsebit(self, pos): "Parse a literal parameter" self.key = self.parseliteral(pos) def process(self): "Add an anchor with the label contents." self.type = 'font' self.label = Label().create(' ', self.key, type = 'eqnumber') self.contents = [self.label] # store as a Label so we know it's been seen Label.names[self.key] = self.label class FontFunction(OneParamFunction): "A function of one parameter that changes the font" commandmap = FormulaConfig.fontfunctions def process(self): "Simplify if possible using a single character." self.type = 'font' self.simplifyifpossible() FormulaFactory.types += [FormulaCommand, SymbolFunction] FormulaCommand.types = [ AlphaCommand, EmptyCommand, OneParamFunction, FontFunction, LabelFunction, TextFunction, SpacedCommand, ] class BigSymbol(object): "A big symbol generator." symbols = FormulaConfig.bigsymbols def __init__(self, symbol): "Create the big symbol." self.symbol = symbol def getpieces(self): "Get an array with all pieces." if not self.symbol in self.symbols: return [self.symbol] if self.smalllimit(): return [self.symbol] return self.symbols[self.symbol] def smalllimit(self): "Decide if the limit should be a small, one-line symbol." if not DocumentParameters.displaymode: return True if len(self.symbols[self.symbol]) == 1: return True return Options.simplemath class BigBracket(BigSymbol): "A big bracket generator." def __init__(self, size, bracket, alignment='l'): "Set the size and symbol for the bracket." self.size = size self.original = bracket self.alignment = alignment self.pieces = None if bracket in FormulaConfig.bigbrackets: self.pieces = FormulaConfig.bigbrackets[bracket] def getpiece(self, index): "Return the nth piece for the bracket." function = getattr(self, 'getpiece' + unicode(len(self.pieces))) return function(index) def getpiece1(self, index): "Return the only piece for a single-piece bracket." return self.pieces[0] def getpiece3(self, index): "Get the nth piece for a 3-piece bracket: parenthesis or square bracket." if index == 0: return self.pieces[0] if index == self.size - 1: return self.pieces[-1] return self.pieces[1] def getpiece4(self, index): "Get the nth piece for a 4-piece bracket: curly bracket." if index == 0: return self.pieces[0] if index == self.size - 1: return self.pieces[3] if index == (self.size - 1)/2: return self.pieces[2] return self.pieces[1] def getcell(self, index): "Get the bracket piece as an array cell." piece = self.getpiece(index) span = 'span class="bracket align-' + self.alignment + '"' return TaggedBit().constant(piece, span) def getcontents(self): "Get the bracket as an array or as a single bracket." if self.size == 1 or not self.pieces: return self.getsinglebracket() rows = [] for index in range(self.size): cell = self.getcell(index) rows.append(TaggedBit().complete([cell], 'span class="arrayrow"')) return [TaggedBit().complete(rows, 'span class="array"')] def getsinglebracket(self): "Return the bracket as a single sign." if self.original == '.': return [TaggedBit().constant('', 'span class="emptydot"')] return [TaggedBit().constant(self.original, 'span class="symbol"')] class FormulaEquation(CommandBit): "A simple numbered equation." piece = 'equation' def parsebit(self, pos): "Parse the array" self.output = ContentsOutput() self.add(self.factory.parsetype(WholeFormula, pos)) class FormulaCell(FormulaCommand): "An array cell inside a row" def setalignment(self, alignment): self.alignment = alignment self.output = TaggedOutput().settag('span class="arraycell align-' + alignment +'"', True) return self def parsebit(self, pos): self.factory.clearskipped(pos) if pos.finished(): return self.add(self.factory.parsetype(WholeFormula, pos)) class FormulaRow(FormulaCommand): "An array row inside an array" cellseparator = FormulaConfig.array['cellseparator'] def setalignments(self, alignments): self.alignments = alignments self.output = TaggedOutput().settag('span class="arrayrow"', True) return self def parsebit(self, pos): "Parse a whole row" index = 0 pos.pushending(self.cellseparator, optional=True) while not pos.finished(): cell = self.createcell(index) cell.parsebit(pos) self.add(cell) index += 1 pos.checkskip(self.cellseparator) if len(self.contents) == 0: self.output = EmptyOutput() def createcell(self, index): "Create the cell that corresponds to the given index." alignment = self.alignments[index % len(self.alignments)] return self.factory.create(FormulaCell).setalignment(alignment) class MultiRowFormula(CommandBit): "A formula with multiple rows." def parserows(self, pos): "Parse all rows, finish when no more row ends" self.rows = [] first = True for row in self.iteraterows(pos): if first: first = False else: # intersparse empty rows self.addempty() row.parsebit(pos) self.addrow(row) self.size = len(self.rows) def iteraterows(self, pos): "Iterate over all rows, end when no more row ends" rowseparator = FormulaConfig.array['rowseparator'] while True: pos.pushending(rowseparator, True) row = self.factory.create(FormulaRow) yield row.setalignments(self.alignments) if pos.checkfor(rowseparator): self.original += pos.popending(rowseparator) else: return def addempty(self): "Add an empty row." row = self.factory.create(FormulaRow).setalignments(self.alignments) for index, originalcell in enumerate(self.rows[-1].contents): cell = row.createcell(index) cell.add(FormulaConstant(u' ')) row.add(cell) self.addrow(row) def addrow(self, row): "Add a row to the contents and to the list of rows." self.rows.append(row) self.add(row) class FormulaArray(MultiRowFormula): "An array within a formula" piece = 'array' def parsebit(self, pos): "Parse the array" self.output = TaggedOutput().settag('span class="array"', False) self.parsealignments(pos) self.parserows(pos) def parsealignments(self, pos): "Parse the different alignments" # vertical self.valign = 'c' literal = self.parsesquareliteral(pos) if literal: self.valign = literal # horizontal literal = self.parseliteral(pos) self.alignments = [] for l in literal: self.alignments.append(l) class FormulaMatrix(MultiRowFormula): "A matrix (array with center alignment)." piece = 'matrix' def parsebit(self, pos): "Parse the matrix, set alignments to 'c'." self.output = TaggedOutput().settag('span class="array"', False) self.valign = 'c' self.alignments = ['c'] self.parserows(pos) class FormulaCases(MultiRowFormula): "A cases statement" piece = 'cases' def parsebit(self, pos): "Parse the cases" self.output = ContentsOutput() self.alignments = ['l', 'l'] self.parserows(pos) for row in self.contents: for cell in row.contents: cell.output.settag('span class="case align-l"', True) cell.contents.append(FormulaConstant(u' ')) array = TaggedBit().complete(self.contents, 'span class="bracketcases"', True) brace = BigBracket(len(self.contents), '{', 'l') self.contents = brace.getcontents() + [array] class EquationEnvironment(MultiRowFormula): "A \\begin{}...\\end equation environment with rows and cells." def parsebit(self, pos): "Parse the whole environment." self.output = TaggedOutput().settag('span class="environment"', False) environment = self.piece.replace('*', '') if environment in FormulaConfig.environments: self.alignments = FormulaConfig.environments[environment] else: Trace.error('Unknown equation environment ' + self.piece) self.alignments = ['l'] self.parserows(pos) class BeginCommand(CommandBit): "A \\begin{}...\end command and what it entails (array, cases, aligned)" commandmap = {FormulaConfig.array['begin']:''} types = [FormulaEquation, FormulaArray, FormulaCases, FormulaMatrix] def parsebit(self, pos): "Parse the begin command" command = self.parseliteral(pos) bit = self.findbit(command) ending = FormulaConfig.array['end'] + '{' + command + '}' pos.pushending(ending) bit.parsebit(pos) self.add(bit) self.original += pos.popending(ending) self.size = bit.size def findbit(self, piece): "Find the command bit corresponding to the \\begin{piece}" for type in BeginCommand.types: if piece.replace('*', '') == type.piece: return self.factory.create(type) bit = self.factory.create(EquationEnvironment) bit.piece = piece return bit FormulaCommand.types += [BeginCommand] import datetime class CombiningFunction(OneParamFunction): commandmap = FormulaConfig.combiningfunctions def parsebit(self, pos): "Parse a combining function." self.type = 'alpha' combining = self.translated parameter = self.parsesingleparameter(pos) if not parameter: Trace.error('Empty parameter for combining function ' + self.command) elif len(parameter.extracttext()) != 1: Trace.error('Applying combining function ' + self.command + ' to invalid string "' + parameter.extracttext() + '"') self.contents.append(Constant(combining)) def parsesingleparameter(self, pos): "Parse a parameter, or a single letter." self.factory.clearskipped(pos) if pos.finished(): Trace.error('Error while parsing single parameter at ' + pos.identifier()) return None if self.factory.detecttype(Bracket, pos) \ or self.factory.detecttype(FormulaCommand, pos): return self.parseparameter(pos) letter = FormulaConstant(pos.skipcurrent()) self.add(letter) return letter class DecoratingFunction(OneParamFunction): "A function that decorates some bit of text" commandmap = FormulaConfig.decoratingfunctions def parsebit(self, pos): "Parse a decorating function" self.type = 'alpha' symbol = self.translated self.symbol = TaggedBit().constant(symbol, 'span class="symbolover"') self.parameter = self.parseparameter(pos) self.output = TaggedOutput().settag('span class="withsymbol"') self.contents.insert(0, self.symbol) self.parameter.output = TaggedOutput().settag('span class="undersymbol"') self.simplifyifpossible() class LimitCommand(EmptyCommand): "A command which accepts limits above and below, in display mode." commandmap = FormulaConfig.limitcommands def parsebit(self, pos): "Parse a limit command." pieces = BigSymbol(self.translated).getpieces() self.output = TaggedOutput().settag('span class="limits"') for piece in pieces: self.contents.append(TaggedBit().constant(piece, 'span class="limit"')) class LimitPreviousCommand(LimitCommand): "A command to limit the previous command." commandmap = None def parsebit(self, pos): "Do nothing." self.output = TaggedOutput().settag('span class="limits"') self.factory.clearskipped(pos) def __unicode__(self): "Return a printable representation." return 'Limit previous command' class LimitsProcessor(MathsProcessor): "A processor for limits inside an element." def process(self, contents, index): "Process the limits for an element." if Options.simplemath: return if self.checklimits(contents, index): self.modifylimits(contents, index) if self.checkscript(contents, index) and self.checkscript(contents, index + 1): self.modifyscripts(contents, index) def checklimits(self, contents, index): "Check if the current position has a limits command." if not DocumentParameters.displaymode: return False if self.checkcommand(contents, index + 1, LimitPreviousCommand): self.limitsahead(contents, index) return False if not isinstance(contents[index], LimitCommand): return False return self.checkscript(contents, index + 1) def limitsahead(self, contents, index): "Limit the current element based on the next." contents[index + 1].add(contents[index].clone()) contents[index].output = EmptyOutput() def modifylimits(self, contents, index): "Modify a limits commands so that the limits appear above and below." limited = contents[index] subscript = self.getlimit(contents, index + 1) limited.contents.append(subscript) if self.checkscript(contents, index + 1): superscript = self.getlimit(contents, index + 1) else: superscript = TaggedBit().constant(u' ', 'sup class="limit"') limited.contents.insert(0, superscript) def getlimit(self, contents, index): "Get the limit for a limits command." limit = self.getscript(contents, index) limit.output.tag = limit.output.tag.replace('script', 'limit') return limit def modifyscripts(self, contents, index): "Modify the super- and subscript to appear vertically aligned." subscript = self.getscript(contents, index) # subscript removed so instead of index + 1 we get index again superscript = self.getscript(contents, index) scripts = TaggedBit().complete([superscript, subscript], 'span class="scripts"') contents.insert(index, scripts) def checkscript(self, contents, index): "Check if the current element is a sub- or superscript." return self.checkcommand(contents, index, SymbolFunction) def checkcommand(self, contents, index, type): "Check for the given type as the current element." if len(contents) <= index: return False return isinstance(contents[index], type) def getscript(self, contents, index): "Get the sub- or superscript." bit = contents[index] bit.output.tag += ' class="script"' del contents[index] return bit class BracketCommand(OneParamFunction): "A command which defines a bracket." commandmap = FormulaConfig.bracketcommands def parsebit(self, pos): "Parse the bracket." OneParamFunction.parsebit(self, pos) def create(self, direction, character): "Create the bracket for the given character." self.original = character self.command = '\\' + direction self.contents = [FormulaConstant(character)] return self class BracketProcessor(MathsProcessor): "A processor for bracket commands." def process(self, contents, index): "Convert the bracket using Unicode pieces, if possible." if Options.simplemath: return if self.checkleft(contents, index): return self.processleft(contents, index) def processleft(self, contents, index): "Process a left bracket." rightindex = self.findright(contents, index + 1) if not rightindex: return size = self.findmax(contents, index, rightindex) self.resize(contents[index], size) self.resize(contents[rightindex], size) def checkleft(self, contents, index): "Check if the command at the given index is left." return self.checkdirection(contents[index], '\\left') def checkright(self, contents, index): "Check if the command at the given index is right." return self.checkdirection(contents[index], '\\right') def checkdirection(self, bit, command): "Check if the given bit is the desired bracket command." if not isinstance(bit, BracketCommand): return False return bit.command == command def findright(self, contents, index): "Find the right bracket starting at the given index, or 0." depth = 1 while index < len(contents): if self.checkleft(contents, index): depth += 1 if self.checkright(contents, index): depth -= 1 if depth == 0: return index index += 1 return None def findmax(self, contents, leftindex, rightindex): "Find the max size of the contents between the two given indices." sliced = contents[leftindex:rightindex] return max([element.size for element in sliced]) def resize(self, command, size): "Resize a bracket command to the given size." character = command.extracttext() alignment = command.command.replace('\\', '') bracket = BigBracket(size, character, alignment) command.output = ContentsOutput() command.contents = bracket.getcontents() class TodayCommand(EmptyCommand): "Shows today's date." commandmap = None def parsebit(self, pos): "Parse a command without parameters" self.output = FixedOutput() self.html = [datetime.date.today().strftime('%b %d, %Y')] FormulaCommand.types += [ DecoratingFunction, CombiningFunction, LimitCommand, BracketCommand, ] FormulaProcessor.processors += [ LimitsProcessor(), BracketProcessor(), ] class ParameterDefinition(object): "The definition of a parameter in a hybrid function." "[] parameters are optional, {} parameters are mandatory." "Each parameter has a one-character name, like {$1} or {$p}." "A parameter that ends in ! like {$p!} is a literal." "Example: [$1]{$p!} reads an optional parameter $1 and a literal mandatory parameter p." parambrackets = [('[', ']'), ('{', '}')] def __init__(self): self.name = None self.literal = False self.optional = False self.value = None self.literalvalue = None def parse(self, pos): "Parse a parameter definition: [$0], {$x}, {$1!}..." for (opening, closing) in ParameterDefinition.parambrackets: if pos.checkskip(opening): if opening == '[': self.optional = True if not pos.checkskip('$'): Trace.error('Wrong parameter name, did you mean $' + pos.current() + '?') return None self.name = pos.skipcurrent() if pos.checkskip('!'): self.literal = True if not pos.checkskip(closing): Trace.error('Wrong parameter closing ' + pos.skipcurrent()) return None return self Trace.error('Wrong character in parameter template: ' + pos.skipcurrent()) return None def read(self, pos, function): "Read the parameter itself using the definition." if self.literal: if self.optional: self.literalvalue = function.parsesquareliteral(pos) else: self.literalvalue = function.parseliteral(pos) if self.literalvalue: self.value = FormulaConstant(self.literalvalue) elif self.optional: self.value = function.parsesquare(pos) else: self.value = function.parseparameter(pos) def __unicode__(self): "Return a printable representation." result = 'param ' + self.name if self.value: result += ': ' + unicode(self.value) else: result += ' (empty)' return result class ParameterFunction(CommandBit): "A function with a variable number of parameters defined in a template." "The parameters are defined as a parameter definition." def readparams(self, readtemplate, pos): "Read the params according to the template." self.params = dict() for paramdef in self.paramdefs(readtemplate): paramdef.read(pos, self) self.params['$' + paramdef.name] = paramdef def paramdefs(self, readtemplate): "Read each param definition in the template" pos = TextPosition(readtemplate) while not pos.finished(): paramdef = ParameterDefinition().parse(pos) if paramdef: yield paramdef def getparam(self, name): "Get a parameter as parsed." if not name in self.params: return None return self.params[name] def getvalue(self, name): "Get the value of a parameter." return self.getparam(name).value def getliteralvalue(self, name): "Get the literal value of a parameter." param = self.getparam(name) if not param or not param.literalvalue: return None return param.literalvalue class HybridFunction(ParameterFunction): """ A parameter function where the output is also defined using a template. The template can use a number of functions; each function has an associated tag. Example: [f0{$1},span class="fbox"] defines a function f0 which corresponds to a span of class fbox, yielding $1. Literal parameters can be used in tags definitions: [f0{$1},span style="color: $p;"] yields $1, where $p is a literal parameter. Sizes can be specified in hybridsizes, e.g. adding parameter sizes. By default the resulting size is the max of all arguments. Sizes are used to generate the right parameters. A function followed by a single / is output as a self-closing XHTML tag: [f0/,hr] will generate
. """ commandmap = FormulaConfig.hybridfunctions def parsebit(self, pos): "Parse a function with [] and {} parameters" readtemplate = self.translated[0] writetemplate = self.translated[1] self.readparams(readtemplate, pos) self.contents = self.writeparams(writetemplate) self.computehybridsize() def writeparams(self, writetemplate): "Write all params according to the template" return self.writepos(TextPosition(writetemplate)) def writepos(self, pos): "Write all params as read in the parse position." result = [] while not pos.finished(): if pos.checkskip('$'): param = self.writeparam(pos) if param: result.append(param) elif pos.checkskip('f'): function = self.writefunction(pos) if function: function.type = None result.append(function) elif pos.checkskip('('): result.append(self.writebracket('left', '(')) elif pos.checkskip(')'): result.append(self.writebracket('right', ')')) else: result.append(FormulaConstant(pos.skipcurrent())) return result def writeparam(self, pos): "Write a single param of the form $0, $x..." name = '$' + pos.skipcurrent() if not name in self.params: Trace.error('Unknown parameter ' + name) return None if not self.params[name]: return None if pos.checkskip('.'): self.params[name].value.type = pos.globalpha() return self.params[name].value def writefunction(self, pos): "Write a single function f0,...,fn." tag = self.readtag(pos) if not tag: return None if pos.checkskip('/'): # self-closing XHTML tag, such as
return TaggedBit().selfcomplete(tag) if not pos.checkskip('{'): Trace.error('Function should be defined in {}') return None pos.pushending('}') contents = self.writepos(pos) pos.popending() if len(contents) == 0: return None return TaggedBit().complete(contents, tag) def readtag(self, pos): "Get the tag corresponding to the given index. Does parameter substitution." if not pos.current().isdigit(): Trace.error('Function should be f0,...,f9: f' + pos.current()) return None index = int(pos.skipcurrent()) if 2 + index > len(self.translated): Trace.error('Function f' + unicode(index) + ' is not defined') return None tag = self.translated[2 + index] if not '$' in tag: return tag for variable in self.params: if variable in tag: param = self.params[variable] if not param.literal: Trace.error('Parameters in tag ' + tag + ' should be literal: {' + variable + '!}') continue if param.literalvalue: value = param.literalvalue else: value = '' tag = tag.replace(variable, value) return tag def writebracket(self, direction, character): "Return a new bracket looking at the given direction." return self.factory.create(BracketCommand).create(direction, character) def computehybridsize(self): "Compute the size of the hybrid function." if not self.command in HybridSize.configsizes: self.computesize() return self.size = HybridSize().getsize(self) # set the size in all elements at first level for element in self.contents: element.size = self.size class HybridSize(object): "The size associated with a hybrid function." configsizes = FormulaConfig.hybridsizes def getsize(self, function): "Read the size for a function and parse it." sizestring = self.configsizes[function.command] for name in function.params: if name in sizestring: size = function.params[name].value.computesize() sizestring = sizestring.replace(name, unicode(size)) if '$' in sizestring: Trace.error('Unconverted variable in hybrid size: ' + sizestring) return 1 return eval(sizestring) FormulaCommand.types += [HybridFunction] class HeaderParser(Parser): "Parses the LyX header" def parse(self, reader): "Parse header parameters into a dictionary, return the preamble." contents = [] self.parseending(reader, lambda: self.parseline(reader, contents)) # skip last line reader.nextline() return contents def parseline(self, reader, contents): "Parse a single line as a parameter or as a start" line = reader.currentline() if line.startswith(HeaderConfig.parameters['branch']): self.parsebranch(reader) return elif line.startswith(HeaderConfig.parameters['lstset']): LstParser().parselstset(reader) return elif line.startswith(HeaderConfig.parameters['beginpreamble']): contents.append(self.factory.createcontainer(reader)) return # no match self.parseparameter(reader) def parsebranch(self, reader): "Parse all branch definitions." branch = reader.currentline().split()[1] reader.nextline() subparser = HeaderParser().complete(HeaderConfig.parameters['endbranch']) subparser.parse(reader) options = BranchOptions(branch) for key in subparser.parameters: options.set(key, subparser.parameters[key]) Options.branches[branch] = options def complete(self, ending): "Complete the parser with the given ending." self.ending = ending return self class PreambleParser(Parser): "A parser for the LyX preamble." preamble = [] def parse(self, reader): "Parse the full preamble with all statements." self.ending = HeaderConfig.parameters['endpreamble'] self.parseending(reader, lambda: self.parsepreambleline(reader)) return [] def parsepreambleline(self, reader): "Parse a single preamble line." PreambleParser.preamble.append(reader.currentline()) reader.nextline() class LstParser(object): "Parse global and local lstparams." globalparams = dict() def parselstset(self, reader): "Parse a declaration of lstparams in lstset." paramtext = self.extractlstset(reader) if not '{' in paramtext: Trace.error('Missing opening bracket in lstset: ' + paramtext) return lefttext = paramtext.split('{')[1] croppedtext = lefttext[:-1] LstParser.globalparams = self.parselstparams(croppedtext) def extractlstset(self, reader): "Extract the global lstset parameters." paramtext = '' while not reader.finished(): paramtext += reader.currentline() reader.nextline() if paramtext.endswith('}'): return paramtext Trace.error('Could not find end of \\lstset settings; aborting') def parsecontainer(self, container): "Parse some lstparams from elyxer.a container." container.lstparams = LstParser.globalparams.copy() paramlist = container.getparameterlist('lstparams') container.lstparams.update(self.parselstparams(paramlist)) def parselstparams(self, paramlist): "Process a number of lstparams from elyxer.a list." paramdict = dict() for param in paramlist: if not '=' in param: if len(param.strip()) > 0: Trace.error('Invalid listing parameter ' + param) else: key, value = param.split('=', 1) paramdict[key] = value return paramdict class MacroDefinition(CommandBit): "A function that defines a new command (a macro)." macros = dict() def parsebit(self, pos): "Parse the function that defines the macro." self.output = EmptyOutput() self.parameternumber = 0 self.defaults = [] self.factory.defining = True self.parseparameters(pos) self.factory.defining = False Trace.debug('New command ' + self.newcommand + ' (' + \ unicode(self.parameternumber) + ' parameters)') self.macros[self.newcommand] = self def parseparameters(self, pos): "Parse all optional parameters (number of parameters, default values)" "and the mandatory definition." self.newcommand = self.parsenewcommand(pos) # parse number of parameters literal = self.parsesquareliteral(pos) if literal: self.parameternumber = int(literal) # parse all default values bracket = self.parsesquare(pos) while bracket: self.defaults.append(bracket) bracket = self.parsesquare(pos) # parse mandatory definition self.definition = self.parseparameter(pos) def parsenewcommand(self, pos): "Parse the name of the new command." self.factory.clearskipped(pos) if self.factory.detecttype(Bracket, pos): return self.parseliteral(pos) if self.factory.detecttype(FormulaCommand, pos): return self.factory.create(FormulaCommand).extractcommand(pos) Trace.error('Unknown formula bit in defining function at ' + pos.identifier()) return 'unknown' def instantiate(self): "Return an instance of the macro." return self.definition.clone() class MacroParameter(FormulaBit): "A parameter from elyxer.a macro." def detect(self, pos): "Find a macro parameter: #n." return pos.checkfor('#') def parsebit(self, pos): "Parse the parameter: #n." if not pos.checkskip('#'): Trace.error('Missing parameter start #.') return self.number = int(pos.skipcurrent()) self.original = '#' + unicode(self.number) self.contents = [TaggedBit().constant('#' + unicode(self.number), 'span class="unknown"')] class MacroFunction(CommandBit): "A function that was defined using a macro." commandmap = MacroDefinition.macros def parsebit(self, pos): "Parse a number of input parameters." self.output = FilteredOutput() self.values = [] macro = self.translated self.parseparameters(pos, macro) self.completemacro(macro) def parseparameters(self, pos, macro): "Parse as many parameters as are needed." self.parseoptional(pos, list(macro.defaults)) self.parsemandatory(pos, macro.parameternumber - len(macro.defaults)) if len(self.values) < macro.parameternumber: Trace.error('Missing parameters in macro ' + unicode(self)) def parseoptional(self, pos, defaults): "Parse optional parameters." optional = [] while self.factory.detecttype(SquareBracket, pos): optional.append(self.parsesquare(pos)) if len(optional) > len(defaults): break for value in optional: default = defaults.pop() if len(value.contents) > 0: self.values.append(value) else: self.values.append(default) self.values += defaults def parsemandatory(self, pos, number): "Parse a number of mandatory parameters." for index in range(number): parameter = self.parsemacroparameter(pos, number - index) if not parameter: return self.values.append(parameter) def parsemacroparameter(self, pos, remaining): "Parse a macro parameter. Could be a bracket or a single letter." "If there are just two values remaining and there is a running number," "parse as two separater numbers." self.factory.clearskipped(pos) if pos.finished(): return None if self.factory.detecttype(FormulaNumber, pos): return self.parsenumbers(pos, remaining) return self.parseparameter(pos) def parsenumbers(self, pos, remaining): "Parse the remaining parameters as a running number." "For example, 12 would be {1}{2}." number = self.factory.parsetype(FormulaNumber, pos) if not len(number.original) == remaining: return number for digit in number.original: value = self.factory.create(FormulaNumber) value.add(FormulaConstant(digit)) value.type = number self.values.append(value) return None def completemacro(self, macro): "Complete the macro with the parameters read." self.contents = [macro.instantiate()] replaced = [False] * len(self.values) for parameter in self.searchall(MacroParameter): index = parameter.number - 1 if index >= len(self.values): Trace.error('Macro parameter index out of bounds: ' + unicode(index)) return replaced[index] = True parameter.contents = [self.values[index].clone()] for index in range(len(self.values)): if not replaced[index]: self.addfilter(index, self.values[index]) def addfilter(self, index, value): "Add a filter for the given parameter number and parameter value." original = '#' + unicode(index + 1) value = ''.join(self.values[0].gethtml()) self.output.addfilter(original, value) class FormulaMacro(Formula): "A math macro defined in an inset." def __init__(self): self.parser = MacroParser() self.output = EmptyOutput() def __unicode__(self): "Return a printable representation." return 'Math macro' FormulaFactory.types += [ MacroParameter ] FormulaCommand.types += [ MacroFunction, ] def math2html(formula): "Convert some TeX math to HTML." factory = FormulaFactory() whole = factory.parseformula(formula) FormulaProcessor().process(whole) whole.process() return ''.join(whole.gethtml()) def main(): "Main function, called if invoked from elyxer.the command line" args = sys.argv Options().parseoptions(args) if len(args) != 1: Trace.error('Usage: math2html.py escaped_string') exit() result = math2html(args[0]) Trace.message(result) if __name__ == '__main__': main() elyxer-1.2.5/src/0000755000175000017500000000000012117063046013124 5ustar chennochennoelyxer-1.2.5/src/freebsd-license0000644000175000017500000000116412074107030016075 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # math2html: convert LaTeX equations to HTML output. # # Copyright (C) 2009-2011 Alex Fernández # # Released under the terms of the `2-Clause BSD license'_, in short: # Copying and distribution of this file, with or without modification, # are permitted in any medium without royalty provided the copyright # notice and this notice are preserved. # This file is offered as-is, without any warranty. # # .. _2-Clause BSD license: http://www.spdx.org/licenses/BSD-2-Clause # Based on eLyXer: convert LyX source files to HTML output. # http://elyxer.nongnu.org/ elyxer-1.2.5/src/jtp/0000755000175000017500000000000012074107030013713 5ustar chennochennoelyxer-1.2.5/src/jtp/exportconfig.sh0000755000175000017500000000020512074107030016756 0ustar chennochenno#!/bin/bash # Alex 2010-03-14: export configuration for JavaToPy ./exportconfig.py --cfg conf/jtp.cfg --py conf/javatopyconf.py py elyxer-1.2.5/src/jtp/porter.py0000644000175000017500000002163212074107030015604 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20091226 # Port a Java program to a Python equivalent. Used to port MathToWeb. from elyxer.jtp.parser import * from elyxer.jtp.grammar import * from elyxer.util.trace import Trace class JavaPorter(object): "Ports a Java file." def __init__(self): Grammar.instance.process() self.chooser = StatementChooser() def topy(self, filepos, writer): "Port the Java input file to Python." tok = Tokenizer(filepos) Grammar.instance.parse(tok) return while not tok.finished(): statement = self.nextstatement(tok) writer.writeline(statement) writer.close() def nextstatement(self, tok): "Return the next statement." statement = None while not statement and not tok.finished(): indent = self.chooser.getindent(tok) statement = self.parsestatement(tok) if not statement: return '' Trace.debug('Statement: ' + statement.strip()) if statement.startswith('\n'): # displace newline return '\n' + indent + statement[1:] return indent + statement def parsestatement(self, tok): "Parse a single statement." pending = self.chooser.pendingstatement(tok) if pending: return pending return self.chooser.choose(tok) class StatementChooser(object): "Chooses the next statement to parse, according to the first token." starttokens = { 'if':'conditionblock', 'catch':'parametersblock', 'import':'ignorestatement', 'public':'classormember', 'protected':'classormember', 'private':'classormember', 'class':'parseclass', 'else':'elseblock', 'try':'tryblock', 'return':'returnstatement', '{':'openblock', '}':'closeblock', 'for':'forparens0', 'throw':'throwstatement', 'throws':'throwsdeclaration', ';':'ignorestatement', 'while':'conditionblock' } javatokens = { 'new':'createstatement', 'this':'thisstatement' } def __init__(self): self.parser = StatementParser(self) def getindent(self, tok): "Get the indent for the next statement." return ' ' * tok.depth def choose(self, tok): "Parse a single statement." token = tok.next() if not token: return None if token in self.starttokens: function = getattr(self, self.starttokens[token]) elif token in self.javatokens: function = getattr(self, self.javatokens[token]) else: function = self.assigninvoke return function(tok) def pendingstatement(self, tok): "Return any pending statement from elyxer.before." if tok.infor != 0: tok.next() function = getattr(self, 'forparens' + unicode(tok.infor)) return function(tok) if len(tok.autoincreases) != 0: return self.autoincrease(tok) if len(tok.autodecreases) != 0: return self.autodecrease(tok) return None def autoincrease(self, tok): "Process a Java autoincrease (++)." variable = tok.autoincreases.pop() return variable + ' += 1' def autodecrease(self, tok): "Process a Java autodecrease (--)." variable = tok.autodecreases.pop() return variable + ' -= 1' def classormember(self, tok): "Parse a class or member (attribute or method)." if tok.inclass: return self.parser.translateinternal(tok) else: return self.parser.translateclass(tok) def conditionblock(self, tok): "Parse a condition in () and then a block {} (if or while statements)." token = tok.current() tok.checknext('(') parens = self.parser.parsecondition(tok, ')') self.parser.expectblock(tok) return token + ' ' + parens + ':' def parametersblock(self, tok): "Parse a parameters () and then a block {} (catch statement)." tok.checknext('(') parens = self.parser.listparameters(tok) self.parser.expectblock(tok) return 'except:' def forparens0(self, tok): "Parse the first statement of a for loop." "The remaining parts of the for(;;){} are parsed later." tok.checknext('(') first = self.assigninvoke(tok, tok.next()) tok.infor = 1 return first def forparens1(self, tok): "Read the condition in a for loop." condition = tok.current() + ' ' + self.parser.parseupto(';', tok) tok.depth += 1 tok.infor = 2 return 'while ' + condition + ':' def forparens2(self, tok): "Read the repeating statement in a for loop." statement = tok.current() + ' ' + self.parser.parseupto(')', tok) tok.depth -= 1 tok.infor = 0 self.parser.expectblock(tok) return statement def tryblock(self, tok): "Parse a block after a try." self.parser.expectblock(tok) return tok.current() + ':' def elseblock(self, tok): "Parse a block after an else." self.parser.expectblock(tok) if tok.peek() == 'if': tok.next() self.closeblock(tok) return 'el' + self.conditionblock(tok) return 'else:' def openblock(self, tok): "Open a block of code." if tok.waitingforblock: tok.waitingforblock = False else: tok.depth += 1 if tok.peek() == '}': return 'pass' return None def closeblock(self, tok): "Close a block of code." tok.depth -= 1 return None def returnstatement(self, tok): "A statement that contains a value (a return statement)." self.onelineblock(tok) return 'return ' + self.parser.parsevalue(tok) def throwstatement(self, tok): "A statement to throw (raise) an exception." exception = tok.next() if exception == 'new': return 'raise ' + self.createstatement(tok) token = tok.next() if token == ';': return 'raise ' + exception Trace.error('Invalid throw statement: "throw ' + exception + ' ' + token + '"') return 'raise ' + exception def throwsdeclaration(self, tok): "A throws clause, should be ignored." name = tok.next() return '' def assigninvoke(self, tok, token = None): "An assignment or a method invocation." self.onelineblock(tok) if not token: token = tok.current() token2 = tok.next() if token2 == '=': # assignment return token + ' = ' + self.parser.parsevalue(tok) if token2 == '.': member = tok.next() return self.assigninvoke(tok, token + '.' + member) if token2 == '(': parameters = self.parser.parseparameters(tok) Trace.debug('Parameters: ' + parameters) return self.assigninvoke(tok, token + parameters) if token2 == '[': square = self.parser.parseinsquare(tok) return self.assigninvoke(tok, token + square) if token2 == '{': # ignore anonymous class self.parser.parseupto('}', tok) return token if token2 == '++': Trace.debug('Increasing invoked ' + token) tok.autoincreases.append(token) return self.assigninvoke(tok, token + ' + 1') if token2 == '--': Trace.debug('Decreasing invoked ' + token) tok.autodecreases.append(token) return self.assigninvoke(tok, token + ' - 1') if token2 in [';', ',', ')']: # finished invocation return token if token2 in tok.javasymbols: Trace.error('Unknown symbol ' + token2 + ' for ' + token) return '*error ' + token + ' ' + token2 + ' error*' token3 = tok.next() if token3 == ';': # a declaration; ignore return '' if token3 == '=': # declaration + assignment tok.variables.append(token2) return token2 + ' = ' + self.parser.parsevalue(tok) if token3 == '[': # array declaration self.parser.parseupto(']', tok) return self.assigninvoke(tok, token2) Trace.error('Unknown combination ' + token + '+' + token2 + '+' + token3) return '*error ' + token + ' ' + token2 + ' ' + token + ' error*' def onelineblock(self, tok): "Check if a block was expected." if tok.waitingforblock: tok.waitingforblock = False tok.depth -= 1 def ignorestatement(self, tok): "Ignore a whole statement." while tok.current() != ';': tok.next() return None def createstatement(self, tok): "A statement to create an object and use it: new Class().do()." tok.next() return self.parser.parseinvocation(tok) def thisstatement(self, tok): "A statement starting with this, which translates to self." return self.assigninvoke(tok, 'self') elyxer-1.2.5/src/jtp/grammar.py0000644000175000017500000002476412074107030015730 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20100311 # Read a generic grammar. from elyxer.util.trace import Trace from elyxer.util.clone import * from elyxer.conf.javatopyconf import * from elyxer.parse.position import * class Piece(object): "Represents a piece (word, bracket... of any type) in a grammar." def __init__(self): "Initialize common variables." self.closed = False self.valid = True def match(self, tok): "Match the piece against the current token and return the match." Trace.error('Unmatchable piece ' + unicode(self) + ' in ' + unicode(tok)) return None def fitnext(self, token): "Try to fit the next token and return the corresponding declaration." Trace.error('Unimplemented method: fit()') class ConstantWord(Piece): "Represents a constant word in a grammar." def __init__(self, constant): "Initialize the word with the constant." self.constant = constant def match(self, tok): "Just match the current token against the constant." if tok.current() == self.constant: tok.next() return self return None def fitnext(self, token): "Try to fit the next token." self.closed = True if token != self.constant: self.valid = False return None return self def __unicode__(self): "Printable representation." return '\'' + self.constant + '\'' class IdentifierWord(Piece): "A word made of alphanumeric and _ characters." def __init__(self): "Just create an empty word." self.word = None def set(self, word): self.word = word return self def match(self, tok): "Match the current token and store in the template." if tok.iscurrentidentifier(): identifier = IdentifierWord().set(tok.current()) tok.next() return identifier return None def fitnext(self, token): "Try to fit the next token." self.closed = True if token.iscurrentidentifier(): return IdentifierWord().set(tok.current()) return None class Bracket(Piece): "A bracket consisting of other words (repeated, conditional)." quantified = dict() def __init__(self): "Create an empty bracket." self.declaration = None self.quantifier = None def create(self, declaration, quantifier): "Create the bracket for a given declaration." self.declaration = declaration self.quantifier = quantifier return self def parse(self, pos): "Parse the bracket." pos.pushending(']') declaration = Declaration('bracket').parse(pos) pos.popending(']') quantifier = pos.skipcurrent() if not quantifier in self.quantified: Trace.error('Unknown quantifier ' + quantifier) return self bracket = Cloner.clone(self.quantified[quantifier]).create(declaration, quantifier) Trace.debug('Bracket: ' + unicode(bracket)) return bracket def __unicode__(self): "Printable representation." return '[' + unicode(self.declaration) + ']' + self.quantifier class MultipleBracket(Bracket): "A bracket present zero or more times (quantifier *)." def match(self, tok): "Match the bracket zero or more times." decl = Declaration('*') result = self.declaration.match(tok) while result != None: decl.pieces.append(result) result = self.declaration.match(tok) return decl class RepeatedBracket(Bracket): "A bracket present one or more times (quantifier +)." def match(self, tok): "Match the bracket at least one time." decl = Declaration('*') result = self.declaration.match(tok) if not result: return None while result != None: decl.pieces.append(result) result = self.declaration.match(tok) return decl class ConditionalBracket(Bracket): "A bracket which may or may not be present (quantifier ?)." def match(self, tok): "Match the bracket, or not." decl = Declaration('?') result = self.declaration.match(tok) if result: decl.pieces.append(result) return decl def fitnext(self, token): "Try to fit the next token." result = self.declaration.fitnext(token) decl = None if not self.declaration.valid: self.closed = True elif self.declaration.closed: self.closed = True if result: return result if token != self.constant: self.valid = False return None return self Bracket.quantified = { '*': MultipleBracket(), '+': RepeatedBracket(), '?': ConditionalBracket() } class Alternatives(Piece): "A group of alternatives to parse." def __init__(self): "Create an empty set of alternatives." self.alternatives = [] def add(self, pieces): "Add a new set of alternative pieces." alternative = Declaration('#' + unicode(len(self.alternatives))) alternative.pieces = pieces self.alternatives.append(alternative) Trace.debug('Alternatives: ' + unicode(self)) return self def match(self, tok): "Match any of the alternatives." for alternative in self.alternatives: result = alternative.match(tok) if result: return result return None def __unicode__(self): "Printable representation." if len(self.alternatives) == 0: return 'Empty alternatives' result = '' for alternative in self.alternatives: result += ' | ' + unicode(alternative) return result[3:] class Declaration(Piece): "A grammar declaration consisting of several pieces." notsymbol = '[]_ |$' pieces = [] def __init__(self, key): self.key = key self.pieces = [] def parse(self, pos): "Parse the given position." while not pos.finished(): if pos.checkskip('$'): self.parsevariable(pos) elif pos.checkskip('['): self.parsebracket(pos) elif pos.checkidentifier(): self.parseidentifier(pos) elif pos.checkskip(' '): # ignore blank characters pass elif pos.checkskip('|'): self.parsealternative(pos) else: self.parsesymbol(pos) self.checkalternatives() return self def parsevariable(self, pos): "Parse a variable." if pos.checkskip('$'): self.pieces.append(IdentifierWord()) return name = '$' + pos.globidentifier() if not name in Grammar.instance.declarations: Trace.error('Unknown variable ' + name) return Trace.debug('New variable ' + name) self.pieces.append(Grammar.instance.declarations[name]) def parsebracket(self, pos): "Parse a bracket and the quantifier (*+?)." self.pieces.append(Bracket().parse(pos)) def parseidentifier(self, pos): "Parse a constant identifier value." self.addconstant(pos.globidentifier()) def parsealternative(self, pos): "Parse an alternative in a group." if len(self.pieces) == 0: Trace.error('Empty beginning alternative at ' + pos.identifier()) return if self.checkalternatives(): return alt = Alternatives().add(self.pieces) self.pieces = [alt] def checkalternatives(self): "Check if there is a set of alternatives active, and add everything there." if len(self.pieces) == 0 or not isinstance(self.pieces[0], Alternatives): return False if len(self.pieces) == 1: Trace.error('Empty alternative') return self.pieces[0].add(self.pieces[1:]) self.pieces = [self.pieces[0]] return True def parsesymbol(self, pos): "Parse a symbol." symbol = '' while self.issymbol(pos): symbol += pos.skipcurrent() if symbol == '': symbol += pos.skipcurrent() Trace.error('Empty symbol; acquiring ' + symbol) self.addconstant(symbol) def issymbol(self, pos): "Find out if the current character belongs to a larger symbol." if pos.finished(): return False if pos.current() in self.notsymbol: return False if pos.checkidentifier(): return False return True def addconstant(self, constant): "Add a constant value." if constant in Grammar.instance.constants: Trace.error('Repeated constant ' + constant) return Trace.debug('New constant: ' + constant) self.pieces.append(ConstantWord(constant)) def match(self, tok): "Match the declaration against a tokenizer." decl = Declaration(self.key) state = tok.mark() for piece in self.pieces: Trace.debug('Matching ' + tok.current() + ' against ' + unicode(piece)) result = piece.match(tok) if not result: Trace.error('Mismatch of ' + tok.current() + ' against ' + unicode(piece)) tok.revert(state) return None decl.pieces.append(result) return decl def __unicode__(self): "Printable representation." if len(self.pieces) == 0: return u'❲empty❳' result = '' for piece in self.pieces: if isinstance(piece, Declaration): pieceresult = piece.key else: pieceresult = unicode(piece) result += ', ' + pieceresult return u'❲' + result[2:] + u'❳' class Grammar(object): "Read a complete grammar into memory." instance = None def __init__(self): "Read all declarations into variables." self.variables = dict() self.declarations = dict() self.constants = dict() def process(self): "Process the grammar and create all necessary structures." for key in JavaToPyConfig.declarations: self.variables[key] = JavaToPyConfig.declarations[key] for key in self.variables: self.declarations[key] = Declaration(key) for key in self.variables: Trace.debug('Interpreting ' + self.variables[key]) pos = TextPosition(self.variables[key]) self.declarations[key].parse(pos) def parse(self, tok): "Parse a whole file using a tokenizer." tok.next() filedecl = self.declarations['$file'] result = filedecl.match(tok) if not result: Trace.error('Actual file does not match $file.') return Grammar.instance = Grammar() elyxer-1.2.5/src/jtp/parser.py0000644000175000017500000002546212074107030015572 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20091226 # Port a Java program to a Python equivalent. Used to port MathToWeb. from elyxer.util.trace import Trace class StatementParser(object): "A parser for a statement." def __init__(self, chooser): self.chooser = chooser def checkvariable(self, token): "Check if the token is a valid variable name." for char in token: if not Tokenizer.isalphanumeric(char): return False return True def autoincrease(self, tok): "Process a Java autoincrease (++)." variable = tok.autoincreases.pop() return variable + ' += 1' def autodecrease(self, tok): "Process a Java autodecrease (--)." variable = tok.autodecreases.pop() return variable + ' -= 1' def translateclass(self, tok): "Translate a class definition." tok.checknext('class') name = tok.next() tok.inclass = name inheritance = '' while tok.peek() != '{': inheritance += ' ' + tok.next() Trace.error('Unused inheritance ' + inheritance) return 'class ' + name + '(object):' def translateinternal(self, tok): "Translate an internal element (attribute or method)." token = self.membertoken(tok) name = self.membertoken(tok) if token == tok.inclass and name == '(': # constructor return self.translatemethod(token, tok) after = tok.next() while after == '[': tok.checknext(']') after = tok.next() if after == ';': return self.translateemptyattribute(name) if after == '(': return self.translatemethod(name, tok) if after != '=': Trace.error('Weird token after member: ' + token + ' ' + name + ' ' + after) return self.translateattribute(name, tok) def membertoken(self, tok): "Get the next member token, excluding static, []..." token = tok.next() if token in ['static', 'synchronized', 'final']: return self.membertoken(tok) if token == '[': tok.checknext(']') return self.membertoken(tok) return token def translatemethod(self, name, tok): "Translate a class method." tok.inmethod = name pars = self.listparameters(tok) self.expectblock(tok) parlist = ', ' for par in pars: if not ' ' in par: Trace.error('Invalid parameter declaration: ' + par) else: newpar = par.strip().split(' ', 1)[1] parlist += newpar + ', ' parlist = parlist[:-2] return '\ndef ' + name + '(self' + parlist + '):' def translateemptyattribute(self, name): "Translate an empty attribute definition." return name + ' = None' def translateattribute(self, name, tok): "Translate a class attribute." return name + ' = ' + self.parseupto(';', tok) def listparameters(self, tok): "Parse the parameters of a method definition, return them as a list." params = self.parseinparens(tok)[1:-1] pars = params.split(',') if pars[0] == '': return [] return pars def processtoken(self, tok): "Process a single token." token = tok.current() if token in self.chooser.javatokens: function = getattr(self.chooser, self.chooser.javatokens[token]) return function(tok) if token in tok.javasymbols: return self.processsymbol(tok) return token def processsymbol(self, tok): "Process a single java symbol." if tok.current() == '"' or tok.current() == '\'': return self.parsequoted(tok.current(), tok) if tok.current() == '{': return '{' + self.parseupto('}', tok) + '}' if tok.current() == '}': Trace.error('Erroneously closing }') return '' if tok.current() == '(': result = self.parseinparens(tok) return result if tok.current() == '[': result = self.parseinsquare(tok) return result if tok.current() == ')': Trace.error('Erroneously closing )') return ')' if tok.current() in tok.modified: return tok.modified[tok.current()] return tok.current() def parsequoted(self, quote, tok): "Parse a quoted sentence, with variable quotes." result = tok.current() + tok.pos.globincluding(quote) while result.endswith('\\' + quote) and not result.endswith('\\\\' + quote): result += tok.pos.globincluding(quote) return result def parseparameters(self, tok): "Parse the parameters to a method invocation." result = '(' while tok.current() != ')': param = self.parsevalue(tok, [',',')']) result += param + ', ' if len(result) == 1: return '()' return result[:-2] + ')' def parseparens(self, tok): "Parse a couple of () and the contents inside." tok.checknext('(') return self.parseinparens(tok) def parseinparens(self, tok): "Parse the contents inside ()." contents = self.parseupto(')', tok) if '{' in contents: # anonymous function; ignore return '()' if Tokenizer.isalphanumeric(contents): if Tokenizer.isalphanumeric(tok.peek()): # type cast; ignore return '' result = '(' + contents + ')' return result result = self.parseinbrackets('(', ')', tok) def parseinsquare(self, tok): "Parse the contents inside []." return self.parseinbrackets('[', ']', tok) def parseinbrackets(self, opening, closing, tok): "Parse the contents in any kind of brackets." result = self.parseupto(closing, tok) return opening + result + closing def parsecondition(self, tok, ending): "Parse a condition given the ending token." return self.parseupto(ending, tok) def parsevalue(self, tok, endings = [';']): "Parse a value (to be assigned or returned)." return self.parsetoendings(tok, endings) def parseinvocation(self, tok, previous = None): "Parse a class or method invocation." result = previous or '' name = tok.current() tok.checknext('(') params = self.parseparameters(tok) result += name + params if tok.peek() != '.': return result tok.checknext('.') return self.parseinvocation(tok, result + '.') def parseupto(self, ending, tok): "Parse the tokenizer up to the supplied ending." return self.parsetoendings(tok, [ending]) def parsetoendings(self, tok, endings): "Parse the tokenizer up to a number of endings." result = '' tok.next() while not tok.current() in endings: processed = self.processtoken(tok) if processed == '++': processed = '+ 1' Trace.debug('Increasing ' + result + ' for endings: ' + unicode(endings)) tok.autoincreases.append(result) if processed == '--': Trace.debug('Decreasing ' + result) processed = '- 1' tok.autodecreases.append(result) if processed != '.' and not result.endswith('.'): processed = ' ' + processed result += processed if not tok.current in endings: tok.next() if len(result) > 0: result = result[1:] Trace.debug('Left after ' + tok.current() + ', endings ' + unicode(endings) + ', result: ' + result) return result def expectblock(self, tok): "Mark that a block is to be expected." tok.depth += 1 tok.waitingforblock = True class Tokenizer(object): "Tokenizes a parse position." unmodified = [ '&', '|', '=', '(', ')', '{', '}', '.', '+', '-', '"', ',', '/', '*', '<', '>', '\'', '[', ']', '%', ';', '!=','<=','>=', '==', '++', '--' ] modified = { '&&':'and', '||':'or', '!':'not' } comments = ['//', '/*'] javasymbols = comments + unmodified + modified.keys() def __init__(self, pos): self.pos = pos self.currenttoken = None self.peeked = None self.autoincreases = [] self.autodecreases = [] self.depth = 0 self.waitingforblock = False self.inclass = None self.inmethod = None self.variables = ['this'] self.infor = 0 def next(self): "Get the next single token, and store it for current()." if self.peeked: self.currenttoken = self.peeked self.peeked = None else: self.currenttoken = self.extractwithoutcomments() return self.currenttoken def checknext(self, token): "Check that the next token is the parameter." self.next() if self.currenttoken != token: Trace.error('Expected token ' + token + ', found ' + self.currenttoken) return False return True def extractwithoutcomments(self): "Get the next single token without comments." token = self.extracttoken() while token in self.comments: self.skipcomment(token) token = self.extracttoken() self.pos.skipspace() return token def extracttoken(self): "Extract the next token." if self.finished(): return None if self.pos.checkidentifier(): return self.pos.globidentifier() if self.pos.current() in self.javasymbols: result = self.pos.skipcurrent() while result + self.pos.current() in self.javasymbols: result += self.pos.skipcurrent() return result current = self.pos.skipcurrent() raise Exception('Unrecognized character: ' + current) def current(self): "Get the current token." return self.currenttoken def finished(self): "Find out if the tokenizer has finished tokenizing." self.pos.skipspace() return self.pos.finished() def iscurrentidentifier(self): "Return if the current token is an identifier (alphanumeric or _ characters)." if self.currenttoken.replace('_', '').isalnum(): return True return False def skipcomment(self, token): "Skip over a comment." if token == '//': comment = self.pos.globexcluding('\n') return if token == '/*': while not self.pos.checkskip('/'): comment = self.pos.globincluding('*') return Trace.error('Unknown comment type ' + token) def peek(self): "Look ahead at the next token, without advancing the parse position." token = self.extractwithoutcomments() self.peeked = token return token def mark(self): "Mark the current state and return a handle." Trace.error('Unimplemented mark()') return None def revert(self, state): "Revert to a previous state as returned by mark()." Trace.error('Unimplemented revert()') elyxer-1.2.5/src/jtp/__init__.py0000644000175000017500000000000012074107030016012 0ustar chennochennoelyxer-1.2.5/src/setup.py0000644000175000017500000000400112074107030014623 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20090908 # eLyXer distutils management from distutils.core import setup packages = [ 'elyxer', 'elyxer.bib', 'elyxer.conf', 'elyxer.gen', 'elyxer.io', 'elyxer.main', 'elyxer.maths', 'elyxer.out', 'elyxer.parse', 'elyxer.proc', 'elyxer.ref', 'elyxer.util', 'elyxer.xtra' ] packages = [] setup(name = 'eLyXer', version = 'unknown', description = 'LyX to HTML converter', long_description = 'eLyXer is a LyX to HTML converter, with a focus on flexibility and elegant output.', author = 'Alex Fernandez', author_email = 'elyxer@gmail.com', url = 'http://elyxer.nongnu.org/', packages = packages, scripts = ['elyxer.py', 'math2html.py', 'loremipsumize.py'], classifiers = [ 'License :: OSI Approved :: GNU General Public License (GPL)', 'Development Status :: 5 - Production/Stable', 'Environment :: Console', 'Operating System :: OS Independent', 'Programming Language :: Python :: 2.4', 'Topic :: Printing', 'Topic :: Text Processing :: Markup :: HTML', 'Topic :: Utilities', 'Topic :: Internet :: WWW/HTTP :: Dynamic Content' ], license = 'GPL version 3 or later', platforms = ['Windows NT/2000/XP', 'Mac OS X', 'GNU/Linux'], ) elyxer-1.2.5/src/elyxer/0000755000175000017500000000000012117175142014435 5ustar chennochennoelyxer-1.2.5/src/elyxer/parse/0000755000175000017500000000000012117175142015547 5ustar chennochennoelyxer-1.2.5/src/elyxer/parse/tableparse.py0000644000175000017500000000365312074107030020243 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20090503 # eLyXer table parsing from elyxer.parse.parser import * from elyxer.conf.config import * class TableParser(BoundedParser): "Parse the whole table" headers = ContainerConfig.table['headers'] def __init__(self): BoundedParser.__init__(self) self.columns = list() def parseheader(self, reader): "Parse table headers" reader.nextline() while self.startswithheader(reader): self.parseparameter(reader) return [] def startswithheader(self, reader): "Check if the current line starts with a header line" for start in TableParser.headers: if reader.currentline().strip().startswith(start): return True return False class TablePartParser(BoundedParser): "Parse a table part (row or cell)" def parseheader(self, reader): "Parse the header" tablekey, parameters = self.parsexml(reader) self.parameters = parameters return list() class ColumnParser(LoneCommand): "Parse column properties" def parseheader(self, reader): "Parse the column definition" key, parameters = self.parsexml(reader) self.parameters = parameters return [] elyxer-1.2.5/src/elyxer/parse/formulaparse.py0000644000175000017500000001246012074107030020615 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20090503 # eLyXer formula parsing from elyxer.util.trace import Trace from elyxer.conf.config import * from elyxer.parse.parser import * from elyxer.parse.position import * class FormulaParser(Parser): "Parses a formula" def parseheader(self, reader): "See if the formula is inlined" self.begin = reader.linenumber + 1 type = self.parsetype(reader) if not type: reader.nextline() type = self.parsetype(reader) if not type: Trace.error('Unknown formula type in ' + reader.currentline().strip()) return ['unknown'] return [type] def parsetype(self, reader): "Get the formula type from the first line." if reader.currentline().find(FormulaConfig.starts['simple']) >= 0: return 'inline' if reader.currentline().find(FormulaConfig.starts['complex']) >= 0: return 'block' if reader.currentline().find(FormulaConfig.starts['unnumbered']) >= 0: return 'block' if reader.currentline().find(FormulaConfig.starts['beginbefore']) >= 0: return 'numbered' return None def parse(self, reader): "Parse the formula until the end" formula = self.parseformula(reader) while not reader.currentline().startswith(self.ending): stripped = reader.currentline().strip() if len(stripped) > 0: Trace.error('Unparsed formula line ' + stripped) reader.nextline() reader.nextline() return formula def parseformula(self, reader): "Parse the formula contents" simple = FormulaConfig.starts['simple'] if simple in reader.currentline(): rest = reader.currentline().split(simple, 1)[1] if simple in rest: # formula is $...$ return self.parsesingleliner(reader, simple, simple) # formula is multiline $...$ return self.parsemultiliner(reader, simple, simple) if FormulaConfig.starts['complex'] in reader.currentline(): # formula of the form \[...\] return self.parsemultiliner(reader, FormulaConfig.starts['complex'], FormulaConfig.endings['complex']) beginbefore = FormulaConfig.starts['beginbefore'] beginafter = FormulaConfig.starts['beginafter'] if beginbefore in reader.currentline(): if reader.currentline().strip().endswith(beginafter): current = reader.currentline().strip() endsplit = current.split(beginbefore)[1].split(beginafter) startpiece = beginbefore + endsplit[0] + beginafter endbefore = FormulaConfig.endings['endbefore'] endafter = FormulaConfig.endings['endafter'] endpiece = endbefore + endsplit[0] + endafter return startpiece + self.parsemultiliner(reader, startpiece, endpiece) + endpiece Trace.error('Missing ' + beginafter + ' in ' + reader.currentline()) return '' begincommand = FormulaConfig.starts['command'] beginbracket = FormulaConfig.starts['bracket'] if begincommand in reader.currentline() and beginbracket in reader.currentline(): endbracket = FormulaConfig.endings['bracket'] return self.parsemultiliner(reader, beginbracket, endbracket) Trace.error('Formula beginning ' + reader.currentline() + ' is unknown') return '' def parsesingleliner(self, reader, start, ending): "Parse a formula in one line" line = reader.currentline().strip() if not start in line: Trace.error('Line ' + line + ' does not contain formula start ' + start) return '' if not line.endswith(ending): Trace.error('Formula ' + line + ' does not end with ' + ending) return '' index = line.index(start) rest = line[index + len(start):-len(ending)] reader.nextline() return rest def parsemultiliner(self, reader, start, ending): "Parse a formula in multiple lines" formula = '' line = reader.currentline() if not start in line: Trace.error('Line ' + line.strip() + ' does not contain formula start ' + start) return '' index = line.index(start) line = line[index + len(start):].strip() while not line.endswith(ending): formula += line + '\n' reader.nextline() line = reader.currentline() formula += line[:-len(ending)] reader.nextline() return formula class MacroParser(FormulaParser): "A parser for a formula macro." def parseheader(self, reader): "See if the formula is inlined" self.begin = reader.linenumber + 1 return ['inline'] def parse(self, reader): "Parse the formula until the end" formula = self.parsemultiliner(reader, self.parent.start, self.ending) reader.nextline() return formula elyxer-1.2.5/src/elyxer/parse/headerparse.py0000644000175000017500000001022312074107030020373 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20100509 # eLyXer: LyX header parsing. from elyxer.util.trace import Trace from elyxer.util.options import * from elyxer.conf.config import * from elyxer.parse.parser import * class HeaderParser(Parser): "Parses the LyX header" def parse(self, reader): "Parse header parameters into a dictionary, return the preamble." contents = [] self.parseending(reader, lambda: self.parseline(reader, contents)) # skip last line reader.nextline() return contents def parseline(self, reader, contents): "Parse a single line as a parameter or as a start" line = reader.currentline() if line.startswith(HeaderConfig.parameters['branch']): self.parsebranch(reader) return elif line.startswith(HeaderConfig.parameters['lstset']): LstParser().parselstset(reader) return elif line.startswith(HeaderConfig.parameters['beginpreamble']): contents.append(self.factory.createcontainer(reader)) return # no match self.parseparameter(reader) def parsebranch(self, reader): "Parse all branch definitions." branch = reader.currentline().split()[1] reader.nextline() subparser = HeaderParser().complete(HeaderConfig.parameters['endbranch']) subparser.parse(reader) options = BranchOptions(branch) for key in subparser.parameters: options.set(key, subparser.parameters[key]) Options.branches[branch] = options def complete(self, ending): "Complete the parser with the given ending." self.ending = ending return self class PreambleParser(Parser): "A parser for the LyX preamble." preamble = [] def parse(self, reader): "Parse the full preamble with all statements." self.ending = HeaderConfig.parameters['endpreamble'] self.parseending(reader, lambda: self.parsepreambleline(reader)) return [] def parsepreambleline(self, reader): "Parse a single preamble line." PreambleParser.preamble.append(reader.currentline()) reader.nextline() class LstParser(object): "Parse global and local lstparams." globalparams = dict() def parselstset(self, reader): "Parse a declaration of lstparams in lstset." paramtext = self.extractlstset(reader) if not '{' in paramtext: Trace.error('Missing opening bracket in lstset: ' + paramtext) return lefttext = paramtext.split('{')[1] croppedtext = lefttext[:-1] LstParser.globalparams = self.parselstparams(croppedtext) def extractlstset(self, reader): "Extract the global lstset parameters." paramtext = '' while not reader.finished(): paramtext += reader.currentline() reader.nextline() if paramtext.endswith('}'): return paramtext Trace.error('Could not find end of \\lstset settings; aborting') def parsecontainer(self, container): "Parse some lstparams from elyxer.a container." container.lstparams = LstParser.globalparams.copy() paramlist = container.getparameterlist('lstparams') container.lstparams.update(self.parselstparams(paramlist)) def parselstparams(self, paramlist): "Process a number of lstparams from elyxer.a list." paramdict = dict() for param in paramlist: if not '=' in param: if len(param.strip()) > 0: Trace.error('Invalid listing parameter ' + param) else: key, value = param.split('=', 1) paramdict[key] = value return paramdict elyxer-1.2.5/src/elyxer/parse/position.py0000644000175000017500000001303512074107030017760 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20090503 # eLyXer formula parsing from elyxer.io.fileline import * from elyxer.util.trace import Trace from elyxer.conf.config import * from elyxer.parse.glob import * class Position(Globable): """A position in a text to parse. Including those in Globable, functions to implement by subclasses are: skip(), identifier(), extract(), isout() and current().""" def __init__(self): Globable.__init__(self) def skip(self, string): "Skip a string" Trace.error('Unimplemented skip()') def identifier(self): "Return an identifier for the current position." Trace.error('Unimplemented identifier()') return 'Error' def extract(self, length): "Extract the next string of the given length, or None if not enough text," "without advancing the parse position." Trace.error('Unimplemented extract()') return None def checkfor(self, string): "Check for a string at the given position." return string == self.extract(len(string)) def checkforlower(self, string): "Check for a string in lower case." extracted = self.extract(len(string)) if not extracted: return False return string.lower() == self.extract(len(string)).lower() def skipcurrent(self): "Return the current character and skip it." current = self.current() self.skip(current) return current def next(self): "Advance the position and return the next character." self.skipcurrent() return self.current() def checkskip(self, string): "Check for a string at the given position; if there, skip it" if not self.checkfor(string): return False self.skip(string) return True def error(self, message): "Show an error message and the position identifier." Trace.error(message + ': ' + self.identifier()) class TextPosition(Position): "A parse position based on a raw text." def __init__(self, text): "Create the position from elyxer.some text." Position.__init__(self) self.pos = 0 self.text = text self.checkbytemark() def skip(self, string): "Skip a string of characters." self.pos += len(string) def identifier(self): "Return a sample of the remaining text." length = 30 if self.pos + length > len(self.text): length = len(self.text) - self.pos return '*' + self.text[self.pos:self.pos + length] + '*' def isout(self): "Find out if we are out of the text yet." return self.pos >= len(self.text) def current(self): "Return the current character, assuming we are not out." return self.text[self.pos] def extract(self, length): "Extract the next string of the given length, or None if not enough text." if self.pos + length > len(self.text): return None return self.text[self.pos : self.pos + length] class FilePosition(Position): "A parse position based on an underlying file." def __init__(self, filename): "Create the position from a file." Position.__init__(self) self.reader = LineReader(filename) self.pos = 0 self.checkbytemark() def skip(self, string): "Skip a string of characters." length = len(string) while self.pos + length > len(self.reader.currentline()): length -= len(self.reader.currentline()) - self.pos + 1 self.nextline() self.pos += length def currentline(self): "Get the current line of the underlying file." return self.reader.currentline() def nextline(self): "Go to the next line." self.reader.nextline() self.pos = 0 def linenumber(self): "Return the line number of the file." return self.reader.linenumber + 1 def identifier(self): "Return the current line and line number in the file." before = self.reader.currentline()[:self.pos - 1] after = self.reader.currentline()[self.pos:] return 'line ' + unicode(self.getlinenumber()) + ': ' + before + '*' + after def isout(self): "Find out if we are out of the text yet." if self.pos > len(self.reader.currentline()): if self.pos > len(self.reader.currentline()) + 1: Trace.error('Out of the line ' + self.reader.currentline() + ': ' + unicode(self.pos)) self.nextline() return self.reader.finished() def current(self): "Return the current character, assuming we are not out." if self.pos == len(self.reader.currentline()): return '\n' if self.pos > len(self.reader.currentline()): Trace.error('Out of the line ' + self.reader.currentline() + ': ' + unicode(self.pos)) return '*' return self.reader.currentline()[self.pos] def extract(self, length): "Extract the next string of the given length, or None if not enough text." if self.pos + length > len(self.reader.currentline()): return None return self.reader.currentline()[self.pos : self.pos + length] elyxer-1.2.5/src/elyxer/parse/parser.py0000644000175000017500000001320612074107030017410 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20090203 # eLyXer parsers from elyxer.util.trace import Trace from elyxer.util.options import * from elyxer.conf.config import * class Parser(object): "A generic parser" def __init__(self): self.begin = 0 self.parameters = dict() def parseheader(self, reader): "Parse the header" header = reader.currentline().split() reader.nextline() self.begin = reader.linenumber return header def parseparameter(self, reader): "Parse a parameter" if reader.currentline().strip().startswith('<'): key, value = self.parsexml(reader) self.parameters[key] = value return split = reader.currentline().strip().split(' ', 1) reader.nextline() if len(split) == 0: return key = split[0] if len(split) == 1: self.parameters[key] = True return if not '"' in split[1]: self.parameters[key] = split[1].strip() return doublesplit = split[1].split('"') self.parameters[key] = doublesplit[1] def parsexml(self, reader): "Parse a parameter in xml form: " strip = reader.currentline().strip() reader.nextline() if not strip.endswith('>'): Trace.error('XML parameter ' + strip + ' should be <...>') split = strip[1:-1].split() if len(split) == 0: Trace.error('Empty XML parameter <>') return None, None key = split[0] del split[0] if len(split) == 0: return key, dict() attrs = dict() for attr in split: if not '=' in attr: Trace.error('Erroneous attribute for ' + key + ': ' + attr) attr += '="0"' parts = attr.split('=') attrkey = parts[0] value = parts[1].split('"')[1] attrs[attrkey] = value return key, attrs def parseending(self, reader, process): "Parse until the current ending is found" if not self.ending: Trace.error('No ending for ' + unicode(self)) return while not reader.currentline().startswith(self.ending): process() def parsecontainer(self, reader, contents): container = self.factory.createcontainer(reader) if container: container.parent = self.parent contents.append(container) def __unicode__(self): "Return a description" return self.__class__.__name__ + ' (' + unicode(self.begin) + ')' class LoneCommand(Parser): "A parser for just one command line" def parse(self,reader): "Read nothing" return [] class TextParser(Parser): "A parser for a command and a bit of text" stack = [] def __init__(self, container): Parser.__init__(self) self.ending = None if container.__class__.__name__ in ContainerConfig.endings: self.ending = ContainerConfig.endings[container.__class__.__name__] self.endings = [] def parse(self, reader): "Parse lines as long as they are text" TextParser.stack.append(self.ending) self.endings = TextParser.stack + [ContainerConfig.endings['Layout'], ContainerConfig.endings['Inset'], self.ending] contents = [] while not self.isending(reader): self.parsecontainer(reader, contents) return contents def isending(self, reader): "Check if text is ending" current = reader.currentline().split() if len(current) == 0: return False if current[0] in self.endings: if current[0] in TextParser.stack: TextParser.stack.remove(current[0]) else: TextParser.stack = [] return True return False class ExcludingParser(Parser): "A parser that excludes the final line" def parse(self, reader): "Parse everything up to (and excluding) the final line" contents = [] self.parseending(reader, lambda: self.parsecontainer(reader, contents)) return contents class BoundedParser(ExcludingParser): "A parser bound by a final line" def parse(self, reader): "Parse everything, including the final line" contents = ExcludingParser.parse(self, reader) # skip last line reader.nextline() return contents class BoundedDummy(Parser): "A bound parser that ignores everything" def parse(self, reader): "Parse the contents of the container" self.parseending(reader, lambda: reader.nextline()) # skip last line reader.nextline() return [] class StringParser(Parser): "Parses just a string" def parseheader(self, reader): "Do nothing, just take note" self.begin = reader.linenumber + 1 return [] def parse(self, reader): "Parse a single line" contents = reader.currentline() reader.nextline() return contents class InsetParser(BoundedParser): "Parses a LyX inset" def parse(self, reader): "Parse inset parameters into a dictionary" startcommand = ContainerConfig.string['startcommand'] while reader.currentline() != '' and not reader.currentline().startswith(startcommand): self.parseparameter(reader) return BoundedParser.parse(self, reader) elyxer-1.2.5/src/elyxer/parse/glob.py0000644000175000017500000001451612074107030017044 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20110111 # eLyXer globbing of an underlying string. from elyxer.util.trace import Trace class Globable(object): """A bit of text which can be globbed (lumped together in bits). Methods current(), skipcurrent(), checkfor() and isout() have to be implemented by subclasses.""" leavepending = False def __init__(self): self.endinglist = EndingList() def checkbytemark(self): "Check for a Unicode byte mark and skip it." if self.finished(): return if ord(self.current()) == 0xfeff: self.skipcurrent() def isout(self): "Find out if we are out of the position yet." Trace.error('Unimplemented isout()') return True def current(self): "Return the current character." Trace.error('Unimplemented current()') return '' def checkfor(self, string): "Check for the given string in the current position." Trace.error('Unimplemented checkfor()') return False def finished(self): "Find out if the current text has finished." if self.isout(): if not self.leavepending: self.endinglist.checkpending() return True return self.endinglist.checkin(self) def skipcurrent(self): "Return the current character and skip it." Trace.error('Unimplemented skipcurrent()') return '' def glob(self, currentcheck): "Glob a bit of text that satisfies a check on the current char." glob = '' while not self.finished() and currentcheck(): glob += self.skipcurrent() return glob def globalpha(self): "Glob a bit of alpha text" return self.glob(lambda: self.current().isalpha()) def globnumber(self): "Glob a row of digits." return self.glob(lambda: self.current().isdigit()) def isidentifier(self): "Return if the current character is alphanumeric or _." if self.current().isalnum() or self.current() == '_': return True return False def globidentifier(self): "Glob alphanumeric and _ symbols." return self.glob(self.isidentifier) def isvalue(self): "Return if the current character is a value character:" "not a bracket or a space." if self.current().isspace(): return False if self.current() in '{}()': return False return True def globvalue(self): "Glob a value: any symbols but brackets." return self.glob(self.isvalue) def skipspace(self): "Skip all whitespace at current position." return self.glob(lambda: self.current().isspace()) def globincluding(self, magicchar): "Glob a bit of text up to (including) the magic char." glob = self.glob(lambda: self.current() != magicchar) + magicchar self.skip(magicchar) return glob def globexcluding(self, excluded): "Glob a bit of text up until (excluding) any excluded character." return self.glob(lambda: self.current() not in excluded) def pushending(self, ending, optional = False): "Push a new ending to the bottom" self.endinglist.add(ending, optional) def popending(self, expected = None): "Pop the ending found at the current position" if self.isout() and self.leavepending: return expected ending = self.endinglist.pop(self) if expected and expected != ending: Trace.error('Expected ending ' + expected + ', got ' + ending) self.skip(ending) return ending def nextending(self): "Return the next ending in the queue." nextending = self.endinglist.findending(self) if not nextending: return None return nextending.ending class EndingList(object): "A list of position endings" def __init__(self): self.endings = [] def add(self, ending, optional = False): "Add a new ending to the list" self.endings.append(PositionEnding(ending, optional)) def pickpending(self, pos): "Pick any pending endings from a parse position." self.endings += pos.endinglist.endings def checkin(self, pos): "Search for an ending" if self.findending(pos): return True return False def pop(self, pos): "Remove the ending at the current position" if pos.isout(): Trace.error('No ending out of bounds') return '' ending = self.findending(pos) if not ending: Trace.error('No ending at ' + pos.current()) return '' for each in reversed(self.endings): self.endings.remove(each) if each == ending: return each.ending elif not each.optional: Trace.error('Removed non-optional ending ' + each) Trace.error('No endings left') return '' def findending(self, pos): "Find the ending at the current position" if len(self.endings) == 0: return None for index, ending in enumerate(reversed(self.endings)): if ending.checkin(pos): return ending if not ending.optional: return None return None def checkpending(self): "Check if there are any pending endings" if len(self.endings) != 0: Trace.error('Pending ' + unicode(self) + ' left open') def __unicode__(self): "Printable representation" string = 'endings [' for ending in self.endings: string += unicode(ending) + ',' if len(self.endings) > 0: string = string[:-1] return string + ']' class PositionEnding(object): "An ending for a parsing position" def __init__(self, ending, optional): self.ending = ending self.optional = optional def checkin(self, pos): "Check for the ending" return pos.checkfor(self.ending) def __unicode__(self): "Printable representation" string = 'Ending ' + self.ending if self.optional: string += ' (optional)' return string elyxer-1.2.5/src/elyxer/parse/__init__.py0000644000175000017500000000000012074107030017637 0ustar chennochennoelyxer-1.2.5/src/elyxer/ref/0000755000175000017500000000000012117175142015211 5ustar chennochennoelyxer-1.2.5/src/elyxer/ref/partkey.py0000644000175000017500000001506412074107030017241 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20100705 # eLyXer: key that identifies a given document part (chapter, section...). from elyxer.util.trace import Trace from elyxer.util.options import * from elyxer.util.translate import * from elyxer.util.numbering import * from elyxer.util.docparams import * from elyxer.ref.label import * from elyxer.gen.inset import * from elyxer.out.template import * class PartKey(object): "A key to identify a given document part (chapter, section...)." partkey = None tocentry = None anchortext = None number = None filename = None titlecontents = None header = False def __init__(self): self.level = 0 def createindex(self, partkey): "Create a part key for an index page." self.partkey = partkey self.tocentry = partkey self.filename = partkey return self def createfloat(self, float): "Create a part key for a float." self.number = NumberGenerator.chaptered.generate(float.type) self.partkey = Translator.translate('float-' + float.type) + self.number if Options.notoclabels: self.tocentry = self.number else: self.tocentry = self.partkey self.readtitle(float) return self def createsubfloat(self, number): "Create the part key for a subfloat." self.partkey = '(' + number + ')' self.number = number return self def createformula(self, number): "Create the part key for a formula." self.number = number self.partkey = 'formula-' + number self.tocentry = '(' + number + ')' return self def createheader(self, headorfooter): "Create the part key for a header or footer." self.partkey = headorfooter self.tocentry = None self.header = True return self def createanchor(self, partkey): "Create an anchor for the page." self.partkey = partkey self.tocentry = partkey self.header = True return self def createmain(self): "Create the part key for the main page." self.partkey = '' self.tocentry = DocumentTitle().getvalue() return self def addtoclabel(self, container): "Create the label for the TOC, and add it to the container." labeltext = '' if self.anchortext: labeltext = self.anchortext container.contents.insert(0, Separator(u' ')) label = Label().create(labeltext, self.partkey, type='toc') container.contents.insert(0, label) def readtitle(self, container): "Read the title of the TOC entry." shorttitles = container.searchall(ShortTitle) if len(shorttitles) > 0: self.titlecontents = [] for shorttitle in shorttitles: self.titlecontents += shorttitle.contents return extractor = ContainerExtractor(TOCConfig.extracttitle) captions = container.searchall(Caption) if len(captions) == 1: self.titlecontents = extractor.extract(captions[0]) return self.titlecontents = extractor.extract(container) def __unicode__(self): "Return a printable representation." return 'Part key for ' + self.partkey class LayoutPartKey(PartKey): "The part key for a layout." generator = NumberGenerator() def create(self, layout): "Set the layout for which we are creating the part key." self.processtype(layout.type) self.readtitle(layout) return self def processtype(self, type): "Process the layout type." self.level = self.generator.getlevel(type) self.number = self.generator.generate(type) anchortype = self.getanchortype(type) self.partkey = 'toc-' + anchortype + '-' + self.number self.tocentry = self.gettocentry(type) self.filename = self.getfilename(type) if self.generator.isnumbered(type): if not self.tocentry: self.tocentry = '' else: self.tocentry += ' ' self.tocentry += self.number self.anchortext = self.getanchortext(type) def getanchortype(self, type): "Get the type for the anchor." parttype = self.generator.getparttype(type) if self.generator.isunordered(type): parttype += '-' return parttype def gettocentry(self, type): "Get the entry for the TOC: Chapter, Section..." if Options.notoclabels: return '' return Translator.translate(self.generator.getparttype(type)) def addtotocentry(self, text): "Add some text to the tocentry; create if None." if not self.tocentry: self.tocentry = '' self.tocentry += text def getanchortext(self, type): "Get the text for the anchor given to a layout type." if self.generator.isunique(type): return self.tocentry + '.' return self.number def getfilename(self, type): "Get the filename to be used if splitpart is active." if self.level == Options.splitpart and self.generator.isnumbered(type): return self.number if self.level <= Options.splitpart: return self.partkey.replace('toc-', '') return None def needspartkey(self, layout): "Find out if a layout needs a part key." if self.generator.isunique(layout.type): return True return self.generator.isinordered(layout.type) def __unicode__(self): "Get a printable representation." return 'Part key for layout ' + self.tocentry class PartKeyGenerator(object): "Number a layout with the relevant attributes." partkeyed = [] layoutpartkey = LayoutPartKey() def forlayout(cls, layout): "Get the part key for a layout." if layout.hasemptyoutput(): return None if not cls.layoutpartkey.needspartkey(layout): return None Label.lastlayout = layout cls.partkeyed.append(layout) return LayoutPartKey().create(layout) def forindex(cls, index): "Get the part key for an index or nomenclature." if index.hasemptyoutput(): return None cls.partkeyed.append(index) return PartKey().createindex(index.name) forlayout = classmethod(forlayout) forindex = classmethod(forindex) elyxer-1.2.5/src/elyxer/ref/link.py0000644000175000017500000000705412074107030016517 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20090218 # eLyXer links from elyxer.util.trace import Trace from elyxer.util.translate import * from elyxer.parse.parser import * from elyxer.out.output import * from elyxer.gen.container import * from elyxer.gen.styles import * class Link(Container): "A link to another part of the document" anchor = None url = None type = None page = None target = None destination = None title = None def __init__(self): "Initialize the link, add target if configured." self.contents = [] self.parser = InsetParser() self.output = LinkOutput() if Options.target: self.target = Options.target def complete(self, text, anchor = None, url = None, type = None, title = None): "Complete the link." self.contents = [Constant(text)] if anchor: self.anchor = anchor if url: self.url = url if type: self.type = type if title: self.title = title return self def computedestination(self): "Use the destination link to fill in the destination URL." if not self.destination: return self.url = '' if self.destination.anchor: self.url = '#' + self.destination.anchor if self.destination.page: self.url = self.destination.page + self.url def setmutualdestination(self, destination): "Set another link as destination, and set its destination to this one." self.destination = destination destination.destination = self def __unicode__(self): "Return a printable representation." result = 'Link' if self.anchor: result += ' #' + self.anchor if self.url: result += ' to ' + self.url return result class URL(Link): "A clickable URL" def process(self): "Read URL from elyxer.parameters" target = self.escape(self.getparameter('target')) self.url = target type = self.getparameter('type') if type: self.url = self.escape(type) + target name = self.getparameter('name') if not name: name = target self.contents = [Constant(name)] class FlexURL(URL): "A flexible URL" def process(self): "Read URL from elyxer.contents" self.url = self.extracttext() class LinkOutput(ContainerOutput): "A link pointing to some destination" "Or an anchor (destination)" def gethtml(self, link): "Get the HTML code for the link" type = link.__class__.__name__ if link.type: type = link.type tag = 'a class="' + type + '"' if link.anchor: tag += ' name="' + link.anchor + '"' if link.destination: link.computedestination() if link.url: tag += ' href="' + link.url + '"' if link.target: tag += ' target="' + link.target + '"' if link.title: tag += ' title="' + link.title + '"' return TaggedOutput().settag(tag).gethtml(link) elyxer-1.2.5/src/elyxer/ref/label.py0000644000175000017500000001051012074107030016630 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20090218 # eLyXer labels from elyxer.util.trace import Trace from elyxer.parse.parser import * from elyxer.out.output import * from elyxer.gen.container import * from elyxer.gen.styles import * from elyxer.ref.link import * from elyxer.proc.postprocess import * class Label(Link): "A label to be referenced" names = dict() lastlayout = None def __init__(self): Link.__init__(self) self.lastnumbered = None def process(self): "Process a label container." key = self.getparameter('name') self.create(' ', key) self.lastnumbered = Label.lastlayout def create(self, text, key, type = 'Label'): "Create the label for a given key." self.key = key self.complete(text, anchor = key, type = type) Label.names[key] = self if key in Reference.references: for reference in Reference.references[key]: reference.destination = self return self def findpartkey(self): "Get the part key for the latest numbered container seen." numbered = self.numbered(self) if numbered and numbered.partkey: return numbered.partkey return '' def numbered(self, container): "Get the numbered container for the label." if container.partkey: return container if not container.parent: if self.lastnumbered: return self.lastnumbered return None return self.numbered(container.parent) def __unicode__(self): "Return a printable representation." if not hasattr(self, 'key'): return 'Unnamed label' return 'Label ' + self.key class Reference(Link): "A reference to a label." references = dict() key = 'none' def process(self): "Read the reference and set the arrow." self.key = self.getparameter('reference') if self.key in Label.names: self.direction = u'↑' label = Label.names[self.key] else: self.direction = u'↓' label = Label().complete(' ', self.key, 'preref') self.destination = label self.formatcontents() if not self.key in Reference.references: Reference.references[self.key] = [] Reference.references[self.key].append(self) def formatcontents(self): "Format the reference contents." formatkey = self.getparameter('LatexCommand') if not formatkey: formatkey = 'ref' self.formatted = u'↕' if formatkey in StyleConfig.referenceformats: self.formatted = StyleConfig.referenceformats[formatkey] else: Trace.error('Unknown reference format ' + formatkey) self.replace(u'↕', self.direction) self.replace('#', '1') self.replace('on-page', Translator.translate('on-page')) partkey = self.destination.findpartkey() # only if partkey and partkey.number are not null, send partkey.number self.replace('@', partkey and partkey.number) self.replace(u'¶', partkey and partkey.tocentry) if not '$' in self.formatted or not partkey or not partkey.titlecontents: # there is a $ left, but it should go away on preprocessing self.contents = [Constant(self.formatted)] return pieces = self.formatted.split('$') self.contents = [Constant(pieces[0])] for piece in pieces[1:]: self.contents += partkey.titlecontents self.contents.append(Constant(piece)) def replace(self, key, value): "Replace a key in the format template with a value." if not key in self.formatted: return if not value: value = '' self.formatted = self.formatted.replace(key, value) def __unicode__(self): "Return a printable representation." return 'Reference ' + self.key elyxer-1.2.5/src/elyxer/ref/index.py0000644000175000017500000002016612074107030016670 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20100713 # eLyXer: indexing entries from elyxer.util.trace import Trace from elyxer.util.translate import * from elyxer.parse.parser import * from elyxer.out.output import * from elyxer.gen.container import * from elyxer.gen.styles import * from elyxer.ref.link import * from elyxer.ref.partkey import * from elyxer.proc.process import * class ListInset(Container): "An inset with a list, normally made of links." def __init__(self): self.parser = InsetParser() self.output = ContentsOutput() def sortdictionary(self, dictionary): "Sort all entries in the dictionary" keys = dictionary.keys() # sort by name keys.sort() return keys sortdictionary = classmethod(sortdictionary) class ListOf(ListInset): "A list of entities (figures, tables, algorithms)" def process(self): "Parse the header and get the type" self.type = self.header[2] text = Translator.translate('list-' + self.type) self.contents = [TaggedText().constant(text, 'div class="tocheader"', True)] class TableOfContents(ListInset): "Table of contents" def process(self): "Parse the header and get the type" self.create(Translator.translate('toc')) def create(self, heading): "Create a table of contents with the given heading text." self.output = TaggedOutput().settag('div class="fulltoc"', True) self.contents = [TaggedText().constant(heading, 'div class="tocheader"', True)] return self def add(self, entry): "Add a new entry to the TOC." if entry: self.contents.append(entry) class IndexReference(Link): "A reference to an entry in the alphabetical index." name = 'none' def process(self): "Put entry in index" name = self.getparameter('name') if name: self.name = name.strip() else: self.name = self.extracttext() IndexEntry.get(self.name).addref(self) def __unicode__(self): "Return a printable representation." return 'Reference to ' + self.name class IndexHeader(Link): "The header line for an index entry. Keeps all arrows." keyescapes = {'!':'', '|':'-', ' ':'-', '--':'-', ',':'', '\\':'', '@':'_', u'°':''} def create(self, names): "Create the header for the given index entry." self.output = TaggedOutput().settag('p class="printindex"', True) self.name = names[-1] keys = [self.escape(part, self.keyescapes) for part in names] self.key = '-'.join(keys) self.anchor = Link().complete('', 'index-' + self.key, None, 'printindex') self.contents = [self.anchor, Constant(self.name + ': ')] self.arrows = [] return self def addref(self, reference): "Create an arrow pointing to a reference." reference.index = unicode(len(self.arrows)) reference.destination = self.anchor reference.complete(u'↓', 'entry-' + self.key + '-' + reference.index) arrow = Link().complete(u'↑', type = 'IndexArrow') arrow.destination = reference if len(self.arrows) > 0: self.contents.append(Constant(u', ')) self.arrows.append(arrow) self.contents.append(arrow) def __unicode__(self): "Return a printable representation." return 'Index header for ' + self.name class IndexGroup(Container): "A group of entries in the alphabetical index, for an entry." root = None def create(self): "Create an index group." self.entries = dict() self.output = EmptyOutput() return self def findentry(self, names): "Find the entry with the given names." if self == IndexGroup.root: self.output = ContentsOutput() else: self.output = TaggedOutput().settag('div class="indexgroup"', True) lastname = names[-1] if not lastname in self.entries: self.entries[lastname] = IndexEntry().create(names) return self.entries[lastname] def sort(self): "Sort all entries in the group." for key in ListInset.sortdictionary(self.entries): entry = self.entries[key] entry.group.sort() self.contents.append(entry) def __unicode__(self): "Return a printable representation." return 'Index group' IndexGroup.root = IndexGroup().create() class IndexEntry(Container): "An entry in the alphabetical index." "When an index entry is of the form 'part1 ! part2 ...', " "a hierarchical structure in the form of an IndexGroup is constructed." "An index entry contains a mandatory header, and an optional group." def create(self, names): "Create an index entry with the given name." self.output = ContentsOutput() self.header = IndexHeader().create(names) self.group = IndexGroup().create() self.contents = [self.header, self.group] return self def addref(self, reference): "Add a reference to the entry." self.header.addref(reference) def get(cls, name): "Get the index entry for the given name." group = IndexGroup.root parts = IndexEntry.splitname(name) readparts = [] for part in parts: readparts.append(part) entry = group.findentry(readparts) group = entry.group return entry def splitname(cls, name): "Split a name in parts divided by !." return [part.strip() for part in name.split('!')] def __unicode__(self): "Return a printable representation." return 'Index entry for ' + self.header.name get = classmethod(get) splitname = classmethod(splitname) class PrintIndex(ListInset): "Command to print an index" def process(self): "Create the alphabetic index" self.name = Translator.translate('index') self.partkey = PartKeyGenerator.forindex(self) if not self.partkey: return self.contents = [TaggedText().constant(self.name, 'h1 class="index"')] self.partkey.addtoclabel(self) IndexGroup.root.sort() self.contents.append(IndexGroup.root) class NomenclatureEntry(Link): "An entry of LyX nomenclature" entries = dict() def process(self): "Put entry in index" symbol = self.getparameter('symbol') description = self.getparameter('description') key = symbol.replace(' ', '-').lower() if key in NomenclatureEntry.entries: Trace.error('Duplicated nomenclature entry ' + key) self.complete(u'↓', 'noment-' + key) entry = Link().complete(u'↑', 'nom-' + key) entry.symbol = symbol entry.description = description self.setmutualdestination(entry) NomenclatureEntry.entries[key] = entry class PrintNomenclature(ListInset): "Print all nomenclature entries" def process(self): "Create the nomenclature." self.name = Translator.translate('nomenclature') self.partkey = PartKeyGenerator.forindex(self) if not self.partkey: return self.contents = [TaggedText().constant(self.name, 'h1 class="nomenclature"')] self.partkey.addtoclabel(self) for key in self.sortdictionary(NomenclatureEntry.entries): entry = NomenclatureEntry.entries[key] contents = [entry, Constant(entry.symbol + u' ' + entry.description)] text = TaggedText().complete(contents, 'div class="Nomenclated"', True) self.contents.append(text) class PreListInset(object): "Preprocess any container that contains a list inset." def preprocess(self, container): "Preprocess a container, extract any list inset and return it." listinsets = container.searchall(ListInset) if len(listinsets) == 0: return container if len(container.contents) > 1: return container return listinsets[0] Processor.prestages += [PreListInset()] elyxer-1.2.5/src/elyxer/ref/__init__.py0000644000175000017500000000000012074107030017301 0ustar chennochennoelyxer-1.2.5/src/elyxer/tex/0000755000175000017500000000000012117175142015235 5ustar chennochennoelyxer-1.2.5/src/elyxer/tex/texcode.py0000644000175000017500000001303712074107030017237 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20110105 # eLyXer TeX (LyX ERT) parser. from elyxer.util.trace import Trace from elyxer.util.clone import * from elyxer.conf.config import * from elyxer.parse.position import * from elyxer.gen.layout import * from elyxer.maths.formula import * from elyxer.maths.command import * class ERT(FirstWord): "Evil Red Text: embedded TeX code." "Considered as a first word for descriptions." def __init__(self): self.parser = InsetParser() self.output = ContentsOutput() def process(self): "Process all TeX code, formulas, commands." text = '' separator = '' for container in self.contents: text += separator + container.extracttext() separator = '\n' pos = TextPosition(text) pos.leavepending = True code = TeXCode() code.parse(pos) self.contents = [code] def isempty(self): "Find out if the ERT is empty or not." if len(self.contents) == 0: return True if len(self.contents) > 1: Trace.error('Unknown ERT length 2') return False texcode = self.contents[0] return len(texcode.contents) == 0 class TeXCode(Container): "A parser and processor for TeX code." texseparators = ['{', '\\', '}', '$', '%'] replaced = BibTeXConfig.replaced factory = FormulaFactory() endinglist = EndingList() def __init__(self): self.contents = [] self.output = ContentsOutput() def parse(self, pos): "Parse some TeX code." self.parserecursive(pos) if pos.leavepending: self.endinglist.pickpending(pos) def findlaststring(self): "Find the last string in the contents." if len(self.contents) == 0: return None string = self.contents[-1] if not isinstance(string, StringContainer): return None return string def add(self, piece): "Add a new piece to the tag." if isinstance(piece, basestring): self.addtext(piece) else: self.contents.append(piece) def addtext(self, piece): "Add a text string to the tag." last = self.findlaststring() if last: last.string += piece return self.contents.append(Constant(piece)) def parserecursive(self, pos): "Parse brackets or quotes recursively." while not pos.finished(): self.parsetext(pos) if pos.finished(): return elif pos.checkfor('{'): self.parseopenbracket(pos) elif pos.checkfor('}'): self.parseclosebracket(pos) elif pos.checkfor('\\'): self.parseescaped(pos) elif pos.checkfor('$'): self.parseformula(pos) elif pos.checkfor('%'): self.parsecomment(pos) else: pos.error('Unexpected character ' + pos.current()) pos.skipcurrent() def parsetext(self, pos): "Parse a bit of text, excluding separators and compressing spaces." text = self.parsecompressingspace(pos) if text == '': return for key in self.replaced: if key in text: text = text.replace(key, self.replaced[key]) self.add(text) def parsecompressingspace(self, pos): "Parse some text excluding value separators and compressing spaces." parsed = '' while not pos.finished(): parsed += pos.glob(lambda: self.excludespaces(pos)) if not pos.finished() and pos.current().isspace(): parsed += ' ' pos.skipspace() else: return parsed return parsed def excludespaces(self, pos): "Exclude value separators and spaces." current = pos.current() if current in self.texseparators: return False if current.isspace(): return False return True def parseescaped(self, pos): "Parse an escaped string \\*." if pos.checkfor('\\(') or pos.checkfor('\\['): # start of formula commands self.parseformula(pos) return if not self.factory.detecttype(FormulaCommand, pos): pos.error('Not an escape sequence') return self.add(self.factory.parsetype(FormulaCommand, pos)) def parseopenbracket(self, pos): "Parse a { bracket." if not pos.checkskip('{'): pos.error('Missing opening { bracket') return pos.pushending('}') self.parserecursive(pos) pos.popending('}') def parseclosebracket(self, pos): "Parse a } bracket." ending = self.endinglist.findending(pos) if not ending: Trace.error('Unexpected closing } bracket') else: self.endinglist.pop(pos) if not pos.checkskip('}'): pos.error('Missing closing } bracket') return def parseformula(self, pos): "Parse a whole formula." formula = Formula().parse(pos) self.add(formula) def parsecomment(self, pos): "Parse a TeX comment: % to the end of the line." pos.globexcluding('\n') def __unicode__(self): "Return a printable representation." return 'TeX code: ' + self.extracttext() elyxer-1.2.5/src/elyxer/tex/__init__.py0000644000175000017500000000000012074107030017325 0ustar chennochennoelyxer-1.2.5/src/elyxer/xtra/0000755000175000017500000000000012117175142015413 5ustar chennochennoelyxer-1.2.5/src/elyxer/xtra/newfangle.py0000644000175000017500000001714412074107030017733 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20100201 # LyX literate programming with the newfangle module. from elyxer.util.trace import Trace from elyxer.util.numbering import * from elyxer.gen.container import * from elyxer.gen.layout import * from elyxer.gen.inset import * from elyxer.gen.float import * from elyxer.ref.label import * class NewfangledChunk(Layout): "A chunk of literate programming." names = dict() firsttime = True def process(self): "Process the literate chunk." self.output.tag = 'div class="chunk"' self.type = 'chunk' text = self.extracttext() parts = text.split(',') if len(parts) < 1: Trace.error('Not enough parameters in ' + text) return self.name = parts[0] self.number = self.order() self.createlinks() self.contents = [self.left, self.declaration(), self.right] ChunkProcessor.lastchunk = self def order(self): "Create the order number for the chunk." return NumberGenerator.generator.generate('chunk') def createlinks(self): "Create back and forward links." self.leftlink = Link().complete(self.number, 'chunk:' + self.number, type='chunk') self.left = TaggedText().complete([self.leftlink], 'span class="chunkleft"', False) self.right = TaggedText().constant('', 'span class="chunkright"', False) if not self.name in NewfangledChunk.names: NewfangledChunk.names[self.name] = [] else: last = NewfangledChunk.names[self.name][-1] forwardlink = Link().complete(self.number + u'→', 'chunkback:' + last.number, type='chunk') backlink = Link().complete(u'←' + last.number + u' ', 'chunkforward:' + self.number, type='chunk') forwardlink.setmutualdestination(backlink) last.right.contents.append(forwardlink) self.right.contents.append(backlink) NewfangledChunk.names[self.name].append(self) self.origin = self.createorigin() if self.name in NewfangledChunkRef.references: for ref in NewfangledChunkRef.references[self.name]: self.linkorigin(ref.origin) def createorigin(self): "Create a link that points to the chunks' origin." link = Link() self.linkorigin(link) return link def linkorigin(self, link): "Create a link to the origin." start = NewfangledChunk.names[self.name][0] link.complete(start.number, type='chunk') link.destination = start.leftlink link.computedestination() def declaration(self): "Get the chunk declaration." contents = [] text = u'⟨' + self.name + '[' + unicode(len(NewfangledChunk.names[self.name])) + '] ' contents.append(Constant(text)) contents.append(self.origin) text = '' if NewfangledChunk.firsttime: Listing.processor = ChunkProcessor() NewfangledChunk.firsttime = False text += u'⟩' if len(NewfangledChunk.names[self.name]) > 1: text += '+' text += u'≡' contents.append(Constant(text)) return TaggedText().complete(contents, 'span class="chunkdecl"', True) class ChunkProcessor(object): "A processor for listings that belong to chunks." lastchunk = None counters = dict() endcommand = '}' chunkref = 'chunkref' def preprocess(self, listing): "Preprocess a listing: set the starting counter." if not ChunkProcessor.lastchunk: return name = ChunkProcessor.lastchunk.name if not name in ChunkProcessor.counters: ChunkProcessor.counters[name] = 0 listing.counter = ChunkProcessor.counters[name] for command, container, index in self.commandsinlisting(listing): chunkref = self.getchunkref(command) if chunkref: self.insertchunkref(chunkref, container, index) def commandsinlisting(self, listing): "Find all newfangle commands in a listing." for container in listing.contents: for index in range(len(container.contents) - 2): if self.findinelement(container, index): third = container.contents[index + 2].string end = third.index(NewfangleConfig.constants['endmark']) command = third[:end] lenstart = len(NewfangleConfig.constants['startmark']) container.contents[index].string = container.contents[index].string[:-lenstart] del container.contents[index + 1] container.contents[index + 1].string = third[end + len(NewfangleConfig.constants['endmark']):] yield command, container, index def findinelement(self, container, index): "Find a newfangle command in an element." for i in range(2): if not isinstance(container.contents[index + i], StringContainer): return False first = container.contents[index].string second = container.contents[index + 1].string third = container.contents[index + 2].string if not first.endswith(NewfangleConfig.constants['startmark']): return False if second != NewfangleConfig.constants['startcommand']: return False if not NewfangleConfig.constants['endmark'] in third: return False return True def getchunkref(self, command): "Get the contents of a chunkref command, if present." if not command.startswith(NewfangleConfig.constants['chunkref']): return None if not NewfangleConfig.constants['endcommand'] in command: return None start = len(NewfangleConfig.constants['chunkref']) end = command.index(NewfangleConfig.constants['endcommand']) return command[start:end] def insertchunkref(self, ref, container, index): "Insert a chunkref after the given index at the given container." chunkref = NewfangledChunkRef().complete(ref) container.contents.insert(index + 1, chunkref) def postprocess(self, listing): "Postprocess a listing: store the ending counter for next chunk." if not ChunkProcessor.lastchunk: return ChunkProcessor.counters[ChunkProcessor.lastchunk.name] = listing.counter class NewfangledChunkRef(Inset): "A reference to a chunk." references = dict() def process(self): "Show the reference." self.output.tag = 'span class="chunkref"' self.ref = self.extracttext() self.addbits() def complete(self, ref): "Complete the reference to the given string." self.output = ContentsOutput() self.ref = ref self.contents = [Constant(self.ref)] self.addbits() return self def addbits(self): "Add the bits to the reference." if not self.ref in NewfangledChunkRef.references: NewfangledChunkRef.references[self.ref] = [] NewfangledChunkRef.references[self.ref].append(self) if self.ref in NewfangledChunk.names: start = NewfangledChunk.names[self.ref][0] self.origin = start.createorigin() else: self.origin = Link() self.contents.insert(0, Constant(u'⟨')) self.contents.append(Constant(' ')) self.contents.append(self.origin) self.contents.append(Constant(u'⟩')) def __unicode__(self): "Return a printable representation." return 'Reference to chunk ' + self.ref elyxer-1.2.5/src/elyxer/xtra/__init__.py0000644000175000017500000000000012074107030017503 0ustar chennochennoelyxer-1.2.5/src/elyxer/io/0000755000175000017500000000000012117175142015044 5ustar chennochennoelyxer-1.2.5/src/elyxer/io/path.py0000644000175000017500000000636412074107030016354 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20090905 # Path manipulations import os import os.path import codecs from elyxer.util.options import Options from elyxer.util.trace import Trace class Path(object): "Represents a generic path" def exists(self): "Check if the file exists" return os.path.exists(self.path) def open(self): "Open the file as readonly binary" return codecs.open(self.path, 'rb') def getmtime(self): "Return last modification time" return os.path.getmtime(self.path) def hasexts(self, exts): "Check if the file has one of the given extensions." for ext in exts: if self.hasext(ext): return True return False def hasext(self, ext): "Check if the file has the given extension" return self.getext() == ext def getext(self): "Get the current extension of the file." base, ext = os.path.splitext(self.path) return ext def __unicode__(self): "Return a unicode string representation" return self.path def __eq__(self, path): "Compare to another path" if not hasattr(path, 'path'): return False return self.path == path.path class InputPath(Path): "Represents an input file" def __init__(self, url): "Create the input path based on url" self.url = url self.path = url if not os.path.isabs(url): self.path = os.path.join(Options.directory, url) class OutputPath(Path): "Represents an output file" def __init__(self, inputpath): "Create the output path based on an input path" self.url = inputpath.url if os.path.isabs(self.url): self.url = os.path.basename(self.url) self.path = os.path.join(Options.destdirectory, self.url) def changeext(self, ext): "Change extension to the given one" base, oldext = os.path.splitext(self.path) self.path = base + ext base, oldext = os.path.splitext(self.url) self.url = base + ext def exists(self): "Check if the file exists" return os.path.exists(self.path) def createdirs(self): "Create any intermediate directories that don't exist" dir = os.path.dirname(self.path) if len(dir) > 0 and not os.path.exists(dir): os.makedirs(dir) def removebackdirs(self): "Remove any occurrences of ../ (or ..\ on Windows)" self.path = os.path.normpath(self.path) backdir = '..' + os.path.sep while self.path.startswith(backdir): self.path = self.path[len(backdir):] while self.url.startswith('../'): self.url = self.url[len('../'):] elyxer-1.2.5/src/elyxer/io/fileline.py0000644000175000017500000000700712074107030017202 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20090308 # File line management for eLyXer import sys import codecs from elyxer.util.trace import Trace class LineReader(object): "Reads a file line by line" def __init__(self, filename): if isinstance(filename, file): self.file = filename else: self.file = codecs.open(filename, 'rU', 'utf-8') self.linenumber = 1 self.lastline = None self.current = None self.mustread = True self.depleted = False try: self.readline() except UnicodeDecodeError: # try compressed file import gzip self.file = gzip.open(filename, 'rb') self.readline() def setstart(self, firstline): "Set the first line to read." for i in range(firstline): self.file.readline() self.linenumber = firstline def setend(self, lastline): "Set the last line to read." self.lastline = lastline def currentline(self): "Get the current line" if self.mustread: self.readline() return self.current def nextline(self): "Go to next line" if self.depleted: Trace.fatal('Read beyond file end') self.mustread = True def readline(self): "Read a line from elyxer.file" self.current = self.file.readline() if not isinstance(self.file, codecs.StreamReaderWriter): self.current = self.current.decode('utf-8') if len(self.current) == 0: self.depleted = True self.current = self.current.rstrip('\n\r') self.linenumber += 1 self.mustread = False Trace.prefix = 'Line ' + unicode(self.linenumber) + ': ' if self.linenumber % 1000 == 0: Trace.message('Parsing') def finished(self): "Find out if the file is finished" if self.lastline and self.linenumber == self.lastline: return True if self.mustread: self.readline() return self.depleted def close(self): self.file.close() class LineWriter(object): "Writes a file as a series of lists" file = False def __init__(self, filename): if isinstance(filename, file): self.file = filename self.filename = None else: self.filename = filename def write(self, strings): "Write a list of strings" for string in strings: if not isinstance(string, basestring): Trace.error('Not a string: ' + unicode(string) + ' in ' + unicode(strings)) return self.writestring(string) def writestring(self, string): "Write a string" if not self.file: self.file = codecs.open(self.filename, 'w', "utf-8") if self.file == sys.stdout and sys.version_info < (3,0): string = string.encode('utf-8') self.file.write(string) def writeline(self, line): "Write a line to file" self.writestring(line + '\n') def close(self): self.file.close() elyxer-1.2.5/src/elyxer/io/bulk.py0000644000175000017500000000410312074107030016342 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20090416 # Bulk file processing import os import codecs from elyxer.io.fileline import * from elyxer.util.trace import Trace class BulkFile(object): "A file to treat in bulk" encodings = ['utf-8','Cp1252'] def __init__(self, filename): self.filename = filename self.temp = self.filename + '.temp' def readall(self): "Read the whole file" for encoding in BulkFile.encodings: try: return self.readcodec(encoding) except UnicodeDecodeError: pass Trace.error('No suitable encoding for ' + self.filename) return [] def readcodec(self, encoding): "Read the whole file with the given encoding" filein = codecs.open(self.filename, 'rU', encoding) lines = filein.readlines() result = [] for line in lines: result.append(line.strip('\r\n') + '\n') filein.close() return result def getfiles(self): "Get reader and writer for a file name" reader = LineReader(self.filename) writer = LineWriter(self.temp) return reader, writer def swaptemp(self): "Swap the temp file for the original" os.chmod(self.temp, os.stat(self.filename).st_mode) os.rename(self.temp, self.filename) def __unicode__(self): "Get the unicode representation" return 'file ' + self.filename elyxer-1.2.5/src/elyxer/io/__init__.py0000644000175000017500000000000012074107030017134 0ustar chennochennoelyxer-1.2.5/src/elyxer/util/0000755000175000017500000000000012117175142015412 5ustar chennochennoelyxer-1.2.5/src/elyxer/util/options.py0000644000175000017500000002430212074107773017467 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20090313 # eLyXer runtime options import os.path import sys from elyxer.conf.config import * from elyxer.util.trace import * from elyxer.util.clparse import * class Options(object): "A set of runtime options" instance = None location = None nocopy = False copyright = False debug = False quiet = False version = False hardversion = False versiondate = False html = False help = False showlines = True unicode = False iso885915 = False css = [] title = None directory = None destdirectory = None toc = False toctarget = '' tocfor = None forceformat = None lyxformat = False target = None splitpart = None memory = True lowmem = False nobib = False converter = 'imagemagick' raw = False jsmath = None mathjax = None nofooter = False simplemath = False template = None noconvert = False notoclabels = False letterfoot = True numberfoot = False symbolfoot = False hoverfoot = True marginfoot = False endfoot = False supfoot = True alignfoot = False footnotes = None imageformat = None copyimages = False googlecharts = False embedcss = [] branches = dict() def parseoptions(self, args): "Parse command line options" Options.location = args[0] del args[0] parser = CommandLineParser(Options) result = parser.parseoptions(args) if result: Trace.error(result) self.usage() self.processoptions() def processoptions(self): "Process all options parsed." if Options.help: self.usage() if Options.version: self.showversion() if Options.hardversion: self.showhardversion() if Options.versiondate: self.showversiondate() if Options.lyxformat: self.showlyxformat() if Options.splitpart: try: Options.splitpart = int(Options.splitpart) if Options.splitpart <= 0: Trace.error('--splitpart requires a number bigger than zero') self.usage() except: Trace.error('--splitpart needs a numeric argument, not ' + Options.splitpart) self.usage() if Options.lowmem or Options.toc or Options.tocfor: Options.memory = False self.parsefootnotes() if Options.forceformat and not Options.imageformat: Options.imageformat = Options.forceformat if Options.imageformat == 'copy': Options.copyimages = True if Options.css == []: Options.css = ['http://elyxer.nongnu.org/lyx.css'] if Options.html: Options.simplemath = True if Options.toc and not Options.tocfor: Trace.error('Option --toc is deprecated; use --tocfor "page" instead') Options.tocfor = Options.toctarget if Options.nocopy: Trace.error('Option --nocopy is deprecated; it is no longer needed') if Options.jsmath: Trace.error('Option --jsmath is deprecated; use --mathjax instead') # set in Trace if necessary for param in dir(Trace): if param.endswith('mode'): setattr(Trace, param, getattr(self, param[:-4])) def usage(self): "Show correct usage" Trace.error('Usage: ' + os.path.basename(Options.location) + ' [options] [filein] [fileout]') Trace.error('Convert LyX input file "filein" to HTML file "fileout".') Trace.error('If filein (or fileout) is not given use standard input (or output).') Trace.error('Main program of the eLyXer package (http://elyxer.nongnu.org/).') self.showoptions() def parsefootnotes(self): "Parse footnotes options." if not Options.footnotes: return Options.marginfoot = False Options.letterfoot = False Options.hoverfoot = False options = Options.footnotes.split(',') for option in options: footoption = option + 'foot' if hasattr(Options, footoption): setattr(Options, footoption, True) else: Trace.error('Unknown footnotes option: ' + option) if not Options.endfoot and not Options.marginfoot and not Options.hoverfoot: Options.hoverfoot = True if not Options.numberfoot and not Options.symbolfoot: Options.letterfoot = True def showoptions(self): "Show all possible options" Trace.error(' Common options:') Trace.error(' --help: show this online help') Trace.error(' --quiet: disables all runtime messages') Trace.error('') Trace.error(' Advanced options:') Trace.error(' --debug: enable debugging messages (for developers)') Trace.error(' --version: show version number and release date') Trace.error(' --lyxformat: return the highest LyX version supported') Trace.error(' Options for HTML output:') Trace.error(' --title "title": set the generated page title') Trace.error(' --css "file.css": use a custom CSS file') Trace.error(' --embedcss "file.css": embed styles from a CSS file into the output') Trace.error(' --html: output HTML 4.0 instead of the default XHTML') Trace.error(' --unicode: full Unicode output') Trace.error(' --iso885915: output a document with ISO-8859-15 encoding') Trace.error(' --nofooter: remove the footer "generated by eLyXer"') Trace.error(' --simplemath: do not generate fancy math constructions') Trace.error(' Options for image output:') Trace.error(' --directory "img_dir": look for images in the specified directory') Trace.error(' --destdirectory "dest": put converted images into this directory') Trace.error(' --imageformat ".ext": image output format, or "copy" to copy images') Trace.error(' --noconvert: do not convert images, use in original locations') Trace.error(' --converter "inkscape": use an alternative program to convert images') Trace.error(' Options for footnote display:') Trace.error(' --numberfoot: mark footnotes with numbers instead of letters') Trace.error(' --symbolfoot: mark footnotes with symbols (*, **...)') Trace.error(' --hoverfoot: show footnotes as hovering text (default)') Trace.error(' --marginfoot: show footnotes on the page margin') Trace.error(' --endfoot: show footnotes at the end of the page') Trace.error(' --supfoot: use superscript for footnote markers (default)') Trace.error(' --alignfoot: use aligned text for footnote markers') Trace.error(' --footnotes "options": specify several comma-separated footnotes options') Trace.error(' Available options are: "number", "symbol", "hover", "margin", "end",') Trace.error(' "sup", "align"') Trace.error(' Advanced output options:') Trace.error(' --splitpart "depth": split the resulting webpage at the given depth') Trace.error(' --tocfor "page": generate a TOC that points to the given page') Trace.error(' --target "frame": make all links point to the given frame') Trace.error(' --notoclabels: omit the part labels in the TOC, such as Chapter') Trace.error(' --lowmem: do the conversion on the fly (conserve memory)') Trace.error(' --raw: generate HTML without header or footer.') Trace.error(' --mathjax remote: use MathJax remotely to display equations') Trace.error(' --mathjax "URL": use MathJax from the given URL to display equations') Trace.error(' --googlecharts: use Google Charts to generate formula images') Trace.error(' --template "file": use a template, put everything in ') Trace.error(' --copyright: add a copyright notice at the bottom') Trace.error(' Deprecated options:') Trace.error(' --toc: (deprecated) create a table of contents') Trace.error(' --toctarget "page": (deprecated) generate a TOC for the given page') Trace.error(' --nocopy: (deprecated) maintained for backwards compatibility') Trace.error(' --jsmath "URL": use jsMath from the given URL to display equations') sys.exit() def showversion(self): "Return the current eLyXer version string" string = 'eLyXer version ' + GeneralConfig.version['number'] string += ' (' + GeneralConfig.version['date'] + ')' Trace.error(string) sys.exit() def showhardversion(self): "Return just the version string" Trace.message(GeneralConfig.version['number']) sys.exit() def showversiondate(self): "Return just the version dte" Trace.message(GeneralConfig.version['date']) sys.exit() def showlyxformat(self): "Return just the lyxformat parameter" Trace.message(GeneralConfig.version['lyxformat']) sys.exit() class BranchOptions(object): "A set of options for a branch" def __init__(self, name): self.name = name self.options = {'color':'#ffffff'} def set(self, key, value): "Set a branch option" if not key.startswith(ContainerConfig.string['startcommand']): Trace.error('Invalid branch option ' + key) return key = key.replace(ContainerConfig.string['startcommand'], '') self.options[key] = value def isselected(self): "Return if the branch is selected" if not 'selected' in self.options: return False return self.options['selected'] == '1' def __unicode__(self): "String representation" return 'options for ' + self.name + ': ' + unicode(self.options) elyxer-1.2.5/src/elyxer/util/clone.py0000644000175000017500000000551012074107030017056 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20091101 # eLyXer object cloning from elyxer.util.trace import Trace class Cloner(object): "An object used to clone other objects." def clone(cls, original): "Return an exact copy of an object." "The original object must have an empty constructor." return cls.create(original.__class__) def create(cls, type): "Create an object of a given class." clone = type.__new__(type) clone.__init__() return clone clone = classmethod(clone) create = classmethod(create) class ContainerExtractor(object): "A class to extract certain containers." def __init__(self, config): "The config parameter is a map containing three lists: allowed, copied and extracted." "Each of the three is a list of class names for containers." "Allowed containers are included as is into the result." "Cloned containers are cloned and placed into the result." "Extracted containers are looked into." "All other containers are silently ignored." self.allowed = config['allowed'] self.cloned = config['cloned'] self.extracted = config['extracted'] def extract(self, container): "Extract a group of selected containers from elyxer.a container." list = [] locate = lambda c: c.__class__.__name__ in self.allowed + self.cloned recursive = lambda c: c.__class__.__name__ in self.extracted process = lambda c: self.process(c, list) container.recursivesearch(locate, recursive, process) return list def process(self, container, list): "Add allowed containers, clone cloned containers and add the clone." name = container.__class__.__name__ if name in self.allowed: list.append(container) elif name in self.cloned: list.append(self.safeclone(container)) else: Trace.error('Unknown container class ' + name) def safeclone(self, container): "Return a new container with contents only in a safe list, recursively." clone = Cloner.clone(container) clone.output = container.output clone.contents = self.extract(container) return clone elyxer-1.2.5/src/elyxer/util/numbering.py0000644000175000017500000002050312074107030017743 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20090418 # eLyXer number generator from elyxer.util.trace import Trace from elyxer.util.translate import * from elyxer.util.docparams import * from elyxer.conf.config import * class NumberCounter(object): "A counter for numbers (by default)." "The type can be changed to return letters, roman numbers..." name = None value = None mode = None master = None letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' symbols = NumberingConfig.sequence['symbols'] romannumerals = [ ('M', 1000), ('CM', 900), ('D', 500), ('CD', 400), ('C', 100), ('XC', 90), ('L', 50), ('XL', 40), ('X', 10), ('IX', 9), ('V', 5), ('IV', 4), ('I', 1) ] def __init__(self, name): "Give a name to the counter." self.name = name def setmode(self, mode): "Set the counter mode. Can be changed at runtime." self.mode = mode return self def init(self, value): "Set an initial value." self.value = value def gettext(self): "Get the next value as a text string." return unicode(self.value) def getletter(self): "Get the next value as a letter." return self.getsequence(self.letters) def getsymbol(self): "Get the next value as a symbol." return self.getsequence(self.symbols) def getsequence(self, sequence): "Get the next value from elyxer.a sequence." return sequence[(self.value - 1) % len(sequence)] def getroman(self): "Get the next value as a roman number." result = '' number = self.value for numeral, value in self.romannumerals: if number >= value: result += numeral * (number / value) number = number % value return result def getvalue(self): "Get the current value as configured in the current mode." if not self.mode or self.mode in ['text', '1']: return self.gettext() if self.mode == 'A': return self.getletter() if self.mode == 'a': return self.getletter().lower() if self.mode == 'I': return self.getroman() if self.mode == '*': return self.getsymbol() Trace.error('Unknown counter mode ' + self.mode) return self.gettext() def getnext(self): "Increase the current value and get the next value as configured." if not self.value: self.value = 0 self.value += 1 return self.getvalue() def reset(self): "Reset the counter." self.value = 0 def __unicode__(self): "Return a printable representation." result = 'Counter ' + self.name if self.mode: result += ' in mode ' + self.mode return result class DependentCounter(NumberCounter): "A counter which depends on another one (the master)." def setmaster(self, master): "Set the master counter." self.master = master self.last = self.master.getvalue() return self def getnext(self): "Increase or, if the master counter has changed, restart." if self.last != self.master.getvalue(): self.reset() value = NumberCounter.getnext(self) self.last = self.master.getvalue() return value def getvalue(self): "Get the value of the combined counter: master.dependent." return self.master.getvalue() + '.' + NumberCounter.getvalue(self) class NumberGenerator(object): "A number generator for unique sequences and hierarchical structures. Used in:" " * ordered part numbers: Chapter 3, Section 5.3." " * unique part numbers: Footnote 15, Bibliography cite [15]." " * chaptered part numbers: Figure 3.15, Equation (8.3)." " * unique roman part numbers: Part I, Book IV." chaptered = None generator = None romanlayouts = [x.lower() for x in NumberingConfig.layouts['roman']] orderedlayouts = [x.lower() for x in NumberingConfig.layouts['ordered']] counters = dict() appendix = None def deasterisk(self, type): "Remove the possible asterisk in a layout type." return type.replace('*', '') def isunique(self, type): "Find out if the layout type corresponds to a unique part." return self.isroman(type) def isroman(self, type): "Find out if the layout type should have roman numeration." return self.deasterisk(type).lower() in self.romanlayouts def isinordered(self, type): "Find out if the layout type corresponds to an (un)ordered part." return self.deasterisk(type).lower() in self.orderedlayouts def isnumbered(self, type): "Find out if the type for a layout corresponds to a numbered layout." if '*' in type: return False if self.isroman(type): return True if not self.isinordered(type): return False if self.getlevel(type) > DocumentParameters.maxdepth: return False return True def isunordered(self, type): "Find out if the type contains an asterisk, basically." return '*' in type def getlevel(self, type): "Get the level that corresponds to a layout type." if self.isunique(type): return 0 if not self.isinordered(type): Trace.error('Unknown layout type ' + type) return 0 type = self.deasterisk(type).lower() level = self.orderedlayouts.index(type) + 1 return level - DocumentParameters.startinglevel def getparttype(self, type): "Obtain the type for the part: without the asterisk, " "and switched to Appendix if necessary." if NumberGenerator.appendix and self.getlevel(type) == 1: return 'Appendix' return self.deasterisk(type) def generate(self, type): "Generate a number for a layout type." "Unique part types such as Part or Book generate roman numbers: Part I." "Ordered part types return dot-separated tuples: Chapter 5, Subsection 2.3.5." "Everything else generates unique numbers: Bibliography [1]." "Each invocation results in a new number." return self.getcounter(type).getnext() def getcounter(self, type): "Get the counter for the given type." type = type.lower() if not type in self.counters: self.counters[type] = self.create(type) return self.counters[type] def create(self, type): "Create a counter for the given type." if self.isnumbered(type) and self.getlevel(type) > 1: index = self.orderedlayouts.index(type) above = self.orderedlayouts[index - 1] master = self.getcounter(above) return self.createdependent(type, master) counter = NumberCounter(type) if self.isroman(type): counter.setmode('I') return counter def getdependentcounter(self, type, master): "Get (or create) a counter of the given type that depends on another." if not type in self.counters or not self.counters[type].master: self.counters[type] = self.createdependent(type, master) return self.counters[type] def createdependent(self, type, master): "Create a dependent counter given the master." return DependentCounter(type).setmaster(master) def startappendix(self): "Start appendices here." firsttype = self.orderedlayouts[DocumentParameters.startinglevel] counter = self.getcounter(firsttype) counter.setmode('A').reset() NumberGenerator.appendix = True class ChapteredGenerator(NumberGenerator): "Generate chaptered numbers, as in Chapter.Number." "Used in equations, figures: Equation (5.3), figure 8.15." def generate(self, type): "Generate a number which goes with first-level numbers (chapters). " "For the article classes a unique number is generated." if DocumentParameters.startinglevel > 0: return NumberGenerator.generator.generate(type) chapter = self.getcounter('Chapter') return self.getdependentcounter(type, chapter).getnext() NumberGenerator.chaptered = ChapteredGenerator() NumberGenerator.generator = NumberGenerator() elyxer-1.2.5/src/elyxer/util/clparse.py0000644000175000017500000000525712074107030017417 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20090416 # Command line option parser from elyxer.util.trace import * class CommandLineParser(object): "A parser for runtime options" def __init__(self, options): self.options = options def parseoptions(self, args): "Parse command line options" if len(args) == 0: return None while len(args) > 0 and args[0].startswith('--'): key, value = self.readoption(args) if not key: return 'Option ' + value + ' not recognized' if not value: return 'Option ' + key + ' needs a value' setattr(self.options, key, value) return None def readoption(self, args): "Read the key and value for an option" arg = args[0][2:] del args[0] if '=' in arg: key = self.readequalskey(arg, args) else: key = arg.replace('-', '') if not hasattr(self.options, key): return None, key current = getattr(self.options, key) if isinstance(current, bool): return key, True # read value if len(args) == 0: return key, None if args[0].startswith('"'): initial = args[0] del args[0] return key, self.readquoted(args, initial) value = args[0].decode('utf-8') del args[0] if isinstance(current, list): current.append(value) return key, current return key, value def readquoted(self, args, initial): "Read a value between quotes" Trace.error('Oops') value = initial[1:] while len(args) > 0 and not args[0].endswith('"') and not args[0].startswith('--'): Trace.error('Appending ' + args[0]) value += ' ' + args[0] del args[0] if len(args) == 0 or args[0].startswith('--'): return None value += ' ' + args[0:-1] return value def readequalskey(self, arg, args): "Read a key using equals" split = arg.split('=', 1) key = split[0] value = split[1] args.insert(0, value) return key elyxer-1.2.5/src/elyxer/util/trace.py0000644000175000017500000000372612074107030017063 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20090131 # eLyXer trace library import sys class Trace(object): "A tracing class" debugmode = False quietmode = False showlinesmode = False prefix = None def debug(cls, message): "Show a debug message" if not Trace.debugmode or Trace.quietmode: return Trace.show(message, sys.stdout) def message(cls, message): "Show a trace message" if Trace.quietmode: return if Trace.prefix and Trace.showlinesmode: message = Trace.prefix + message Trace.show(message, sys.stdout) def error(cls, message): "Show an error message" message = '* ' + message if Trace.prefix and Trace.showlinesmode: message = Trace.prefix + message Trace.show(message, sys.stderr) def fatal(cls, message): "Show an error message and terminate" Trace.error('FATAL: ' + message) exit(-1) def show(cls, message, channel): "Show a message out of a channel" if sys.version_info < (3,0): message = message.encode('utf-8') channel.write(message + '\n') debug = classmethod(debug) message = classmethod(message) error = classmethod(error) fatal = classmethod(fatal) show = classmethod(show) elyxer-1.2.5/src/elyxer/util/docparams.py0000644000175000017500000000220512074107030017725 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20100713 # eLyXer: LyX document parameters from elyxer.util.trace import Trace class DocumentParameters(object): "Global parameters for the document." pdftitle = None indentstandard = False tocdepth = 10 startinglevel = 0 maxdepth = 10 language = None bibliography = None outputchanges = False displaymode = False elyxer-1.2.5/src/elyxer/util/translate.py0000644000175000017500000000520712074107030017756 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20100112 # eLyXer translations and translation generation import gettext from elyxer.util.trace import Trace from elyxer.util.docparams import * from elyxer.conf.config import * class Translator(object): "Reads the configuration file and tries to find a translation." "Otherwise falls back to the messages in the config file." instance = None def translate(cls, key): "Get the translated message for a key." return cls.instance.getmessage(key) translate = classmethod(translate) def __init__(self): self.translation = None self.first = True def findtranslation(self): "Find the translation for the document language." self.langcodes = None if not DocumentParameters.language: Trace.error('No language in document') return if not DocumentParameters.language in TranslationConfig.languages: Trace.error('Unknown language ' + DocumentParameters.language) return if TranslationConfig.languages[DocumentParameters.language] == 'en': return langcodes = [TranslationConfig.languages[DocumentParameters.language]] try: self.translation = gettext.translation('elyxer', None, langcodes) except IOError: Trace.error('No translation for ' + unicode(langcodes)) def getmessage(self, key): "Get the translated message for the given key." if self.first: self.findtranslation() self.first = False message = self.getuntranslated(key) if not self.translation: return message try: message = self.translation.ugettext(message) except IOError: pass return message def getuntranslated(self, key): "Get the untranslated message." if not key in TranslationConfig.constants: Trace.error('Cannot translate ' + key) return key return TranslationConfig.constants[key] Translator.instance = Translator() elyxer-1.2.5/src/elyxer/util/__init__.py0000644000175000017500000000000012074107030017502 0ustar chennochennoelyxer-1.2.5/src/elyxer/bib/0000755000175000017500000000000012117175142015171 5ustar chennochennoelyxer-1.2.5/src/elyxer/bib/tag.py0000644000175000017500000002014212074107030016306 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20101027 # eLyXer BibTeX tag parsing from elyxer.util.trace import Trace from elyxer.util.clone import * from elyxer.conf.config import * from elyxer.parse.position import * from elyxer.gen.container import * from elyxer.maths.formula import * from elyxer.maths.command import * from elyxer.tex.texcode import * class BibTagParser(object): "A parser for BibTeX tags." nameseparators = ['{', '=', '"', '#'] def __init__(self): self.key = None tags = BibStylesConfig.defaulttags self.tags = dict((x, BibTag().constant(tags[x])) for x in tags) def parse(self, pos): "Parse the entry between {}." self.type = pos.globexcluding(self.nameseparators).strip() if not pos.checkskip('{'): pos.error('Entry should start with {') return pos.pushending('}') self.parsetags(pos) pos.popending('}') pos.skipspace() def parsetags(self, pos): "Parse all tags in the entry." pos.skipspace() while not pos.finished(): if pos.checkskip('{'): pos.error('Unmatched {') return pos.pushending(',', True) self.parsetag(pos) if pos.checkfor(','): pos.popending(',') def parsetag(self, pos): "Parse a single tag." (key, value) = self.getkeyvalue(pos) if not key: return if not value: self.key = key return name = key.lower() self.tags[name] = value if hasattr(self, 'dissect' + name): dissector = getattr(self, 'dissect' + name) dissector(value.extracttext()) if not pos.finished(): remainder = pos.globexcluding(',') pos.error('Ignored ' + remainder + ' before comma') def getkeyvalue(self, pos): "Parse a string of the form key=value." piece = pos.globexcluding(self.nameseparators).strip() if pos.finished(): return (piece, None) if not pos.checkskip('='): pos.error('Undesired character in tag name ' + piece) pos.skipcurrent() return (piece, None) key = piece.lower() pos.skipspace() value = self.parsevalue(pos) return (key, value) def parsevalue(self, pos): "Parse the value for a tag." tag = BibTag() pos.skipspace() if pos.checkfor(','): pos.error('Unexpected ,') return tag.error() tag.parse(pos) return tag def dissectauthor(self, authortag): "Dissect the author tag into pieces." authorsplit = authortag.split(' and ') if len(authorsplit) == 0: return authorlist = [] for authorname in authorsplit: author = BibAuthor().parse(authorname) authorlist.append(author) initials = '' authors = '' if len(authorlist) == 1: initials = authorlist[0].surname[0:3] authors = unicode(authorlist[0]) else: for author in authorlist: initials += author.surname[0:1] authors += unicode(author) + ', ' authors = authors[:-2] self.tags['surname'] = BibTag().constant(authorlist[0].surname) self.tags['Sur'] = BibTag().constant(initials) self.tags['authors'] = BibTag().constant(authors) def dissectyear(self, yeartag): "Dissect the year tag into pieces, looking for 4 digits in a row." pos = TextPosition(yeartag) while not pos.finished(): if pos.current().isdigit(): number = pos.globnumber() if len(number) == 4: self.tags['YY'] = BibTag().constant(number[2:]) return else: pos.skipcurrent() def dissectfile(self, filetag): "Extract the filename from elyxer.the file tag as ':filename:FORMAT'." if not filetag.startswith(':'): return bits = filetag.split(':') if len(bits) != 3: return self.tags['filename'] = BibTag().constant(bits[1]) self.tags['format'] = BibTag().constant(bits[2]) def gettag(self, key): "Get the tag for a given key." if not key in self.tags: return None return self.tags[key] def gettagtext(self, key): "Get the tag for a key as raw text." return self.gettag(key).extracttext() class BibTag(Container): "A tag in a BibTeX file." valueseparators = ['{', '"', '#', '}'] stringdefs = dict() def __init__(self): self.contents = [] self.output = ContentsOutput() def constant(self, text): "Initialize for a single constant." self.contents = [Constant(text)] return self def error(self): "To use when parsing resulted in an error." return self.constant('') def parse(self, pos): "Parse brackets or quotes at the first level." while not pos.finished(): self.parsetext(pos) if pos.finished(): return elif pos.checkfor('{'): self.parsebracket(pos) elif pos.checkfor('"'): self.parsequoted(pos) elif pos.checkfor('#'): self.parsehash(pos) else: pos.error('Unexpected character ' + pos.current()) pos.skipcurrent() def parsetext(self, pos): "Parse a bit of text, try to substitute strings with string defs." text = pos.globexcluding(self.valueseparators) key = text.strip() if key == '': return if key in self.stringdefs: self.add(self.stringdefs[key]) return self.add(Constant(key)) def add(self, piece): "Add a new piece to the tag." self.contents.append(piece) def parsetex(self, pos): "Parse some TeX code." tex = TeXCode() tex.parse(pos) self.add(tex) def parsebracket(self, pos): "Parse a {} bracket" if not pos.checkskip('{'): pos.error('Missing opening { in bracket') return pos.pushending('}') self.parsetex(pos) pos.popending('}') def parsequoted(self, pos): "Parse a piece of quoted text" if not pos.checkskip('"'): pos.error('Missing opening " in quote') return pos.pushending('"') self.parsetex(pos) pos.popending('"') pos.skipspace() def parsehash(self, pos): "Parse a hash mark #." if not pos.checkskip('#'): pos.error('Missing # in hash') return def __unicode__(self): "Return a printable representation." return 'BibTag: ' + self.extracttext() class BibAuthor(object): "A BibTeX individual author." def __init__(self): self.surname = '' self.firstnames = [] def parse(self, tag): "Parse an individual author tag." if ',' in tag: self.parsecomma(tag) else: self.parsewithoutcomma(tag) return self def parsecomma(self, tag): "Parse an author with a comma: Python, M." bits = tag.split(',') if len(bits) > 2: Trace.error('Too many commas in ' + tag) self.surname = bits[0].strip() self.parsefirstnames(bits[1].strip()) def parsewithoutcomma(self, tag): "Parse an author without a comma: M. Python." bits = tag.rsplit(None, 1) if len(bits) == 0: Trace.error('Empty author') ppp() return self.surname = bits[-1].strip() if len(bits) == 1: return self.parsefirstnames(bits[0].strip()) def parsefirstnames(self, firstnames): "Parse the first name." for firstname in firstnames.split(): self.firstnames.append(firstname) def getinitial(self): "Get the main initial for the author." if len(self.surname) == 0: return '' return self.surname[0].toupper() def __unicode__(self): "Return a printable representation." result = '' for firstname in self.firstnames: result += firstname + ' ' return result + self.surname elyxer-1.2.5/src/elyxer/bib/pub.py0000644000175000017500000001440512074107030016326 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20100606 # eLyXer BibTeX publication entries. from elyxer.util.trace import Trace from elyxer.out.output import * from elyxer.conf.config import * from elyxer.parse.position import * from elyxer.ref.link import * from elyxer.bib.tex import * from elyxer.bib.tag import * class PubEntry(BibEntry): "A publication entry" def __init__(self): self.output = TaggedOutput().settag('p class="biblio"', True) def detect(self, pos): "Detect a publication entry." return pos.checkfor('@') def parse(self, pos): "Parse the publication entry." self.parser = BibTagParser() self.parser.parse(pos) self.type = self.parser.type def isvisible(self): "A publication entry is always visible." return True def isreferenced(self): "Check if the entry is referenced." if not self.parser.key: return False return self.parser.key in BiblioReference.references def process(self): "Process the entry." self.index = NumberGenerator.generator.generate('pubentry') self.parser.tags['index'] = Constant(self.index) biblio = BiblioEntry() biblio.citeref = self.createref() biblio.processcites(self.parser.key) self.contents = [biblio, Constant(' ')] self.contents += self.entrycontents() def entrycontents(self): "Get the contents of the entry." return self.translatetemplate(self.template) def createref(self): "Create the reference to cite." return self.translatetemplate(self.citetemplate) def translatetemplate(self, template): "Translate a complete template into a list of contents." pos = TextPosition(template) part = BibPart(self.parser.tags).parse(pos) for variable in part.searchall(BibVariable): if variable.empty(): Trace.error('Error parsing BibTeX template for ' + unicode(self) + ': ' + unicode(variable) + ' is empty') return [part] def __unicode__(self): "Return a string representation" string = '' if 'author' in self.parser.tags: string += self.parser.gettagtext('author') + ': ' if 'title' in self.parser.tags: string += '"' + self.parser.gettagtext('title') + '"' return string class BibPart(Container): "A part of a BibTeX template." def __init__(self, tags): self.output = ContentsOutput() self.contents = [] self.tags = tags self.quotes = 0 def parse(self, pos): "Parse a part of a template, return a list of contents." while not pos.finished(): self.add(self.parsepiece(pos)) return self def parsepiece(self, pos): "Get the next piece of the template, return if it was empty." if pos.checkfor('{'): return self.parsebraces(pos) elif pos.checkfor('$'): return self.parsevariable(pos) result = '' while not pos.finished() and not pos.current() in '{$': if pos.current() == '"': self.quotes += 1 result += pos.skipcurrent() return Constant(result) def parsebraces(self, pos): "Parse a pair of curly braces {}." if not pos.checkskip('{'): Trace.error('Missing { in braces.') return None pos.pushending('}') part = BibPart(self.tags).parse(pos) pos.popending('}') empty = part.emptyvariables() if empty: return None return part def parsevariable(self, pos): "Parse a variable $name." var = BibVariable(self.tags).parse(pos) if self.quotes % 2 == 1: # odd number of quotes; don't add spans in an attribute var.removetag() return var def emptyvariables(self): "Find out if there are only empty variables in the part." for variable in self.searchall(BibVariable): if not variable.empty(): return False return True def add(self, piece): "Add a new piece to the current part." if not piece: return if self.redundantdot(piece): # remove extra dot piece.string = piece.string[1:] self.contents.append(piece) piece.parent = self def redundantdot(self, piece): "Find out if there is a redundant dot in the next piece." if not isinstance(piece, Constant): return False if not piece.string.startswith('.'): return False if len(self.contents) == 0: return False if not isinstance(self.contents[-1], BibVariable): return False if not self.contents[-1].extracttext().endswith('.'): return False return True class BibVariable(Container): "A variable in a BibTeX template." def __init__(self, tags): self.output = TaggedOutput() self.contents = [] self.tags = tags def parse(self, pos): "Parse the variable name." if not pos.checkskip('$'): Trace.error('Missing $ in variable name.') return self self.key = pos.globalpha() self.output.tag = 'span class="bib-' + self.key + '"' self.processtags() return self def processtags(self): "Find the tag with the appropriate key in the list of tags." if not self.key in self.tags: return result = self.tags[self.key] self.contents = [result] def empty(self): "Find out if the variable is empty." if not self.contents: return True if self.extracttext() == '': return True return False def removetag(self): "Remove the output tag and leave just the contents." self.output = ContentsOutput() def __unicode__(self): "Return a printable representation." result = 'variable ' + self.key if not self.empty(): result += ':' + self.extracttext() return result BibEntry.instances += [PubEntry()] elyxer-1.2.5/src/elyxer/bib/biblio.py0000644000175000017500000001130012074107030016767 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20090415 # eLyXer bibliography from elyxer.util.numbering import * from elyxer.util.docparams import * from elyxer.parse.parser import * from elyxer.out.output import * from elyxer.ref.link import * from elyxer.gen.layout import * from elyxer.proc.postprocess import * class BiblioCitation(Container): "A complete bibliography citation (possibly with many cites)." citations = dict() def __init__(self): self.parser = InsetParser() self.output = TaggedOutput().settag('span class="bibcites"') self.contents = [] def process(self): "Process the complete citation and all cites within." self.contents = [Constant('[')] keys = self.getparameterlist('key') for key in keys: self.contents += [BiblioCite().create(key), Constant(', ')] if len(keys) > 0: # remove trailing , self.contents.pop() self.contents.append(Constant(']')) class BiblioCite(Link): "Cite of a bibliography entry" cites = dict() def create(self, key): "Create the cite to the given key." self.key = key number = NumberGenerator.generator.generate('bibliocite') ref = BiblioReference().create(key, number) self.complete(number, 'cite-' + number, type='bibliocite') self.setmutualdestination(ref) if not key in BiblioCite.cites: BiblioCite.cites[key] = [] BiblioCite.cites[key].append(self) return self class Bibliography(Container): "A bibliography layout containing an entry" def __init__(self): self.parser = BoundedParser() self.output = TaggedOutput().settag('p class="biblio"', True) class BiblioHeader(Container): "The header of the bibliography." def __init__(self): "Create the header for the bibliography section." self.type = 'biblio' self.output = ContentsOutput() self.name = Translator.translate(DocumentParameters.bibliography) self.contents = [TaggedText().constant(self.name, 'h1 class="biblio"', True)] def addtotoc(self, parent): "Add the bibliography header to the TOC." self.parent = parent self.partkey = PartKeyGenerator.forindex(self) if not self.partkey: return self.partkey.addtoclabel(self) while parent: parent.partkey = self.partkey parent = parent.parent class PostBiblio(object): "Insert a Bibliography legend before the first item" processedclass = Bibliography def postprocess(self, last, element, next): "If we have the first bibliography insert a tag" if isinstance(last, Bibliography) or Options.nobib: return element layout = StandardLayout() header = BiblioHeader() header.addtotoc(layout) layout.complete([header, element]) return layout Postprocessor.stages += [PostBiblio] class BiblioReference(Link): "A reference to a bibliographical entry." references = dict() def create(self, key, number): "Create the reference with the given key and number." self.key = key self.complete(number, 'biblio-' + number, type='biblioentry') if not key in BiblioReference.references: BiblioReference.references[key] = [] BiblioReference.references[key].append(self) return self class BiblioEntry(Container): "A bibliography entry" entries = dict() def __init__(self): self.parser = InsetParser() self.output = TaggedOutput().settag('span class="entry"') self.contents = [] def process(self): "Process the cites for the entry's key" self.citeref = [Constant(NumberGenerator.generator.generate('biblioentry'))] self.processcites(self.getparameter('key')) def processcites(self, key): "Get all the cites of the entry" self.key = key if not key in BiblioReference.references: self.contents.append(Constant('[-] ')) return self.contents = [Constant('[')] for ref in BiblioReference.references[key]: self.contents.append(ref) self.contents.append(Constant(',')) self.contents.pop(-1) self.contents.append(Constant('] ')) elyxer-1.2.5/src/elyxer/bib/tex.py0000644000175000017500000001707312074107030016344 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20090905 # eLyXer BibTeX processing from elyxer.util.trace import Trace from elyxer.util.clone import * from elyxer.out.output import * from elyxer.io.path import * from elyxer.io.bulk import * from elyxer.conf.config import * from elyxer.parse.position import * from elyxer.ref.link import * from elyxer.bib.biblio import * from elyxer.bib.tag import * class BibTeX(Container): "Show a BibTeX bibliography and all referenced entries" def __init__(self): self.parser = InsetParser() self.output = ContentsOutput() def process(self): "Read all bibtex files and process them." self.entries = [] self.contents = [self.createheader()] bibliography = Translator.translate('bibliography') files = self.getparameterlist('bibfiles') showall = False if self.getparameter('btprint') == 'btPrintAll': showall = True for file in files: bibfile = BibFile(file, showall) bibfile.parse() self.entries += bibfile.entries Trace.message('Parsed ' + unicode(bibfile)) self.entries.sort(key = unicode) self.applystyle() def createheader(self): "Create the header for the bibliography." header = BiblioHeader() if 'bibtotoc' in self.getparameterlist('options'): header.addtotoc(self) return header def applystyle(self): "Read the style and apply it to all entries" style = self.readstyle() for entry in self.entries: entry.template = style['default'] entry.citetemplate = style['cite'] type = entry.type.lower() if type in style: entry.template = style[type] entry.process() self.contents.append(entry) def readstyle(self): "Read the style from elyxer.the bibliography options" for option in self.getparameterlist('options'): if hasattr(BibStylesConfig, option): return getattr(BibStylesConfig, option) return BibStylesConfig.default class BibFile(object): "A BibTeX file" def __init__(self, filename, showall): "Create the BibTeX file" self.filename = filename + '.bib' self.showall = showall self.added = 0 self.ignored = 0 self.entries = [] def parse(self): "Parse the BibTeX file and extract all entries." try: self.parsefile() except IOError: Trace.error('Error reading ' + self.filename + '; make sure the file exists and can be read.') def parsefile(self): "Parse the whole file." bibpath = InputPath(self.filename) if Options.lowmem: pos = FilePosition(bibpath.path) else: bulkfile = BulkFile(bibpath.path) text = ''.join(bulkfile.readall()) pos = TextPosition(text) while not pos.finished(): pos.skipspace() if pos.checkskip(','): pos.skipspace() self.parseentry(pos) def parseentry(self, pos): "Parse a single entry" for entry in BibEntry.instances: if entry.detect(pos): newentry = Cloner.clone(entry) newentry.parse(pos) if not newentry.isvisible(): return if self.showall or newentry.isreferenced(): self.entries.append(newentry) self.added += 1 else: Trace.debug('Ignored entry ' + unicode(newentry)) self.ignored += 1 return # Skip the whole line since it's a comment outside an entry pos.globincluding('\n').strip() def __unicode__(self): "String representation" string = self.filename + ': ' + unicode(self.added) + ' entries added, ' string += unicode(self.ignored) + ' entries ignored' return string class BibEntry(Container): "An entry in a BibTeX file" instances = [] def detect(self, pos): "Throw an error." Trace.error('Tried to detect() in ' + unicode(self)) def parse(self, pos): "Throw an error." Trace.error('Tried to parse() in ' + unicode(self)) def isvisible(self): "Return if the entry should be visible. Throws an error." Trace.error('Function isvisible() not implemented for ' + unicode(self)) def isreferenced(self): "Return if the entry is referenced. Throws an error." Trace.error('Function isreferenced() not implemented for ' + unicode(self)) def __unicode__(self): "Return a string representation" return 'BibTeX entry ' + self.__class__.__name__ class CommentEntry(BibEntry): "A simple comment." def detect(self, pos): "Detect the special entry" return pos.checkfor('%') def parse(self, pos): "Parse all consecutive comment lines." while pos.checkfor('%'): pos.globincluding('\n') def isvisible(self): "A comment entry is never visible." return False def __unicode__(self): "Return a string representation" return 'Comment' class SpecialEntry(BibEntry): "A special entry" types = ['@preamble', '@comment'] def __init__(self): self.contents = [] self.output = EmptyOutput() def detect(self, pos): "Detect the special entry" for type in self.types: if pos.checkforlower(type): return True return False def parse(self, pos): "Parse and ignore." self.type = 'special' pos.globincluding('{') pos.pushending('}') while not pos.finished(): if pos.checkfor('{'): self.parse(pos) else: pos.skipcurrent() pos.popending() def isvisible(self): "A special entry is never visible." return False def __unicode__(self): "Return a string representation" return self.type class StringEntry(SpecialEntry): "A string definition. The definition can later be used in other entries." parser = BibTagParser() start = '@string' key = None def detect(self, pos): "Detect the string definition." return pos.checkforlower(self.start) def parse(self, pos): "Parse a single tag, which will define a string." self.type = self.start if not self.checkstart(pos): return pos.skipspace() if not pos.checkskip('{'): Trace.error('Missing opening { in ' + unicode(self)) pos.globincluding('\n') return pos.pushending('}') (self.key, value) = self.parser.getkeyvalue(pos) BibTag.stringdefs[self.key] = value pos.popending('}') def checkstart(self, pos): "Check that the entry starts with @string." if not pos.checkskip('@'): Trace.error('Missing @ from elyxer.string definition') return False name = '@' + pos.globalpha() if not name.lower() == self.start.lower(): Trace.error('Invalid start @' + name +', missing ' + self.start + ' from elyxer.' + unicode(self)) pos.globincluding('\n') return False return True def __unicode__(self): "Return a printable representation." result = 'string definition' if self.key: result += ' for ' + self.key return result # More instances will be added later BibEntry.instances += [CommentEntry(), SpecialEntry(), StringEntry()] elyxer-1.2.5/src/elyxer/bib/__init__.py0000644000175000017500000000000012074107030017261 0ustar chennochennoelyxer-1.2.5/src/elyxer/proc/0000755000175000017500000000000012117175142015400 5ustar chennochennoelyxer-1.2.5/src/elyxer/proc/postprocess.py0000644000175000017500000000571412074107030020336 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20090324 # eLyXer postprocessor code class Postprocessor(object): "Postprocess a container keeping some context" stages = [] def __init__(self): self.stages = StageDict(Postprocessor.stages, self) self.current = None self.last = None def postprocess(self, next): "Postprocess a container and its contents." self.postrecursive(self.current) result = self.postcurrent(next) self.last = self.current self.current = next return result def postrecursive(self, container): "Postprocess the container contents recursively" if not hasattr(container, 'contents'): return if len(container.contents) == 0: return if hasattr(container, 'postprocess'): if not container.postprocess: return postprocessor = Postprocessor() contents = [] for element in container.contents: post = postprocessor.postprocess(element) if post: contents.append(post) # two rounds to empty the pipeline for i in range(2): post = postprocessor.postprocess(None) if post: contents.append(post) container.contents = contents def postcurrent(self, next): "Postprocess the current element taking into account next and last." stage = self.stages.getstage(self.current) if not stage: return self.current return stage.postprocess(self.last, self.current, next) class StageDict(object): "A dictionary of stages corresponding to classes" def __init__(self, classes, postprocessor): "Instantiate an element from elyxer.each class and store as a dictionary" instances = self.instantiate(classes, postprocessor) self.stagedict = dict([(x.processedclass, x) for x in instances]) def instantiate(self, classes, postprocessor): "Instantiate an element from elyxer.each class" stages = [x.__new__(x) for x in classes] for element in stages: element.__init__() element.postprocessor = postprocessor return stages def getstage(self, element): "Get the stage for a given element, if the type is in the dict" if not element.__class__ in self.stagedict: return None return self.stagedict[element.__class__] elyxer-1.2.5/src/elyxer/proc/process.py0000644000175000017500000000470712074107030017431 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20100714 # eLyXer: internal processing code from elyxer.util.trace import * from elyxer.gen.header import * from elyxer.ref.index import * from elyxer.gen.layout import * from elyxer.proc.postprocess import * class Processor(object): "Process a container and its contents." prestages = [] skipfiltered = ['LyXHeader', 'LyXFooter', 'Title', 'Author', 'TableOfContents'] def __init__(self, filtering): "Set filtering mode (to skip postprocessing)." "With filtering on, the classes in skipfiltered are not processed at all." self.filtering = filtering self.postprocessor = Postprocessor() def process(self, container): "Do the whole processing on a container." if self.filtering and container.__class__.__name__ in self.skipfiltered: return None container = self.preprocess(container) self.processcontainer(container) if not container: # do not postprocess empty containers from elyxer.here return container return self.postprocess(container) def preprocess(self, root): "Preprocess a root container with all prestages." if not root: return None for stage in self.prestages: root = stage.preprocess(root) if not root: return None return root def processcontainer(self, container): "Process a container and its contents, recursively." if not container: return for element in container.contents: self.processcontainer(element) container.process() def postprocess(self, container): "Postprocess a container, unless filtering is on." if self.filtering: return container return self.postprocessor.postprocess(container) elyxer-1.2.5/src/elyxer/proc/formulaproc.py0000644000175000017500000000576712074107030020313 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20101111 # eLyXer formulae processing. from elyxer.util.trace import * from elyxer.conf.config import * from elyxer.maths.bits import * class MathsProcessor(object): "A processor for a maths construction inside the FormulaProcessor." def process(self, contents, index): "Process an element inside a formula." Trace.error('Unimplemented process() in ' + unicode(self)) def __unicode__(self): "Return a printable description." return 'Maths processor ' + self.__class__.__name__ class FormulaProcessor(object): "A processor specifically for formulas." processors = [] def process(self, bit): "Process the contents of every formula bit, recursively." self.processcontents(bit) self.processinsides(bit) self.traversewhole(bit) def processcontents(self, bit): "Process the contents of a formula bit." if not isinstance(bit, FormulaBit): return bit.process() for element in bit.contents: self.processcontents(element) def processinsides(self, bit): "Process the insides (limits, brackets) in a formula bit." if not isinstance(bit, FormulaBit): return for index, element in enumerate(bit.contents): for processor in self.processors: processor.process(bit.contents, index) # continue with recursive processing self.processinsides(element) def traversewhole(self, formula): "Traverse over the contents to alter variables and space units." last = None for bit, contents in self.traverse(formula): if bit.type == 'alpha': self.italicize(bit, contents) elif bit.type == 'font' and last and last.type == 'number': bit.contents.insert(0, FormulaConstant(u' ')) last = bit def traverse(self, bit): "Traverse a formula and yield a flattened structure of (bit, list) pairs." for element in bit.contents: if hasattr(element, 'type') and element.type: yield (element, bit.contents) elif isinstance(element, FormulaBit): for pair in self.traverse(element): yield pair def italicize(self, bit, contents): "Italicize the given bit of text." index = contents.index(bit) contents[index] = TaggedBit().complete([bit], 'i') elyxer-1.2.5/src/elyxer/proc/__init__.py0000644000175000017500000000000012074107030017470 0ustar chennochennoelyxer-1.2.5/src/elyxer/main/0000755000175000017500000000000012117175142015361 5ustar chennochennoelyxer-1.2.5/src/elyxer/main/convert.py0000644000175000017500000001355412074107030017414 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20090919 # eLyXer converter # http://www.nongnu.org/elyxer/ import os.path from elyxer.io.fileline import * from elyxer.util.options import * from elyxer.gen.factory import * from elyxer.gen.toc import * from elyxer.gen.inset import * from elyxer.gen.basket import * from elyxer.gen.integral import * from elyxer.gen.splitpart import * from elyxer.proc.process import * from elyxer.maths.postformula import * class eLyXerConverter(object): "Converter for a document in a lyx file. Places all output in a given basket." def __init__(self): self.filtering = False def setio(self, ioparser): "Set the InOutParser" self.reader = ioparser.getreader() self.basket = self.getbasket() self.basket.setwriter(ioparser.getwriter()) return self def getbasket(self): "Get the appropriate basket for the current options." if Options.tocfor: if Options.splitpart: return SplitTOCBasket() return TOCBasket() if Options.splitpart: return SplitPartBasket() if Options.memory: return MemoryBasket() return WriterBasket() def embed(self, reader): "Embed the results from elyxer.a reader into a memory basket." "Header and footer are ignored. Useful for embedding one document inside another." self.filtering = True self.reader = reader self.basket = MemoryBasket() return self def convert(self): "Perform the conversion for the document" try: self.processcontents() except (Exception): version = '[eLyXer version ' + GeneralConfig.version['number'] version += ' (' + GeneralConfig.version['date'] + ') in ' version += Options.location + '] ' Trace.error(version) Trace.error('Conversion failed at ' + self.reader.currentline()) raise def processcontents(self): "Parse the contents and write it by containers" factory = ContainerFactory() processor = Processor(self.filtering) while not self.reader.finished(): container = factory.createcontainer(self.reader) result = processor.process(container) self.writecontainer(result) result = processor.postprocess(None) self.writecontainer(result) if not self.filtering: self.basket.finish() def writecontainer(self, container): "Write each container to the correct basket." if not container: return includes = container.searchremove(IncludeInset) self.basket.write(container) # recursive processing for IncludeInset for include in includes: for element in include.contents: self.basket.write(element) def getcontents(self): "Return the contents of the basket." return self.basket.contents def __unicode__(self): "Printable representation." string = 'Converter with filtering ' + unicode(self.filtering) string += ' and basket ' + unicode(self.basket) return string class InOutParser(object): "Parse in and out arguments" def __init__(self): self.filein = sys.stdin self.fileout = sys.stdout def parse(self, args): "Parse command line arguments" self.filein = sys.stdin self.fileout = sys.stdout if len(args) < 2: Trace.quietmode = True if len(args) > 0: self.filein = args[0] del args[0] self.readdir(self.filein, 'directory') else: Options.directory = '.' if len(args) > 0: self.fileout = args[0] del args[0] self.readdir(self.fileout, 'destdirectory') else: Options.destdirectory = '.' if len(args) > 0: raise Exception('Unused arguments: ' + unicode(args)) return self def getreader(self): "Get the resulting reader." return LineReader(self.filein) def getwriter(self): "Get the resulting writer." return LineWriter(self.fileout) def readdir(self, filename, diroption): "Read the current directory if needed" if getattr(Options, diroption) != None: return setattr(Options, diroption, os.path.dirname(filename)) if getattr(Options, diroption) == '': setattr(Options, diroption, '.') class NullWriter(object): "A writer that goes nowhere." def write(self, list): "Do nothing." pass class ConverterFactory(object): "Create a converter fit for converting a filename and embedding the result." def create(self, container): "Create a converter for a given container, with filename" " and possibly other parameters." fullname = os.path.join(Options.directory, container.filename) reader = LineReader(container.filename) if 'firstline' in container.lstparams: reader.setstart(int(container.lstparams['firstline'])) if 'lastline' in container.lstparams: reader.setend(int(container.lstparams['lastline'])) return eLyXerConverter().embed(reader) IncludeInset.converterfactory = ConverterFactory() def convertdoc(args): "Read a whole document from the command line and write it." Options().parseoptions(args) ioparser = InOutParser().parse(args) converter = eLyXerConverter().setio(ioparser) converter.convert() def main(): "Main function, called if invoked from the command line" convertdoc(list(sys.argv)) elyxer-1.2.5/src/elyxer/main/__init__.py0000644000175000017500000000000012074107030017451 0ustar chennochennoelyxer-1.2.5/src/elyxer/conf/0000755000175000017500000000000012117175142015362 5ustar chennochennoelyxer-1.2.5/src/elyxer/conf/fileconfig.py0000644000175000017500000001714212074107030020037 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20090203 # eLyXer parsers import datetime from elyxer.util.trace import Trace from elyxer.io.fileline import * class ConfigReader(object): "Read a configuration file" escapes = [ ('\n', ' '), (':', ':'), ('#', '#'), ('[', '['), (']', ']'), ('&', '&'), ] def __init__(self, filename): self.reader = LineReader(filename) self.objects = dict() self.section = None self.serializer = ConfigSerializer(ConfigReader.escapes) def parse(self): "Parse the whole file" while not self.reader.finished(): self.parseline(self.reader.currentline()) self.reader.nextline() return self def parseline(self, line): "Parse a single line" if line == '': return if line.startswith('#'): return if line.startswith('['): self.parsesection(line) else: self.parseparam(line) def parsesection(self, line): "Parse a section header" if not line.endswith(']'): Trace.error('Incorrect section header ' + line) return name = line[1:-1] self.section = name self.objects[name] = dict() def parseparam(self, line): "Parse a parameter line" if len(line.strip()) == 0: return if not ':' in line: Trace.error('Invalid configuration parameter ' + line) return pieces = line.split(':', 1) key = self.serializer.unescape(pieces[0]) value = self.serializer.deserialize(pieces[1]) object = self.objects[self.section] if key in object: Trace.error('Repeated key ' + key + ' for ' + value) object[key] = value class ConfigWriter(object): "Write a configuration file" def __init__(self, writer): self.writer = writer self.serializer = ConfigSerializer(ConfigReader.escapes) def writeall(self, types): "Write a list of configuration objects given their class names" for type in types: object = type.__new__(type) self.write(object) def write(self, object): "Write a configuration object" for attr in dir(object): self.writeattr(object, attr) def writeattr(self, object, attr): "Write an attribute" if attr.startswith('__'): return self.writesection(object, attr) valuedict = getattr(object, attr) if not isinstance(valuedict, dict): Trace.error('Unknown config type ' + valuedict.__class__.__name__ + ' in ' + attr) return names = valuedict.keys() names.sort() for name in names: value = self.serializer.serialize(valuedict[name]) self.writer.writeline(self.serializer.escape(name) + ':' + value) def writesection(self, object, attr): "Write a new section" self.writer.writeline('') header = '[' + object.__class__.__name__ + '.' + attr + ']' self.writer.writeline(header) class ConfigToPython(ConfigWriter): "Exports a number of dictionaries from elyxer.a config file to a Python class" escapes = [ ('\\', '\\\\'), ('\n', '\\n'), ('\'', '\\\'') ] def __init__(self, writer): self.writer = writer self.serializer = ConfigSerializer(ConfigToPython.escapes) def write(self, objects): "Write the whole set of objects" self.writer.writeline('#! /usr/bin/env python') self.writer.writeline('# -*- coding: utf-8 -*-') self.writer.writeline('') self.writer.writeline('# eLyXer configuration') self.writer.writeline('# autogenerated from elyxer.config file on ' + datetime.date.today().isoformat()) self.writer.writeline('') classes = self.sort(objects) names = classes.keys() names.sort() for classname in names: self.writeclass(classname, classes[classname]) def writeclass(self, name, current): "Write an object class" self.writer.writeline('class ' + name + '(object):') self.writer.writeline(' "Configuration class from elyxer.config file"') self.writer.writeline('') names = current.keys() names.sort() for attrname in names: self.writeattr(attrname, current[attrname]) def writeattr(self, name, contents): "Write a dictionary attribute" if not isinstance(contents, dict): Trace.error('Unknown config type ' + contents.__class__.__name__) return self.writer.writestring(' ' + name + ' = ') self.writer.writeline('{') string = ' ' names = contents.keys() names.sort() for name in names: value = self.serializer.pyserialize(contents[name]) piece = 'u\'' + self.serializer.escape(name) + '\':' + value + ', ' string = self.append(string, piece) self.writer.writeline(string) self.writer.writeline(' }') self.writer.writeline('') def append(self, string, piece): "Write a piece to the string or to disk" if len(string + piece) > 80: self.writer.writeline(string) string = ' ' return string + piece def sort(self, objects): "Sort the objects into classes" classes = dict() for name, object in objects.iteritems(): pieces = name.split('.') if len(pieces) != 2: Trace.error('Wrong method name ' + name) return classname = pieces[0] methodname = pieces[1] if not classname in classes: classes[classname] = dict() currentclass = classes[classname] currentclass[methodname] = object return classes class ConfigSerializer(object): "Serialize and deserialize config object" def __init__(self, escapes): self.escapes = escapes def serialize(self, object): "Convert an object to a string" if not isinstance(object, list): return self.escape(object) result = '' for value in object: result += self.escape(value) + ',' if len(object) > 0: result = result[:-1] return '[' + result + ']' def pyserialize(self, object): "Convert an object to a Python definition" if not isinstance(object, list): return 'u\'' + self.escape(object) + '\'' result = '[u\'' for value in object: result += self.escape(value) + '\',u\'' if len(object) > 0: result = result[:-2] return result + ']' def escape(self, string): "Escape a string or a list" for escape, value in self.escapes: if escape in string: string = string.replace(escape, value) return string def deserialize(self, string): "Parse a string into an object (string or list)" if not string.startswith('[') or not string.endswith(']'): return self.unescape(string) result = [] contents = string[1:-1].split(',') for piece in contents: result.append(self.unescape(piece)) return result def unescape(self, string): "Remove the escaping from elyxer.a string." if string.startswith('&#x') and string.endswith(';'): # single unicode character return unichr(int('0x' + string[3:-1], 16)) for escape, value in self.escapes: string = string.replace(value, escape) return string elyxer-1.2.5/src/elyxer/conf/config.py0000644000175000017500000014251512117174753017220 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer configuration # autogenerated from elyxer.config file on 2013-03-10 class BibStylesConfig(object): "Configuration class from elyxer.config file" abbrvnat = { u'@article':u'$authors. $title. $journal,{ {$volume:}$pages,} $month $year.{ doi: $doi.}{ URL $url.}{ $note.}', u'cite':u'$surname($year)', u'default':u'$authors. $title. $publisher, $year.{ URL $url.}{ $note.}', } alpha = { u'@article':u'$authors. $title.{ $journal{, {$volume}{($number)}}{: $pages}{, $year}.}{ $url.}{ $filename.}{ $note.}', u'cite':u'$Sur$YY', u'default':u'$authors. $title.{ $journal,} $year.{ $url.}{ $filename.}{ $note.}', } authordate2 = { u'@article':u'$authors. $year. $title. $journal, $volume($number), $pages.{ URL $url.}{ $note.}', u'@book':u'$authors. $year. $title. $publisher.{ URL $url.}{ $note.}', u'cite':u'$surname, $year', u'default':u'$authors. $year. $title. $publisher.{ URL $url.}{ $note.}', } default = { u'@article':u'$authors: “$title”, $journal,{ pp. $pages,} $year.{ URL $url.}{ $note.}', u'@book':u'{$authors: }$title{ ($editor, ed.)}.{{ $publisher,} $year.}{ URL $url.}{ $note.}', u'@booklet':u'$authors: $title.{{ $publisher,} $year.}{ URL $url.}{ $note.}', u'@conference':u'$authors: “$title”, $journal,{ pp. $pages,} $year.{ URL $url.}{ $note.}', u'@inbook':u'$authors: $title.{{ $publisher,} $year.}{ URL $url.}{ $note.}', u'@incollection':u'$authors: $title{ in $booktitle{ ($editor, ed.)}}.{{ $publisher,} $year.}{ URL $url.}{ $note.}', u'@inproceedings':u'$authors: “$title”, $booktitle,{ pp. $pages,} $year.{ URL $url.}{ $note.}', u'@manual':u'$authors: $title.{{ $publisher,} $year.}{ URL $url.}{ $note.}', u'@mastersthesis':u'$authors: $title.{{ $publisher,} $year.}{ URL $url.}{ $note.}', u'@misc':u'$authors: $title.{{ $publisher,}{ $howpublished,} $year.}{ URL $url.}{ $note.}', u'@phdthesis':u'$authors: $title.{{ $publisher,} $year.}{ URL $url.}{ $note.}', u'@proceedings':u'$authors: “$title”, $journal,{ pp. $pages,} $year.{ URL $url.}{ $note.}', u'@techreport':u'$authors: $title, $year.{ URL $url.}{ $note.}', u'@unpublished':u'$authors: “$title”, $journal, $year.{ URL $url.}{ $note.}', u'cite':u'$index', u'default':u'$authors: $title.{{ $publisher,} $year.}{ URL $url.}{ $note.}', } defaulttags = { u'YY':u'??', u'authors':u'', u'surname':u'', } ieeetr = { u'@article':u'$authors, “$title”, $journal, vol. $volume, no. $number, pp. $pages, $year.{ URL $url.}{ $note.}', u'@book':u'$authors, $title. $publisher, $year.{ URL $url.}{ $note.}', u'cite':u'$index', u'default':u'$authors, “$title”. $year.{ URL $url.}{ $note.}', } plain = { u'@article':u'$authors. $title.{ $journal{, {$volume}{($number)}}{:$pages}{, $year}.}{ URL $url.}{ $note.}', u'@book':u'$authors. $title. $publisher,{ $month} $year.{ URL $url.}{ $note.}', u'@incollection':u'$authors. $title.{ In $booktitle {($editor, ed.)}.} $publisher,{ $month} $year.{ URL $url.}{ $note.}', u'@inproceedings':u'$authors. $title. { $booktitle{, {$volume}{($number)}}{:$pages}{, $year}.}{ URL $url.}{ $note.}', u'cite':u'$index', u'default':u'{$authors. }$title.{{ $publisher,} $year.}{ URL $url.}{ $note.}', } vancouver = { u'@article':u'$authors. $title. $journal, $year{;{$volume}{($number)}{:$pages}}.{ URL: $url.}{ $note.}', u'@book':u'$authors. $title. {$publisher, }$year.{ URL: $url.}{ $note.}', u'cite':u'$index', u'default':u'$authors. $title; {$publisher, }$year.{ $howpublished.}{ URL: $url.}{ $note.}', } class BibTeXConfig(object): "Configuration class from elyxer.config file" replaced = { u'--':u'—', u'..':u'.', } class ContainerConfig(object): "Configuration class from elyxer.config file" endings = { u'Align':u'\\end_layout', u'BarredText':u'\\bar', u'BoldText':u'\\series', u'Cell':u'':u'>', } html = { u'/>':u'>', } iso885915 = { u' ':u' ', u' ':u' ', u' ':u' ', } nonunicode = { u' ':u' ', } class FormulaConfig(object): "Configuration class from elyxer.config file" alphacommands = { u'\\AA':u'Å', u'\\AE':u'Æ', u'\\AmS':u'AmS', u'\\Angstroem':u'Å', u'\\DH':u'Ð', u'\\Koppa':u'Ϟ', u'\\L':u'Ł', u'\\Micro':u'µ', u'\\O':u'Ø', u'\\OE':u'Œ', u'\\Sampi':u'Ϡ', u'\\Stigma':u'Ϛ', u'\\TH':u'Þ', u'\\aa':u'å', u'\\ae':u'æ', u'\\alpha':u'α', u'\\beta':u'β', u'\\delta':u'δ', u'\\dh':u'ð', u'\\digamma':u'ϝ', u'\\epsilon':u'ϵ', u'\\eta':u'η', u'\\eth':u'ð', u'\\gamma':u'γ', u'\\i':u'ı', u'\\imath':u'ı', u'\\iota':u'ι', u'\\j':u'ȷ', u'\\jmath':u'ȷ', u'\\kappa':u'κ', u'\\koppa':u'ϟ', u'\\l':u'ł', u'\\lambda':u'λ', u'\\mu':u'μ', u'\\nu':u'ν', u'\\o':u'ø', u'\\oe':u'œ', u'\\omega':u'ω', u'\\phi':u'φ', u'\\pi':u'π', u'\\psi':u'ψ', u'\\rho':u'ρ', u'\\sampi':u'ϡ', u'\\sigma':u'σ', u'\\ss':u'ß', u'\\stigma':u'ϛ', u'\\tau':u'τ', u'\\tcohm':u'Ω', u'\\textcrh':u'ħ', u'\\th':u'þ', u'\\theta':u'θ', u'\\upsilon':u'υ', u'\\varDelta':u'∆', u'\\varGamma':u'Γ', u'\\varLambda':u'Λ', u'\\varOmega':u'Ω', u'\\varPhi':u'Φ', u'\\varPi':u'Π', u'\\varPsi':u'Ψ', u'\\varSigma':u'Σ', u'\\varTheta':u'Θ', u'\\varUpsilon':u'Υ', u'\\varXi':u'Ξ', u'\\varbeta':u'ϐ', u'\\varepsilon':u'ε', u'\\varkappa':u'ϰ', u'\\varphi':u'φ', u'\\varpi':u'ϖ', u'\\varrho':u'ϱ', u'\\varsigma':u'ς', u'\\vartheta':u'ϑ', u'\\xi':u'ξ', u'\\zeta':u'ζ', } array = { u'begin':u'\\begin', u'cellseparator':u'&', u'end':u'\\end', u'rowseparator':u'\\\\', } bigbrackets = { u'(':[u'⎛',u'⎜',u'⎝',], u')':[u'⎞',u'⎟',u'⎠',], u'[':[u'⎡',u'⎢',u'⎣',], u']':[u'⎤',u'⎥',u'⎦',], u'{':[u'⎧',u'⎪',u'⎨',u'⎩',], u'|':[u'|',], u'}':[u'⎫',u'⎪',u'⎬',u'⎭',], u'∥':[u'∥',], } bigsymbols = { u'∑':[u'⎲',u'⎳',], u'∫':[u'⌠',u'⌡',], } bracketcommands = { u'\\left':u'span class="symbol"', u'\\left.':u'', u'\\middle':u'span class="symbol"', u'\\right':u'span class="symbol"', u'\\right.':u'', } combiningfunctions = { u'\\"':u'̈', u'\\\'':u'́', u'\\^':u'̂', u'\\`':u'̀', u'\\acute':u'́', u'\\bar':u'̄', u'\\breve':u'̆', u'\\c':u'̧', u'\\check':u'̌', u'\\dddot':u'⃛', u'\\ddot':u'̈', u'\\dot':u'̇', u'\\grave':u'̀', u'\\hat':u'̂', u'\\mathring':u'̊', u'\\overleftarrow':u'⃖', u'\\overrightarrow':u'⃗', u'\\r':u'̊', u'\\s':u'̩', u'\\textcircled':u'⃝', u'\\textsubring':u'̥', u'\\tilde':u'̃', u'\\v':u'̌', u'\\vec':u'⃗', u'\\~':u'̃', } commands = { u'\\ ':u' ', u'\\!':u'', u'\\#':u'#', u'\\$':u'$', u'\\%':u'%', u'\\&':u'&', u'\\,':u' ', u'\\:':u' ', u'\\;':u' ', u'\\AC':u'∿', u'\\APLcomment':u'⍝', u'\\APLdownarrowbox':u'⍗', u'\\APLinput':u'⍞', u'\\APLinv':u'⌹', u'\\APLleftarrowbox':u'⍇', u'\\APLlog':u'⍟', u'\\APLrightarrowbox':u'⍈', u'\\APLuparrowbox':u'⍐', u'\\Box':u'□', u'\\Bumpeq':u'≎', u'\\CIRCLE':u'●', u'\\Cap':u'⋒', u'\\CapitalDifferentialD':u'ⅅ', u'\\CheckedBox':u'☑', u'\\Circle':u'○', u'\\Coloneqq':u'⩴', u'\\ComplexI':u'ⅈ', u'\\ComplexJ':u'ⅉ', u'\\Corresponds':u'≙', u'\\Cup':u'⋓', u'\\Delta':u'Δ', u'\\Diamond':u'◇', u'\\Diamondblack':u'◆', u'\\Diamonddot':u'⟐', u'\\DifferentialD':u'ⅆ', u'\\Downarrow':u'⇓', u'\\EUR':u'€', u'\\Euler':u'ℇ', u'\\ExponetialE':u'ⅇ', u'\\Finv':u'Ⅎ', u'\\Game':u'⅁', u'\\Gamma':u'Γ', u'\\Im':u'ℑ', u'\\Join':u'⨝', u'\\LEFTCIRCLE':u'◖', u'\\LEFTcircle':u'◐', u'\\LHD':u'◀', u'\\Lambda':u'Λ', u'\\Lbag':u'⟅', u'\\Leftarrow':u'⇐', u'\\Lleftarrow':u'⇚', u'\\Longleftarrow':u'⟸', u'\\Longleftrightarrow':u'⟺', u'\\Longrightarrow':u'⟹', u'\\Lparen':u'⦅', u'\\Lsh':u'↰', u'\\Mapsfrom':u'⇐|', u'\\Mapsto':u'|⇒', u'\\Omega':u'Ω', u'\\P':u'¶', u'\\Phi':u'Φ', u'\\Pi':u'Π', u'\\Pr':u'Pr', u'\\Psi':u'Ψ', u'\\Qoppa':u'Ϙ', u'\\RHD':u'▶', u'\\RIGHTCIRCLE':u'◗', u'\\RIGHTcircle':u'◑', u'\\Rbag':u'⟆', u'\\Re':u'ℜ', u'\\Rparen':u'⦆', u'\\Rrightarrow':u'⇛', u'\\Rsh':u'↱', u'\\S':u'§', u'\\Sigma':u'Σ', u'\\Square':u'☐', u'\\Subset':u'⋐', u'\\Sun':u'☉', u'\\Supset':u'⋑', u'\\Theta':u'Θ', u'\\Uparrow':u'⇑', u'\\Updownarrow':u'⇕', u'\\Upsilon':u'Υ', u'\\Vdash':u'⊩', u'\\Vert':u'∥', u'\\Vvdash':u'⊪', u'\\XBox':u'☒', u'\\Xi':u'Ξ', u'\\Yup':u'⅄', u'\\\\':u'
', u'\\_':u'_', u'\\aleph':u'ℵ', u'\\amalg':u'∐', u'\\anchor':u'⚓', u'\\angle':u'∠', u'\\aquarius':u'♒', u'\\arccos':u'arccos', u'\\arcsin':u'arcsin', u'\\arctan':u'arctan', u'\\arg':u'arg', u'\\aries':u'♈', u'\\arrowbullet':u'➢', u'\\ast':u'∗', u'\\asymp':u'≍', u'\\backepsilon':u'∍', u'\\backprime':u'‵', u'\\backsimeq':u'⋍', u'\\backslash':u'\\', u'\\ballotx':u'✗', u'\\barwedge':u'⊼', u'\\because':u'∵', u'\\beth':u'ℶ', u'\\between':u'≬', u'\\bigcap':u'∩', u'\\bigcirc':u'○', u'\\bigcup':u'∪', u'\\bigodot':u'⊙', u'\\bigoplus':u'⊕', u'\\bigotimes':u'⊗', u'\\bigsqcup':u'⊔', u'\\bigstar':u'★', u'\\bigtriangledown':u'▽', u'\\bigtriangleup':u'△', u'\\biguplus':u'⊎', u'\\bigvee':u'∨', u'\\bigwedge':u'∧', u'\\biohazard':u'☣', u'\\blacklozenge':u'⧫', u'\\blacksmiley':u'☻', u'\\blacksquare':u'■', u'\\blacktriangle':u'▲', u'\\blacktriangledown':u'▼', u'\\blacktriangleleft':u'◂', u'\\blacktriangleright':u'▶', u'\\blacktriangleup':u'▴', u'\\bot':u'⊥', u'\\bowtie':u'⋈', u'\\box':u'▫', u'\\boxast':u'⧆', u'\\boxbar':u'◫', u'\\boxbox':u'⧈', u'\\boxbslash':u'⧅', u'\\boxcircle':u'⧇', u'\\boxdot':u'⊡', u'\\boxminus':u'⊟', u'\\boxplus':u'⊞', u'\\boxslash':u'⧄', u'\\boxtimes':u'⊠', u'\\bullet':u'•', u'\\bumpeq':u'≏', u'\\cancer':u'♋', u'\\cap':u'∩', u'\\capricornus':u'♑', u'\\cat':u'⁀', u'\\cdot':u'⋅', u'\\cdots':u'⋯', u'\\cent':u'¢', u'\\centerdot':u'∙', u'\\checkmark':u'✓', u'\\chi':u'χ', u'\\circ':u'○', u'\\circeq':u'≗', u'\\circlearrowleft':u'↺', u'\\circlearrowright':u'↻', u'\\circledR':u'®', u'\\circledast':u'⊛', u'\\circledbslash':u'⦸', u'\\circledcirc':u'⊚', u'\\circleddash':u'⊝', u'\\circledgtr':u'⧁', u'\\circledless':u'⧀', u'\\clubsuit':u'♣', u'\\coloneqq':u'≔', u'\\complement':u'∁', u'\\cong':u'≅', u'\\coprod':u'∐', u'\\copyright':u'©', u'\\cos':u'cos', u'\\cosh':u'cosh', u'\\cot':u'cot', u'\\coth':u'coth', u'\\csc':u'csc', u'\\cup':u'∪', u'\\curlyvee':u'⋎', u'\\curlywedge':u'⋏', u'\\curvearrowleft':u'↶', u'\\curvearrowright':u'↷', u'\\dag':u'†', u'\\dagger':u'†', u'\\daleth':u'ℸ', u'\\dashleftarrow':u'⇠', u'\\dashv':u'⊣', u'\\ddag':u'‡', u'\\ddagger':u'‡', u'\\ddots':u'⋱', u'\\deg':u'deg', u'\\det':u'det', u'\\diagdown':u'╲', u'\\diagup':u'╱', u'\\diameter':u'⌀', u'\\diamond':u'◇', u'\\diamondsuit':u'♦', u'\\dim':u'dim', u'\\div':u'÷', u'\\divideontimes':u'⋇', u'\\dotdiv':u'∸', u'\\doteq':u'≐', u'\\doteqdot':u'≑', u'\\dotplus':u'∔', u'\\dots':u'…', u'\\doublebarwedge':u'⌆', u'\\downarrow':u'↓', u'\\downdownarrows':u'⇊', u'\\downharpoonleft':u'⇃', u'\\downharpoonright':u'⇂', u'\\dsub':u'⩤', u'\\earth':u'♁', u'\\eighthnote':u'♪', u'\\ell':u'ℓ', u'\\emptyset':u'∅', u'\\eqcirc':u'≖', u'\\eqcolon':u'≕', u'\\eqsim':u'≂', u'\\euro':u'€', u'\\exists':u'∃', u'\\exp':u'exp', u'\\fallingdotseq':u'≒', u'\\fcmp':u'⨾', u'\\female':u'♀', u'\\flat':u'♭', u'\\forall':u'∀', u'\\fourth':u'⁗', u'\\frown':u'⌢', u'\\frownie':u'☹', u'\\gcd':u'gcd', u'\\gemini':u'♊', u'\\geq)':u'≥', u'\\geqq':u'≧', u'\\geqslant':u'≥', u'\\gets':u'←', u'\\gg':u'≫', u'\\ggg':u'⋙', u'\\gimel':u'ℷ', u'\\gneqq':u'≩', u'\\gnsim':u'⋧', u'\\gtrdot':u'⋗', u'\\gtreqless':u'⋚', u'\\gtreqqless':u'⪌', u'\\gtrless':u'≷', u'\\gtrsim':u'≳', u'\\guillemotleft':u'«', u'\\guillemotright':u'»', u'\\hbar':u'ℏ', u'\\heartsuit':u'♥', u'\\hfill':u' ', u'\\hom':u'hom', u'\\hookleftarrow':u'↩', u'\\hookrightarrow':u'↪', u'\\hslash':u'ℏ', u'\\idotsint':u'∫⋯∫', u'\\iiint':u'', u'\\iint':u'', u'\\imath':u'ı', u'\\inf':u'inf', u'\\infty':u'∞', u'\\intercal':u'⊺', u'\\interleave':u'⫴', u'\\invamp':u'⅋', u'\\invneg':u'⌐', u'\\jmath':u'ȷ', u'\\jupiter':u'♃', u'\\ker':u'ker', u'\\land':u'∧', u'\\landupint':u'', u'\\lang':u'⟪', u'\\langle':u'⟨', u'\\lblot':u'⦉', u'\\lbrace':u'{', u'\\lbrace)':u'{', u'\\lbrack':u'[', u'\\lceil':u'⌈', u'\\ldots':u'…', u'\\leadsto':u'⇝', u'\\leftarrow)':u'←', u'\\leftarrowtail':u'↢', u'\\leftarrowtobar':u'⇤', u'\\leftharpoondown':u'↽', u'\\leftharpoonup':u'↼', u'\\leftleftarrows':u'⇇', u'\\leftleftharpoons':u'⥢', u'\\leftmoon':u'☾', u'\\leftrightarrow':u'↔', u'\\leftrightarrows':u'⇆', u'\\leftrightharpoons':u'⇋', u'\\leftthreetimes':u'⋋', u'\\leo':u'♌', u'\\leq)':u'≤', u'\\leqq':u'≦', u'\\leqslant':u'≤', u'\\lessdot':u'⋖', u'\\lesseqgtr':u'⋛', u'\\lesseqqgtr':u'⪋', u'\\lessgtr':u'≶', u'\\lesssim':u'≲', u'\\lfloor':u'⌊', u'\\lg':u'lg', u'\\lgroup':u'⟮', u'\\lhd':u'⊲', u'\\libra':u'♎', u'\\lightning':u'↯', u'\\limg':u'⦇', u'\\liminf':u'liminf', u'\\limsup':u'limsup', u'\\ll':u'≪', u'\\llbracket':u'⟦', u'\\llcorner':u'⌞', u'\\lll':u'⋘', u'\\ln':u'ln', u'\\lneqq':u'≨', u'\\lnot':u'¬', u'\\lnsim':u'⋦', u'\\log':u'log', u'\\longleftarrow':u'⟵', u'\\longleftrightarrow':u'⟷', u'\\longmapsto':u'⟼', u'\\longrightarrow':u'⟶', u'\\looparrowleft':u'↫', u'\\looparrowright':u'↬', u'\\lor':u'∨', u'\\lozenge':u'◊', u'\\lrcorner':u'⌟', u'\\ltimes':u'⋉', u'\\lyxlock':u'', u'\\male':u'♂', u'\\maltese':u'✠', u'\\mapsfrom':u'↤', u'\\mapsto':u'↦', u'\\mathcircumflex':u'^', u'\\max':u'max', u'\\measuredangle':u'∡', u'\\medbullet':u'⚫', u'\\medcirc':u'⚪', u'\\mercury':u'☿', u'\\mho':u'℧', u'\\mid':u'∣', u'\\min':u'min', u'\\models':u'⊨', u'\\mp':u'∓', u'\\multimap':u'⊸', u'\\nLeftarrow':u'⇍', u'\\nLeftrightarrow':u'⇎', u'\\nRightarrow':u'⇏', u'\\nVDash':u'⊯', u'\\nabla':u'∇', u'\\napprox':u'≉', u'\\natural':u'♮', u'\\ncong':u'≇', u'\\nearrow':u'↗', u'\\neg':u'¬', u'\\neg)':u'¬', u'\\neptune':u'♆', u'\\nequiv':u'≢', u'\\newline':u'
', u'\\nexists':u'∄', u'\\ngeqslant':u'≱', u'\\ngtr':u'≯', u'\\ngtrless':u'≹', u'\\ni':u'∋', u'\\ni)':u'∋', u'\\nleftarrow':u'↚', u'\\nleftrightarrow':u'↮', u'\\nleqslant':u'≰', u'\\nless':u'≮', u'\\nlessgtr':u'≸', u'\\nmid':u'∤', u'\\nolimits':u'', u'\\nonumber':u'', u'\\not':u'¬', u'\\not<':u'≮', u'\\not=':u'≠', u'\\not>':u'≯', u'\\notbackslash':u'⍀', u'\\notin':u'∉', u'\\notni':u'∌', u'\\notslash':u'⌿', u'\\nparallel':u'∦', u'\\nprec':u'⊀', u'\\nrightarrow':u'↛', u'\\nsim':u'≁', u'\\nsimeq':u'≄', u'\\nsqsubset':u'⊏̸', u'\\nsubseteq':u'⊈', u'\\nsucc':u'⊁', u'\\nsucccurlyeq':u'⋡', u'\\nsupset':u'⊅', u'\\nsupseteq':u'⊉', u'\\ntriangleleft':u'⋪', u'\\ntrianglelefteq':u'⋬', u'\\ntriangleright':u'⋫', u'\\ntrianglerighteq':u'⋭', u'\\nvDash':u'⊭', u'\\nvdash':u'⊬', u'\\nwarrow':u'↖', u'\\odot':u'⊙', u'\\officialeuro':u'€', u'\\oiiint':u'', u'\\oiint':u'', u'\\oint':u'', u'\\ointclockwise':u'', u'\\ointctrclockwise':u'', u'\\ominus':u'⊖', u'\\oplus':u'⊕', u'\\oslash':u'⊘', u'\\otimes':u'⊗', u'\\owns':u'∋', u'\\parallel':u'∥', u'\\partial':u'∂', u'\\pencil':u'✎', u'\\perp':u'⊥', u'\\pisces':u'♓', u'\\pitchfork':u'⋔', u'\\pluto':u'♇', u'\\pm':u'±', u'\\pointer':u'➪', u'\\pointright':u'☞', u'\\pounds':u'£', u'\\prec':u'≺', u'\\preccurlyeq':u'≼', u'\\preceq':u'≼', u'\\precsim':u'≾', u'\\prime':u'′', u'\\prompto':u'∝', u'\\qoppa':u'ϙ', u'\\qquad':u' ', u'\\quad':u' ', u'\\quarternote':u'♩', u'\\radiation':u'☢', u'\\rang':u'⟫', u'\\rangle':u'⟩', u'\\rblot':u'⦊', u'\\rbrace':u'}', u'\\rbrace)':u'}', u'\\rbrack':u']', u'\\rceil':u'⌉', u'\\recycle':u'♻', u'\\rfloor':u'⌋', u'\\rgroup':u'⟯', u'\\rhd':u'⊳', u'\\rightangle':u'∟', u'\\rightarrow)':u'→', u'\\rightarrowtail':u'↣', u'\\rightarrowtobar':u'⇥', u'\\rightharpoondown':u'⇁', u'\\rightharpoonup':u'⇀', u'\\rightharpooondown':u'⇁', u'\\rightharpooonup':u'⇀', u'\\rightleftarrows':u'⇄', u'\\rightleftharpoons':u'⇌', u'\\rightmoon':u'☽', u'\\rightrightarrows':u'⇉', u'\\rightrightharpoons':u'⥤', u'\\rightthreetimes':u'⋌', u'\\rimg':u'⦈', u'\\risingdotseq':u'≓', u'\\rrbracket':u'⟧', u'\\rsub':u'⩥', u'\\rtimes':u'⋊', u'\\sagittarius':u'♐', u'\\saturn':u'♄', u'\\scorpio':u'♏', u'\\searrow':u'↘', u'\\sec':u'sec', u'\\second':u'″', u'\\setminus':u'∖', u'\\sharp':u'♯', u'\\simeq':u'≃', u'\\sin':u'sin', u'\\sinh':u'sinh', u'\\sixteenthnote':u'♬', u'\\skull':u'☠', u'\\slash':u'∕', u'\\smallsetminus':u'∖', u'\\smalltriangledown':u'▿', u'\\smalltriangleleft':u'◃', u'\\smalltriangleright':u'▹', u'\\smalltriangleup':u'▵', u'\\smile':u'⌣', u'\\smiley':u'☺', u'\\spadesuit':u'♠', u'\\spddot':u'¨', u'\\sphat':u'', u'\\sphericalangle':u'∢', u'\\spot':u'⦁', u'\\sptilde':u'~', u'\\sqcap':u'⊓', u'\\sqcup':u'⊔', u'\\sqsubset':u'⊏', u'\\sqsubseteq':u'⊑', u'\\sqsupset':u'⊐', u'\\sqsupseteq':u'⊒', u'\\square':u'□', u'\\sslash':u'⫽', u'\\star':u'⋆', u'\\steaming':u'☕', u'\\subseteqq':u'⫅', u'\\subsetneqq':u'⫋', u'\\succ':u'≻', u'\\succcurlyeq':u'≽', u'\\succeq':u'≽', u'\\succnsim':u'⋩', u'\\succsim':u'≿', u'\\sun':u'☼', u'\\sup':u'sup', u'\\supseteqq':u'⫆', u'\\supsetneqq':u'⫌', u'\\surd':u'√', u'\\swarrow':u'↙', u'\\swords':u'⚔', u'\\talloblong':u'⫾', u'\\tan':u'tan', u'\\tanh':u'tanh', u'\\taurus':u'♉', u'\\textasciicircum':u'^', u'\\textasciitilde':u'~', u'\\textbackslash':u'\\', u'\\textcopyright':u'©\'', u'\\textdegree':u'°', u'\\textellipsis':u'…', u'\\textemdash':u'—', u'\\textendash':u'—', u'\\texteuro':u'€', u'\\textgreater':u'>', u'\\textless':u'<', u'\\textordfeminine':u'ª', u'\\textordmasculine':u'º', u'\\textquotedblleft':u'“', u'\\textquotedblright':u'”', u'\\textquoteright':u'’', u'\\textregistered':u'®', u'\\textrightarrow':u'→', u'\\textsection':u'§', u'\\texttrademark':u'™', u'\\texttwosuperior':u'²', u'\\textvisiblespace':u' ', u'\\therefore':u'∴', u'\\third':u'‴', u'\\top':u'⊤', u'\\triangle':u'△', u'\\triangleleft':u'⊲', u'\\trianglelefteq':u'⊴', u'\\triangleq':u'≜', u'\\triangleright':u'▷', u'\\trianglerighteq':u'⊵', u'\\twoheadleftarrow':u'↞', u'\\twoheadrightarrow':u'↠', u'\\twonotes':u'♫', u'\\udot':u'⊍', u'\\ulcorner':u'⌜', u'\\unlhd':u'⊴', u'\\unrhd':u'⊵', u'\\unrhl':u'⊵', u'\\uparrow':u'↑', u'\\updownarrow':u'↕', u'\\upharpoonleft':u'↿', u'\\upharpoonright':u'↾', u'\\uplus':u'⊎', u'\\upuparrows':u'⇈', u'\\uranus':u'♅', u'\\urcorner':u'⌝', u'\\vDash':u'⊨', u'\\varclubsuit':u'♧', u'\\vardiamondsuit':u'♦', u'\\varheartsuit':u'♥', u'\\varnothing':u'∅', u'\\varspadesuit':u'♤', u'\\vdash':u'⊢', u'\\vdots':u'⋮', u'\\vee':u'∨', u'\\vee)':u'∨', u'\\veebar':u'⊻', u'\\vert':u'∣', u'\\virgo':u'♍', u'\\warning':u'⚠', u'\\wasylozenge':u'⌑', u'\\wedge':u'∧', u'\\wedge)':u'∧', u'\\wp':u'℘', u'\\wr':u'≀', u'\\yen':u'¥', u'\\yinyang':u'☯', u'\\{':u'{', u'\\|':u'∥', u'\\}':u'}', } decoratedcommand = { } decoratingfunctions = { u'\\overleftarrow':u'⟵', u'\\overrightarrow':u'⟶', u'\\widehat':u'^', } endings = { u'bracket':u'}', u'complex':u'\\]', u'endafter':u'}', u'endbefore':u'\\end{', u'squarebracket':u']', } environments = { u'align':[u'r',u'l',], u'eqnarray':[u'r',u'c',u'l',], u'gathered':[u'l',u'l',], } fontfunctions = { u'\\boldsymbol':u'b', u'\\mathbb':u'span class="blackboard"', u'\\mathbb{A}':u'𝔸', u'\\mathbb{B}':u'𝔹', u'\\mathbb{C}':u'ℂ', u'\\mathbb{D}':u'𝔻', u'\\mathbb{E}':u'𝔼', u'\\mathbb{F}':u'𝔽', u'\\mathbb{G}':u'𝔾', u'\\mathbb{H}':u'ℍ', u'\\mathbb{J}':u'𝕁', u'\\mathbb{K}':u'𝕂', u'\\mathbb{L}':u'𝕃', u'\\mathbb{N}':u'ℕ', u'\\mathbb{O}':u'𝕆', u'\\mathbb{P}':u'ℙ', u'\\mathbb{Q}':u'ℚ', u'\\mathbb{R}':u'ℝ', u'\\mathbb{S}':u'𝕊', u'\\mathbb{T}':u'𝕋', u'\\mathbb{W}':u'𝕎', u'\\mathbb{Z}':u'ℤ', u'\\mathbf':u'b', u'\\mathcal':u'span class="scriptfont"', u'\\mathcal{B}':u'ℬ', u'\\mathcal{E}':u'ℰ', u'\\mathcal{F}':u'ℱ', u'\\mathcal{H}':u'ℋ', u'\\mathcal{I}':u'ℐ', u'\\mathcal{L}':u'ℒ', u'\\mathcal{M}':u'ℳ', u'\\mathcal{R}':u'ℛ', u'\\mathfrak':u'span class="fraktur"', u'\\mathfrak{C}':u'ℭ', u'\\mathfrak{F}':u'𝔉', u'\\mathfrak{H}':u'ℌ', u'\\mathfrak{I}':u'ℑ', u'\\mathfrak{R}':u'ℜ', u'\\mathfrak{Z}':u'ℨ', u'\\mathit':u'i', u'\\mathring{A}':u'Å', u'\\mathring{U}':u'Ů', u'\\mathring{a}':u'å', u'\\mathring{u}':u'ů', u'\\mathring{w}':u'ẘ', u'\\mathring{y}':u'ẙ', u'\\mathrm':u'span class="mathrm"', u'\\mathscr':u'span class="scriptfont"', u'\\mathscr{B}':u'ℬ', u'\\mathscr{E}':u'ℰ', u'\\mathscr{F}':u'ℱ', u'\\mathscr{H}':u'ℋ', u'\\mathscr{I}':u'ℐ', u'\\mathscr{L}':u'ℒ', u'\\mathscr{M}':u'ℳ', u'\\mathscr{R}':u'ℛ', u'\\mathsf':u'span class="mathsf"', u'\\mathtt':u'tt', } hybridfunctions = { u'\\addcontentsline':[u'{$p!}{$q!}{$r!}',u'f0{}',u'ignored',], u'\\addtocontents':[u'{$p!}{$q!}',u'f0{}',u'ignored',], u'\\backmatter':[u'',u'f0{}',u'ignored',], u'\\binom':[u'{$1}{$2}',u'f2{(}f0{f1{$1}f1{$2}}f2{)}',u'span class="binom"',u'span class="binomstack"',u'span class="bigsymbol"',], u'\\boxed':[u'{$1}',u'f0{$1}',u'span class="boxed"',], u'\\cfrac':[u'[$p!]{$1}{$2}',u'f0{f3{(}f1{$1}f3{)/(}f2{$2}f3{)}}',u'span class="fullfraction"',u'span class="numerator align-$p"',u'span class="denominator"',u'span class="ignored"',], u'\\color':[u'{$p!}{$1}',u'f0{$1}',u'span style="color: $p;"',], u'\\colorbox':[u'{$p!}{$1}',u'f0{$1}',u'span class="colorbox" style="background: $p;"',], u'\\dbinom':[u'{$1}{$2}',u'(f0{f1{f2{$1}}f1{f2{ }}f1{f2{$2}}})',u'span class="binomial"',u'span class="binomrow"',u'span class="binomcell"',], u'\\dfrac':[u'{$1}{$2}',u'f0{f3{(}f1{$1}f3{)/(}f2{$2}f3{)}}',u'span class="fullfraction"',u'span class="numerator"',u'span class="denominator"',u'span class="ignored"',], u'\\displaystyle':[u'{$1}',u'f0{$1}',u'span class="displaystyle"',], u'\\fancyfoot':[u'[$p!]{$q!}',u'f0{}',u'ignored',], u'\\fancyhead':[u'[$p!]{$q!}',u'f0{}',u'ignored',], u'\\fbox':[u'{$1}',u'f0{$1}',u'span class="fbox"',], u'\\fboxrule':[u'{$p!}',u'f0{}',u'ignored',], u'\\fboxsep':[u'{$p!}',u'f0{}',u'ignored',], u'\\fcolorbox':[u'{$p!}{$q!}{$1}',u'f0{$1}',u'span class="boxed" style="border-color: $p; background: $q;"',], u'\\frac':[u'{$1}{$2}',u'f0{f3{(}f1{$1}f3{)/(}f2{$2}f3{)}}',u'span class="fraction"',u'span class="numerator"',u'span class="denominator"',u'span class="ignored"',], u'\\framebox':[u'[$p!][$q!]{$1}',u'f0{$1}',u'span class="framebox align-$q" style="width: $p;"',], u'\\frontmatter':[u'',u'f0{}',u'ignored',], u'\\href':[u'[$o]{$u!}{$t!}',u'f0{$t}',u'a href="$u"',], u'\\hspace':[u'{$p!}',u'f0{ }',u'span class="hspace" style="width: $p;"',], u'\\leftroot':[u'{$p!}',u'f0{ }',u'span class="leftroot" style="width: $p;px"',], u'\\mainmatter':[u'',u'f0{}',u'ignored',], u'\\markboth':[u'{$p!}{$q!}',u'f0{}',u'ignored',], u'\\markright':[u'{$p!}',u'f0{}',u'ignored',], u'\\nicefrac':[u'{$1}{$2}',u'f0{f1{$1}⁄f2{$2}}',u'span class="fraction"',u'sup class="numerator"',u'sub class="denominator"',u'span class="ignored"',], u'\\parbox':[u'[$p!]{$w!}{$1}',u'f0{1}',u'div class="Boxed" style="width: $w;"',], u'\\raisebox':[u'{$p!}{$1}',u'f0{$1.font}',u'span class="raisebox" style="vertical-align: $p;"',], u'\\renewenvironment':[u'{$1!}{$2!}{$3!}',u'',], u'\\rule':[u'[$v!]{$w!}{$h!}',u'f0/',u'hr class="line" style="width: $w; height: $h;"',], u'\\scriptscriptstyle':[u'{$1}',u'f0{$1}',u'span class="scriptscriptstyle"',], u'\\scriptstyle':[u'{$1}',u'f0{$1}',u'span class="scriptstyle"',], u'\\sqrt':[u'[$0]{$1}',u'f0{f1{$0}f2{√}f4{(}f3{$1}f4{)}}',u'span class="sqrt"',u'sup class="root"',u'span class="radical"',u'span class="root"',u'span class="ignored"',], u'\\stackrel':[u'{$1}{$2}',u'f0{f1{$1}f2{$2}}',u'span class="stackrel"',u'span class="upstackrel"',u'span class="downstackrel"',], u'\\tbinom':[u'{$1}{$2}',u'(f0{f1{f2{$1}}f1{f2{ }}f1{f2{$2}}})',u'span class="binomial"',u'span class="binomrow"',u'span class="binomcell"',], u'\\textcolor':[u'{$p!}{$1}',u'f0{$1}',u'span style="color: $p;"',], u'\\textstyle':[u'{$1}',u'f0{$1}',u'span class="textstyle"',], u'\\thispagestyle':[u'{$p!}',u'f0{}',u'ignored',], u'\\unit':[u'[$0]{$1}',u'$0f0{$1.font}',u'span class="unit"',], u'\\unitfrac':[u'[$0]{$1}{$2}',u'$0f0{f1{$1.font}⁄f2{$2.font}}',u'span class="fraction"',u'sup class="unit"',u'sub class="unit"',], u'\\uproot':[u'{$p!}',u'f0{ }',u'span class="uproot" style="width: $p;px"',], u'\\url':[u'{$u!}',u'f0{$u}',u'a href="$u"',], u'\\vspace':[u'{$p!}',u'f0{ }',u'span class="vspace" style="height: $p;"',], } hybridsizes = { u'\\binom':u'$1+$2', u'\\cfrac':u'$1+$2', u'\\dbinom':u'$1+$2+1', u'\\dfrac':u'$1+$2', u'\\frac':u'$1+$2', u'\\tbinom':u'$1+$2+1', } labelfunctions = { u'\\label':u'a name="#"', } limitcommands = { u'\\biginterleave':u'⫼', u'\\bigsqcap':u'⨅', u'\\fint':u'⨏', u'\\iiiint':u'⨌', u'\\int':u'∫', u'\\intop':u'∫', u'\\lim':u'lim', u'\\prod':u'∏', u'\\smallint':u'∫', u'\\sqint':u'⨖', u'\\sum':u'∑', u'\\varointclockwise':u'∲', u'\\varprod':u'⨉', u'\\zcmp':u'⨟', u'\\zhide':u'⧹', u'\\zpipe':u'⨠', u'\\zproject':u'⨡', } misccommands = { u'\\limits':u'LimitPreviousCommand', u'\\newcommand':u'MacroDefinition', u'\\renewcommand':u'MacroDefinition', u'\\setcounter':u'SetCounterFunction', u'\\tag':u'FormulaTag', u'\\tag*':u'FormulaTag', u'\\today':u'TodayCommand', } modified = { u'\n':u'', u' ':u'', u'$':u'', u'&':u' ', u'\'':u'’', u'+':u' + ', u',':u', ', u'-':u' − ', u'/':u' ⁄ ', u'<':u' < ', u'=':u' = ', u'>':u' > ', u'@':u'', u'~':u'', } onefunctions = { u'\\Big':u'span class="bigsymbol"', u'\\Bigg':u'span class="hugesymbol"', u'\\bar':u'span class="bar"', u'\\begin{array}':u'span class="arraydef"', u'\\big':u'span class="symbol"', u'\\bigg':u'span class="largesymbol"', u'\\bigl':u'span class="bigsymbol"', u'\\bigr':u'span class="bigsymbol"', u'\\centering':u'span class="align-center"', u'\\ensuremath':u'span class="ensuremath"', u'\\hphantom':u'span class="phantom"', u'\\noindent':u'span class="noindent"', u'\\overbrace':u'span class="overbrace"', u'\\overline':u'span class="overline"', u'\\phantom':u'span class="phantom"', u'\\underbrace':u'span class="underbrace"', u'\\underline':u'u', u'\\vphantom':u'span class="phantom"', } spacedcommands = { u'\\Bot':u'⫫', u'\\Doteq':u'≑', u'\\DownArrowBar':u'⤓', u'\\DownLeftTeeVector':u'⥞', u'\\DownLeftVectorBar':u'⥖', u'\\DownRightTeeVector':u'⥟', u'\\DownRightVectorBar':u'⥗', u'\\Equal':u'⩵', u'\\LeftArrowBar':u'⇤', u'\\LeftDownTeeVector':u'⥡', u'\\LeftDownVectorBar':u'⥙', u'\\LeftTeeVector':u'⥚', u'\\LeftTriangleBar':u'⧏', u'\\LeftUpTeeVector':u'⥠', u'\\LeftUpVectorBar':u'⥘', u'\\LeftVectorBar':u'⥒', u'\\Leftrightarrow':u'⇔', u'\\Longmapsfrom':u'⟽', u'\\Longmapsto':u'⟾', u'\\MapsDown':u'↧', u'\\MapsUp':u'↥', u'\\Nearrow':u'⇗', u'\\NestedGreaterGreater':u'⪢', u'\\NestedLessLess':u'⪡', u'\\NotGreaterLess':u'≹', u'\\NotGreaterTilde':u'≵', u'\\NotLessTilde':u'≴', u'\\Nwarrow':u'⇖', u'\\Proportion':u'∷', u'\\RightArrowBar':u'⇥', u'\\RightDownTeeVector':u'⥝', u'\\RightDownVectorBar':u'⥕', u'\\RightTeeVector':u'⥛', u'\\RightTriangleBar':u'⧐', u'\\RightUpTeeVector':u'⥜', u'\\RightUpVectorBar':u'⥔', u'\\RightVectorBar':u'⥓', u'\\Rightarrow':u'⇒', u'\\Same':u'⩶', u'\\Searrow':u'⇘', u'\\Swarrow':u'⇙', u'\\Top':u'⫪', u'\\UpArrowBar':u'⤒', u'\\VDash':u'⊫', u'\\approx':u'≈', u'\\approxeq':u'≊', u'\\backsim':u'∽', u'\\barin':u'⋶', u'\\barleftharpoon':u'⥫', u'\\barrightharpoon':u'⥭', u'\\bij':u'⤖', u'\\coloneq':u'≔', u'\\corresponds':u'≙', u'\\curlyeqprec':u'⋞', u'\\curlyeqsucc':u'⋟', u'\\dashrightarrow':u'⇢', u'\\dlsh':u'↲', u'\\downdownharpoons':u'⥥', u'\\downuparrows':u'⇵', u'\\downupharpoons':u'⥯', u'\\drsh':u'↳', u'\\eqslantgtr':u'⪖', u'\\eqslantless':u'⪕', u'\\equiv':u'≡', u'\\ffun':u'⇻', u'\\finj':u'⤕', u'\\ge':u'≥', u'\\geq':u'≥', u'\\ggcurly':u'⪼', u'\\gnapprox':u'⪊', u'\\gneq':u'⪈', u'\\gtrapprox':u'⪆', u'\\hash':u'⋕', u'\\iddots':u'⋰', u'\\implies':u' ⇒ ', u'\\in':u'∈', u'\\le':u'≤', u'\\leftarrow':u'←', u'\\leftarrowtriangle':u'⇽', u'\\leftbarharpoon':u'⥪', u'\\leftrightarrowtriangle':u'⇿', u'\\leftrightharpoon':u'⥊', u'\\leftrightharpoondown':u'⥐', u'\\leftrightharpoonup':u'⥎', u'\\leftrightsquigarrow':u'↭', u'\\leftslice':u'⪦', u'\\leftsquigarrow':u'⇜', u'\\leftupdownharpoon':u'⥑', u'\\leq':u'≤', u'\\lessapprox':u'⪅', u'\\llcurly':u'⪻', u'\\lnapprox':u'⪉', u'\\lneq':u'⪇', u'\\longmapsfrom':u'⟻', u'\\multimapboth':u'⧟', u'\\multimapdotbothA':u'⊶', u'\\multimapdotbothB':u'⊷', u'\\multimapinv':u'⟜', u'\\nVdash':u'⊮', u'\\ne':u'≠', u'\\neq':u'≠', u'\\ngeq':u'≱', u'\\nleq':u'≰', u'\\nni':u'∌', u'\\not\\in':u'∉', u'\\notasymp':u'≭', u'\\npreceq':u'⋠', u'\\nsqsubseteq':u'⋢', u'\\nsqsupseteq':u'⋣', u'\\nsubset':u'⊄', u'\\nsucceq':u'⋡', u'\\pfun':u'⇸', u'\\pinj':u'⤔', u'\\precapprox':u'⪷', u'\\preceqq':u'⪳', u'\\precnapprox':u'⪹', u'\\precnsim':u'⋨', u'\\propto':u'∝', u'\\psur':u'⤀', u'\\rightarrow':u'→', u'\\rightarrowtriangle':u'⇾', u'\\rightbarharpoon':u'⥬', u'\\rightleftharpoon':u'⥋', u'\\rightslice':u'⪧', u'\\rightsquigarrow':u'⇝', u'\\rightupdownharpoon':u'⥏', u'\\sim':u'~', u'\\strictfi':u'⥼', u'\\strictif':u'⥽', u'\\subset':u'⊂', u'\\subseteq':u'⊆', u'\\subsetneq':u'⊊', u'\\succapprox':u'⪸', u'\\succeqq':u'⪴', u'\\succnapprox':u'⪺', u'\\supset':u'⊃', u'\\supseteq':u'⊇', u'\\supsetneq':u'⊋', u'\\times':u'×', u'\\to':u'→', u'\\updownarrows':u'⇅', u'\\updownharpoons':u'⥮', u'\\upupharpoons':u'⥣', u'\\vartriangleleft':u'⊲', u'\\vartriangleright':u'⊳', } starts = { u'beginafter':u'}', u'beginbefore':u'\\begin{', u'bracket':u'{', u'command':u'\\', u'comment':u'%', u'complex':u'\\[', u'simple':u'$', u'squarebracket':u'[', u'unnumbered':u'*', } symbolfunctions = { u'^':u'sup', u'_':u'sub', } textfunctions = { u'\\mbox':u'span class="mbox"', u'\\text':u'span class="text"', u'\\textbf':u'b', u'\\textipa':u'span class="textipa"', u'\\textit':u'i', u'\\textnormal':u'span class="textnormal"', u'\\textrm':u'span class="textrm"', u'\\textsc':u'span class="versalitas"', u'\\textsf':u'span class="textsf"', u'\\textsl':u'i', u'\\texttt':u'tt', u'\\textup':u'span class="normal"', } unmodified = { u'characters':[u'.',u'*',u'€',u'(',u')',u'[',u']',u':',u'·',u'!',u';',u'|',u'§',u'"',], } urls = { u'googlecharts':u'http://chart.googleapis.com/chart?cht=tx&chl=', } class GeneralConfig(object): "Configuration class from elyxer.config file" version = { u'date':u'2013-03-10', u'lyxformat':u'413', u'number':u'1.2.5', } class HeaderConfig(object): "Configuration class from elyxer.config file" parameters = { u'beginpreamble':u'\\begin_preamble', u'branch':u'\\branch', u'documentclass':u'\\textclass', u'endbranch':u'\\end_branch', u'endpreamble':u'\\end_preamble', u'language':u'\\language', u'lstset':u'\\lstset', u'outputchanges':u'\\output_changes', u'paragraphseparation':u'\\paragraph_separation', u'pdftitle':u'\\pdf_title', u'secnumdepth':u'\\secnumdepth', u'tocdepth':u'\\tocdepth', } styles = { u'article':[u'article',u'aastex',u'aapaper',u'acmsiggraph',u'sigplanconf',u'achemso',u'amsart',u'apa',u'arab-article',u'armenian-article',u'article-beamer',u'chess',u'dtk',u'elsarticle',u'heb-article',u'IEEEtran',u'iopart',u'kluwer',u'scrarticle-beamer',u'scrartcl',u'extarticle',u'paper',u'mwart',u'revtex4',u'spie',u'svglobal3',u'ltugboat',u'agu-dtd',u'jgrga',u'agums',u'entcs',u'egs',u'ijmpc',u'ijmpd',u'singlecol-new',u'doublecol-new',u'isprs',u'tarticle',u'jsarticle',u'jarticle',u'jss',u'literate-article',u'siamltex',u'cl2emult',u'llncs',u'svglobal',u'svjog',u'svprobth',], u'book':[u'book',u'amsbook',u'scrbook',u'extbook',u'tufte-book',u'report',u'extreport',u'scrreprt',u'memoir',u'tbook',u'jsbook',u'jbook',u'mwbk',u'svmono',u'svmult',u'treport',u'jreport',u'mwrep',], } class ImageConfig(object): "Configuration class from elyxer.config file" converters = { u'imagemagick':u'convert[ -density $scale][ -define $format:use-cropbox=true] "$input" "$output"', u'inkscape':u'inkscape "$input" --export-png="$output"', u'lyx':u'lyx -C "$input" "$output"', } cropboxformats = { u'.eps':u'ps', u'.pdf':u'pdf', u'.ps':u'ps', } formats = { u'default':u'.png', u'vector':[u'.svg',u'.eps',], } class LayoutConfig(object): "Configuration class from elyxer.config file" groupable = { u'allowed':[u'StringContainer',u'Constant',u'TaggedText',u'Align',u'TextFamily',u'EmphaticText',u'VersalitasText',u'BarredText',u'SizeText',u'ColorText',u'LangLine',u'Formula',], } class NewfangleConfig(object): "Configuration class from elyxer.config file" constants = { u'chunkref':u'chunkref{', u'endcommand':u'}', u'endmark':u'>', u'startcommand':u'\\', u'startmark':u'=<', } class NumberingConfig(object): "Configuration class from elyxer.config file" layouts = { u'ordered':[u'Chapter',u'Section',u'Subsection',u'Subsubsection',u'Paragraph',], u'roman':[u'Part',u'Book',], } sequence = { u'symbols':[u'*',u'**',u'†',u'‡',u'§',u'§§',u'¶',u'¶¶',u'#',u'##',], } class StyleConfig(object): "Configuration class from elyxer.config file" hspaces = { u'\\enskip{}':u' ', u'\\hfill{}':u' ', u'\\hspace*{\\fill}':u' ', u'\\hspace*{}':u'', u'\\hspace{}':u' ', u'\\negthinspace{}':u'', u'\\qquad{}':u'  ', u'\\quad{}':u' ', u'\\space{}':u' ', u'\\thinspace{}':u' ', u'~':u' ', } quotes = { u'ald':u'»', u'als':u'›', u'ard':u'«', u'ars':u'‹', u'eld':u'“', u'els':u'‘', u'erd':u'”', u'ers':u'’', u'fld':u'«', u'fls':u'‹', u'frd':u'»', u'frs':u'›', u'gld':u'„', u'gls':u'‚', u'grd':u'“', u'grs':u'‘', u'pld':u'„', u'pls':u'‚', u'prd':u'”', u'prs':u'’', u'sld':u'”', u'srd':u'”', } referenceformats = { u'eqref':u'(@↕)', u'formatted':u'¶↕', u'nameref':u'$↕', u'pageref':u'#↕', u'ref':u'@↕', u'vpageref':u'on-page#↕', u'vref':u'@on-page#↕', } size = { u'ignoredtexts':[u'col',u'text',u'line',u'page',u'theight',u'pheight',], } vspaces = { u'bigskip':u'
', u'defskip':u'
', u'medskip':u'
', u'smallskip':u'
', u'vfill':u'
', } class TOCConfig(object): "Configuration class from elyxer.config file" extractplain = { u'allowed':[u'StringContainer',u'Constant',u'TaggedText',u'Align',u'TextFamily',u'EmphaticText',u'VersalitasText',u'BarredText',u'SizeText',u'ColorText',u'LangLine',u'Formula',], u'cloned':[u'',], u'extracted':[u'',], } extracttitle = { u'allowed':[u'StringContainer',u'Constant',u'Space',], u'cloned':[u'TextFamily',u'EmphaticText',u'VersalitasText',u'BarredText',u'SizeText',u'ColorText',u'LangLine',u'Formula',], u'extracted':[u'PlainLayout',u'TaggedText',u'Align',u'Caption',u'StandardLayout',u'FlexInset',], } class TagConfig(object): "Configuration class from elyxer.config file" barred = { u'under':u'u', } family = { u'sans':u'span class="sans"', u'typewriter':u'tt', } flex = { u'CharStyle:Code':u'span class="code"', u'CharStyle:MenuItem':u'span class="menuitem"', u'Code':u'span class="code"', u'MenuItem':u'span class="menuitem"', u'Noun':u'span class="noun"', u'Strong':u'span class="strong"', } group = { u'layouts':[u'Quotation',u'Quote',], } layouts = { u'Center':u'div', u'Chapter':u'h?', u'Date':u'h2', u'Paragraph':u'div', u'Part':u'h1', u'Quotation':u'blockquote', u'Quote':u'blockquote', u'Section':u'h?', u'Subsection':u'h?', u'Subsubsection':u'h?', } listitems = { u'Enumerate':u'ol', u'Itemize':u'ul', } notes = { u'Comment':u'', u'Greyedout':u'span class="greyedout"', u'Note':u'', } script = { u'subscript':u'sub', u'superscript':u'sup', } shaped = { u'italic':u'i', u'slanted':u'i', u'smallcaps':u'span class="versalitas"', } class TranslationConfig(object): "Configuration class from elyxer.config file" constants = { u'Appendix':u'Appendix', u'Book':u'Book', u'Chapter':u'Chapter', u'Paragraph':u'Paragraph', u'Part':u'Part', u'Section':u'Section', u'Subsection':u'Subsection', u'Subsubsection':u'Subsubsection', u'abstract':u'Abstract', u'bibliography':u'Bibliography', u'figure':u'figure', u'float-algorithm':u'Algorithm ', u'float-figure':u'Figure ', u'float-listing':u'Listing ', u'float-table':u'Table ', u'float-tableau':u'Tableau ', u'footnotes':u'Footnotes', u'generated-by':u'Document generated by ', u'generated-on':u' on ', u'index':u'Index', u'jsmath-enable':u'Please enable JavaScript on your browser.', u'jsmath-requires':u' requires JavaScript to correctly process the mathematics on this page. ', u'jsmath-warning':u'Warning: ', u'list-algorithm':u'List of Algorithms', u'list-figure':u'List of Figures', u'list-table':u'List of Tables', u'list-tableau':u'List of Tableaux', u'main-page':u'Main page', u'next':u'Next', u'nomenclature':u'Nomenclature', u'on-page':u' on page ', u'prev':u'Prev', u'references':u'References', u'toc':u'Table of Contents', u'toc-for':u'Contents for ', u'up':u'Up', } languages = { u'american':u'en', u'british':u'en', u'deutsch':u'de', u'dutch':u'nl', u'english':u'en', u'french':u'fr', u'ngerman':u'de', u'russian':u'ru', u'spanish':u'es', } elyxer-1.2.5/src/elyxer/conf/importconfig.py0000644000175000017500000001227712117063046020444 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20090617 # eLyXer import configuration file from elyxer.util.trace import Trace from elyxer.io.fileline import * from elyxer.conf.fileconfig import * class ImportFile(object): "Generic import file." def __init__(self, filename): self.reader = LineReader(filename) self.objects = dict() self.section = 'FormulaConfig.commands' self.objects[self.section] = dict() self.sectionobject = self.objects[self.section] self.serializer = ConfigSerializer(ImportCommands.escapes) self.existing = dict() self.existing.update(FormulaConfig.commands) self.existing.update(FormulaConfig.alphacommands) self.existing.update(FormulaConfig.spacedcommands) def parsewhole(self, parseline): "Parse the whole file line by line." while not self.reader.finished(): line = self.convertline(self.reader.currentline()) if line: parseline(line) self.reader.nextline() def convertline(self, line): "Convert a single line removing comments." if line == '': return None if line.startswith('#'): return None if '#' in line: line = line.split('#')[0] return line def setsymbol(self, command, unicodesymbol): "Set the unicode symbol for a command." if not command.startswith('\\'): Trace.error('Invalid command ' + command) return if command.count('\\') > 1: Trace.error('Too many commands ' + command) return if command in self.existing: return self.sectionobject[command] = unicodesymbol class ImportCommands(ImportFile): "Import a LyX unicodesymbols file" escapes = [ ('\\', '\\\\') ] def parse(self): "Parse the whole LyX commands file." self.parsewhole(self.parseparam) return self def parseparam(self, line): "Parse a parameter line" line = line.strip() if len(line) == 0: return pieces = line.split() if len(pieces) < 5: return unicode = pieces[0] if not unicode.startswith('0x'): Trace.error('Invalid unicode ' + unicode) return unicode = unicode.replace('0x', '') unicodechar = unichr(int(unicode, 16)) command = pieces[4].replace('"', '') command = self.serializer.unescape(command) self.setsymbol(command, unicodechar) class ImportCsv(ImportFile): "Import a file with comma-separated values of the form: \command,unicode." def parse(self): "Parse the whole CSV file." self.parsewhole(self.parsecsv) return self def parsecsv(self, line): "Parse a line \command,unicode." line = line.strip() if len(line) == 0: return pieces = line.split(',') if len(pieces) != 2: return self.setsymbol(pieces[0],pieces[1]) class ImportUnimath(ImportFile): "Import a file in unimath format." "See http://milde.users.sourceforge.net/LUCR/Math/" def parse(self): "Parse the whole unimath file." self.parsewhole(self.parseunimath) return self def parseunimath(self, line): "Parse a line \command,unicode." line = line.strip() if len(line) == 0: return pieces = line.split('^') if len(pieces) != 8: Trace.error('Weird line: ' + line) return symbol = pieces[1] command = pieces[2] if command == '' or not command.startswith('\\'): return mathclass = pieces[4] mathcategory = pieces[5] if mathcategory in ['mathord', 'mathbin', 'mathopen', 'mathclose']: # plain old command self.add(symbol, command, 'FormulaConfig.commands') elif mathcategory in ['mathalpha']: # alpha command self.add(symbol, command, 'FormulaConfig.alphacommands') elif mathcategory in ['mathaccent', 'mathfence', 'mathradical', 'mathover', 'mathunder', '']: # ignore Trace.error('Ignoring ' + symbol + ' with category ' + mathcategory) elif mathcategory in ['mathop']: self.add(symbol, command, 'FormulaConfig.limitcommands') elif mathcategory in ['mathrel']: self.add(symbol, command, 'FormulaConfig.spacedcommands') else: Trace.error('Unknown math category ' + mathcategory + ' for ' + symbol) def add(self, symbol, command, category): "Add a symbol to a category." if not category in self.objects: self.objects[category] = dict() self.sectionobject = self.objects[category] if command == '': return if '{' in command or '}' in command or '[' in command or ']' in command: return self.setsymbol(command, symbol) elyxer-1.2.5/src/elyxer/conf/jtp.cfg0000644000175000017500000000413712074107030016636 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009-2010 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- [GeneralConfig.version] date:2010-03-11 number:0.1 [JavaToPyConfig.declarations] $file:[$class]+ $class:$scope class $classname $inheritance { [$method]* } $scope:public|private|protected $classname:$$ $inheritance:[extends $classlist]? [implements $classlist]? $classlist:[$classname]?[, $classname]* $method:$scope [$qualifier]* $type $methodname ( $paramsdeclaration ) { $block } $methodname:$$ $paramsdeclaration:[$paramdeclaration]?[,$paramdeclaration]* $paramdeclaration:$type $variablename $variablename:$$ $qualifier:static|final $type:int|String|$classname $conditional:if ($condition) $block $condition:$value|$logicalvalue $logicalvalue:$orvalue|$andvalue $orvalue:$value || $value $andvalue:$value && $value $block:[$statement]* $statement:$conditional|$declaration|$assignment|$methodcall $methodcall:$variablename[.$methodname($params)]+ $params:[$value]?[,$value]+ $value:$variablename|$methodcall|$arithmeticexpression $arithmeticexpression:$value + $value $declaration:$simpledeclaration|$declarationassignment $simpledeclaration:$type $variablename; $declarationassignment:$type $variablename = $value; $assignment:$variablename = $value; [JavaToPyConfig.output] $class:class $classname(object):\n\t[$method]* $classname:$classname $method:def $methodname:\n\t$block $conditional:if $condition:\n\t$block elyxer-1.2.5/src/elyxer/conf/javatopyconf.py0000644000175000017500000000400012074107030020422 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer configuration # autogenerated from elyxer.config file on 2010-03-15 class GeneralConfig(object): "Configuration class from elyxer.config file" version = { u'date':u'2010-03-15', u'number':u'0.1', } class JavaToPyConfig(object): "Configuration class from elyxer.config file" declarations = { u'$andvalue':u'$value && $value', u'$arithmeticexpression':u'$value + $value', u'$assignment':u'$variablename = $value;', u'$block':u'[$statement]*', u'$class':u'$scope class $classname $inheritance { [$method]* }', u'$classlist':u'[$classname]?[, $classname]*', u'$classname':u'$$', u'$condition':u'$value|$logicalvalue', u'$conditional':u'if ($condition) $block', u'$declaration':u'$simpledeclaration|$declarationassignment', u'$declarationassignment':u'$type $variablename = $value;', u'$file':u'[$class]+', u'$inheritance':u'[extends $classlist]? [implements $classlist]?', u'$logicalvalue':u'$orvalue|$andvalue', u'$method':u'$scope [$qualifier]* $type $methodname ( $paramsdeclaration ) { $block }', u'$methodcall':u'$variablename[.$methodname($params)]+', u'$methodname':u'$$', u'$orvalue':u'$value || $value', u'$paramdeclaration':u'$type $variablename', u'$params':u'[$value]?[,$value]+', u'$paramsdeclaration':u'[$paramdeclaration]?[,$paramdeclaration]*', u'$qualifier':u'static|final', u'$scope':u'public|private|protected', u'$simpledeclaration':u'$type $variablename;', u'$statement':u'$conditional|$declaration|$assignment|$methodcall', u'$type':u'int|String|$classname', u'$value':u'$variablename|$methodcall|$arithmeticexpression', u'$variablename':u'$$', } output = { u'$class':u'class $classname(object):\\n\\t[$method]*', u'$classname':u'$classname', u'$conditional':u'if $condition:\\n\\t$block', u'$method':u'def $methodname:\\n\\t$block', } elyxer-1.2.5/src/elyxer/conf/__init__.py0000644000175000017500000000000012074107030017452 0ustar chennochennoelyxer-1.2.5/src/elyxer/maths/0000755000175000017500000000000012117175142015551 5ustar chennochennoelyxer-1.2.5/src/elyxer/maths/symbol.py0000644000175000017500000000707412074107030017431 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20101218 # eLyXer big symbol generation. from elyxer.util.trace import Trace from elyxer.util.docparams import * from elyxer.conf.config import * from elyxer.maths.bits import * class BigSymbol(object): "A big symbol generator." symbols = FormulaConfig.bigsymbols def __init__(self, symbol): "Create the big symbol." self.symbol = symbol def getpieces(self): "Get an array with all pieces." if not self.symbol in self.symbols: return [self.symbol] if self.smalllimit(): return [self.symbol] return self.symbols[self.symbol] def smalllimit(self): "Decide if the limit should be a small, one-line symbol." if not DocumentParameters.displaymode: return True if len(self.symbols[self.symbol]) == 1: return True return Options.simplemath class BigBracket(BigSymbol): "A big bracket generator." def __init__(self, size, bracket, alignment='l'): "Set the size and symbol for the bracket." self.size = size self.original = bracket self.alignment = alignment self.pieces = None if bracket in FormulaConfig.bigbrackets: self.pieces = FormulaConfig.bigbrackets[bracket] def getpiece(self, index): "Return the nth piece for the bracket." function = getattr(self, 'getpiece' + unicode(len(self.pieces))) return function(index) def getpiece1(self, index): "Return the only piece for a single-piece bracket." return self.pieces[0] def getpiece3(self, index): "Get the nth piece for a 3-piece bracket: parenthesis or square bracket." if index == 0: return self.pieces[0] if index == self.size - 1: return self.pieces[-1] return self.pieces[1] def getpiece4(self, index): "Get the nth piece for a 4-piece bracket: curly bracket." if index == 0: return self.pieces[0] if index == self.size - 1: return self.pieces[3] if index == (self.size - 1)/2: return self.pieces[2] return self.pieces[1] def getcell(self, index): "Get the bracket piece as an array cell." piece = self.getpiece(index) span = 'span class="bracket align-' + self.alignment + '"' return TaggedBit().constant(piece, span) def getcontents(self): "Get the bracket as an array or as a single bracket." if self.size == 1 or not self.pieces: return self.getsinglebracket() rows = [] for index in range(self.size): cell = self.getcell(index) rows.append(TaggedBit().complete([cell], 'span class="arrayrow"')) return [TaggedBit().complete(rows, 'span class="array"')] def getsinglebracket(self): "Return the bracket as a single sign." if self.original == '.': return [TaggedBit().constant('', 'span class="emptydot"')] return [TaggedBit().constant(self.original, 'span class="symbol"')] elyxer-1.2.5/src/elyxer/maths/hybrid.py0000644000175000017500000002137312074107030017403 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20091214 # eLyXer functions with a variable number of parameters. from elyxer.util.trace import Trace from elyxer.conf.config import * from elyxer.maths.command import * from elyxer.maths.extracommand import * class ParameterDefinition(object): "The definition of a parameter in a hybrid function." "[] parameters are optional, {} parameters are mandatory." "Each parameter has a one-character name, like {$1} or {$p}." "A parameter that ends in ! like {$p!} is a literal." "Example: [$1]{$p!} reads an optional parameter $1 and a literal mandatory parameter p." parambrackets = [('[', ']'), ('{', '}')] def __init__(self): self.name = None self.literal = False self.optional = False self.value = None self.literalvalue = None def parse(self, pos): "Parse a parameter definition: [$0], {$x}, {$1!}..." for (opening, closing) in ParameterDefinition.parambrackets: if pos.checkskip(opening): if opening == '[': self.optional = True if not pos.checkskip('$'): Trace.error('Wrong parameter name, did you mean $' + pos.current() + '?') return None self.name = pos.skipcurrent() if pos.checkskip('!'): self.literal = True if not pos.checkskip(closing): Trace.error('Wrong parameter closing ' + pos.skipcurrent()) return None return self Trace.error('Wrong character in parameter template: ' + pos.skipcurrent()) return None def read(self, pos, function): "Read the parameter itself using the definition." if self.literal: if self.optional: self.literalvalue = function.parsesquareliteral(pos) else: self.literalvalue = function.parseliteral(pos) if self.literalvalue: self.value = FormulaConstant(self.literalvalue) elif self.optional: self.value = function.parsesquare(pos) else: self.value = function.parseparameter(pos) def __unicode__(self): "Return a printable representation." result = 'param ' + self.name if self.value: result += ': ' + unicode(self.value) else: result += ' (empty)' return result class ParameterFunction(CommandBit): "A function with a variable number of parameters defined in a template." "The parameters are defined as a parameter definition." def readparams(self, readtemplate, pos): "Read the params according to the template." self.params = dict() for paramdef in self.paramdefs(readtemplate): paramdef.read(pos, self) self.params['$' + paramdef.name] = paramdef def paramdefs(self, readtemplate): "Read each param definition in the template" pos = TextPosition(readtemplate) while not pos.finished(): paramdef = ParameterDefinition().parse(pos) if paramdef: yield paramdef def getparam(self, name): "Get a parameter as parsed." if not name in self.params: return None return self.params[name] def getvalue(self, name): "Get the value of a parameter." return self.getparam(name).value def getliteralvalue(self, name): "Get the literal value of a parameter." param = self.getparam(name) if not param or not param.literalvalue: return None return param.literalvalue class HybridFunction(ParameterFunction): """ A parameter function where the output is also defined using a template. The template can use a number of functions; each function has an associated tag. Example: [f0{$1},span class="fbox"] defines a function f0 which corresponds to a span of class fbox, yielding $1. Literal parameters can be used in tags definitions: [f0{$1},span style="color: $p;"] yields $1, where $p is a literal parameter. Sizes can be specified in hybridsizes, e.g. adding parameter sizes. By default the resulting size is the max of all arguments. Sizes are used to generate the right parameters. A function followed by a single / is output as a self-closing XHTML tag: [f0/,hr] will generate
. """ commandmap = FormulaConfig.hybridfunctions def parsebit(self, pos): "Parse a function with [] and {} parameters" readtemplate = self.translated[0] writetemplate = self.translated[1] self.readparams(readtemplate, pos) self.contents = self.writeparams(writetemplate) self.computehybridsize() def writeparams(self, writetemplate): "Write all params according to the template" return self.writepos(TextPosition(writetemplate)) def writepos(self, pos): "Write all params as read in the parse position." result = [] while not pos.finished(): if pos.checkskip('$'): param = self.writeparam(pos) if param: result.append(param) elif pos.checkskip('f'): function = self.writefunction(pos) if function: function.type = None result.append(function) elif pos.checkskip('('): result.append(self.writebracket('left', '(')) elif pos.checkskip(')'): result.append(self.writebracket('right', ')')) else: result.append(FormulaConstant(pos.skipcurrent())) return result def writeparam(self, pos): "Write a single param of the form $0, $x..." name = '$' + pos.skipcurrent() if not name in self.params: Trace.error('Unknown parameter ' + name) return None if not self.params[name]: return None if pos.checkskip('.'): self.params[name].value.type = pos.globalpha() return self.params[name].value def writefunction(self, pos): "Write a single function f0,...,fn." tag = self.readtag(pos) if not tag: return None if pos.checkskip('/'): # self-closing XHTML tag, such as
return TaggedBit().selfcomplete(tag) if not pos.checkskip('{'): Trace.error('Function should be defined in {}') return None pos.pushending('}') contents = self.writepos(pos) pos.popending() if len(contents) == 0: return None return TaggedBit().complete(contents, tag) def readtag(self, pos): "Get the tag corresponding to the given index. Does parameter substitution." if not pos.current().isdigit(): Trace.error('Function should be f0,...,f9: f' + pos.current()) return None index = int(pos.skipcurrent()) if 2 + index > len(self.translated): Trace.error('Function f' + unicode(index) + ' is not defined') return None tag = self.translated[2 + index] if not '$' in tag: return tag for variable in self.params: if variable in tag: param = self.params[variable] if not param.literal: Trace.error('Parameters in tag ' + tag + ' should be literal: {' + variable + '!}') continue if param.literalvalue: value = param.literalvalue else: value = '' tag = tag.replace(variable, value) return tag def writebracket(self, direction, character): "Return a new bracket looking at the given direction." return self.factory.create(BracketCommand).create(direction, character) def computehybridsize(self): "Compute the size of the hybrid function." if not self.command in HybridSize.configsizes: self.computesize() return self.size = HybridSize().getsize(self) # set the size in all elements at first level for element in self.contents: element.size = self.size class HybridSize(object): "The size associated with a hybrid function." configsizes = FormulaConfig.hybridsizes def getsize(self, function): "Read the size for a function and parse it." sizestring = self.configsizes[function.command] for name in function.params: if name in sizestring: size = function.params[name].value.computesize() sizestring = sizestring.replace(name, unicode(size)) if '$' in sizestring: Trace.error('Unconverted variable in hybrid size: ' + sizestring) return 1 return eval(sizestring) FormulaCommand.types += [HybridFunction] elyxer-1.2.5/src/elyxer/maths/postformula.py0000644000175000017500000000606012074107030020471 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20090422 # eLyXer postprocessor for formulae from elyxer.util.numbering import * from elyxer.maths.command import * from elyxer.maths.array import * from elyxer.maths.misc import * from elyxer.proc.postprocess import * from elyxer.ref.link import * from elyxer.ref.label import * from elyxer.ref.partkey import * class PostFormula(object): "Postprocess a formula" processedclass = Formula def postprocess(self, last, formula, next): "Postprocess any formulae" if Options.jsmath or Options.mathjax: return formula self.postnumbering(formula) return formula def postnumbering(self, formula): "Check if it's a numbered equation, insert number." if formula.header[0] != 'numbered': return functions = formula.searchremove(LabelFunction) if len(functions) == 0: label = self.createlabel(formula) elif len(functions) == 1: label = self.createlabel(formula, functions[0]) if len(functions) <= 1: label.parent = formula formula.contents.insert(0, label) return for function in functions: label = self.createlabel(formula, function) row = self.searchrow(function) label.parent = row row.contents.insert(0, label) def createlabel(self, formula, function = None): "Create a new label for a formula." "Add a label to a formula." tag = self.createtag(formula) partkey = PartKey().createformula(tag) if not formula.partkey: formula.partkey = partkey if not function: label = Label() label.create(partkey.tocentry + ' ', 'eq-' + tag, type="eqnumber") else: label = function.label label.complete(partkey.tocentry + ' ') return label def createtag(self, formula): "Create the label tag." tags = formula.searchall(FormulaTag) if len(tags) == 0: return NumberGenerator.chaptered.generate('formula') if len(tags) > 1: Trace.error('More than one tag in formula: ' + unicode(formula)) return tags[0].tag def searchrow(self, function): "Search for the row that contains the label function." if isinstance(function.parent, Formula) or isinstance(function.parent, FormulaRow): return function.parent return self.searchrow(function.parent) Postprocessor.stages.append(PostFormula) elyxer-1.2.5/src/elyxer/maths/misc.py0000644000175000017500000000422012074107030017045 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20110109 # eLyXer misc commands, invoked by class name from the configuration file. from elyxer.util.numbering import * from elyxer.maths.command import * from elyxer.maths.extracommand import * from elyxer.maths.macro import * class SetCounterFunction(CommandBit): "A function which is used in the preamble to set a counter." def parsebit(self, pos): "Parse a function with [] and {} parameters." counter = self.parseliteral(pos) value = self.parseliteral(pos) try: self.setcounter(counter, int(value)) except: Trace.error('Counter ' + counter + ' cannot be set to ' + value) def setcounter(self, counter, value): "Set a global counter." Trace.debug('Setting counter ' + unicode(counter) + ' to ' + unicode(value)) NumberGenerator.generator.getcounter(counter).init(value) class FormulaTag(CommandBit): "A \\tag command." def parsebit(self, pos): "Parse the tag and apply it." self.output = EmptyOutput() self.tag = self.parseliteral(pos) class MiscCommand(CommandBit): "A generic command which maps to a command class." commandmap = FormulaConfig.misccommands def parsebit(self, pos): "Find the right command to parse and parse it." commandtype = globals()[self.translated] return self.parsecommandtype(self.translated, commandtype, pos) FormulaCommand.types += [MiscCommand] elyxer-1.2.5/src/elyxer/maths/formula.py0000644000175000017500000001525112074107030017565 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20090207 # eLyXer formula processing import urllib from elyxer.gen.container import * from elyxer.util.trace import Trace from elyxer.util.clone import * from elyxer.util.docparams import * from elyxer.conf.config import * from elyxer.parse.formulaparse import * from elyxer.proc.formulaproc import * class Formula(Container): "A LaTeX formula" def __init__(self): self.parser = FormulaParser() self.output = TaggedOutput().settag('span class="formula"') def process(self): "Convert the formula to tags" if self.header[0] == 'inline': DocumentParameters.displaymode = False else: DocumentParameters.displaymode = True self.output.settag('div class="formula"', True) if Options.jsmath: self.jsmath() elif Options.mathjax: self.mathjax() elif Options.googlecharts: self.googlecharts() else: self.classic() def jsmath(self): "Make the contents for jsMath." if self.header[0] != 'inline': self.output = TaggedOutput().settag('div class="math"') else: self.output = TaggedOutput().settag('span class="math"') self.contents = [Constant(self.parsed)] def mathjax(self): "Make the contents for MathJax." self.output.tag = 'span class="MathJax_Preview"' tag = 'script type="math/tex' if self.header[0] != 'inline': tag += ';mode=display' self.contents = [TaggedText().constant(self.parsed, tag + '"', True)] def googlecharts(self): "Make the contents using Google Charts http://code.google.com/apis/chart/." url = FormulaConfig.urls['googlecharts'] + urllib.quote_plus(self.parsed) img = '' + self.parsed + '' self.contents = [Constant(img)] def classic(self): "Make the contents using classic output generation with XHTML and CSS." whole = FormulaFactory().parseformula(self.parsed) FormulaProcessor().process(whole) whole.parent = self self.contents = [whole] def parse(self, pos): "Parse using a parse position instead of self.parser." if pos.checkskip('$$'): self.parsedollarblock(pos) elif pos.checkskip('$'): self.parsedollarinline(pos) elif pos.checkskip('\\('): self.parseinlineto(pos, '\\)') elif pos.checkskip('\\['): self.parseblockto(pos, '\\]') else: pos.error('Unparseable formula') self.process() return self def parsedollarinline(self, pos): "Parse a $...$ formula." self.header = ['inline'] self.parsedollar(pos) def parsedollarblock(self, pos): "Parse a $$...$$ formula." self.header = ['block'] self.parsedollar(pos) if not pos.checkskip('$'): pos.error('Formula should be $$...$$, but last $ is missing.') def parsedollar(self, pos): "Parse to the next $." pos.pushending('$') self.parsed = pos.globexcluding('$') pos.popending('$') def parseinlineto(self, pos, limit): "Parse a \\(...\\) formula." self.header = ['inline'] self.parseupto(pos, limit) def parseblockto(self, pos, limit): "Parse a \\[...\\] formula." self.header = ['block'] self.parseupto(pos, limit) def parseupto(self, pos, limit): "Parse a formula that ends with the given command." pos.pushending(limit) self.parsed = pos.glob(lambda: True) pos.popending(limit) def __unicode__(self): "Return a printable representation." if self.partkey and self.partkey.number: return 'Formula (' + self.partkey.number + ')' return 'Unnumbered formula' class WholeFormula(FormulaBit): "Parse a whole formula" def detect(self, pos): "Not outside the formula is enough." return not pos.finished() def parsebit(self, pos): "Parse with any formula bit" while not pos.finished(): self.add(self.factory.parseany(pos)) class FormulaFactory(object): "Construct bits of formula" # bit types will be appended later types = [FormulaSymbol, RawText, FormulaNumber, Bracket, Comment, WhiteSpace] skippedtypes = [Comment, WhiteSpace] defining = False def __init__(self): "Initialize the map of instances." self.instances = dict() def detecttype(self, type, pos): "Detect a bit of a given type." if pos.finished(): return False return self.instance(type).detect(pos) def instance(self, type): "Get an instance of the given type." if not type in self.instances or not self.instances[type]: self.instances[type] = self.create(type) return self.instances[type] def create(self, type): "Create a new formula bit of the given type." return Cloner.create(type).setfactory(self) def clearskipped(self, pos): "Clear any skipped types." while not pos.finished(): if not self.skipany(pos): return return def skipany(self, pos): "Skip any skipped types." for type in self.skippedtypes: if self.instance(type).detect(pos): return self.parsetype(type, pos) return None def parseany(self, pos): "Parse any formula bit at the current location." for type in self.types + self.skippedtypes: if self.detecttype(type, pos): return self.parsetype(type, pos) Trace.error('Unrecognized formula at ' + pos.identifier()) return FormulaConstant(pos.skipcurrent()) def parsetype(self, type, pos): "Parse the given type and return it." bit = self.instance(type) self.instances[type] = None returnedbit = bit.parsebit(pos) if returnedbit: return returnedbit.setfactory(self) return bit def parseformula(self, formula): "Parse a string of text that contains a whole formula." pos = TextPosition(formula) whole = self.create(WholeFormula) if whole.detect(pos): whole.parsebit(pos) return whole # no formula found if not pos.finished(): Trace.error('Unknown formula at: ' + pos.identifier()) whole.add(TaggedBit().constant(formula, 'span class="unknown"')) return whole elyxer-1.2.5/src/elyxer/maths/command.py0000644000175000017500000002077412074107030017544 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20090330 # eLyXer commands in formula processing import unicodedata from elyxer.gen.container import * from elyxer.ref.label import * from elyxer.util.trace import Trace from elyxer.util.clone import * from elyxer.conf.config import * from elyxer.maths.formula import * from elyxer.maths.bits import * class FormulaCommand(FormulaBit): "A LaTeX command inside a formula" types = [] start = FormulaConfig.starts['command'] commandmap = None def detect(self, pos): "Find the current command." return pos.checkfor(FormulaCommand.start) def parsebit(self, pos): "Parse the command." command = self.extractcommand(pos) bit = self.parsewithcommand(command, pos) if bit: return bit if command.startswith('\\up') or command.startswith('\\Up'): upgreek = self.parseupgreek(command, pos) if upgreek: return upgreek if not self.factory.defining: Trace.error('Unknown command ' + command) self.output = TaggedOutput().settag('span class="unknown"') self.add(FormulaConstant(command)) return None def parsewithcommand(self, command, pos): "Parse the command type once we have the command." for type in FormulaCommand.types: if command in type.commandmap: return self.parsecommandtype(command, type, pos) return None def parsecommandtype(self, command, type, pos): "Parse a given command type." bit = self.factory.create(type) bit.setcommand(command) returned = bit.parsebit(pos) if returned: return returned return bit def extractcommand(self, pos): "Extract the command from elyxer.the current position." if not pos.checkskip(FormulaCommand.start): pos.error('Missing command start ' + FormulaCommand.start) return if pos.finished(): return self.emptycommand(pos) if pos.current().isalpha(): # alpha command command = FormulaCommand.start + pos.globalpha() # skip mark of short command pos.checkskip('*') return command # symbol command return FormulaCommand.start + pos.skipcurrent() def emptycommand(self, pos): """Check for an empty command: look for command disguised as ending. Special case against '{ \{ \} }' situation.""" command = '' if not pos.isout(): ending = pos.nextending() if ending and pos.checkskip(ending): command = ending return FormulaCommand.start + command def parseupgreek(self, command, pos): "Parse the Greek \\up command.." if len(command) < 4: return None if command.startswith('\\up'): upcommand = '\\' + command[3:] elif pos.checkskip('\\Up'): upcommand = '\\' + command[3:4].upper() + command[4:] else: Trace.error('Impossible upgreek command: ' + command) return upgreek = self.parsewithcommand(upcommand, pos) if upgreek: upgreek.type = 'font' return upgreek class CommandBit(FormulaCommand): "A formula bit that includes a command" def setcommand(self, command): "Set the command in the bit" self.command = command if self.commandmap: self.original += command self.translated = self.commandmap[self.command] def parseparameter(self, pos): "Parse a parameter at the current position" self.factory.clearskipped(pos) if pos.finished(): return None parameter = self.factory.parseany(pos) self.add(parameter) return parameter def parsesquare(self, pos): "Parse a square bracket" self.factory.clearskipped(pos) if not self.factory.detecttype(SquareBracket, pos): return None bracket = self.factory.parsetype(SquareBracket, pos) self.add(bracket) return bracket def parseliteral(self, pos): "Parse a literal bracket." self.factory.clearskipped(pos) if not self.factory.detecttype(Bracket, pos): if not pos.isvalue(): Trace.error('No literal parameter found at: ' + pos.identifier()) return None return pos.globvalue() bracket = Bracket().setfactory(self.factory) self.add(bracket.parseliteral(pos)) return bracket.literal def parsesquareliteral(self, pos): "Parse a square bracket literally." self.factory.clearskipped(pos) if not self.factory.detecttype(SquareBracket, pos): return None bracket = SquareBracket().setfactory(self.factory) self.add(bracket.parseliteral(pos)) return bracket.literal def parsetext(self, pos): "Parse a text parameter." self.factory.clearskipped(pos) if not self.factory.detecttype(Bracket, pos): Trace.error('No text parameter for ' + self.command) return None bracket = Bracket().setfactory(self.factory).parsetext(pos) self.add(bracket) return bracket class EmptyCommand(CommandBit): "An empty command (without parameters)" commandmap = FormulaConfig.commands def parsebit(self, pos): "Parse a command without parameters" self.contents = [FormulaConstant(self.translated)] class SpacedCommand(CommandBit): "An empty command which should have math spacing in formulas." commandmap = FormulaConfig.spacedcommands def parsebit(self, pos): "Place as contents the command translated and spaced." self.contents = [FormulaConstant(u' ' + self.translated + u' ')] class AlphaCommand(EmptyCommand): "A command without paramters whose result is alphabetical" commandmap = FormulaConfig.alphacommands def parsebit(self, pos): "Parse the command and set type to alpha" EmptyCommand.parsebit(self, pos) self.type = 'alpha' class OneParamFunction(CommandBit): "A function of one parameter" commandmap = FormulaConfig.onefunctions simplified = False def parsebit(self, pos): "Parse a function with one parameter" self.output = TaggedOutput().settag(self.translated) self.parseparameter(pos) self.simplifyifpossible() def simplifyifpossible(self): "Try to simplify to a single character." if self.original in self.commandmap: self.output = FixedOutput() self.html = [self.commandmap[self.original]] self.simplified = True class SymbolFunction(CommandBit): "Find a function which is represented by a symbol (like _ or ^)" commandmap = FormulaConfig.symbolfunctions def detect(self, pos): "Find the symbol" return pos.current() in SymbolFunction.commandmap def parsebit(self, pos): "Parse the symbol" self.setcommand(pos.current()) pos.skip(self.command) self.output = TaggedOutput().settag(self.translated) self.parseparameter(pos) class TextFunction(CommandBit): "A function where parameters are read as text." commandmap = FormulaConfig.textfunctions def parsebit(self, pos): "Parse a text parameter" self.output = TaggedOutput().settag(self.translated) self.parsetext(pos) def process(self): "Set the type to font" self.type = 'font' class LabelFunction(CommandBit): "A function that acts as a label" commandmap = FormulaConfig.labelfunctions def parsebit(self, pos): "Parse a literal parameter" self.key = self.parseliteral(pos) def process(self): "Add an anchor with the label contents." self.type = 'font' self.label = Label().create(' ', self.key, type = 'eqnumber') self.contents = [self.label] # store as a Label so we know it's been seen Label.names[self.key] = self.label class FontFunction(OneParamFunction): "A function of one parameter that changes the font" commandmap = FormulaConfig.fontfunctions def process(self): "Simplify if possible using a single character." self.type = 'font' self.simplifyifpossible() FormulaFactory.types += [FormulaCommand, SymbolFunction] FormulaCommand.types = [ AlphaCommand, EmptyCommand, OneParamFunction, FontFunction, LabelFunction, TextFunction, SpacedCommand, ] elyxer-1.2.5/src/elyxer/maths/macro.py0000644000175000017500000001475012074107030017224 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20100615 # eLyXer macro processing from elyxer.util.trace import Trace from elyxer.conf.config import * from elyxer.parse.formulaparse import * from elyxer.parse.headerparse import * from elyxer.maths.formula import * from elyxer.maths.hybrid import * class MacroDefinition(CommandBit): "A function that defines a new command (a macro)." macros = dict() def parsebit(self, pos): "Parse the function that defines the macro." self.output = EmptyOutput() self.parameternumber = 0 self.defaults = [] self.factory.defining = True self.parseparameters(pos) self.factory.defining = False Trace.debug('New command ' + self.newcommand + ' (' + \ unicode(self.parameternumber) + ' parameters)') self.macros[self.newcommand] = self def parseparameters(self, pos): "Parse all optional parameters (number of parameters, default values)" "and the mandatory definition." self.newcommand = self.parsenewcommand(pos) # parse number of parameters literal = self.parsesquareliteral(pos) if literal: self.parameternumber = int(literal) # parse all default values bracket = self.parsesquare(pos) while bracket: self.defaults.append(bracket) bracket = self.parsesquare(pos) # parse mandatory definition self.definition = self.parseparameter(pos) def parsenewcommand(self, pos): "Parse the name of the new command." self.factory.clearskipped(pos) if self.factory.detecttype(Bracket, pos): return self.parseliteral(pos) if self.factory.detecttype(FormulaCommand, pos): return self.factory.create(FormulaCommand).extractcommand(pos) Trace.error('Unknown formula bit in defining function at ' + pos.identifier()) return 'unknown' def instantiate(self): "Return an instance of the macro." return self.definition.clone() class MacroParameter(FormulaBit): "A parameter from elyxer.a macro." def detect(self, pos): "Find a macro parameter: #n." return pos.checkfor('#') def parsebit(self, pos): "Parse the parameter: #n." if not pos.checkskip('#'): Trace.error('Missing parameter start #.') return self.number = int(pos.skipcurrent()) self.original = '#' + unicode(self.number) self.contents = [TaggedBit().constant('#' + unicode(self.number), 'span class="unknown"')] class MacroFunction(CommandBit): "A function that was defined using a macro." commandmap = MacroDefinition.macros def parsebit(self, pos): "Parse a number of input parameters." self.output = FilteredOutput() self.values = [] macro = self.translated self.parseparameters(pos, macro) self.completemacro(macro) def parseparameters(self, pos, macro): "Parse as many parameters as are needed." self.parseoptional(pos, list(macro.defaults)) self.parsemandatory(pos, macro.parameternumber - len(macro.defaults)) if len(self.values) < macro.parameternumber: Trace.error('Missing parameters in macro ' + unicode(self)) def parseoptional(self, pos, defaults): "Parse optional parameters." optional = [] while self.factory.detecttype(SquareBracket, pos): optional.append(self.parsesquare(pos)) if len(optional) > len(defaults): break for value in optional: default = defaults.pop() if len(value.contents) > 0: self.values.append(value) else: self.values.append(default) self.values += defaults def parsemandatory(self, pos, number): "Parse a number of mandatory parameters." for index in range(number): parameter = self.parsemacroparameter(pos, number - index) if not parameter: return self.values.append(parameter) def parsemacroparameter(self, pos, remaining): "Parse a macro parameter. Could be a bracket or a single letter." "If there are just two values remaining and there is a running number," "parse as two separater numbers." self.factory.clearskipped(pos) if pos.finished(): return None if self.factory.detecttype(FormulaNumber, pos): return self.parsenumbers(pos, remaining) return self.parseparameter(pos) def parsenumbers(self, pos, remaining): "Parse the remaining parameters as a running number." "For example, 12 would be {1}{2}." number = self.factory.parsetype(FormulaNumber, pos) if not len(number.original) == remaining: return number for digit in number.original: value = self.factory.create(FormulaNumber) value.add(FormulaConstant(digit)) value.type = number self.values.append(value) return None def completemacro(self, macro): "Complete the macro with the parameters read." self.contents = [macro.instantiate()] replaced = [False] * len(self.values) for parameter in self.searchall(MacroParameter): index = parameter.number - 1 if index >= len(self.values): Trace.error('Macro parameter index out of bounds: ' + unicode(index)) return replaced[index] = True parameter.contents = [self.values[index].clone()] for index in range(len(self.values)): if not replaced[index]: self.addfilter(index, self.values[index]) def addfilter(self, index, value): "Add a filter for the given parameter number and parameter value." original = '#' + unicode(index + 1) value = ''.join(self.values[0].gethtml()) self.output.addfilter(original, value) class FormulaMacro(Formula): "A math macro defined in an inset." def __init__(self): self.parser = MacroParser() self.output = EmptyOutput() def __unicode__(self): "Return a printable representation." return 'Math macro' FormulaFactory.types += [ MacroParameter ] FormulaCommand.types += [ MacroFunction, ] elyxer-1.2.5/src/elyxer/maths/bits.py0000644000175000017500000001737612074107030017073 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20090614 # eLyXer formula bits from elyxer.util.trace import Trace from elyxer.conf.config import * from elyxer.maths.formula import * class FormulaBit(Container): "A bit of a formula" type = None size = 1 original = '' def __init__(self): "The formula bit type can be 'alpha', 'number', 'font'." self.contents = [] self.output = ContentsOutput() def setfactory(self, factory): "Set the internal formula factory." self.factory = factory return self def add(self, bit): "Add any kind of formula bit already processed" self.contents.append(bit) self.original += bit.original bit.parent = self def skiporiginal(self, string, pos): "Skip a string and add it to the original formula" self.original += string if not pos.checkskip(string): Trace.error('String ' + string + ' not at ' + pos.identifier()) def computesize(self): "Compute the size of the bit as the max of the sizes of all contents." if len(self.contents) == 0: return 1 self.size = max([element.size for element in self.contents]) return self.size def clone(self): "Return a copy of itself." return self.factory.parseformula(self.original) def __unicode__(self): "Get a string representation" return self.__class__.__name__ + ' read in ' + self.original class TaggedBit(FormulaBit): "A tagged string in a formula" def constant(self, constant, tag): "Set the constant and the tag" self.output = TaggedOutput().settag(tag) self.add(FormulaConstant(constant)) return self def complete(self, contents, tag, breaklines = False): "Set the constant and the tag" self.contents = contents self.output = TaggedOutput().settag(tag, breaklines) return self def selfcomplete(self, tag): "Set the self-closing tag, no contents (as in
)." self.output = TaggedOutput().settag(tag, empty = True) return self class FormulaConstant(Constant): "A constant string in a formula" def __init__(self, string): "Set the constant string" Constant.__init__(self, string) self.original = string self.size = 1 self.type = None def computesize(self): "Compute the size of the constant: always 1." return self.size def clone(self): "Return a copy of itself." return FormulaConstant(self.original) def __unicode__(self): "Return a printable representation." return 'Formula constant: ' + self.string class RawText(FormulaBit): "A bit of text inside a formula" def detect(self, pos): "Detect a bit of raw text" return pos.current().isalpha() def parsebit(self, pos): "Parse alphabetic text" alpha = pos.globalpha() self.add(FormulaConstant(alpha)) self.type = 'alpha' class FormulaSymbol(FormulaBit): "A symbol inside a formula" modified = FormulaConfig.modified unmodified = FormulaConfig.unmodified['characters'] def detect(self, pos): "Detect a symbol" if pos.current() in FormulaSymbol.unmodified: return True if pos.current() in FormulaSymbol.modified: return True return False def parsebit(self, pos): "Parse the symbol" if pos.current() in FormulaSymbol.unmodified: self.addsymbol(pos.current(), pos) return if pos.current() in FormulaSymbol.modified: self.addsymbol(FormulaSymbol.modified[pos.current()], pos) return Trace.error('Symbol ' + pos.current() + ' not found') def addsymbol(self, symbol, pos): "Add a symbol" self.skiporiginal(pos.current(), pos) self.contents.append(FormulaConstant(symbol)) class FormulaNumber(FormulaBit): "A string of digits in a formula" def detect(self, pos): "Detect a digit" return pos.current().isdigit() def parsebit(self, pos): "Parse a bunch of digits" digits = pos.glob(lambda: pos.current().isdigit()) self.add(FormulaConstant(digits)) self.type = 'number' class Comment(FormulaBit): "A LaTeX comment: % to the end of the line." start = FormulaConfig.starts['comment'] def detect(self, pos): "Detect the %." return pos.current() == self.start def parsebit(self, pos): "Parse to the end of the line." self.original += pos.globincluding('\n') class WhiteSpace(FormulaBit): "Some white space inside a formula." def detect(self, pos): "Detect the white space." return pos.current().isspace() def parsebit(self, pos): "Parse all whitespace." self.original += pos.skipspace() def __unicode__(self): "Return a printable representation." return 'Whitespace: *' + self.original + '*' class Bracket(FormulaBit): "A {} bracket inside a formula" start = FormulaConfig.starts['bracket'] ending = FormulaConfig.endings['bracket'] def __init__(self): "Create a (possibly literal) new bracket" FormulaBit.__init__(self) self.inner = None def detect(self, pos): "Detect the start of a bracket" return pos.checkfor(self.start) def parsebit(self, pos): "Parse the bracket" self.parsecomplete(pos, self.innerformula) return self def parsetext(self, pos): "Parse a text bracket" self.parsecomplete(pos, self.innertext) return self def parseliteral(self, pos): "Parse a literal bracket" self.parsecomplete(pos, self.innerliteral) return self def parsecomplete(self, pos, innerparser): "Parse the start and end marks" if not pos.checkfor(self.start): Trace.error('Bracket should start with ' + self.start + ' at ' + pos.identifier()) return None self.skiporiginal(self.start, pos) pos.pushending(self.ending) innerparser(pos) self.original += pos.popending(self.ending) self.computesize() def innerformula(self, pos): "Parse a whole formula inside the bracket" while not pos.finished(): self.add(self.factory.parseany(pos)) def innertext(self, pos): "Parse some text inside the bracket, following textual rules." specialchars = FormulaConfig.symbolfunctions.keys() specialchars.append(FormulaConfig.starts['command']) specialchars.append(FormulaConfig.starts['bracket']) specialchars.append(Comment.start) while not pos.finished(): if pos.current() in specialchars: self.add(self.factory.parseany(pos)) if pos.checkskip(' '): self.original += ' ' else: self.add(FormulaConstant(pos.skipcurrent())) def innerliteral(self, pos): "Parse a literal inside the bracket, which does not generate HTML." self.literal = '' while not pos.finished() and not pos.current() == self.ending: if pos.current() == self.start: self.parseliteral(pos) else: self.literal += pos.skipcurrent() self.original += self.literal class SquareBracket(Bracket): "A [] bracket inside a formula" start = FormulaConfig.starts['squarebracket'] ending = FormulaConfig.endings['squarebracket'] def clone(self): "Return a new square bracket with the same contents." bracket = SquareBracket() bracket.contents = self.contents return bracket elyxer-1.2.5/src/elyxer/maths/extracommand.py0000644000175000017500000002147512074107030020607 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20101218 # eLyXer extra commands for unusual things. from elyxer.util.trace import Trace from elyxer.util.clone import * from elyxer.conf.config import * from elyxer.maths.command import * from elyxer.maths.symbol import * from elyxer.maths.array import * import datetime class CombiningFunction(OneParamFunction): commandmap = FormulaConfig.combiningfunctions def parsebit(self, pos): "Parse a combining function." self.type = 'alpha' combining = self.translated parameter = self.parsesingleparameter(pos) if not parameter: Trace.error('Empty parameter for combining function ' + self.command) elif len(parameter.extracttext()) != 1: Trace.error('Applying combining function ' + self.command + ' to invalid string "' + parameter.extracttext() + '"') self.contents.append(Constant(combining)) def parsesingleparameter(self, pos): "Parse a parameter, or a single letter." self.factory.clearskipped(pos) if pos.finished(): Trace.error('Error while parsing single parameter at ' + pos.identifier()) return None if self.factory.detecttype(Bracket, pos) \ or self.factory.detecttype(FormulaCommand, pos): return self.parseparameter(pos) letter = FormulaConstant(pos.skipcurrent()) self.add(letter) return letter class DecoratingFunction(OneParamFunction): "A function that decorates some bit of text" commandmap = FormulaConfig.decoratingfunctions def parsebit(self, pos): "Parse a decorating function" self.type = 'alpha' symbol = self.translated self.symbol = TaggedBit().constant(symbol, 'span class="symbolover"') self.parameter = self.parseparameter(pos) self.output = TaggedOutput().settag('span class="withsymbol"') self.contents.insert(0, self.symbol) self.parameter.output = TaggedOutput().settag('span class="undersymbol"') self.simplifyifpossible() class LimitCommand(EmptyCommand): "A command which accepts limits above and below, in display mode." commandmap = FormulaConfig.limitcommands def parsebit(self, pos): "Parse a limit command." pieces = BigSymbol(self.translated).getpieces() self.output = TaggedOutput().settag('span class="limits"') for piece in pieces: self.contents.append(TaggedBit().constant(piece, 'span class="limit"')) class LimitPreviousCommand(LimitCommand): "A command to limit the previous command." commandmap = None def parsebit(self, pos): "Do nothing." self.output = TaggedOutput().settag('span class="limits"') self.factory.clearskipped(pos) def __unicode__(self): "Return a printable representation." return 'Limit previous command' class LimitsProcessor(MathsProcessor): "A processor for limits inside an element." def process(self, contents, index): "Process the limits for an element." if Options.simplemath: return if self.checklimits(contents, index): self.modifylimits(contents, index) if self.checkscript(contents, index) and self.checkscript(contents, index + 1): self.modifyscripts(contents, index) def checklimits(self, contents, index): "Check if the current position has a limits command." if not DocumentParameters.displaymode: return False if self.checkcommand(contents, index + 1, LimitPreviousCommand): self.limitsahead(contents, index) return False if not isinstance(contents[index], LimitCommand): return False return self.checkscript(contents, index + 1) def limitsahead(self, contents, index): "Limit the current element based on the next." contents[index + 1].add(contents[index].clone()) contents[index].output = EmptyOutput() def modifylimits(self, contents, index): "Modify a limits commands so that the limits appear above and below." limited = contents[index] subscript = self.getlimit(contents, index + 1) limited.contents.append(subscript) if self.checkscript(contents, index + 1): superscript = self.getlimit(contents, index + 1) else: superscript = TaggedBit().constant(u' ', 'sup class="limit"') limited.contents.insert(0, superscript) def getlimit(self, contents, index): "Get the limit for a limits command." limit = self.getscript(contents, index) limit.output.tag = limit.output.tag.replace('script', 'limit') return limit def modifyscripts(self, contents, index): "Modify the super- and subscript to appear vertically aligned." subscript = self.getscript(contents, index) # subscript removed so instead of index + 1 we get index again superscript = self.getscript(contents, index) scripts = TaggedBit().complete([superscript, subscript], 'span class="scripts"') contents.insert(index, scripts) def checkscript(self, contents, index): "Check if the current element is a sub- or superscript." return self.checkcommand(contents, index, SymbolFunction) def checkcommand(self, contents, index, type): "Check for the given type as the current element." if len(contents) <= index: return False return isinstance(contents[index], type) def getscript(self, contents, index): "Get the sub- or superscript." bit = contents[index] bit.output.tag += ' class="script"' del contents[index] return bit class BracketCommand(OneParamFunction): "A command which defines a bracket." commandmap = FormulaConfig.bracketcommands def parsebit(self, pos): "Parse the bracket." OneParamFunction.parsebit(self, pos) def create(self, direction, character): "Create the bracket for the given character." self.original = character self.command = '\\' + direction self.contents = [FormulaConstant(character)] return self class BracketProcessor(MathsProcessor): "A processor for bracket commands." def process(self, contents, index): "Convert the bracket using Unicode pieces, if possible." if Options.simplemath: return if self.checkleft(contents, index): return self.processleft(contents, index) def processleft(self, contents, index): "Process a left bracket." rightindex = self.findright(contents, index + 1) if not rightindex: return size = self.findmax(contents, index, rightindex) self.resize(contents[index], size) self.resize(contents[rightindex], size) def checkleft(self, contents, index): "Check if the command at the given index is left." return self.checkdirection(contents[index], '\\left') def checkright(self, contents, index): "Check if the command at the given index is right." return self.checkdirection(contents[index], '\\right') def checkdirection(self, bit, command): "Check if the given bit is the desired bracket command." if not isinstance(bit, BracketCommand): return False return bit.command == command def findright(self, contents, index): "Find the right bracket starting at the given index, or 0." depth = 1 while index < len(contents): if self.checkleft(contents, index): depth += 1 if self.checkright(contents, index): depth -= 1 if depth == 0: return index index += 1 return None def findmax(self, contents, leftindex, rightindex): "Find the max size of the contents between the two given indices." sliced = contents[leftindex:rightindex] return max([element.size for element in sliced]) def resize(self, command, size): "Resize a bracket command to the given size." character = command.extracttext() alignment = command.command.replace('\\', '') bracket = BigBracket(size, character, alignment) command.output = ContentsOutput() command.contents = bracket.getcontents() class TodayCommand(EmptyCommand): "Shows today's date." commandmap = None def parsebit(self, pos): "Parse a command without parameters" self.output = FixedOutput() self.html = [datetime.date.today().strftime('%b %d, %Y')] FormulaCommand.types += [ DecoratingFunction, CombiningFunction, LimitCommand, BracketCommand, ] FormulaProcessor.processors += [ LimitsProcessor(), BracketProcessor(), ] elyxer-1.2.5/src/elyxer/maths/array.py0000644000175000017500000001515512112242377017250 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20090427 # eLyXer arrays in formulae from elyxer.gen.container import * from elyxer.util.trace import Trace from elyxer.util.clone import * from elyxer.conf.config import * from elyxer.maths.formula import * from elyxer.maths.command import * from elyxer.maths.symbol import * class FormulaEquation(CommandBit): "A simple numbered equation." piece = 'equation' def parsebit(self, pos): "Parse the array" self.output = ContentsOutput() self.add(self.factory.parsetype(WholeFormula, pos)) class FormulaCell(FormulaCommand): "An array cell inside a row" def setalignment(self, alignment): self.alignment = alignment self.output = TaggedOutput().settag('span class="arraycell align-' + alignment +'"', True) return self def parsebit(self, pos): self.factory.clearskipped(pos) if pos.finished(): return self.add(self.factory.parsetype(WholeFormula, pos)) class FormulaRow(FormulaCommand): "An array row inside an array" cellseparator = FormulaConfig.array['cellseparator'] def setalignments(self, alignments): self.alignments = alignments self.output = TaggedOutput().settag('span class="arrayrow"', True) return self def parsebit(self, pos): "Parse a whole row" index = 0 pos.pushending(self.cellseparator, optional=True) while not pos.finished(): cell = self.createcell(index) cell.parsebit(pos) self.add(cell) index += 1 pos.checkskip(self.cellseparator) if len(self.contents) == 0: self.output = EmptyOutput() def createcell(self, index): "Create the cell that corresponds to the given index." alignment = self.alignments[index % len(self.alignments)] return self.factory.create(FormulaCell).setalignment(alignment) class MultiRowFormula(CommandBit): "A formula with multiple rows." def parserows(self, pos): "Parse all rows, finish when no more row ends" self.rows = [] first = True for row in self.iteraterows(pos): if first: first = False else: # intersparse empty rows self.addempty() row.parsebit(pos) self.addrow(row) self.size = len(self.rows) def iteraterows(self, pos): "Iterate over all rows, end when no more row ends" rowseparator = FormulaConfig.array['rowseparator'] while True: pos.pushending(rowseparator, True) row = self.factory.create(FormulaRow) yield row.setalignments(self.alignments) if pos.checkfor(rowseparator): self.original += pos.popending(rowseparator) else: return def addempty(self): "Add an empty row." row = self.factory.create(FormulaRow).setalignments(self.alignments) for index, originalcell in enumerate(self.rows[-1].contents): cell = row.createcell(index) cell.add(FormulaConstant(u' ')) row.add(cell) self.addrow(row) def addrow(self, row): "Add a row to the contents and to the list of rows." self.rows.append(row) self.add(row) class FormulaArray(MultiRowFormula): "An array within a formula" piece = 'array' def parsebit(self, pos): "Parse the array" self.output = TaggedOutput().settag('span class="array"', False) self.parsealignments(pos) self.parserows(pos) def parsealignments(self, pos): "Parse the different alignments" # vertical self.valign = 'c' literal = self.parsesquareliteral(pos) if literal: self.valign = literal # horizontal literal = self.parseliteral(pos) self.alignments = [] for l in literal: self.alignments.append(l) class FormulaMatrix(MultiRowFormula): "A matrix (array with center alignment)." piece = 'matrix' def parsebit(self, pos): "Parse the matrix, set alignments to 'c'." self.output = TaggedOutput().settag('span class="array"', False) self.valign = 'c' self.alignments = ['c'] self.parserows(pos) class FormulaCases(MultiRowFormula): "A cases statement" piece = 'cases' def parsebit(self, pos): "Parse the cases" self.output = ContentsOutput() self.alignments = ['l', 'l'] self.parserows(pos) for row in self.contents: for cell in row.contents: cell.output.settag('span class="case align-l"', True) cell.contents.append(FormulaConstant(u' ')) array = TaggedBit().complete(self.contents, 'span class="bracketcases"', True) brace = BigBracket(len(self.contents), '{', 'l') self.contents = brace.getcontents() + [array] class EquationEnvironment(MultiRowFormula): "A \\begin{}...\\end equation environment with rows and cells." def parsebit(self, pos): "Parse the whole environment." self.output = TaggedOutput().settag('span class="environment"', False) environment = self.piece.replace('*', '') if environment in FormulaConfig.environments: self.alignments = FormulaConfig.environments[environment] else: Trace.error('Unknown equation environment ' + self.piece) self.alignments = ['l'] self.parserows(pos) class BeginCommand(CommandBit): "A \\begin{}...\end command and what it entails (array, cases, aligned)" commandmap = {FormulaConfig.array['begin']:''} types = [FormulaEquation, FormulaArray, FormulaCases, FormulaMatrix] def parsebit(self, pos): "Parse the begin command" command = self.parseliteral(pos) bit = self.findbit(command) ending = FormulaConfig.array['end'] + '{' + command + '}' pos.pushending(ending) bit.parsebit(pos) self.add(bit) self.original += pos.popending(ending) self.size = bit.size def findbit(self, piece): "Find the command bit corresponding to the \\begin{piece}" for type in BeginCommand.types: if piece.replace('*', '') == type.piece: return self.factory.create(type) bit = self.factory.create(EquationEnvironment) bit.piece = piece return bit FormulaCommand.types += [BeginCommand] elyxer-1.2.5/src/elyxer/maths/__init__.py0000644000175000017500000000000012074107030017641 0ustar chennochennoelyxer-1.2.5/src/elyxer/out/0000755000175000017500000000000012117175142015244 5ustar chennochennoelyxer-1.2.5/src/elyxer/out/template.py0000644000175000017500000002434612074107030017433 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20100620 # eLyXer HTML templates import datetime from elyxer.io.bulk import * from elyxer.parse.position import * from elyxer.util.trace import Trace from elyxer.util.options import * from elyxer.util.translate import * from elyxer.util.docparams import * from elyxer.out.output import * class HTMLTemplate(object): "A template for HTML generation." current = None def getheader(self): "Get the header (before content) of the template." return [] def convertheader(self): "Convert the header and all variables." return self.convert(self.getheader()) def convertfooter(self): "Convert the footer and all variables." return self.convert(self.getfooter()) def convert(self, html): "Convert a bit of HTML replacing all variables." varmap = VariableMap() for index, line in enumerate(html): if '\n'] def getfooter(self): "Get the raw footer." return ['\n\n'] class FileTemplate(HTMLTemplate): "A template read from elyxer.a file." divider = '' def read(self): "Read the file, separate header and footer." self.header = [] lines = [] for line in self.templatelines(): if FileTemplate.divider == line: self.header = lines lines = [] else: lines.append(line) if self.header == []: Trace.error('No ' + FileTemplate.divider + ' in template') self.header = lines lines = [] self.footer = lines return self def templatelines(self): "Read all lines in the template, separate content into its own line." template = BulkFile(Options.template).readall() for line in template: if not FileTemplate.divider in line: yield line else: split = line.split(FileTemplate.divider) for part in split[:-1]: yield part yield FileTemplate.divider yield split[-1] def getheader(self): "Return the header (before content)." return self.header def getfooter(self): "Return the footer (after the content)." return self.footer class DefaultTemplate(HTMLTemplate): "The default HTML template when not configured." def getheader(self): "Get the default header (before content)." html = [] if not Options.html: html.append(u'"?>\n') html.append(u'\n') html.append(u'\n') else: html.append(u'\n') html.append(u'\n') html.append(u'\n') html.append(u'\n') html.append(u'\n') html.append(u'\n') html += self.getcss() html.append(u'<!--$title-->\n') if Options.jsmath: html.append(u'\n') html.append(u'\n') if Options.mathjax: if Options.mathjax == 'remote': html.append(u'\n') else: html.append(u'\n') html.append('\n') html.append('\n') html.append('
\n') if Options.jsmath or Options.mathjax: if Options.mathjax: html.append(u'\n') html.append(u'\n') return html def getcss(self): "Get the CSS headers, both linked and embedded." html = [] for cssdoc in Options.css: if cssdoc != '': html.append(u'\n') for cssfile in Options.embedcss: html.append(u'\n') return html def getfooter(self): "Get the default footer (after content)." html = [] html.append('\n') footer = self.createfooter() if len(footer) > 0: html.append('\n') html += footer html.append('
\n') html.append('\n') html.append('\n') return html def createfooter(self): "Create the footer proper." html = [] if Options.copyright: html.append('\n') if Options.nofooter: return html html.append('\n') return html class VariableMap(object): "A map with all replacement variables." def __init__(self): self.variables = dict() self.variables['title'] = DocumentTitle().getvalue() self.variables['author'] = DocumentAuthor().getvalue() self.variables['version'] = GeneralConfig.version['number'] + ' (' \ + GeneralConfig.version['date'] + ')' self.variables['year'] = unicode(datetime.date.today().year) self.variables['date'] = datetime.date.today().isoformat() self.variables['datetime'] = datetime.datetime.now().isoformat() self.variables['css'] = Options.css[0] if Options.iso885915: self.variables['encoding'] = 'ISO-8859-1' else: self.variables['encoding'] = 'UTF-8' if Options.jsmath: self.variables['jsmath'] = Options.jsmath if Options.mathjax: self.variables['mathjax'] = Options.mathjax def replace(self, line): "Replace all variables in a line." result = '' pos = TextPosition(line) while not pos.finished(): if pos.checkskip(''): Trace.error('Weird template format in ' + line) return value class DocumentTitle(object): "The title of the whole document." title = None def getvalue(self): "Return the correct title from elyxer.the option or the PDF title." if Options.title: return Options.title if DocumentTitle.title: return DocumentTitle.title if DocumentParameters.pdftitle: return DocumentParameters.pdftitle return 'Converted document' class DocumentAuthor(object): "The author of the document." author = '' def appendauthor(cls, authorline): "Append a line with author information." cls.author += authorline appendauthor = classmethod(appendauthor) def getvalue(self): "Get the document author." return DocumentAuthor.author class HeaderOutput(ContainerOutput): "Returns the HTML headers" def gethtml(self, container): "Return a constant header" return HTMLTemplate.get().convertheader() class FooterOutput(ContentsOutput): "Return the HTML code for the footer" def gethtml(self, container): "Footer HTML" contents = ContentsOutput.gethtml(self, container) return contents + HTMLTemplate.get().convertfooter() elyxer-1.2.5/src/elyxer/out/output.py0000644000175000017500000001071212074107030017150 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20090203 # eLyXer html outputters from elyxer.util.trace import Trace class ContainerOutput(object): "The generic HTML output for a container." def gethtml(self, container): "Show an error." Trace.error('gethtml() not implemented for ' + unicode(self)) def isempty(self): "Decide if the output is empty: by default, not empty." return False class EmptyOutput(ContainerOutput): def gethtml(self, container): "Return empty HTML code." return [] def isempty(self): "This output is particularly empty." return True class FixedOutput(ContainerOutput): "Fixed output" def gethtml(self, container): "Return constant HTML code" return container.html class ContentsOutput(ContainerOutput): "Outputs the contents converted to HTML" def gethtml(self, container): "Return the HTML code" html = [] if container.contents == None: return html for element in container.contents: if not hasattr(element, 'gethtml'): Trace.error('No html in ' + element.__class__.__name__ + ': ' + unicode(element)) return html html += element.gethtml() return html class TaggedOutput(ContentsOutput): "Outputs an HTML tag surrounding the contents." tag = None breaklines = False empty = False def settag(self, tag, breaklines=False, empty=False): "Set the value for the tag and other attributes." self.tag = tag if breaklines: self.breaklines = breaklines if empty: self.empty = empty return self def setbreaklines(self, breaklines): "Set the value for breaklines." self.breaklines = breaklines return self def gethtml(self, container): "Return the HTML code." if self.empty: return [self.selfclosing(container)] html = [self.open(container)] html += ContentsOutput.gethtml(self, container) html.append(self.close(container)) return html def open(self, container): "Get opening line." if not self.checktag(): return '' open = '<' + self.tag + '>' if self.breaklines: return open + '\n' return open def close(self, container): "Get closing line." if not self.checktag(): return '' close = '' if self.breaklines: return '\n' + close + '\n' return close def selfclosing(self, container): "Get self-closing line." if not self.checktag(): return '' selfclosing = '<' + self.tag + '/>' if self.breaklines: return selfclosing + '\n' return selfclosing def checktag(self): "Check that the tag is valid." if not self.tag: Trace.error('No tag in ' + unicode(container)) return False if self.tag == '': return False return True class FilteredOutput(ContentsOutput): "Returns the output in the contents, but filtered:" "some strings are replaced by others." def __init__(self): "Initialize the filters." self.filters = [] def addfilter(self, original, replacement): "Add a new filter: replace the original by the replacement." self.filters.append((original, replacement)) def gethtml(self, container): "Return the HTML code" result = [] html = ContentsOutput.gethtml(self, container) for line in html: result.append(self.filter(line)) return result def filter(self, line): "Filter a single line with all available filters." for original, replacement in self.filters: if original in line: line = line.replace(original, replacement) return line class StringOutput(ContainerOutput): "Returns a bare string as output" def gethtml(self, container): "Return a bare string" return [container.string] elyxer-1.2.5/src/elyxer/out/__init__.py0000644000175000017500000000000012074107030017334 0ustar chennochennoelyxer-1.2.5/src/elyxer/gen/0000755000175000017500000000000012117175142015206 5ustar chennochennoelyxer-1.2.5/src/elyxer/gen/container.py0000644000175000017500000002122512074107030017535 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20090131 # eLyXer containers for Lyx data that output HTML from elyxer.util.trace import Trace from elyxer.util.clone import * from elyxer.parse.parser import * from elyxer.out.output import * from elyxer.conf.config import * from elyxer.parse.position import * class Container(object): "A container for text and objects in a lyx file" partkey = None parent = None begin = None def __init__(self): self.contents = list() def process(self): "Process contents" pass def gethtml(self): "Get the resulting HTML" html = self.output.gethtml(self) if isinstance(html, basestring): Trace.error('Raw string ' + html) html = [html] return self.escapeall(html) def escapeall(self, lines): "Escape all lines in an array according to the output options." result = [] for line in lines: if Options.html: line = self.escape(line, EscapeConfig.html) if Options.iso885915: line = self.escape(line, EscapeConfig.iso885915) line = self.escapeentities(line) elif not Options.unicode: line = self.escape(line, EscapeConfig.nonunicode) result.append(line) return result def escape(self, line, replacements = EscapeConfig.entities): "Escape a line with replacements from elyxer.a map" pieces = replacements.keys() # do them in order pieces.sort() for piece in pieces: if piece in line: line = line.replace(piece, replacements[piece]) return line def escapeentities(self, line): "Escape all Unicode characters to HTML entities." result = '' pos = TextPosition(line) while not pos.finished(): if ord(pos.current()) > 128: codepoint = hex(ord(pos.current())) if codepoint == '0xd835': codepoint = hex(ord(pos.next()) + 0xf800) result += '&#' + codepoint[1:] + ';' else: result += pos.current() pos.skipcurrent() return result def searchall(self, type): "Search for all embedded containers of a given type" list = [] self.searchprocess(type, lambda container: list.append(container)) return list def searchremove(self, type): "Search for all containers of a type and remove them" list = self.searchall(type) for container in list: container.parent.contents.remove(container) return list def searchprocess(self, type, process): "Search for elements of a given type and process them" self.locateprocess(lambda container: isinstance(container, type), process) def locateprocess(self, locate, process): "Search for all embedded containers and process them" for container in self.contents: container.locateprocess(locate, process) if locate(container): process(container) def recursivesearch(self, locate, recursive, process): "Perform a recursive search in the container." for container in self.contents: if recursive(container): container.recursivesearch(locate, recursive, process) if locate(container): process(container) def extracttext(self): "Extract all text from elyxer.allowed containers." result = '' constants = ContainerExtractor(ContainerConfig.extracttext).extract(self) for constant in constants: result += constant.string return result def group(self, index, group, isingroup): "Group some adjoining elements into a group" if index >= len(self.contents): return if hasattr(self.contents[index], 'grouped'): return while index < len(self.contents) and isingroup(self.contents[index]): self.contents[index].grouped = True group.contents.append(self.contents[index]) self.contents.pop(index) self.contents.insert(index, group) def remove(self, index): "Remove a container but leave its contents" container = self.contents[index] self.contents.pop(index) while len(container.contents) > 0: self.contents.insert(index, container.contents.pop()) def tree(self, level = 0): "Show in a tree" Trace.debug(" " * level + unicode(self)) for container in self.contents: container.tree(level + 1) def getparameter(self, name): "Get the value of a parameter, if present." if not name in self.parameters: return None return self.parameters[name] def getparameterlist(self, name): "Get the value of a comma-separated parameter as a list." paramtext = self.getparameter(name) if not paramtext: return [] return paramtext.split(',') def hasemptyoutput(self): "Check if the parent's output is empty." current = self.parent while current: if current.output.isempty(): return True current = current.parent return False def __unicode__(self): "Get a description" if not self.begin: return self.__class__.__name__ return self.__class__.__name__ + '@' + unicode(self.begin) class BlackBox(Container): "A container that does not output anything" def __init__(self): self.parser = LoneCommand() self.output = EmptyOutput() self.contents = [] class LyXFormat(BlackBox): "Read the lyxformat command" def process(self): "Show warning if version < 276" version = int(self.header[1]) if version < 276: Trace.error('Warning: unsupported old format version ' + str(version)) if version > int(GeneralConfig.version['lyxformat']): Trace.error('Warning: unsupported new format version ' + str(version)) class StringContainer(Container): "A container for a single string" parsed = None def __init__(self): self.parser = StringParser() self.output = StringOutput() self.string = '' def process(self): "Replace special chars from elyxer.the contents." if self.parsed: self.string = self.replacespecial(self.parsed) self.parsed = None def replacespecial(self, line): "Replace all special chars from elyxer.a line" replaced = self.escape(line, EscapeConfig.entities) replaced = self.changeline(replaced) if ContainerConfig.string['startcommand'] in replaced and len(replaced) > 1: # unprocessed commands if self.begin: message = 'Unknown command at ' + unicode(self.begin) + ': ' else: message = 'Unknown command: ' Trace.error(message + replaced.strip()) return replaced def changeline(self, line): line = self.escape(line, EscapeConfig.chars) if not ContainerConfig.string['startcommand'] in line: return line line = self.escape(line, EscapeConfig.commands) return line def extracttext(self): "Return all text." return self.string def __unicode__(self): "Return a printable representation." result = 'StringContainer' if self.begin: result += '@' + unicode(self.begin) ellipsis = '...' if len(self.string.strip()) <= 15: ellipsis = '' return result + ' (' + self.string.strip()[:15] + ellipsis + ')' class Constant(StringContainer): "A constant string" def __init__(self, text): self.contents = [] self.string = text self.output = StringOutput() def __unicode__(self): return 'Constant: ' + self.string class TaggedText(Container): "Text inside a tag" output = None def __init__(self): self.parser = TextParser(self) self.output = TaggedOutput() def complete(self, contents, tag, breaklines=False): "Complete the tagged text and return it" self.contents = contents self.output.tag = tag self.output.breaklines = breaklines return self def constant(self, text, tag, breaklines=False): "Complete the tagged text with a constant" constant = Constant(text) return self.complete([constant], tag, breaklines) def __unicode__(self): "Return a printable representation." if not hasattr(self.output, 'tag'): return 'Emtpy tagged text' if not self.output.tag: return 'Tagged ' return 'Tagged <' + self.output.tag + '>' elyxer-1.2.5/src/elyxer/gen/toc.py0000644000175000017500000001300712074107030016337 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20091006 # eLyXer TOC generation # http://www.nongnu.org/elyxer/ from elyxer.gen.header import * from elyxer.ref.label import * from elyxer.util.docparams import * class TOCEntry(Container): "A container for a TOC entry." def __init__(self): Container.__init__(self) self.branches = [] def create(self, container): "Create the TOC entry for a container, consisting of a single link." if container.partkey.header: return self.header(container) self.contents = [self.createlink(container)] self.output = TaggedOutput().settag('div class="toc"', True) self.partkey = container.partkey return self def header(self, container): "Create a TOC entry for header and footer (0 depth)." self.partkey = container.partkey self.output = EmptyOutput() return self def createlink(self, container): "Create the link that will make the whole TOC entry." labels = container.searchall(Label) link = Link() if self.isanchor(labels): link.url = '#' + container.partkey.partkey if Options.tocfor: link.url = Options.tocfor + link.url else: label = labels[0] link.destination = label if container.partkey.tocentry: link.complete(container.partkey.tocentry) if container.partkey.titlecontents: if Options.notoclabels: separator = u' ' else: separator = u': ' if container.partkey.tocentry: link.contents.append(Constant(separator)) link.contents += container.partkey.titlecontents return link def isanchor(self, labels): "Decide if the link is an anchor based on a set of labels." if len(labels) == 0: return True if not Options.tocfor: return False if Options.splitpart: return False return True def __unicode__(self): "Return a printable representation." if not self.partkey.tocentry: return 'Unnamed TOC entry' return 'TOC entry: ' + self.partkey.tocentry class Indenter(object): "Manages and writes indentation for the TOC." def __init__(self): self.depth = 0 def getindent(self, depth): indent = '' if depth > self.depth: indent = self.openindent(depth - self.depth) elif depth < self.depth: indent = self.closeindent(self.depth - depth) self.depth = depth return Constant(indent) def openindent(self, times): "Open the indenting div a few times." indent = '' for i in range(times): indent += '
\n' return indent def closeindent(self, times): "Close the indenting div a few times." indent = '' for i in range(times): indent += '
\n' return indent class IndentedEntry(Container): "An entry with an indentation." def __init__(self): self.output = ContentsOutput() def create(self, indent, entry): "Create the indented entry." self.entry = entry self.contents = [indent, entry] return self def __unicode__(self): "Return a printable documentation." return 'Indented ' + unicode(self.entry) class TOCTree(object): "A tree that contains the full TOC." def __init__(self): self.tree = [] self.branches = [] def store(self, entry): "Place the entry in a tree of entries." while len(self.tree) < entry.partkey.level: self.tree.append(None) if len(self.tree) > entry.partkey.level: self.tree = self.tree[:entry.partkey.level] stem = self.findstem() if len(self.tree) == 0: self.branches.append(entry) self.tree.append(entry) if stem: entry.stem = stem stem.branches.append(entry) def findstem(self): "Find the stem where our next element will be inserted." for element in reversed(self.tree): if element: return element return None class TOCConverter(object): "A converter from elyxer.containers to TOC entries." cache = dict() tree = TOCTree() def __init__(self): self.indenter = Indenter() def convertindented(self, container): "Convert a container into an indented TOC entry." entry = self.convert(container) if not entry: return None return self.indent(entry) def indent(self, entry): "Indent a TOC entry." indent = self.indenter.getindent(entry.partkey.level) return IndentedEntry().create(indent, entry) def convert(self, container): "Convert a container to a TOC entry." if not container.partkey: return None if container.partkey.partkey in self.cache: return TOCConverter.cache[container.partkey.partkey] if container.partkey.level > DocumentParameters.tocdepth: return None entry = TOCEntry().create(container) TOCConverter.cache[container.partkey.partkey] = entry TOCConverter.tree.store(entry) return entry elyxer-1.2.5/src/elyxer/gen/inset.py0000644000175000017500000001155012074107030016675 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20090506 # LyX insets from elyxer.util.trace import Trace from elyxer.parse.parser import * from elyxer.parse.headerparse import * from elyxer.out.output import * from elyxer.io.bulk import * from elyxer.gen.container import * from elyxer.gen.styles import * from elyxer.gen.layout import * class InsetText(Container): "An inset of text in a lyx file" def __init__(self): self.parser = BoundedParser() self.output = ContentsOutput() class Inset(Container): "A generic inset in a LyX document" def __init__(self): self.contents = list() self.parser = InsetParser() self.output = TaggedOutput().setbreaklines(True) def process(self): self.type = self.header[1] self.output.tag = 'span class="' + self.type + '"' def __unicode__(self): return 'Inset of type ' + self.type class NewlineInset(Newline): "A newline or line break in an inset" def __init__(self): self.parser = InsetParser() self.output = FixedOutput() class NewPageInset(NewPage): "A new page command." def __init__(self): self.parser = InsetParser() self.output = FixedOutput() class Branch(Container): "A branch within a LyX document" def __init__(self): self.parser = InsetParser() self.output = TaggedOutput().settag('span class="branch"', True) def process(self): "Disable inactive branches" self.branch = self.header[2] if not self.isactive(): Trace.debug('Branch ' + self.branch + ' not active') self.output = EmptyOutput() def isactive(self): "Check if the branch is active" if not self.branch in Options.branches: Trace.error('Invalid branch ' + self.branch) return True branch = Options.branches[self.branch] return branch.isselected() class ShortTitle(Container): "A short title to display (always hidden)" def __init__(self): self.parser = InsetParser() self.output = EmptyOutput() class FlexInset(Container): "A flexible inset, generic version." def __init__(self): self.parser = InsetParser() self.output = TaggedOutput().settag('span', False) def process(self): "Set the correct flex tag." self.type = self.header[2] if self.type in TagConfig.flex: self.output.settag(TagConfig.flex[self.type], False) else: self.output.settag('span class="' + self.type + '"', False) class InfoInset(Container): "A LyX Info inset" def __init__(self): self.parser = InsetParser() self.output = TaggedOutput().settag('span class="Info"', False) def process(self): "Set the shortcut as text" self.type = self.getparameter('type') self.contents = [Constant(self.getparameter('arg'))] class BoxInset(Container): "A box inset" def __init__(self): self.parser = InsetParser() self.output = TaggedOutput().settag('div', True) def process(self): "Set the correct tag" self.type = self.header[2] self.output.settag('div class="' + self.type + '"', True) ContainerSize().readparameters(self).addstyle(self) class PhantomText(Container): "A line of invisible text (white over white)." def __init__(self): self.parser = InsetParser() self.output = TaggedOutput().settag('span class="phantom"', False) class LineInset(LyXLine): "A LaTeX ruler, but parsed as an inset." def __init__(self): self.parser = InsetParser() self.output = FixedOutput() class Caption(Container): "A caption for a figure or a table" def __init__(self): self.parser = InsetParser() self.output = TaggedOutput().settag('div class="caption"', True) def create(self, message): "Create a caption with a given message." self.contents = [Constant(message)] return self class ScriptInset(Container): "Sub- or super-script in an inset." def __init__(self): self.parser = InsetParser() self.output = TaggedOutput().settag('span', False) def process(self): "Set the correct script tag." self.type = self.header[2] if not self.type in TagConfig.script: Trace.error('Unknown script type ' + self.type) return self.output.settag(TagConfig.script[self.type], False) elyxer-1.2.5/src/elyxer/gen/list.py0000644000175000017500000001105412074107030016525 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20100427 # eLyXer lists and list post-processing from elyxer.util.trace import Trace from elyxer.parse.parser import * from elyxer.out.output import * from elyxer.gen.container import * from elyxer.proc.postprocess import * class ListItem(Container): "An element in a list" type = 'none' def __init__(self): "Create a list item." self.parser = BoundedParser() self.output = ContentsOutput() def process(self): "Set the correct type and contents." self.type = self.header[1] tag = TaggedText().complete(self.contents, 'li', True) self.contents = [tag] def __unicode__(self): return self.type + ' item @ ' + unicode(self.begin) class DeeperList(Container): "A nested list" def __init__(self): "Create a nested list element." self.parser = BoundedParser() self.output = ContentsOutput() self.contents = [] def process(self): "Create the deeper list" if len(self.contents) == 0: Trace.error('Empty deeper list') return def __unicode__(self): result = 'deeper list @ ' + unicode(self.begin) + ': [' for element in self.contents: result += unicode(element) + ', ' return result[:-2] + ']' class PendingList(object): "A pending list" def __init__(self): self.contents = [] self.type = None def additem(self, item): "Add a list item" self.contents += item.contents if not self.type: self.type = item.type def adddeeper(self, deeper): "Add a deeper list item" if self.empty(): self.insertfake() self.contents[-1].contents += deeper.contents def generate(self): "Get the resulting list" if not self.type: tag = 'ul' else: tag = TagConfig.listitems[self.type] text = TaggedText().complete(self.contents, tag, True) self.__init__() return text def isduewithitem(self, item): "Decide whether the pending list must be generated before the given item" if not self.type: return False if self.type != item.type: return True return False def isduewithnext(self, next): "Applies only if the list is finished with next item." if not next: return True if not isinstance(next, ListItem) and not isinstance(next, DeeperList): return True return False def empty(self): return len(self.contents) == 0 def insertfake(self): "Insert a fake item" item = TaggedText().constant('', 'li class="nested"', True) self.contents = [item] self.type = 'Itemize' def __unicode__(self): result = 'pending ' + unicode(self.type) + ': [' for element in self.contents: result += unicode(element) + ', ' if len(self.contents) > 0: result = result[:-2] return result + ']' class PostListItem(object): "Postprocess a list item" processedclass = ListItem def postprocess(self, last, item, next): "Add the item to pending and return an empty item" if not hasattr(self.postprocessor, 'list'): self.postprocessor.list = PendingList() self.postprocessor.list.additem(item) if self.postprocessor.list.isduewithnext(next): return self.postprocessor.list.generate() if isinstance(next, ListItem) and self.postprocessor.list.isduewithitem(next): return self.postprocessor.list.generate() return BlackBox() class PostDeeperList(object): "Postprocess a deeper list" processedclass = DeeperList def postprocess(self, last, deeper, next): "Append to the list in the postprocessor" if not hasattr(self.postprocessor, 'list'): self.postprocessor.list = PendingList() self.postprocessor.list.adddeeper(deeper) if self.postprocessor.list.isduewithnext(next): return self.postprocessor.list.generate() return BlackBox() Postprocessor.stages += [PostListItem, PostDeeperList] elyxer-1.2.5/src/elyxer/gen/styles.py0000644000175000017500000001434212074107030017100 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20090311 # LyX styles in containers from elyxer.util.trace import Trace from elyxer.util.numbering import * from elyxer.parse.parser import * from elyxer.out.output import * from elyxer.gen.container import * from elyxer.gen.size import * class QuoteContainer(Container): "A container for a pretty quote" def __init__(self): self.parser = BoundedParser() self.output = FixedOutput() def process(self): "Process contents" self.type = self.header[2] if not self.type in StyleConfig.quotes: Trace.error('Quote type ' + self.type + ' not found') self.html = ['"'] return self.html = [StyleConfig.quotes[self.type]] class LyXLine(Container): "A Lyx line" def __init__(self): self.parser = LoneCommand() self.output = FixedOutput() def process(self): self.html = ['
'] class EmphaticText(TaggedText): "Text with emphatic mode" def process(self): self.output.tag = 'i' class ShapedText(TaggedText): "Text shaped (italic, slanted)" def process(self): self.type = self.header[1] if not self.type in TagConfig.shaped: Trace.error('Unrecognized shape ' + self.header[1]) self.output.tag = 'span' return self.output.tag = TagConfig.shaped[self.type] class VersalitasText(TaggedText): "Text in versalitas" def process(self): self.output.tag = 'span class="versalitas"' class ColorText(TaggedText): "Colored text" def process(self): self.color = self.header[1] self.output.tag = 'span class="' + self.color + '"' class SizeText(TaggedText): "Sized text" def process(self): self.size = self.header[1] self.output.tag = 'span class="' + self.size + '"' class BoldText(TaggedText): "Bold text" def process(self): self.output.tag = 'b' class TextFamily(TaggedText): "A bit of text from elyxer.a different family" def process(self): "Parse the type of family" self.type = self.header[1] if not self.type in TagConfig.family: Trace.error('Unrecognized family ' + type) self.output.tag = 'span' return self.output.tag = TagConfig.family[self.type] class Hfill(TaggedText): "Horizontall fill" def process(self): self.output.tag = 'span class="hfill"' class BarredText(TaggedText): "Text with a bar somewhere" def process(self): "Parse the type of bar" self.type = self.header[1] if not self.type in TagConfig.barred: Trace.error('Unknown bar type ' + self.type) self.output.tag = 'span' return self.output.tag = TagConfig.barred[self.type] class LangLine(TaggedText): "A line with language information" def process(self): "Only generate a span with lang info when the language is recognized." lang = self.header[1] if not lang in TranslationConfig.languages: self.output = ContentsOutput() return isolang = TranslationConfig.languages[lang] self.output = TaggedOutput().settag('span lang="' + isolang + '"', False) class InsetLength(BlackBox): "A length measure inside an inset." def process(self): self.length = self.header[1] class Space(Container): "A space of several types" def __init__(self): self.parser = InsetParser() self.output = FixedOutput() def process(self): self.type = self.header[2] if self.type not in StyleConfig.hspaces: Trace.error('Unknown space type ' + self.type) self.html = [' '] return self.html = [StyleConfig.hspaces[self.type]] length = self.getlength() if not length: return self.output = TaggedOutput().settag('span class="hspace"', False) ContainerSize().set(length).addstyle(self) def getlength(self): "Get the space length from elyxer.the contents or parameters." if len(self.contents) == 0 or not isinstance(self.contents[0], InsetLength): return None return self.contents[0].length class VerticalSpace(Container): "An inset that contains a vertical space." def __init__(self): self.parser = InsetParser() self.output = FixedOutput() def process(self): "Set the correct tag" self.type = self.header[2] if self.type not in StyleConfig.vspaces: self.output = TaggedOutput().settag('div class="vspace" style="height: ' + self.type + ';"', True) return self.html = [StyleConfig.vspaces[self.type]] class Align(Container): "Bit of aligned text" def __init__(self): self.parser = ExcludingParser() self.output = TaggedOutput().setbreaklines(True) def process(self): self.output.tag = 'div class="' + self.header[1] + '"' class Newline(Container): "A newline" def __init__(self): self.parser = LoneCommand() self.output = FixedOutput() def process(self): "Process contents" self.html = ['
\n'] class NewPage(Newline): "A new page" def process(self): "Process contents" self.html = ['


\n

\n'] class Separator(Container): "A separator string which is not extracted by extracttext()." def __init__(self, constant): self.output = FixedOutput() self.contents = [] self.html = [constant] class StrikeOut(TaggedText): "Striken out text." def process(self): "Set the output tag to strike." self.output.tag = 'strike' class StartAppendix(BlackBox): "Mark to start an appendix here." "From this point on, all chapters become appendices." def process(self): "Activate the special numbering scheme for appendices, using letters." NumberGenerator.generator.startappendix() elyxer-1.2.5/src/elyxer/gen/integral.py0000644000175000017500000001232712074107030017363 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20091109 # eLyXer integral processing # http://www.nongnu.org/elyxer/ from elyxer.gen.layout import * from elyxer.gen.float import * from elyxer.ref.index import * from elyxer.bib.biblio import * from elyxer.gen.basket import * class IntegralProcessor(object): "A processor for an integral document." def __init__(self): "Create the processor for the integral contents." self.storage = [] def locate(self, container): "Locate only containers of the processed type." return isinstance(container, self.processedtype) def store(self, container): "Store a new container." self.storage.append(container) def process(self): "Process the whole storage." for container in self.storage: self.processeach(container) class IntegralTOC(IntegralProcessor): "A processor for an integral TOC." processedtype = TableOfContents tocentries = [] def processeach(self, toc): "Fill in a Table of Contents." converter = TOCConverter() for container in PartKeyGenerator.partkeyed: toc.add(converter.convertindented(container)) # finish off with the footer to align indents toc.add(converter.convertindented(LyXFooter())) def writetotoc(self, entries, toc): "Write some entries to the TOC." for entry in entries: toc.contents.append(entry) class IntegralBiblioEntry(IntegralProcessor): "A processor for an integral bibliography entry." processedtype = BiblioEntry def processeach(self, entry): "Process each entry." number = NumberGenerator.generator.generate('integralbib') link = Link().complete('cite', 'biblio-' + number, type='biblioentry') link.contents = entry.citeref entry.contents = [Constant('['), link, Constant('] ')] if entry.key in BiblioCite.cites: for cite in BiblioCite.cites[entry.key]: cite.contents = entry.citeref cite.anchor = 'cite-' + number cite.destination = link class IntegralFloat(IntegralProcessor): "Store all floats in the document by type." processedtype = Float bytype = dict() def processeach(self, float): "Store each float by type." if not float.type in IntegralFloat.bytype: IntegralFloat.bytype[float.type] = [] IntegralFloat.bytype[float.type].append(float) class IntegralListOf(IntegralProcessor): "A processor for an integral list of floats." processedtype = ListOf def processeach(self, listof): "Fill in a list of floats." listof.output = TaggedOutput().settag('div class="fulltoc"', True) if not listof.type in IntegralFloat.bytype: Trace.message('No floats of type ' + listof.type) return for float in IntegralFloat.bytype[listof.type]: entry = self.processfloat(float) if entry: listof.contents.append(entry) def processfloat(self, float): "Get an entry for the list of floats." if not float.isparent(): return None return TOCEntry().create(float) class IntegralReference(IntegralProcessor): "A processor for a reference to a label." processedtype = Reference def processeach(self, reference): "Extract the text of the original label." reference.formatcontents() class MemoryBasket(KeeperBasket): "A basket which stores everything in memory, processes it and writes it." def __init__(self): "Create all processors in one go." KeeperBasket.__init__(self) self.processors = [ IntegralTOC(), IntegralBiblioEntry(), IntegralFloat(), IntegralListOf(), IntegralReference(), ] def finish(self): "Process everything which cannot be done in one pass and write to disk." self.process() self.flush() def process(self): "Process everything with the integral processors." self.searchintegral() for processor in self.processors: processor.process() def searchintegral(self): "Search for all containers for all integral processors." for container in self.contents: # container.tree() if self.integrallocate(container): self.integralstore(container) container.locateprocess(self.integrallocate, self.integralstore) def integrallocate(self, container): "Locate all integrals." for processor in self.processors: if processor.locate(container): return True return False def integralstore(self, container): "Store a container in one or more processors." for processor in self.processors: if processor.locate(container): processor.store(container) elyxer-1.2.5/src/elyxer/gen/include.py0000644000175000017500000000657612074107030017212 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20110201 # LyX child documents (included insets). from elyxer.util.trace import Trace from elyxer.parse.parser import * from elyxer.parse.headerparse import * from elyxer.out.output import * from elyxer.io.bulk import * from elyxer.gen.container import * from elyxer.gen.styles import * from elyxer.gen.layout import * from elyxer.gen.float import * class IncludeInset(Container): "A child document included within another." # the converter factory will be set in converter.py converterfactory = None filename = None def __init__(self): self.parser = InsetParser() self.output = ContentsOutput() def process(self): "Include the provided child document" self.filename = os.path.join(Options.directory, self.getparameter('filename')) Trace.debug('Child document: ' + self.filename) LstParser().parsecontainer(self) command = self.getparameter('LatexCommand') if command == 'verbatiminput': self.readverbatim() return elif command == 'lstinputlisting': self.readlisting() return self.processinclude() def processinclude(self): "Process a regular include: standard child document." self.contents = [] olddir = Options.directory newdir = os.path.dirname(self.getparameter('filename')) if newdir != '': Trace.debug('Child dir: ' + newdir) Options.directory = os.path.join(Options.directory, newdir) try: self.convertinclude() finally: Options.directory = olddir def convertinclude(self): "Convert an included document." try: converter = IncludeInset.converterfactory.create(self) except: Trace.error('Could not read ' + self.filename + ', please check that the file exists and has read permissions.') return if self.hasemptyoutput(): return converter.convert() self.contents = converter.getcontents() def readverbatim(self): "Read a verbatim document." self.contents = [TaggedText().complete(self.readcontents(), 'pre', True)] def readlisting(self): "Read a document as a listing." listing = Listing() listing.contents = self.readcontents() listing.parameters = self.parameters listing.process() self.contents = [listing] def readcontents(self): "Read the contents of a complete file." contents = list() lines = BulkFile(self.filename).readall() for line in lines: contents.append(Constant(line)) return contents def __unicode__(self): "Return a printable description." if not self.filename: return 'Included unnamed file' return 'Included "' + self.filename + '"' elyxer-1.2.5/src/elyxer/gen/image.py0000644000175000017500000002140512074107030016635 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20090308 # eLyXer image treatment import struct import sys import os import shutil from elyxer.util.trace import Trace from elyxer.util.translate import * from elyxer.gen.container import * from elyxer.gen.size import * from elyxer.io.path import * class Image(Container): "An embedded image" defaultformat = ImageConfig.formats['default'] size = None copy = None def __init__(self): self.parser = InsetParser() self.output = TaggedOutput() self.type = 'embedded' def process(self): "Place the url, convert the image if necessary." self.origin = InputPath(self.getparameter('filename')) self.destination = self.getdestination(self.origin) self.size = ContainerSize().readparameters(self) if self.origin.exists(): ImageConverter.instance.convert(self) else: Trace.error('Image ' + unicode(self.origin) + ' not found') self.setsize() self.settag() def getdestination(self, origin): "Convert origin path to destination path." "Changes extension of destination to output image format." destination = OutputPath(origin) if Options.noconvert: return destination self.convertformat(destination) destination.removebackdirs() return destination def convertformat(self, destination): "Convert the format of the destination image." if Options.copyimages: return imageformat = '.jpg' forcedest = Image.defaultformat if Options.imageformat: imageformat = Options.imageformat forcedest = Options.imageformat if not destination.hasext(imageformat): destination.changeext(forcedest) def setsize(self): "Set the size attributes width and height." width, height = ImageFile(self.destination).getdimensions() self.size.checkimage(width, height) def scalevalue(self, value): "Scale the value according to the image scale and return it as unicode." scaled = value * int(self.size.scale) / 100 return unicode(int(scaled)) + 'px' def settag(self): "Set the output tag for the image." tag = 'img class="' + self.type + '"' if self.origin.exists(): url = self.destination.url else: url = self.origin.url alt = Translator.translate('figure') + ' ' + url tag += ' src="' + url + '" alt="' + alt + '"' emptytag = True if self.destination.hasext('.svg'): self.contents = [Constant(alt)] tag = 'object class="' + self.type + '" data="' + url + '"' emptytag = False self.output.settag(tag, True, empty=emptytag) self.size.addstyle(self) class ImageConverter(object): "A converter from elyxer.one image file to another." vectorformats = ImageConfig.formats['vector'] cropboxformats = ImageConfig.cropboxformats active = True instance = None def convert(self, image): "Convert an image to PNG" if not ImageConverter.active or Options.noconvert: return if image.origin.path == image.destination.path: return if image.destination.exists(): if image.origin.getmtime() <= image.destination.getmtime(): # file has not changed; do not convert return image.destination.createdirs() if Options.copyimages: Trace.debug('Copying ' + image.origin.path + ' to ' + image.destination.path) shutil.copy2(image.origin.path, image.destination.path) return converter, command = self.buildcommand(image) try: Trace.debug(converter + ' command: "' + command + '"') result = os.system(command.encode(sys.getfilesystemencoding())) if result != 0: Trace.error(converter + ' not installed; images will not be processed') ImageConverter.active = False return Trace.message('Converted ' + unicode(image.origin) + ' to ' + unicode(image.destination)) except OSError, exception: Trace.error('Error while converting image ' + unicode(image.origin) + ': ' + unicode(exception)) def buildcommand(self, image): "Build the command to convert the image." if Options.converter in ImageConfig.converters: command = ImageConfig.converters[Options.converter] else: command = Options.converter; params = self.getparams(image) for param in params: command = command.replace('$' + param, unicode(params[param])) # remove unwanted options while '[' in command and ']' in command: command = self.removeparam(command) return Options.converter, command def removeparam(self, command): "Remove an unwanted param." if command.index('[') > command.index(']'): Trace.error('Converter command should be [...$...]: ' + command) exit() before = command[:command.index('[')] after = command[command.index(']') + 1:] between = command[command.index('[') + 1:command.index(']')] if '$' in between: return before + after return before + between + after def getparams(self, image): "Get the parameters for ImageMagick conversion" params = dict() params['input'] = image.origin params['output'] = image.destination if image.origin.hasexts(self.vectorformats): scale = 100 if image.size.scale: scale = image.size.scale # descale image.size.scale = None params['scale'] = scale if image.origin.getext() in self.cropboxformats: params['format'] = self.cropboxformats[image.origin.getext()] return params ImageConverter.instance = ImageConverter() class ImageFile(object): "A file corresponding to an image (JPG or PNG)" dimensions = dict() def __init__(self, path): "Create the file based on its path" self.path = path def getdimensions(self): "Get the dimensions of a JPG or PNG image" if not self.path.exists(): return None, None if unicode(self.path) in ImageFile.dimensions: return ImageFile.dimensions[unicode(self.path)] dimensions = (None, None) if self.path.hasext('.png'): dimensions = self.getpngdimensions() elif self.path.hasext('.jpg'): dimensions = self.getjpgdimensions() elif self.path.hasext('.svg'): dimensions = self.getsvgdimensions() ImageFile.dimensions[unicode(self.path)] = dimensions return dimensions def getpngdimensions(self): "Get the dimensions of a PNG image" pngfile = self.path.open() pngfile.seek(16) width = self.readlong(pngfile) height = self.readlong(pngfile) pngfile.close() return (width, height) def getjpgdimensions(self): "Get the dimensions of a JPEG image" jpgfile = self.path.open() start = self.readword(jpgfile) if start != int('ffd8', 16): Trace.error(unicode(self.path) + ' not a JPEG file') return (None, None) self.skipheaders(jpgfile, ['ffc0', 'ffc2']) self.seek(jpgfile, 3) height = self.readword(jpgfile) width = self.readword(jpgfile) jpgfile.close() return (width, height) def getsvgdimensions(self): "Get the dimensions of a SVG image." return (None, None) def skipheaders(self, file, hexvalues): "Skip JPEG headers until one of the parameter headers is found" headervalues = [int(value, 16) for value in hexvalues] header = self.readword(file) safetycounter = 0 while header not in headervalues and safetycounter < 30: length = self.readword(file) if length == 0: Trace.error('End of file ' + file.name) return self.seek(file, length - 2) header = self.readword(file) safetycounter += 1 def readlong(self, file): "Read a long (32-bit) value from elyxer.file" return self.readformat(file, '>L', 4) def readword(self, file): "Read a 16-bit value from elyxer.file" return self.readformat(file, '>H', 2) def readformat(self, file, format, bytes): "Read any format from elyxer.file" read = file.read(bytes) if read == '' or len(read) < bytes: Trace.error('EOF reached') return 0 tuple = struct.unpack(format, read) return tuple[0] def seek(self, file, bytes): "Seek forward, just by reading the given number of bytes" file.read(bytes) elyxer-1.2.5/src/elyxer/gen/change.py0000644000175000017500000000277512074107030017011 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20100829 # Change tracking from elyxer.util.trace import Trace from elyxer.util.docparams import * from elyxer.gen.container import * class ChangeInserted(Container): "A change which consists of an insertion." def __init__(self): self.parser = TextParser(self) if DocumentParameters.outputchanges: self.output = TaggedOutput().settag('span class="inserted"') else: self.output = ContentsOutput() class ChangeDeleted(TaggedText): "A change which consists of a deletion." def __init__(self): self.parser = TextParser(self) if DocumentParameters.outputchanges: self.output = TaggedOutput().settag('span class="deleted"') else: self.output = EmptyOutput() elyxer-1.2.5/src/elyxer/gen/header.py0000644000175000017500000001011012074107030016772 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20090312 # LyX structure in containers from elyxer.util.docparams import * from elyxer.parse.parser import * from elyxer.parse.headerparse import * from elyxer.out.output import * from elyxer.out.template import * from elyxer.gen.container import * from elyxer.ref.partkey import * from elyxer.maths.command import * from elyxer.maths.macro import * from elyxer.gen.notes import * class LyXHeader(Container): "Reads the header, outputs the HTML header" def __init__(self): self.contents = [] self.parser = HeaderParser() self.output = HeaderOutput() self.parameters = dict() self.partkey = PartKey().createheader('header') def process(self): "Find pdf title" DocumentParameters.pdftitle = self.getheaderparameter('pdftitle') documentclass = self.getheaderparameter('documentclass') if documentclass in HeaderConfig.styles['article']: DocumentParameters.startinglevel = 1 if documentclass in HeaderConfig.styles['book']: DocumentParameters.bibliography = 'bibliography' else: DocumentParameters.bibliography = 'references' if self.getheaderparameter('paragraphseparation') == 'indent': DocumentParameters.indentstandard = True DocumentParameters.tocdepth = self.getlevel('tocdepth') DocumentParameters.maxdepth = self.getlevel('secnumdepth') DocumentParameters.language = self.getheaderparameter('language') if self.getheaderparameter('outputchanges') == 'true': DocumentParameters.outputchanges = True return self def getheaderparameter(self, configparam): "Get a parameter configured in HeaderConfig." key = HeaderConfig.parameters[configparam] if not key in self.parameters: return None return self.parameters[key] def getlevel(self, configparam): "Get a level read as a parameter from elyxer.HeaderConfig." paramvalue = self.getheaderparameter(configparam) if not paramvalue: return 0 value = int(paramvalue) if DocumentParameters.startinglevel == 1: return value return value + 1 class LyXPreamble(Container): "The preamble at the beginning of a LyX file. Parsed for macros." def __init__(self): self.parser = PreambleParser() self.output = EmptyOutput() self.factory = FormulaFactory() def process(self): "Parse the LyX preamble, if needed." if len(PreambleParser.preamble) == 0: return pos = TextPosition('\n'.join(PreambleParser.preamble)) while not pos.finished(): if self.detectfunction(pos): self.parsefunction(pos) else: pos.globincluding('\n') PreambleParser.preamble = [] def detectfunction(self, pos): "Detect a macro definition or a preamble function." for function in FormulaConfig.misccommands: if pos.checkfor(function): return True return False def parsefunction(self, pos): "Parse a single command." self.factory.parsetype(FormulaCommand, pos) class LyXFooter(Container): "Reads the footer, outputs the HTML footer" def __init__(self): self.contents = [] self.parser = BoundedDummy() self.output = FooterOutput() self.partkey = PartKey().createheader('footer') def process(self): "Include any footnotes at the end." if EndFootnotes.footnotes: endnotes = EndFootnotes() self.contents = [endnotes] elyxer-1.2.5/src/elyxer/gen/basket.py0000644000175000017500000000464312074107030017031 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20091101 # eLyXer output baskets # http://www.nongnu.org/elyxer/ from elyxer.util.options import * from elyxer.util.clone import * from elyxer.gen.toc import * class Basket(object): "A basket to place a set of containers. Can write them, store them..." def setwriter(self, writer): self.writer = writer return self class WriterBasket(Basket): "A writer of containers. Just writes them out to a writer." def write(self, container): "Write a container to the line writer." self.writer.write(container.gethtml()) def finish(self): "Mark as finished." self.writer.close() class KeeperBasket(Basket): "Keeps all containers stored." def __init__(self): self.contents = [] def write(self, container): "Keep the container." self.contents.append(container) def finish(self): "Finish the basket by flushing to disk." self.flush() def flush(self): "Flush the contents to the writer." for container in self.contents: self.writer.write(container.gethtml()) self.writer.close() class TOCBasket(Basket): "A basket to place the TOC of a document." def __init__(self): self.converter = TOCConverter() def setwriter(self, writer): Basket.setwriter(self, writer) Options.nocopy = True self.writer.write(LyXHeader().gethtml()) return self def write(self, container): "Write the table of contents for a container." entry = self.converter.convertindented(container) if entry: self.writer.write(entry.gethtml()) def finish(self): "Mark as finished." self.writer.write(LyXFooter().gethtml()) self.writer.close() elyxer-1.2.5/src/elyxer/gen/size.py0000644000175000017500000001141312074107030016523 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20100828 # Container size parsing and output from elyxer.util.trace import Trace from elyxer.gen.container import * class ContainerSize(object): "The size of a container." width = None height = None maxwidth = None maxheight = None scale = None def set(self, width = None, height = None): "Set the proper size with width and height." self.setvalue('width', width) self.setvalue('height', height) return self def setmax(self, maxwidth = None, maxheight = None): "Set max width and/or height." self.setvalue('maxwidth', maxwidth) self.setvalue('maxheight', maxheight) return self def readparameters(self, container): "Read some size parameters off a container." self.setparameter(container, 'width') self.setparameter(container, 'height') self.setparameter(container, 'scale') self.checkvalidheight(container) return self def setparameter(self, container, name): "Read a size parameter off a container, and set it if present." value = container.getparameter(name) self.setvalue(name, value) def setvalue(self, name, value): "Set the value of a parameter name, only if it's valid." value = self.processparameter(value) if value: setattr(self, name, value) def checkvalidheight(self, container): "Check if the height parameter is valid; otherwise erase it." heightspecial = container.getparameter('height_special') if self.height and self.extractnumber(self.height) == '1' and heightspecial == 'totalheight': self.height = None def processparameter(self, value): "Do the full processing on a parameter." if not value: return None if self.extractnumber(value) == '0': return None for ignored in StyleConfig.size['ignoredtexts']: if ignored in value: value = value.replace(ignored, '') return value def extractnumber(self, text): "Extract the first number in the given text." result = '' decimal = False for char in text: if char.isdigit(): result += char elif char == '.' and not decimal: result += char decimal = True else: return result return result def checkimage(self, width, height): "Check image dimensions, set them if possible." if width: self.maxwidth = unicode(width) + 'px' if self.scale and not self.width: self.width = self.scalevalue(width) if height: self.maxheight = unicode(height) + 'px' if self.scale and not self.height: self.height = self.scalevalue(height) if self.width and not self.height: self.height = 'auto' if self.height and not self.width: self.width = 'auto' def scalevalue(self, value): "Scale the value according to the image scale and return it as unicode." scaled = value * int(self.scale) / 100 return unicode(int(scaled)) + 'px' def removepercentwidth(self): "Remove percent width if present, to set it at the figure level." if not self.width: return None if not '%' in self.width: return None width = self.width self.width = None if self.height == 'auto': self.height = None return width def addstyle(self, container): "Add the proper style attribute to the output tag." if not isinstance(container.output, TaggedOutput): Trace.error('No tag to add style, in ' + unicode(container)) if not self.width and not self.height and not self.maxwidth and not self.maxheight: # nothing to see here; move along return tag = ' style="' tag += self.styleparameter('width') tag += self.styleparameter('maxwidth') tag += self.styleparameter('height') tag += self.styleparameter('maxheight') if tag[-1] == ' ': tag = tag[:-1] tag += '"' container.output.tag += tag def styleparameter(self, name): "Get the style for a single parameter." value = getattr(self, name) if value: return name.replace('max', 'max-') + ': ' + value + '; ' return '' elyxer-1.2.5/src/elyxer/gen/layout.py0000644000175000017500000002356712074107030017103 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20090411 # LyX layout and derived classes from elyxer.util.trace import Trace from elyxer.parse.parser import * from elyxer.out.output import * from elyxer.gen.container import * from elyxer.gen.styles import * from elyxer.gen.header import * from elyxer.proc.postprocess import * from elyxer.ref.label import * from elyxer.ref.partkey import * from elyxer.ref.link import * class Layout(Container): "A layout (block of text) inside a lyx file" type = 'none' def __init__(self): "Initialize the layout." self.contents = [] self.parser = BoundedParser() self.output = TaggedOutput().setbreaklines(True) def process(self): "Get the type and numerate if necessary." self.type = self.header[1] if self.type in TagConfig.layouts: self.output.tag = TagConfig.layouts[self.type] + ' class="' + self.type + '"' elif self.type.replace('*', '') in TagConfig.layouts: self.output.tag = TagConfig.layouts[self.type.replace('*', '')] self.output.tag += ' class="' + self.type.replace('*', '-') + '"' else: self.output.tag = 'div class="' + self.type + '"' self.numerate() def numerate(self): "Numerate if necessary." partkey = PartKeyGenerator.forlayout(self) if partkey: self.partkey = partkey self.output.tag = self.output.tag.replace('?', unicode(partkey.level)) def __unicode__(self): "Return a printable representation." if self.partkey: return 'Layout ' + self.type + ' #' + unicode(self.partkey.partkey) return 'Layout of type ' + self.type class StandardLayout(Layout): "A standard layout -- can be a true div or nothing at all" indentation = False def process(self): self.type = 'standard' self.output = ContentsOutput() def complete(self, contents): "Set the contents and return it." self.process() self.contents = contents return self class Title(Layout): "The title of the whole document" def process(self): self.type = 'title' self.output.tag = 'h1 class="title"' title = self.extracttext() DocumentTitle.title = title Trace.message('Title: ' + title) class Author(Layout): "The document author" def process(self): self.type = 'author' self.output.tag = 'h2 class="author"' author = self.extracttext() Trace.debug('Author: ' + author) DocumentAuthor.appendauthor(author) class Abstract(Layout): "A paper abstract" done = False def process(self): self.type = 'abstract' self.output.tag = 'div class="abstract"' if Abstract.done: return message = Translator.translate('abstract') tagged = TaggedText().constant(message, 'p class="abstract-message"', True) self.contents.insert(0, tagged) Abstract.done = True class FirstWorder(Layout): "A layout where the first word is extracted" def extractfirstword(self): "Extract the first word as a list" return self.extractfromcontents(self.contents) def extractfromcontents(self, contents): "Extract the first word in contents." firstcontents = [] while len(contents) > 0: if self.isfirstword(contents[0]): firstcontents.append(contents[0]) del contents[0] return firstcontents if self.spaceincontainer(contents[0]): extracted = self.extractfromcontainer(contents[0]) firstcontents.append(extracted) return firstcontents firstcontents.append(contents[0]) del contents[0] return firstcontents def extractfromcontainer(self, container): "Extract the first word from a container cloning it including its output." if isinstance(container, StringContainer): return self.extractfromstring(container) result = Cloner.clone(container) result.output = container.output result.contents = self.extractfromcontents(container.contents) return result def extractfromstring(self, container): "Extract the first word from elyxer.a string container." if not ' ' in container.string: Trace.error('No space in string ' + container.string) return container split = container.string.split(' ', 1) container.string = split[1] return Constant(split[0]) def spaceincontainer(self, container): "Find out if the container contains a space somewhere." return ' ' in container.extracttext() def isfirstword(self, container): "Find out if the container is valid as a first word." if not isinstance(container, FirstWord): return False return not container.isempty() class FirstWord(Container): "A container which is in itself a first word, unless it's empty." "Should be inherited by other containers, e.g. ERT." def isempty(self): "Find out if the first word is empty." Trace.error('Unimplemented isempty()') return True class Description(FirstWorder): "A description layout" def process(self): "Set the first word to bold" self.type = 'Description' self.output.tag = 'div class="Description"' firstword = self.extractfirstword() if not firstword: return tag = 'span class="Description-entry"' self.contents.insert(0, TaggedText().complete(firstword, tag)) self.contents.insert(1, Constant(u' ')) class List(FirstWorder): "A list layout" def process(self): "Set the first word to bold" self.type = 'List' self.output.tag = 'div class="List"' firstword = self.extractfirstword() if not firstword: return first = TaggedText().complete(firstword, 'span class="List-entry"') second = TaggedText().complete(self.contents, 'span class="List-contents"') self.contents = [first, second] class PlainLayout(Layout): "A plain layout" def process(self): "Output just as contents." self.output = ContentsOutput() self.type = 'Plain' def makevisible(self): "Make the layout visible, output as tagged text." self.output = TaggedOutput().settag('div class="PlainVisible"', True) class LyXCode(Layout): "A bit of LyX-Code." def process(self): "Output as pre." self.output.tag = 'pre class="LyX-Code"' for newline in self.searchall(Newline): index = newline.parent.contents.index(newline) newline.parent.contents[index] = Constant('\n') class PostLayout(object): "Numerate an indexed layout" processedclass = Layout def postprocess(self, last, layout, next): "Group layouts and/or number them." if layout.type in TagConfig.group['layouts']: return self.group(last, layout) if layout.partkey: self.number(layout) return layout def group(self, last, layout): "Group two layouts if they are the same type." if not self.isgroupable(layout) or not self.isgroupable(last) or last.type != layout.type: return layout layout.contents = last.contents + [Constant('
\n')] + layout.contents last.contents = [] last.output = EmptyOutput() return layout def isgroupable(self, container): "Check that the container can be grouped." if not isinstance(container, Layout): return False for element in container.contents: if not element.__class__.__name__ in LayoutConfig.groupable['allowed']: return False return True def number(self, layout): "Generate a number and place it before the text" layout.partkey.addtoclabel(layout) class PostStandard(object): "Convert any standard spans in root to divs" processedclass = StandardLayout def postprocess(self, last, standard, next): "Switch to div, and clear if empty." type = 'Standard' if self.isempty(standard): standard.output = EmptyOutput() return standard if DocumentParameters.indentstandard: if isinstance(last, StandardLayout): type = 'Indented' else: type = 'Unindented' standard.output = TaggedOutput().settag('div class="' + type + '"', True) return standard def isempty(self, standard): "Find out if the standard layout is empty." for element in standard.contents: if not element.output.isempty(): return False return True class PostPlainLayout(PostLayout): "Numerate a plain layout" processedclass = PlainLayout def postprocess(self, last, plain, next): "Group plain layouts." if not self.istext(last) or not self.istext(plain): return plain plain.makevisible() return self.group(last, plain) def istext(self, container): "Find out if the container is only text." if not isinstance(container, PlainLayout): return False extractor = ContainerExtractor(TOCConfig.extractplain) text = extractor.extract(container) return (len(text) > 0) class PostLyXCode(object): "Coalesce contiguous LyX-Code layouts." processedclass = LyXCode def postprocess(self, last, lyxcode, next): "Coalesce if last was also LyXCode" if not isinstance(last, LyXCode): return lyxcode if hasattr(last, 'first'): lyxcode.first = last.first else: lyxcode.first = last toappend = lyxcode.first.contents toappend.append(Constant('\n')) toappend += lyxcode.contents lyxcode.output = EmptyOutput() return lyxcode Postprocessor.stages += [ PostLayout, PostStandard, PostLyXCode, PostPlainLayout ] elyxer-1.2.5/src/elyxer/gen/table.py0000644000175000017500000001301212074107030016635 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20090207 # eLyXer tables from elyxer.util.trace import Trace from elyxer.gen.container import * from elyxer.gen.layout import * from elyxer.parse.parser import * from elyxer.out.output import * from elyxer.parse.tableparse import * from elyxer.proc.postprocess import * class Table(Container): "A lyx table" def __init__(self): self.parser = TableParser() self.output = TaggedOutput().settag('table', True) self.columns = [] def process(self): "Set the columns on every row" index = 0 while index < len(self.contents): element = self.contents[index] if isinstance(element, Column): self.columns.append(element) del self.contents[index] elif isinstance(element, BlackBox): del self.contents[index] elif isinstance(element, Row): element.setcolumns(self.columns) index += 1 else: Trace.error('Unknown element type ' + element.__class__.__name__ + ' in table: ' + unicode(element.contents[0])) index += 1 class Row(Container): "A row in a table" def __init__(self): self.parser = TablePartParser() self.output = TaggedOutput().settag('tr', True) self.columns = list() def setcolumns(self, columns): "Process alignments for every column" if len(columns) != len(self.contents): Trace.error('Columns: ' + unicode(len(columns)) + ', cells: ' + unicode(len(self.contents))) return for index, cell in enumerate(self.contents): columns[index].set(cell) class Column(Container): "A column definition in a table" def __init__(self): self.parser = ColumnParser() self.output = EmptyOutput() def process(self): "Read size parameters if present." self.size = ContainerSize().readparameters(self) def set(self, cell): "Set alignments in the corresponding cell" alignment = self.getparameter('alignment') if alignment == 'block': alignment = 'justify' cell.setattribute('align', alignment) valignment = self.getparameter('valignment') cell.setattribute('valign', valignment) self.size.addstyle(cell) class Cell(Container): "A cell in a table" def __init__(self): self.parser = TablePartParser() self.output = TaggedOutput().settag('td', True) def setmulticolumn(self, span): "Set the cell as multicolumn" self.setattribute('colspan', span) def setattribute(self, attribute, value): "Set a cell attribute in the tag" self.output.tag += ' ' + attribute + '="' + unicode(value) + '"' class PostTable(object): "Postprocess a table" processedclass = Table def postprocess(self, last, table, next): "Postprocess a table: long table, multicolumn rows" self.longtable(table) for row in table.contents: index = 0 while index < len(row.contents): self.checkforplain(row, index) self.checkmulticolumn(row, index) index += 1 return table def longtable(self, table): "Postprocess a long table, removing unwanted rows" features = table.getparameter('features') if not features: return if not 'islongtable' in features: return if features['islongtable'] != 'true': return if self.hasrow(table, 'endfirsthead'): self.removerows(table, 'endhead') if self.hasrow(table, 'endlastfoot'): self.removerows(table, 'endfoot') def hasrow(self, table, attrname): "Find out if the table has a row of first heads" for row in table.contents: if row.getparameter(attrname): return True return False def removerows(self, table, attrname): "Remove the head rows, since the table has first head rows." for row in table.contents: if row.getparameter(attrname): row.output = EmptyOutput() def checkforplain(self, row, index): "Make plain layouts visible if necessary." cell = row.contents[index] plainlayouts = cell.searchall(PlainLayout) if len(plainlayouts) <= 1: return for plain in plainlayouts: plain.makevisible() def checkmulticolumn(self, row, index): "Process a multicolumn attribute" cell = row.contents[index] mc = cell.getparameter('multicolumn') if not mc: return if mc != '1': Trace.error('Unprocessed multicolumn=' + unicode(multicolumn) + ' cell ' + unicode(cell)) return total = 1 index += 1 while self.checkbounds(row, index): del row.contents[index] total += 1 cell.setmulticolumn(total) def checkbounds(self, row, index): "Check if the index is within bounds for the row" if index >= len(row.contents): return False mc = row.contents[index].getparameter('multicolumn') if mc != '2': return False return True Postprocessor.stages.append(PostTable) elyxer-1.2.5/src/elyxer/gen/float.py0000644000175000017500000002004112074107030016653 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20090518 # LyX floats from elyxer.util.trace import Trace from elyxer.util.numbering import * from elyxer.parse.parser import * from elyxer.out.output import * from elyxer.gen.layout import * from elyxer.gen.image import * from elyxer.ref.label import * from elyxer.ref.partkey import * from elyxer.proc.postprocess import * class Float(Container): "A floating inset" type = 'none' def __init__(self): self.parser = InsetParser() self.output = TaggedOutput().settag('div class="float"', True) def process(self): "Get the float type." self.type = self.header[2] self.processnumber() self.processfloats() self.processtags() def isparent(self): "Find out whether the float is the parent float or is contained in another float." current = self.parent while current: if isinstance(current, Float): return False current = current.parent return True def processnumber(self): "Number a float if it isn't numbered." if not self.isparent(): # do nothing; parent will take care of numbering return self.partkey = PartKey().createfloat(self) def processtags(self): "Process the HTML tags." tagged = self.embed() self.applywideningtag(tagged) def embed(self): "Embed the whole contents in a div." embeddedtag = self.getembeddedtag() tagged = TaggedText().complete(self.contents, embeddedtag, True) self.contents = [tagged] return tagged def processfloats(self): "Process all floats contained inside." floats = self.searchall(Float) counter = NumberCounter('subfloat').setmode('a') for subfloat in floats: subfloat.output.tag = subfloat.output.tag.replace('div', 'span') subfloat.partkey = PartKey().createsubfloat(counter.getnext()) def getembeddedtag(self): "Get the tag for the embedded object." floats = self.searchall(Float) if len(floats) > 0: return 'div class="multi' + self.type + '"' return 'div class="' + self.type + '"' def applywideningtag(self, container): "Apply the tag to set float width, if present." images = self.searchall(Image) if len(images) != 1: return '' image = images[0] if not image.size: return width = image.size.removepercentwidth() if not width: return image.type = 'figure' ContainerSize().setmax(width).addstyle(container) image.settag() def searchinside(self, type): "Search for a given type in the contents" return self.searchincontents(self.contents, type) def searchincontents(self, contents, type): "Search in the given contents for the required type." list = [] for element in contents: list += self.searchinelement(element, type) return list def searchinelement(self, element, type): "Search for a given type outside floats" if isinstance(element, Float): return [] if isinstance(element, type): return [element] return self.searchincontents(element.contents, type) def __unicode__(self): "Return a printable representation" return 'Floating inset of type ' + self.type class Wrap(Float): "A wrapped (floating) float" def processtags(self): "Add the widening tag to the parent tag." self.embed() placement = self.getparameter('placement') if not placement: placement = 'o' self.output.tag = 'div class="wrap-' + placement + '"' self.applywideningtag(self) class Listing(Container): "A code listing" processor = None def __init__(self): self.parser = InsetParser() self.output = TaggedOutput().settag('div class="listing"', True) self.numbered = None def process(self): "Remove all layouts" self.counter = 0 self.type = 'listing' self.processparams() if Listing.processor: Listing.processor.preprocess(self) for container in self.extractcontents(): if container: self.contents.append(container) if 'caption' in self.lstparams: text = self.lstparams['caption'][1:-1] self.contents.insert(0, Caption().create(text)) if Listing.processor: Listing.processor.postprocess(self) def extractcontents(self): "Extract all contents one container at a time." oldcontents = self.contents self.contents = [] inpre = [] for container in oldcontents: if self.iscaption(container): yield self.completepre(inpre) inpre = [] yield container else: inpre += self.extract(container) yield self.completepre(inpre) def processparams(self): "Process listing parameteres." LstParser().parsecontainer(self) if 'numbers' in self.lstparams: self.numbered = self.lstparams['numbers'] def iscaption(self, container): "Find out if the container has a caption (which should not be in
)."
    return (len(container.searchall(Caption)) > 0)

  def completepre(self, listinpre):
    "Complete the 
 tag with whatever has already been added."
    if len(listinpre) == 0:
      return None
    return TaggedText().complete(listinpre, 'pre class="listing"', False)

  def extract(self, container):
    "Extract the container's contents and return them"
    if isinstance(container, StringContainer):
      return self.modifystring(container)
    if isinstance(container, StandardLayout):
      return self.modifylayout(container)
    if isinstance(container, PlainLayout):
      return self.modifylayout(container)
    Trace.error('Unexpected container ' + container.__class__.__name__ +
        ' in listing')
    container.tree()
    return []

  def modifystring(self, string):
    "Modify a listing string"
    if string.string == '':
      string.string = u'​'
    return self.modifycontainer(string)

  def modifylayout(self, layout):
    "Modify a standard layout"
    if len(layout.contents) == 0:
      layout.contents = [Constant(u'​')]
    return self.modifycontainer(layout)

  def modifycontainer(self, container):
    "Modify a listing container"
    contents = [container, Constant('\n')]
    if self.numbered:
      self.counter += 1
      tag = 'span class="number-' + self.numbered + '"'
      contents.insert(0, TaggedText().constant(unicode(self.counter), tag))
    return contents

class FloatNumber(Container):
  "Holds the number for a float in the caption."

  def __init__(self):
    self.output = ContentsOutput()

  def create(self, float):
    "Create the float number."
    self.contents = [Constant(float.partkey.partkey)]
    return self

class PostFloat(object):
  "Postprocess a float: number it and move the label"

  processedclass = Float

  def postprocess(self, last, float, next):
    "Move the label to the top and number the caption"
    number = FloatNumber().create(float)
    for caption in float.searchinside(Caption):
      self.postlabels(float, caption)
      caption.contents = [number, Separator(u' ')] + caption.contents
    return float

  def postlabels(self, float, caption):
    "Search for labels and move them to the top"
    labels = caption.searchremove(Label)
    if len(labels) == 0 and float.partkey.tocentry:
      labels = [Label().create(' ', float.partkey.partkey.replace(' ', '-'))]
    float.contents = labels + float.contents

class PostWrap(PostFloat):
  "For a wrap: exactly like a float"

  processedclass = Wrap

Postprocessor.stages += [PostFloat, PostWrap]

elyxer-1.2.5/src/elyxer/gen/factory.py0000644000175000017500000001145012074107030017221 0ustar  chennochenno#! /usr/bin/env python
# -*- coding: utf-8 -*-

#   eLyXer -- convert LyX source files to HTML output.
#
#   Copyright (C) 2009 Alex Fernández
#
#   This program is free software: 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 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
#   GNU General Public License for more details.
#
#   You should have received a copy of the GNU General Public License
#   along with this program.  If not, see .

# --end--
# Alex 20090509
# eLyXer factory to create and parse containers

from elyxer.util.trace import Trace
from elyxer.conf.config import *
from elyxer.gen.styles import *
from elyxer.ref.link import *
from elyxer.ref.label import *
from elyxer.bib.biblio import *
from elyxer.ref.index import *
from elyxer.maths.formula import *
from elyxer.maths.command import *
from elyxer.maths.hybrid import *
from elyxer.gen.table import *
from elyxer.gen.image import *
from elyxer.gen.layout import *
from elyxer.gen.list import *
from elyxer.gen.inset import *
from elyxer.gen.include import *
from elyxer.gen.notes import *
from elyxer.gen.float import *
from elyxer.gen.header import *
from elyxer.gen.change import *
from elyxer.maths.array import *
from elyxer.bib.tex import *
from elyxer.bib.pub import *
from elyxer.xtra.newfangle import *
from elyxer.maths.macro import *
from elyxer.maths.extracommand import *
from elyxer.tex.texcode import *
from elyxer.maths.misc import *


class ContainerFactory(object):
  "Creates containers depending on the first line"

  def __init__(self):
    "Read table that convert start lines to containers"
    types = dict()
    for start, typename in ContainerConfig.starts.iteritems():
      types[start] = globals()[typename]
    self.tree = ParseTree(types)

  def createcontainer(self, reader):
    "Parse a single container."
    #Trace.debug('processing "' + reader.currentline().strip() + '"')
    if reader.currentline() == '':
      reader.nextline()
      return None
    container = Cloner.create(self.tree.find(reader))
    container.start = reader.currentline().strip()
    self.parse(container, reader)
    return container

  def parse(self, container, reader):
    "Parse a container"
    parser = container.parser
    parser.parent = container
    parser.ending = self.getending(container)
    parser.factory = self
    container.header = parser.parseheader(reader)
    container.begin = parser.begin
    self.parsecontents(container, reader)
    container.parameters = parser.parameters
    container.parser = None

  def parsecontents(self, container, reader):
    "Parse the contents of a container."
    contents = container.parser.parse(reader)
    if isinstance(contents, basestring):
      # read a string, set as parsed
      container.parsed = contents
      container.contents = []
    else:
      container.contents = contents

  def getending(self, container):
    "Get the ending for a container"
    split = container.start.split()
    if len(split) == 0:
      return None
    start = split[0]
    if start in ContainerConfig.startendings:
      return ContainerConfig.startendings[start]
    classname = container.__class__.__name__
    if classname in ContainerConfig.endings:
      return ContainerConfig.endings[classname]
    if hasattr(container, 'ending'):
      Trace.error('Pending ending in ' + container.__class__.__name__)
      return container.ending
    return None

class ParseTree(object):
  "A parsing tree"

  default = '~~default~~'

  def __init__(self, types):
    "Create the parse tree"
    self.root = dict()
    for start, type in types.iteritems():
      self.addstart(type, start)

  def addstart(self, type, start):
    "Add a start piece to the tree"
    tree = self.root
    for piece in start.split():
      if not piece in tree:
        tree[piece] = dict()
      tree = tree[piece]
    if ParseTree.default in tree:
      Trace.error('Start ' + start + ' duplicated')
    tree[ParseTree.default] = type

  def find(self, reader):
    "Find the current sentence in the tree"
    branches = self.matchline(reader.currentline())
    while not ParseTree.default in branches[-1]:
      branches.pop()
    last = branches[-1]
    return last[ParseTree.default]

  def matchline(self, line):
    "Match a given line against the tree, as deep as possible."
    branches = [self.root]
    for piece in line.split(' '):
      current = branches[-1]
      piece = piece.rstrip('>')
      if piece in current:
        branches.append(current[piece])
      else:
        return branches
    return branches

elyxer-1.2.5/src/elyxer/gen/splitpart.py0000644000175000017500000002436512074107030017605 0ustar  chennochenno#! /usr/bin/env python
# -*- coding: utf-8 -*-

#   eLyXer -- convert LyX source files to HTML output.
#
#   Copyright (C) 2009 Alex Fernández
#
#   This program is free software: 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 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
#   GNU General Public License for more details.
#
#   You should have received a copy of the GNU General Public License
#   along with this program.  If not, see .

# --end--
# Alex 20100418
# eLyXer split part processing
# http://www.nongnu.org/elyxer/


from elyxer.util.translate import *
from elyxer.gen.basket import *
from elyxer.gen.integral import *


class SplitPartLink(IntegralProcessor):
  "A link processor for multi-page output."

  processedtype = Link

  def processeach(self, link):
    "Process each link and add the current page."
    link.page = self.page

class NavigationLink(Container):
  "A link in the navigation header."

  def __init__(self, name):
    "Create the link for a given name (prev, next...)."
    self.name = name
    self.link = Link().complete(u' ', name, type=name)
    self.output = TaggedOutput().settag('span class="' + name + '"')
    self.contents = [self.link]

  def complete(self, container, after = False):
    "Complete the navigation link with destination container."
    "The 'after' parameter decides if the link goes after the part title."
    if not container.partkey:
      Trace.error('No part key for link name ' + unicode(container))
      return
    self.link.contents = [Constant(Translator.translate(self.name))]
    partname = self.getpartname(container)
    separator = Constant(u' ')
    if after:
      self.contents = partname + [separator, self.link]
    else:
      self.contents = [self.link, separator] + partname

  def getpartname(self, container):
    "Get the part name for a container, title optional."
    partname = [Constant(container.partkey.tocentry)]
    if not container.partkey.titlecontents:
      return partname
    if Options.notoclabels:
      return container.partkey.titlecontents
    return partname + [Constant(': ')] + container.partkey.titlecontents

  def setdestination(self, destination):
    "Set the destination for this link."
    self.link.destination = destination

  def setmutualdestination(self, destination):
    "Set the destination for this link, and vice versa."
    self.link.setmutualdestination(destination.link)

class UpAnchor(Link):
  "An anchor to the top of the page for the up links."

  def create(self, container):
    "Create the up anchor based on the first container."
    if not container.partkey:
      Trace.error('No part key for ' + unicode(container))
      return None
    self.createliteral(container.partkey.tocentry)
    self.partkey.titlecontents = container.partkey.titlecontents
    return self

  def createmain(self):
    "Create the up anchor for the main page."
    return self.createliteral(Translator.translate('main-page'))

  def createliteral(self, literal):
    "Create the up anchor based on a literal string."
    self.complete('', '')
    self.output = EmptyOutput()
    self.partkey = PartKey().createanchor(literal)
    return self

class SplitPartNavigation(object):
  "Used to create the navigation links for a new split page."

  def __init__(self):
    self.upanchors = []
    self.lastcontainer = None
    self.nextlink = None
    self.lastnavigation = None

  def writefirstheader(self, basket):
    "Write the first header to the basket."
    anchor = self.createmainanchor()
    basket.write(anchor)
    basket.write(self.createnavigation(anchor))

  def writeheader(self, basket, container):
    "Write the header to the basket."
    basket.write(LyXHeader())
    basket.write(self.currentupanchor(container))
    basket.write(self.createnavigation(container))

  def writefooter(self, basket):
    "Write the footer to the basket."
    if self.lastnavigation:
      basket.write(self.lastnavigation)
    basket.write(LyXFooter())

  def createnavigation(self, container):
    "Create the navigation bar with all links."
    prevlink = NavigationLink('prev')
    uplink = NavigationLink('up')
    if self.nextlink:
      prevlink.complete(self.lastcontainer)
      self.nextlink.complete(container, after=True)
      prevlink.setmutualdestination(self.nextlink)
      uplink.complete(self.getupdestination(container))
      uplink.setdestination(self.getupdestination(container))
    self.nextlink = NavigationLink('next')
    contents = [prevlink, Constant('\n'), uplink, Constant('\n'), self.nextlink]
    header = TaggedText().complete(contents, 'div class="splitheader"', True)
    self.lastcontainer = container
    self.lastnavigation = header
    return header
  
  def currentupanchor(self, container):
    "Update the internal list of up anchors, and return the current one."
    level = self.getlevel(container)
    while len(self.upanchors) > level:
      del self.upanchors[-1]
    while len(self.upanchors) < level:
      self.upanchors.append(self.upanchors[-1])
    upanchor = UpAnchor().create(container)
    self.upanchors.append(upanchor)
    return upanchor

  def createmainanchor(self):
    "Create the up anchor to the main page."
    mainanchor = UpAnchor().createmain()
    self.upanchors.append(mainanchor)
    return mainanchor

  def getupdestination(self, container):
    "Get the name of the up page."
    level = self.getlevel(container)
    if len(self.upanchors) < level:
      uppage = self.upanchors[-1]
    else:
      uppage = self.upanchors[level - 1]
    return uppage

  def getlevel(self, container):
    "Get the level of the container."
    if not container.partkey:
      return 1
    else:
      return container.partkey.level + 1

class SplitFileBasket(MemoryBasket):
  "A memory basket which contains a part split into a file, possibly with a TOC."

  def __init__(self):
    MemoryBasket.__init__(self)
    self.entrycount = 0
    self.root = None
    self.converter = TOCConverter()

  def write(self, container):
    "Keep track of numbered layouts."
    MemoryBasket.write(self, container)
    if not container.partkey:
      return
    if container.partkey.header:
      return
    entry = self.converter.convert(container)
    if not entry:
      return
    self.entrycount += 1
    self.root = entry

  def addtoc(self):
    "Add the table of contents if necessary."
    if self.entrycount != 1:
      return
    if self.root.branches == []:
      return
    text = Translator.translate('toc-for') + self.root.partkey.tocentry
    toc = TableOfContents().create(text)
    self.addbranches(self.root, toc)
    toc.add(self.converter.convertindented(LyXFooter()))
    self.write(toc)

  def addbranches(self, entry, toc):
    "Add an entry and all of its branches to the table of contents."
    for branch in entry.branches:
      toc.add(self.converter.indent(branch))
      self.addbranches(branch, toc)
  
class SplitPartBasket(Basket):
  "A basket used to split the output in different files."

  baskets = []

  def setwriter(self, writer):
    if not hasattr(writer, 'filename') or not writer.filename:
      Trace.error('Cannot use standard output for split output; ' +
          'please supply an output filename.')
      exit()
    self.writer = writer
    self.filename = writer.filename
    self.converter = TOCConverter()
    self.basket = MemoryBasket()
    self.basket.page = writer.filename
    return self

  def write(self, container):
    "Write a container, possibly splitting the file."
    self.basket.write(container)

  def splitbaskets(self):
    "Process the whole basket and create all baskets for split part pages."
    self.basket.process()
    basket = self.firstbasket()
    navigation = SplitPartNavigation()
    for container in self.basket.contents:
      if self.mustsplit(container):
        filename = self.getfilename(container)
        Trace.debug('New page ' + filename)
        basket.addtoc()
        navigation.writefooter(basket)
        basket = self.addbasket(filename)
        navigation.writeheader(basket, container)
      basket.write(container)
      if self.afterheader(container):
        navigation.writefirstheader(basket)
        self.mainanchor = navigation.upanchors[0]
    for basket in self.baskets:
      basket.process()

  def finish(self):
    "Process the whole basket, split into page baskets and flush all of them."
    self.splitbaskets()
    for basket in self.baskets:
      basket.flush()

  def afterheader(self, container):
    "Find out if this is the header on the file."
    return isinstance(container, LyXHeader)

  def firstbasket(self):
    "Create the first basket."
    return self.addbasket(self.filename, self.writer)

  def addbasket(self, filename, writer = None):
    "Add a new basket."
    if not writer:
      writer = LineWriter(filename)
    basket = SplitFileBasket()
    basket.setwriter(writer)
    self.baskets.append(basket)
    # set the page name everywhere
    basket.page = filename
    splitpartlink = SplitPartLink()
    splitpartlink.page = os.path.basename(basket.page)
    basket.processors = [splitpartlink]
    return basket

  def mustsplit(self, container):
    "Find out if the oputput file has to be split at this entry."
    if not container.partkey:
      return False
    if not container.partkey.filename:
      return False
    return True

  def getfilename(self, container):
    "Get the new file name for a given container."
    partname = container.partkey.filename
    basename = self.filename
    if Options.tocfor:
      basename = Options.tocfor
    base, extension = os.path.splitext(basename)
    return base + '-' + partname + extension

class SplitTOCBasket(SplitPartBasket):
  "A basket which contains the TOC for a split part document."

  def finish(self):
    "Process the whole basket, split into page baskets and flush all of them."
    self.splitbaskets()
    tocbasket = TOCBasket().setwriter(self.writer)
    self.mainanchor.partkey = PartKey().createmain()
    tocbasket.write(self.mainanchor)
    for container in self.basket.contents:
      tocbasket.write(container)
    tocbasket.finish()

elyxer-1.2.5/src/elyxer/gen/notes.py0000644000175000017500000001151612117063046016713 0ustar  chennochenno#! /usr/bin/env python
# -*- coding: utf-8 -*-

#   eLyXer -- convert LyX source files to HTML output.
#
#   Copyright (C) 2009 Alex Fernández
#
#   This program is free software: 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 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
#   GNU General Public License for more details.
#
#   You should have received a copy of the GNU General Public License
#   along with this program.  If not, see .

# --end--
# Alex 20101119
# LyX notes: notes, footnotes and margin notes.

from elyxer.util.trace import Trace
from elyxer.util.numbering import *
from elyxer.parse.parser import *
from elyxer.out.output import *
from elyxer.gen.container import *
from elyxer.ref.link import *


class SideNote(Container):
  "A side note that appears at the right."

  def __init__(self):
    self.parser = InsetParser()
    self.output = TaggedOutput()

  def process(self):
    "Enclose everything in a marginal span."
    self.output.settag('span class="Marginal"', True)

class FootnoteMarker(Container):
  "A marker for a footnote."

  def __init__(self):
    "Set the correct span class."
    self.contents = []
    span = 'span class="SupFootMarker"'
    if Options.alignfoot:
      span = 'span class="AlignFootMarker"'
    self.output = TaggedOutput().settag(span, False)
    mode = 'A'
    if Options.numberfoot:
      mode = '1'
    if Options.symbolfoot:
      mode = '*'
    NumberGenerator.generator.getcounter('Footnote').setmode(mode)

  def create(self):
    "Create the marker for a footnote."
    self.order = NumberGenerator.generator.generate('Footnote')
    if Options.endfoot:
      self.link = Link().complete(self.getmark(), 'footmarker-' + self.order)
    self.createcontents()
    return self

  def createanchor(self, marker):
    "Create the anchor for a footnote. Adds a link for end footnotes."
    self.order = marker.order
    if Options.endfoot:
      self.link = Link().complete(self.getmark(), 'footnote-' + self.order)
      self.link.setmutualdestination(marker.link)
    self.createcontents()
    return self

  def createlabel(self, marker):
    "Create the label for a footnote. Used in hoverfoot and marginfoot."
    self.order = marker.order
    self.contents = [Constant(self.getmark())]
    space = Constant(u' ')
    self.contents = [space] + self.contents + [space]
    return self

  def createcontents(self):
    "Create the contents of the marker."
    if Options.endfoot:
      self.contents = [self.link]
    else:
      self.contents = [Constant(self.getmark())]
    space = Constant(u' ')
    self.contents = [space] + self.contents + [space]

  def getmark(self):
    "Get the mark to be displayed in the marker based on the order."
    if Options.symbolfoot:
      return self.order
    else:
      return '[' + self.order + ']'

class Footnote(Container):
  "A footnote to the main text."

  def __init__(self):
    self.parser = InsetParser()
    self.output = TaggedOutput().settag('span class="FootOuter"', False)

  def process(self):
    "Add a counter for the footnote."
    "Can be numeric or a letter depending on runtime options."
    marker = FootnoteMarker().create()
    anchor = FootnoteMarker().createanchor(marker)
    label = FootnoteMarker().createlabel(marker)
    notecontents = list(self.contents)
    self.contents = [marker]
    if Options.hoverfoot:
      self.contents.append(self.createnote([label] + notecontents, 'span class="HoverFoot"'))
    if Options.marginfoot:
      self.contents.append(self.createnote([label] + notecontents, 'span class="MarginFoot"'))
    if Options.endfoot:
      EndFootnotes.footnotes.append(self.createnote([anchor] + notecontents, 'div class="EndFoot"'))

  def createnote(self, contents, tag):
    "Create a note with the given contents and HTML tag."
    return TaggedText().complete(contents, tag, False)

class EndFootnotes(Container):
  "The collection of footnotes at the document end."

  footnotes = []

  def __init__(self):
    "Generate all footnotes and a proper header for them all."
    self.output = ContentsOutput()
    header = TaggedText().constant(Translator.translate('footnotes'), 'h1 class="index"')
    self.contents = [header] + self.footnotes

class Note(Container):
  "A LyX note of several types"

  def __init__(self):
    self.parser = InsetParser()
    self.output = EmptyOutput()

  def process(self):
    "Hide note and comment, dim greyed out"
    self.type = self.header[2]
    if TagConfig.notes[self.type] == '':
      return
    self.output = TaggedOutput().settag(TagConfig.notes[self.type], True)

elyxer-1.2.5/src/elyxer/gen/__init__.py0000644000175000017500000000000012074107030017276 0ustar  chennochennoelyxer-1.2.5/src/elyxer/__init__.py0000644000175000017500000000000012074107030016525 0ustar  chennochennoelyxer-1.2.5/src/gpl-license0000644000175000017500000000144612074107030015250 0ustar  chennochenno#! /usr/bin/env python
# -*- coding: utf-8 -*-

#   eLyXer -- convert LyX source files to HTML output.
#
#   Copyright (C) 2009-2010 Alex Fernández
#
#   This program is free software: 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 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
#   GNU General Public License for more details.
#
#   You should have received a copy of the GNU General Public License
#   along with this program.  If not, see .

elyxer-1.2.5/src/math2html.py0000755000175000017500000000325612074107030015401 0ustar  chennochenno#! /usr/bin/env python
# -*- coding: utf-8 -*-

#   eLyXer -- convert LyX source files to HTML output.
#
#   Copyright (C) 2009 Alex Fernández
#
#   This program is free software: 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 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
#   GNU General Public License for more details.
#
#   You should have received a copy of the GNU General Public License
#   along with this program.  If not, see .

# --end--
# Alex 20101110
# eLyXer standalone formula conversion to HTML.

from elyxer.util.trace import Trace
from elyxer.util.options import *
from elyxer.maths.formula import *
from elyxer.maths.bits import *
from elyxer.maths.command import *
from elyxer.maths.hybrid import *
from elyxer.maths.array import *
from elyxer.maths.macro import *
from elyxer.proc.formulaproc import *


def math2html(formula):
  "Convert some TeX math to HTML."
  factory = FormulaFactory()
  whole = factory.parseformula(formula)
  FormulaProcessor().process(whole)
  whole.process()
  return ''.join(whole.gethtml())

def main():
  "Main function, called if invoked from elyxer.the command line"
  args = sys.argv
  Options().parseoptions(args)
  if len(args) != 1:
    Trace.error('Usage: math2html.py escaped_string')
    exit()
  result = math2html(args[0])
  Trace.message(result)

if __name__ == '__main__':
  main()

elyxer-1.2.5/src/licensify.py0000755000175000017500000000337012074107030015463 0ustar  chennochenno#! /usr/bin/env python
# -*- coding: utf-8 -*-

#   eLyXer -- convert LyX source files to HTML output.
#
#   Copyright (C) 2009 Alex Fernández
#
#   This program is free software: 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 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
#   GNU General Public License for more details.
#
#   You should have received a copy of the GNU General Public License
#   along with this program.  If not, see .

# --end--
# Alex 20090314
# Modifies the license of a Python source file

import sys
from elyxer.io.fileline import *
from elyxer.io.bulk import *
from elyxer.util.trace import Trace


mark = '--end--'

def process(reader, writer, license):
  "Conflate all Python files used in filein to fileout"
  for line in license:
    writer.writestring(line)
  while not mark in reader.currentline():
    reader.nextline()
  while not reader.finished():
    line = reader.currentline()
    writer.writeline(line)
    reader.nextline()
  reader.close()

def processall(args):
  "Process all arguments"
  del args[0]
  if len(args) == 0:
    Trace.error('Usage: licensify.py licensefile [file...]')
    return
  licensefile = BulkFile(args[0])
  license = licensefile.readall()
  del args[0]
  while len(args) > 0:
    pythonfile = BulkFile(args[0])
    reader, writer = pythonfile.getfiles()
    del args[0]
    process(reader, writer, license)
    pythonfile.swaptemp()

processall(sys.argv)

elyxer-1.2.5/src/css/0000755000175000017500000000000012074107030013706 5ustar  chennochennoelyxer-1.2.5/src/css/print.css0000644000175000017500000000151312074107030015554 0ustar  chennochenno/*
* CSS section for print.
*/
@media print {
body {
	font: 90% serif;
	background: #ffffff;
	color: black;
	margin: 0;
	padding: 0;
}
#globalWrapper {
	width: 100%;
	margin: 0px;
	padding: 0px;
	background: #ffffff;
	line-height: 1.5em;
}
span.FootOuter .Foot {
	display: block;
	position: relative;
	float: right;
	clear: right;
	margin: 0.2ex;
	border: thin solid #c0c0c0;
	background: #ffffff;
	width: 30%;
	padding: 0.5ex;
	font-size: small;
	font-weight: normal;
	line-height: 1.5em;
	text-align: left;
}
span.FootOuter .HoverFoot {
	display: block;
	position: relative;
	float: right;
	clear: right;
	margin: 0.2ex;
	border: thin solid #c0c0c0;
	background: #ffffff;
	width: 30%;
	padding: 0.5ex;
	font-size: small;
	font-weight: normal;
	line-height: 1.5em;
	text-align: left;
}
a:visited {
	color: #0030c0;
}
/* end of print CSS */
}
elyxer-1.2.5/src/css/master.css0000644000175000017500000001315512074107030015720 0ustar  chennochenno/*
*   eLyXer -- convert LyX source files to HTML output.
*
*   Copyright (C) 2009-2010 Alex Fernández
*
*   This program is free software: 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 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
*   GNU General Public License for more details.
*
*   You should have received a copy of the GNU General Public License
*   along with this program.  If not, see http://www.gnu.org/licenses/.
*/
/* --end--
* Global CSS file for LyX documents.
*/

body {
	font: 90% sans-serif;
	background: #f9f9f9;
	color: black;
	margin: 0;
	padding: 0;
}

#globalWrapper {
	margin: 10px 5%;
	padding: 20px;
	background: #ffffff;
	line-height: 1.5em;
}

/* Basic styles */
a {
	text-decoration: none;
	background: none;
}
a:link {
	color: #0030c0;
}
a:visited {
	color: #603090;
}
a:active {
	color: #ffa000;
}
a:hover {
	text-decoration: underline;
}
h1 {
	margin-top: 1em;
	line-height: 1.5em;
}
h1.Part {
	text-align: center;
}
h1.Part- {
	text-align: center;
}
sup {
	font-size: 0.75em;
	line-height: 0.5em;
	vertical-align: text-top;
}
sub {
	font-size: 0.75em;
	line-height: 0.5em;
	vertical-align: text-bottom;
}
div.Standard {
	margin: 1em 0;
}
div.Unindented {
	margin: 0;
}
div.Indented {
	text-indent: 30pt;
	margin: 0;
}
div.Indented * {
	text-indent: 0pt;
}
p.dir {
	float: right;
}
p.printindex {
	font-size: 0.90em;
}
a.printindex {
	color: black;
}
table {
	display: inline-table;
	text-align: center;
	border-collapse: collapse;
	margin-top: 1em;
	margin-bottom: 1em;
}
tr.header {
	border-bottom: thin solid #c0c0c0;
	background: #ffffff;
	font-weight: bold;
}
td {
	padding: 1ex;
	border: thin solid #f0f0f0;
}
td div.Standard {
	margin: 0ex;
	padding: 0ex;
}
div.caption div.Standard, div.table div.Standard {
	margin: 0ex;
	padding: 0ex;
}
td.numeric {
	text-align: right;
}
td.empty {
	text-align: center;
}
div.right {
	text-align: right;
}
div.center {
	text-align: center;
	margin-left: auto;
	margin-right: auto;
}
p.biblio {
}
div.Paragraph, div.Paragraph- {
	font-weight: bold;
	font-size: 103%;
}
span.versalitas, span.noun {
	font-variant: small-caps;
}
span.sans {
	font-family: sans-serif;
}
span.code {
	font-family: monospace;
}
div.Plain {
	display: inline;
	width: auto;
}
h2 {
	line-height: 1.4em;
}
span.Description-entry {
	font-weight: bold;
}
span.List-entry {
	display: inline-block;
	width: 25%;
	vertical-align: text-top;
}
span.List-contents {
	display: inline-block;
	width: 75%;
	vertical-align: text-top;
}
div.Space {
	display: none;
}
span.appendix {
	display: none;
}
h1.biblio {
}
span.greyedout {
	color: #808080;
}
div.Description, div.List, li {
	margin: 1em 0;
}
li.nested {
	list-style-type: none;
}
span.Info {
	background: #f0f0f0;
	border: thin solid #c0c0c0;
}
pre {
	padding: 0em;
	margin: 0em;
	width: auto;
	font-family: monospace;
	line-height: 1.5em;
}
pre.LyX-Code {
	margin: 0.5em 3em;
}
a.Label {
	text-decoration: none;
	color: #000000;
}
span.phantom {
	color: #ffffff;
}
a.biblioentry {
	color: black;
}
span.menuitem {
	font-size: 105%;
}
span.normal {
	font-style: normal;
}
div.PlainVisible {
	width: auto;
}
div.indexgroup {
	margin-left: 2em;
}
span.strong {
	font-weight: bold;
}

/* Figures and Tables */
img.embedded {
	width: 100%;
	_width: auto;
}
div.float {
	margin-top: 1ex;
	margin-bottom: 1ex;
	text-align: center;
}
span.float {
	margin-top: 1ex;
	margin-bottom: 1ex;
	text-align: center;
}
div.figure {
	display: inline-block;
	text-align: left;
	padding: 1ex;
	margin-left: auto;
	margin-right: auto;
	border: thin solid #c0c0c0;
}
div.table {
	display: inline-block;
	text-align: left;
	padding: 1ex;
	margin-left: auto;
	margin-right: auto;
	border: thin solid #c0c0c0;
}
div.algorithm {
	display: inline-block;
	text-align: left;
	padding: 1ex;
	margin-left: auto;
	margin-right: auto;
	border: thin solid #c0c0c0;
}
div.caption {
	text-align: center;
	font-family: sans-serif;
	margin-left: auto;
	margin-right: auto;
	padding: 0.5ex;
}
img.figure {
	width: 100%;
	_width: auto;
}
div.multifigure {
	padding: 1ex;
	width: 100%;
}
div.multitable {
	display: inline-block;
	padding: 1ex;
	margin-left: auto;
	margin-right: auto;
	border: thin solid #c0c0c0;
}
div.multialgorithm {
	display: inline-block;
	padding: 1ex;
	margin-left: auto;
	margin-right: auto;
	border: thin solid #c0c0c0;
}
div.wrap-l, div.wrap-o, div.wrap-i {
	margin: 2ex;
	float: left;
}
div.wrap-r {
	margin: 2ex;
	float: right;
}
div.listing {
	display: inline-block;
	text-align: left;
	margin-left: auto;
	margin-right: auto;
	padding: 0.5ex;
	border: thin solid #c0c0c0;
}
span.number-left {
	float: left;
	background: #f0f0f0;
	width: 3em;
	text-align: right;
	margin-right: 1em;
}
span.number-right {
	float: right;
	background: #f0f0f0;
	width: 3em;
	text-align: right;
	margin-left: 1em;
}

/* Header */
h1.title {
	text-align: center;
}
h2.author {
	text-align: center;
}
h2.Date {
	text-align: center;
}
div.abstract {
	margin: 1em 3em;
	text-align: left;
	font-size: 0.95em;
}
p.abstract-message {
	text-align: center;
	font-weight: bold;
}
div.tocheader {
	margin: 1em 0;
	font-size: large;
}
a.toc {
	color: black;
}
div.tocindent {
	padding: 0 0 0 2em;
}
div.toc {
	margin: 0.5em 0;
	font-size: 0.95em;
}
div.fulltoc {
	padding: 1em;
}
div.warning {
	font-size: 120%;
	color:#cc0000;
}
div.Institute {
	text-align: center;
}
@import "extras.css";
@import "math.css";
@import "obsolete.css";
@import "print.css";
elyxer-1.2.5/src/css/math.css0000644000175000017500000000524612074107030015360 0ustar  chennochenno/* --end--
* CSS file for LaTeX formulas.
*/

/* Formulas */
.formula {
	text-align: center;
	font-family: "DejaVu Serif", serif;
	margin: 1.2em 0;
}
span.formula {
	white-space: nowrap;
}
div.formula {
	padding: 0.5ex;
	margin-left: auto;
	margin-right: auto;
}

/* Basic features */
a.eqnumber {
	display: inline-block;
	float: right;
	clear: right;
	font-weight: bold;
}
span.unknown {
	color: #800000;
}
span.ignored, span.arraydef {
	display: none;
}
.formula i {
	letter-spacing: 0.1ex;
}

/* Alignment */
.align-left, .align-l {
	text-align: left;
}
.align-right, .align-r {
	text-align: right;
}
.align-center, .align-c {
	text-align: center;
}

/* Structures */
span.overline, span.bar {
	text-decoration: overline;
}
.fraction, .fullfraction {
	display: inline-block;
	vertical-align: middle;
	text-align: center;
}
.fraction .fraction {
	font-size: 80%;
	line-height: 100%;
}
span.numerator {
	display: block;
}
span.denominator {
	display: block;
	padding: 0ex;
	border-top: thin solid;
}
sup.numerator, sup.unit {
	font-size: 70%;
	vertical-align: 80%;
}
sub.denominator, sub.unit {
	font-size: 70%;
	vertical-align: -20%;
}
span.sqrt {
	display: inline-block;
	vertical-align: middle;
	padding: 0.1ex;
}
sup.root {
	font-size: 70%;
	position: relative;
	left: 1.4ex;
}
span.radical {
	display: inline-block;
	padding: 0ex;
	font-size: 150%;
	vertical-align: top;
}
span.root {
	display: inline-block;
	border-top: thin solid;
	padding: 0ex;
	vertical-align: middle;
}
span.symbol {
	font-size: 125%;
}
span.bigsymbol {
	font-size: 150%;
}
span.largesymbol {
	font-size: 175%;
}
span.hugesymbol {
	font-size: 200%;
}
span.scripts {
	display: inline-table;
	vertical-align: middle;
}
.script {
	display: table-row;
	text-align: left;
	line-height: 150%;
}
span.limits {
	display: inline-table;
	vertical-align: middle;
}
.limit {
	display: table-row;
	line-height: 95%;
}
sup.limit, sub.limit {
	line-height: 150%;
}
span.symbolover {
	display: inline-block;
	text-align: center;
	position: relative;
	float: right;
	right: 100%;
	bottom: 0.5em;
	width: 0px;
}
span.withsymbol {
	display: inline-block;
}
span.symbolunder {
	display: inline-block;
	text-align: center;
	position: relative;
	float: right;
	right: 80%;
	top: 0.3em;
	width: 0px;
}

/* Environments */
span.array, span.bracketcases, span.binomial, span.environment {
	display: inline-table;
	text-align: center;
	border-collapse: collapse;
	margin: 0em;
	vertical-align: middle;
}
span.arrayrow, span.binomrow {
	display: table-row;
	padding: 0ex;
	border: 0ex;
}
span.arraycell, span.bracket, span.case, span.binomcell, span.environmentcell {
	display: table-cell;
	padding: 0ex 0.2ex;
	line-height: 99%;
	border: 0ex;
}
@import "math-extras.css";

elyxer-1.2.5/src/css/math-extras.css0000644000175000017500000000263312074107030016661 0ustar  chennochenno/*
* CSS file for LaTeX formulas, extra stuff:
* binomials, vertical braces, stackrel, fonts and colors.
*/

/* Inline binomials */
span.binom {
	display: inline-block;
	vertical-align: middle;
	text-align: center;
	font-size: 80%;
}
span.binomstack {
	display: block;
	padding: 0em;
}

/* Over- and underbraces */
span.overbrace {
	border-top: 2pt solid;
}
span.underbrace {
	border-bottom: 2pt solid;
}

/* Stackrel */
span.stackrel {
	display: inline-block;
	text-align: center;
}
span.upstackrel {
	display: block;
	padding: 0em;
	font-size: 80%;
	line-height: 64%;
	position: relative;
	top: 0.15em;

}
span.downstackrel {
	display: block;
	vertical-align: bottom;
	padding: 0em;
}

/* Fonts */
span.mathsf, span.textsf {
	font-style: normal;
	font-family: sans-serif;
}
span.mathrm, span.textrm {
	font-style: normal;
	font-family: serif;
}
span.text, span.textnormal {
	font-style: normal;
}
span.textipa {
	color: #008080;
}
span.fraktur {
	font-family: "Lucida Blackletter", eufm10, blackletter;
}
span.blackboard {
	font-family: Blackboard, msbm10, serif;
}
span.scriptfont {
	font-family: "Monotype Corsiva", "Apple Chancery", "URW Chancery L", cursive;
	font-style: italic;
}

/* Colors */
span.colorbox {
	display: inline-block;
	padding: 5px;
}
span.fbox {
	display: inline-block;
	border: thin solid black;
	padding: 2px;
}
span.boxed, span.framebox {
	display: inline-block;
	border: thin solid black;
	padding: 5px;
}
elyxer-1.2.5/src/css/freebsd-license.css0000644000175000017500000000111212074107030017445 0ustar  chennochenno/*
*   math2html: convert LaTeX equations to HTML output.
*
*   Copyright (C) 2009,2010 Alex Fernández
*
*   Released under the terms of the `2-Clause BSD license'_, in short:
*   Copying and distribution of this file, with or without modification,
*   are permitted in any medium without royalty provided the copyright
*   notice and this notice are preserved.
*   This file is offered as-is, without any warranty.
*
* .. _2-Clause BSD license: http://www.spdx.org/licenses/BSD-2-Clause
*
*   Based on eLyXer: convert LyX source files to HTML output.
*   http://elyxer.nongnu.org/
*/
elyxer-1.2.5/src/css/extras.css0000644000175000017500000000626512074107030015737 0ustar  chennochenno/*
* Extras: colors, footnotes, boxes, spaces...
*/

/* Raw colors */
span.red {
	color: #c00000;
}
span.blue {
	color: #0000c0;
}
span.green {
	color: #00c000;
}
span.magenta {
	color: #c000c0;
}
span.cyan {
	color: #00c0c0;
}
span.yellow {
	color: #c0c000;
}
span.white {
	color: #ffffff;
}

/* Footnotes */
span.SupFootMarker {
	color: #0030c0;
	font-size: 0.75em;
	line-height: 0.5em;
	vertical-align: text-top;
}
span.AlignFootMarker {
	color: #0030c0;
}
div.EndFoot {
	margin: 0.2ex;
	background: #ffffff;
	padding: 0.5ex;
	font-size: small;
	font-weight: normal;
	line-height: 1.5em;
	text-align: left;
}
span.MarginFoot {
	float: right;
	clear: right;
	margin: 0.2ex;
	border: thin solid #c0c0c0;
	background: #ffffff;
	width: 30%;
	padding: 0.5ex;
	font-size: small;
	font-weight: normal;
	line-height: 1.5em;
	text-align: left;
}
span.HoverFoot {
	margin: 0.2ex;
	border: thin solid #c0c0c0;
	background: #ffffff;
	padding: 0.5ex;
	font-size: small;
	font-weight: normal;
	line-height: 1.5em;
	text-align: left;
}
span.FootOuter .HoverFoot {
	display: none;
	position: absolute;
}
span.FootOuter:hover .HoverFoot {
	display: inline;
	float: none;
}
span.Marginal {
	float: right;
	clear: right;
	margin: 0.2ex;
	border: thin solid #c0c0c0;
	background: #ffffff;
	width: 30%;
	padding: 0.5ex;
	font-size: small;
	font-weight: normal;
	line-height: 1.5em;
	text-align: left;
}
span.Note {
	display: none;
}

/* Boxes */
div.framed {
	outline-style: solid;
}
div.frameless {
}
div.Frameless {
}
div.Boxed {
	outline-width: thin;
	outline-style: solid;
}
div.Framed {
	outline-width: thin;
	outline-style: solid;
	line-height: 200%;
}
div.Doublebox {
	outline-style: double;
}
div.Shadowbox {
	outline-style: outset;
}
div.Shaded {
	outline-style: inset;
}
div.ovalbox {
	outline-style: groove;
}
div.Ovalbox {
	outline-style: ridge;
}
hr.line {
	display: inline-block;
}

/* Spaces */
span.hspace {
	display: inline-block;
}
span.vspace {
	display: inline-block;
	vertical-align: text-top;
}
span.hfill {
	display: inline-block;
	margin-left: auto;
	margin-right: auto;
	min-width: 20mm;
	background: #fff0f0;
}
div.defskip {
	display: block;
	height: 1em;
}
div.smallskip {
	display: block;
	height: 0.5em;
}
div.medskip {
	display: block;
	height: 1em;
}
div.bigskip {
	display: block;
	height: 2em;
}
div.vfill {
	display: block;
	height: 30em;
}

/* Sizes */
span.scriptstyle {
	font-size: 0.75em;
}
span.scriptscriptstyle {
	font-size: 0.60em;
}

/* Chunks */
div.chunk {
	width: auto;
}
span.chunkleft span.chunkright {
	font-style: normal;
}
span.chunkdecl {
	font-style: italic;
	padding: 0em 2em;
}
span.chunkref {
	font-style: italic;
}

/* Split Part Navigation */
div.splitheader {
	margin: 0em;
	padding: 0.1em;
	text-align: center;
	background: #f9f9f9;
	overflow: auto;
}
span.next {
	float: right;
	width: 30%;
	text-align: right;
}
span.up {
	display: inline-block;
	width: 30%;
	text-align: center;
}
span.prev {
	float: left;
	width: 30%;
	text-align: left;
}
hr.footer {
	margin-top: 2em;
}
div.footer {
	font-size: 0.90em;
	margin: 1em 0;
}

/* Change Tracking */
span.inserted {
	color: #0000ff;
}
span.deleted {
	color: #ff0000;
	text-decoration: line-through;
}

/* Google Charts */
img.chart {
	vertical-align: middle;
}
elyxer-1.2.5/src/css/gpl-license.css0000644000175000017500000000137112074107030016624 0ustar  chennochenno/*
*   eLyXer -- convert LyX source files to HTML output.
*
*   Copyright (C) 2009-2010 Alex Fernández
*
*   This program is free software: 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 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
*   GNU General Public License for more details.
*
*   You should have received a copy of the GNU General Public License
*   along with this program.  If not, see http://www.gnu.org/licenses/.
*/
elyxer-1.2.5/src/css/obsolete.css0000644000175000017500000000442212074107030016236 0ustar  chennochenno/*
* Obsolete definitions, kept for backwards compatibility.
*/

/* Footnotes */
span.FootMarker {
	color: #0030c0;
	font-size: 0.75em;
	line-height: 0.5em;
	vertical-align: text-top;
}
span.Foot {
	margin: 0.2ex;
	border: thin solid #c0c0c0;
	background: #ffffff;
	padding: 0.5ex;
	font-size: small;
	font-weight: normal;
	line-height: 1.5em;
	text-align: left;
}
span.FootOuter .Foot {
	display: none;
	position: absolute;
}
span.FootOuter:hover .Foot {
	display: inline;
	float: none;
}

/* Dotted box */
span.dotted {
	border-top: thin dotted;
}

/* Obsolete aligned structures */
span.numerator-l {
	display: block;
	text-align: left;
}
span.numerator-r {
	display: block;
	text-align: right;
}
span.numeratorl {
	display: block;
	text-align: left;
}
span.numeratorr {
	display: block;
	text-align: right;
}
span.framebox- {
	display: inline-block;
	border: thin solid black;
	text-align: center;
	padding: 5px;
}
span.framebox-l {
	display: inline-block;
	border: thin solid black;
	text-align: left;
	padding: 5px;
}
span.framebox-r {
	display: inline-block;
	border: thin solid black;
	text-align: right;
	padding: 5px;
}
td.formula-l {
	text-align: left;
	padding: 0.2ex;
	border: 0ex;
}
td.formula-c {
	text-align: center;
	padding: 0.2ex;
	border: 0ex;
}
td.formula-r {
	text-align: right;
	padding: 0.2ex;
	border: 0ex;
}

/* Obsolete limits */
sub.bigsymbol {
	display: table-row;
	text-align: left;
	line-height: 150%;
}
sup.bigsymbol {
	display: table-row;
	text-align: left;
	line-height: 150%;
}

/* Obsolete cases */
table.cases {
	display: inline-block;
	text-align: center;
	border-collapse: collapse;
	margin: 0.2em;
	border-left: thin solid;
	vertical-align: middle;
}
table.cases tr td {
	padding-left: 1ex;
	padding-right: 1em;
}

/* Obsolete binomials */
span.fullbinom {
	display: inline-block;
	vertical-align: middle;
	text-align: center;
}
span.upbinom {
	display: block;
	padding: 0em;
}
span.downbinom {
	display: block;
	padding: 0em;
}

/* Obsolete environments */
table.formula {
	display: inline-block;
	text-align: center;
	border-collapse: collapse;
	margin: 0em;
	vertical-align: middle;
}
td.formula {
	padding: 0.2ex;
	border: 0ex;
}
table.environment {
	display: inline-block;
	text-align: right;
	margin: 0;
	vertical-align: middle;
}
table.environment tr td {
	padding: 0 1em;
}
elyxer-1.2.5/src/loremipsumize.py0000755000175000017500000000622112074107030016400 0ustar  chennochenno#! /usr/bin/env python
# -*- coding: utf-8 -*-

#   eLyXer -- convert LyX source files to HTML output.
#
#   Copyright (C) 2009 Alex Fernández
#
#   This program is free software: 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 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
#   GNU General Public License for more details.
#
#   You should have received a copy of the GNU General Public License
#   along with this program.  If not, see .

# --end--
# Alex 20091210
# Lorem-ipsumize a document: replace all alphanumeric texts longer than two words with "Lorem ipsum" and leave the symbols.

import sys
from elyxer.io.fileline import *
from elyxer.parse.position import *
from elyxer.util.trace import Trace


files = list()

def getreader(filename):
  "Get a reader for lines"
  if filename in files:
    # already parsed; skip
    return None
  files.append(filename)
  return LineReader(filename)

def readargs(args):
  "Read arguments from the command line"
  del args[0]
  if len(args) == 0:
    usage()
    return None, None
  if args[0] == '-h' or args[0] == '--help':
    usage()
    return None, None
  reader = getreader(args[0])
  del args[0]
  fileout = sys.stdout
  if len(args) > 0:
    fileout = args[0]
    del args[0]
  if len(args) > 0:
    usage()
    return
  writer = LineWriter(fileout)
  return reader, writer

def usage():
  "Show command line help."
  Trace.error('Usage: loremipsumize.py filein [fileout]')
  Trace.error('Mask your document using nonsensical words (Lorem Ipsum).')
  Trace.error('Part of the eLyXer package (http://elyxer.nongnu.org/).')
  Trace.error('  Options:')
  Trace.error('    --help: show this message and quit.')
  return

class LoremIpsumizer(object):

  starts = '@\\'

  def loremipsumize(self, reader, writer):
    "Convert all texts longer than two words to 'lorem ipsum'."
    if not reader:
      return
    while not reader.finished():
      line = self.processline(reader.currentline())
      writer.writeline(line)
      reader.nextline()
    reader.close()

  def processline(self, line):
    "Process a single line and return the result."
    if len(line) == 0:
      return ''
    if line[0] in LoremIpsumizer.starts:
      return line
    pos = TextPosition(line)
    result = ''
    while not pos.finished():
      result += self.parsepos(pos)
    return result

  def parsepos(self, pos):
    "Parse the current position, return the result."
    if pos.current().isalpha() or pos.current().isdigit():
      alpha = pos.glob(lambda current: current.isalpha() or current.isspace() or current.isdigit())
      if len(alpha.split()) > 2:
        return "lorem ipsum"
      return alpha
    if pos.current().isspace():
      return pos.skipspace()
    return pos.skipcurrent()

reader, writer = readargs(sys.argv)
if reader:
  LoremIpsumizer().loremipsumize(reader, writer)
  writer.close()


elyxer-1.2.5/src/javatopy.py0000755000175000017500000000334412074107030015334 0ustar  chennochenno#! /usr/bin/env python
# -*- coding: utf-8 -*-

#   eLyXer -- convert LyX source files to HTML output.
#
#   Copyright (C) 2009 Alex Fernández
#
#   This program is free software: 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 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
#   GNU General Public License for more details.
#
#   You should have received a copy of the GNU General Public License
#   along with this program.  If not, see .

# --end--
# Alex 20091226
# Port a Java program to a Python equivalent. Used to port MathToWeb.

import sys
import os.path
from elyxer.io.fileline import *
from elyxer.parse.position import *
from elyxer.util.trace import Trace
from jtp.porter import *


def readargs(args):
  "Read arguments from the command line"
  del args[0]
  if len(args) == 0:
    usage()
    return
  inputfile = args[0]
  del args[0]
  outputfile = os.path.splitext(inputfile)[0].lower() + '.py'
  if len(args) > 0:
    outputfile = args[0]
    del args[0]
  if len(args) > 0:
    usage()
    return
  return inputfile, outputfile

def usage():
  Trace.error('Usage: javatopy.py filein.java [fileout.py]')
  return

inputfile, outputfile = readargs(sys.argv)
Trace.debugmode = True
Trace.showlinesmode = True
if inputfile:
  JavaPorter().topy(FilePosition(inputfile), LineWriter(outputfile))
  Trace.message('Conversion done, running ' + outputfile)
  os.system('python ' + outputfile)

elyxer-1.2.5/src/exportconfig.py0000755000175000017500000001315112117063046016211 0ustar  chennochenno#! /usr/bin/env python
# -*- coding: utf-8 -*-

#   eLyXer -- convert LyX source files to HTML output.
#
#   Copyright (C) 2009 Alex Fernández
#
#   This program is free software: 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 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
#   GNU General Public License for more details.
#
#   You should have received a copy of the GNU General Public License
#   along with this program.  If not, see .

# --end--
# Alex 20090504
# eLyXer configuration manipulation

import sys
import datetime
from elyxer.util.trace import Trace
from elyxer.util.clparse import *
from elyxer.conf.fileconfig import *
from elyxer.conf.importconfig import *


class Config(object):
  "A configuration file"

  cfg = 'conf/base.cfg'
  py = 'elyxer/conf/config.py'
  po = 'conf/elyxer.pot'
  addcfg = None
  importcfg = None
  importcsv = None
  importunimath = None
  help = False

  def run(self, args):
    "Parse command line options and run export to cfg or to py"
    parser = CommandLineParser(Config)
    error = parser.parseoptions(args)
    if error:
      Trace.error(error)
      self.usage()
    elif Config.help:
      self.usage()
    option = self.parseoption(args)
    if not option:
      Trace.error('Choose cfg, py or po')
      self.usage()
    if option == 'cfg':
      self.exportcfg()
      return
    elif option == 'py':
      self.exportpy()
      return
    elif option == 'po':
      self.exportpo()
    else:
      Trace.error('Unknown option ' + option)
      self.usage()

  def usage(self):
    "Show tool usage"
    Trace.error('Usage: exportconfig.py [options] [cfg|py|po]')
    Trace.error('  cfg: export to text configuration file')
    Trace.error('  py: export to python file')
    Trace.error('  po: export elyxer.pot internationalization file')
    Trace.error('  options:')
    Trace.error('    --cfg base.cfg: choose base config file')
    Trace.error('    --addcfg add.cfg: load additional config file')
    Trace.error('    --py config.py: choose Python config file')
    Trace.error('    --importcfg unicodesymbols: import LyX unicode symbols file')
    Trace.error('    --importcsv unicodecsv: import a file of "\command,unicode" pairs')
    Trace.error('    --importunimath unimath.txt: import a file in unimath format')
    Trace.error('      (See http://milde.users.sourceforge.net/LUCR/Math/)')
    exit()

  def read(self):
    "Read from configuration file"
    reader = ConfigReader(Config.cfg).parse()
    if Config.addcfg:
      addreader = ConfigReader(Config.addcfg).parse()
      self.mix(reader, addreader)
    if Config.importcfg:
      addreader = ImportCommands(Config.importcfg).parse()
      self.mix(reader, addreader)
    if Config.importcsv:
      addreader = ImportCsv(Config.importcsv).parse()
      self.mix(reader, addreader)
    if Config.importunimath:
      addreader = ImportUnimath(Config.importunimath).parse()
      self.mix(reader, addreader)
    reader.objects['GeneralConfig.version']['date'] = datetime.date.today().isoformat()
    return reader

  def exportcfg(self):
    "Export configuration to a cfg file"
    linewriter = LineWriter(Config.cfg)
    writer = ConfigWriter(linewriter)
    configs = [globals()[x] for x in dir(elyxer.conf.config) if x.endswith('Config')]
    writer.writeall(configs)

  def exportpy(self):
    "Export configuration as a Python file"
    reader = self.read()
    linewriter = LineWriter(Config.py)
    translator = ConfigToPython(linewriter)
    translator.write(reader.objects)

  def exportpo(self):
    "Export configuration as a gettext .po file."
    reader = self.read()
    writer = LineWriter(Config.po)
    export = TranslationExport(writer)
    export.export(reader.objects['TranslationConfig.constants'])

  def parseoption(self, args):
    "Parse the next option"
    if len(args) == 0:
      return None
    option = args[0]
    del args[0]
    return option

  def mix(self, reader, addreader):
    "Mix two configuration files"
    Trace.message('--- new content follows ---')
    for name, object in addreader.objects.iteritems():
      Trace.message('')
      Trace.message('[' + name + ']')
      equiv = reader.objects[name]
      for key, value in object.iteritems():
        if not key in equiv:
          equiv[key] = value
          Trace.message(key + ':' + unicode(value))

class TranslationExport(object):
  "Export the translation to a file."

  def __init__(self, writer):
    self.writer = writer

  def export(self, constants):
    "Export the translation constants as a .po file."
    self.writer.writeline('# eLyXer internationalization file.')
    self.writer.writeline('# Created on ' + datetime.date.today().isoformat())
    self.writer.writeline(u'# Contact: Alex Fernandez ')
    self.writer.writeline(u'# http://elyxer.nongnu.org/')
    self.writer.writeline('# This file is distributed under the same license as the eLyXer package.')
    self.writer.writeline('# (C) 2010 Alex Fernandez .')
    self.writer.writeline('#')
    self.writer.writeline('')
    for key, message in constants.iteritems():
      self.writer.writeline('')
      self.writer.writeline('#: ' + key)
      self.writer.writeline('msgid  "' + message + '"')
      self.writer.writeline('msgstr "' + message + '"')
    self.writer.close()

config = Config()
del sys.argv[0]
config.run(sys.argv)

elyxer-1.2.5/src/textchange.py0000755000175000017500000000454612074107030015636 0ustar  chennochenno#! /usr/bin/env python
# -*- coding: utf-8 -*-

#   eLyXer -- convert LyX source files to HTML output.
#
#   Copyright (C) 2009 Alex Fernández
#
#   This program is free software: 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 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
#   GNU General Public License for more details.
#
#   You should have received a copy of the GNU General Public License
#   along with this program.  If not, see .

# --end--
# Alex 20090416
# Change text in some files at once

import sys
from elyxer.io.fileline import *
from elyxer.io.bulk import *
from elyxer.util.trace import Trace
from elyxer.util.clparse import *


class TextChange(object):
  "A change in some text"

  def __init__(self, key, value):
    self.key = key
    self.value = value

  def affects(self, line):
    "Decide if the change affects the line"
    if self.key in line:
      return True
    return False

  def do(self, line):
    "Change the text in the line"
    return line.replace(self.key, self.value)

def process(reader, writer, change):
  "Change all lines in the file"
  counter = 0
  while not reader.finished():
    line = reader.currentline()
    if change.affects(line):
      line = change.do(line)
      counter += 1
    writer.writeline(line)
    reader.nextline()
  reader.close()
  return counter

def processall(args):
  "Process all arguments"
  del args[0]
  if len(args) < 3:
    Trace.error('Usage: textchange.py original changed [file...]')
    return
  original = args[0]
  del args[0]
  changed = args[0]
  del args[0]
  Trace.message('Replacing ' + original + '->' + changed)
  change = TextChange(original, changed)
  total = 0
  while len(args) > 0:
    pythonfile = BulkFile(args[0])
    reader, writer = pythonfile.getfiles()
    del args[0]
    counter = process(reader, writer, change)
    total += counter
    Trace.message('  ' + unicode(counter) + ' occurrences in ' +
        unicode(pythonfile))
    pythonfile.swaptemp()
  Trace.message('Total replacements: ' + unicode(total))

processall(sys.argv)

elyxer-1.2.5/src/conf/0000755000175000017500000000000012117174744014061 5ustar  chennochennoelyxer-1.2.5/src/conf/elyxer.pot0000644000175000017500000000446412117174754016126 0ustar  chennochenno# eLyXer internationalization file.
# Created on 2013-03-10
# Contact: Alex Fernandez 
# http://elyxer.nongnu.org/
# This file is distributed under the same license as the eLyXer package.
# (C) 2010 Alex Fernandez .
#


#: Subsubsection
msgid  "Subsubsection"
msgstr "Subsubsection"

#: figure
msgid  "figure"
msgstr "figure"

#: abstract
msgid  "Abstract"
msgstr "Abstract"

#: jsmath-warning
msgid  "Warning: "
msgstr "Warning: "

#: up
msgid  "Up"
msgstr "Up"

#: Book
msgid  "Book"
msgstr "Book"

#: references
msgid  "References"
msgstr "References"

#: Subsection
msgid  "Subsection"
msgstr "Subsection"

#: list-algorithm
msgid  "List of Algorithms"
msgstr "List of Algorithms"

#: Appendix
msgid  "Appendix"
msgstr "Appendix"

#: index
msgid  "Index"
msgstr "Index"

#: bibliography
msgid  "Bibliography"
msgstr "Bibliography"

#: list-table
msgid  "List of Tables"
msgstr "List of Tables"

#: next
msgid  "Next"
msgstr "Next"

#: float-algorithm
msgid  "Algorithm "
msgstr "Algorithm "

#: Part
msgid  "Part"
msgstr "Part"

#: generated-by
msgid  "Document generated by "
msgstr "Document generated by "

#: toc
msgid  "Table of Contents"
msgstr "Table of Contents"

#: prev
msgid  "Prev"
msgstr "Prev"

#: Section
msgid  "Section"
msgstr "Section"

#: Chapter
msgid  "Chapter"
msgstr "Chapter"

#: list-tableau
msgid  "List of Tableaux"
msgstr "List of Tableaux"

#: generated-on
msgid  " on "
msgstr " on "

#: float-tableau
msgid  "Tableau "
msgstr "Tableau "

#: Paragraph
msgid  "Paragraph"
msgstr "Paragraph"

#: list-figure
msgid  "List of Figures"
msgstr "List of Figures"

#: main-page
msgid  "Main page"
msgstr "Main page"

#: float-listing
msgid  "Listing "
msgstr "Listing "

#: on-page
msgid  " on page "
msgstr " on page "

#: nomenclature
msgid  "Nomenclature"
msgstr "Nomenclature"

#: float-table
msgid  "Table "
msgstr "Table "

#: float-figure
msgid  "Figure "
msgstr "Figure "

#: toc-for
msgid  "Contents for "
msgstr "Contents for "

#: jsmath-enable
msgid  "Please enable JavaScript on your browser."
msgstr "Please enable JavaScript on your browser."

#: footnotes
msgid  "Footnotes"
msgstr "Footnotes"

#: jsmath-requires
msgid  " requires JavaScript to correctly process the mathematics on this page. "
msgstr " requires JavaScript to correctly process the mathematics on this page. "
elyxer-1.2.5/src/conf/unimathsymbols.txt0000644000175000017500000064551612074107030017703 0ustar  chennochenno# Unicode characters and corresponding LaTeX math mode commands
# *************************************************************
#
# :Copyright: © 2011 Günter Milde
# :Date:      Last revised 2011-03-14
# :Licence:   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.
#
# .. _LaTeX Project Public License: http://www.latex-project.org/lppl.txt
#
# This is a mapping of mathematical Unicode characters to corresponding
# (La)TeX commands.
#
# While the contents of this file represent the best information
# available to the author as of the date referenced above, it
# contains omissions and maybe errors. It is likely that the
# information in this file will change from time to time.
#
# The character encoding of the file is UTF-8.
#
# Each data record consists of 8 fields. Fields are delimited by “^”.
# Spaces adjacent to the delimiter are not significant. The number and
# type of fields in this file may change in future versions.
#
# 1. code point (Unicode character number)
#
#    The code point field is unique.
#
# 2. literal character (UTF-8 encoded)
#
# 3. (La)TeX _`command`
#
#    Preferred representation of the character in TeX.
#    Alternative commands are listed in the comments_ field.
#
# 4. command used by the `unicode-math`_ package
#
#    .. _unicode-math:
#       http://mirror.ctan.org/help/Catalogue/entries/unicode-math.html
#
# 5. Unicode math character class (after MathClassEx_).
#
#    .. _MathClassEx:
#       http://www.unicode.org/Public/math/revision-11/MathClassEx-11.txt
#
#    The class can be one of:
#
#    :N: Normal- includes all digits and symbols requiring only one form
#    :A: Alphabetic
#    :B: Binary
#    :C: Closing – usually paired with opening delimiter
#    :D: Diacritic
#    :F: Fence - unpaired delimiter (often used as opening or closing)
#    :G: Glyph_Part- piece of large operator
#    :L: Large -n-ary or Large operator, often takes limits
#    :O: Opening – usually paired with closing delimiter
#    :P: Punctuation
#    :R: Relation- includes arrows
#    :S: Space
#    :U: Unary – operators that are only unary
#    :V: Vary – operators that can be unary or binary depending on context
#    :X: Special –characters not covered by other classes
#
#    C, O, and F operators are stretchy. In addition some binary
#    operators, such as 002F are stretchy as noted in the descriptive
#    comments. The classes are also useful in determining extra spacing
#    around the operators as discussed in UTR#25.
#
# 6. TeX math category (after unimath-symbols_)
#
#    .. _unimath-symbols:
#       http://mirror.ctan.org/macros/latex/contrib/unicode-math/unimath-symbols.pdf
#
# 7. requirements and conflicts
#
#    Space delimited list of LaTeX packages or features [1]_ providing
#    the LaTeX command_ or conflicting with it.
#
#    Packages/features preceded by a HYPHEN-MINUS (-) use the command
#    for a different symbol.
#
#    To save space, packages providing/modifying (almost) all commands
#    of a feature or another package are not listed here but in the
#    ``packages.txt`` file.
#
#    .. [1] A feature can be a set of commands common to several packages,
#    	    (e.g. ``mathbb`` or ``slantedGreek``) or a constraint (e.g.
#	    ``literal`` mapping plain characters to upright face).
#
# 8. descriptive _`comments`
#
#    The descriptive comments provide more information about the
#    character, or its specific appearance or use.
#
#    Some descriptions contain references to related commands,
#    marked by a character describing the relation
#
#    :=:  equals  (alias commands),
#    :#:  approx  (similar, different character with same glyph),
#    :x:  not     (false friends and name clashes),
#    :t:  text    (text mode command),
#
#    followed by requirements in parantheses, and
#    delimited by commas.
#
#    Comments in UPPERCASE are Unicode character names
#
# no.^chr^LaTeX^unicode-math^cls^category^requirements^comments
00021^!^!^\exclam^N^mathpunct^^EXCLAMATION MARK
00023^#^\#^\octothorpe^N^mathord^^NUMBER SIGN
00024^$^\$^\mathdollar^N^mathord^^= \mathdollar, DOLLAR SIGN
00025^%^\%^\percent^N^mathord^^PERCENT SIGN
00026^&^\&^\ampersand^N^mathord^^# \binampersand (stmaryrd)
00028^(^(^\lparen^O^mathopen^^LEFT PARENTHESIS
00029^)^)^\rparen^C^mathclose^^RIGHT PARENTHESIS
0002A^*^*^^N^mathord^^# \ast, (high) ASTERISK, star
0002B^+^+^\plus^V^mathbin^^PLUS SIGN
0002C^,^,^\comma^P^mathpunct^^COMMA
0002D^-^^^N^mathbin^^t -, HYPHEN-MINUS (deprecated for math)
0002E^.^.^\period^P^mathalpha^^FULL STOP, period
0002F^/^/^\mathslash^B^mathord^^# \slash, SOLIDUS
00030^0^0^^N^mathord^^DIGIT ZERO
00031^1^1^^N^mathord^^DIGIT ONE
00032^2^2^^N^mathord^^DIGIT TWO
00033^3^3^^N^mathord^^DIGIT THREE
00034^4^4^^N^mathord^^DIGIT FOUR
00035^5^5^^N^mathord^^DIGIT FIVE
00036^6^6^^N^mathord^^DIGIT SIX
00037^7^7^^N^mathord^^DIGIT SEVEN
00038^8^8^^N^mathord^^DIGIT EIGHT
00039^9^9^^N^mathord^^DIGIT NINE
0003A^:^:^\mathcolon^P^mathpunct^-literal^= \colon (literal), COLON (not ratio)
0003B^;^;^\semicolon^P^mathpunct^^SEMICOLON p:
0003C^<^<^\less^R^mathrel^^LESS-THAN SIGN r:
0003D^=^=^\equal^R^mathrel^^EQUALS SIGN r:
0003E^>^>^\greater^R^mathrel^^GREATER-THAN SIGN r:
0003F^?^?^\question^P^mathord^^QUESTION MARK
00040^@^@^\atsign^N^mathord^^at
00041^A^A^^A^mathalpha^-literal^= \mathrm{A}, LATIN CAPITAL LETTER A
00042^B^B^^A^mathalpha^-literal^= \mathrm{B}, LATIN CAPITAL LETTER B
00043^C^C^^A^mathalpha^-literal^= \mathrm{C}, LATIN CAPITAL LETTER C
00044^D^D^^A^mathalpha^-literal^= \mathrm{D}, LATIN CAPITAL LETTER D
00045^E^E^^A^mathalpha^-literal^= \mathrm{E}, LATIN CAPITAL LETTER E
00046^F^F^^A^mathalpha^-literal^= \mathrm{F}, LATIN CAPITAL LETTER F
00047^G^G^^A^mathalpha^-literal^= \mathrm{G}, LATIN CAPITAL LETTER G
00048^H^H^^A^mathalpha^-literal^= \mathrm{H}, LATIN CAPITAL LETTER H
00049^I^I^^A^mathalpha^-literal^= \mathrm{I}, LATIN CAPITAL LETTER I
0004A^J^J^^A^mathalpha^-literal^= \mathrm{J}, LATIN CAPITAL LETTER J
0004B^K^K^^A^mathalpha^-literal^= \mathrm{K}, LATIN CAPITAL LETTER K
0004C^L^L^^A^mathalpha^-literal^= \mathrm{L}, LATIN CAPITAL LETTER L
0004D^M^M^^A^mathalpha^-literal^= \mathrm{M}, LATIN CAPITAL LETTER M
0004E^N^N^^A^mathalpha^-literal^= \mathrm{N}, LATIN CAPITAL LETTER N
0004F^O^O^^A^mathalpha^-literal^= \mathrm{O}, LATIN CAPITAL LETTER O
00050^P^P^^A^mathalpha^-literal^= \mathrm{P}, LATIN CAPITAL LETTER P
00051^Q^Q^^A^mathalpha^-literal^= \mathrm{Q}, LATIN CAPITAL LETTER Q
00052^R^R^^A^mathalpha^-literal^= \mathrm{R}, LATIN CAPITAL LETTER R
00053^S^S^^A^mathalpha^-literal^= \mathrm{S}, LATIN CAPITAL LETTER S
00054^T^T^^A^mathalpha^-literal^= \mathrm{T}, LATIN CAPITAL LETTER T
00055^U^U^^A^mathalpha^-literal^= \mathrm{U}, LATIN CAPITAL LETTER U
00056^V^V^^A^mathalpha^-literal^= \mathrm{V}, LATIN CAPITAL LETTER V
00057^W^W^^A^mathalpha^-literal^= \mathrm{W}, LATIN CAPITAL LETTER W
00058^X^X^^A^mathalpha^-literal^= \mathrm{X}, LATIN CAPITAL LETTER X
00059^Y^Y^^A^mathalpha^-literal^= \mathrm{Y}, LATIN CAPITAL LETTER Y
0005A^Z^Z^^A^mathalpha^-literal^= \mathrm{Z}, LATIN CAPITAL LETTER Z
0005B^[^\lbrack^\lbrack^O^mathopen^^LEFT SQUARE BRACKET
0005C^\^\backslash^\backslash^B^mathord^^REVERSE SOLIDUS
0005D^]^\rbrack^\rbrack^C^mathclose^^RIGHT SQUARE BRACKET
0005E^^\sphat^^N^mathord^amsxtra^CIRCUMFLEX ACCENT, TeX superscript operator
0005F^_^\_^^N^mathord^^LOW LINE, TeX subscript operator
00060^`^^^D^mathord^^grave, alias for 0300
00061^a^a^^A^mathalpha^-literal^= \mathrm{a}, LATIN SMALL LETTER A
00062^b^b^^A^mathalpha^-literal^= \mathrm{b}, LATIN SMALL LETTER B
00063^c^c^^A^mathalpha^-literal^= \mathrm{c}, LATIN SMALL LETTER C
00064^d^d^^A^mathalpha^-literal^= \mathrm{d}, LATIN SMALL LETTER D
00065^e^e^^A^mathalpha^-literal^= \mathrm{e}, LATIN SMALL LETTER E
00066^f^f^^A^mathalpha^-literal^= \mathrm{f}, LATIN SMALL LETTER F
00067^g^g^^A^mathalpha^-literal^= \mathrm{g}, LATIN SMALL LETTER G
00068^h^h^^A^mathalpha^-literal^= \mathrm{h}, LATIN SMALL LETTER H
00069^i^i^^A^mathalpha^-literal^= \mathrm{i}, LATIN SMALL LETTER I
0006A^j^j^^A^mathalpha^-literal^= \mathrm{j}, LATIN SMALL LETTER J
0006B^k^k^^A^mathalpha^-literal^= \mathrm{k}, LATIN SMALL LETTER K
0006C^l^l^^A^mathalpha^-literal^= \mathrm{l}, LATIN SMALL LETTER L
0006D^m^m^^A^mathalpha^-literal^= \mathrm{m}, LATIN SMALL LETTER M
0006E^n^n^^A^mathalpha^-literal^= \mathrm{n}, LATIN SMALL LETTER N
0006F^o^o^^A^mathalpha^-literal^= \mathrm{o}, LATIN SMALL LETTER O
00070^p^p^^A^mathalpha^-literal^= \mathrm{p}, LATIN SMALL LETTER P
00071^q^q^^A^mathalpha^-literal^= \mathrm{q}, LATIN SMALL LETTER Q
00072^r^r^^A^mathalpha^-literal^= \mathrm{r}, LATIN SMALL LETTER R
00073^s^s^^A^mathalpha^-literal^= \mathrm{s}, LATIN SMALL LETTER S
00074^t^t^^A^mathalpha^-literal^= \mathrm{t}, LATIN SMALL LETTER T
00075^u^u^^A^mathalpha^-literal^= \mathrm{u}, LATIN SMALL LETTER U
00076^v^v^^A^mathalpha^-literal^= \mathrm{v}, LATIN SMALL LETTER V
00077^w^w^^A^mathalpha^-literal^= \mathrm{w}, LATIN SMALL LETTER W
00078^x^x^^A^mathalpha^-literal^= \mathrm{x}, LATIN SMALL LETTER X
00079^y^y^^A^mathalpha^-literal^= \mathrm{y}, LATIN SMALL LETTER Y
0007A^z^z^^A^mathalpha^-literal^= \mathrm{z}, LATIN SMALL LETTER Z
0007B^{^\{^\lbrace^O^mathopen^^= \lbrace, LEFT CURLY BRACKET
0007C^|^|^\vert^F^mathfence^^= \vert, vertical bar
0007D^}^\}^\rbrace^C^mathclose^^= \rbrace, RIGHT CURLY BRACKET
0007E^~^\sptilde^^N^mathord^amsxtra^# \sim, TILDE
000A0^ ^~^^S^^^nbsp
000A1^¡^^^P^^^iexcl
000A2^¢^\cent^^N^mathord^wasysym^= \mathcent (txfonts), cent
000A3^£^\pounds^\sterling^N^mathord^-fourier -omlmathit^= \mathsterling (txfonts), POUND SIGN, fourier prints a dollar sign
000A4^¤^^^N^mathord^^t \currency (wasysym), curren
000A5^¥^\yen^\yen^N^mathord^amsfonts^YEN SIGN
000A6^¦^^^N^mathord^^brvbar (vertical)
000A7^§^^^N^mathord^^sect
000A8^¨^\spddot^^D^mathord^amsxtra^Dot /die, alias for 0308
000AC^¬^\neg^\neg^U^mathord^^= \lnot, NOT SIGN
000AE^®^\circledR^^X^mathord^amsfonts^REGISTERED SIGN
000AF^¯^^^D^mathord^^macr, alias for 0304
000B0^°^^^N^mathord^^deg
000B1^±^\pm^\pm^V^mathbin^^plus-or-minus sign
000B2^²^^^N^mathord^^sup2
000B3^³^^^N^mathord^^sup3
000B4^´^^^N^mathord^^acute, alias for 0301
000B5^µ^\Micro^^N^mathalpha^wrisym^= \tcmu (mathcomp), t \textmu (textcomp), # \mathrm{\mu} (omlmathrm), # \muup (kpfonts mathdesign), MICRO SIGN
000B6^¶^^^N^mathord^^para (paragraph sign, pilcrow)
000B7^·^^\cdotp^B^mathbin^^# \cdot, x \centerdot, b: MIDDLE DOT
000B9^¹^^^N^mathord^^sup1
000BC^¼^^^N^mathord^^frac14
000BD^½^^^N^mathord^^frac12
000BE^¾^^^N^mathord^^frac34
000BF^¿^^^P^^^iquest
000D7^×^\times^\times^B^mathbin^^MULTIPLICATION SIGN, z notation Cartesian product
000F0^ð^\eth^\matheth^^mathalpha^amssymb arevmath^eth
000F7^÷^\div^\div^B^mathbin^^divide sign
00131^ı^\imath^^A^mathalpha^-literal^imath
001B5^Ƶ^^\Zbar^^mathord^^impedance
00237^ȷ^\jmath^^A^mathalpha^-literal^jmath
002C6^ˆ^^^D^mathalpha^^circ, alias for 0302
002C7^ˇ^^^D^mathalpha^^CARON, alias for 030C
002D8^˘^^^D^mathord^^BREVE, alias for 0306
002D9^˙^^^D^mathord^^dot, alias for 0307
002DA^˚^^^D^mathord^^ring, alias for 030A
002DC^˜^^^D^mathord^^tilde, alias for 0303
00300^x̀^\grave^\grave^D^mathaccent^^grave accent
00301^x́^\acute^\acute^D^mathaccent^^acute accent
00302^x̂^\hat^\hat^D^mathaccent^^# \widehat (amssymb), circumflex accent
00303^x̃^\tilde^\tilde^D^mathaccent^^# \widetilde (yhmath, fourier), tilde
00304^x̄^\bar^\bar^D^mathaccent^^macron
00305^x̅^\overline^\overbar^D^mathaccent^^overbar embellishment
00306^x̆^\breve^\breve^D^mathaccent^^breve
00307^ẋ^\dot^\dot^D^mathaccent^-oz^= \Dot (wrisym), dot above
00308^ẍ^\ddot^\ddot^D^mathaccent^^= \DDot (wrisym), dieresis
00309^x̉^^\ovhook^^mathaccent^^COMBINING HOOK ABOVE
0030A^x̊^\mathring^\ocirc^D^mathaccent^amssymb^= \ring (yhmath), ring
0030C^x̌^\check^\check^D^mathaccent^^caron
00310^x̐^^\candra^^mathaccent^^candrabindu (non-spacing)
00311^x̑^^^D^mathaccent^^COMBINING INVERTED BREVE
00312^x̒^^\oturnedcomma^^mathaccent^^COMBINING TURNED COMMA ABOVE
00315^x̕^^\ocommatopright^^mathaccent^^COMBINING COMMA ABOVE RIGHT
0031A^x̚^^\droang^^mathaccent^^left angle above (non-spacing)
00323^x̣^^^D^mathaccent^^COMBINING DOT BELOW
0032C^x̬^^^D^mathaccent^^COMBINING CARON BELOW
0032D^x̭^^^D^mathaccent^^COMBINING CIRCUMFLEX ACCENT BELOW
0032E^x̮^^^D^mathaccent^^COMBINING BREVE BELOW
0032F^x̯^^^D^mathaccent^^COMBINING INVERTED BREVE BELOW
00330^x̰^\utilde^\wideutilde^D^mathaccent^undertilde^under tilde accent (multiple characters and non-spacing)
00331^x̱^\underbar^\underbar^D^mathaccent^^COMBINING MACRON BELOW
00332^x̲^\underline^^D^mathaccent^^COMBINING LOW LINE
00333^x̳^^^D^mathaccent^^2lowbar
00338^x̸^\not^\not^D^mathaccent^^COMBINING LONG SOLIDUS OVERLAY
0033A^x̺^^^D^mathaccent^^COMBINING INVERTED BRIDGE BELOW
0033F^x̿^^^D^mathaccent^^COMBINING DOUBLE OVERLINE
00346^x͆^^^D^mathaccent^^COMBINING BRIDGE ABOVE
00391^Α^^\upAlpha^A^mathalpha^^capital alpha, greek
00392^Β^^\upBeta^A^mathalpha^^capital beta, greek
00393^Γ^\Gamma^\upGamma^A^mathalpha^-literal^= \Gamma (-slantedGreek), = \mathrm{\Gamma}, capital gamma, greek
00394^Δ^\Delta^\upDelta^A^mathalpha^-literal^= \Delta (-slantedGreek), = \mathrm{\Delta}, capital delta, greek
00395^Ε^^\upEpsilon^A^mathalpha^^capital epsilon, greek
00396^Ζ^^\upZeta^A^mathalpha^^capital zeta, greek
00397^Η^^\upEta^A^mathalpha^^capital eta, greek
00398^Θ^\Theta^\upTheta^A^mathalpha^-literal^= \Theta (-slantedGreek), = \mathrm{\Theta}, capital theta, greek
00399^Ι^^\upIota^A^mathalpha^^capital iota, greek
0039A^Κ^^\upKappa^A^mathalpha^^capital kappa, greek
0039B^Λ^\Lambda^\upLambda^A^mathalpha^-literal^= \Lambda (-slantedGreek), = \mathrm{\Lambda}, capital lambda, greek
0039C^Μ^^\upMu^A^mathalpha^^capital mu, greek
0039D^Ν^^\upNu^A^mathalpha^^capital nu, greek
0039E^Ξ^\Xi^\upXi^A^mathalpha^-literal^= \Xi (-slantedGreek), = \mathrm{\Xi}, capital xi, greek
0039F^Ο^^\upOmicron^A^mathalpha^^capital omicron, greek
003A0^Π^\Pi^\upPi^A^mathalpha^-literal^= \Pi (-slantedGreek), = \mathrm{\Pi}, capital pi, greek
003A1^Ρ^^\upRho^A^mathalpha^^capital rho, greek
003A3^Σ^\Sigma^\upSigma^A^mathalpha^-literal^= \Sigma (-slantedGreek), = \mathrm{\Sigma}, capital sigma, greek
003A4^Τ^^\upTau^A^mathalpha^^capital tau, greek
003A5^Υ^\Upsilon^\upUpsilon^A^mathalpha^-literal^= \Upsilon (-slantedGreek), = \mathrm{\Upsilon}, capital upsilon, greek
003A6^Φ^\Phi^\upPhi^A^mathalpha^-literal^= \Phi (-slantedGreek), = \mathrm{\Phi}, capital phi, greek
003A7^Χ^^\upChi^A^mathalpha^^capital chi, greek
003A8^Ψ^\Psi^\upPsi^A^mathalpha^-literal^= \Psi (-slantedGreek), = \mathrm{\Psi}, capital psi, greek
003A9^Ω^\Omega^\upOmega^A^mathalpha^-literal^= \Omega (-slantedGreek), = \mathrm{\Omega}, capital omega, greek
003B1^α^\alpha^\upalpha^A^mathalpha^-literal^= \mathrm{\alpha} (omlmathrm), = \alphaup (kpfonts mathdesign), = \upalpha (upgreek), alpha, greek
003B2^β^\beta^\upbeta^A^mathalpha^-literal^= \mathrm{\beta} (omlmathrm), = \betaup (kpfonts mathdesign), = \upbeta (upgreek), beta, greek
003B3^γ^\gamma^\upgamma^A^mathalpha^-literal^= \mathrm{\gamma} (omlmathrm), = \gammaup (kpfonts mathdesign), = \upgamma (upgreek), gamma, greek
003B4^δ^\delta^\updelta^A^mathalpha^-literal^= \mathrm{\delta} (omlmathrm), = \deltaup (kpfonts mathdesign), = \updelta (upgreek), delta, greek
003B5^ε^\varepsilon^\upepsilon^A^mathalpha^-literal^= \mathrm{\varepsilon} (omlmathrm), = \varepsilonup (kpfonts mathdesign), = \upepsilon (upgreek), rounded epsilon, greek
003B6^ζ^\zeta^\upzeta^A^mathalpha^-literal^= \mathrm{\zeta} (omlmathrm), = \zetaup (kpfonts mathdesign), = \upzeta (upgreek), zeta, greek
003B7^η^\eta^\upeta^A^mathalpha^-literal^= \mathrm{\eta} (omlmathrm), = \etaup (kpfonts mathdesign), = \upeta (upgreek), eta, greek
003B8^θ^\theta^\uptheta^A^mathalpha^-literal^= \mathrm{\theta} (omlmathrm), = \thetaup (kpfonts mathdesign), straight theta, = \uptheta (upgreek), theta, greek
003B9^ι^\iota^\upiota^A^mathalpha^-literal^= \mathrm{\iota} (omlmathrm), = \iotaup (kpfonts mathdesign), = \upiota (upgreek), iota, greek
003BA^κ^\kappa^\upkappa^A^mathalpha^-literal^= \mathrm{\kappa} (omlmathrm), = \kappaup (kpfonts mathdesign), = \upkappa (upgreek), kappa, greek
003BB^λ^\lambda^\uplambda^A^mathalpha^-literal^= \mathrm{\lambda} (omlmathrm), = \lambdaup (kpfonts mathdesign), = \uplambda (upgreek), lambda, greek
003BC^μ^\mu^\upmu^A^mathalpha^-literal^= \mathrm{\mu} (omlmathrm), = \muup (kpfonts mathdesign), = \upmu (upgreek), mu, greek
003BD^ν^\nu^\upnu^A^mathalpha^-literal^= \mathrm{\nu} (omlmathrm), = \nuup (kpfonts mathdesign), = \upnu (upgreek), nu, greek
003BE^ξ^\xi^\upxi^A^mathalpha^-literal^= \mathrm{\xi} (omlmathrm), = \xiup (kpfonts mathdesign), = \upxi (upgreek), xi, greek
003BF^ο^^\upomicron^A^mathalpha^^small omicron, greek
003C0^π^\pi^\uppi^A^mathalpha^-literal^= \mathrm{\pi} (omlmathrm), = \piup (kpfonts mathdesign), = \uppi (upgreek), pi, greek
003C1^ρ^\rho^\uprho^A^mathalpha^-literal^= \mathrm{\rho} (omlmathrm), = \rhoup (kpfonts mathdesign), = \uprho (upgreek), rho, greek
003C2^ς^\varsigma^\upvarsigma^^mathalpha^-literal^= \mathrm{\varsigma} (omlmathrm), = \varsigmaup (kpfonts mathdesign), = \upvarsigma (upgreek), terminal sigma, greek
003C3^σ^\sigma^\upsigma^A^mathalpha^-literal^= \mathrm{\sigma} (omlmathrm), = \sigmaup (kpfonts mathdesign), = \upsigma (upgreek), sigma, greek
003C4^τ^\tau^\uptau^A^mathalpha^-literal^= \mathrm{\tau} (omlmathrm), = \tauup (kpfonts mathdesign), = \uptau (upgreek), tau, greek
003C5^υ^\upsilon^\upupsilon^A^mathalpha^-literal^= \mathrm{\upsilon} (omlmathrm), = \upsilonup (kpfonts mathdesign), = \upupsilon (upgreek), upsilon, greek
003C6^φ^\varphi^\upvarphi^A^mathalpha^-literal^= \mathrm{\varphi} (omlmathrm), = \varphiup (kpfonts mathdesign), = \upvarphi (upgreek), curly or open phi, greek
003C7^χ^\chi^\upchi^A^mathalpha^-literal^= \mathrm{\chi} (omlmathrm), = \chiup (kpfonts mathdesign), = \upchi (upgreek), chi, greek
003C8^ψ^\psi^\uppsi^A^mathalpha^-literal^= \mathrm{\psi} (omlmathrm), = \psiup (kpfonts mathdesign), = \uppsi (upgreek), psi, greek
003C9^ω^\omega^\upomega^A^mathalpha^-literal^= \mathrm{\omega} (omlmathrm), = \omegaup (kpfonts mathdesign), = \upomega (upgreek), omega, greek
003D0^ϐ^\varbeta^\upvarbeta^A^mathalpha^arevmath^rounded beta, greek
003D1^ϑ^\vartheta^\upvartheta^A^mathalpha^-literal^= \mathrm{\vartheta} (omlmathrm), = \varthetaup (kpfonts mathdesign), curly or open theta
003D2^ϒ^^\upUpsilon^A^mathalpha^^# \mathrm{\Upsilon}, GREEK UPSILON WITH HOOK SYMBOL
003D5^ϕ^\phi^\upphi^A^mathalpha^-literal^= \mathrm{\phi} (omlmathrm), = \phiup (kpfonts mathdesign), GREEK PHI SYMBOL (straight)
003D6^ϖ^\varpi^\upvarpi^A^mathalpha^-literal^= \mathrm{\varpi} (omlmathrm), = \varpiup (kpfonts mathdesign), GREEK PI SYMBOL (pomega)
003D8^Ϙ^\Qoppa^\upoldKoppa^N^mathord^arevmath^= \Koppa (wrisym), t \Qoppa (LGR), GREEK LETTER ARCHAIC KOPPA
003D9^ϙ^\qoppa^\upoldkoppa^N^mathord^arevmath^= \koppa (wrisym), t \qoppa (LGR), GREEK SMALL LETTER ARCHAIC KOPPA
003DA^Ϛ^\Stigma^\upStigma^A^mathalpha^arevmath wrisym^capital stigma
003DB^ϛ^\stigma^\upstigma^A^mathalpha^arevmath wrisym^GREEK SMALL LETTER STIGMA
003DC^Ϝ^\digamma^\upDigamma^A^mathalpha^amssymb -wrisym^= \Digamma (wrisym), capital digamma
003DD^ϝ^\digamma^\updigamma^A^mathalpha^arevmath wrisym -amssymb^GREEK SMALL LETTER DIGAMMA
003DE^Ϟ^\Koppa^\upKoppa^^mathalpha^arevmath^capital koppa
003DF^ϟ^\koppa^\upkoppa^^mathalpha^arevmath^GREEK SMALL LETTER KOPPA
003E0^Ϡ^\Sampi^\upSampi^A^mathalpha^arevmath wrisym^capital sampi
003E1^ϡ^\sampi^\upsampi^A^mathalpha^arevmath^# \sampi (wrisym), GREEK SMALL LETTER SAMPI
003F0^ϰ^^\upvarkappa^A^mathalpha^^GREEK KAPPA SYMBOL (round)
003F1^ϱ^\varrho^\upvarrho^A^mathalpha^omlmathrm -literal^= \mathrm{\varrho} (omlmathrm), = \varrhoup (kpfonts mathdesign), GREEK RHO SYMBOL (round)
003F4^ϴ^^\upvarTheta^A^mathalpha^^x \varTheta (amssymb), GREEK CAPITAL THETA SYMBOL
003F5^ϵ^\epsilon^\upvarepsilon^A^mathalpha^omlmathrm -literal^= \mathrm{\epsilon} (omlmathrm), = \epsilonup (kpfonts mathdesign), GREEK LUNATE EPSILON SYMBOL
003F6^϶^\backepsilon^\upbackepsilon^N^mathord^amssymb wrisym^GREEK REVERSED LUNATE EPSILON SYMBOL
00428^Ш^^^A^mathalpha^^t \CYRSHHA (T2A), Shcy, CYRILLIC CAPITAL LETTER SHA
02000^ ^^^S^^^enquad
02001^ ^\quad^^S^^^emquad
02002^ ^^^S^^^ensp (half an em)
02003^ ^^^S^^^emsp
02004^ ^^^S^^^THREE-PER-EM SPACE
02005^ ^^^S^^^FOUR-PER-EM SPACE, mid space
02006^ ^^^S^^^SIX-PER-EM SPACE
02007^ ^^^S^^^FIGURE SPACE
02009^ ^^^S^^^THIN SPACE
0200A^ ^^^S^^^HAIR SPACE
0200B^​^^^S^^^# \hspace{0pt}, zwsp
02010^‐^^^P^mathord^^HYPHEN (true graphic)
02012^‒^^^P^mathord^^dash
02013^–^^^P^mathord^^ndash
02014^—^^^P^mathord^^mdash
02015^―^^\horizbar^^mathord^^HORIZONTAL BAR
02016^‖^\|^\Vert^F^mathfence^^= \Vert, double vertical bar
02017^‗^^\twolowline^^mathord^^DOUBLE LOW LINE (spacing)
02020^†^\dagger^\dagger^N^mathbin^^DAGGER relation
02021^‡^\ddagger^\ddagger^N^mathbin^^DOUBLE DAGGER relation
02022^•^^\smblkcircle^B^mathbin^^# \bullet, b: round BULLET, filled
02025^‥^^\enleadertwodots^^mathord^^double baseline dot (en leader)
02026^…^\ldots^\unicodeellipsis^N^mathord^^ellipsis (horizontal)
02032^′^\prime^\prime^N^mathord^^PRIME or minute, not superscripted
02033^″^\second^\dprime^N^mathord^mathabx^DOUBLE PRIME or second, not superscripted
02034^‴^\third^\trprime^N^mathord^mathabx^TRIPLE PRIME (not superscripted)
02035^‵^\backprime^\backprime^N^mathord^amssymb^reverse prime, not superscripted
02036^‶^^\backdprime^N^mathord^^double reverse prime, not superscripted
02037^‷^^\backtrprime^N^mathord^^triple reverse prime, not superscripted
02038^‸^^\caretinsert^^mathord^^CARET (insertion mark)
0203B^※^^^N^^^REFERENCE MARK, Japanese kome jirushi
0203C^‼^^\Exclam^N^mathord^^# !!, DOUBLE EXCLAMATION MARK
02040^⁀^\cat^\tieconcat^B^mathbin^oz^CHARACTER TIE, z notation sequence concatenation
02043^⁃^^\hyphenbullet^^mathord^^rectangle, filled (HYPHEN BULLET)
02044^⁄^^\fracslash^B^mathbin^^# /, FRACTION SLASH
02047^⁇^^\Question^^mathord^^# ??, DOUBLE QUESTION MARK
0204E^⁎^^^B^mathbin^^# \ast, lowast, LOW ASTERISK
0204F^⁏^^^R^^^bsemi, REVERSED SEMICOLON
02050^⁐^^\closure^R^mathrel^^CLOSE UP (editing mark)
02051^⁑^^^N^^^Ast
02052^⁒^^^N^mathord^^# ./., COMMERCIAL MINUS SIGN
02057^⁗^\fourth^\qprime^N^mathord^mathabx^QUADRUPLE PRIME, not superscripted
0205F^ ^\:^^S^^^= \medspace (amsmath), MEDIUM MATHEMATICAL SPACE, four-eighteenths of an em
02061^⁡^^^B^^^FUNCTION APPLICATION
02062^⁢^^^B^^^INVISIBLE TIMES
02063^⁣^^^P^^^INVISIBLE SEPARATOR
02064^⁤^^^X^^^INVISIBLE PLUS
0207A^⁺^^^N^mathord^^SUPERSCRIPT PLUS SIGN subscript operators
0207B^⁻^^^N^mathord^^SUPERSCRIPT MINUS subscript operators
0207C^⁼^^^N^mathord^^SUPERSCRIPT EQUALS SIGN subscript operators
0207D^⁽^^^N^mathopen^^SUPERSCRIPT LEFT PARENTHESIS subscript operators
0207E^⁾^^^N^mathclose^^SUPERSCRIPT RIGHT PARENTHESIS subscript operators
0208A^₊^^^N^mathord^^SUBSCRIPT PLUS SIGN superscript operators
0208B^₋^^^N^mathord^^SUBSCRIPT MINUS superscript operators
0208C^₌^^^N^mathord^^SUBSCRIPT EQUALS SIGN superscript operators
0208D^₍^^^N^mathopen^^SUBSCRIPT LEFT PARENTHESIS superscript operators
0208E^₎^^^N^mathclose^^SUBSCRIPT RIGHT PARENTHESIS superscript operators
020AC^€^^\euro^^mathord^^EURO SIGN
020D0^x⃐^\lvec^\leftharpoonaccent^D^mathaccent^wrisym^COMBINING LEFT HARPOON ABOVE
020D1^x⃑^\vec^\rightharpoonaccent^D^mathaccent^wrisym^COMBINING RIGHT HARPOON ABOVE
020D2^x⃒^^\vertoverlay^D^mathaccent^^COMBINING LONG VERTICAL LINE OVERLAY
020D3^x⃓^^^X^mathaccent^^COMBINING SHORT VERTICAL LINE OVERLAY
020D4^x⃔^^^D^mathaccent^^COMBINING ANTICLOCKWISE ARROW ABOVE
020D6^x⃖^\LVec^\overleftarrow^D^mathaccent^wrisym^# \overleftarrow, COMBINING LEFT ARROW ABOVE
020D7^x⃗^\vec^\vec^D^mathaccent^-wrisym^= \Vec (wrisym), # \overrightarrow, COMBINING RIGHT ARROW ABOVE
020D8^x⃘^^^D^mathaccent^^COMBINING RING OVERLAY
020D9^x⃙^^^D^mathaccent^^COMBINING CLOCKWISE RING OVERLAY
020DA^x⃚^^^D^mathaccent^^COMBINING ANTICLOCKWISE RING OVERLAY
020DB^x⃛^\dddot^\dddot^D^mathaccent^amsmath^= \DDDot (wrisym), COMBINING THREE DOTS ABOVE
020DC^x⃜^\ddddot^\ddddot^D^mathaccent^amsmath^COMBINING FOUR DOTS ABOVE
020DD^x⃝^^\enclosecircle^D^mathaccent^^COMBINING ENCLOSING CIRCLE
020DE^x⃞^^\enclosesquare^D^mathaccent^^COMBINING ENCLOSING SQUARE
020DF^x⃟^^\enclosediamond^D^mathaccent^^COMBINING ENCLOSING DIAMOND
020E1^x⃡^\overleftrightarrow^\overleftrightarrow^D^mathaccent^amsmath^COMBINING LEFT RIGHT ARROW ABOVE
020E4^x⃤^^\enclosetriangle^D^mathaccent^^COMBINING ENCLOSING UPWARD POINTING TRIANGLE
020E5^x⃥^^^D^mathaccent^^COMBINING REVERSE SOLIDUS OVERLAY
020E6^x⃦^^^D^mathaccent^^COMBINING DOUBLE VERTICAL STROKE OVERLAY, z notation finite function diacritic
020E7^x⃧^^\annuity^D^mathaccent^^COMBINING ANNUITY SYMBOL
020E8^x⃨^^\threeunderdot^D^mathaccent^^COMBINING TRIPLE UNDERDOT
020E9^x⃩^^\widebridgeabove^D^mathaccent^^COMBINING WIDE BRIDGE ABOVE
020EA^x⃪^^^D^mathaccent^^COMBINING LEFTWARDS ARROW OVERLAY
020EB^x⃫^^^D^mathaccent^^COMBINING LONG DOUBLE SOLIDUS OVERLAY
020EC^x⃬^^\underrightharpoondown^D^mathaccent^^COMBINING RIGHTWARDS HARPOON WITH BARB DOWNWARDS
020ED^x⃭^^\underleftharpoondown^D^mathaccent^^COMBINING LEFTWARDS HARPOON WITH BARB DOWNWARDS
020EE^x⃮^\underleftarrow^\underleftarrow^D^mathaccent^amsmath^COMBINING LEFT ARROW BELOW
020EF^x⃯^\underrightarrow^\underrightarrow^D^mathaccent^amsmath^COMBINING RIGHT ARROW BELOW
020F0^x⃰^^\asteraccent^^mathaccent^^COMBINING ASTERISK ABOVE
02102^ℂ^\mathbb{C}^\BbbC^A^mathalpha^mathbb^= \mathds{C} (dsfont), open face C
02107^ℇ^\Euler^\Eulerconst^N^mathord^wrisym^EULER CONSTANT
0210A^ℊ^\mathcal{g}^\mscrg^A^mathalpha^urwchancal^/scr g, script small letter g
0210B^ℋ^\mathcal{H}^\mscrH^A^mathalpha^^hamiltonian (script capital H)
0210C^ℌ^\mathfrak{H}^\mfrakH^A^mathalpha^eufrak^/frak H, black-letter capital H
0210D^ℍ^\mathbb{H}^\BbbH^A^mathalpha^mathbb^= \mathds{H} (dsfont), open face capital H
0210E^ℎ^^\Planckconst^N^mathord^^# h, Planck constant
0210F^ℏ^\hslash^\hslash^N^mathalpha^amssymb fourier arevmath^=\HBar (wrisym), Planck's h over 2pi
02110^ℐ^\mathcal{I}^\mscrI^A^mathalpha^^/scr I, script capital I
02111^ℑ^\Im^\Im^A^mathalpha^^= \mathfrak{I} (eufrak), imaginary part
02112^ℒ^\mathcal{L}^\mscrL^A^mathalpha^^lagrangian (script capital L)
02113^ℓ^\ell^\ell^A^mathalpha^^cursive small l
02115^ℕ^\mathbb{N}^\BbbN^A^mathalpha^mathbb^= \mathds{N} (dsfont), open face N
02118^℘^\wp^\wp^A^mathalpha^amssymb^weierstrass p
02119^ℙ^\mathbb{P}^\BbbP^A^mathalpha^mathbb^= \mathds{P} (dsfont), open face P
0211A^ℚ^\mathbb{Q}^\BbbQ^A^mathalpha^mathbb^= \mathds{Q} (dsfont), open face Q
0211B^ℛ^\mathcal{R}^\mscrR^A^mathalpha^^/scr R, script capital R
0211C^ℜ^\Re^\Re^A^mathalpha^^= \mathfrak{R} (eufrak), real part
0211D^ℝ^\mathbb{R}^\BbbR^A^mathalpha^mathbb^= \mathds{R} (dsfont), open face R
02124^ℤ^\mathbb{Z}^\BbbZ^A^mathalpha^mathbb^= \mathds{Z} (dsfont), open face Z
02126^Ω^\tcohm^^N^mathalpha^mathcomp^# \mathrm{\Omega}, ohm (deprecated in math, use greek letter)
02127^℧^\mho^\mho^N^mathord^amsfonts arevmath^= \Mho (wrisym), t \agemO (wasysym), conductance
02128^ℨ^\mathfrak{Z}^\mfrakZ^A^mathalpha^eufrak^/frak Z, black-letter capital Z
02129^℩^^\turnediota^N^mathalpha^^turned iota
0212B^Å^\Angstroem^\Angstrom^A^mathalpha^wrisym^# \mathring{\mathrm{A}}, Ångström capital A with ring
0212C^ℬ^\mathcal{B}^\mscrB^A^mathalpha^^bernoulli function (script capital B)
0212D^ℭ^\mathfrak{C}^\mfrakC^A^mathalpha^eufrak^black-letter capital C
0212F^ℯ^\mathcal{e}^\mscre^A^mathalpha^urwchancal^/scr e, script small letter e
02130^ℰ^\mathcal{E}^\mscrE^A^mathalpha^^/scr E, script capital E
02131^ℱ^\mathcal{F}^\mscrF^A^mathalpha^^/scr F, script capital F
02132^Ⅎ^\Finv^\Finv^N^mathord^amssymb^TURNED CAPITAL F
02133^ℳ^\mathcal{M}^\mscrM^A^mathalpha^^physics m-matrix (SCRIPT CAPITAL M)
02134^ℴ^\mathcal{o}^\mscro^A^mathalpha^urwchancal^order of (SCRIPT SMALL O)
02135^ℵ^\aleph^\aleph^A^mathalpha^^aleph, hebrew
02136^ℶ^\beth^\beth^A^mathalpha^amssymb wrisym^beth, hebrew
02137^ℷ^\gimel^\gimel^A^mathalpha^amssymb wrisym^gimel, hebrew
02138^ℸ^\daleth^\daleth^A^mathalpha^amssymb wrisym^daleth, hebrew
0213C^ℼ^\mathbb{\pi}^\Bbbpi^A^mathord^bbold^\DoublePi (wrisym), DOUBLE-STRUCK SMALL PI
0213D^ℽ^\mathbb{\gamma}^\Bbbgamma^A^mathalpha^bbold^\EulerGamma (wrisym), DOUBLE-STRUCK SMALL GAMMA
0213E^ℾ^\mathbb{\Gamma}^\BbbGamma^N^mathalpha^bbold^DOUBLE-STRUCK CAPITAL GAMMA
0213F^ℿ^\mathbb{\Pi}^\BbbPi^A^mathalpha^bbold^DOUBLE-STRUCK CAPITAL PI
02140^⅀^\mathbb{\Sigma}^\Bbbsum^L^mathop^bbold^DOUBLE-STRUCK N-ARY SUMMATION
02141^⅁^^\Game^N^mathord^^# \Game (amssymb), TURNED SANS-SERIF CAPITAL G (amssymb has mirrored G)
02142^⅂^^\sansLturned^N^mathord^^TURNED SANS-SERIF CAPITAL L
02143^⅃^^\sansLmirrored^N^mathord^^REVERSED SANS-SERIF CAPITAL L
02144^⅄^\Yup^\Yup^N^mathord^stmaryrd^TURNED SANS-SERIF CAPITAL Y
02145^ⅅ^\CapitalDifferentialD^\mitBbbD^N^mathord^wrisym^= \DD (wrisym), DOUBLE-STRUCK ITALIC CAPITAL D
02146^ⅆ^\DifferentialD^\mitBbbd^N^mathord^wrisym^= \dd (wrisym), DOUBLE-STRUCK ITALIC SMALL D
02147^ⅇ^\ExponetialE^\mitBbbe^N^mathord^wrisym^= \ee (wrisym), DOUBLE-STRUCK ITALIC SMALL E
02148^ⅈ^\ComplexI^\mitBbbi^N^mathord^wrisym^= \ii (wrisym), DOUBLE-STRUCK ITALIC SMALL I
02149^ⅉ^\ComplexJ^\mitBbbj^N^mathord^wrisym^= \jj (wrisym), DOUBLE-STRUCK ITALIC SMALL J
0214A^⅊^^\PropertyLine^^mathord^^PROPERTY LINE
0214B^⅋^\invamp^\upand^N^mathbin^txfonts^# \bindnasrepma (stmaryrd), TURNED AMPERSAND
02190^←^\leftarrow^\leftarrow^R^mathrel^^= \gets, a: leftward arrow
02191^↑^\uparrow^\uparrow^R^mathrel^^upward arrow
02192^→^\rightarrow^\rightarrow^R^mathrel^^= \to, = \tfun (oz), = \fun (oz), rightward arrow, z notation total function
02193^↓^\downarrow^\downarrow^R^mathrel^^downward arrow
02194^↔^\leftrightarrow^\leftrightarrow^R^mathrel^-wrisym^= \rel (oz), LEFT RIGHT ARROW, z notation relation
02195^↕^\updownarrow^\updownarrow^R^mathrel^^up and down arrow
02196^↖^\nwarrow^\nwarrow^R^mathrel^amssymb^nw pointing arrow
02197^↗^\nearrow^\nearrow^R^mathrel^^ne pointing arrow
02198^↘^\searrow^\searrow^R^mathrel^^se pointing arrow
02199^↙^\swarrow^\swarrow^R^mathrel^^sw pointing arrow
0219A^↚^\nleftarrow^\nleftarrow^R^mathrel^amssymb^not left arrow
0219B^↛^\nrightarrow^\nrightarrow^R^mathrel^amssymb^not right arrow
0219C^↜^^\leftwavearrow^R^mathrel^^left arrow-wavy
0219D^↝^^\rightwavearrow^R^mathrel^^right arrow-wavy
0219E^↞^\twoheadleftarrow^\twoheadleftarrow^R^mathrel^amssymb^left two-headed arrow
0219F^↟^^\twoheaduparrow^R^mathrel^^up two-headed arrow
021A0^↠^\twoheadrightarrow^\twoheadrightarrow^R^mathrel^amssymb^= \tsur (oz), = \surj (oz), right two-headed arrow, z notation total surjection
021A1^↡^^\twoheaddownarrow^R^mathrel^^down two-headed arrow
021A2^↢^\leftarrowtail^\leftarrowtail^R^mathrel^amssymb^left arrow-tailed
021A3^↣^\rightarrowtail^\rightarrowtail^R^mathrel^amssymb^= \tinj (oz), = \inj (oz), right arrow-tailed, z notation total injection
021A4^↤^\mapsfrom^\mapsfrom^R^mathrel^stmaryrd^= \mappedfrom (kpfonts), maps to, leftward
021A5^↥^\MapsUp^\mapsup^R^mathrel^wrisym^maps to, upward
021A6^↦^\mapsto^\mapsto^R^mathrel^^maps to, rightward, z notation maplet
021A7^↧^\MapsDown^\mapsdown^R^mathrel^wrisym^maps to, downward
021A8^↨^^\updownarrowbar^R^mathord^^UP DOWN ARROW WITH BASE (perpendicular)
021A9^↩^\hookleftarrow^\hookleftarrow^R^mathrel^^left arrow-hooked
021AA^↪^\hookrightarrow^\hookrightarrow^R^mathrel^^right arrow-hooked
021AB^↫^\looparrowleft^\looparrowleft^R^mathrel^amssymb^left arrow-looped
021AC^↬^\looparrowright^\looparrowright^R^mathrel^amssymb^right arrow-looped
021AD^↭^\leftrightsquigarrow^\leftrightsquigarrow^R^mathrel^amssymb^left and right arr-wavy
021AE^↮^\nleftrightarrow^\nleftrightarrow^R^mathrel^amssymb^not left and right arrow
021AF^↯^\lightning^\downzigzagarrow^R^mathrel^stmaryrd^t \Lightning (marvosym), DOWNWARDS ZIGZAG ARROW
021B0^↰^\Lsh^\Lsh^R^mathrel^amssymb^a: UPWARDS ARROW WITH TIP LEFTWARDS
021B1^↱^\Rsh^\Rsh^R^mathrel^amssymb^a: UPWARDS ARROW WITH TIP RIGHTWARDS
021B2^↲^\dlsh^\Ldsh^R^mathrel^mathabx^left down angled arrow
021B3^↳^\drsh^\Rdsh^R^mathrel^mathabx^right down angled arrow
021B4^↴^^\linefeed^^mathord^^RIGHTWARDS ARROW WITH CORNER DOWNWARDS
021B5^↵^^\carriagereturn^^mathord^^downwards arrow with corner leftward = carriage return
021B6^↶^\curvearrowleft^\curvearrowleft^R^mathrel^amssymb fourier^left curved arrow
021B7^↷^\curvearrowright^\curvearrowright^R^mathrel^amssymb fourier^right curved arrow
021B8^↸^^\barovernorthwestarrow^^mathord^^NORTH WEST ARROW TO LONG BAR
021B9^↹^^\barleftarrowrightarrowba^^mathord^^LEFTWARDS ARROW TO BAR OVER RIGHTWARDS ARROW TO BAR
021BA^↺^\circlearrowleft^\acwopencirclearrow^R^mathord^amssymb^= \leftturn (wasysym), ANTICLOCKWISE OPEN CIRCLE ARROW
021BB^↻^\circlearrowright^\cwopencirclearrow^R^mathord^amssymb^= \rightturn (wasysym), CLOCKWISE OPEN CIRCLE ARROW
021BC^↼^\leftharpoonup^\leftharpoonup^R^mathrel^^left harpoon-up
021BD^↽^\leftharpoondown^\leftharpoondown^R^mathrel^^left harpoon-down
021BE^↾^\upharpoonright^\upharpoonright^R^mathrel^amssymb^= \restriction (amssymb), = \upharpoonrightup (wrisym), a: up harpoon-right
021BF^↿^\upharpoonleft^\upharpoonleft^R^mathrel^amssymb^= \upharpoonleftup (wrisym), up harpoon-left
021C0^⇀^\rightharpoonup^\rightharpoonup^R^mathrel^^right harpoon-up
021C1^⇁^\rightharpoondown^\rightharpoondown^R^mathrel^^right harpoon-down
021C2^⇂^\downharpoonright^\downharpoonright^R^mathrel^amssymb^= \upharpoonrightdown (wrisym), down harpoon-right
021C3^⇃^\downharpoonleft^\downharpoonleft^R^mathrel^amssymb^= \upharpoonleftdown (wrisym), down harpoon-left
021C4^⇄^\rightleftarrows^\rightleftarrows^R^mathrel^amssymb^= \rightleftarrow (wrisym), right arrow over left arrow
021C5^⇅^\updownarrows^\updownarrows^R^mathrel^mathabx^= \uparrowdownarrow (wrisym), up arrow, down arrow
021C6^⇆^\leftrightarrows^\leftrightarrows^R^mathrel^amssymb^= \leftrightarrow (wrisym), left arrow over right arrow
021C7^⇇^\leftleftarrows^\leftleftarrows^R^mathrel^amssymb fourier^two left arrows
021C8^⇈^\upuparrows^\upuparrows^R^mathrel^amssymb^two up arrows
021C9^⇉^\rightrightarrows^\rightrightarrows^R^mathrel^amssymb fourier^two right arrows
021CA^⇊^\downdownarrows^\downdownarrows^R^mathrel^amssymb^two down arrows
021CB^⇋^\leftrightharpoons^\leftrightharpoons^R^mathrel^amssymb^= \revequilibrium (wrisym), left harpoon over right
021CC^⇌^\rightleftharpoons^\rightleftharpoons^R^mathrel^^= \equilibrium (wrisym), right harpoon over left
021CD^⇍^\nLeftarrow^\nLeftarrow^R^mathrel^amssymb^not implied by
021CE^⇎^\nLeftrightarrow^\nLeftrightarrow^R^mathrel^amssymb^not left and right double arrows
021CF^⇏^\nRightarrow^\nRightarrow^R^mathrel^amssymb^not implies
021D0^⇐^\Leftarrow^\Leftarrow^R^mathrel^^left double arrow
021D1^⇑^\Uparrow^\Uparrow^R^mathrel^^up double arrow
021D2^⇒^\Rightarrow^\Rightarrow^R^mathrel^-marvosym^right double arrow
021D3^⇓^\Downarrow^\Downarrow^R^mathrel^^down double arrow
021D4^⇔^\Leftrightarrow^\Leftrightarrow^R^mathrel^^left and right double arrow
021D5^⇕^\Updownarrow^\Updownarrow^R^mathrel^^up and down double arrow
021D6^⇖^\Nwarrow^\Nwarrow^R^mathrel^txfonts^nw pointing double arrow
021D7^⇗^\Nearrow^\Nearrow^R^mathrel^txfonts^ne pointing double arrow
021D8^⇘^\Searrow^\Searrow^R^mathrel^txfonts^se pointing double arrow
021D9^⇙^\Swarrow^\Swarrow^R^mathrel^txfonts^sw pointing double arrow
021DA^⇚^\Lleftarrow^\Lleftarrow^R^mathrel^amssymb^left triple arrow
021DB^⇛^\Rrightarrow^\Rrightarrow^R^mathrel^amssymb^right triple arrow
021DC^⇜^\leftsquigarrow^\leftsquigarrow^R^mathrel^mathabx txfonts^LEFTWARDS SQUIGGLE ARROW
021DD^⇝^\rightsquigarrow^\rightsquigarrow^R^mathrel^amssymb^RIGHTWARDS SQUIGGLE ARROW
021DE^⇞^^\nHuparrow^R^mathord^^UPWARDS ARROW WITH DOUBLE STROKE
021DF^⇟^^\nHdownarrow^R^mathord^^DOWNWARDS ARROW WITH DOUBLE STROKE
021E0^⇠^\dashleftarrow^\leftdasharrow^R^mathord^amsfonts^LEFTWARDS DASHED ARROW
021E1^⇡^^\updasharrow^R^mathord^^UPWARDS DASHED ARROW
021E2^⇢^\dashrightarrow^\rightdasharrow^R^mathord^amsfonts^= \dasharrow (amsfonts), RIGHTWARDS DASHED ARROW
021E3^⇣^^\downdasharrow^R^mathord^^DOWNWARDS DASHED ARROW
021E4^⇤^\LeftArrowBar^\barleftarrow^R^mathrel^wrisym^LEFTWARDS ARROW TO BAR
021E5^⇥^\RightArrowBar^\rightarrowbar^R^mathrel^wrisym^RIGHTWARDS ARROW TO BAR
021E6^⇦^^\leftwhitearrow^R^mathord^^LEFTWARDS WHITE ARROW
021E7^⇧^^\upwhitearrow^R^mathord^^UPWARDS WHITE ARROW
021E8^⇨^^\rightwhitearrow^R^mathord^^RIGHTWARDS WHITE ARROW
021E9^⇩^^\downwhitearrow^R^mathord^^DOWNWARDS WHITE ARROW
021EA^⇪^^\whitearrowupfrombar^^mathord^^UPWARDS WHITE ARROW FROM BAR
021EB^⇫^^^^mathord^^UPWARDS WHITE ARROW ON PEDESTAL
021EC^⇬^^^^mathord^^UPWARDS WHITE ARROW ON PEDESTAL WITH HORIZONTAL BAR
021ED^⇭^^^^mathord^^UPWARDS WHITE ARROW ON PEDESTAL WITH VERTICAL BAR
021EE^⇮^^^^mathord^^UPWARDS WHITE DOUBLE ARROW
021EF^⇯^^^^mathord^^UPWARDS WHITE DOUBLE ARROW ON PEDESTAL
021F0^⇰^^^^mathord^^RIGHTWARDS WHITE ARROW FROM WALL
021F1^⇱^^^^mathord^^NORTH WEST ARROW TO CORNER
021F2^⇲^^^^mathord^^SOUTH EAST ARROW TO CORNER
021F3^⇳^^^^mathord^^UP DOWN WHITE ARROW
021F4^⇴^^\circleonrightarrow^R^mathrel^^RIGHT ARROW WITH SMALL CIRCLE
021F5^⇵^\downuparrows^\downuparrows^R^mathrel^mathabx^= \downarrowuparrow (wrisym), DOWNWARDS ARROW LEFTWARDS OF UPWARDS ARROW
021F6^⇶^^\rightthreearrows^R^mathrel^^THREE RIGHTWARDS ARROWS
021F7^⇷^^\nvleftarrow^R^mathrel^^LEFTWARDS ARROW WITH VERTICAL STROKE
021F8^⇸^\pfun^\nvrightarrow^R^mathrel^oz^RIGHTWARDS ARROW WITH VERTICAL STROKE, z notation partial function
021F9^⇹^^\nvleftrightarrow^R^mathrel^^LEFT RIGHT ARROW WITH VERTICAL STROKE, z notation partial relation
021FA^⇺^^\nVleftarrow^R^mathrel^^LEFTWARDS ARROW WITH DOUBLE VERTICAL STROKE
021FB^⇻^\ffun^\nVrightarrow^R^mathrel^oz^RIGHTWARDS ARROW WITH DOUBLE VERTICAL STROKE, z notation finite function
021FC^⇼^^\nVleftrightarrow^R^mathrel^^LEFT RIGHT ARROW WITH DOUBLE VERTICAL STROKE, z notation finite relation
021FD^⇽^\leftarrowtriangle^\leftarrowtriangle^R^mathrel^stmaryrd^LEFTWARDS OPEN-HEADED ARROW
021FE^⇾^\rightarrowtriangle^\rightarrowtriangle^R^mathrel^stmaryrd^RIGHTWARDS OPEN-HEADED ARROW
021FF^⇿^\leftrightarrowtriangle^\leftrightarrowtriangle^R^mathrel^stmaryrd^LEFT RIGHT OPEN-HEADED ARROW
02200^∀^\forall^\forall^U^mathord^^FOR ALL
02201^∁^\complement^\complement^U^mathord^amssymb fourier^COMPLEMENT sign
02202^∂^\partial^\partial^N^mathord^-literal^= \partialup (kpfonts), PARTIAL DIFFERENTIAL
02203^∃^\exists^\exists^U^mathord^^= \exi (oz), at least one exists
02204^∄^\nexists^\nexists^U^mathord^amssymb fourier^= \nexi (oz), negated exists
02205^∅^\varnothing^\varnothing^N^mathord^amssymb^circle, slash
02206^∆^^\increment^U^mathord^^# \mathrm{\Delta}, laplacian (Delta; nabla square)
02207^∇^\nabla^\nabla^U^mathord^^NABLA, del, hamilton operator
02208^∈^\in^\in^R^mathrel^^set membership, variant
02209^∉^\notin^\notin^R^mathrel^^= \nin (wrisym), negated set membership
0220A^∊^^\smallin^R^mathrel^^set membership (small set membership)
0220B^∋^\ni^\ni^R^mathrel^^= \owns, contains, variant
0220C^∌^\nni^\nni^R^mathrel^wrisym^= \notni (txfonts), = \notowner (mathabx), = \notowns (fourier), negated contains, variant
0220D^∍^^\smallni^R^mathrel^^r: contains (SMALL CONTAINS AS MEMBER)
0220E^∎^^\QED^N^mathord^^# \blacksquare (amssymb), END OF PROOF
0220F^∏^\prod^\prod^L^mathop^^product operator
02210^∐^\coprod^\coprod^L^mathop^^coproduct operator
02211^∑^\sum^\sum^L^mathop^^summation operator
02212^−^-^\minus^V^mathbin^^MINUS SIGN
02213^∓^\mp^\mp^V^mathbin^^MINUS-OR-PLUS SIGN
02214^∔^\dotplus^\dotplus^B^mathbin^amssymb^plus sign, dot above
02215^∕^\slash^\divslash^B^mathbin^^DIVISION SLASH
02216^∖^\smallsetminus^\smallsetminus^B^mathbin^amssymb fourier^small SET MINUS (cf. reverse solidus)
02217^∗^\ast^\ast^B^mathbin^^ASTERISK OPERATOR (Hodge star operator)
02218^∘^\circ^\vysmwhtcircle^B^mathbin^^composite function (small circle)
02219^∙^\bullet^\vysmblkcircle^B^mathbin^^BULLET OPERATOR
0221A^√^\sqrt^\sqrt^L^mathradical^^radical
0221B^∛^\sqrt[3]^\cuberoot^L^mathradical^^CUBE ROOT
0221C^∜^\sqrt[4]^\fourthroot^L^mathradical^^FOURTH ROOT
0221D^∝^\propto^\propto^R^mathrel^^# \varpropto (amssymb), is PROPORTIONAL TO
0221E^∞^\infty^\infty^N^mathord^^INFINITY
0221F^∟^\rightangle^\rightangle^N^mathord^wrisym^right (90 degree) angle
02220^∠^\angle^\angle^N^mathord^^ANGLE
02221^∡^\measuredangle^\measuredangle^N^mathord^amssymb wrisym^MEASURED ANGLE
02222^∢^\sphericalangle^\sphericalangle^N^mathord^amssymb wrisym^SPHERICAL ANGLE
02223^∣^\mid^\mid^R^mathrel^^r: DIVIDES
02224^∤^\nmid^\nmid^R^mathrel^amssymb^negated mid, DOES NOT DIVIDE
02225^∥^\parallel^\parallel^R^mathrel^^parallel
02226^∦^\nparallel^\nparallel^R^mathrel^amssymb fourier^not parallel
02227^∧^\wedge^\wedge^B^mathbin^amssymb^= \land, b: LOGICAL AND
02228^∨^\vee^\vee^B^mathbin^^= \lor, b: LOGICAL OR
02229^∩^\cap^\cap^B^mathbin^^INTERSECTION
0222A^∪^\cup^\cup^B^mathbin^^UNION or logical sum
0222B^∫^\int^\int^L^mathop^^INTEGRAL operator
0222C^∬^\iint^\iint^L^mathop^amsmath fourier esint wasysym^DOUBLE INTEGRAL operator
0222D^∭^\iiint^\iiint^L^mathop^amsmath fourier esint wasysym^TRIPLE INTEGRAL operator
0222E^∮^\oint^\oint^L^mathop^^CONTOUR INTEGRAL operator
0222F^∯^\oiint^\oiint^L^mathop^esint wasysym fourier^= \dbloint (wrisym), double contour integral operator
02230^∰^\oiiint^\oiiint^L^mathop^txfonts fourier^triple contour integral operator
02231^∱^^\intclockwise^L^mathop^^CLOCKWISE INTEGRAL
02232^∲^\varointclockwise^\varointclockwise^L^mathop^esint^= \clockoint (wrisym), contour integral, clockwise
02233^∳^\ointctrclockwise^\ointctrclockwise^L^mathop^esint^= \cntclockoint (wrisym), contour integral, anticlockwise
02234^∴^\therefore^\therefore^R^mathord^amssymb wrisym^= \wasytherefore (wasysym), THEREFORE
02235^∵^\because^\because^R^mathord^amssymb wrisym^BECAUSE
02236^∶^:^\mathratio^R^mathrel^^x \colon, RATIO
02237^∷^\Proportion^\Colon^R^mathrel^wrisym^# ::, two colons
02238^∸^^\dotminus^B^mathbin^^minus sign, dot above
02239^∹^\eqcolon^\dashcolon^R^mathrel^txfonts -mathabx^# -: ,EXCESS
0223A^∺^^\dotsminusdots^R^mathrel^^minus with four dots, GEOMETRIC PROPORTION
0223B^∻^^\kernelcontraction^R^mathrel^^HOMOTHETIC
0223C^∼^\sim^\sim^R^mathrel^^similar to, TILDE OPERATOR
0223D^∽^\backsim^\backsim^R^mathrel^amssymb^reverse similar
0223E^∾^^\invlazys^B^mathbin^^most positive, INVERTED LAZY S
0223F^∿^\AC^\sinewave^N^mathord^wasysym^SINE WAVE, alternating current
02240^≀^\wr^\wr^B^mathbin^amssymb^WREATH PRODUCT
02241^≁^\nsim^\nsim^R^mathrel^amssymb wrisym^not similar
02242^≂^\eqsim^\eqsim^R^mathrel^amssymb^equals, similar
02243^≃^\simeq^\simeq^R^mathrel^^similar, equals
02244^≄^\nsimeq^\nsime^R^mathrel^txfonts^not similar, equals
02245^≅^\cong^\cong^R^mathrel^^congruent with
02246^≆^^\simneqq^R^mathrel^^similar, not equals [vert only for 9573 entity]
02247^≇^\ncong^\ncong^R^mathrel^amssymb wrisym^not congruent with
02248^≈^\approx^\approx^R^mathrel^^approximate
02249^≉^\napprox^\napprox^R^mathrel^wrisym^not approximate
0224A^≊^\approxeq^\approxeq^R^mathrel^amssymb^approximate, equals
0224B^≋^^\approxident^R^mathrel^^approximately identical to
0224C^≌^^\backcong^R^mathrel^^ALL EQUAL TO
0224D^≍^\asymp^\asymp^R^mathrel^^asymptotically equal to
0224E^≎^\Bumpeq^\Bumpeq^R^mathrel^amssymb wrisym^bumpy equals
0224F^≏^\bumpeq^\bumpeq^R^mathrel^amssymb wrisym^bumpy equals, equals
02250^≐^\doteq^\doteq^R^mathrel^^= \dotequal (wrisym), equals, single dot above
02251^≑^\Doteq^\Doteq^R^mathrel^amssymb^= \doteqdot (amssymb), /doteq r: equals, even dots
02252^≒^\fallingdotseq^\fallingdotseq^R^mathrel^amssymb^equals, falling dots
02253^≓^\risingdotseq^\risingdotseq^R^mathrel^amssymb^equals, rising dots
02254^≔^\coloneq^\coloneq^R^mathrel^mathabx -txfonts^= \coloneqq (txfonts), = \SetDelayed (wrisym), # := colon, equals
02255^≕^\eqcolon^\eqcolon^R^mathrel^mathabx -txfonts^= \eqqcolon (txfonts), # =:, equals, colon
02256^≖^\eqcirc^\eqcirc^R^mathrel^amssymb^circle on equals sign
02257^≗^\circeq^\circeq^R^mathrel^amssymb^circle, equals
02258^≘^^\arceq^R^mathrel^^arc, equals; CORRESPONDS TO
02259^≙^\corresponds^\wedgeq^R^mathrel^mathabx^= \sdef (oz), t \Corresponds (marvosym), corresponds to (wedge over equals)
0225A^≚^^\veeeq^R^mathrel^^logical or, equals
0225B^≛^^\stareq^R^mathrel^^STAR EQUALS
0225C^≜^\triangleq^\triangleq^R^mathrel^amssymb^= \varsdef (oz), triangle, equals
0225D^≝^^\eqdef^R^mathrel^^equals by definition
0225E^≞^^\measeq^R^mathrel^^MEASURED BY (m over equals)
0225F^≟^^\questeq^R^mathrel^^equal with questionmark
02260^≠^\neq^\ne^R^mathrel^^= \ne, r: not equal
02261^≡^\equiv^\equiv^R^mathrel^^identical with
02262^≢^\nequiv^\nequiv^R^mathrel^wrisym^not identical with
02263^≣^^\Equiv^R^mathrel^^strict equivalence (4 lines)
02264^≤^\leq^\leq^R^mathrel^^= \le, r: less-than-or-equal
02265^≥^\geq^\geq^R^mathrel^^= \ge, r: greater-than-or-equal
02266^≦^\leqq^\leqq^R^mathrel^amssymb^less, double equals
02267^≧^\geqq^\geqq^R^mathrel^amssymb^greater, double equals
02268^≨^\lneqq^\lneqq^R^mathrel^amssymb^less, not double equals
02269^≩^\gneqq^\gneqq^R^mathrel^amssymb^greater, not double equals
0226A^≪^\ll^\ll^R^mathrel^^much less than, type 2
0226B^≫^\gg^\gg^R^mathrel^^much greater than, type 2
0226C^≬^\between^\between^R^mathrel^amssymb^BETWEEN
0226D^≭^\notasymp^\nasymp^R^mathrel^mathabx^= \nasymp (wrisym), not asymptotically equal to
0226E^≮^\nless^\nless^R^mathrel^amssymb^NOT LESS-THAN
0226F^≯^\ngtr^\ngtr^R^mathrel^amssymb^NOT GREATER-THAN
02270^≰^\nleq^\nleq^R^mathrel^amssymb wrisym^= \nleqslant (fourier), not less-than-or-equal
02271^≱^\ngeq^\ngeq^R^mathrel^amssymb wrisym^= \ngeqslant (fourier), not greater-than-or-equal
02272^≲^\lesssim^\lesssim^R^mathrel^amssymb^= \apprle (wasysym), = \LessTilde (wrisym), less, similar
02273^≳^\gtrsim^\gtrsim^R^mathrel^amssymb^= \apprge (wasysym), = \GreaterTilde (wrisym), greater, similar
02274^≴^\NotLessTilde^\nlesssim^R^mathrel^wrisym^not less, similar
02275^≵^\NotGreaterTilde^\ngtrsim^R^mathrel^wrisym^not greater, similar
02276^≶^\lessgtr^\lessgtr^R^mathrel^amssymb^less, greater
02277^≷^\gtrless^\gtrless^R^mathrel^amssymb^= \GreaterLess (wrisym), greater, less
02278^≸^^\nlessgtr^R^mathrel^wrisym^not less, greater
02279^≹^\NotGreaterLess^\ngtrless^R^mathrel^wrisym^not greater, less
0227A^≺^\prec^\prec^R^mathrel^^PRECEDES
0227B^≻^\succ^\succ^R^mathrel^^SUCCEEDS
0227C^≼^\preccurlyeq^\preccurlyeq^R^mathrel^amssymb^= \PrecedesSlantEqual (wrisym), precedes, curly equals
0227D^≽^\succcurlyeq^\succcurlyeq^R^mathrel^amssymb^= \SucceedsSlantEqual (wrisym), succeeds, curly equals
0227E^≾^\precsim^\precsim^R^mathrel^amssymb^= \PrecedesTilde (wrisym), precedes, similar
0227F^≿^\succsim^\succsim^R^mathrel^amssymb^= \SucceedsTilde (wrisym), succeeds, similar
02280^⊀^\nprec^\nprec^R^mathrel^amssymb wrisym^not precedes
02281^⊁^\nsucc^\nsucc^R^mathrel^amssymb wrisym^not succeeds
02282^⊂^\subset^\subset^R^mathrel^^subset or is implied by
02283^⊃^\supset^\supset^R^mathrel^^superset or implies
02284^⊄^\nsubset^\nsubset^R^mathrel^wrisym^not subset, variant [slash negation]
02285^⊅^\nsupset^\nsupset^R^mathrel^wrisym^not superset, variant [slash negation]
02286^⊆^\subseteq^\subseteq^R^mathrel^^subset, equals
02287^⊇^\supseteq^\supseteq^R^mathrel^^superset, equals
02288^⊈^\nsubseteq^\nsubseteq^R^mathrel^amssymb wrisym^not subset, equals
02289^⊉^\nsupseteq^\nsupseteq^R^mathrel^amssymb wrisym^not superset, equals
0228A^⊊^\subsetneq^\subsetneq^R^mathrel^amssymb^= \varsubsetneq (fourier), subset, not equals
0228B^⊋^\supsetneq^\supsetneq^R^mathrel^amssymb^superset, not equals
0228C^⊌^^\cupleftarrow^B^mathbin^^MULTISET
0228D^⊍^^\cupdot^B^mathbin^^union, with dot
0228E^⊎^\uplus^\uplus^B^mathbin^^= \buni (oz), plus sign in union
0228F^⊏^\sqsubset^\sqsubset^R^mathrel^amsfonts^square subset
02290^⊐^\sqsupset^\sqsupset^R^mathrel^amsfonts^square superset
02291^⊑^\sqsubseteq^\sqsubseteq^R^mathrel^^square subset, equals
02292^⊒^\sqsupseteq^\sqsupseteq^R^mathrel^^square superset, equals
02293^⊓^\sqcap^\sqcap^B^mathbin^^square intersection
02294^⊔^\sqcup^\sqcup^B^mathbin^^square union
02295^⊕^\oplus^\oplus^B^mathbin^^plus sign in circle
02296^⊖^\ominus^\ominus^B^mathbin^^minus sign in circle
02297^⊗^\otimes^\otimes^B^mathbin^^multiply sign in circle
02298^⊘^\oslash^\oslash^B^mathbin^^solidus in circle
02299^⊙^\odot^\odot^B^mathbin^^middle dot in circle
0229A^⊚^\circledcirc^\circledcirc^B^mathbin^amssymb^small circle in circle
0229B^⊛^\circledast^\circledast^B^mathbin^amssymb^asterisk in circle
0229C^⊜^^\circledequal^B^mathbin^^equal in circle
0229D^⊝^\circleddash^\circleddash^B^mathbin^amssymb^hyphen in circle
0229E^⊞^\boxplus^\boxplus^B^mathbin^amssymb^plus sign in box
0229F^⊟^\boxminus^\boxminus^B^mathbin^amssymb^minus sign in box
022A0^⊠^\boxtimes^\boxtimes^B^mathbin^amssymb^multiply sign in box
022A1^⊡^\boxdot^\boxdot^B^mathbin^amssymb stmaryrd^/dotsquare /boxdot b: small dot in box
022A2^⊢^\vdash^\vdash^R^mathrel^^RIGHT TACK, proves, implies, yields, (vertical, dash)
022A3^⊣^\dashv^\dashv^R^mathrel^amssymb^LEFT TACK, non-theorem, does not yield, (dash, vertical)
022A4^⊤^\top^\top^N^mathord^^DOWN TACK, top
022A5^⊥^\bot^\bot^R^mathord^^UP TACK, bottom
022A6^⊦^^\assert^R^mathrel^^# \vdash, ASSERTION (vertical, short dash)
022A7^⊧^\models^\models^R^mathrel^^MODELS (vertical, short double dash)
022A8^⊨^\vDash^\vDash^R^mathrel^amssymb fourier^TRUE (vertical, double dash)
022A9^⊩^\Vdash^\Vdash^R^mathrel^amssymb^double vertical, dash
022AA^⊪^\Vvdash^\Vvdash^R^mathrel^amssymb^triple vertical, dash
022AB^⊫^\VDash^\VDash^R^mathrel^mathabx txfonts^double vert, double dash
022AC^⊬^\nvdash^\nvdash^R^mathrel^amssymb^not vertical, dash
022AD^⊭^\nvDash^\nvDash^R^mathrel^amssymb fourier^not vertical, double dash
022AE^⊮^\nVdash^\nVdash^R^mathrel^amssymb^not double vertical, dash
022AF^⊯^\nVDash^\nVDash^R^mathrel^amssymb^not double vert, double dash
022B0^⊰^^\prurel^R^mathrel^^element PRECEDES UNDER RELATION
022B1^⊱^^\scurel^R^mathrel^^SUCCEEDS UNDER RELATION
022B2^⊲^\vartriangleleft^\vartriangleleft^R^mathrel^amssymb^left triangle, open, variant
022B3^⊳^\vartriangleright^\vartriangleright^R^mathrel^amssymb^right triangle, open, variant
022B4^⊴^\trianglelefteq^\trianglelefteq^R^mathrel^amssymb^= \unlhd (wrisym), left triangle, equals
022B5^⊵^\trianglerighteq^\trianglerighteq^R^mathrel^amssymb^= \unrhd (wrisym), right triangle, equals
022B6^⊶^\multimapdotbothA^\origof^R^mathrel^txfonts^ORIGINAL OF
022B7^⊷^\multimapdotbothB^\imageof^R^mathrel^txfonts^IMAGE OF
022B8^⊸^\multimap^\multimap^R^mathrel^amssymb^/MULTIMAP a:
022B9^⊹^^\hermitmatrix^B^mathord^^HERMITIAN CONJUGATE MATRIX
022BA^⊺^\intercal^\intercal^B^mathbin^amssymb fourier^intercal
022BB^⊻^\veebar^\veebar^B^mathbin^amssymb^logical or, bar below (large vee); exclusive disjunction
022BC^⊼^\barwedge^\barwedge^B^mathbin^amssymb^logical NAND (bar over wedge)
022BD^⊽^^\barvee^B^mathbin^^bar, vee (large vee)
022BE^⊾^^\measuredrightangle^N^mathord^^right angle-measured [with arc]
022BF^⊿^^\varlrtriangle^N^mathord^^RIGHT TRIANGLE
022C0^⋀^\bigwedge^\bigwedge^L^mathop^^logical or operator
022C1^⋁^\bigvee^\bigvee^L^mathop^^logical and operator
022C2^⋂^\bigcap^\bigcap^L^mathop^^= \dint (oz), \dinter (oz), intersection operator
022C3^⋃^\bigcup^\bigcup^L^mathop^^= \duni (oz), \dunion (oz), union operator
022C4^⋄^\diamond^\smwhtdiamond^B^mathbin^^DIAMOND OPERATOR (white diamond)
022C5^⋅^\cdot^\cdot^B^mathbin^^DOT OPERATOR (small middle dot)
022C6^⋆^\star^\star^B^mathbin^^small star, filled, low
022C7^⋇^\divideontimes^\divideontimes^B^mathbin^amssymb^division on times
022C8^⋈^\bowtie^\bowtie^R^mathrel^^= \lrtimes (txfonts), BOWTIE
022C9^⋉^\ltimes^\ltimes^B^mathbin^amssymb^times sign, left closed
022CA^⋊^\rtimes^\rtimes^B^mathbin^amssymb^times sign, right closed
022CB^⋋^\leftthreetimes^\leftthreetimes^B^mathbin^amssymb^LEFT SEMIDIRECT PRODUCT
022CC^⋌^\rightthreetimes^\rightthreetimes^B^mathbin^amssymb^RIGHT SEMIDIRECT PRODUCT
022CD^⋍^\backsimeq^\backsimeq^R^mathrel^amssymb^reverse similar, equals
022CE^⋎^\curlyvee^\curlyvee^B^mathbin^amssymb^CURLY LOGICAL OR
022CF^⋏^\curlywedge^\curlywedge^B^mathbin^amssymb^CURLY LOGICAL AND
022D0^⋐^\Subset^\Subset^R^mathrel^amssymb^DOUBLE SUBSET
022D1^⋑^\Supset^\Supset^R^mathrel^amssymb^DOUBLE SUPERSET
022D2^⋒^\Cap^\Cap^B^mathbin^amssymb^/cap /doublecap b: DOUBLE INTERSECTION
022D3^⋓^\Cup^\Cup^B^mathbin^amssymb^/cup /doublecup b: DOUBLE UNION
022D4^⋔^\pitchfork^\pitchfork^R^mathrel^amssymb^PITCHFORK
022D5^⋕^\hash^\equalparallel^R^mathrel^mathabx^parallel, equal; equal or parallel
022D6^⋖^\lessdot^\lessdot^R^mathrel^amssymb^less than, with dot
022D7^⋗^\gtrdot^\gtrdot^R^mathrel^amssymb^greater than, with dot
022D8^⋘^\lll^\lll^R^mathrel^amssymb -mathabx^triple less-than
022D9^⋙^\ggg^\ggg^R^mathrel^amssymb -mathabx^triple greater-than
022DA^⋚^\lesseqgtr^\lesseqgtr^R^mathrel^amssymb^less, equals, greater
022DB^⋛^\gtreqless^\gtreqless^R^mathrel^amssymb^greater, equals, less
022DC^⋜^^\eqless^R^mathrel^^equal-or-less
022DD^⋝^^\eqgtr^R^mathrel^^equal-or-greater
022DE^⋞^\curlyeqprec^\curlyeqprec^R^mathrel^amssymb^curly equals, precedes
022DF^⋟^\curlyeqsucc^\curlyeqsucc^R^mathrel^amssymb^curly equals, succeeds
022E0^⋠^\npreceq^\npreccurlyeq^R^mathrel^amssymb wrisym^DOES NOT PRECEDE OR EQUAL
022E1^⋡^\nsucceq^\nsucccurlyeq^R^mathrel^amssymb wrisym^not succeeds, curly equals
022E2^⋢^\nsqsubseteq^\nsqsubseteq^R^mathrel^wrisym^not, square subset, equals
022E3^⋣^\nsqsupseteq^\nsqsupseteq^R^mathrel^wrisym^not, square superset, equals
022E4^⋤^^\sqsubsetneq^R^mathrel^^square subset, not equals
022E5^⋥^^\sqsupsetneq^R^mathrel^^square superset, not equals
022E6^⋦^\lnsim^\lnsim^R^mathrel^amssymb^less, not similar
022E7^⋧^\gnsim^\gnsim^R^mathrel^amssymb^greater, not similar
022E8^⋨^\precnsim^\precnsim^R^mathrel^amssymb^precedes, not similar
022E9^⋩^\succnsim^\succnsim^R^mathrel^amssymb^succeeds, not similar
022EA^⋪^\ntriangleleft^\ntriangleleft^R^mathrel^amssymb^= \NotLeftTriangle (wrisym), not left triangle
022EB^⋫^\ntriangleright^\ntriangleright^R^mathrel^amssymb^= \NotRightTriangle (wrisym), not right triangle
022EC^⋬^\ntrianglelefteq^\ntrianglelefteq^R^mathrel^amssymb^= \nunlhd (wrisym), not left triangle, equals
022ED^⋭^\ntrianglerighteq^\ntrianglerighteq^R^mathrel^amssymb^= \nunrhd (wrisym), not right triangle, equals
022EE^⋮^\vdots^\vdots^R^mathrel^^VERTICAL ELLIPSIS
022EF^⋯^\cdots^\unicodecdots^R^mathord^^three dots, centered
022F0^⋰^\iddots^\adots^R^mathrel^mathdots^= \adots (yhmath), three dots, ascending
022F1^⋱^\ddots^\ddots^R^mathrel^^three dots, descending
022F2^⋲^^\disin^R^mathrel^^ELEMENT OF WITH LONG HORIZONTAL STROKE
022F3^⋳^^\varisins^R^mathrel^^ELEMENT OF WITH VERTICAL BAR AT END OF HORIZONTAL STROKE
022F4^⋴^^\isins^R^mathrel^^SMALL ELEMENT OF WITH VERTICAL BAR AT END OF HORIZONTAL STROKE
022F5^⋵^^\isindot^R^mathrel^^ELEMENT OF WITH DOT ABOVE
022F6^⋶^\barin^\varisinobar^R^mathrel^mathabx^ELEMENT OF WITH OVERBAR
022F7^⋷^^\isinobar^R^mathrel^^SMALL ELEMENT OF WITH OVERBAR
022F8^⋸^^\isinvb^R^mathrel^^ELEMENT OF WITH UNDERBAR
022F9^⋹^^\isinE^R^mathrel^^ELEMENT OF WITH TWO HORIZONTAL STROKES
022FA^⋺^^\nisd^R^mathrel^^CONTAINS WITH LONG HORIZONTAL STROKE
022FB^⋻^^\varnis^R^mathrel^^CONTAINS WITH VERTICAL BAR AT END OF HORIZONTAL STROKE
022FC^⋼^^\nis^R^mathrel^^SMALL CONTAINS WITH VERTICAL BAR AT END OF HORIZONTAL STROKE
022FD^⋽^^\varniobar^R^mathrel^^CONTAINS WITH OVERBAR
022FE^⋾^^\niobar^R^mathrel^^SMALL CONTAINS WITH OVERBAR
022FF^⋿^^\bagmember^R^mathrel^^# \mathsf{E}, Z NOTATION BAG MEMBERSHIP
02300^⌀^\diameter^\diameter^N^mathord^mathabx^# \varnothing (amssymb), DIAMETER SIGN
02302^⌂^^\house^N^mathord^^HOUSE
02305^⌅^^\varbarwedge^B^mathbin^^# \barwedge (amssymb), PROJECTIVE (bar over small wedge) not nand
02306^⌆^^\vardoublebarwedge^B^mathbin^^# \doublebarwedge (amssymb), PERSPECTIVE (double bar over small wedge)
02308^⌈^\lceil^\lceil^O^mathopen^^LEFT CEILING
02309^⌉^\rceil^\rceil^C^mathclose^^RIGHT CEILING
0230A^⌊^\lfloor^\lfloor^O^mathopen^^LEFT FLOOR
0230B^⌋^\rfloor^\rfloor^C^mathclose^^RIGHT FLOOR
02310^⌐^\invneg^\invnot^N^mathord^wasysym^reverse not
02311^⌑^\wasylozenge^\sqlozenge^N^mathord^wasysym^SQUARE LOZENGE
02312^⌒^^\profline^^mathord^^profile of a line
02313^⌓^^\profsurf^^mathord^^profile of a surface
02317^⌗^^\viewdata^^mathord^^VIEWDATA SQUARE
02319^⌙^^\turnednot^N^mathord^^TURNED NOT SIGN
0231C^⌜^\ulcorner^\ulcorner^O^mathopen^amsfonts^upper left corner
0231D^⌝^\urcorner^\urcorner^C^mathclose^amsfonts^upper right corner
0231E^⌞^\llcorner^\llcorner^O^mathopen^amsfonts^lower left corner
0231F^⌟^\lrcorner^\lrcorner^C^mathclose^amsfonts^lower right corner
02320^⌠^^\inttop^G^mathord^^TOP HALF INTEGRAL
02321^⌡^^\intbottom^G^mathord^^BOTTOM HALF INTEGRAL
02322^⌢^\frown^\frown^R^mathrel^^# \smallFROWN, down curve
02323^⌣^\smile^\smile^R^mathrel^^# \smallSMILE, up curve
0232C^⌬^^\varhexagonlrbonds^^mathord^^six carbon ring, corner down, double bonds lower right etc
02332^⌲^^\conictaper^^mathord^^CONICAL TAPER
02336^⌶^^\topbot^N^mathord^^APL FUNCTIONAL SYMBOL I-BEAM, top and bottom
02337^⌷^^^^mathord^^APL FUNCTIONAL SYMBOL SQUISH QUAD
02338^⌸^^^^mathord^^APL FUNCTIONAL SYMBOL QUAD EQUAL
02339^⌹^\APLinv^^^mathord^wasysym^APL FUNCTIONAL SYMBOL QUAD DIVIDE
0233A^⌺^^^^mathord^^APL FUNCTIONAL SYMBOL QUAD DIAMOND
0233B^⌻^^^^mathord^^APL FUNCTIONAL SYMBOL QUAD JOT
0233C^⌼^^^^mathord^^# \APLcirc{\APLbox} (wasysym), APL FUNCTIONAL SYMBOL QUAD CIRCLE
0233D^⌽^^\obar^B^mathbin^^# \APLvert{\Circle} (wasysym), x \obar (stmaryrd), APL FUNCTIONAL SYMBOL CIRCLE STILE, circle with vertical bar
0233E^⌾^^^^mathord^^# \APLcirc{\Circle} (wasysym), APL FUNCTIONAL SYMBOL CIRCLE JOT
0233F^⌿^\notslash^\APLnotslash^R^mathrel^wasysym^APL FUNCTIONAL SYMBOL SLASH BAR, solidus, bar through
02340^⍀^\notbackslash^\APLnotbackslash^^mathord^wasysym^APL FUNCTIONAL SYMBOL BACKSLASH BAR
02341^⍁^^^^mathord^^APL FUNCTIONAL SYMBOL QUAD SLASH
02342^⍂^^^^mathord^^APL FUNCTIONAL SYMBOL QUAD BACKSLASH
02343^⍃^^^^mathord^^APL FUNCTIONAL SYMBOL QUAD LESS-THAN
02344^⍄^^^^mathord^^APL FUNCTIONAL SYMBOL QUAD GREATER-THAN
02345^⍅^^^^mathord^^APL FUNCTIONAL SYMBOL LEFTWARDS VANE
02346^⍆^^^^mathord^^APL FUNCTIONAL SYMBOL RIGHTWARDS VANE
02347^⍇^\APLleftarrowbox^^^mathord^wasysym^APL FUNCTIONAL SYMBOL QUAD LEFTWARDS ARROW
02348^⍈^\APLrightarrowbox^^^mathord^wasysym^APL FUNCTIONAL SYMBOL QUAD RIGHTWARDS ARROW
02349^⍉^^^^mathord^^APL FUNCTIONAL SYMBOL CIRCLE BACKSLASH
0234A^⍊^^^^mathord^^APL FUNCTIONAL SYMBOL DOWN TACK UNDERBAR
0234B^⍋^^^^mathord^^# \APLvert{\APLup} (wasysym), APL FUNCTIONAL SYMBOL DELTA STILE
0234C^⍌^^^^mathord^^APL FUNCTIONAL SYMBOL QUAD DOWN CARET
0234D^⍍^^^^mathord^^APL FUNCTIONAL SYMBOL QUAD DELTA
0234E^⍎^^^^mathord^^APL FUNCTIONAL SYMBOL DOWN TACK JOT
0234F^⍏^^^^mathord^^APL FUNCTIONAL SYMBOL UPWARDS VANE
02350^⍐^\APLuparrowbox^^^mathord^wasysym^APL FUNCTIONAL SYMBOL QUAD UPWARDS ARROW
02351^⍑^^^^mathord^^APL FUNCTIONAL SYMBOL UP TACK OVERBAR
02352^⍒^^^^mathord^wasysym^# \APLvert{\APLdown} (wasysym), APL FUNCTIONAL SYMBOL DEL STILE
02353^⍓^^\APLboxupcaret^^mathord^^APL FUNCTIONAL SYMBOL QUAD UP CARET
02354^⍔^^^^mathord^^APL FUNCTIONAL SYMBOL QUAD DEL
02355^⍕^^^^mathord^^APL FUNCTIONAL SYMBOL UP TACK JOT
02356^⍖^^^^mathord^^APL FUNCTIONAL SYMBOL DOWNWARDS VANE
02357^⍗^\APLdownarrowbox^^^mathord^wasysym^APL FUNCTIONAL SYMBOL QUAD DOWNWARDS ARROW
02358^⍘^^^^mathord^^APL FUNCTIONAL SYMBOL QUOTE UNDERBAR
02359^⍙^^^^mathord^^APL FUNCTIONAL SYMBOL DELTA UNDERBAR
0235A^⍚^^^^mathord^^APL FUNCTIONAL SYMBOL DIAMOND UNDERBAR
0235B^⍛^^^^mathord^^APL FUNCTIONAL SYMBOL JOT UNDERBAR
0235C^⍜^^^^mathord^^APL FUNCTIONAL SYMBOL CIRCLE UNDERBAR
0235D^⍝^\APLcomment^^^mathord^wasysym^APL FUNCTIONAL SYMBOL UP SHOE JOT
0235E^⍞^\APLinput^^^mathord^wasysym^APL FUNCTIONAL SYMBOL QUOTE QUAD
0235F^⍟^\APLlog^^^mathord^wasysym^APL FUNCTIONAL SYMBOL CIRCLE STAR
02360^⍠^^^^mathord^^APL FUNCTIONAL SYMBOL QUAD COLON
02361^⍡^^^^mathord^^APL FUNCTIONAL SYMBOL UP TACK DIAERESIS
02362^⍢^^^^mathord^^APL FUNCTIONAL SYMBOL DEL DIAERESIS
02363^⍣^^^^mathord^^APL FUNCTIONAL SYMBOL STAR DIAERESIS
02364^⍤^^^^mathord^^APL FUNCTIONAL SYMBOL JOT DIAERESIS
02365^⍥^^^^mathord^^APL FUNCTIONAL SYMBOL CIRCLE DIAERESIS
02366^⍦^^^^mathord^^APL FUNCTIONAL SYMBOL DOWN SHOE STILE
02367^⍧^^^^mathord^^APL FUNCTIONAL SYMBOL LEFT SHOE STILE
02368^⍨^^^^mathord^^APL FUNCTIONAL SYMBOL TILDE DIAERESIS
02369^⍩^^^^mathord^^APL FUNCTIONAL SYMBOL GREATER-THAN DIAERESIS
0236A^⍪^^^^mathord^^APL FUNCTIONAL SYMBOL COMMA BAR
0236B^⍫^^^^mathord^^# \APLnot{\APLdown} (wasysym), APL FUNCTIONAL SYMBOL DEL TILDE
0236C^⍬^^^^mathord^^APL FUNCTIONAL SYMBOL ZILDE
0236D^⍭^^^^mathord^^APL FUNCTIONAL SYMBOL STILE TILDE
0236E^⍮^^^^mathord^^APL FUNCTIONAL SYMBOL SEMICOLON UNDERBAR
0236F^⍯^^^^mathord^^APL FUNCTIONAL SYMBOL QUAD NOT EQUAL
02370^⍰^^\APLboxquestion^^mathord^^APL FUNCTIONAL SYMBOL QUAD QUESTION
02371^⍱^^^^mathord^^APL FUNCTIONAL SYMBOL DOWN CARET TILDE
02372^⍲^^^^mathord^^APL FUNCTIONAL SYMBOL UP CARET TILDE
02373^⍳^^^^mathord^^APL FUNCTIONAL SYMBOL IOTA
02374^⍴^^^^mathord^^APL FUNCTIONAL SYMBOL RHO
02375^⍵^^^^mathord^^APL FUNCTIONAL SYMBOL OMEGA
02376^⍶^^^^mathord^^APL FUNCTIONAL SYMBOL ALPHA UNDERBAR
02377^⍷^^^^mathord^^APL FUNCTIONAL SYMBOL EPSILON UNDERBAR
02378^⍸^^^^mathord^^APL FUNCTIONAL SYMBOL IOTA UNDERBAR
02379^⍹^^^^mathord^^APL FUNCTIONAL SYMBOL OMEGA UNDERBAR
0237C^⍼^^\rangledownzigzagarrow^^mathord^^RIGHT ANGLE WITH DOWNWARDS ZIGZAG ARROW
02394^⎔^^\hexagon^N^mathord^^horizontal benzene ring [hexagon flat open]
0239B^⎛^^\lparenuend^G^mathord^^LEFT PARENTHESIS UPPER HOOK
0239C^⎜^^\lparenextender^G^mathord^^LEFT PARENTHESIS EXTENSION
0239D^⎝^^\lparenlend^G^mathord^^LEFT PARENTHESIS LOWER HOOK
0239E^⎞^^\rparenuend^G^mathord^^RIGHT PARENTHESIS UPPER HOOK
0239F^⎟^^\rparenextender^G^mathord^^RIGHT PARENTHESIS EXTENSION
023A0^⎠^^\rparenlend^G^mathord^^RIGHT PARENTHESIS LOWER HOOK
023A1^⎡^^\lbrackuend^G^mathord^^LEFT SQUARE BRACKET UPPER CORNER
023A2^⎢^^\lbrackextender^G^mathord^^LEFT SQUARE BRACKET EXTENSION
023A3^⎣^^\lbracklend^G^mathord^^LEFT SQUARE BRACKET LOWER CORNER
023A4^⎤^^\rbrackuend^G^mathord^^RIGHT SQUARE BRACKET UPPER CORNER
023A5^⎥^^\rbrackextender^G^mathord^^RIGHT SQUARE BRACKET EXTENSION
023A6^⎦^^\rbracklend^G^mathord^^RIGHT SQUARE BRACKET LOWER CORNER
023A7^⎧^^\lbraceuend^G^mathord^^LEFT CURLY BRACKET UPPER HOOK
023A8^⎨^^\lbracemid^G^mathord^^LEFT CURLY BRACKET MIDDLE PIECE
023A9^⎩^^\lbracelend^G^mathord^^LEFT CURLY BRACKET LOWER HOOK
023AA^⎪^^\vbraceextender^G^mathord^^CURLY BRACKET EXTENSION
023AB^⎫^^\rbraceuend^G^mathord^^RIGHT CURLY BRACKET UPPER HOOK
023AC^⎬^^\rbracemid^G^mathord^^RIGHT CURLY BRACKET MIDDLE PIECE
023AD^⎭^^\rbracelend^G^mathord^^RIGHT CURLY BRACKET LOWER HOOK
023AE^⎮^^\intextender^G^mathord^^INTEGRAL EXTENSION
023AF^⎯^^\harrowextender^G^mathord^^HORIZONTAL LINE EXTENSION (used to extend arrows)
023B0^⎰^^\lmoustache^R^mathord^^? \lmoustache, UPPER LEFT OR LOWER RIGHT CURLY BRACKET SECTION
023B1^⎱^^\rmoustache^R^mathord^^? \rmoustache, UPPER RIGHT OR LOWER LEFT CURLY BRACKET SECTION
023B2^⎲^^\sumtop^G^mathord^^SUMMATION TOP
023B3^⎳^^\sumbottom^G^mathord^^SUMMATION BOTTOM
023B4^⎴^^\overbracket^N^mathover^^TOP SQUARE BRACKET
023B5^⎵^^\underbracket^N^mathunder^^BOTTOM SQUARE BRACKET
023B6^⎶^^\bbrktbrk^N^mathord^^BOTTOM SQUARE BRACKET OVER TOP SQUARE BRACKET
023B7^⎷^^\sqrtbottom^G^mathord^^RADICAL SYMBOL BOTTOM
023B8^⎸^^\lvboxline^^mathord^^LEFT VERTICAL BOX LINE
023B9^⎹^^\rvboxline^^mathord^^RIGHT VERTICAL BOX LINE
023CE^⏎^^\varcarriagereturn^^mathord^^RETURN SYMBOL
023D0^⏐^^^G^mathord^^VERTICAL LINE EXTENSION (VERTICAL LINE EXTENSION)
023DC^⏜^\overparen^\overparen^N^mathover^wrisym^= \wideparen (yhmath mathabx fourier), TOP PARENTHESIS (mathematical use)
023DD^⏝^\underparen^\underparen^N^mathunder^wrisym^BOTTOM PARENTHESIS (mathematical use)
023DE^⏞^\overbrace^\overbrace^N^mathover^^TOP CURLY BRACKET (mathematical use)
023DF^⏟^\underbrace^\underbrace^N^mathunder^^BOTTOM CURLY BRACKET (mathematical use)
023E0^⏠^^\obrbrak^N^mathord^^TOP TORTOISE SHELL BRACKET (mathematical use)
023E1^⏡^^\ubrbrak^N^mathord^^BOTTOM TORTOISE SHELL BRACKET (mathematical use)
023E2^⏢^^\trapezium^N^mathord^^WHITE TRAPEZIUM
023E3^⏣^^\benzenr^N^mathord^^BENZENE RING WITH CIRCLE
023E4^⏤^^\strns^N^mathord^^STRAIGHTNESS
023E5^⏥^^\fltns^N^mathord^^FLATNESS
023E6^⏦^^\accurrent^N^mathord^^# \AC (wasysym), AC CURRENT
023E7^⏧^^\elinters^N^mathord^^ELECTRICAL INTERSECTION
024C8^Ⓢ^^^N^mathord^^oS capital S in circle
02506^┆^^\bdtriplevdash^^mathord^^doubly broken vert
02580^▀^^\blockuphalf^^mathord^^UPPER HALF BLOCK
02584^▄^^\blocklowhalf^^mathord^^LOWER HALF BLOCK
02588^█^^\blockfull^^mathord^^FULL BLOCK
0258C^▌^^\blocklefthalf^^mathord^^LEFT HALF BLOCK
02590^▐^^\blockrighthalf^^mathord^^RIGHT HALF BLOCK
02591^░^^\blockqtrshaded^^mathord^^25\% shaded block
02592^▒^^\blockhalfshaded^^mathord^^50\% shaded block
02593^▓^^\blockthreeqtrshaded^^mathord^^75\% shaded block
025A0^■^^\mdlgblksquare^N^mathord^^square, filled
025A1^□^^\mdlgwhtsquare^N^mathord^^square, open
025A2^▢^^\squoval^^mathord^^WHITE SQUARE WITH ROUNDED CORNERS
025A3^▣^^\blackinwhitesquare^^mathord^^WHITE SQUARE CONTAINING BLACK SMALL SQUARE
025A4^▤^^\squarehfill^^mathord^^square, horizontal rule filled
025A5^▥^^\squarevfill^^mathord^^square, vertical rule filled
025A6^▦^^\squarehvfill^^mathord^^SQUARE WITH ORTHOGONAL CROSSHATCH FILL
025A7^▧^^\squarenwsefill^^mathord^^square, nw-to-se rule filled
025A8^▨^^\squareneswfill^^mathord^^square, ne-to-sw rule filled
025A9^▩^^\squarecrossfill^^mathord^^SQUARE WITH DIAGONAL CROSSHATCH FILL
025AA^▪^^\smblksquare^N^mathord^^sq bullet, filled
025AB^▫^^\smwhtsquare^N^mathord^^WHITE SMALL SQUARE
025AC^▬^^\hrectangleblack^^mathord^^BLACK RECTANGLE
025AD^▭^^\hrectangle^N^mathord^^horizontal rectangle, open
025AE^▮^^\vrectangleblack^N^mathord^^BLACK VERTICAL RECTANGLE
025AF^▯^^\vrectangle^N^mathord^^rectangle, white (vertical)
025B0^▰^^\parallelogramblack^^mathord^^BLACK PARALLELOGRAM
025B1^▱^^\parallelogram^N^mathord^^parallelogram, open
025B2^▲^^\bigblacktriangleup^B^mathord^^BLACK UP-POINTING TRIANGLE
025B3^△^\bigtriangleup^\bigtriangleup^B^mathbin^-stmaryrd^= \triangle (amsfonts), # \vartriangle (amssymb), big up triangle, open
025B4^▴^\blacktriangleup^\blacktriangle^B^mathbin^mathabx^up triangle, filled
025B5^▵^\smalltriangleup^\vartriangle^B^mathbin^mathabx^# \vartriangle (amssymb), small up triangle, open
025B6^▶^\RHD^\blacktriangleright^B^mathbin^wasysym^= \blacktriangleright (fourier -mathabx), (large) right triangle, filled
025B7^▷^\rhd^\triangleright^B^mathbin^amssymb wasysym^= \rres (oz), = \RightTriangle (wrisym), (large) right triangle, open; z notation range restriction
025B8^▸^\blacktriangleright^\smallblacktriangleright^B^mathbin^mathabx -fourier^right triangle, filled
025B9^▹^\smalltriangleright^\smalltriangleright^B^mathbin^mathabx^# \triangleright, x \triangleright (mathabx), right triangle, open
025BA^►^^\blackpointerright^^mathord^^BLACK RIGHT-POINTING POINTER
025BB^▻^^\whitepointerright^^mathord^^# \triangleright (mathabx), WHITE RIGHT-POINTING POINTER
025BC^▼^^\bigblacktriangledown^B^mathord^^big down triangle, filled
025BD^▽^\bigtriangledown^\bigtriangledown^B^mathbin^-stmaryrd^big down triangle, open
025BE^▾^\blacktriangledown^\blacktriangledown^B^mathbin^mathabx^BLACK DOWN-POINTING SMALL TRIANGLE
025BF^▿^\smalltriangledown^\triangledown^B^mathbin^mathabx^# \triangledown (amssymb), WHITE DOWN-POINTING SMALL TRIANGLE
025C0^◀^\LHD^\blacktriangleleft^B^mathbin^wasysym^= \blacktriangleleft (fourier -mathabx), (large) left triangle, filled
025C1^◁^\lhd^\triangleleft^B^mathbin^amssymb wasysym^= \dres (oz), = \LeftTriangle (wrisym), (large) left triangle, open; z notation domain restriction
025C2^◂^\blacktriangleleft^\smallblacktriangleleft^B^mathbin^mathabx -fourier^left triangle, filled
025C3^◃^\smalltriangleleft^\smalltriangleleft^B^mathbin^mathabx^# \triangleleft, x \triangleleft (mathabx), left triangle, open
025C4^◄^^\blackpointerleft^B^mathord^^BLACK LEFT-POINTING POINTER
025C5^◅^^\whitepointerleft^B^mathord^^# \triangleleft (mathabx), WHITE LEFT-POINTING POINTER
025C6^◆^\Diamondblack^\mdlgblkdiamond^N^mathord^txfonts^BLACK DIAMOND
025C7^◇^\Diamond^\mdlgwhtdiamond^N^mathord^amssymb^WHITE DIAMOND; diamond, open
025C8^◈^^\blackinwhitediamond^N^mathord^^WHITE DIAMOND CONTAINING BLACK SMALL DIAMOND
025C9^◉^^\fisheye^N^mathord^^FISHEYE
025CA^◊^\lozenge^\mdlgwhtlozenge^B^mathord^amssymb^LOZENGE or total mark
025CB^○^\Circle^\mdlgwhtcircle^B^mathbin^wasysym^medium large circle
025CC^◌^^\dottedcircle^^mathord^^DOTTED CIRCLE
025CD^◍^^\circlevertfill^^mathord^^CIRCLE WITH VERTICAL FILL
025CE^◎^^\bullseye^N^mathord^^# \circledcirc (amssymb), BULLSEYE
025CF^●^\CIRCLE^\mdlgblkcircle^N^mathord^wasysym^circle, filled
025D0^◐^\LEFTcircle^\circlelefthalfblack^^mathord^wasysym^circle, filled left half [harvey ball]
025D1^◑^\RIGHTcircle^\circlerighthalfblack^^mathord^wasysym^circle, filled right half
025D2^◒^^\circlebottomhalfblack^^mathord^^circle, filled bottom half
025D3^◓^^\circletophalfblack^^mathord^^circle, filled top half
025D4^◔^^\circleurquadblack^^mathord^^CIRCLE WITH UPPER RIGHT QUADRANT BLACK
025D5^◕^^\blackcircleulquadwhite^^mathord^^CIRCLE WITH ALL BUT UPPER LEFT QUADRANT BLACK
025D6^◖^\LEFTCIRCLE^\blacklefthalfcircle^N^mathord^wasysym^LEFT HALF BLACK CIRCLE
025D7^◗^\RIGHTCIRCLE^\blackrighthalfcircle^N^mathord^wasysym^RIGHT HALF BLACK CIRCLE
025D8^◘^^\inversebullet^^mathord^^INVERSE BULLET
025D9^◙^^\inversewhitecircle^^mathord^^INVERSE WHITE CIRCLE
025DA^◚^^\invwhiteupperhalfcircle^^mathord^^UPPER HALF INVERSE WHITE CIRCLE
025DB^◛^^\invwhitelowerhalfcircle^^mathord^^LOWER HALF INVERSE WHITE CIRCLE
025DC^◜^^\ularc^^mathord^^UPPER LEFT QUADRANT CIRCULAR ARC
025DD^◝^^\urarc^^mathord^^UPPER RIGHT QUADRANT CIRCULAR ARC
025DE^◞^^\lrarc^^mathord^^LOWER RIGHT QUADRANT CIRCULAR ARC
025DF^◟^^\llarc^^mathord^^LOWER LEFT QUADRANT CIRCULAR ARC
025E0^◠^^\topsemicircle^^mathord^^UPPER HALF CIRCLE
025E1^◡^^\botsemicircle^^mathord^^LOWER HALF CIRCLE
025E2^◢^^\lrblacktriangle^N^mathord^^lower right triangle, filled
025E3^◣^^\llblacktriangle^N^mathord^^lower left triangle, filled
025E4^◤^^\ulblacktriangle^N^mathord^^upper left triangle, filled
025E5^◥^^\urblacktriangle^N^mathord^^upper right triangle, filled
025E6^◦^^\smwhtcircle^B^mathord^^WHITE BULLET
025E7^◧^^\squareleftblack^^mathord^^square, filled left half
025E8^◨^^\squarerightblack^^mathord^^square, filled right half
025E9^◩^^\squareulblack^^mathord^^square, filled top left corner
025EA^◪^^\squarelrblack^^mathord^^square, filled bottom right corner
025EB^◫^\boxbar^\boxbar^B^mathbin^stmaryrd txfonts^vertical bar in box
025EC^◬^^\trianglecdot^B^mathord^^triangle with centered dot
025ED^◭^^\triangleleftblack^^mathord^^UP-POINTING TRIANGLE WITH LEFT HALF BLACK
025EE^◮^^\trianglerightblack^^mathord^^UP-POINTING TRIANGLE WITH RIGHT HALF BLACK
025EF^◯^^\lgwhtcircle^N^mathord^^LARGE CIRCLE
025F0^◰^^\squareulquad^^mathord^^WHITE SQUARE WITH UPPER LEFT QUADRANT
025F1^◱^^\squarellquad^^mathord^^WHITE SQUARE WITH LOWER LEFT QUADRANT
025F2^◲^^\squarelrquad^^mathord^^WHITE SQUARE WITH LOWER RIGHT QUADRANT
025F3^◳^^\squareurquad^^mathord^^WHITE SQUARE WITH UPPER RIGHT QUADRANT
025F4^◴^^\circleulquad^^mathord^^WHITE CIRCLE WITH UPPER LEFT QUADRANT
025F5^◵^^\circlellquad^^mathord^^WHITE CIRCLE WITH LOWER LEFT QUADRANT
025F6^◶^^\circlelrquad^^mathord^^WHITE CIRCLE WITH LOWER RIGHT QUADRANT
025F7^◷^^\circleurquad^^mathord^^WHITE CIRCLE WITH UPPER RIGHT QUADRANT
025F8^◸^^\ultriangle^B^mathord^^UPPER LEFT TRIANGLE
025F9^◹^^\urtriangle^B^mathord^^UPPER RIGHT TRIANGLE
025FA^◺^^\lltriangle^B^mathord^^LOWER LEFT TRIANGLE
025FB^◻^\square^\mdwhtsquare^B^mathord^amssymb -fourier^WHITE MEDIUM SQUARE
025FC^◼^\blacksquare^\mdblksquare^B^mathord^amssymb -fourier^BLACK MEDIUM SQUARE
025FD^◽^^\mdsmwhtsquare^B^mathord^^WHITE MEDIUM SMALL SQUARE
025FE^◾^^\mdsmblksquare^B^mathord^^BLACK MEDIUM SMALL SQUARE
025FF^◿^^\lrtriangle^B^mathord^^LOWER RIGHT TRIANGLE
02605^★^\bigstar^\bigstar^B^mathord^amssymb^star, filled
02606^☆^^\bigwhitestar^B^mathord^^star, open
02609^☉^\Sun^\astrosun^N^mathord^mathabx^SUN
0260C^☌^^^N^mathord^wasysym^text \CONJUNCTION (wasysym), CONJUNCTION
02610^☐^\Square^^^mathord^wasysym^BALLOT BOX
02611^☑^\CheckedBox^^^mathord^wasysym^t \Checkedbox (marvosym), BALLOT BOX WITH CHECK
02612^☒^\XBox^^N^mathord^wasysym^t \Crossedbox (marvosym), BALLOT BOX WITH X
02615^☕^\steaming^^^mathord^arevmath^HOT BEVERAGE
0261E^☞^\pointright^^^mathord^arevmath^WHITE RIGHT POINTING INDEX
02620^☠^\skull^^^mathord^arevmath^SKULL AND CROSSBONES
02621^☡^^\danger^^mathord^^CAUTION SIGN, dangerous bend
02622^☢^\radiation^^^mathord^arevmath^RADIOACTIVE SIGN
02623^☣^\biohazard^^^mathord^arevmath^BIOHAZARD SIGN
0262F^☯^\yinyang^^^mathord^arevmath^YIN YANG
02639^☹^\frownie^^^mathord^wasysym^= \sadface (arevmath), WHITE FROWNING FACE
0263A^☺^\smiley^^^mathord^wasysym^= \smileface (arevmath), WHITE SMILING FACE
0263B^☻^\blacksmiley^\blacksmiley^^mathord^wasysym^= \invsmileface (arevmath), BLACK SMILING FACE
0263C^☼^\sun^\sun^^mathord^wasysym^WHITE SUN WITH RAYS
0263D^☽^\rightmoon^\rightmoon^N^mathord^wasysym mathabx^FIRST QUARTER MOON
0263E^☾^\leftmoon^\leftmoon^N^mathord^wasysym mathabx^LAST QUARTER MOON
0263F^☿^\mercury^^N^mathord^wasysym^= \Mercury (mathabx), MERCURY
02640^♀^\female^\female^N^mathord^wasysym^= \Venus (mathabx), = \girl (mathabx), venus, female
02641^♁^\earth^^N^mathord^wasysym^= \varEarth (mathabx), EARTH
02642^♂^\male^\male^N^mathord^wasysym^= \Mars (mathabx), = \boy (mathabx), mars, male
02643^♃^\jupiter^^N^mathord^wasysym^= \Jupiter (mathabx), JUPITER
02644^♄^\saturn^^N^mathord^wasysym^= \Saturn (mathabx), SATURN
02645^♅^\uranus^^^mathord^wasysym^= \Uranus (mathabx), URANUS
02646^♆^\neptune^^N^mathord^wasysym^= \Neptune (mathabx), NEPTUNE
02647^♇^\pluto^^N^mathord^wasysym^= \Pluto (mathabx), PLUTO
02648^♈^\aries^^N^mathord^wasysym^= \Aries (mathabx), ARIES
02649^♉^\taurus^^N^mathord^wasysym^= \Taurus (mathabx), TAURUS
0264A^♊^\gemini^^^mathord^wasysym^= \Gemini (mathabx), GEMINI
0264B^♋^\cancer^^^mathord^wasysym^CANCER
0264C^♌^\leo^^^mathord^wasysym^= \Leo (mathabx), LEO
0264D^♍^\virgo^^^mathord^wasysym^VIRGO
0264E^♎^\libra^^^mathord^wasysym^= \Libra (mathabx), LIBRA
0264F^♏^\scorpio^^^mathord^wasysym^= \Scorpio (mathabx), SCORPIUS
02650^♐^\sagittarius^^^mathord^wasysym^SAGITTARIUS
02651^♑^\capricornus^^^mathord^wasysym^CAPRICORN
02652^♒^\aquarius^^^mathord^wasysym^AQUARIUS
02653^♓^\pisces^^^mathord^wasysym^PISCES
02660^♠^\spadesuit^\spadesuit^N^mathord^^spades suit symbol
02661^♡^\heartsuit^\heartsuit^N^mathord^^heart suit symbol
02662^♢^\diamondsuit^\diamondsuit^N^mathord^^diamond suit symbol
02663^♣^\clubsuit^\clubsuit^N^mathord^^club suit symbol
02664^♤^\varspadesuit^\varspadesuit^N^mathord^txfonts^= \varspade (arevmath), spade, white (card suit)
02665^♥^\varheartsuit^\varheartsuit^N^mathord^txfonts^= \varheart (arevmath), filled heart (card suit)
02666^♦^\vardiamondsuit^\vardiamondsuit^N^mathord^txfonts^= \vardiamond (arevmath), filled diamond (card suit)
02667^♧^\varclubsuit^\varclubsuit^N^mathord^txfonts^= \varclub (arevmath), club, white (card suit)
02669^♩^\quarternote^\quarternote^N^mathord^arevmath wasysym^music note (sung text sign)
0266A^♪^\eighthnote^\eighthnote^^mathord^arevmath^EIGHTH NOTE
0266B^♫^\twonotes^\twonotes^^mathord^wasysym^BEAMED EIGHTH NOTES
0266C^♬^\sixteenthnote^^^mathord^arevmath^BEAMED SIXTEENTH NOTES
0266D^♭^\flat^\flat^N^mathord^^musical flat
0266E^♮^\natural^\natural^N^mathord^^music natural
0266F^♯^\sharp^\sharp^N^mathord^^# \# (oz), musical sharp, z notation infix bag count
0267B^♻^\recycle^^^mathord^arevmath^BLACK UNIVERSAL RECYCLING SYMBOL
0267E^♾^^\acidfree^^mathord^^PERMANENT PAPER SIGN
02680^⚀^^\dicei^N^mathord^^DIE FACE-1
02681^⚁^^\diceii^N^mathord^^DIE FACE-2
02682^⚂^^\diceiii^N^mathord^^DIE FACE-3
02683^⚃^^\diceiv^N^mathord^^DIE FACE-4
02684^⚄^^\dicev^N^mathord^^DIE FACE-5
02685^⚅^^\dicevi^N^mathord^^DIE FACE-6
02686^⚆^^\circledrightdot^N^mathord^^WHITE CIRCLE WITH DOT RIGHT
02687^⚇^^\circledtwodots^N^mathord^^WHITE CIRCLE WITH TWO DOTS
02688^⚈^^\blackcircledrightdot^N^mathord^^BLACK CIRCLE WITH WHITE DOT RIGHT
02689^⚉^^\blackcircledtwodots^N^mathord^^BLACK CIRCLE WITH TWO WHITE DOTS
02693^⚓^\anchor^^^mathord^arevmath^ANCHOR
02694^⚔^\swords^^^mathord^arevmath^CROSSED SWORDS
026A0^⚠^\warning^^^mathord^arevmath^WARNING SIGN
026A5^⚥^^\Hermaphrodite^^mathord^^MALE AND FEMALE SIGN
026AA^⚪^\medcirc^\mdwhtcircle^N^mathord^txfonts^MEDIUM WHITE CIRCLE
026AB^⚫^\medbullet^\mdblkcircle^N^mathord^txfonts^MEDIUM BLACK CIRCLE
026AC^⚬^^\mdsmwhtcircle^N^mathord^^MEDIUM SMALL WHITE CIRCLE
026B2^⚲^^\neuter^N^mathord^^NEUTER
0270E^✎^\pencil^^^mathord^arevmath^LOWER RIGHT PENCIL
02713^✓^\checkmark^\checkmark^N^mathord^amsfonts^= \ballotcheck (arevmath), tick, CHECK MARK
02717^✗^\ballotx^^^mathord^arevmath^BALLOT X
02720^✠^\maltese^\maltese^N^mathord^amsfonts^MALTESE CROSS
0272A^✪^^\circledstar^N^mathord^^CIRCLED WHITE STAR
02736^✶^^\varstar^N^mathord^^SIX POINTED BLACK STAR
0273D^✽^^\dingasterisk^^mathord^^HEAVY TEARDROP-SPOKED ASTERISK
02772^❲^^\lbrbrak^O^mathopen^^LIGHT LEFT TORTOISE SHELL BRACKET ORNAMENT
02773^❳^^\rbrbrak^C^mathclose^^LIGHT RIGHT TORTOISE SHELL BRACKET ORNAMENT
0279B^➛^^\draftingarrow^^mathord^^right arrow with bold head (drafting)
027A2^➢^\arrowbullet^^^mathord^arevmath^THREE-D TOP-LIGHTED RIGHTWARDS ARROWHEAD
027C0^⟀^^\threedangle^N^mathord^^THREE DIMENSIONAL ANGLE
027C1^⟁^^\whiteinwhitetriangle^N^mathord^^WHITE TRIANGLE CONTAINING SMALL WHITE TRIANGLE
027C2^⟂^\perp^\perp^R^mathrel^^PERPENDICULAR
027C3^⟃^^\subsetcirc^R^mathord^^OPEN SUBSET
027C4^⟄^^\supsetcirc^R^mathord^^OPEN SUPERSET
027C5^⟅^\Lbag^\lbag^R^mathopen^stmaryrd txfonts^= \lbag (stmaryrd -oz), LEFT S-SHAPED BAG DELIMITER
027C6^⟆^\Rbag^\rbag^R^mathclose^stmaryrd txfonts^= \rbag (stmaryrd -oz), RIGHT S-SHAPED BAG DELIMITER
027C7^⟇^^\veedot^R^mathbin^^OR WITH DOT INSIDE
027C8^⟈^^\bsolhsub^R^mathrel^^REVERSE SOLIDUS PRECEDING SUBSET
027C9^⟉^^\suphsol^R^mathrel^^SUPERSET PRECEDING SOLIDUS
027CC^⟌^^\longdivision^^mathopen^^LONG DIVISION
027D0^⟐^\Diamonddot^\diamondcdot^N^mathord^txfonts^WHITE DIAMOND WITH CENTRED DOT
027D1^⟑^^\wedgedot^B^mathbin^^AND WITH DOT
027D2^⟒^^\upin^R^mathrel^^ELEMENT OF OPENING UPWARDS
027D3^⟓^^\pullback^R^mathrel^^LOWER RIGHT CORNER WITH DOT
027D4^⟔^^\pushout^R^mathrel^^UPPER LEFT CORNER WITH DOT
027D5^⟕^^\leftouterjoin^L^mathop^^LEFT OUTER JOIN
027D6^⟖^^\rightouterjoin^L^mathop^^RIGHT OUTER JOIN
027D7^⟗^^\fullouterjoin^L^mathop^^FULL OUTER JOIN
027D8^⟘^^\bigbot^L^mathop^^LARGE UP TACK
027D9^⟙^^\bigtop^L^mathop^^LARGE DOWN TACK
027DA^⟚^^\DashVDash^R^mathrel^^LEFT AND RIGHT DOUBLE TURNSTILE
027DB^⟛^^\dashVdash^R^mathrel^^LEFT AND RIGHT TACK
027DC^⟜^\multimapinv^\multimapinv^R^mathrel^txfonts^LEFT MULTIMAP
027DD^⟝^^\vlongdash^R^mathrel^^long left tack
027DE^⟞^^\longdashv^R^mathrel^^long right tack
027DF^⟟^^\cirbot^R^mathrel^^UP TACK WITH CIRCLE ABOVE
027E0^⟠^^\lozengeminus^B^mathbin^^LOZENGE DIVIDED BY HORIZONTAL RULE
027E1^⟡^^\concavediamond^B^mathbin^^WHITE CONCAVE-SIDED DIAMOND
027E2^⟢^^\concavediamondtickleft^B^mathbin^^WHITE CONCAVE-SIDED DIAMOND WITH LEFTWARDS TICK
027E3^⟣^^\concavediamondtickright^B^mathbin^^WHITE CONCAVE-SIDED DIAMOND WITH RIGHTWARDS TICK
027E4^⟤^^\whitesquaretickleft^B^mathbin^^WHITE SQUARE WITH LEFTWARDS TICK
027E5^⟥^^\whitesquaretickright^B^mathbin^^WHITE SQUARE WITH RIGHTWARDS TICK
027E6^⟦^\llbracket^\lBrack^O^mathopen^stmaryrd wrisym kpfonts fourier^= \Lbrack (mathbbol), = \lbag (oz -stmaryrd), MATHEMATICAL LEFT WHITE SQUARE BRACKET
027E7^⟧^\rrbracket^\rBrack^C^mathclose^stmaryrd wrisym kpfonts fourier^= \Rbrack (mathbbol), = \rbag (oz -stmaryrd), MATHEMATICAL RIGHT WHITE SQUARE BRACKET
027E8^⟨^\langle^\langle^O^mathopen^^MATHEMATICAL LEFT ANGLE BRACKET
027E9^⟩^\rangle^\rangle^C^mathclose^^MATHEMATICAL RIGHT ANGLE BRACKET
027EA^⟪^\lang^\lAngle^O^mathopen^oz^MATHEMATICAL LEFT DOUBLE ANGLE BRACKET, z notation left chevron bracket
027EB^⟫^\rang^\rAngle^C^mathclose^oz^MATHEMATICAL RIGHT DOUBLE ANGLE BRACKET, z notation right chevron bracket
027EC^⟬^^\Lbrbrak^O^mathopen^^MATHEMATICAL LEFT WHITE TORTOISE SHELL BRACKET
027ED^⟭^^\Rbrbrak^C^mathclose^^MATHEMATICAL RIGHT WHITE TORTOISE SHELL BRACKET
027EE^⟮^\lgroup^^O^mathopen^^MATHEMATICAL LEFT FLATTENED PARENTHESIS
027EF^⟯^\rgroup^^C^mathclose^^MATHEMATICAL RIGHT FLATTENED PARENTHESIS
027F0^⟰^^\UUparrow^R^mathrel^^UPWARDS QUADRUPLE ARROW
027F1^⟱^^\DDownarrow^R^mathrel^^DOWNWARDS QUADRUPLE ARROW
027F2^⟲^^\acwgapcirclearrow^R^mathrel^^ANTICLOCKWISE GAPPED CIRCLE ARROW
027F3^⟳^^\cwgapcirclearrow^R^mathrel^^CLOCKWISE GAPPED CIRCLE ARROW
027F4^⟴^^\rightarrowonoplus^R^mathrel^^RIGHT ARROW WITH CIRCLED PLUS
027F5^⟵^\longleftarrow^\longleftarrow^R^mathrel^^LONG LEFTWARDS ARROW
027F6^⟶^\longrightarrow^\longrightarrow^R^mathrel^^LONG RIGHTWARDS ARROW
027F7^⟷^\longleftrightarrow^\longleftrightarrow^R^mathrel^^LONG LEFT RIGHT ARROW
027F8^⟸^\Longleftarrow^\Longleftarrow^R^mathrel^^= \impliedby (amsmath), LONG LEFTWARDS DOUBLE ARROW
027F9^⟹^\Longrightarrow^\Longrightarrow^R^mathrel^^= \implies (amsmath), LONG RIGHTWARDS DOUBLE ARROW
027FA^⟺^\Longleftrightarrow^\Longleftrightarrow^R^mathrel^^= \iff (oz), LONG LEFT RIGHT DOUBLE ARROW
027FB^⟻^\longmapsfrom^\longmapsfrom^R^mathrel^stmaryrd^= \longmappedfrom (kpfonts), LONG LEFTWARDS ARROW FROM BAR
027FC^⟼^\longmapsto^\longmapsto^R^mathrel^^LONG RIGHTWARDS ARROW FROM BAR
027FD^⟽^\Longmapsfrom^\Longmapsfrom^R^mathrel^stmaryrd^= \Longmappedfrom (kpfonts), LONG LEFTWARDS DOUBLE ARROW FROM BAR
027FE^⟾^\Longmapsto^\Longmapsto^R^mathrel^stmaryrd^LONG RIGHTWARDS DOUBLE ARROW FROM BAR
027FF^⟿^^\longrightsquigarrow^R^mathrel^^LONG RIGHTWARDS SQUIGGLE ARROW
02900^⤀^\psur^\nvtwoheadrightarrow^R^mathrel^oz^= \psurj (oz), RIGHTWARDS TWO-HEADED ARROW WITH VERTICAL STROKE, z notation partial surjection
02901^⤁^^\nVtwoheadrightarrow^R^mathrel^^RIGHTWARDS TWO-HEADED ARROW WITH DOUBLE VERTICAL STROKE, z notation finite surjection
02902^⤂^^\nvLeftarrow^R^mathrel^^LEFTWARDS DOUBLE ARROW WITH VERTICAL STROKE
02903^⤃^^\nvRightarrow^R^mathrel^^RIGHTWARDS DOUBLE ARROW WITH VERTICAL STROKE
02904^⤄^^\nvLeftrightarrow^R^mathrel^^LEFT RIGHT DOUBLE ARROW WITH VERTICAL STROKE
02905^⤅^^\twoheadmapsto^R^mathrel^^RIGHTWARDS TWO-HEADED ARROW FROM BAR
02906^⤆^\Mapsfrom^\Mapsfrom^R^mathrel^stmaryrd^= \Mappedfrom (kpfonts), LEFTWARDS DOUBLE ARROW FROM BAR
02907^⤇^\Mapsto^\Mapsto^R^mathrel^stmaryrd^RIGHTWARDS DOUBLE ARROW FROM BAR
02908^⤈^^\downarrowbarred^R^mathrel^^DOWNWARDS ARROW WITH HORIZONTAL STROKE
02909^⤉^^\uparrowbarred^R^mathrel^^UPWARDS ARROW WITH HORIZONTAL STROKE
0290A^⤊^^\Uuparrow^R^mathrel^^UPWARDS TRIPLE ARROW
0290B^⤋^^\Ddownarrow^R^mathrel^^DOWNWARDS TRIPLE ARROW
0290C^⤌^^\leftbkarrow^R^mathrel^^LEFTWARDS DOUBLE DASH ARROW
0290D^⤍^^\rightbkarrow^R^mathrel^^RIGHTWARDS DOUBLE DASH ARROW
0290E^⤎^^\leftdbkarrow^R^mathrel^^LEFTWARDS TRIPLE DASH ARROW
0290F^⤏^^\dbkarow^R^mathrel^^RIGHTWARDS TRIPLE DASH ARROW
02910^⤐^^\drbkarow^R^mathrel^^RIGHTWARDS TWO-HEADED TRIPLE DASH ARROW
02911^⤑^^\rightdotarrow^R^mathrel^^RIGHTWARDS ARROW WITH DOTTED STEM
02912^⤒^\UpArrowBar^\baruparrow^R^mathrel^wrisym^UPWARDS ARROW TO BAR
02913^⤓^\DownArrowBar^\downarrowbar^R^mathrel^wrisym^DOWNWARDS ARROW TO BAR
02914^⤔^\pinj^\nvrightarrowtail^R^mathrel^oz^RIGHTWARDS ARROW WITH TAIL WITH VERTICAL STROKE, z notation partial injection
02915^⤕^\finj^\nVrightarrowtail^R^mathrel^oz^RIGHTWARDS ARROW WITH TAIL WITH DOUBLE VERTICAL STROKE, z notation finite injection
02916^⤖^\bij^\twoheadrightarrowtail^R^mathrel^oz^RIGHTWARDS TWO-HEADED ARROW WITH TAIL, z notation bijection
02917^⤗^^\nvtwoheadrightarrowtail^R^mathrel^^RIGHTWARDS TWO-HEADED ARROW WITH TAIL WITH VERTICAL STROKE, z notation surjective injection
02918^⤘^^\nVtwoheadrightarrowtail^R^mathrel^^RIGHTWARDS TWO-HEADED ARROW WITH TAIL WITH DOUBLE VERTICAL STROKE, z notation finite surjective injection
02919^⤙^^\lefttail^R^mathrel^^LEFTWARDS ARROW-TAIL
0291A^⤚^^\righttail^R^mathrel^^RIGHTWARDS ARROW-TAIL
0291B^⤛^^\leftdbltail^R^mathrel^^LEFTWARDS DOUBLE ARROW-TAIL
0291C^⤜^^\rightdbltail^R^mathrel^^RIGHTWARDS DOUBLE ARROW-TAIL
0291D^⤝^^\diamondleftarrow^R^mathrel^^LEFTWARDS ARROW TO BLACK DIAMOND
0291E^⤞^^\rightarrowdiamond^R^mathrel^^RIGHTWARDS ARROW TO BLACK DIAMOND
0291F^⤟^^\diamondleftarrowbar^R^mathrel^^LEFTWARDS ARROW FROM BAR TO BLACK DIAMOND
02920^⤠^^\barrightarrowdiamond^R^mathrel^^RIGHTWARDS ARROW FROM BAR TO BLACK DIAMOND
02921^⤡^^\nwsearrow^R^mathrel^^NORTH WEST AND SOUTH EAST ARROW
02922^⤢^^\neswarrow^R^mathrel^^NORTH EAST AND SOUTH WEST ARROW
02923^⤣^^\hknwarrow^R^mathrel^^NORTH WEST ARROW WITH HOOK
02924^⤤^^\hknearrow^R^mathrel^^NORTH EAST ARROW WITH HOOK
02925^⤥^^\hksearow^R^mathrel^^SOUTH EAST ARROW WITH HOOK
02926^⤦^^\hkswarow^R^mathrel^^SOUTH WEST ARROW WITH HOOK
02927^⤧^^\tona^R^mathrel^^NORTH WEST ARROW AND NORTH EAST ARROW
02928^⤨^^\toea^R^mathrel^^NORTH EAST ARROW AND SOUTH EAST ARROW
02929^⤩^^\tosa^R^mathrel^^SOUTH EAST ARROW AND SOUTH WEST ARROW
0292A^⤪^^\towa^R^mathrel^^SOUTH WEST ARROW AND NORTH WEST ARROW
0292B^⤫^^\rdiagovfdiag^R^mathord^^RISING DIAGONAL CROSSING FALLING DIAGONAL
0292C^⤬^^\fdiagovrdiag^R^mathord^^FALLING DIAGONAL CROSSING RISING DIAGONAL
0292D^⤭^^\seovnearrow^R^mathord^^SOUTH EAST ARROW CROSSING NORTH EAST ARROW
0292E^⤮^^\neovsearrow^R^mathord^^NORTH EAST ARROW CROSSING SOUTH EAST ARROW
0292F^⤯^^\fdiagovnearrow^R^mathord^^FALLING DIAGONAL CROSSING NORTH EAST ARROW
02930^⤰^^\rdiagovsearrow^R^mathord^^RISING DIAGONAL CROSSING SOUTH EAST ARROW
02931^⤱^^\neovnwarrow^R^mathord^^NORTH EAST ARROW CROSSING NORTH WEST ARROW
02932^⤲^^\nwovnearrow^R^mathord^^NORTH WEST ARROW CROSSING NORTH EAST ARROW
02933^⤳^\leadsto^\rightcurvedarrow^R^mathrel^txfonts^WAVE ARROW POINTING DIRECTLY RIGHT
02934^⤴^^\uprightcurvearrow^R^mathord^^ARROW POINTING RIGHTWARDS THEN CURVING UPWARDS
02935^⤵^^\downrightcurvedarrow^R^mathord^^ARROW POINTING RIGHTWARDS THEN CURVING DOWNWARDS
02936^⤶^^\leftdowncurvedarrow^R^mathrel^^ARROW POINTING DOWNWARDS THEN CURVING LEFTWARDS
02937^⤷^^\rightdowncurvedarrow^R^mathrel^^ARROW POINTING DOWNWARDS THEN CURVING RIGHTWARDS
02938^⤸^^\cwrightarcarrow^R^mathrel^^RIGHT-SIDE ARC CLOCKWISE ARROW
02939^⤹^^\acwleftarcarrow^R^mathrel^^LEFT-SIDE ARC ANTICLOCKWISE ARROW
0293A^⤺^^\acwoverarcarrow^R^mathrel^^TOP ARC ANTICLOCKWISE ARROW
0293B^⤻^^\acwunderarcarrow^R^mathrel^^BOTTOM ARC ANTICLOCKWISE ARROW
0293C^⤼^^\curvearrowrightminus^R^mathrel^^TOP ARC CLOCKWISE ARROW WITH MINUS
0293D^⤽^^\curvearrowleftplus^R^mathrel^^TOP ARC ANTICLOCKWISE ARROW WITH PLUS
0293E^⤾^^\cwundercurvearrow^R^mathrel^^LOWER RIGHT SEMICIRCULAR CLOCKWISE ARROW
0293F^⤿^^\ccwundercurvearrow^R^mathrel^^LOWER LEFT SEMICIRCULAR ANTICLOCKWISE ARROW
02940^⥀^^\acwcirclearrow^R^mathrel^^ANTICLOCKWISE CLOSED CIRCLE ARROW
02941^⥁^^\cwcirclearrow^R^mathrel^^CLOCKWISE CLOSED CIRCLE ARROW
02942^⥂^^\rightarrowshortleftarrow^R^mathrel^^RIGHTWARDS ARROW ABOVE SHORT LEFTWARDS ARROW
02943^⥃^^\leftarrowshortrightarrow^R^mathrel^^LEFTWARDS ARROW ABOVE SHORT RIGHTWARDS ARROW
02944^⥄^^\shortrightarrowleftarrow^R^mathrel^^SHORT RIGHTWARDS ARROW ABOVE LEFTWARDS ARROW
02945^⥅^^\rightarrowplus^R^mathrel^^RIGHTWARDS ARROW WITH PLUS BELOW
02946^⥆^^\leftarrowplus^R^mathrel^^LEFTWARDS ARROW WITH PLUS BELOW
02947^⥇^^\rightarrowx^R^mathrel^^RIGHTWARDS ARROW THROUGH X
02948^⥈^^\leftrightarrowcircle^R^mathrel^^LEFT RIGHT ARROW THROUGH SMALL CIRCLE
02949^⥉^^\twoheaduparrowcircle^R^mathrel^^UPWARDS TWO-HEADED ARROW FROM SMALL CIRCLE
0294A^⥊^\leftrightharpoon^\leftrightharpoonupdown^R^mathrel^mathabx^LEFT BARB UP RIGHT BARB DOWN HARPOON
0294B^⥋^\rightleftharpoon^\leftrightharpoondownup^R^mathrel^mathabx^LEFT BARB DOWN RIGHT BARB UP HARPOON
0294C^⥌^^\updownharpoonrightleft^R^mathrel^^UP BARB RIGHT DOWN BARB LEFT HARPOON
0294D^⥍^^\updownharpoonleftright^R^mathrel^^UP BARB LEFT DOWN BARB RIGHT HARPOON
0294E^⥎^\leftrightharpoonup^\leftrightharpoonupup^R^mathrel^wrisym^LEFT BARB UP RIGHT BARB UP HARPOON
0294F^⥏^\rightupdownharpoon^\updownharpoonrightright^R^mathrel^wrisym^UP BARB RIGHT DOWN BARB RIGHT HARPOON
02950^⥐^\leftrightharpoondown^\leftrightharpoondowndown^R^mathrel^wrisym^LEFT BARB DOWN RIGHT BARB DOWN HARPOON
02951^⥑^\leftupdownharpoon^\updownharpoonleftleft^R^mathrel^wrisym^UP BARB LEFT DOWN BARB LEFT HARPOON
02952^⥒^\LeftVectorBar^\barleftharpoonup^R^mathrel^wrisym^LEFTWARDS HARPOON WITH BARB UP TO BAR
02953^⥓^\RightVectorBar^\rightharpoonupbar^R^mathrel^wrisym^RIGHTWARDS HARPOON WITH BARB UP TO BAR
02954^⥔^\RightUpVectorBar^\barupharpoonright^R^mathrel^wrisym^UPWARDS HARPOON WITH BARB RIGHT TO BAR
02955^⥕^\RightDownVectorBar^\downharpoonrightbar^R^mathrel^wrisym^DOWNWARDS HARPOON WITH BARB RIGHT TO BAR
02956^⥖^\DownLeftVectorBar^\barleftharpoondown^R^mathrel^wrisym^LEFTWARDS HARPOON WITH BARB DOWN TO BAR
02957^⥗^\DownRightVectorBar^\rightharpoondownbar^R^mathrel^wrisym^RIGHTWARDS HARPOON WITH BARB DOWN TO BAR
02958^⥘^\LeftUpVectorBar^\barupharpoonleft^R^mathrel^wrisym^UPWARDS HARPOON WITH BARB LEFT TO BAR
02959^⥙^\LeftDownVectorBar^\downharpoonleftbar^R^mathrel^wrisym^DOWNWARDS HARPOON WITH BARB LEFT TO BAR
0295A^⥚^\LeftTeeVector^\leftharpoonupbar^R^mathrel^wrisym^LEFTWARDS HARPOON WITH BARB UP FROM BAR
0295B^⥛^\RightTeeVector^\barrightharpoonup^R^mathrel^wrisym^RIGHTWARDS HARPOON WITH BARB UP FROM BAR
0295C^⥜^\RightUpTeeVector^\upharpoonrightbar^R^mathrel^wrisym^UPWARDS HARPOON WITH BARB RIGHT FROM BAR
0295D^⥝^\RightDownTeeVector^\bardownharpoonright^R^mathrel^wrisym^DOWNWARDS HARPOON WITH BARB RIGHT FROM BAR
0295E^⥞^\DownLeftTeeVector^\leftharpoondownbar^R^mathrel^wrisym^LEFTWARDS HARPOON WITH BARB DOWN FROM BAR
0295F^⥟^\DownRightTeeVector^\barrightharpoondown^R^mathrel^wrisym^RIGHTWARDS HARPOON WITH BARB DOWN FROM BAR
02960^⥠^\LeftUpTeeVector^\upharpoonleftbar^R^mathrel^wrisym^UPWARDS HARPOON WITH BARB LEFT FROM BAR
02961^⥡^\LeftDownTeeVector^\bardownharpoonleft^R^mathrel^wrisym^DOWNWARDS HARPOON WITH BARB LEFT FROM BAR
02962^⥢^\leftleftharpoons^\leftharpoonsupdown^R^mathrel^mathabx^LEFTWARDS HARPOON WITH BARB UP ABOVE LEFTWARDS HARPOON WITH BARB DOWN
02963^⥣^\upupharpoons^\upharpoonsleftright^R^mathrel^mathabx^UPWARDS HARPOON WITH BARB LEFT BESIDE UPWARDS HARPOON WITH BARB RIGHT
02964^⥤^\rightrightharpoons^\rightharpoonsupdown^R^mathrel^mathabx^RIGHTWARDS HARPOON WITH BARB UP ABOVE RIGHTWARDS HARPOON WITH BARB DOWN
02965^⥥^\downdownharpoons^\downharpoonsleftright^R^mathrel^mathabx^DOWNWARDS HARPOON WITH BARB LEFT BESIDE DOWNWARDS HARPOON WITH BARB RIGHT
02966^⥦^^\leftrightharpoonsup^R^mathrel^^LEFTWARDS HARPOON WITH BARB UP ABOVE RIGHTWARDS HARPOON WITH BARB UP
02967^⥧^^\leftrightharpoonsdown^R^mathrel^^LEFTWARDS HARPOON WITH BARB DOWN ABOVE RIGHTWARDS HARPOON WITH BARB DOWN
02968^⥨^^\rightleftharpoonsup^R^mathrel^^RIGHTWARDS HARPOON WITH BARB UP ABOVE LEFTWARDS HARPOON WITH BARB UP
02969^⥩^^\rightleftharpoonsdown^R^mathrel^^RIGHTWARDS HARPOON WITH BARB DOWN ABOVE LEFTWARDS HARPOON WITH BARB DOWN
0296A^⥪^\leftbarharpoon^\leftharpoonupdash^R^mathrel^mathabx^LEFTWARDS HARPOON WITH BARB UP ABOVE LONG DASH
0296B^⥫^\barleftharpoon^\dashleftharpoondown^R^mathrel^mathabx^LEFTWARDS HARPOON WITH BARB DOWN BELOW LONG DASH
0296C^⥬^\rightbarharpoon^\rightharpoonupdash^R^mathrel^mathabx^RIGHTWARDS HARPOON WITH BARB UP ABOVE LONG DASH
0296D^⥭^\barrightharpoon^\dashrightharpoondown^R^mathrel^mathabx^RIGHTWARDS HARPOON WITH BARB DOWN BELOW LONG DASH
0296E^⥮^\updownharpoons^\updownharpoonsleftright^R^mathrel^mathabx^= \upequilibrium (wrisym), UPWARDS HARPOON WITH BARB LEFT BESIDE DOWNWARDS HARPOON WITH BARB RIGHT
0296F^⥯^\downupharpoons^\downupharpoonsleftright^R^mathrel^mathabx^= \uprevequilibrium (wrisym), DOWNWARDS HARPOON WITH BARB LEFT BESIDE UPWARDS HARPOON WITH BARB RIGHT
02970^⥰^^\rightimply^R^mathrel^^RIGHT DOUBLE ARROW WITH ROUNDED HEAD
02971^⥱^^\equalrightarrow^R^mathrel^^EQUALS SIGN ABOVE RIGHTWARDS ARROW
02972^⥲^^\similarrightarrow^R^mathrel^^TILDE OPERATOR ABOVE RIGHTWARDS ARROW
02973^⥳^^\leftarrowsimilar^R^mathrel^^LEFTWARDS ARROW ABOVE TILDE OPERATOR
02974^⥴^^\rightarrowsimilar^R^mathrel^^RIGHTWARDS ARROW ABOVE TILDE OPERATOR
02975^⥵^^\rightarrowapprox^R^mathrel^^RIGHTWARDS ARROW ABOVE ALMOST EQUAL TO
02976^⥶^^\ltlarr^R^mathrel^^LESS-THAN ABOVE LEFTWARDS ARROW
02977^⥷^^\leftarrowless^R^mathrel^^LEFTWARDS ARROW THROUGH LESS-THAN
02978^⥸^^\gtrarr^R^mathrel^^GREATER-THAN ABOVE RIGHTWARDS ARROW
02979^⥹^^\subrarr^R^mathrel^^SUBSET ABOVE RIGHTWARDS ARROW
0297A^⥺^^\leftarrowsubset^R^mathrel^^LEFTWARDS ARROW THROUGH SUBSET
0297B^⥻^^\suplarr^R^mathrel^^SUPERSET ABOVE LEFTWARDS ARROW
0297C^⥼^\strictfi^\leftfishtail^R^mathrel^txfonts^LEFT FISH TAIL
0297D^⥽^\strictif^\rightfishtail^R^mathrel^txfonts^RIGHT FISH TAIL
0297E^⥾^^\upfishtail^R^mathrel^^UP FISH TAIL
0297F^⥿^^\downfishtail^R^mathrel^^DOWN FISH TAIL
02980^⦀^\VERT^\Vvert^F^mathfence^fourier^TRIPLE VERTICAL BAR DELIMITER
02981^⦁^\spot^\mdsmblkcircle^N^mathord^oz^= \dot (oz), Z NOTATION SPOT
02982^⦂^^\typecolon^F^mathbin^^Z NOTATION TYPE COLON, (present in bbold font but no command)
02983^⦃^^\lBrace^O^mathopen^^LEFT WHITE CURLY BRACKET
02984^⦄^^\rBrace^C^mathclose^^RIGHT WHITE CURLY BRACKET
02985^⦅^\Lparen^\lParen^O^mathopen^mathbbol^LEFT WHITE PARENTHESIS
02986^⦆^\Rparen^\rParen^C^mathclose^mathbbol^RIGHT WHITE PARENTHESIS
02987^⦇^\limg^\llparenthesis^O^mathopen^oz^= \llparenthesis (stmaryrd), Z NOTATION LEFT IMAGE BRACKET
02988^⦈^\rimg^\rrparenthesis^C^mathclose^oz^= \rrparenthesis (stmaryrd), Z NOTATION RIGHT IMAGE BRACKET
02989^⦉^\lblot^\llangle^O^mathopen^oz^Z NOTATION LEFT BINDING BRACKET
0298A^⦊^\rblot^\rrangle^C^mathclose^oz^Z NOTATION RIGHT BINDING BRACKET
0298B^⦋^^\lbrackubar^O^mathopen^^LEFT SQUARE BRACKET WITH UNDERBAR
0298C^⦌^^\rbrackubar^C^mathclose^^RIGHT SQUARE BRACKET WITH UNDERBAR
0298D^⦍^^\lbrackultick^O^mathopen^^LEFT SQUARE BRACKET WITH TICK IN TOP CORNER
0298E^⦎^^\rbracklrtick^C^mathclose^^RIGHT SQUARE BRACKET WITH TICK IN BOTTOM CORNER
0298F^⦏^^\lbracklltick^O^mathopen^^LEFT SQUARE BRACKET WITH TICK IN BOTTOM CORNER
02990^⦐^^\rbrackurtick^C^mathclose^^RIGHT SQUARE BRACKET WITH TICK IN TOP CORNER
02991^⦑^^\langledot^O^mathopen^^LEFT ANGLE BRACKET WITH DOT
02992^⦒^^\rangledot^C^mathclose^^RIGHT ANGLE BRACKET WITH DOT
02993^⦓^^\lparenless^O^mathopen^^LEFT ARC LESS-THAN BRACKET
02994^⦔^^\rparengtr^C^mathclose^^RIGHT ARC GREATER-THAN BRACKET
02995^⦕^^\Lparengtr^O^mathopen^^DOUBLE LEFT ARC GREATER-THAN BRACKET
02996^⦖^^\Rparenless^C^mathclose^^DOUBLE RIGHT ARC LESS-THAN BRACKET
02997^⦗^^\lblkbrbrak^O^mathopen^^LEFT BLACK TORTOISE SHELL BRACKET
02998^⦘^^\rblkbrbrak^C^mathclose^^RIGHT BLACK TORTOISE SHELL BRACKET
02999^⦙^^\fourvdots^F^mathord^^DOTTED FENCE
0299A^⦚^^\vzigzag^F^mathord^^VERTICAL ZIGZAG LINE
0299B^⦛^^\measuredangleleft^N^mathord^^MEASURED ANGLE OPENING LEFT
0299C^⦜^^\rightanglesqr^N^mathord^^RIGHT ANGLE VARIANT WITH SQUARE
0299D^⦝^^\rightanglemdot^N^mathord^^MEASURED RIGHT ANGLE WITH DOT
0299E^⦞^^\angles^N^mathord^^ANGLE WITH S INSIDE
0299F^⦟^^\angdnr^N^mathord^^ACUTE ANGLE
029A0^⦠^^\gtlpar^N^mathord^^SPHERICAL ANGLE OPENING LEFT
029A1^⦡^^\sphericalangleup^N^mathord^^SPHERICAL ANGLE OPENING UP
029A2^⦢^^\turnangle^N^mathord^^TURNED ANGLE
029A3^⦣^^\revangle^N^mathord^^REVERSED ANGLE
029A4^⦤^^\angleubar^N^mathord^^ANGLE WITH UNDERBAR
029A5^⦥^^\revangleubar^N^mathord^^REVERSED ANGLE WITH UNDERBAR
029A6^⦦^^\wideangledown^N^mathord^^OBLIQUE ANGLE OPENING UP
029A7^⦧^^\wideangleup^N^mathord^^OBLIQUE ANGLE OPENING DOWN
029A8^⦨^^\measanglerutone^N^mathord^^MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING UP AND RIGHT
029A9^⦩^^\measanglelutonw^N^mathord^^MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING UP AND LEFT
029AA^⦪^^\measanglerdtose^N^mathord^^MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING DOWN AND RIGHT
029AB^⦫^^\measangleldtosw^N^mathord^^MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING DOWN AND LEFT
029AC^⦬^^\measangleurtone^N^mathord^^MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING RIGHT AND UP
029AD^⦭^^\measangleultonw^N^mathord^^MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING LEFT AND UP
029AE^⦮^^\measangledrtose^N^mathord^^MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING RIGHT AND DOWN
029AF^⦯^^\measangledltosw^N^mathord^^MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING LEFT AND DOWN
029B0^⦰^^\revemptyset^N^mathord^^REVERSED EMPTY SET
029B1^⦱^^\emptysetobar^N^mathord^^EMPTY SET WITH OVERBAR
029B2^⦲^^\emptysetocirc^N^mathord^^EMPTY SET WITH SMALL CIRCLE ABOVE
029B3^⦳^^\emptysetoarr^N^mathord^^EMPTY SET WITH RIGHT ARROW ABOVE
029B4^⦴^^\emptysetoarrl^N^mathord^^EMPTY SET WITH LEFT ARROW ABOVE
029B5^⦵^^\circlehbar^N^mathbin^^CIRCLE WITH HORIZONTAL BAR
029B6^⦶^^\circledvert^B^mathbin^^CIRCLED VERTICAL BAR
029B7^⦷^^\circledparallel^B^mathbin^^CIRCLED PARALLEL
029B8^⦸^\circledbslash^\obslash^B^mathbin^txfonts^CIRCLED REVERSE SOLIDUS
029B9^⦹^^\operp^B^mathbin^^CIRCLED PERPENDICULAR
029BA^⦺^^\obot^N^mathord^^CIRCLE DIVIDED BY HORIZONTAL BAR AND TOP HALF DIVIDED BY VERTICAL BAR
029BB^⦻^^\olcross^N^mathord^^CIRCLE WITH SUPERIMPOSED X
029BC^⦼^^\odotslashdot^N^mathord^^CIRCLED ANTICLOCKWISE-ROTATED DIVISION SIGN
029BD^⦽^^\uparrowoncircle^N^mathord^^UP ARROW THROUGH CIRCLE
029BE^⦾^^\circledwhitebullet^N^mathord^^CIRCLED WHITE BULLET
029BF^⦿^^\circledbullet^N^mathord^^CIRCLED BULLET
029C0^⧀^\circledless^\olessthan^B^mathbin^txfonts^CIRCLED LESS-THAN
029C1^⧁^\circledgtr^\ogreaterthan^B^mathbin^txfonts^CIRCLED GREATER-THAN
029C2^⧂^^\cirscir^N^mathord^^CIRCLE WITH SMALL CIRCLE TO THE RIGHT
029C3^⧃^^\cirE^N^mathord^^CIRCLE WITH TWO HORIZONTAL STROKES TO THE RIGHT
029C4^⧄^\boxslash^\boxdiag^B^mathbin^stmaryrd txfonts^SQUARED RISING DIAGONAL SLASH
029C5^⧅^\boxbslash^\boxbslash^B^mathbin^stmaryrd txfonts^SQUARED FALLING DIAGONAL SLASH
029C6^⧆^\boxast^\boxast^B^mathbin^stmaryrd txfonts^SQUARED ASTERISK
029C7^⧇^\boxcircle^\boxcircle^B^mathbin^stmaryrd^SQUARED SMALL CIRCLE
029C8^⧈^\boxbox^\boxbox^B^mathbin^stmaryrd^SQUARED SQUARE
029C9^⧉^^\boxonbox^N^mathord^^TWO JOINED SQUARES
029CA^⧊^^\triangleodot^N^mathord^^TRIANGLE WITH DOT ABOVE
029CB^⧋^^\triangleubar^N^mathord^^TRIANGLE WITH UNDERBAR
029CC^⧌^^\triangles^N^mathord^^S IN TRIANGLE
029CD^⧍^^\triangleserifs^N^mathbin^^TRIANGLE WITH SERIFS AT BOTTOM
029CE^⧎^^\rtriltri^R^mathrel^^RIGHT TRIANGLE ABOVE LEFT TRIANGLE
029CF^⧏^\LeftTriangleBar^\ltrivb^R^mathrel^wrisym^LEFT TRIANGLE BESIDE VERTICAL BAR
029D0^⧐^\RightTriangleBar^\vbrtri^R^mathrel^wrisym^VERTICAL BAR BESIDE RIGHT TRIANGLE
029D1^⧑^^\lfbowtie^R^mathrel^^left black bowtie
029D2^⧒^^\rfbowtie^R^mathrel^^right black bowtie
029D3^⧓^^\fbowtie^R^mathrel^^BLACK BOWTIE
029D4^⧔^^\lftimes^R^mathrel^^left black times
029D5^⧕^^\rftimes^R^mathrel^^right black times
029D6^⧖^^\hourglass^B^mathbin^^WHITE HOURGLASS
029D7^⧗^^\blackhourglass^B^mathbin^^BLACK HOURGLASS
029D8^⧘^^\lvzigzag^O^mathopen^^LEFT WIGGLY FENCE
029D9^⧙^^\rvzigzag^C^mathclose^^RIGHT WIGGLY FENCE
029DA^⧚^^\Lvzigzag^O^mathopen^^LEFT DOUBLE WIGGLY FENCE
029DB^⧛^^\Rvzigzag^C^mathclose^^RIGHT DOUBLE WIGGLY FENCE
029DC^⧜^^\iinfin^N^mathord^^INCOMPLETE INFINITY
029DD^⧝^^\tieinfty^N^mathord^^TIE OVER INFINITY
029DE^⧞^^\nvinfty^N^mathord^^INFINITY NEGATED WITH VERTICAL BAR
029DF^⧟^\multimapboth^\dualmap^R^mathrel^txfonts^DOUBLE-ENDED MULTIMAP
029E0^⧠^^\laplac^N^mathord^^SQUARE WITH CONTOURED OUTLINE
029E1^⧡^^\lrtriangleeq^R^mathrel^^INCREASES AS
029E2^⧢^^\shuffle^B^mathbin^^SHUFFLE PRODUCT
029E3^⧣^^\eparsl^R^mathrel^^EQUALS SIGN AND SLANTED PARALLEL
029E4^⧤^^\smeparsl^R^mathrel^^EQUALS SIGN AND SLANTED PARALLEL WITH TILDE ABOVE
029E5^⧥^^\eqvparsl^R^mathrel^^IDENTICAL TO AND SLANTED PARALLEL
029E6^⧦^^\gleichstark^R^mathrel^^GLEICH STARK
029E7^⧧^^\thermod^N^mathord^^THERMODYNAMIC
029E8^⧨^^\downtriangleleftblack^N^mathord^^DOWN-POINTING TRIANGLE WITH LEFT HALF BLACK
029E9^⧩^^\downtrianglerightblack^N^mathord^^DOWN-POINTING TRIANGLE WITH RIGHT HALF BLACK
029EA^⧪^^\blackdiamonddownarrow^N^mathord^^BLACK DIAMOND WITH DOWN ARROW
029EB^⧫^\blacklozenge^\mdlgblklozenge^B^mathbin^amssymb^BLACK LOZENGE
029EC^⧬^^\circledownarrow^N^mathord^^WHITE CIRCLE WITH DOWN ARROW
029ED^⧭^^\blackcircledownarrow^N^mathord^^BLACK CIRCLE WITH DOWN ARROW
029EE^⧮^^\errbarsquare^N^mathord^^ERROR-BARRED WHITE SQUARE
029EF^⧯^^\errbarblacksquare^N^mathord^^ERROR-BARRED BLACK SQUARE
029F0^⧰^^\errbardiamond^N^mathord^^ERROR-BARRED WHITE DIAMOND
029F1^⧱^^\errbarblackdiamond^N^mathord^^ERROR-BARRED BLACK DIAMOND
029F2^⧲^^\errbarcircle^N^mathord^^ERROR-BARRED WHITE CIRCLE
029F3^⧳^^\errbarblackcircle^N^mathord^^ERROR-BARRED BLACK CIRCLE
029F4^⧴^^\ruledelayed^R^mathrel^^RULE-DELAYED
029F5^⧵^\setminus^\setminus^B^mathbin^^REVERSE SOLIDUS OPERATOR
029F6^⧶^^\dsol^B^mathbin^^SOLIDUS WITH OVERBAR
029F7^⧷^^\rsolbar^B^mathbin^^REVERSE SOLIDUS WITH HORIZONTAL STROKE
029F8^⧸^^\xsol^L^mathop^^BIG SOLIDUS
029F9^⧹^\zhide^\xbsol^L^mathop^oz^= \hide (oz), BIG REVERSE SOLIDUS, z notation schema hiding
029FA^⧺^^\doubleplus^B^mathbin^^DOUBLE PLUS
029FB^⧻^^\tripleplus^B^mathbin^^TRIPLE PLUS
029FC^⧼^^\lcurvyangle^O^mathopen^^left pointing curved angle bracket
029FD^⧽^^\rcurvyangle^C^mathclose^^right pointing curved angle bracket
029FE^⧾^^\tplus^B^mathbin^^TINY
029FF^⧿^^\tminus^B^mathbin^^MINY
02A00^⨀^\bigodot^\bigodot^L^mathop^^N-ARY CIRCLED DOT OPERATOR
02A01^⨁^\bigoplus^\bigoplus^L^mathop^^N-ARY CIRCLED PLUS OPERATOR
02A02^⨂^\bigotimes^\bigotimes^L^mathop^^N-ARY CIRCLED TIMES OPERATOR
02A03^⨃^^\bigcupdot^L^mathop^^N-ARY UNION OPERATOR WITH DOT
02A04^⨄^\biguplus^\biguplus^L^mathop^^N-ARY UNION OPERATOR WITH PLUS
02A05^⨅^\bigsqcap^\bigsqcap^L^mathop^txfonts^N-ARY SQUARE INTERSECTION OPERATOR
02A06^⨆^\bigsqcup^\bigsqcup^L^mathop^^N-ARY SQUARE UNION OPERATOR
02A07^⨇^^\conjquant^L^mathop^^TWO LOGICAL AND OPERATOR
02A08^⨈^^\disjquant^L^mathop^^TWO LOGICAL OR OPERATOR
02A09^⨉^\varprod^\bigtimes^L^mathop^txfonts^N-ARY TIMES OPERATOR
02A0A^⨊^^\modtwosum^L^mathord^^MODULO TWO SUM
02A0B^⨋^^\sumint^L^mathop^^SUMMATION WITH INTEGRAL
02A0C^⨌^\iiiint^\iiiint^L^mathop^amsmath esint^QUADRUPLE INTEGRAL OPERATOR
02A0D^⨍^^\intbar^L^mathop^^FINITE PART INTEGRAL
02A0E^⨎^^\intBar^L^mathop^^INTEGRAL WITH DOUBLE STROKE
02A0F^⨏^\fint^\fint^L^mathop^esint wrisym^INTEGRAL AVERAGE WITH SLASH
02A10^⨐^^\cirfnint^L^mathop^^CIRCULATION FUNCTION
02A11^⨑^^\awint^L^mathop^^ANTICLOCKWISE INTEGRATION
02A12^⨒^^\rppolint^L^mathop^^LINE INTEGRATION WITH RECTANGULAR PATH AROUND POLE
02A13^⨓^^\scpolint^L^mathop^^LINE INTEGRATION WITH SEMICIRCULAR PATH AROUND POLE
02A14^⨔^^\npolint^L^mathop^^LINE INTEGRATION NOT INCLUDING THE POLE
02A15^⨕^^\pointint^L^mathop^^INTEGRAL AROUND A POINT OPERATOR
02A16^⨖^\sqint^\sqint^L^mathop^esint^= \sqrint (wrisym), QUATERNION INTEGRAL OPERATOR
02A17^⨗^^\intlarhk^L^mathop^^INTEGRAL WITH LEFTWARDS ARROW WITH HOOK
02A18^⨘^^\intx^L^mathop^^INTEGRAL WITH TIMES SIGN
02A19^⨙^^\intcap^L^mathop^^INTEGRAL WITH INTERSECTION
02A1A^⨚^^\intcup^L^mathop^^INTEGRAL WITH UNION
02A1B^⨛^^\upint^L^mathop^^INTEGRAL WITH OVERBAR
02A1C^⨜^^\lowint^L^mathop^^INTEGRAL WITH UNDERBAR
02A1D^⨝^\Join^\Join^L^mathop^amssymb^JOIN
02A1E^⨞^^\bigtriangleleft^L^mathop^^LARGE LEFT TRIANGLE OPERATOR
02A1F^⨟^\zcmp^\zcmp^L^mathop^oz^= \semi (oz), = \fatsemi (stmaryrd), Z NOTATION SCHEMA COMPOSITION
02A20^⨠^\zpipe^\zpipe^L^mathop^oz^Z NOTATION SCHEMA PIPING
02A21^⨡^\zproject^\zproject^L^mathop^oz^= \project (oz), Z NOTATION SCHEMA PROJECTION
02A22^⨢^^\ringplus^B^mathbin^^PLUS SIGN WITH SMALL CIRCLE ABOVE
02A23^⨣^^\plushat^B^mathbin^^PLUS SIGN WITH CIRCUMFLEX ACCENT ABOVE
02A24^⨤^^\simplus^B^mathbin^^PLUS SIGN WITH TILDE ABOVE
02A25^⨥^^\plusdot^B^mathbin^^PLUS SIGN WITH DOT BELOW
02A26^⨦^^\plussim^B^mathbin^^PLUS SIGN WITH TILDE BELOW
02A27^⨧^^\plussubtwo^B^mathbin^^PLUS SIGN WITH SUBSCRIPT TWO
02A28^⨨^^\plustrif^B^mathbin^^PLUS SIGN WITH BLACK TRIANGLE
02A29^⨩^^\commaminus^B^mathbin^^MINUS SIGN WITH COMMA ABOVE
02A2A^⨪^^\minusdot^B^mathbin^^MINUS SIGN WITH DOT BELOW
02A2B^⨫^^\minusfdots^B^mathbin^^MINUS SIGN WITH FALLING DOTS
02A2C^⨬^^\minusrdots^B^mathbin^^MINUS SIGN WITH RISING DOTS
02A2D^⨭^^\opluslhrim^B^mathbin^^PLUS SIGN IN LEFT HALF CIRCLE
02A2E^⨮^^\oplusrhrim^B^mathbin^^PLUS SIGN IN RIGHT HALF CIRCLE
02A2F^⨯^^\vectimes^B^mathbin^^# \times, VECTOR OR CROSS PRODUCT
02A30^⨰^^\dottimes^B^mathbin^^MULTIPLICATION SIGN WITH DOT ABOVE
02A31^⨱^^\timesbar^B^mathbin^^MULTIPLICATION SIGN WITH UNDERBAR
02A32^⨲^^\btimes^B^mathbin^^SEMIDIRECT PRODUCT WITH BOTTOM CLOSED
02A33^⨳^^\smashtimes^B^mathbin^^SMASH PRODUCT
02A34^⨴^^\otimeslhrim^B^mathbin^^MULTIPLICATION SIGN IN LEFT HALF CIRCLE
02A35^⨵^^\otimesrhrim^B^mathbin^^MULTIPLICATION SIGN IN RIGHT HALF CIRCLE
02A36^⨶^^\otimeshat^B^mathbin^^CIRCLED MULTIPLICATION SIGN WITH CIRCUMFLEX ACCENT
02A37^⨷^^\Otimes^B^mathbin^^MULTIPLICATION SIGN IN DOUBLE CIRCLE
02A38^⨸^^\odiv^B^mathbin^^CIRCLED DIVISION SIGN
02A39^⨹^^\triangleplus^B^mathbin^^PLUS SIGN IN TRIANGLE
02A3A^⨺^^\triangleminus^B^mathbin^^MINUS SIGN IN TRIANGLE
02A3B^⨻^^\triangletimes^B^mathbin^^MULTIPLICATION SIGN IN TRIANGLE
02A3C^⨼^^\intprod^B^mathbin^^INTERIOR PRODUCT
02A3D^⨽^^\intprodr^B^mathbin^^RIGHTHAND INTERIOR PRODUCT
02A3E^⨾^\fcmp^\fcmp^B^mathbin^oz^= \comp (oz), Z NOTATION RELATIONAL COMPOSITION
02A3F^⨿^\amalg^\amalg^B^mathbin^^AMALGAMATION OR COPRODUCT
02A40^⩀^^\capdot^B^mathbin^^INTERSECTION WITH DOT
02A41^⩁^^\uminus^B^mathbin^^UNION WITH MINUS SIGN, z notation bag subtraction
02A42^⩂^^\barcup^B^mathbin^^UNION WITH OVERBAR
02A43^⩃^^\barcap^B^mathbin^^INTERSECTION WITH OVERBAR
02A44^⩄^^\capwedge^B^mathbin^^INTERSECTION WITH LOGICAL AND
02A45^⩅^^\cupvee^B^mathbin^^UNION WITH LOGICAL OR
02A46^⩆^^\cupovercap^B^mathbin^^UNION ABOVE INTERSECTION
02A47^⩇^^\capovercup^B^mathbin^^INTERSECTION ABOVE UNION
02A48^⩈^^\cupbarcap^B^mathbin^^UNION ABOVE BAR ABOVE INTERSECTION
02A49^⩉^^\capbarcup^B^mathbin^^INTERSECTION ABOVE BAR ABOVE UNION
02A4A^⩊^^\twocups^B^mathbin^^UNION BESIDE AND JOINED WITH UNION
02A4B^⩋^^\twocaps^B^mathbin^^INTERSECTION BESIDE AND JOINED WITH INTERSECTION
02A4C^⩌^^\closedvarcup^B^mathbin^^CLOSED UNION WITH SERIFS
02A4D^⩍^^\closedvarcap^B^mathbin^^CLOSED INTERSECTION WITH SERIFS
02A4E^⩎^^\Sqcap^B^mathbin^^DOUBLE SQUARE INTERSECTION
02A4F^⩏^^\Sqcup^B^mathbin^^DOUBLE SQUARE UNION
02A50^⩐^^\closedvarcupsmashprod^B^mathbin^^CLOSED UNION WITH SERIFS AND SMASH PRODUCT
02A51^⩑^^\wedgeodot^B^mathbin^^LOGICAL AND WITH DOT ABOVE
02A52^⩒^^\veeodot^B^mathbin^^LOGICAL OR WITH DOT ABOVE
02A53^⩓^^\Wedge^B^mathbin^^DOUBLE LOGICAL AND
02A54^⩔^^\Vee^B^mathbin^^DOUBLE LOGICAL OR
02A55^⩕^^\wedgeonwedge^B^mathbin^^TWO INTERSECTING LOGICAL AND
02A56^⩖^^\veeonvee^B^mathbin^^TWO INTERSECTING LOGICAL OR
02A57^⩗^^\bigslopedvee^B^mathbin^^SLOPING LARGE OR
02A58^⩘^^\bigslopedwedge^B^mathbin^^SLOPING LARGE AND
02A59^⩙^^\veeonwedge^R^mathrel^^LOGICAL OR OVERLAPPING LOGICAL AND
02A5A^⩚^^\wedgemidvert^B^mathbin^^LOGICAL AND WITH MIDDLE STEM
02A5B^⩛^^\veemidvert^B^mathbin^^LOGICAL OR WITH MIDDLE STEM
02A5C^⩜^^\midbarwedge^B^mathbin^^ogical and with horizontal dash
02A5D^⩝^^\midbarvee^B^mathbin^^LOGICAL OR WITH HORIZONTAL DASH
02A5E^⩞^\doublebarwedge^\doublebarwedge^B^mathbin^amssymb^LOGICAL AND WITH DOUBLE OVERBAR
02A5F^⩟^^\wedgebar^B^mathbin^^LOGICAL AND WITH UNDERBAR
02A60^⩠^^\wedgedoublebar^B^mathbin^^LOGICAL AND WITH DOUBLE UNDERBAR
02A61^⩡^^\varveebar^B^mathbin^^SMALL VEE WITH UNDERBAR
02A62^⩢^^\doublebarvee^B^mathbin^^LOGICAL OR WITH DOUBLE OVERBAR
02A63^⩣^^\veedoublebar^B^mathbin^^LOGICAL OR WITH DOUBLE UNDERBAR
02A64^⩤^\dsub^\dsub^B^mathbin^oz^= \ndres (oz), Z NOTATION DOMAIN ANTIRESTRICTION
02A65^⩥^\rsub^\rsub^B^mathbin^oz^= \nrres (oz), Z NOTATION RANGE ANTIRESTRICTION
02A66^⩦^^\eqdot^R^mathrel^^EQUALS SIGN WITH DOT BELOW
02A67^⩧^^\dotequiv^R^mathrel^^IDENTICAL WITH DOT ABOVE
02A68^⩨^^\equivVert^R^mathrel^^TRIPLE HORIZONTAL BAR WITH DOUBLE VERTICAL STROKE
02A69^⩩^^\equivVvert^R^mathrel^^TRIPLE HORIZONTAL BAR WITH TRIPLE VERTICAL STROKE
02A6A^⩪^^\dotsim^R^mathrel^^TILDE OPERATOR WITH DOT ABOVE
02A6B^⩫^^\simrdots^R^mathrel^^TILDE OPERATOR WITH RISING DOTS
02A6C^⩬^^\simminussim^R^mathrel^^SIMILAR MINUS SIMILAR
02A6D^⩭^^\congdot^R^mathrel^^CONGRUENT WITH DOT ABOVE
02A6E^⩮^^\asteq^R^mathrel^^EQUALS WITH ASTERISK
02A6F^⩯^^\hatapprox^R^mathrel^^ALMOST EQUAL TO WITH CIRCUMFLEX ACCENT
02A70^⩰^^\approxeqq^R^mathrel^^APPROXIMATELY EQUAL OR EQUAL TO
02A71^⩱^^\eqqplus^B^mathbin^^EQUALS SIGN ABOVE PLUS SIGN
02A72^⩲^^\pluseqq^B^mathbin^^PLUS SIGN ABOVE EQUALS SIGN
02A73^⩳^^\eqqsim^R^mathrel^^EQUALS SIGN ABOVE TILDE OPERATOR
02A74^⩴^\Coloneqq^\Coloneq^R^mathrel^txfonts^# ::=, x \Coloneq (txfonts), DOUBLE COLON EQUAL
02A75^⩵^\Equal^\eqeq^R^mathrel^wrisym^# ==, TWO CONSECUTIVE EQUALS SIGNS
02A76^⩶^\Same^\eqeqeq^R^mathrel^wrisym^# ===, THREE CONSECUTIVE EQUALS SIGNS
02A77^⩷^^\ddotseq^R^mathrel^^EQUALS SIGN WITH TWO DOTS ABOVE AND TWO DOTS BELOW
02A78^⩸^^\equivDD^R^mathrel^^EQUIVALENT WITH FOUR DOTS ABOVE
02A79^⩹^^\ltcir^R^mathrel^^LESS-THAN WITH CIRCLE INSIDE
02A7A^⩺^^\gtcir^R^mathrel^^GREATER-THAN WITH CIRCLE INSIDE
02A7B^⩻^^\ltquest^R^mathrel^^LESS-THAN WITH QUESTION MARK ABOVE
02A7C^⩼^^\gtquest^R^mathrel^^GREATER-THAN WITH QUESTION MARK ABOVE
02A7D^⩽^\leqslant^\leqslant^R^mathrel^amssymb fourier^LESS-THAN OR SLANTED EQUAL TO
02A7E^⩾^\geqslant^\geqslant^R^mathrel^amssymb fourier^GREATER-THAN OR SLANTED EQUAL TO
02A7F^⩿^^\lesdot^R^mathrel^^LESS-THAN OR SLANTED EQUAL TO WITH DOT INSIDE
02A80^⪀^^\gesdot^R^mathrel^^GREATER-THAN OR SLANTED EQUAL TO WITH DOT INSIDE
02A81^⪁^^\lesdoto^R^mathrel^^LESS-THAN OR SLANTED EQUAL TO WITH DOT ABOVE
02A82^⪂^^\gesdoto^R^mathrel^^GREATER-THAN OR SLANTED EQUAL TO WITH DOT ABOVE
02A83^⪃^^\lesdotor^R^mathrel^^LESS-THAN OR SLANTED EQUAL TO WITH DOT ABOVE RIGHT
02A84^⪄^^\gesdotol^R^mathrel^^GREATER-THAN OR SLANTED EQUAL TO WITH DOT ABOVE LEFT
02A85^⪅^\lessapprox^\lessapprox^R^mathrel^amssymb^LESS-THAN OR APPROXIMATE
02A86^⪆^\gtrapprox^\gtrapprox^R^mathrel^amssymb^GREATER-THAN OR APPROXIMATE
02A87^⪇^\lneq^\lneq^R^mathrel^amssymb^LESS-THAN AND SINGLE-LINE NOT EQUAL TO
02A88^⪈^\gneq^\gneq^R^mathrel^amssymb^GREATER-THAN AND SINGLE-LINE NOT EQUAL TO
02A89^⪉^\lnapprox^\lnapprox^R^mathrel^amssymb^LESS-THAN AND NOT APPROXIMATE
02A8A^⪊^\gnapprox^\gnapprox^R^mathrel^amssymb^GREATER-THAN AND NOT APPROXIMATE
02A8B^⪋^\lesseqqgtr^\lesseqqgtr^R^mathrel^amssymb^LESS-THAN ABOVE DOUBLE-LINE EQUAL ABOVE GREATER-THAN
02A8C^⪌^\gtreqqless^\gtreqqless^R^mathrel^amssymb^GREATER-THAN ABOVE DOUBLE-LINE EQUAL ABOVE LESS-THAN
02A8D^⪍^^\lsime^R^mathrel^^LESS-THAN ABOVE SIMILAR OR EQUAL
02A8E^⪎^^\gsime^R^mathrel^^GREATER-THAN ABOVE SIMILAR OR EQUAL
02A8F^⪏^^\lsimg^R^mathrel^^LESS-THAN ABOVE SIMILAR ABOVE GREATER-THAN
02A90^⪐^^\gsiml^R^mathrel^^GREATER-THAN ABOVE SIMILAR ABOVE LESS-THAN
02A91^⪑^^\lgE^R^mathrel^^LESS-THAN ABOVE GREATER-THAN ABOVE DOUBLE-LINE EQUAL
02A92^⪒^^\glE^R^mathrel^^GREATER-THAN ABOVE LESS-THAN ABOVE DOUBLE-LINE EQUAL
02A93^⪓^^\lesges^R^mathrel^^LESS-THAN ABOVE SLANTED EQUAL ABOVE GREATER-THAN ABOVE SLANTED EQUAL
02A94^⪔^^\gesles^R^mathrel^^GREATER-THAN ABOVE SLANTED EQUAL ABOVE LESS-THAN ABOVE SLANTED EQUAL
02A95^⪕^\eqslantless^\eqslantless^R^mathrel^amssymb^SLANTED EQUAL TO OR LESS-THAN
02A96^⪖^\eqslantgtr^\eqslantgtr^R^mathrel^amssymb^SLANTED EQUAL TO OR GREATER-THAN
02A97^⪗^^\elsdot^R^mathrel^^SLANTED EQUAL TO OR LESS-THAN WITH DOT INSIDE
02A98^⪘^^\egsdot^R^mathrel^^SLANTED EQUAL TO OR GREATER-THAN WITH DOT INSIDE
02A99^⪙^^\eqqless^R^mathrel^^DOUBLE-LINE EQUAL TO OR LESS-THAN
02A9A^⪚^^\eqqgtr^R^mathrel^^DOUBLE-LINE EQUAL TO OR GREATER-THAN
02A9B^⪛^^\eqqslantless^R^mathrel^^DOUBLE-LINE SLANTED EQUAL TO OR LESS-THAN
02A9C^⪜^^\eqqslantgtr^R^mathrel^^DOUBLE-LINE SLANTED EQUAL TO OR GREATER-THAN
02A9D^⪝^^\simless^R^mathrel^^SIMILAR OR LESS-THAN
02A9E^⪞^^\simgtr^R^mathrel^^SIMILAR OR GREATER-THAN
02A9F^⪟^^\simlE^R^mathrel^^SIMILAR ABOVE LESS-THAN ABOVE EQUALS SIGN
02AA0^⪠^^\simgE^R^mathrel^^SIMILAR ABOVE GREATER-THAN ABOVE EQUALS SIGN
02AA1^⪡^\NestedLessLess^\Lt^R^mathrel^wrisym^= \lll (mathabx -amssymb), DOUBLE NESTED LESS-THAN
02AA2^⪢^\NestedGreaterGreater^\Gt^R^mathrel^wrisym^= \ggg (mathabx -amssymb), DOUBLE NESTED GREATER-THAN
02AA3^⪣^^\partialmeetcontraction^R^mathrel^^double less-than with underbar
02AA4^⪤^^\glj^R^mathrel^^GREATER-THAN OVERLAPPING LESS-THAN
02AA5^⪥^^\gla^R^mathrel^^GREATER-THAN BESIDE LESS-THAN
02AA6^⪦^\leftslice^\ltcc^R^mathrel^stmaryrd^LESS-THAN CLOSED BY CURVE
02AA7^⪧^\rightslice^\gtcc^R^mathrel^stmaryrd^GREATER-THAN CLOSED BY CURVE
02AA8^⪨^^\lescc^R^mathrel^^LESS-THAN CLOSED BY CURVE ABOVE SLANTED EQUAL
02AA9^⪩^^\gescc^R^mathrel^^GREATER-THAN CLOSED BY CURVE ABOVE SLANTED EQUAL
02AAA^⪪^^\smt^R^mathrel^^SMALLER THAN
02AAB^⪫^^\lat^R^mathrel^^LARGER THAN
02AAC^⪬^^\smte^R^mathrel^^SMALLER THAN OR EQUAL TO
02AAD^⪭^^\late^R^mathrel^^LARGER THAN OR EQUAL TO
02AAE^⪮^^\bumpeqq^R^mathrel^^EQUALS SIGN WITH BUMPY ABOVE
02AAF^⪯^\preceq^\preceq^R^mathrel^^PRECEDES ABOVE SINGLE-LINE EQUALS SIGN
02AB0^⪰^\succeq^\succeq^R^mathrel^^SUCCEEDS ABOVE SINGLE-LINE EQUALS SIGN
02AB1^⪱^^\precneq^R^mathrel^^PRECEDES ABOVE SINGLE-LINE NOT EQUAL TO
02AB2^⪲^^\succneq^R^mathrel^^SUCCEEDS ABOVE SINGLE-LINE NOT EQUAL TO
02AB3^⪳^\preceqq^\preceqq^R^mathrel^txfonts^PRECEDES ABOVE EQUALS SIGN
02AB4^⪴^\succeqq^\succeqq^R^mathrel^txfonts^SUCCEEDS ABOVE EQUALS SIGN
02AB5^⪵^^\precneqq^R^mathrel^amssymb^PRECEDES ABOVE NOT EQUAL TO
02AB6^⪶^^\succneqq^R^mathrel^amssymb^SUCCEEDS ABOVE NOT EQUAL TO
02AB7^⪷^\precapprox^\precapprox^R^mathrel^amssymb^PRECEDES ABOVE ALMOST EQUAL TO
02AB8^⪸^\succapprox^\succapprox^R^mathrel^amssymb^SUCCEEDS ABOVE ALMOST EQUAL TO
02AB9^⪹^\precnapprox^\precnapprox^R^mathrel^amssymb^PRECEDES ABOVE NOT ALMOST EQUAL TO
02ABA^⪺^\succnapprox^\succnapprox^R^mathrel^amssymb^SUCCEEDS ABOVE NOT ALMOST EQUAL TO
02ABB^⪻^\llcurly^\Prec^R^mathrel^mathabx^DOUBLE PRECEDES
02ABC^⪼^\ggcurly^\Succ^R^mathrel^mathabx^DOUBLE SUCCEEDS
02ABD^⪽^^\subsetdot^R^mathrel^^SUBSET WITH DOT
02ABE^⪾^^\supsetdot^R^mathrel^^SUPERSET WITH DOT
02ABF^⪿^^\subsetplus^R^mathrel^^SUBSET WITH PLUS SIGN BELOW
02AC0^⫀^^\supsetplus^R^mathrel^^SUPERSET WITH PLUS SIGN BELOW
02AC1^⫁^^\submult^R^mathrel^^SUBSET WITH MULTIPLICATION SIGN BELOW
02AC2^⫂^^\supmult^R^mathrel^^SUPERSET WITH MULTIPLICATION SIGN BELOW
02AC3^⫃^^\subedot^R^mathrel^^SUBSET OF OR EQUAL TO WITH DOT ABOVE
02AC4^⫄^^\supedot^R^mathrel^^SUPERSET OF OR EQUAL TO WITH DOT ABOVE
02AC5^⫅^\subseteqq^\subseteqq^R^mathrel^amssymb^SUBSET OF ABOVE EQUALS SIGN
02AC6^⫆^\supseteqq^\supseteqq^R^mathrel^amssymb^SUPERSET OF ABOVE EQUALS SIGN
02AC7^⫇^^\subsim^R^mathrel^^SUBSET OF ABOVE TILDE OPERATOR
02AC8^⫈^^\supsim^R^mathrel^^SUPERSET OF ABOVE TILDE OPERATOR
02AC9^⫉^^\subsetapprox^R^mathrel^^SUBSET OF ABOVE ALMOST EQUAL TO
02ACA^⫊^^\supsetapprox^R^mathrel^^SUPERSET OF ABOVE ALMOST EQUAL TO
02ACB^⫋^\subsetneqq^\subsetneqq^R^mathrel^amssymb^SUBSET OF ABOVE NOT EQUAL TO
02ACC^⫌^\supsetneqq^\supsetneqq^R^mathrel^amssymb^SUPERSET OF ABOVE NOT EQUAL TO
02ACD^⫍^^\lsqhook^R^mathrel^^SQUARE LEFT OPEN BOX OPERATOR
02ACE^⫎^^\rsqhook^R^mathrel^^SQUARE RIGHT OPEN BOX OPERATOR
02ACF^⫏^^\csub^R^mathrel^^CLOSED SUBSET
02AD0^⫐^^\csup^R^mathrel^^CLOSED SUPERSET
02AD1^⫑^^\csube^R^mathrel^^CLOSED SUBSET OR EQUAL TO
02AD2^⫒^^\csupe^R^mathrel^^CLOSED SUPERSET OR EQUAL TO
02AD3^⫓^^\subsup^R^mathrel^^SUBSET ABOVE SUPERSET
02AD4^⫔^^\supsub^R^mathrel^^SUPERSET ABOVE SUBSET
02AD5^⫕^^\subsub^R^mathrel^^SUBSET ABOVE SUBSET
02AD6^⫖^^\supsup^R^mathrel^^SUPERSET ABOVE SUPERSET
02AD7^⫗^^\suphsub^R^mathrel^^SUPERSET BESIDE SUBSET
02AD8^⫘^^\supdsub^R^mathrel^^SUPERSET BESIDE AND JOINED BY DASH WITH SUBSET
02AD9^⫙^^\forkv^R^mathrel^^ELEMENT OF OPENING DOWNWARDS
02ADA^⫚^^\topfork^R^mathrel^^PITCHFORK WITH TEE TOP
02ADB^⫛^^\mlcp^R^mathrel^^TRANSVERSAL INTERSECTION
02ADC^⫝̸^^\forks^R^mathrel^^FORKING
02ADD^⫝^^\forksnot^R^mathrel^^NONFORKING
02ADE^⫞^^\shortlefttack^R^mathrel^^SHORT LEFT TACK
02ADF^⫟^^\shortdowntack^R^mathrel^^SHORT DOWN TACK
02AE0^⫠^^\shortuptack^R^mathrel^^SHORT UP TACK
02AE1^⫡^^\perps^N^mathord^^PERPENDICULAR WITH S
02AE2^⫢^^\vDdash^R^mathrel^^VERTICAL BAR TRIPLE RIGHT TURNSTILE
02AE3^⫣^^\dashV^R^mathrel^^DOUBLE VERTICAL BAR LEFT TURNSTILE
02AE4^⫤^^\Dashv^R^mathrel^^VERTICAL BAR DOUBLE LEFT TURNSTILE
02AE5^⫥^^\DashV^R^mathrel^^DOUBLE VERTICAL BAR DOUBLE LEFT TURNSTILE
02AE6^⫦^^\varVdash^R^mathrel^^LONG DASH FROM LEFT MEMBER OF DOUBLE VERTICAL
02AE7^⫧^^\Barv^R^mathrel^^SHORT DOWN TACK WITH OVERBAR
02AE8^⫨^^\vBar^R^mathrel^^SHORT UP TACK WITH UNDERBAR
02AE9^⫩^^\vBarv^R^mathrel^^SHORT UP TACK ABOVE SHORT DOWN TACK
02AEA^⫪^\Top^\barV^R^mathrel^txfonts^DOUBLE DOWN TACK
02AEB^⫫^\Bot^\Vbar^R^mathrel^txfonts^= \Perp (txfonts), DOUBLE UP TACK
02AEC^⫬^^\Not^R^mathrel^^DOUBLE STROKE NOT SIGN
02AED^⫭^^\bNot^R^mathrel^^REVERSED DOUBLE STROKE NOT SIGN
02AEE^⫮^^\revnmid^R^mathrel^^DOES NOT DIVIDE WITH REVERSED NEGATION SLASH
02AEF^⫯^^\cirmid^R^mathrel^^VERTICAL LINE WITH CIRCLE ABOVE
02AF0^⫰^^\midcir^R^mathrel^^VERTICAL LINE WITH CIRCLE BELOW
02AF1^⫱^^\topcir^N^mathord^^DOWN TACK WITH CIRCLE BELOW
02AF2^⫲^^\nhpar^R^mathrel^^PARALLEL WITH HORIZONTAL STROKE
02AF3^⫳^^\parsim^R^mathrel^^PARALLEL WITH TILDE OPERATOR
02AF4^⫴^\interleave^\interleave^B^mathbin^stmaryrd^TRIPLE VERTICAL BAR BINARY RELATION
02AF5^⫵^^\nhVvert^B^mathbin^^TRIPLE VERTICAL BAR WITH HORIZONTAL STROKE
02AF6^⫶^^\threedotcolon^B^mathbin^^TRIPLE COLON OPERATOR
02AF7^⫷^^\lllnest^R^mathrel^^TRIPLE NESTED LESS-THAN
02AF8^⫸^^\gggnest^R^mathrel^^TRIPLE NESTED GREATER-THAN
02AF9^⫹^^\leqqslant^R^mathrel^^DOUBLE-LINE SLANTED LESS-THAN OR EQUAL TO
02AFA^⫺^^\geqqslant^R^mathrel^^DOUBLE-LINE SLANTED GREATER-THAN OR EQUAL TO
02AFB^⫻^^\trslash^B^mathbin^^TRIPLE SOLIDUS BINARY RELATION
02AFC^⫼^\biginterleave^\biginterleave^L^mathop^stmaryrd^LARGE TRIPLE VERTICAL BAR OPERATOR
02AFD^⫽^\sslash^\sslash^B^mathbin^stmaryrd^# \varparallel (txfonts), DOUBLE SOLIDUS OPERATOR
02AFE^⫾^\talloblong^\talloblong^B^mathbin^stmaryrd^WHITE VERTICAL BAR
02AFF^⫿^^\bigtalloblong^L^mathop^^N-ARY WHITE VERTICAL BAR
02B00^⬀^^^R?^mathord^^NORTH EAST WHITE ARROW
02B01^⬁^^^R?^mathord^^NORTH WEST WHITE ARROW
02B02^⬂^^^R?^mathord^^SOUTH EAST WHITE ARROW
02B03^⬃^^^R?^mathord^^SOUTH WEST WHITE ARROW
02B04^⬄^^^R?^mathord^^LEFT RIGHT WHITE ARROW
02B05^⬅^^^R?^mathord^^LEFTWARDS BLACK ARROW
02B06^⬆^^^R?^mathord^^UPWARDS BLACK ARROW
02B07^⬇^^^R?^mathord^^DOWNWARDS BLACK ARROW
02B08^⬈^^^R?^mathord^^NORTH EAST BLACK ARROW
02B09^⬉^^^R?^mathord^^NORTH WEST BLACK ARROW
02B0A^⬊^^^R?^mathord^^SOUTH EAST BLACK ARROW
02B0B^⬋^^^R?^mathord^^SOUTH WEST BLACK ARROW
02B0C^⬌^^^R?^mathord^^LEFT RIGHT BLACK ARROW
02B0D^⬍^^^R?^mathord^^UP DOWN BLACK ARROW
02B0E^⬎^^^R?^mathord^^RIGHTWARDS ARROW WITH TIP DOWNWARDS
02B0F^⬏^^^R?^mathord^^RIGHTWARDS ARROW WITH TIP UPWARDS
02B10^⬐^^^R?^mathord^^LEFTWARDS ARROW WITH TIP DOWNWARDS
02B11^⬑^^^R?^mathord^^LEFTWARDS ARROW WITH TIP UPWARDS
02B12^⬒^^\squaretopblack^N^mathord^^SQUARE WITH TOP HALF BLACK
02B13^⬓^^\squarebotblack^N^mathord^^SQUARE WITH BOTTOM HALF BLACK
02B14^⬔^^\squareurblack^N^mathord^^SQUARE WITH UPPER RIGHT DIAGONAL HALF BLACK
02B15^⬕^^\squarellblack^N^mathord^^SQUARE WITH LOWER LEFT DIAGONAL HALF BLACK
02B16^⬖^^\diamondleftblack^N^mathord^^DIAMOND WITH LEFT HALF BLACK
02B17^⬗^^\diamondrightblack^N^mathord^^DIAMOND WITH RIGHT HALF BLACK
02B18^⬘^^\diamondtopblack^N^mathord^^DIAMOND WITH TOP HALF BLACK
02B19^⬙^^\diamondbotblack^N^mathord^^DIAMOND WITH BOTTOM HALF BLACK
02B1A^⬚^^\dottedsquare^^mathord^^DOTTED SQUARE
02B1B^⬛^\blacksquare^\lgblksquare^^mathord^fourier -amssymb^BLACK LARGE SQUARE
02B1C^⬜^\square^\lgwhtsquare^^mathord^fourier -amssymb^WHITE LARGE SQUARE
02B1D^⬝^^\vysmblksquare^^mathord^^# \centerdot (amssymb), t \Squaredot (marvosym), BLACK VERY SMALL SQUARE
02B1E^⬞^^\vysmwhtsquare^^mathord^^WHITE VERY SMALL SQUARE
02B1F^⬟^^\pentagonblack^^mathord^^BLACK PENTAGON
02B20^⬠^^\pentagon^N^mathord^^WHITE PENTAGON
02B21^⬡^^\varhexagon^N^mathord^^WHITE HEXAGON
02B22^⬢^^\varhexagonblack^N^mathord^^BLACK HEXAGON
02B23^⬣^^\hexagonblack^N^mathord^^HORIZONTAL BLACK HEXAGON
02B24^⬤^^\lgblkcircle^^mathord^^BLACK LARGE CIRCLE
02B25^⬥^^\mdblkdiamond^^mathord^^BLACK MEDIUM DIAMOND
02B26^⬦^^\mdwhtdiamond^^mathord^^WHITE MEDIUM DIAMOND
02B27^⬧^^\mdblklozenge^^mathord^^# \blacklozenge (amssymb), BLACK MEDIUM LOZENGE
02B28^⬨^^\mdwhtlozenge^^mathord^^# \lozenge (amssymb), WHITE MEDIUM LOZENGE
02B29^⬩^^\smblkdiamond^^mathord^^BLACK SMALL DIAMOND
02B2A^⬪^^\smblklozenge^^mathord^^BLACK SMALL LOZENGE
02B2B^⬫^^\smwhtlozenge^^mathord^^WHITE SMALL LOZENGE
02B2C^⬬^^\blkhorzoval^^mathord^^BLACK HORIZONTAL ELLIPSE
02B2D^⬭^^\whthorzoval^^mathord^^WHITE HORIZONTAL ELLIPSE
02B2E^⬮^^\blkvertoval^^mathord^^BLACK VERTICAL ELLIPSE
02B2F^⬯^^\whtvertoval^^mathord^^WHITE VERTICAL ELLIPSE
02B30^⬰^^\circleonleftarrow^^mathrel^^LEFT ARROW WITH SMALL CIRCLE
02B31^⬱^^\leftthreearrows^^mathrel^^THREE LEFTWARDS ARROWS
02B32^⬲^^\leftarrowonoplus^^mathrel^^LEFT ARROW WITH CIRCLED PLUS
02B33^⬳^^\longleftsquigarrow^^mathrel^^LONG LEFTWARDS SQUIGGLE ARROW
02B34^⬴^^\nvtwoheadleftarrow^^mathrel^^LEFTWARDS TWO-HEADED ARROW WITH VERTICAL STROKE
02B35^⬵^^\nVtwoheadleftarrow^^mathrel^^LEFTWARDS TWO-HEADED ARROW WITH DOUBLE VERTICAL STROKE
02B36^⬶^^\twoheadmapsfrom^^mathrel^^LEFTWARDS TWO-HEADED ARROW FROM BAR
02B37^⬷^^\twoheadleftdbkarrow^^mathrel^^leftwards two-headed triple-dash arrow
02B38^⬸^^\leftdotarrow^^mathrel^^LEFTWARDS ARROW WITH DOTTED STEM
02B39^⬹^^\nvleftarrowtail^^mathrel^^LEFTWARDS ARROW WITH TAIL WITH VERTICAL STROKE
02B3A^⬺^^\nVleftarrowtail^^mathrel^^LEFTWARDS ARROW WITH TAIL WITH DOUBLE VERTICAL STROKE
02B3B^⬻^^\twoheadleftarrowtail^^mathrel^^LEFTWARDS TWO-HEADED ARROW WITH TAIL
02B3C^⬼^^\nvtwoheadleftarrowtail^^mathrel^^LEFTWARDS TWO-HEADED ARROW WITH TAIL WITH VERTICAL STROKE
02B3D^⬽^^\nVtwoheadleftarrowtail^^mathrel^^LEFTWARDS TWO-HEADED ARROW WITH TAIL WITH DOUBLE VERTICAL STROKE
02B3E^⬾^^\leftarrowx^^mathrel^^LEFTWARDS ARROW THROUGH X
02B3F^⬿^^\leftcurvedarrow^^mathrel^^WAVE ARROW POINTING DIRECTLY LEFT
02B40^⭀^^\equalleftarrow^^mathrel^^EQUALS SIGN ABOVE LEFTWARDS ARROW
02B41^⭁^^\bsimilarleftarrow^^mathrel^^REVERSE TILDE OPERATOR ABOVE LEFTWARDS ARROW
02B42^⭂^^\leftarrowbackapprox^^mathrel^^LEFTWARDS ARROW ABOVE REVERSE ALMOST EQUAL TO
02B43^⭃^^\rightarrowgtr^^mathrel^^rightwards arrow through less-than
02B44^⭄^^\rightarrowsupset^^mathrel^^rightwards arrow through subset
02B45^⭅^^\LLeftarrow^^mathrel^^LEFTWARDS QUADRUPLE ARROW
02B46^⭆^^\RRightarrow^^mathrel^^RIGHTWARDS QUADRUPLE ARROW
02B47^⭇^^\bsimilarrightarrow^^mathrel^^REVERSE TILDE OPERATOR ABOVE RIGHTWARDS ARROW
02B48^⭈^^\rightarrowbackapprox^^mathrel^^RIGHTWARDS ARROW ABOVE REVERSE ALMOST EQUAL TO
02B49^⭉^^\similarleftarrow^^mathrel^^TILDE OPERATOR ABOVE LEFTWARDS ARROW
02B4A^⭊^^\leftarrowapprox^^mathrel^^LEFTWARDS ARROW ABOVE ALMOST EQUAL TO
02B4B^⭋^^\leftarrowbsimilar^^mathrel^^LEFTWARDS ARROW ABOVE REVERSE TILDE OPERATOR
02B4C^⭌^^\rightarrowbsimilar^^mathrel^^righttwards arrow above reverse tilde operator
02B50^⭐^^\medwhitestar^^mathord^^WHITE MEDIUM STAR
02B51^⭑^^\medblackstar^^mathord^^black medium star
02B52^⭒^^\smwhitestar^^mathord^^WHITE SMALL STAR
02B53^⭓^^\rightpentagonblack^^mathord^^BLACK RIGHT-POINTING PENTAGON
02B54^⭔^^\rightpentagon^^mathord^^WHITE RIGHT-POINTING PENTAGON
03008^〈^^^X^mathopen^^# \langle, LEFT ANGLE BRACKET (deprecated for math use)
03009^〉^^^X^mathclose^^# \rangle, RIGHT ANGLE BRACKET (deprecated for math use)
03012^〒^^\postalmark^^mathord^^POSTAL MARK
03014^〔^^\lbrbrak^^mathopen^^left broken bracket
03015^〕^^\rbrbrak^^mathclose^^right broken bracket
03018^〘^^\Lbrbrak^^mathopen^^LEFT WHITE TORTOISE SHELL BRACKET
03019^〙^^\Rbrbrak^^mathclose^^RIGHT WHITE TORTOISE SHELL BRACKET
0301A^〚^^^X^mathopen^^# \llbracket (stmaryrd), LEFT WHITE SQUARE BRACKET (deprecated for math use)
0301B^〛^^^X^mathclose^^# \rrbracket (stmaryrd), RIGHT WHITE SQUARE BRACKET (deprecated for math use)
03030^〰^^\hzigzag^^mathord^^zigzag
0306E^の^^^N^mathalpha^^HIRAGANA LETTER NO
0FB29^﬩^^^X^mathord^^HEBREW LETTER ALTERNATIVE PLUS SIGN (doesn't have cross shape)
0FE00^︀^^^D^mathaccent^^VARIATION SELECTOR-1
0FE61^﹡^^^X^^^SMALL ASTERISK
0FE62^﹢^^^X^mathord^^SMALL PLUS SIGN
0FE63^﹣^^^X^mathord^^SMALL HYPHEN-MINUS
0FE64^﹤^^^X^mathord^^SMALL LESS-THAN SIGN
0FE65^﹥^^^X^mathord^^SMALL GREATER-THAN SIGN
0FE66^﹦^^^X^mathord^^SMALL EQUALS SIGN
0FE68^﹨^^^X^^^SMALL REVERSE SOLIDUS
0FF0B^+^^^X^mathord^^FULLWIDTH PLUS SIGN
0FF1C^<^^^X^mathord^^FULLWIDTH LESS-THAN SIGN
0FF1D^=^^^X^mathord^^FULLWIDTH EQUALS SIGN
0FF1E^>^^^X^mathord^^FULLWIDTH GREATER-THAN SIGN
0FF3C^\^^^X^^^FULLWIDTH REVERSE SOLIDUS
0FF3E^^^^^X^mathord^^FULLWIDTH CIRCUMFLEX ACCENT
0FF5C^|^^^X^mathord^^FULLWIDTH VERTICAL LINE
0FF5E^~^^^X^mathord^^FULLWIDTH TILDE
0FFE2^¬^^^X^mathord^^FULLWIDTH NOT SIGN
0FFE9^←^^^X^mathord^^HALFWIDTH LEFTWARDS ARROW
0FFEA^↑^^^X^mathord^^HALFWIDTH UPWARDS ARROW
0FFEB^→^^^X^mathord^^HALFWIDTH RIGHTWARDS ARROW
0FFEC^↓^^^X^mathord^^HALFWIDTH DOWNWARDS ARROW
1D400^𝐀^\mathbf{A}^\mbfA^A^mathalpha^^MATHEMATICAL BOLD CAPITAL A
1D401^𝐁^\mathbf{B}^\mbfB^A^mathalpha^^MATHEMATICAL BOLD CAPITAL B
1D402^𝐂^\mathbf{C}^\mbfC^A^mathalpha^^MATHEMATICAL BOLD CAPITAL C
1D403^𝐃^\mathbf{D}^\mbfD^A^mathalpha^^MATHEMATICAL BOLD CAPITAL D
1D404^𝐄^\mathbf{E}^\mbfE^A^mathalpha^^MATHEMATICAL BOLD CAPITAL E
1D405^𝐅^\mathbf{F}^\mbfF^A^mathalpha^^MATHEMATICAL BOLD CAPITAL F
1D406^𝐆^\mathbf{G}^\mbfG^A^mathalpha^^MATHEMATICAL BOLD CAPITAL G
1D407^𝐇^\mathbf{H}^\mbfH^A^mathalpha^^MATHEMATICAL BOLD CAPITAL H
1D408^𝐈^\mathbf{I}^\mbfI^A^mathalpha^^MATHEMATICAL BOLD CAPITAL I
1D409^𝐉^\mathbf{J}^\mbfJ^A^mathalpha^^MATHEMATICAL BOLD CAPITAL J
1D40A^𝐊^\mathbf{K}^\mbfK^A^mathalpha^^MATHEMATICAL BOLD CAPITAL K
1D40B^𝐋^\mathbf{L}^\mbfL^A^mathalpha^^MATHEMATICAL BOLD CAPITAL L
1D40C^𝐌^\mathbf{M}^\mbfM^A^mathalpha^^MATHEMATICAL BOLD CAPITAL M
1D40D^𝐍^\mathbf{N}^\mbfN^A^mathalpha^^MATHEMATICAL BOLD CAPITAL N
1D40E^𝐎^\mathbf{O}^\mbfO^A^mathalpha^^MATHEMATICAL BOLD CAPITAL O
1D40F^𝐏^\mathbf{P}^\mbfP^A^mathalpha^^MATHEMATICAL BOLD CAPITAL P
1D410^𝐐^\mathbf{Q}^\mbfQ^A^mathalpha^^MATHEMATICAL BOLD CAPITAL Q
1D411^𝐑^\mathbf{R}^\mbfR^A^mathalpha^^MATHEMATICAL BOLD CAPITAL R
1D412^𝐒^\mathbf{S}^\mbfS^A^mathalpha^^MATHEMATICAL BOLD CAPITAL S
1D413^𝐓^\mathbf{T}^\mbfT^A^mathalpha^^MATHEMATICAL BOLD CAPITAL T
1D414^𝐔^\mathbf{U}^\mbfU^A^mathalpha^^MATHEMATICAL BOLD CAPITAL U
1D415^𝐕^\mathbf{V}^\mbfV^A^mathalpha^^MATHEMATICAL BOLD CAPITAL V
1D416^𝐖^\mathbf{W}^\mbfW^A^mathalpha^^MATHEMATICAL BOLD CAPITAL W
1D417^𝐗^\mathbf{X}^\mbfX^A^mathalpha^^MATHEMATICAL BOLD CAPITAL X
1D418^𝐘^\mathbf{Y}^\mbfY^A^mathalpha^^MATHEMATICAL BOLD CAPITAL Y
1D419^𝐙^\mathbf{Z}^\mbfZ^A^mathalpha^^MATHEMATICAL BOLD CAPITAL Z
1D41A^𝐚^\mathbf{a}^\mbfa^A^mathalpha^^MATHEMATICAL BOLD SMALL A
1D41B^𝐛^\mathbf{b}^\mbfb^A^mathalpha^^MATHEMATICAL BOLD SMALL B
1D41C^𝐜^\mathbf{c}^\mbfc^A^mathalpha^^MATHEMATICAL BOLD SMALL C
1D41D^𝐝^\mathbf{d}^\mbfd^A^mathalpha^^MATHEMATICAL BOLD SMALL D
1D41E^𝐞^\mathbf{e}^\mbfe^A^mathalpha^^MATHEMATICAL BOLD SMALL E
1D41F^𝐟^\mathbf{f}^\mbff^A^mathalpha^^MATHEMATICAL BOLD SMALL F
1D420^𝐠^\mathbf{g}^\mbfg^A^mathalpha^^MATHEMATICAL BOLD SMALL G
1D421^𝐡^\mathbf{h}^\mbfh^A^mathalpha^^MATHEMATICAL BOLD SMALL H
1D422^𝐢^\mathbf{i}^\mbfi^A^mathalpha^^MATHEMATICAL BOLD SMALL I
1D423^𝐣^\mathbf{j}^\mbfj^A^mathalpha^^MATHEMATICAL BOLD SMALL J
1D424^𝐤^\mathbf{k}^\mbfk^A^mathalpha^^MATHEMATICAL BOLD SMALL K
1D425^𝐥^\mathbf{l}^\mbfl^A^mathalpha^^MATHEMATICAL BOLD SMALL L
1D426^𝐦^\mathbf{m}^\mbfm^A^mathalpha^^MATHEMATICAL BOLD SMALL M
1D427^𝐧^\mathbf{n}^\mbfn^A^mathalpha^^MATHEMATICAL BOLD SMALL N
1D428^𝐨^\mathbf{o}^\mbfo^A^mathalpha^^MATHEMATICAL BOLD SMALL O
1D429^𝐩^\mathbf{p}^\mbfp^A^mathalpha^^MATHEMATICAL BOLD SMALL P
1D42A^𝐪^\mathbf{q}^\mbfq^A^mathalpha^^MATHEMATICAL BOLD SMALL Q
1D42B^𝐫^\mathbf{r}^\mbfr^A^mathalpha^^MATHEMATICAL BOLD SMALL R
1D42C^𝐬^\mathbf{s}^\mbfs^A^mathalpha^^MATHEMATICAL BOLD SMALL S
1D42D^𝐭^\mathbf{t}^\mbft^A^mathalpha^^MATHEMATICAL BOLD SMALL T
1D42E^𝐮^\mathbf{u}^\mbfu^A^mathalpha^^MATHEMATICAL BOLD SMALL U
1D42F^𝐯^\mathbf{v}^\mbfv^A^mathalpha^^MATHEMATICAL BOLD SMALL V
1D430^𝐰^\mathbf{w}^\mbfw^A^mathalpha^^MATHEMATICAL BOLD SMALL W
1D431^𝐱^\mathbf{x}^\mbfx^A^mathalpha^^MATHEMATICAL BOLD SMALL X
1D432^𝐲^\mathbf{y}^\mbfy^A^mathalpha^^MATHEMATICAL BOLD SMALL Y
1D433^𝐳^\mathbf{z}^\mbfz^A^mathalpha^^MATHEMATICAL BOLD SMALL Z
1D434^𝐴^A^\mitA^A^mathalpha^-frenchstyle^= \mathit{A}, MATHEMATICAL ITALIC CAPITAL A
1D435^𝐵^B^\mitB^A^mathalpha^-frenchstyle^= \mathit{B}, MATHEMATICAL ITALIC CAPITAL B
1D436^𝐶^C^\mitC^A^mathalpha^-frenchstyle^= \mathit{C}, MATHEMATICAL ITALIC CAPITAL C
1D437^𝐷^D^\mitD^A^mathalpha^-frenchstyle^= \mathit{D}, MATHEMATICAL ITALIC CAPITAL D
1D438^𝐸^E^\mitE^A^mathalpha^-frenchstyle^= \mathit{E}, MATHEMATICAL ITALIC CAPITAL E
1D439^𝐹^F^\mitF^A^mathalpha^-frenchstyle^= \mathit{F}, MATHEMATICAL ITALIC CAPITAL F
1D43A^𝐺^G^\mitG^A^mathalpha^-frenchstyle^= \mathit{G}, MATHEMATICAL ITALIC CAPITAL G
1D43B^𝐻^H^\mitH^A^mathalpha^-frenchstyle^= \mathit{H}, MATHEMATICAL ITALIC CAPITAL H
1D43C^𝐼^I^\mitI^A^mathalpha^-frenchstyle^= \mathit{I}, MATHEMATICAL ITALIC CAPITAL I
1D43D^𝐽^J^\mitJ^A^mathalpha^-frenchstyle^= \mathit{J}, MATHEMATICAL ITALIC CAPITAL J
1D43E^𝐾^K^\mitK^A^mathalpha^-frenchstyle^= \mathit{K}, MATHEMATICAL ITALIC CAPITAL K
1D43F^𝐿^L^\mitL^A^mathalpha^-frenchstyle^= \mathit{L}, MATHEMATICAL ITALIC CAPITAL L
1D440^𝑀^M^\mitM^A^mathalpha^-frenchstyle^= \mathit{M}, MATHEMATICAL ITALIC CAPITAL M
1D441^𝑁^N^\mitN^A^mathalpha^-frenchstyle^= \mathit{N}, MATHEMATICAL ITALIC CAPITAL N
1D442^𝑂^O^\mitO^A^mathalpha^-frenchstyle^= \mathit{O}, MATHEMATICAL ITALIC CAPITAL O
1D443^𝑃^P^\mitP^A^mathalpha^-frenchstyle^= \mathit{P}, MATHEMATICAL ITALIC CAPITAL P
1D444^𝑄^Q^\mitQ^A^mathalpha^-frenchstyle^= \mathit{Q}, MATHEMATICAL ITALIC CAPITAL Q
1D445^𝑅^R^\mitR^A^mathalpha^-frenchstyle^= \mathit{R}, MATHEMATICAL ITALIC CAPITAL R
1D446^𝑆^S^\mitS^A^mathalpha^-frenchstyle^= \mathit{S}, MATHEMATICAL ITALIC CAPITAL S
1D447^𝑇^T^\mitT^A^mathalpha^-frenchstyle^= \mathit{T}, MATHEMATICAL ITALIC CAPITAL T
1D448^𝑈^U^\mitU^A^mathalpha^-frenchstyle^= \mathit{U}, MATHEMATICAL ITALIC CAPITAL U
1D449^𝑉^V^\mitV^A^mathalpha^-frenchstyle^= \mathit{V}, MATHEMATICAL ITALIC CAPITAL V
1D44A^𝑊^W^\mitW^A^mathalpha^-frenchstyle^= \mathit{W}, MATHEMATICAL ITALIC CAPITAL W
1D44B^𝑋^X^\mitX^A^mathalpha^-frenchstyle^= \mathit{X}, MATHEMATICAL ITALIC CAPITAL X
1D44C^𝑌^Y^\mitY^A^mathalpha^-frenchstyle^= \mathit{Y}, MATHEMATICAL ITALIC CAPITAL Y
1D44D^𝑍^Z^\mitZ^A^mathalpha^-frenchstyle^= \mathit{Z}, MATHEMATICAL ITALIC CAPITAL Z
1D44E^𝑎^a^\mita^A^mathalpha^-uprightstyle^= \mathit{a}, MATHEMATICAL ITALIC SMALL A
1D44F^𝑏^b^\mitb^A^mathalpha^-uprightstyle^= \mathit{b}, MATHEMATICAL ITALIC SMALL B
1D450^𝑐^c^\mitc^A^mathalpha^-uprightstyle^= \mathit{c}, MATHEMATICAL ITALIC SMALL C
1D451^𝑑^d^\mitd^A^mathalpha^-uprightstyle^= \mathit{d}, MATHEMATICAL ITALIC SMALL D
1D452^𝑒^e^\mite^A^mathalpha^-uprightstyle^= \mathit{e}, MATHEMATICAL ITALIC SMALL E
1D453^𝑓^f^\mitf^A^mathalpha^-uprightstyle^= \mathit{f}, MATHEMATICAL ITALIC SMALL F
1D454^𝑔^g^\mitg^A^mathalpha^-uprightstyle^= \mathit{g}, MATHEMATICAL ITALIC SMALL G
1D456^𝑖^i^\miti^A^mathalpha^-uprightstyle^= \mathit{i}, MATHEMATICAL ITALIC SMALL I
1D457^𝑗^j^\mitj^A^mathalpha^-uprightstyle^= \mathit{j}, MATHEMATICAL ITALIC SMALL J
1D458^𝑘^k^\mitk^A^mathalpha^-uprightstyle^= \mathit{k}, MATHEMATICAL ITALIC SMALL K
1D459^𝑙^l^\mitl^A^mathalpha^-uprightstyle^= \mathit{l}, MATHEMATICAL ITALIC SMALL L
1D45A^𝑚^m^\mitm^A^mathalpha^-uprightstyle^= \mathit{m}, MATHEMATICAL ITALIC SMALL M
1D45B^𝑛^n^\mitn^A^mathalpha^-uprightstyle^= \mathit{n}, MATHEMATICAL ITALIC SMALL N
1D45C^𝑜^o^\mito^A^mathalpha^-uprightstyle^= \mathit{o}, MATHEMATICAL ITALIC SMALL O
1D45D^𝑝^p^\mitp^A^mathalpha^-uprightstyle^= \mathit{p}, MATHEMATICAL ITALIC SMALL P
1D45E^𝑞^q^\mitq^A^mathalpha^-uprightstyle^= \mathit{q}, MATHEMATICAL ITALIC SMALL Q
1D45F^𝑟^r^\mitr^A^mathalpha^-uprightstyle^= \mathit{r}, MATHEMATICAL ITALIC SMALL R
1D460^𝑠^s^\mits^A^mathalpha^-uprightstyle^= \mathit{s}, MATHEMATICAL ITALIC SMALL S
1D461^𝑡^t^\mitt^A^mathalpha^-uprightstyle^= \mathit{t}, MATHEMATICAL ITALIC SMALL T
1D462^𝑢^u^\mitu^A^mathalpha^-uprightstyle^= \mathit{u}, MATHEMATICAL ITALIC SMALL U
1D463^𝑣^v^\mitv^A^mathalpha^-uprightstyle^= \mathit{v}, MATHEMATICAL ITALIC SMALL V
1D464^𝑤^w^\mitw^A^mathalpha^-uprightstyle^= \mathit{w}, MATHEMATICAL ITALIC SMALL W
1D465^𝑥^x^\mitx^A^mathalpha^-uprightstyle^= \mathit{x}, MATHEMATICAL ITALIC SMALL X
1D466^𝑦^y^\mity^A^mathalpha^-uprightstyle^= \mathit{y}, MATHEMATICAL ITALIC SMALL Y
1D467^𝑧^z^\mitz^A^mathalpha^-uprightstyle^= \mathit{z}, MATHEMATICAL ITALIC SMALL Z
1D468^𝑨^\mathbfit{A}^\mbfitA^A^mathalpha^isomath^= \mathbold{A} (fixmath), MATHEMATICAL BOLD ITALIC CAPITAL A
1D469^𝑩^\mathbfit{B}^\mbfitB^A^mathalpha^isomath^= \mathbold{B} (fixmath), MATHEMATICAL BOLD ITALIC CAPITAL B
1D46A^𝑪^\mathbfit{C}^\mbfitC^A^mathalpha^isomath^= \mathbold{C} (fixmath), MATHEMATICAL BOLD ITALIC CAPITAL C
1D46B^𝑫^\mathbfit{D}^\mbfitD^A^mathalpha^isomath^= \mathbold{D} (fixmath), MATHEMATICAL BOLD ITALIC CAPITAL D
1D46C^𝑬^\mathbfit{E}^\mbfitE^A^mathalpha^isomath^= \mathbold{E} (fixmath), MATHEMATICAL BOLD ITALIC CAPITAL E
1D46D^𝑭^\mathbfit{F}^\mbfitF^A^mathalpha^isomath^= \mathbold{F} (fixmath), MATHEMATICAL BOLD ITALIC CAPITAL F
1D46E^𝑮^\mathbfit{G}^\mbfitG^A^mathalpha^isomath^= \mathbold{G} (fixmath), MATHEMATICAL BOLD ITALIC CAPITAL G
1D46F^𝑯^\mathbfit{H}^\mbfitH^A^mathalpha^isomath^= \mathbold{H} (fixmath), MATHEMATICAL BOLD ITALIC CAPITAL H
1D470^𝑰^\mathbfit{I}^\mbfitI^A^mathalpha^isomath^= \mathbold{I} (fixmath), MATHEMATICAL BOLD ITALIC CAPITAL I
1D471^𝑱^\mathbfit{J}^\mbfitJ^A^mathalpha^isomath^= \mathbold{J} (fixmath), MATHEMATICAL BOLD ITALIC CAPITAL J
1D472^𝑲^\mathbfit{K}^\mbfitK^A^mathalpha^isomath^= \mathbold{K} (fixmath), MATHEMATICAL BOLD ITALIC CAPITAL K
1D473^𝑳^\mathbfit{L}^\mbfitL^A^mathalpha^isomath^= \mathbold{L} (fixmath), MATHEMATICAL BOLD ITALIC CAPITAL L
1D474^𝑴^\mathbfit{M}^\mbfitM^A^mathalpha^isomath^= \mathbold{M} (fixmath), MATHEMATICAL BOLD ITALIC CAPITAL M
1D475^𝑵^\mathbfit{N}^\mbfitN^A^mathalpha^isomath^= \mathbold{N} (fixmath), MATHEMATICAL BOLD ITALIC CAPITAL N
1D476^𝑶^\mathbfit{O}^\mbfitO^A^mathalpha^isomath^= \mathbold{O} (fixmath), MATHEMATICAL BOLD ITALIC CAPITAL O
1D477^𝑷^\mathbfit{P}^\mbfitP^A^mathalpha^isomath^= \mathbold{P} (fixmath), MATHEMATICAL BOLD ITALIC CAPITAL P
1D478^𝑸^\mathbfit{Q}^\mbfitQ^A^mathalpha^isomath^= \mathbold{Q} (fixmath), MATHEMATICAL BOLD ITALIC CAPITAL Q
1D479^𝑹^\mathbfit{R}^\mbfitR^A^mathalpha^isomath^= \mathbold{R} (fixmath), MATHEMATICAL BOLD ITALIC CAPITAL R
1D47A^𝑺^\mathbfit{S}^\mbfitS^A^mathalpha^isomath^= \mathbold{S} (fixmath), MATHEMATICAL BOLD ITALIC CAPITAL S
1D47B^𝑻^\mathbfit{T}^\mbfitT^A^mathalpha^isomath^= \mathbold{T} (fixmath), MATHEMATICAL BOLD ITALIC CAPITAL T
1D47C^𝑼^\mathbfit{U}^\mbfitU^A^mathalpha^isomath^= \mathbold{U} (fixmath), MATHEMATICAL BOLD ITALIC CAPITAL U
1D47D^𝑽^\mathbfit{V}^\mbfitV^A^mathalpha^isomath^= \mathbold{V} (fixmath), MATHEMATICAL BOLD ITALIC CAPITAL V
1D47E^𝑾^\mathbfit{W}^\mbfitW^A^mathalpha^isomath^= \mathbold{W} (fixmath), MATHEMATICAL BOLD ITALIC CAPITAL W
1D47F^𝑿^\mathbfit{X}^\mbfitX^A^mathalpha^isomath^= \mathbold{X} (fixmath), MATHEMATICAL BOLD ITALIC CAPITAL X
1D480^𝒀^\mathbfit{Y}^\mbfitY^A^mathalpha^isomath^= \mathbold{Y} (fixmath), MATHEMATICAL BOLD ITALIC CAPITAL Y
1D481^𝒁^\mathbfit{Z}^\mbfitZ^A^mathalpha^isomath^= \mathbold{Z} (fixmath), MATHEMATICAL BOLD ITALIC CAPITAL Z
1D482^𝒂^\mathbfit{a}^\mbfita^A^mathalpha^isomath^= \mathbold{a} (fixmath), MATHEMATICAL BOLD ITALIC SMALL A
1D483^𝒃^\mathbfit{b}^\mbfitb^A^mathalpha^isomath^= \mathbold{b} (fixmath), MATHEMATICAL BOLD ITALIC SMALL B
1D484^𝒄^\mathbfit{c}^\mbfitc^A^mathalpha^isomath^= \mathbold{c} (fixmath), MATHEMATICAL BOLD ITALIC SMALL C
1D485^𝒅^\mathbfit{d}^\mbfitd^A^mathalpha^isomath^= \mathbold{d} (fixmath), MATHEMATICAL BOLD ITALIC SMALL D
1D486^𝒆^\mathbfit{e}^\mbfite^A^mathalpha^isomath^= \mathbold{e} (fixmath), MATHEMATICAL BOLD ITALIC SMALL E
1D487^𝒇^\mathbfit{f}^\mbfitf^A^mathalpha^isomath^= \mathbold{f} (fixmath), MATHEMATICAL BOLD ITALIC SMALL F
1D488^𝒈^\mathbfit{g}^\mbfitg^A^mathalpha^isomath^= \mathbold{g} (fixmath), MATHEMATICAL BOLD ITALIC SMALL G
1D489^𝒉^\mathbfit{h}^\mbfith^A^mathalpha^isomath^= \mathbold{h} (fixmath), MATHEMATICAL BOLD ITALIC SMALL H
1D48A^𝒊^\mathbfit{i}^\mbfiti^A^mathalpha^isomath^= \mathbold{i} (fixmath), MATHEMATICAL BOLD ITALIC SMALL I
1D48B^𝒋^\mathbfit{j}^\mbfitj^A^mathalpha^isomath^= \mathbold{j} (fixmath), MATHEMATICAL BOLD ITALIC SMALL J
1D48C^𝒌^\mathbfit{k}^\mbfitk^A^mathalpha^isomath^= \mathbold{k} (fixmath), MATHEMATICAL BOLD ITALIC SMALL K
1D48D^𝒍^\mathbfit{l}^\mbfitl^A^mathalpha^isomath^= \mathbold{l} (fixmath), MATHEMATICAL BOLD ITALIC SMALL L
1D48E^𝒎^\mathbfit{m}^\mbfitm^A^mathalpha^isomath^= \mathbold{m} (fixmath), MATHEMATICAL BOLD ITALIC SMALL M
1D48F^𝒏^\mathbfit{n}^\mbfitn^A^mathalpha^isomath^= \mathbold{n} (fixmath), MATHEMATICAL BOLD ITALIC SMALL N
1D490^𝒐^\mathbfit{o}^\mbfito^A^mathalpha^isomath^= \mathbold{o} (fixmath), MATHEMATICAL BOLD ITALIC SMALL O
1D491^𝒑^\mathbfit{p}^\mbfitp^A^mathalpha^isomath^= \mathbold{p} (fixmath), MATHEMATICAL BOLD ITALIC SMALL P
1D492^𝒒^\mathbfit{q}^\mbfitq^A^mathalpha^isomath^= \mathbold{q} (fixmath), MATHEMATICAL BOLD ITALIC SMALL Q
1D493^𝒓^\mathbfit{r}^\mbfitr^A^mathalpha^isomath^= \mathbold{r} (fixmath), MATHEMATICAL BOLD ITALIC SMALL R
1D494^𝒔^\mathbfit{s}^\mbfits^A^mathalpha^isomath^= \mathbold{s} (fixmath), MATHEMATICAL BOLD ITALIC SMALL S
1D495^𝒕^\mathbfit{t}^\mbfitt^A^mathalpha^isomath^= \mathbold{t} (fixmath), MATHEMATICAL BOLD ITALIC SMALL T
1D496^𝒖^\mathbfit{u}^\mbfitu^A^mathalpha^isomath^= \mathbold{u} (fixmath), MATHEMATICAL BOLD ITALIC SMALL U
1D497^𝒗^\mathbfit{v}^\mbfitv^A^mathalpha^isomath^= \mathbold{v} (fixmath), MATHEMATICAL BOLD ITALIC SMALL V
1D498^𝒘^\mathbfit{w}^\mbfitw^A^mathalpha^isomath^= \mathbold{w} (fixmath), MATHEMATICAL BOLD ITALIC SMALL W
1D499^𝒙^\mathbfit{x}^\mbfitx^A^mathalpha^isomath^= \mathbold{x} (fixmath), MATHEMATICAL BOLD ITALIC SMALL X
1D49A^𝒚^\mathbfit{y}^\mbfity^A^mathalpha^isomath^= \mathbold{y} (fixmath), MATHEMATICAL BOLD ITALIC SMALL Y
1D49B^𝒛^\mathbfit{z}^\mbfitz^A^mathalpha^isomath^= \mathbold{z} (fixmath), MATHEMATICAL BOLD ITALIC SMALL Z
1D49C^𝒜^\mathcal{A}^\mscrA^A^mathalpha^^MATHEMATICAL SCRIPT CAPITAL A
1D49E^𝒞^\mathcal{C}^\mscrC^A^mathalpha^^MATHEMATICAL SCRIPT CAPITAL C
1D49F^𝒟^\mathcal{D}^\mscrD^A^mathalpha^^MATHEMATICAL SCRIPT CAPITAL D
1D4A2^𝒢^\mathcal{G}^\mscrG^A^mathalpha^^MATHEMATICAL SCRIPT CAPITAL G
1D4A5^𝒥^\mathcal{J}^\mscrJ^A^mathalpha^^MATHEMATICAL SCRIPT CAPITAL J
1D4A6^𝒦^\mathcal{K}^\mscrK^A^mathalpha^^MATHEMATICAL SCRIPT CAPITAL K
1D4A9^𝒩^\mathcal{N}^\mscrN^A^mathalpha^^MATHEMATICAL SCRIPT CAPITAL N
1D4AA^𝒪^\mathcal{O}^\mscrO^A^mathalpha^^MATHEMATICAL SCRIPT CAPITAL O
1D4AB^𝒫^\mathcal{P}^\mscrP^A^mathalpha^^MATHEMATICAL SCRIPT CAPITAL P
1D4AC^𝒬^\mathcal{Q}^\mscrQ^A^mathalpha^^MATHEMATICAL SCRIPT CAPITAL Q
1D4AE^𝒮^\mathcal{S}^\mscrS^A^mathalpha^^MATHEMATICAL SCRIPT CAPITAL S
1D4AF^𝒯^\mathcal{T}^\mscrT^A^mathalpha^^MATHEMATICAL SCRIPT CAPITAL T
1D4B0^𝒰^\mathcal{U}^\mscrU^A^mathalpha^^MATHEMATICAL SCRIPT CAPITAL U
1D4B1^𝒱^\mathcal{V}^\mscrV^A^mathalpha^^MATHEMATICAL SCRIPT CAPITAL V
1D4B2^𝒲^\mathcal{W}^\mscrW^A^mathalpha^^MATHEMATICAL SCRIPT CAPITAL W
1D4B3^𝒳^\mathcal{X}^\mscrX^A^mathalpha^^MATHEMATICAL SCRIPT CAPITAL X
1D4B4^𝒴^\mathcal{Y}^\mscrY^A^mathalpha^^MATHEMATICAL SCRIPT CAPITAL Y
1D4B5^𝒵^\mathcal{Z}^\mscrZ^A^mathalpha^^MATHEMATICAL SCRIPT CAPITAL Z
1D4B6^𝒶^\mathcal{a}^\mscra^A^mathalpha^urwchancal^MATHEMATICAL SCRIPT SMALL A
1D4B7^𝒷^\mathcal{b}^\mscrb^A^mathalpha^urwchancal^MATHEMATICAL SCRIPT SMALL B
1D4B8^𝒸^\mathcal{c}^\mscrc^A^mathalpha^urwchancal^MATHEMATICAL SCRIPT SMALL C
1D4B9^𝒹^\mathcal{d}^\mscrd^A^mathalpha^urwchancal^MATHEMATICAL SCRIPT SMALL D
1D4BB^𝒻^\mathcal{f}^\mscrf^A^mathalpha^urwchancal^MATHEMATICAL SCRIPT SMALL F
1D4BD^𝒽^\mathcal{h}^\mscrh^A^mathalpha^urwchancal^MATHEMATICAL SCRIPT SMALL H
1D4BE^𝒾^\mathcal{i}^\mscri^A^mathalpha^urwchancal^MATHEMATICAL SCRIPT SMALL I
1D4BF^𝒿^\mathcal{j}^\mscrj^A^mathalpha^urwchancal^MATHEMATICAL SCRIPT SMALL J
1D4C0^𝓀^\mathcal{k}^\mscrk^A^mathalpha^urwchancal^MATHEMATICAL SCRIPT SMALL K
1D4C1^𝓁^\mathcal{l}^\mscrl^A^mathalpha^urwchancal^MATHEMATICAL SCRIPT SMALL L
1D4C2^𝓂^\mathcal{m}^\mscrm^A^mathalpha^urwchancal^MATHEMATICAL SCRIPT SMALL M
1D4C3^𝓃^\mathcal{n}^\mscrn^A^mathalpha^urwchancal^MATHEMATICAL SCRIPT SMALL N
1D4C5^𝓅^\mathcal{p}^\mscrp^A^mathalpha^urwchancal^MATHEMATICAL SCRIPT SMALL P
1D4C6^𝓆^\mathcal{q}^\mscrq^A^mathalpha^urwchancal^MATHEMATICAL SCRIPT SMALL Q
1D4C7^𝓇^\mathcal{r}^\mscrr^A^mathalpha^urwchancal^MATHEMATICAL SCRIPT SMALL R
1D4C8^𝓈^\mathcal{s}^\mscrs^A^mathalpha^urwchancal^MATHEMATICAL SCRIPT SMALL S
1D4C9^𝓉^\mathcal{t}^\mscrt^A^mathalpha^urwchancal^MATHEMATICAL SCRIPT SMALL T
1D4CA^𝓊^\mathcal{u}^\mscru^A^mathalpha^urwchancal^MATHEMATICAL SCRIPT SMALL U
1D4CB^𝓋^\mathcal{v}^\mscrv^A^mathalpha^urwchancal^MATHEMATICAL SCRIPT SMALL V
1D4CC^𝓌^\mathcal{w}^\mscrw^A^mathalpha^urwchancal^MATHEMATICAL SCRIPT SMALL W
1D4CD^𝓍^\mathcal{x}^\mscrx^A^mathalpha^urwchancal^MATHEMATICAL SCRIPT SMALL X
1D4CE^𝓎^\mathcal{y}^\mscry^A^mathalpha^urwchancal^MATHEMATICAL SCRIPT SMALL Y
1D4CF^𝓏^\mathcal{z}^\mscrz^A^mathalpha^urwchancal^MATHEMATICAL SCRIPT SMALL Z
1D4D0^𝓐^^\mbfscrA^A^mathalpha^^MATHEMATICAL BOLD SCRIPT CAPITAL A
1D4D1^𝓑^^\mbfscrB^A^mathalpha^^MATHEMATICAL BOLD SCRIPT CAPITAL B
1D4D2^𝓒^^\mbfscrC^A^mathalpha^^MATHEMATICAL BOLD SCRIPT CAPITAL C
1D4D3^𝓓^^\mbfscrD^A^mathalpha^^MATHEMATICAL BOLD SCRIPT CAPITAL D
1D4D4^𝓔^^\mbfscrE^A^mathalpha^^MATHEMATICAL BOLD SCRIPT CAPITAL E
1D4D5^𝓕^^\mbfscrF^A^mathalpha^^MATHEMATICAL BOLD SCRIPT CAPITAL F
1D4D6^𝓖^^\mbfscrG^A^mathalpha^^MATHEMATICAL BOLD SCRIPT CAPITAL G
1D4D7^𝓗^^\mbfscrH^A^mathalpha^^MATHEMATICAL BOLD SCRIPT CAPITAL H
1D4D8^𝓘^^\mbfscrI^A^mathalpha^^MATHEMATICAL BOLD SCRIPT CAPITAL I
1D4D9^𝓙^^\mbfscrJ^A^mathalpha^^MATHEMATICAL BOLD SCRIPT CAPITAL J
1D4DA^𝓚^^\mbfscrK^A^mathalpha^^MATHEMATICAL BOLD SCRIPT CAPITAL K
1D4DB^𝓛^^\mbfscrL^A^mathalpha^^MATHEMATICAL BOLD SCRIPT CAPITAL L
1D4DC^𝓜^^\mbfscrM^A^mathalpha^^MATHEMATICAL BOLD SCRIPT CAPITAL M
1D4DD^𝓝^^\mbfscrN^A^mathalpha^^MATHEMATICAL BOLD SCRIPT CAPITAL N
1D4DE^𝓞^^\mbfscrO^A^mathalpha^^MATHEMATICAL BOLD SCRIPT CAPITAL O
1D4DF^𝓟^^\mbfscrP^A^mathalpha^^MATHEMATICAL BOLD SCRIPT CAPITAL P
1D4E0^𝓠^^\mbfscrQ^A^mathalpha^^MATHEMATICAL BOLD SCRIPT CAPITAL Q
1D4E1^𝓡^^\mbfscrR^A^mathalpha^^MATHEMATICAL BOLD SCRIPT CAPITAL R
1D4E2^𝓢^^\mbfscrS^A^mathalpha^^MATHEMATICAL BOLD SCRIPT CAPITAL S
1D4E3^𝓣^^\mbfscrT^A^mathalpha^^MATHEMATICAL BOLD SCRIPT CAPITAL T
1D4E4^𝓤^^\mbfscrU^A^mathalpha^^MATHEMATICAL BOLD SCRIPT CAPITAL U
1D4E5^𝓥^^\mbfscrV^A^mathalpha^^MATHEMATICAL BOLD SCRIPT CAPITAL V
1D4E6^𝓦^^\mbfscrW^A^mathalpha^^MATHEMATICAL BOLD SCRIPT CAPITAL W
1D4E7^𝓧^^\mbfscrX^A^mathalpha^^MATHEMATICAL BOLD SCRIPT CAPITAL X
1D4E8^𝓨^^\mbfscrY^A^mathalpha^^MATHEMATICAL BOLD SCRIPT CAPITAL Y
1D4E9^𝓩^^\mbfscrZ^A^mathalpha^^MATHEMATICAL BOLD SCRIPT CAPITAL Z
1D4EA^𝓪^^\mbfscra^A^mathalpha^^MATHEMATICAL BOLD SCRIPT SMALL A
1D4EB^𝓫^^\mbfscrb^A^mathalpha^^MATHEMATICAL BOLD SCRIPT SMALL B
1D4EC^𝓬^^\mbfscrc^A^mathalpha^^MATHEMATICAL BOLD SCRIPT SMALL C
1D4ED^𝓭^^\mbfscrd^A^mathalpha^^MATHEMATICAL BOLD SCRIPT SMALL D
1D4EE^𝓮^^\mbfscre^A^mathalpha^^MATHEMATICAL BOLD SCRIPT SMALL E
1D4EF^𝓯^^\mbfscrf^A^mathalpha^^MATHEMATICAL BOLD SCRIPT SMALL F
1D4F0^𝓰^^\mbfscrg^A^mathalpha^^MATHEMATICAL BOLD SCRIPT SMALL G
1D4F1^𝓱^^\mbfscrh^A^mathalpha^^MATHEMATICAL BOLD SCRIPT SMALL H
1D4F2^𝓲^^\mbfscri^A^mathalpha^^MATHEMATICAL BOLD SCRIPT SMALL I
1D4F3^𝓳^^\mbfscrj^A^mathalpha^^MATHEMATICAL BOLD SCRIPT SMALL J
1D4F4^𝓴^^\mbfscrk^A^mathalpha^^MATHEMATICAL BOLD SCRIPT SMALL K
1D4F5^𝓵^^\mbfscrl^A^mathalpha^^MATHEMATICAL BOLD SCRIPT SMALL L
1D4F6^𝓶^^\mbfscrm^A^mathalpha^^MATHEMATICAL BOLD SCRIPT SMALL M
1D4F7^𝓷^^\mbfscrn^A^mathalpha^^MATHEMATICAL BOLD SCRIPT SMALL N
1D4F8^𝓸^^\mbfscro^A^mathalpha^^MATHEMATICAL BOLD SCRIPT SMALL O
1D4F9^𝓹^^\mbfscrp^A^mathalpha^^MATHEMATICAL BOLD SCRIPT SMALL P
1D4FA^𝓺^^\mbfscrq^A^mathalpha^^MATHEMATICAL BOLD SCRIPT SMALL Q
1D4FB^𝓻^^\mbfscrr^A^mathalpha^^MATHEMATICAL BOLD SCRIPT SMALL R
1D4FC^𝓼^^\mbfscrs^A^mathalpha^^MATHEMATICAL BOLD SCRIPT SMALL S
1D4FD^𝓽^^\mbfscrt^A^mathalpha^^MATHEMATICAL BOLD SCRIPT SMALL T
1D4FE^𝓾^^\mbfscru^A^mathalpha^^MATHEMATICAL BOLD SCRIPT SMALL U
1D4FF^𝓿^^\mbfscrv^A^mathalpha^^MATHEMATICAL BOLD SCRIPT SMALL V
1D500^𝔀^^\mbfscrw^A^mathalpha^^MATHEMATICAL BOLD SCRIPT SMALL W
1D501^𝔁^^\mbfscrx^A^mathalpha^^MATHEMATICAL BOLD SCRIPT SMALL X
1D502^𝔂^^\mbfscry^A^mathalpha^^MATHEMATICAL BOLD SCRIPT SMALL Y
1D503^𝔃^^\mbfscrz^A^mathalpha^^MATHEMATICAL BOLD SCRIPT SMALL Z
1D504^𝔄^\mathfrak{A}^\mfrakA^A^mathalpha^eufrak^MATHEMATICAL FRAKTUR CAPITAL A
1D505^𝔅^\mathfrak{B}^\mfrakB^A^mathalpha^eufrak^MATHEMATICAL FRAKTUR CAPITAL B
1D507^𝔇^\mathfrak{D}^\mfrakD^A^mathalpha^eufrak^MATHEMATICAL FRAKTUR CAPITAL D
1D508^𝔈^\mathfrak{E}^\mfrakE^A^mathalpha^eufrak^MATHEMATICAL FRAKTUR CAPITAL E
1D509^𝔉^\mathfrak{F}^\mfrakF^A^mathalpha^eufrak^MATHEMATICAL FRAKTUR CAPITAL F
1D50A^𝔊^\mathfrak{G}^\mfrakG^A^mathalpha^eufrak^MATHEMATICAL FRAKTUR CAPITAL G
1D50D^𝔍^\mathfrak{J}^\mfrakJ^A^mathalpha^eufrak^MATHEMATICAL FRAKTUR CAPITAL J
1D50E^𝔎^\mathfrak{K}^\mfrakK^A^mathalpha^eufrak^MATHEMATICAL FRAKTUR CAPITAL K
1D50F^𝔏^\mathfrak{L}^\mfrakL^A^mathalpha^eufrak^MATHEMATICAL FRAKTUR CAPITAL L
1D510^𝔐^\mathfrak{M}^\mfrakM^A^mathalpha^eufrak^MATHEMATICAL FRAKTUR CAPITAL M
1D511^𝔑^\mathfrak{N}^\mfrakN^A^mathalpha^eufrak^MATHEMATICAL FRAKTUR CAPITAL N
1D512^𝔒^\mathfrak{O}^\mfrakO^A^mathalpha^eufrak^MATHEMATICAL FRAKTUR CAPITAL O
1D513^𝔓^\mathfrak{P}^\mfrakP^A^mathalpha^eufrak^MATHEMATICAL FRAKTUR CAPITAL P
1D514^𝔔^\mathfrak{Q}^\mfrakQ^A^mathalpha^eufrak^MATHEMATICAL FRAKTUR CAPITAL Q
1D516^𝔖^\mathfrak{S}^\mfrakS^A^mathalpha^eufrak^MATHEMATICAL FRAKTUR CAPITAL S
1D517^𝔗^\mathfrak{T}^\mfrakT^A^mathalpha^eufrak^MATHEMATICAL FRAKTUR CAPITAL T
1D518^𝔘^\mathfrak{U}^\mfrakU^A^mathalpha^eufrak^MATHEMATICAL FRAKTUR CAPITAL U
1D519^𝔙^\mathfrak{V}^\mfrakV^A^mathalpha^eufrak^MATHEMATICAL FRAKTUR CAPITAL V
1D51A^𝔚^\mathfrak{W}^\mfrakW^A^mathalpha^eufrak^MATHEMATICAL FRAKTUR CAPITAL W
1D51B^𝔛^\mathfrak{X}^\mfrakX^A^mathalpha^eufrak^MATHEMATICAL FRAKTUR CAPITAL X
1D51C^𝔜^\mathfrak{Y}^\mfrakY^A^mathalpha^eufrak^MATHEMATICAL FRAKTUR CAPITAL Y
1D51E^𝔞^\mathfrak{a}^\mfraka^A^mathalpha^eufrak^MATHEMATICAL FRAKTUR SMALL A
1D51F^𝔟^\mathfrak{b}^\mfrakb^A^mathalpha^eufrak^MATHEMATICAL FRAKTUR SMALL B
1D520^𝔠^\mathfrak{c}^\mfrakc^A^mathalpha^eufrak^MATHEMATICAL FRAKTUR SMALL C
1D521^𝔡^\mathfrak{d}^\mfrakd^A^mathalpha^eufrak^MATHEMATICAL FRAKTUR SMALL D
1D522^𝔢^\mathfrak{e}^\mfrake^A^mathalpha^eufrak^MATHEMATICAL FRAKTUR SMALL E
1D523^𝔣^\mathfrak{f}^\mfrakf^A^mathalpha^eufrak^MATHEMATICAL FRAKTUR SMALL F
1D524^𝔤^\mathfrak{g}^\mfrakg^A^mathalpha^eufrak^MATHEMATICAL FRAKTUR SMALL G
1D525^𝔥^\mathfrak{h}^\mfrakh^A^mathalpha^eufrak^MATHEMATICAL FRAKTUR SMALL H
1D526^𝔦^\mathfrak{i}^\mfraki^A^mathalpha^eufrak^MATHEMATICAL FRAKTUR SMALL I
1D527^𝔧^\mathfrak{j}^\mfrakj^A^mathalpha^eufrak^MATHEMATICAL FRAKTUR SMALL J
1D528^𝔨^\mathfrak{k}^\mfrakk^A^mathalpha^eufrak^MATHEMATICAL FRAKTUR SMALL K
1D529^𝔩^\mathfrak{l}^\mfrakl^A^mathalpha^eufrak^MATHEMATICAL FRAKTUR SMALL L
1D52A^𝔪^\mathfrak{m}^\mfrakm^A^mathalpha^eufrak^MATHEMATICAL FRAKTUR SMALL M
1D52B^𝔫^\mathfrak{n}^\mfrakn^A^mathalpha^eufrak^MATHEMATICAL FRAKTUR SMALL N
1D52C^𝔬^\mathfrak{o}^\mfrako^A^mathalpha^eufrak^MATHEMATICAL FRAKTUR SMALL O
1D52D^𝔭^\mathfrak{p}^\mfrakp^A^mathalpha^eufrak^MATHEMATICAL FRAKTUR SMALL P
1D52E^𝔮^\mathfrak{q}^\mfrakq^A^mathalpha^eufrak^MATHEMATICAL FRAKTUR SMALL Q
1D52F^𝔯^\mathfrak{r}^\mfrakr^A^mathalpha^eufrak^MATHEMATICAL FRAKTUR SMALL R
1D530^𝔰^\mathfrak{s}^\mfraks^A^mathalpha^eufrak^MATHEMATICAL FRAKTUR SMALL S
1D531^𝔱^\mathfrak{t}^\mfrakt^A^mathalpha^eufrak^MATHEMATICAL FRAKTUR SMALL T
1D532^𝔲^\mathfrak{u}^\mfraku^A^mathalpha^eufrak^MATHEMATICAL FRAKTUR SMALL U
1D533^𝔳^\mathfrak{v}^\mfrakv^A^mathalpha^eufrak^MATHEMATICAL FRAKTUR SMALL V
1D534^𝔴^\mathfrak{w}^\mfrakw^A^mathalpha^eufrak^MATHEMATICAL FRAKTUR SMALL W
1D535^𝔵^\mathfrak{x}^\mfrakx^A^mathalpha^eufrak^MATHEMATICAL FRAKTUR SMALL X
1D536^𝔶^\mathfrak{y}^\mfraky^A^mathalpha^eufrak^MATHEMATICAL FRAKTUR SMALL Y
1D537^𝔷^\mathfrak{z}^\mfrakz^A^mathalpha^eufrak^MATHEMATICAL FRAKTUR SMALL Z
1D538^𝔸^\mathbb{A}^\BbbA^A^mathalpha^mathbb^= \mathds{A} (dsfont), MATHEMATICAL DOUBLE-STRUCK CAPITAL A
1D539^𝔹^\mathbb{B}^\BbbB^A^mathalpha^mathbb^= \mathds{B} (dsfont), matMATHEMATICAL DOUBLE-STRUCK CAPITAL B
1D53B^𝔻^\mathbb{D}^\BbbD^A^mathalpha^mathbb^= \mathds{D} (dsfont), matMATHEMATICAL DOUBLE-STRUCK CAPITAL D
1D53C^𝔼^\mathbb{E}^\BbbE^A^mathalpha^mathbb^= \mathds{E} (dsfont), matMATHEMATICAL DOUBLE-STRUCK CAPITAL E
1D53D^𝔽^\mathbb{F}^\BbbF^A^mathalpha^mathbb^= \mathds{F} (dsfont), matMATHEMATICAL DOUBLE-STRUCK CAPITAL F
1D53E^𝔾^\mathbb{G}^\BbbG^A^mathalpha^mathbb^= \mathds{G} (dsfont), matMATHEMATICAL DOUBLE-STRUCK CAPITAL G
1D540^𝕀^\mathbb{I}^\BbbI^A^mathalpha^mathbb^= \mathds{I} (dsfont), matMATHEMATICAL DOUBLE-STRUCK CAPITAL I
1D541^𝕁^\mathbb{J}^\BbbJ^A^mathalpha^mathbb^= \mathds{J} (dsfont), matMATHEMATICAL DOUBLE-STRUCK CAPITAL J
1D542^𝕂^\mathbb{K}^\BbbK^A^mathalpha^mathbb^= \mathds{K} (dsfont), matMATHEMATICAL DOUBLE-STRUCK CAPITAL K
1D543^𝕃^\mathbb{L}^\BbbL^A^mathalpha^mathbb^= \mathds{L} (dsfont), matMATHEMATICAL DOUBLE-STRUCK CAPITAL L
1D544^𝕄^\mathbb{M}^\BbbM^A^mathalpha^mathbb^= \mathds{M} (dsfont), matMATHEMATICAL DOUBLE-STRUCK CAPITAL M
1D546^𝕆^\mathbb{O}^\BbbO^A^mathalpha^mathbb^= \mathds{O} (dsfont), matMATHEMATICAL DOUBLE-STRUCK CAPITAL O
1D54A^𝕊^\mathbb{S}^\BbbS^A^mathalpha^mathbb^= \mathds{S} (dsfont), matMATHEMATICAL DOUBLE-STRUCK CAPITAL S
1D54B^𝕋^\mathbb{T}^\BbbT^A^mathalpha^mathbb^= \mathds{T} (dsfont), matMATHEMATICAL DOUBLE-STRUCK CAPITAL T
1D54C^𝕌^\mathbb{U}^\BbbU^A^mathalpha^mathbb^= \mathds{U} (dsfont), matMATHEMATICAL DOUBLE-STRUCK CAPITAL U
1D54D^𝕍^\mathbb{V}^\BbbV^A^mathalpha^mathbb^= \mathds{V} (dsfont), matMATHEMATICAL DOUBLE-STRUCK CAPITAL V
1D54E^𝕎^\mathbb{W}^\BbbW^A^mathalpha^mathbb^= \mathds{W} (dsfont), matMATHEMATICAL DOUBLE-STRUCK CAPITAL W
1D54F^𝕏^\mathbb{X}^\BbbX^A^mathalpha^mathbb^= \mathds{X} (dsfont), matMATHEMATICAL DOUBLE-STRUCK CAPITAL X
1D550^𝕐^\mathbb{Y}^\BbbY^A^mathalpha^mathbb^= \mathds{Y} (dsfont), matMATHEMATICAL DOUBLE-STRUCK CAPITAL Y
1D552^𝕒^\mathbb{a}^\Bbba^A^mathalpha^bbold^MATHEMATICAL DOUBLE-STRUCK SMALL A
1D553^𝕓^\mathbb{b}^\Bbbb^A^mathalpha^bbold^MATHEMATICAL DOUBLE-STRUCK SMALL B
1D554^𝕔^\mathbb{c}^\Bbbc^A^mathalpha^bbold^MATHEMATICAL DOUBLE-STRUCK SMALL C
1D555^𝕕^\mathbb{d}^\Bbbd^A^mathalpha^bbold^MATHEMATICAL DOUBLE-STRUCK SMALL D
1D556^𝕖^\mathbb{e}^\Bbbe^A^mathalpha^bbold^MATHEMATICAL DOUBLE-STRUCK SMALL E
1D557^𝕗^\mathbb{f}^\Bbbf^A^mathalpha^bbold^MATHEMATICAL DOUBLE-STRUCK SMALL F
1D558^𝕘^\mathbb{g}^\Bbbg^A^mathalpha^bbold^MATHEMATICAL DOUBLE-STRUCK SMALL G
1D559^𝕙^\mathbb{h}^\Bbbh^A^mathalpha^bbold^MATHEMATICAL DOUBLE-STRUCK SMALL H
1D55A^𝕚^\mathbb{i}^\Bbbi^A^mathalpha^bbold^MATHEMATICAL DOUBLE-STRUCK SMALL I
1D55B^𝕛^\mathbb{j}^\Bbbj^A^mathalpha^bbold^MATHEMATICAL DOUBLE-STRUCK SMALL J
1D55C^𝕜^\mathbb{k}^\Bbbk^A^mathalpha^bbold fourier^= \Bbbk (amssymb), MATHEMATICAL DOUBLE-STRUCK SMALL K
1D55D^𝕝^\mathbb{l}^\Bbbl^A^mathalpha^bbold^MATHEMATICAL DOUBLE-STRUCK SMALL L
1D55E^𝕞^\mathbb{m}^\Bbbm^A^mathalpha^bbold^MATHEMATICAL DOUBLE-STRUCK SMALL M
1D55F^𝕟^\mathbb{n}^\Bbbn^A^mathalpha^bbold^MATHEMATICAL DOUBLE-STRUCK SMALL N
1D560^𝕠^\mathbb{o}^\Bbbo^A^mathalpha^bbold^MATHEMATICAL DOUBLE-STRUCK SMALL O
1D561^𝕡^\mathbb{p}^\Bbbp^A^mathalpha^bbold^MATHEMATICAL DOUBLE-STRUCK SMALL P
1D562^𝕢^\mathbb{q}^\Bbbq^A^mathalpha^bbold^MATHEMATICAL DOUBLE-STRUCK SMALL Q
1D563^𝕣^\mathbb{r}^\Bbbr^A^mathalpha^bbold^MATHEMATICAL DOUBLE-STRUCK SMALL R
1D564^𝕤^\mathbb{s}^\Bbbs^A^mathalpha^bbold^MATHEMATICAL DOUBLE-STRUCK SMALL S
1D565^𝕥^\mathbb{t}^\Bbbt^A^mathalpha^bbold^MATHEMATICAL DOUBLE-STRUCK SMALL T
1D566^𝕦^\mathbb{u}^\Bbbu^A^mathalpha^bbold^MATHEMATICAL DOUBLE-STRUCK SMALL U
1D567^𝕧^\mathbb{v}^\Bbbv^A^mathalpha^bbold^MATHEMATICAL DOUBLE-STRUCK SMALL V
1D568^𝕨^\mathbb{w}^\Bbbw^A^mathalpha^bbold^MATHEMATICAL DOUBLE-STRUCK SMALL W
1D569^𝕩^\mathbb{x}^\Bbbx^A^mathalpha^bbold^MATHEMATICAL DOUBLE-STRUCK SMALL X
1D56A^𝕪^\mathbb{y}^\Bbby^A^mathalpha^bbold^MATHEMATICAL DOUBLE-STRUCK SMALL Y
1D56B^𝕫^\mathbb{z}^\Bbbz^A^mathalpha^bbold^MATHEMATICAL DOUBLE-STRUCK SMALL Z
1D56C^𝕬^^\mbffrakA^A^mathalpha^^MATHEMATICAL BOLD FRAKTUR CAPITAL A
1D56D^𝕭^^\mbffrakB^A^mathalpha^^MATHEMATICAL BOLD FRAKTUR CAPITAL B
1D56E^𝕮^^\mbffrakC^A^mathalpha^^MATHEMATICAL BOLD FRAKTUR CAPITAL C
1D56F^𝕯^^\mbffrakD^A^mathalpha^^MATHEMATICAL BOLD FRAKTUR CAPITAL D
1D570^𝕰^^\mbffrakE^A^mathalpha^^MATHEMATICAL BOLD FRAKTUR CAPITAL E
1D571^𝕱^^\mbffrakF^A^mathalpha^^MATHEMATICAL BOLD FRAKTUR CAPITAL F
1D572^𝕲^^\mbffrakG^A^mathalpha^^MATHEMATICAL BOLD FRAKTUR CAPITAL G
1D573^𝕳^^\mbffrakH^A^mathalpha^^MATHEMATICAL BOLD FRAKTUR CAPITAL H
1D574^𝕴^^\mbffrakI^A^mathalpha^^MATHEMATICAL BOLD FRAKTUR CAPITAL I
1D575^𝕵^^\mbffrakJ^A^mathalpha^^MATHEMATICAL BOLD FRAKTUR CAPITAL J
1D576^𝕶^^\mbffrakK^A^mathalpha^^MATHEMATICAL BOLD FRAKTUR CAPITAL K
1D577^𝕷^^\mbffrakL^A^mathalpha^^MATHEMATICAL BOLD FRAKTUR CAPITAL L
1D578^𝕸^^\mbffrakM^A^mathalpha^^MATHEMATICAL BOLD FRAKTUR CAPITAL M
1D579^𝕹^^\mbffrakN^A^mathalpha^^MATHEMATICAL BOLD FRAKTUR CAPITAL N
1D57A^𝕺^^\mbffrakO^A^mathalpha^^MATHEMATICAL BOLD FRAKTUR CAPITAL O
1D57B^𝕻^^\mbffrakP^A^mathalpha^^MATHEMATICAL BOLD FRAKTUR CAPITAL P
1D57C^𝕼^^\mbffrakQ^A^mathalpha^^MATHEMATICAL BOLD FRAKTUR CAPITAL Q
1D57D^𝕽^^\mbffrakR^A^mathalpha^^MATHEMATICAL BOLD FRAKTUR CAPITAL R
1D57E^𝕾^^\mbffrakS^A^mathalpha^^MATHEMATICAL BOLD FRAKTUR CAPITAL S
1D57F^𝕿^^\mbffrakT^A^mathalpha^^MATHEMATICAL BOLD FRAKTUR CAPITAL T
1D580^𝖀^^\mbffrakU^A^mathalpha^^MATHEMATICAL BOLD FRAKTUR CAPITAL U
1D581^𝖁^^\mbffrakV^A^mathalpha^^MATHEMATICAL BOLD FRAKTUR CAPITAL V
1D582^𝖂^^\mbffrakW^A^mathalpha^^MATHEMATICAL BOLD FRAKTUR CAPITAL W
1D583^𝖃^^\mbffrakX^A^mathalpha^^MATHEMATICAL BOLD FRAKTUR CAPITAL X
1D584^𝖄^^\mbffrakY^A^mathalpha^^MATHEMATICAL BOLD FRAKTUR CAPITAL Y
1D585^𝖅^^\mbffrakZ^A^mathalpha^^MATHEMATICAL BOLD FRAKTUR CAPITAL Z
1D586^𝖆^^\mbffraka^A^mathalpha^^MATHEMATICAL BOLD FRAKTUR SMALL A
1D587^𝖇^^\mbffrakb^A^mathalpha^^MATHEMATICAL BOLD FRAKTUR SMALL B
1D588^𝖈^^\mbffrakc^A^mathalpha^^MATHEMATICAL BOLD FRAKTUR SMALL C
1D589^𝖉^^\mbffrakd^A^mathalpha^^MATHEMATICAL BOLD FRAKTUR SMALL D
1D58A^𝖊^^\mbffrake^A^mathalpha^^MATHEMATICAL BOLD FRAKTUR SMALL E
1D58B^𝖋^^\mbffrakf^A^mathalpha^^MATHEMATICAL BOLD FRAKTUR SMALL F
1D58C^𝖌^^\mbffrakg^A^mathalpha^^MATHEMATICAL BOLD FRAKTUR SMALL G
1D58D^𝖍^^\mbffrakh^A^mathalpha^^MATHEMATICAL BOLD FRAKTUR SMALL H
1D58E^𝖎^^\mbffraki^A^mathalpha^^MATHEMATICAL BOLD FRAKTUR SMALL I
1D58F^𝖏^^\mbffrakj^A^mathalpha^^MATHEMATICAL BOLD FRAKTUR SMALL J
1D590^𝖐^^\mbffrakk^A^mathalpha^^MATHEMATICAL BOLD FRAKTUR SMALL K
1D591^𝖑^^\mbffrakl^A^mathalpha^^MATHEMATICAL BOLD FRAKTUR SMALL L
1D592^𝖒^^\mbffrakm^A^mathalpha^^MATHEMATICAL BOLD FRAKTUR SMALL M
1D593^𝖓^^\mbffrakn^A^mathalpha^^MATHEMATICAL BOLD FRAKTUR SMALL N
1D594^𝖔^^\mbffrako^A^mathalpha^^MATHEMATICAL BOLD FRAKTUR SMALL O
1D595^𝖕^^\mbffrakp^A^mathalpha^^MATHEMATICAL BOLD FRAKTUR SMALL P
1D596^𝖖^^\mbffrakq^A^mathalpha^^MATHEMATICAL BOLD FRAKTUR SMALL Q
1D597^𝖗^^\mbffrakr^A^mathalpha^^MATHEMATICAL BOLD FRAKTUR SMALL R
1D598^𝖘^^\mbffraks^A^mathalpha^^MATHEMATICAL BOLD FRAKTUR SMALL S
1D599^𝖙^^\mbffrakt^A^mathalpha^^MATHEMATICAL BOLD FRAKTUR SMALL T
1D59A^𝖚^^\mbffraku^A^mathalpha^^MATHEMATICAL BOLD FRAKTUR SMALL U
1D59B^𝖛^^\mbffrakv^A^mathalpha^^MATHEMATICAL BOLD FRAKTUR SMALL V
1D59C^𝖜^^\mbffrakw^A^mathalpha^^MATHEMATICAL BOLD FRAKTUR SMALL W
1D59D^𝖝^^\mbffrakx^A^mathalpha^^MATHEMATICAL BOLD FRAKTUR SMALL X
1D59E^𝖞^^\mbffraky^A^mathalpha^^MATHEMATICAL BOLD FRAKTUR SMALL Y
1D59F^𝖟^^\mbffrakz^A^mathalpha^^MATHEMATICAL BOLD FRAKTUR SMALL Z
1D5A0^𝖠^\mathsf{A}^\msansA^A^mathalpha^^MATHEMATICAL SANS-SERIF CAPITAL A
1D5A1^𝖡^\mathsf{B}^\msansB^A^mathalpha^^MATHEMATICAL SANS-SERIF CAPITAL B
1D5A2^𝖢^\mathsf{C}^\msansC^A^mathalpha^^MATHEMATICAL SANS-SERIF CAPITAL C
1D5A3^𝖣^\mathsf{D}^\msansD^A^mathalpha^^MATHEMATICAL SANS-SERIF CAPITAL D
1D5A4^𝖤^\mathsf{E}^\msansE^A^mathalpha^^MATHEMATICAL SANS-SERIF CAPITAL E
1D5A5^𝖥^\mathsf{F}^\msansF^A^mathalpha^^MATHEMATICAL SANS-SERIF CAPITAL F
1D5A6^𝖦^\mathsf{G}^\msansG^A^mathalpha^^MATHEMATICAL SANS-SERIF CAPITAL G
1D5A7^𝖧^\mathsf{H}^\msansH^A^mathalpha^^MATHEMATICAL SANS-SERIF CAPITAL H
1D5A8^𝖨^\mathsf{I}^\msansI^A^mathalpha^^MATHEMATICAL SANS-SERIF CAPITAL I
1D5A9^𝖩^\mathsf{J}^\msansJ^A^mathalpha^^MATHEMATICAL SANS-SERIF CAPITAL J
1D5AA^𝖪^\mathsf{K}^\msansK^A^mathalpha^^MATHEMATICAL SANS-SERIF CAPITAL K
1D5AB^𝖫^\mathsf{L}^\msansL^A^mathalpha^^MATHEMATICAL SANS-SERIF CAPITAL L
1D5AC^𝖬^\mathsf{M}^\msansM^A^mathalpha^^MATHEMATICAL SANS-SERIF CAPITAL M
1D5AD^𝖭^\mathsf{N}^\msansN^A^mathalpha^^MATHEMATICAL SANS-SERIF CAPITAL N
1D5AE^𝖮^\mathsf{O}^\msansO^A^mathalpha^^MATHEMATICAL SANS-SERIF CAPITAL O
1D5AF^𝖯^\mathsf{P}^\msansP^A^mathalpha^^MATHEMATICAL SANS-SERIF CAPITAL P
1D5B0^𝖰^\mathsf{Q}^\msansQ^A^mathalpha^^MATHEMATICAL SANS-SERIF CAPITAL Q
1D5B1^𝖱^\mathsf{R}^\msansR^A^mathalpha^^MATHEMATICAL SANS-SERIF CAPITAL R
1D5B2^𝖲^\mathsf{S}^\msansS^A^mathalpha^^MATHEMATICAL SANS-SERIF CAPITAL S
1D5B3^𝖳^\mathsf{T}^\msansT^A^mathalpha^^MATHEMATICAL SANS-SERIF CAPITAL T
1D5B4^𝖴^\mathsf{U}^\msansU^A^mathalpha^^MATHEMATICAL SANS-SERIF CAPITAL U
1D5B5^𝖵^\mathsf{V}^\msansV^A^mathalpha^^MATHEMATICAL SANS-SERIF CAPITAL V
1D5B6^𝖶^\mathsf{W}^\msansW^A^mathalpha^^MATHEMATICAL SANS-SERIF CAPITAL W
1D5B7^𝖷^\mathsf{X}^\msansX^A^mathalpha^^MATHEMATICAL SANS-SERIF CAPITAL X
1D5B8^𝖸^\mathsf{Y}^\msansY^A^mathalpha^^MATHEMATICAL SANS-SERIF CAPITAL Y
1D5B9^𝖹^\mathsf{Z}^\msansZ^A^mathalpha^^MATHEMATICAL SANS-SERIF CAPITAL Z
1D5BA^𝖺^\mathsf{a}^\msansa^A^mathalpha^^MATHEMATICAL SANS-SERIF SMALL A
1D5BB^𝖻^\mathsf{b}^\msansb^A^mathalpha^^MATHEMATICAL SANS-SERIF SMALL B
1D5BC^𝖼^\mathsf{c}^\msansc^A^mathalpha^^MATHEMATICAL SANS-SERIF SMALL C
1D5BD^𝖽^\mathsf{d}^\msansd^A^mathalpha^^MATHEMATICAL SANS-SERIF SMALL D
1D5BE^𝖾^\mathsf{e}^\msanse^A^mathalpha^^MATHEMATICAL SANS-SERIF SMALL E
1D5BF^𝖿^\mathsf{f}^\msansf^A^mathalpha^^MATHEMATICAL SANS-SERIF SMALL F
1D5C0^𝗀^\mathsf{g}^\msansg^A^mathalpha^^MATHEMATICAL SANS-SERIF SMALL G
1D5C1^𝗁^\mathsf{h}^\msansh^A^mathalpha^^MATHEMATICAL SANS-SERIF SMALL H
1D5C2^𝗂^\mathsf{i}^\msansi^A^mathalpha^^MATHEMATICAL SANS-SERIF SMALL I
1D5C3^𝗃^\mathsf{j}^\msansj^A^mathalpha^^MATHEMATICAL SANS-SERIF SMALL J
1D5C4^𝗄^\mathsf{k}^\msansk^A^mathalpha^^MATHEMATICAL SANS-SERIF SMALL K
1D5C5^𝗅^\mathsf{l}^\msansl^A^mathalpha^^MATHEMATICAL SANS-SERIF SMALL L
1D5C6^𝗆^\mathsf{m}^\msansm^A^mathalpha^^MATHEMATICAL SANS-SERIF SMALL M
1D5C7^𝗇^\mathsf{n}^\msansn^A^mathalpha^^MATHEMATICAL SANS-SERIF SMALL N
1D5C8^𝗈^\mathsf{o}^\msanso^A^mathalpha^^MATHEMATICAL SANS-SERIF SMALL O
1D5C9^𝗉^\mathsf{p}^\msansp^A^mathalpha^^MATHEMATICAL SANS-SERIF SMALL P
1D5CA^𝗊^\mathsf{q}^\msansq^A^mathalpha^^MATHEMATICAL SANS-SERIF SMALL Q
1D5CB^𝗋^\mathsf{r}^\msansr^A^mathalpha^^MATHEMATICAL SANS-SERIF SMALL R
1D5CC^𝗌^\mathsf{s}^\msanss^A^mathalpha^^MATHEMATICAL SANS-SERIF SMALL S
1D5CD^𝗍^\mathsf{t}^\msanst^A^mathalpha^^MATHEMATICAL SANS-SERIF SMALL T
1D5CE^𝗎^\mathsf{u}^\msansu^A^mathalpha^^MATHEMATICAL SANS-SERIF SMALL U
1D5CF^𝗏^\mathsf{v}^\msansv^A^mathalpha^^MATHEMATICAL SANS-SERIF SMALL V
1D5D0^𝗐^\mathsf{w}^\msansw^A^mathalpha^^MATHEMATICAL SANS-SERIF SMALL W
1D5D1^𝗑^\mathsf{x}^\msansx^A^mathalpha^^MATHEMATICAL SANS-SERIF SMALL X
1D5D2^𝗒^\mathsf{y}^\msansy^A^mathalpha^^MATHEMATICAL SANS-SERIF SMALL Y
1D5D3^𝗓^\mathsf{z}^\msansz^A^mathalpha^^MATHEMATICAL SANS-SERIF SMALL Z
1D5D4^𝗔^\mathsfbf{A}^\mbfsansA^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD CAPITAL A
1D5D5^𝗕^\mathsfbf{B}^\mbfsansB^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD CAPITAL B
1D5D6^𝗖^\mathsfbf{C}^\mbfsansC^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD CAPITAL C
1D5D7^𝗗^\mathsfbf{D}^\mbfsansD^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD CAPITAL D
1D5D8^𝗘^\mathsfbf{E}^\mbfsansE^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD CAPITAL E
1D5D9^𝗙^\mathsfbf{F}^\mbfsansF^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD CAPITAL F
1D5DA^𝗚^\mathsfbf{G}^\mbfsansG^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD CAPITAL G
1D5DB^𝗛^\mathsfbf{H}^\mbfsansH^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD CAPITAL H
1D5DC^𝗜^\mathsfbf{I}^\mbfsansI^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD CAPITAL I
1D5DD^𝗝^\mathsfbf{J}^\mbfsansJ^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD CAPITAL J
1D5DE^𝗞^\mathsfbf{K}^\mbfsansK^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD CAPITAL K
1D5DF^𝗟^\mathsfbf{L}^\mbfsansL^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD CAPITAL L
1D5E0^𝗠^\mathsfbf{M}^\mbfsansM^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD CAPITAL M
1D5E1^𝗡^\mathsfbf{N}^\mbfsansN^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD CAPITAL N
1D5E2^𝗢^\mathsfbf{O}^\mbfsansO^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD CAPITAL O
1D5E3^𝗣^\mathsfbf{P}^\mbfsansP^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD CAPITAL P
1D5E4^𝗤^\mathsfbf{Q}^\mbfsansQ^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD CAPITAL Q
1D5E5^𝗥^\mathsfbf{R}^\mbfsansR^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD CAPITAL R
1D5E6^𝗦^\mathsfbf{S}^\mbfsansS^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD CAPITAL S
1D5E7^𝗧^\mathsfbf{T}^\mbfsansT^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD CAPITAL T
1D5E8^𝗨^\mathsfbf{U}^\mbfsansU^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD CAPITAL U
1D5E9^𝗩^\mathsfbf{V}^\mbfsansV^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD CAPITAL V
1D5EA^𝗪^\mathsfbf{W}^\mbfsansW^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD CAPITAL W
1D5EB^𝗫^\mathsfbf{X}^\mbfsansX^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD CAPITAL X
1D5EC^𝗬^\mathsfbf{Y}^\mbfsansY^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD CAPITAL Y
1D5ED^𝗭^\mathsfbf{Z}^\mbfsansZ^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD CAPITAL Z
1D5EE^𝗮^\mathsfbf{a}^\mbfsansa^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD SMALL A
1D5EF^𝗯^\mathsfbf{b}^\mbfsansb^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD SMALL B
1D5F0^𝗰^\mathsfbf{c}^\mbfsansc^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD SMALL C
1D5F1^𝗱^\mathsfbf{d}^\mbfsansd^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD SMALL D
1D5F2^𝗲^\mathsfbf{e}^\mbfsanse^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD SMALL E
1D5F3^𝗳^\mathsfbf{f}^\mbfsansf^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD SMALL F
1D5F4^𝗴^\mathsfbf{g}^\mbfsansg^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD SMALL G
1D5F5^𝗵^\mathsfbf{h}^\mbfsansh^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD SMALL H
1D5F6^𝗶^\mathsfbf{i}^\mbfsansi^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD SMALL I
1D5F7^𝗷^\mathsfbf{j}^\mbfsansj^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD SMALL J
1D5F8^𝗸^\mathsfbf{k}^\mbfsansk^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD SMALL K
1D5F9^𝗹^\mathsfbf{l}^\mbfsansl^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD SMALL L
1D5FA^𝗺^\mathsfbf{m}^\mbfsansm^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD SMALL M
1D5FB^𝗻^\mathsfbf{n}^\mbfsansn^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD SMALL N
1D5FC^𝗼^\mathsfbf{o}^\mbfsanso^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD SMALL O
1D5FD^𝗽^\mathsfbf{p}^\mbfsansp^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD SMALL P
1D5FE^𝗾^\mathsfbf{q}^\mbfsansq^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD SMALL Q
1D5FF^𝗿^\mathsfbf{r}^\mbfsansr^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD SMALL R
1D600^𝘀^\mathsfbf{s}^\mbfsanss^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD SMALL S
1D601^𝘁^\mathsfbf{t}^\mbfsanst^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD SMALL T
1D602^𝘂^\mathsfbf{u}^\mbfsansu^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD SMALL U
1D603^𝘃^\mathsfbf{v}^\mbfsansv^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD SMALL V
1D604^𝘄^\mathsfbf{w}^\mbfsansw^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD SMALL W
1D605^𝘅^\mathsfbf{x}^\mbfsansx^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD SMALL X
1D606^𝘆^\mathsfbf{y}^\mbfsansy^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD SMALL Y
1D607^𝘇^\mathsfbf{z}^\mbfsansz^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD SMALL Z
1D608^𝘈^\mathsfit{A}^\mitsansA^A^mathalpha^omlmathsfit^MATHEMATICAL SANS-SERIF ITALIC CAPITAL A
1D609^𝘉^\mathsfit{B}^\mitsansB^A^mathalpha^omlmathsfit^MATHEMATICAL SANS-SERIF ITALIC CAPITAL B
1D60A^𝘊^\mathsfit{C}^\mitsansC^A^mathalpha^omlmathsfit^MATHEMATICAL SANS-SERIF ITALIC CAPITAL C
1D60B^𝘋^\mathsfit{D}^\mitsansD^A^mathalpha^omlmathsfit^MATHEMATICAL SANS-SERIF ITALIC CAPITAL D
1D60C^𝘌^\mathsfit{E}^\mitsansE^A^mathalpha^omlmathsfit^MATHEMATICAL SANS-SERIF ITALIC CAPITAL E
1D60D^𝘍^\mathsfit{F}^\mitsansF^A^mathalpha^omlmathsfit^MATHEMATICAL SANS-SERIF ITALIC CAPITAL F
1D60E^𝘎^\mathsfit{G}^\mitsansG^A^mathalpha^omlmathsfit^MATHEMATICAL SANS-SERIF ITALIC CAPITAL G
1D60F^𝘏^\mathsfit{H}^\mitsansH^A^mathalpha^omlmathsfit^MATHEMATICAL SANS-SERIF ITALIC CAPITAL H
1D610^𝘐^\mathsfit{I}^\mitsansI^A^mathalpha^omlmathsfit^MATHEMATICAL SANS-SERIF ITALIC CAPITAL I
1D611^𝘑^\mathsfit{J}^\mitsansJ^A^mathalpha^omlmathsfit^MATHEMATICAL SANS-SERIF ITALIC CAPITAL J
1D612^𝘒^\mathsfit{K}^\mitsansK^A^mathalpha^omlmathsfit^MATHEMATICAL SANS-SERIF ITALIC CAPITAL K
1D613^𝘓^\mathsfit{L}^\mitsansL^A^mathalpha^omlmathsfit^MATHEMATICAL SANS-SERIF ITALIC CAPITAL L
1D614^𝘔^\mathsfit{M}^\mitsansM^A^mathalpha^omlmathsfit^MATHEMATICAL SANS-SERIF ITALIC CAPITAL M
1D615^𝘕^\mathsfit{N}^\mitsansN^A^mathalpha^omlmathsfit^MATHEMATICAL SANS-SERIF ITALIC CAPITAL N
1D616^𝘖^\mathsfit{O}^\mitsansO^A^mathalpha^omlmathsfit^MATHEMATICAL SANS-SERIF ITALIC CAPITAL O
1D617^𝘗^\mathsfit{P}^\mitsansP^A^mathalpha^omlmathsfit^MATHEMATICAL SANS-SERIF ITALIC CAPITAL P
1D618^𝘘^\mathsfit{Q}^\mitsansQ^A^mathalpha^omlmathsfit^MATHEMATICAL SANS-SERIF ITALIC CAPITAL Q
1D619^𝘙^\mathsfit{R}^\mitsansR^A^mathalpha^omlmathsfit^MATHEMATICAL SANS-SERIF ITALIC CAPITAL R
1D61A^𝘚^\mathsfit{S}^\mitsansS^A^mathalpha^omlmathsfit^MATHEMATICAL SANS-SERIF ITALIC CAPITAL S
1D61B^𝘛^\mathsfit{T}^\mitsansT^A^mathalpha^omlmathsfit^MATHEMATICAL SANS-SERIF ITALIC CAPITAL T
1D61C^𝘜^\mathsfit{U}^\mitsansU^A^mathalpha^omlmathsfit^MATHEMATICAL SANS-SERIF ITALIC CAPITAL U
1D61D^𝘝^\mathsfit{V}^\mitsansV^A^mathalpha^omlmathsfit^MATHEMATICAL SANS-SERIF ITALIC CAPITAL V
1D61E^𝘞^\mathsfit{W}^\mitsansW^A^mathalpha^omlmathsfit^MATHEMATICAL SANS-SERIF ITALIC CAPITAL W
1D61F^𝘟^\mathsfit{X}^\mitsansX^A^mathalpha^omlmathsfit^MATHEMATICAL SANS-SERIF ITALIC CAPITAL X
1D620^𝘠^\mathsfit{Y}^\mitsansY^A^mathalpha^omlmathsfit^MATHEMATICAL SANS-SERIF ITALIC CAPITAL Y
1D621^𝘡^\mathsfit{Z}^\mitsansZ^A^mathalpha^omlmathsfit^MATHEMATICAL SANS-SERIF ITALIC CAPITAL Z
1D622^𝘢^\mathsfit{a}^\mitsansa^A^mathalpha^omlmathsfit^MATHEMATICAL SANS-SERIF ITALIC SMALL A
1D623^𝘣^\mathsfit{b}^\mitsansb^A^mathalpha^omlmathsfit^MATHEMATICAL SANS-SERIF ITALIC SMALL B
1D624^𝘤^\mathsfit{c}^\mitsansc^A^mathalpha^omlmathsfit^MATHEMATICAL SANS-SERIF ITALIC SMALL C
1D625^𝘥^\mathsfit{d}^\mitsansd^A^mathalpha^omlmathsfit^MATHEMATICAL SANS-SERIF ITALIC SMALL D
1D626^𝘦^\mathsfit{e}^\mitsanse^A^mathalpha^omlmathsfit^MATHEMATICAL SANS-SERIF ITALIC SMALL E
1D627^𝘧^\mathsfit{f}^\mitsansf^A^mathalpha^omlmathsfit^MATHEMATICAL SANS-SERIF ITALIC SMALL F
1D628^𝘨^\mathsfit{g}^\mitsansg^A^mathalpha^omlmathsfit^MATHEMATICAL SANS-SERIF ITALIC SMALL G
1D629^𝘩^\mathsfit{h}^\mitsansh^A^mathalpha^omlmathsfit^MATHEMATICAL SANS-SERIF ITALIC SMALL H
1D62A^𝘪^\mathsfit{i}^\mitsansi^A^mathalpha^omlmathsfit^MATHEMATICAL SANS-SERIF ITALIC SMALL I
1D62B^𝘫^\mathsfit{j}^\mitsansj^A^mathalpha^omlmathsfit^MATHEMATICAL SANS-SERIF ITALIC SMALL J
1D62C^𝘬^\mathsfit{k}^\mitsansk^A^mathalpha^omlmathsfit^MATHEMATICAL SANS-SERIF ITALIC SMALL K
1D62D^𝘭^\mathsfit{l}^\mitsansl^A^mathalpha^omlmathsfit^MATHEMATICAL SANS-SERIF ITALIC SMALL L
1D62E^𝘮^\mathsfit{m}^\mitsansm^A^mathalpha^omlmathsfit^MATHEMATICAL SANS-SERIF ITALIC SMALL M
1D62F^𝘯^\mathsfit{n}^\mitsansn^A^mathalpha^omlmathsfit^MATHEMATICAL SANS-SERIF ITALIC SMALL N
1D630^𝘰^\mathsfit{o}^\mitsanso^A^mathalpha^omlmathsfit^MATHEMATICAL SANS-SERIF ITALIC SMALL O
1D631^𝘱^\mathsfit{p}^\mitsansp^A^mathalpha^omlmathsfit^MATHEMATICAL SANS-SERIF ITALIC SMALL P
1D632^𝘲^\mathsfit{q}^\mitsansq^A^mathalpha^omlmathsfit^MATHEMATICAL SANS-SERIF ITALIC SMALL Q
1D633^𝘳^\mathsfit{r}^\mitsansr^A^mathalpha^omlmathsfit^MATHEMATICAL SANS-SERIF ITALIC SMALL R
1D634^𝘴^\mathsfit{s}^\mitsanss^A^mathalpha^omlmathsfit^MATHEMATICAL SANS-SERIF ITALIC SMALL S
1D635^𝘵^\mathsfit{t}^\mitsanst^A^mathalpha^omlmathsfit^MATHEMATICAL SANS-SERIF ITALIC SMALL T
1D636^𝘶^\mathsfit{u}^\mitsansu^A^mathalpha^omlmathsfit^MATHEMATICAL SANS-SERIF ITALIC SMALL U
1D637^𝘷^\mathsfit{v}^\mitsansv^A^mathalpha^omlmathsfit^MATHEMATICAL SANS-SERIF ITALIC SMALL V
1D638^𝘸^\mathsfit{w}^\mitsansw^A^mathalpha^omlmathsfit^MATHEMATICAL SANS-SERIF ITALIC SMALL W
1D639^𝘹^\mathsfit{x}^\mitsansx^A^mathalpha^omlmathsfit^MATHEMATICAL SANS-SERIF ITALIC SMALL X
1D63A^𝘺^\mathsfit{y}^\mitsansy^A^mathalpha^omlmathsfit^MATHEMATICAL SANS-SERIF ITALIC SMALL Y
1D63B^𝘻^\mathsfit{z}^\mitsansz^A^mathalpha^omlmathsfit^MATHEMATICAL SANS-SERIF ITALIC SMALL Z
1D63C^𝘼^\mathsfbfit{A}^\mbfitsansA^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL A
1D63D^𝘽^\mathsfbfit{B}^\mbfitsansB^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL B
1D63E^𝘾^\mathsfbfit{C}^\mbfitsansC^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL C
1D63F^𝘿^\mathsfbfit{D}^\mbfitsansD^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL D
1D640^𝙀^\mathsfbfit{E}^\mbfitsansE^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL E
1D641^𝙁^\mathsfbfit{F}^\mbfitsansF^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL F
1D642^𝙂^\mathsfbfit{G}^\mbfitsansG^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL G
1D643^𝙃^\mathsfbfit{H}^\mbfitsansH^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL H
1D644^𝙄^\mathsfbfit{I}^\mbfitsansI^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL I
1D645^𝙅^\mathsfbfit{J}^\mbfitsansJ^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL J
1D646^𝙆^\mathsfbfit{K}^\mbfitsansK^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL K
1D647^𝙇^\mathsfbfit{L}^\mbfitsansL^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL L
1D648^𝙈^\mathsfbfit{M}^\mbfitsansM^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL M
1D649^𝙉^\mathsfbfit{N}^\mbfitsansN^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL N
1D64A^𝙊^\mathsfbfit{O}^\mbfitsansO^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL O
1D64B^𝙋^\mathsfbfit{P}^\mbfitsansP^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL P
1D64C^𝙌^\mathsfbfit{Q}^\mbfitsansQ^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL Q
1D64D^𝙍^\mathsfbfit{R}^\mbfitsansR^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL R
1D64E^𝙎^\mathsfbfit{S}^\mbfitsansS^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL S
1D64F^𝙏^\mathsfbfit{T}^\mbfitsansT^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL T
1D650^𝙐^\mathsfbfit{U}^\mbfitsansU^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL U
1D651^𝙑^\mathsfbfit{V}^\mbfitsansV^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL V
1D652^𝙒^\mathsfbfit{W}^\mbfitsansW^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL W
1D653^𝙓^\mathsfbfit{X}^\mbfitsansX^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL X
1D654^𝙔^\mathsfbfit{Y}^\mbfitsansY^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL Y
1D655^𝙕^\mathsfbfit{Z}^\mbfitsansZ^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL Z
1D656^𝙖^\mathsfbfit{a}^\mbfitsansa^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL A
1D657^𝙗^\mathsfbfit{b}^\mbfitsansb^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL B
1D658^𝙘^\mathsfbfit{c}^\mbfitsansc^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL C
1D659^𝙙^\mathsfbfit{d}^\mbfitsansd^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL D
1D65A^𝙚^\mathsfbfit{e}^\mbfitsanse^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL E
1D65B^𝙛^\mathsfbfit{f}^\mbfitsansf^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL F
1D65C^𝙜^\mathsfbfit{g}^\mbfitsansg^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL G
1D65D^𝙝^\mathsfbfit{h}^\mbfitsansh^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL H
1D65E^𝙞^\mathsfbfit{i}^\mbfitsansi^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL I
1D65F^𝙟^\mathsfbfit{j}^\mbfitsansj^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL J
1D660^𝙠^\mathsfbfit{k}^\mbfitsansk^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL K
1D661^𝙡^\mathsfbfit{l}^\mbfitsansl^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL L
1D662^𝙢^\mathsfbfit{m}^\mbfitsansm^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL M
1D663^𝙣^\mathsfbfit{n}^\mbfitsansn^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL N
1D664^𝙤^\mathsfbfit{o}^\mbfitsanso^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL O
1D665^𝙥^\mathsfbfit{p}^\mbfitsansp^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL P
1D666^𝙦^\mathsfbfit{q}^\mbfitsansq^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL Q
1D667^𝙧^\mathsfbfit{r}^\mbfitsansr^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL R
1D668^𝙨^\mathsfbfit{s}^\mbfitsanss^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL S
1D669^𝙩^\mathsfbfit{t}^\mbfitsanst^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL T
1D66A^𝙪^\mathsfbfit{u}^\mbfitsansu^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL U
1D66B^𝙫^\mathsfbfit{v}^\mbfitsansv^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL V
1D66C^𝙬^\mathsfbfit{w}^\mbfitsansw^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL W
1D66D^𝙭^\mathsfbfit{x}^\mbfitsansx^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL X
1D66E^𝙮^\mathsfbfit{y}^\mbfitsansy^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL Y
1D66F^𝙯^\mathsfbfit{z}^\mbfitsansz^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL Z
1D670^𝙰^\mathtt{A}^\mttA^A^mathalpha^^MATHEMATICAL MONOSPACE CAPITAL A
1D671^𝙱^\mathtt{B}^\mttB^A^mathalpha^^MATHEMATICAL MONOSPACE CAPITAL B
1D672^𝙲^\mathtt{C}^\mttC^A^mathalpha^^MATHEMATICAL MONOSPACE CAPITAL C
1D673^𝙳^\mathtt{D}^\mttD^A^mathalpha^^MATHEMATICAL MONOSPACE CAPITAL D
1D674^𝙴^\mathtt{E}^\mttE^A^mathalpha^^MATHEMATICAL MONOSPACE CAPITAL E
1D675^𝙵^\mathtt{F}^\mttF^A^mathalpha^^MATHEMATICAL MONOSPACE CAPITAL F
1D676^𝙶^\mathtt{G}^\mttG^A^mathalpha^^MATHEMATICAL MONOSPACE CAPITAL G
1D677^𝙷^\mathtt{H}^\mttH^A^mathalpha^^MATHEMATICAL MONOSPACE CAPITAL H
1D678^𝙸^\mathtt{I}^\mttI^A^mathalpha^^MATHEMATICAL MONOSPACE CAPITAL I
1D679^𝙹^\mathtt{J}^\mttJ^A^mathalpha^^MATHEMATICAL MONOSPACE CAPITAL J
1D67A^𝙺^\mathtt{K}^\mttK^A^mathalpha^^MATHEMATICAL MONOSPACE CAPITAL K
1D67B^𝙻^\mathtt{L}^\mttL^A^mathalpha^^MATHEMATICAL MONOSPACE CAPITAL L
1D67C^𝙼^\mathtt{M}^\mttM^A^mathalpha^^MATHEMATICAL MONOSPACE CAPITAL M
1D67D^𝙽^\mathtt{N}^\mttN^A^mathalpha^^MATHEMATICAL MONOSPACE CAPITAL N
1D67E^𝙾^\mathtt{O}^\mttO^A^mathalpha^^MATHEMATICAL MONOSPACE CAPITAL O
1D67F^𝙿^\mathtt{P}^\mttP^A^mathalpha^^MATHEMATICAL MONOSPACE CAPITAL P
1D680^𝚀^\mathtt{Q}^\mttQ^A^mathalpha^^MATHEMATICAL MONOSPACE CAPITAL Q
1D681^𝚁^\mathtt{R}^\mttR^A^mathalpha^^MATHEMATICAL MONOSPACE CAPITAL R
1D682^𝚂^\mathtt{S}^\mttS^A^mathalpha^^MATHEMATICAL MONOSPACE CAPITAL S
1D683^𝚃^\mathtt{T}^\mttT^A^mathalpha^^MATHEMATICAL MONOSPACE CAPITAL T
1D684^𝚄^\mathtt{U}^\mttU^A^mathalpha^^MATHEMATICAL MONOSPACE CAPITAL U
1D685^𝚅^\mathtt{V}^\mttV^A^mathalpha^^MATHEMATICAL MONOSPACE CAPITAL V
1D686^𝚆^\mathtt{W}^\mttW^A^mathalpha^^MATHEMATICAL MONOSPACE CAPITAL W
1D687^𝚇^\mathtt{X}^\mttX^A^mathalpha^^MATHEMATICAL MONOSPACE CAPITAL X
1D688^𝚈^\mathtt{Y}^\mttY^A^mathalpha^^MATHEMATICAL MONOSPACE CAPITAL Y
1D689^𝚉^\mathtt{Z}^\mttZ^A^mathalpha^^MATHEMATICAL MONOSPACE CAPITAL Z
1D68A^𝚊^\mathtt{a}^\mtta^A^mathalpha^^MATHEMATICAL MONOSPACE SMALL A
1D68B^𝚋^\mathtt{b}^\mttb^A^mathalpha^^MATHEMATICAL MONOSPACE SMALL B
1D68C^𝚌^\mathtt{c}^\mttc^A^mathalpha^^MATHEMATICAL MONOSPACE SMALL C
1D68D^𝚍^\mathtt{d}^\mttd^A^mathalpha^^MATHEMATICAL MONOSPACE SMALL D
1D68E^𝚎^\mathtt{e}^\mtte^A^mathalpha^^MATHEMATICAL MONOSPACE SMALL E
1D68F^𝚏^\mathtt{f}^\mttf^A^mathalpha^^MATHEMATICAL MONOSPACE SMALL F
1D690^𝚐^\mathtt{g}^\mttg^A^mathalpha^^MATHEMATICAL MONOSPACE SMALL G
1D691^𝚑^\mathtt{h}^\mtth^A^mathalpha^^MATHEMATICAL MONOSPACE SMALL H
1D692^𝚒^\mathtt{i}^\mtti^A^mathalpha^^MATHEMATICAL MONOSPACE SMALL I
1D693^𝚓^\mathtt{j}^\mttj^A^mathalpha^^MATHEMATICAL MONOSPACE SMALL J
1D694^𝚔^\mathtt{k}^\mttk^A^mathalpha^^MATHEMATICAL MONOSPACE SMALL K
1D695^𝚕^\mathtt{l}^\mttl^A^mathalpha^^MATHEMATICAL MONOSPACE SMALL L
1D696^𝚖^\mathtt{m}^\mttm^A^mathalpha^^MATHEMATICAL MONOSPACE SMALL M
1D697^𝚗^\mathtt{n}^\mttn^A^mathalpha^^MATHEMATICAL MONOSPACE SMALL N
1D698^𝚘^\mathtt{o}^\mtto^A^mathalpha^^MATHEMATICAL MONOSPACE SMALL O
1D699^𝚙^\mathtt{p}^\mttp^A^mathalpha^^MATHEMATICAL MONOSPACE SMALL P
1D69A^𝚚^\mathtt{q}^\mttq^A^mathalpha^^MATHEMATICAL MONOSPACE SMALL Q
1D69B^𝚛^\mathtt{r}^\mttr^A^mathalpha^^MATHEMATICAL MONOSPACE SMALL R
1D69C^𝚜^\mathtt{s}^\mtts^A^mathalpha^^MATHEMATICAL MONOSPACE SMALL S
1D69D^𝚝^\mathtt{t}^\mttt^A^mathalpha^^MATHEMATICAL MONOSPACE SMALL T
1D69E^𝚞^\mathtt{u}^\mttu^A^mathalpha^^MATHEMATICAL MONOSPACE SMALL U
1D69F^𝚟^\mathtt{v}^\mttv^A^mathalpha^^MATHEMATICAL MONOSPACE SMALL V
1D6A0^𝚠^\mathtt{w}^\mttw^A^mathalpha^^MATHEMATICAL MONOSPACE SMALL W
1D6A1^𝚡^\mathtt{x}^\mttx^A^mathalpha^^MATHEMATICAL MONOSPACE SMALL X
1D6A2^𝚢^\mathtt{y}^\mtty^A^mathalpha^^MATHEMATICAL MONOSPACE SMALL Y
1D6A3^𝚣^\mathtt{z}^\mttz^A^mathalpha^^MATHEMATICAL MONOSPACE SMALL Z
1D6A4^𝚤^\imath^\imath^A^mathalpha^^MATHEMATICAL ITALIC SMALL DOTLESS I
1D6A5^𝚥^\jmath^\jmath^A^mathalpha^^MATHEMATICAL ITALIC SMALL DOTLESS J
1D6A8^𝚨^^\mbfAlpha^A^mathalpha^^MATHEMATICAL BOLD CAPITAL ALPHA
1D6A9^𝚩^^\mbfBeta^A^mathalpha^^MATHEMATICAL BOLD CAPITAL BETA
1D6AA^𝚪^\mathbf{\Gamma}^\mbfGamma^A^mathalpha^-fourier^MATHEMATICAL BOLD CAPITAL GAMMA
1D6AB^𝚫^\mathbf{\Delta}^\mbfDelta^A^mathalpha^-fourier^MATHEMATICAL BOLD CAPITAL DELTA
1D6AC^𝚬^^\mbfEpsilon^A^mathalpha^^MATHEMATICAL BOLD CAPITAL EPSILON
1D6AD^𝚭^^\mbfZeta^A^mathalpha^^MATHEMATICAL BOLD CAPITAL ZETA
1D6AE^𝚮^^\mbfEta^A^mathalpha^^MATHEMATICAL BOLD CAPITAL ETA
1D6AF^𝚯^\mathbf{\Theta}^\mbfTheta^A^mathalpha^-fourier^MATHEMATICAL BOLD CAPITAL THETA
1D6B0^𝚰^^\mbfIota^A^mathalpha^^MATHEMATICAL BOLD CAPITAL IOTA
1D6B1^𝚱^^\mbfKappa^A^mathalpha^^MATHEMATICAL BOLD CAPITAL KAPPA
1D6B2^𝚲^\mathbf{\Lambda}^\mbfLambda^A^mathalpha^-fourier^mathematical bold capital lambda
1D6B3^𝚳^^\mbfMu^A^mathalpha^^MATHEMATICAL BOLD CAPITAL MU
1D6B4^𝚴^^\mbfNu^A^mathalpha^^MATHEMATICAL BOLD CAPITAL NU
1D6B5^𝚵^\mathbf{\Xi}^\mbfXi^A^mathalpha^-fourier^MATHEMATICAL BOLD CAPITAL XI
1D6B6^𝚶^^\mbfOmicron^A^mathalpha^^MATHEMATICAL BOLD CAPITAL OMICRON
1D6B7^𝚷^\mathbf{\Pi}^\mbfPi^A^mathalpha^-fourier^MATHEMATICAL BOLD CAPITAL PI
1D6B8^𝚸^^\mbfRho^A^mathalpha^^MATHEMATICAL BOLD CAPITAL RHO
1D6B9^𝚹^^\mbfvarTheta^A^mathalpha^^MATHEMATICAL BOLD CAPITAL THETA SYMBOL
1D6BA^𝚺^\mathbf{\Sigma}^\mbfSigma^A^mathalpha^-fourier^MATHEMATICAL BOLD CAPITAL SIGMA
1D6BB^𝚻^^\mbfTau^A^mathalpha^^MATHEMATICAL BOLD CAPITAL TAU
1D6BC^𝚼^\mathbf{\Upsilon}^\mbfUpsilon^A^mathalpha^-fourier^MATHEMATICAL BOLD CAPITAL UPSILON
1D6BD^𝚽^\mathbf{\Phi}^\mbfPhi^A^mathalpha^-fourier^MATHEMATICAL BOLD CAPITAL PHI
1D6BE^𝚾^^\mbfChi^A^mathalpha^^MATHEMATICAL BOLD CAPITAL CHI
1D6BF^𝚿^\mathbf{\Psi}^\mbfPsi^A^mathalpha^-fourier^MATHEMATICAL BOLD CAPITAL PSI
1D6C0^𝛀^\mathbf{\Omega}^\mbfOmega^A^mathalpha^-fourier^MATHEMATICAL BOLD CAPITAL OMEGA
1D6C1^𝛁^^\mbfnabla^A^mathord^^MATHEMATICAL BOLD NABLA
1D6C2^𝛂^\mathbf{\alpha}^\mbfalpha^A^mathalpha^omlmathbf^MATHEMATICAL BOLD SMALL ALPHA
1D6C3^𝛃^\mathbf{\beta}^\mbfbeta^A^mathalpha^omlmathbf^MATHEMATICAL BOLD SMALL BETA
1D6C4^𝛄^\mathbf{\gamma}^\mbfgamma^A^mathalpha^omlmathbf^MATHEMATICAL BOLD SMALL GAMMA
1D6C5^𝛅^\mathbf{\delta}^\mbfdelta^A^mathalpha^omlmathbf^MATHEMATICAL BOLD SMALL DELTA
1D6C6^𝛆^\mathbf{\varepsilon}^\mbfepsilon^A^mathalpha^omlmathbf^MATHEMATICAL BOLD SMALL EPSILON
1D6C7^𝛇^\mathbf{\zeta}^\mbfzeta^A^mathalpha^omlmathbf^MATHEMATICAL BOLD SMALL ZETA
1D6C8^𝛈^\mathbf{\eta}^\mbfeta^A^mathalpha^omlmathbf^MATHEMATICAL BOLD SMALL ETA
1D6C9^𝛉^\mathbf{\theta}^\mbftheta^A^mathalpha^omlmathbf^MATHEMATICAL BOLD SMALL THETA
1D6CA^𝛊^\mathbf{\iota}^\mbfiota^A^mathalpha^omlmathbf^MATHEMATICAL BOLD SMALL IOTA
1D6CB^𝛋^\mathbf{\kappa}^\mbfkappa^A^mathalpha^omlmathbf^MATHEMATICAL BOLD SMALL KAPPA
1D6CC^𝛌^\mathbf{\lambda}^\mbflambda^A^mathalpha^omlmathbf^mathematical bold small lambda
1D6CD^𝛍^\mathbf{\mu}^\mbfmu^A^mathalpha^omlmathbf^MATHEMATICAL BOLD SMALL MU
1D6CE^𝛎^\mathbf{\nu}^\mbfnu^A^mathalpha^omlmathbf^MATHEMATICAL BOLD SMALL NU
1D6CF^𝛏^\mathbf{\xi}^\mbfxi^A^mathalpha^omlmathbf^MATHEMATICAL BOLD SMALL XI
1D6D0^𝛐^^\mbfomicron^A^mathalpha^^MATHEMATICAL BOLD SMALL OMICRON
1D6D1^𝛑^\mathbf{\pi}^\mbfpi^A^mathalpha^omlmathbf^MATHEMATICAL BOLD SMALL PI
1D6D2^𝛒^\mathbf{\rho}^\mbfrho^A^mathalpha^omlmathbf^MATHEMATICAL BOLD SMALL RHO
1D6D3^𝛓^\mathbf{\varsigma}^\mbfvarsigma^A^mathalpha^omlmathbf^MATHEMATICAL BOLD SMALL FINAL SIGMA
1D6D4^𝛔^\mathbf{\sigma}^\mbfsigma^A^mathalpha^omlmathbf^MATHEMATICAL BOLD SMALL SIGMA
1D6D5^𝛕^\mathbf{\tau}^\mbftau^A^mathalpha^omlmathbf^MATHEMATICAL BOLD SMALL TAU
1D6D6^𝛖^\mathbf{\upsilon}^\mbfupsilon^A^mathalpha^omlmathbf^MATHEMATICAL BOLD SMALL UPSILON
1D6D7^𝛗^\mathbf{\varphi}^\mbfvarphi^A^mathalpha^omlmathbf^MATHEMATICAL BOLD SMALL PHI
1D6D8^𝛘^\mathbf{\chi}^\mbfchi^A^mathalpha^omlmathbf^MATHEMATICAL BOLD SMALL CHI
1D6D9^𝛙^\mathbf{\psi}^\mbfpsi^A^mathalpha^omlmathbf^MATHEMATICAL BOLD SMALL PSI
1D6DA^𝛚^\mathbf{\omega}^\mbfomega^A^mathalpha^omlmathbf^MATHEMATICAL BOLD SMALL OMEGA
1D6DB^𝛛^^\mbfpartial^A^mathord^^MATHEMATICAL BOLD PARTIAL DIFFERENTIAL
1D6DC^𝛜^\mathbf{\epsilon}^\mbfvarepsilon^A^mathalpha^omlmathbf^MATHEMATICAL BOLD EPSILON SYMBOL
1D6DD^𝛝^\mathbf{\vartheta}^\mbfvartheta^A^mathalpha^omlmathbf^MATHEMATICAL BOLD THETA SYMBOL
1D6DE^𝛞^^\mbfvarkappa^A^mathalpha^^MATHEMATICAL BOLD KAPPA SYMBOL
1D6DF^𝛟^\mathbf{\phi}^\mbfphi^A^mathalpha^omlmathbf^MATHEMATICAL BOLD PHI SYMBOL
1D6E0^𝛠^\mathbf{\varrho}^\mbfvarrho^A^mathalpha^omlmathbf^MATHEMATICAL BOLD RHO SYMBOL
1D6E1^𝛡^\mathbf{\varpi}^\mbfvarpi^A^mathalpha^omlmathbf^MATHEMATICAL BOLD PI SYMBOL
1D6E2^𝛢^^\mitAlpha^A^mathalpha^^MATHEMATICAL ITALIC CAPITAL ALPHA
1D6E3^𝛣^^\mitBeta^A^mathalpha^^MATHEMATICAL ITALIC CAPITAL BETA
1D6E4^𝛤^\Gamma^\mitGamma^A^mathalpha^slantedGreek^= \mathit{\Gamma} (-fourier), = \varGamma (amsmath fourier), MATHEMATICAL ITALIC CAPITAL GAMMA
1D6E5^𝛥^\Delta^\mitDelta^A^mathalpha^slantedGreek^= \mathit{\Delta} (-fourier), = \varDelta (amsmath fourier), MATHEMATICAL ITALIC CAPITAL DELTA
1D6E6^𝛦^^\mitEpsilon^A^mathalpha^^MATHEMATICAL ITALIC CAPITAL EPSILON
1D6E7^𝛧^^\mitZeta^A^mathalpha^^MATHEMATICAL ITALIC CAPITAL ZETA
1D6E8^𝛨^^\mitEta^A^mathalpha^^MATHEMATICAL ITALIC CAPITAL ETA
1D6E9^𝛩^\Theta^\mitTheta^A^mathalpha^slantedGreek^= \mathit{\Theta} (-fourier), = \varTheta (amsmath fourier), MATHEMATICAL ITALIC CAPITAL THETA
1D6EA^𝛪^^\mitIota^A^mathalpha^^MATHEMATICAL ITALIC CAPITAL IOTA
1D6EB^𝛫^^\mitKappa^A^mathalpha^^MATHEMATICAL ITALIC CAPITAL KAPPA
1D6EC^𝛬^\Lambda^\mitLambda^A^mathalpha^slantedGreek^= \mathit{\Lambda} (-fourier), = \varLambda (amsmath fourier), mathematical italic capital lambda
1D6ED^𝛭^^\mitMu^A^mathalpha^^MATHEMATICAL ITALIC CAPITAL MU
1D6EE^𝛮^^\mitNu^A^mathalpha^^MATHEMATICAL ITALIC CAPITAL NU
1D6EF^𝛯^\Xi^\mitXi^A^mathalpha^slantedGreek^= \mathit{\Xi} (-fourier), = \varXi (amsmath fourier), MATHEMATICAL ITALIC CAPITAL XI
1D6F0^𝛰^^\mitOmicron^A^mathalpha^^MATHEMATICAL ITALIC CAPITAL OMICRON
1D6F1^𝛱^\Pi^\mitPi^A^mathalpha^slantedGreek^= \mathit{\Pi} (-fourier), = \varPi (amsmath fourier), MATHEMATICAL ITALIC CAPITAL PI
1D6F2^𝛲^^\mitRho^A^mathalpha^^MATHEMATICAL ITALIC CAPITAL RHO
1D6F3^𝛳^^\mitvarTheta^A^mathalpha^^MATHEMATICAL ITALIC CAPITAL THETA SYMBOL
1D6F4^𝛴^\Sigma^\mitSigma^A^mathalpha^slantedGreek^= \mathit{\Sigma} (-fourier), = \varSigma (amsmath fourier), MATHEMATICAL ITALIC CAPITAL SIGMA
1D6F5^𝛵^^\mitTau^A^mathalpha^^MATHEMATICAL ITALIC CAPITAL TAU
1D6F6^𝛶^\Upsilon^\mitUpsilon^A^mathalpha^slantedGreek^= \mathit{\Upsilon} (-fourier), = \varUpsilon (amsmath fourier), MATHEMATICAL ITALIC CAPITAL UPSILON
1D6F7^𝛷^\Phi^\mitPhi^A^mathalpha^slantedGreek^= \mathit{\Phi} (-fourier), = \varPhi (amsmath fourier), MATHEMATICAL ITALIC CAPITAL PHI
1D6F8^𝛸^^\mitChi^A^mathalpha^^MATHEMATICAL ITALIC CAPITAL CHI
1D6F9^𝛹^\Psi^\mitPsi^A^mathalpha^slantedGreek^= \mathit{\Psi} (-fourier), = \varPsi (amsmath fourier), MATHEMATICAL ITALIC CAPITAL PSI
1D6FA^𝛺^\Omega^\mitOmega^A^mathalpha^slantedGreek^= \mathit{\Omega} (-fourier), = \varOmega (amsmath fourier), MATHEMATICAL ITALIC CAPITAL OMEGA
1D6FB^𝛻^^\mitnabla^A^mathord^^MATHEMATICAL ITALIC NABLA
1D6FC^𝛼^\alpha^\mitalpha^A^mathalpha^^= \mathit{\alpha} (omlmathit), MATHEMATICAL ITALIC SMALL ALPHA
1D6FD^𝛽^\beta^\mitbeta^A^mathalpha^^= \mathit{\beta} (omlmathit), MATHEMATICAL ITALIC SMALL BETA
1D6FE^𝛾^\gamma^\mitgamma^A^mathalpha^^= \mathit{\gamma} (omlmathit), MATHEMATICAL ITALIC SMALL GAMMA
1D6FF^𝛿^\delta^\mitdelta^A^mathalpha^^= \mathit{\delta} (omlmathit), MATHEMATICAL ITALIC SMALL DELTA
1D700^𝜀^\varepsilon^\mitepsilon^A^mathalpha^^= \mathit{\varepsilon} (omlmathit), MATHEMATICAL ITALIC SMALL EPSILON
1D701^𝜁^\zeta^\mitzeta^A^mathalpha^^= \mathit{\zeta} (omlmathit), MATHEMATICAL ITALIC SMALL ZETA
1D702^𝜂^\eta^\miteta^A^mathalpha^^= \mathit{\eta} (omlmathit), MATHEMATICAL ITALIC SMALL ETA
1D703^𝜃^\theta^\mittheta^A^mathalpha^^= \mathit{\theta} (omlmathit), MATHEMATICAL ITALIC SMALL THETA
1D704^𝜄^\iota^\mitiota^A^mathalpha^^= \mathit{\iota} (omlmathit), MATHEMATICAL ITALIC SMALL IOTA
1D705^𝜅^\kappa^\mitkappa^A^mathalpha^^= \mathit{\kappa} (omlmathit), MATHEMATICAL ITALIC SMALL KAPPA
1D706^𝜆^\lambda^\mitlambda^A^mathalpha^^= \mathit{\lambda} (omlmathit), mathematical italic small lambda
1D707^𝜇^\mu^\mitmu^A^mathalpha^^= \mathit{\mu} (omlmathit), MATHEMATICAL ITALIC SMALL MU
1D708^𝜈^\nu^\mitnu^A^mathalpha^^= \mathit{\nu} (omlmathit), MATHEMATICAL ITALIC SMALL NU
1D709^𝜉^\xi^\mitxi^A^mathalpha^^= \mathit{\xi} (omlmathit), MATHEMATICAL ITALIC SMALL XI
1D70A^𝜊^^\mitomicron^A^mathalpha^^MATHEMATICAL ITALIC SMALL OMICRON
1D70B^𝜋^\pi^\mitpi^A^mathalpha^^= \mathit{\pi} (omlmathit), MATHEMATICAL ITALIC SMALL PI
1D70C^𝜌^\rho^\mitrho^A^mathalpha^^= \mathit{\rho} (omlmathit), MATHEMATICAL ITALIC SMALL RHO
1D70D^𝜍^\varsigma^\mitvarsigma^A^mathalpha^^= \mathit{\varsigma} (omlmathit), MATHEMATICAL ITALIC SMALL FINAL SIGMA
1D70E^𝜎^\sigma^\mitsigma^A^mathalpha^^= \mathit{\sigma} (omlmathit), MATHEMATICAL ITALIC SMALL SIGMA
1D70F^𝜏^\tau^\mittau^A^mathalpha^^= \mathit{\tau} (omlmathit), MATHEMATICAL ITALIC SMALL TAU
1D710^𝜐^\upsilon^\mitupsilon^A^mathalpha^^= \mathit{\upsilon} (omlmathit), MATHEMATICAL ITALIC SMALL UPSILON
1D711^𝜑^\varphi^\mitphi^A^mathalpha^^= \mathit{\varphi} (omlmathit), MATHEMATICAL ITALIC SMALL PHI
1D712^𝜒^\chi^\mitchi^A^mathalpha^^= \mathit{\chi} (omlmathit), MATHEMATICAL ITALIC SMALL CHI
1D713^𝜓^\psi^\mitpsi^A^mathalpha^^= \mathit{\psi} (omlmathit), MATHEMATICAL ITALIC SMALL PSI
1D714^𝜔^\omega^\mitomega^A^mathalpha^^= \mathit{\omega} (omlmathit), MATHEMATICAL ITALIC SMALL OMEGA
1D715^𝜕^\partial^\mitpartial^A^mathord^^= \mathit{\partial} (omlmathit), MATHEMATICAL ITALIC PARTIAL DIFFERENTIAL
1D716^𝜖^\epsilon^\mitvarepsilon^A^mathalpha^^= \mathit{\epsilon} (omlmathit), MATHEMATICAL ITALIC EPSILON SYMBOL
1D717^𝜗^\vartheta^\mitvartheta^A^mathalpha^^= \mathit{\vartheta} (omlmathit), MATHEMATICAL ITALIC THETA SYMBOL
1D718^𝜘^\varkappa^\mitvarkappa^A^mathalpha^amssymb^MATHEMATICAL ITALIC KAPPA SYMBOL
1D719^𝜙^\phi^\mitvarphi^A^mathalpha^^= \mathit{\phi} (omlmathit), MATHEMATICAL ITALIC PHI SYMBOL
1D71A^𝜚^\varrho^\mitvarrho^A^mathalpha^^= \mathit{\varrho} (omlmathit), MATHEMATICAL ITALIC RHO SYMBOL
1D71B^𝜛^\varpi^\mitvarpi^A^mathalpha^^= \mathit{\varpi} (omlmathit), MATHEMATICAL ITALIC PI SYMBOL
1D71C^𝜜^^\mbfitAlpha^A^mathalpha^^MATHEMATICAL BOLD ITALIC CAPITAL ALPHA
1D71D^𝜝^^\mbfitBeta^A^mathalpha^^MATHEMATICAL BOLD ITALIC CAPITAL BETA
1D71E^𝜞^\mathbfit{\Gamma}^\mbfitGamma^A^mathalpha^isomath^= \mathbold{\Gamma} (fixmath), MATHEMATICAL BOLD ITALIC CAPITAL GAMMA
1D71F^𝜟^\mathbfit{\Delta}^\mbfitDelta^A^mathalpha^isomath^= \mathbold{\Delta} (fixmath), MATHEMATICAL BOLD ITALIC CAPITAL DELTA
1D720^𝜠^^\mbfitEpsilon^A^mathalpha^^MATHEMATICAL BOLD ITALIC CAPITAL EPSILON
1D721^𝜡^^\mbfitZeta^A^mathalpha^^MATHEMATICAL BOLD ITALIC CAPITAL ZETA
1D722^𝜢^^\mbfitEta^A^mathalpha^^MATHEMATICAL BOLD ITALIC CAPITAL ETA
1D723^𝜣^\mathbfit{\Theta}^\mbfitTheta^A^mathalpha^isomath^= \mathbold{\Theta} (fixmath), MATHEMATICAL BOLD ITALIC CAPITAL THETA
1D724^𝜤^^\mbfitIota^A^mathalpha^^MATHEMATICAL BOLD ITALIC CAPITAL IOTA
1D725^𝜥^^\mbfitKappa^A^mathalpha^^MATHEMATICAL BOLD ITALIC CAPITAL KAPPA
1D726^𝜦^\mathbfit{\Lambda}^\mbfitLambda^A^mathalpha^isomath^= \mathbold{\Lambda} (fixmath), mathematical bold italic capital lambda
1D727^𝜧^^\mbfitMu^A^mathalpha^^MATHEMATICAL BOLD ITALIC CAPITAL MU
1D728^𝜨^^\mbfitNu^A^mathalpha^^MATHEMATICAL BOLD ITALIC CAPITAL NU
1D729^𝜩^\mathbfit{\Xi}^\mbfitXi^A^mathalpha^isomath^= \mathbold{\Xi} (fixmath), MATHEMATICAL BOLD ITALIC CAPITAL XI
1D72A^𝜪^^\mbfitOmicron^A^mathalpha^^MATHEMATICAL BOLD ITALIC CAPITAL OMICRON
1D72B^𝜫^\mathbfit{\Pi}^\mbfitPi^A^mathalpha^isomath^= \mathbold{\Pi} (fixmath), MATHEMATICAL BOLD ITALIC CAPITAL PI
1D72C^𝜬^^\mbfitRho^A^mathalpha^^MATHEMATICAL BOLD ITALIC CAPITAL RHO
1D72D^𝜭^^\mbfitvarTheta^A^mathalpha^^MATHEMATICAL BOLD ITALIC CAPITAL THETA SYMBOL
1D72E^𝜮^\mathbfit{\Sigma}^\mbfitSigma^A^mathalpha^isomath^= \mathbold{\Sigma} (fixmath), MATHEMATICAL BOLD ITALIC CAPITAL SIGMA
1D72F^𝜯^^\mbfitTau^A^mathalpha^^MATHEMATICAL BOLD ITALIC CAPITAL TAU
1D730^𝜰^\mathbfit{\Upsilon}^\mbfitUpsilon^A^mathalpha^isomath^= \mathbold{\Upsilon} (fixmath), MATHEMATICAL BOLD ITALIC CAPITAL UPSILON
1D731^𝜱^\mathbfit{\Phi}^\mbfitPhi^A^mathalpha^isomath^= \mathbold{\Phi} (fixmath), MATHEMATICAL BOLD ITALIC CAPITAL PHI
1D732^𝜲^^\mbfitChi^A^mathalpha^^MATHEMATICAL BOLD ITALIC CAPITAL CHI
1D733^𝜳^\mathbfit{\Psi}^\mbfitPsi^A^mathalpha^isomath^= \mathbold{\Psi} (fixmath), MATHEMATICAL BOLD ITALIC CAPITAL PSI
1D734^𝜴^\mathbfit{\Omega}^\mbfitOmega^A^mathalpha^isomath^= \mathbold{\Omega} (fixmath), MATHEMATICAL BOLD ITALIC CAPITAL OMEGA
1D735^𝜵^^\mbfitnabla^A^mathord^^MATHEMATICAL BOLD ITALIC NABLA
1D736^𝜶^\mathbfit{\alpha}^\mbfitalpha^A^mathalpha^isomath^= \mathbold{\alpha} (fixmath), MATHEMATICAL BOLD ITALIC SMALL ALPHA
1D737^𝜷^\mathbfit{\beta}^\mbfitbeta^A^mathalpha^isomath^= \mathbold{\beta} (fixmath), MATHEMATICAL BOLD ITALIC SMALL BETA
1D738^𝜸^\mathbfit{\gamma}^\mbfitgamma^A^mathalpha^isomath^= \mathbold{\gamma} (fixmath), MATHEMATICAL BOLD ITALIC SMALL GAMMA
1D739^𝜹^\mathbfit{\delta}^\mbfitdelta^A^mathalpha^isomath^= \mathbold{\delta} (fixmath), MATHEMATICAL BOLD ITALIC SMALL DELTA
1D73A^𝜺^\mathbfit{\varepsilon}^\mbfitepsilon^A^mathalpha^isomath^= \mathbold{\varepsilon} (fixmath), MATHEMATICAL BOLD ITALIC SMALL EPSILON
1D73B^𝜻^\mathbfit{\zeta}^\mbfitzeta^A^mathalpha^isomath^= \mathbold{\zeta} (fixmath), MATHEMATICAL BOLD ITALIC SMALL ZETA
1D73C^𝜼^\mathbfit{\eta}^\mbfiteta^A^mathalpha^isomath^= \mathbold{\eta} (fixmath), MATHEMATICAL BOLD ITALIC SMALL ETA
1D73D^𝜽^\mathbfit{\theta}^\mbfittheta^A^mathalpha^isomath^= \mathbold{\theta} (fixmath), MATHEMATICAL BOLD ITALIC SMALL THETA
1D73E^𝜾^\mathbfit{\iota}^\mbfitiota^A^mathalpha^isomath^= \mathbold{\iota} (fixmath), MATHEMATICAL BOLD ITALIC SMALL IOTA
1D73F^𝜿^\mathbfit{\kappa}^\mbfitkappa^A^mathalpha^isomath^= \mathbold{\kappa} (fixmath), MATHEMATICAL BOLD ITALIC SMALL KAPPA
1D740^𝝀^\mathbfit{\lambda}^\mbfitlambda^A^mathalpha^isomath^= \mathbold{\lambda} (fixmath), mathematical bold italic small lambda
1D741^𝝁^\mathbfit{\mu}^\mbfitmu^A^mathalpha^isomath^= \mathbold{\mu} (fixmath), MATHEMATICAL BOLD ITALIC SMALL MU
1D742^𝝂^\mathbfit{\nu}^\mbfitnu^A^mathalpha^isomath^= \mathbold{\nu} (fixmath), MATHEMATICAL BOLD ITALIC SMALL NU
1D743^𝝃^\mathbfit{\xi}^\mbfitxi^A^mathalpha^isomath^= \mathbold{\xi} (fixmath), MATHEMATICAL BOLD ITALIC SMALL XI
1D744^𝝄^^\mbfitomicron^A^mathalpha^^MATHEMATICAL BOLD ITALIC SMALL OMICRON
1D745^𝝅^\mathbfit{\pi}^\mbfitpi^A^mathalpha^isomath^= \mathbold{\pi} (fixmath), MATHEMATICAL BOLD ITALIC SMALL PI
1D746^𝝆^\mathbfit{\rho}^\mbfitrho^A^mathalpha^isomath^= \mathbold{\rho} (fixmath), MATHEMATICAL BOLD ITALIC SMALL RHO
1D747^𝝇^\mathbfit{\varsigma}^\mbfitvarsigma^A^mathalpha^isomath^= \mathbold{\varsigma} (fixmath), MATHEMATICAL BOLD ITALIC SMALL FINAL SIGMA
1D748^𝝈^\mathbfit{\sigma}^\mbfitsigma^A^mathalpha^isomath^= \mathbold{\sigma} (fixmath), MATHEMATICAL BOLD ITALIC SMALL SIGMA
1D749^𝝉^\mathbfit{\tau}^\mbfittau^A^mathalpha^isomath^= \mathbold{\tau} (fixmath), MATHEMATICAL BOLD ITALIC SMALL TAU
1D74A^𝝊^\mathbfit{\upsilon}^\mbfitupsilon^A^mathalpha^isomath^= \mathbold{\upsilon} (fixmath), MATHEMATICAL BOLD ITALIC SMALL UPSILON
1D74B^𝝋^\mathbfit{\varphi}^\mbfitphi^A^mathalpha^isomath^= \mathbold{\varphi} (fixmath), MATHEMATICAL BOLD ITALIC SMALL PHI
1D74C^𝝌^\mathbfit{\chi}^\mbfitchi^A^mathalpha^isomath^= \mathbold{\chi} (fixmath), MATHEMATICAL BOLD ITALIC SMALL CHI
1D74D^𝝍^\mathbfit{\psi}^\mbfitpsi^A^mathalpha^isomath^= \mathbold{\psi} (fixmath), MATHEMATICAL BOLD ITALIC SMALL PSI
1D74E^𝝎^\mathbfit{\omega}^\mbfitomega^A^mathalpha^isomath^= \mathbold{\omega} (fixmath), MATHEMATICAL BOLD ITALIC SMALL OMEGA
1D74F^𝝏^^\mbfitpartial^A^mathord^^MATHEMATICAL BOLD ITALIC PARTIAL DIFFERENTIAL
1D750^𝝐^\mathbfit{\epsilon}^\mbfitvarepsilon^A^mathalpha^isomath^= \mathbold{\epsilon} (fixmath), MATHEMATICAL BOLD ITALIC EPSILON SYMBOL
1D751^𝝑^\mathbfit{\vartheta}^\mbfitvartheta^A^mathalpha^isomath^= \mathbold{\vartheta} (fixmath), MATHEMATICAL BOLD ITALIC THETA SYMBOL
1D752^𝝒^^\mbfitvarkappa^A^mathalpha^^MATHEMATICAL BOLD ITALIC KAPPA SYMBOL
1D753^𝝓^\mathbfit{\phi}^\mbfitvarphi^A^mathalpha^isomath^= \mathbold{\phi} (fixmath), MATHEMATICAL BOLD ITALIC PHI SYMBOL
1D754^𝝔^\mathbfit{\varrho}^\mbfitvarrho^A^mathalpha^isomath^= \mathbold{\varrho} (fixmath), MATHEMATICAL BOLD ITALIC RHO SYMBOL
1D755^𝝕^\mathbfit{\varpi}^\mbfitvarpi^A^mathalpha^isomath^= \mathbold{\varpi} (fixmath), MATHEMATICAL BOLD ITALIC PI SYMBOL
1D756^𝝖^^\mbfsansAlpha^A^mathalpha^^MATHEMATICAL SANS-SERIF BOLD CAPITAL ALPHA
1D757^𝝗^^\mbfsansBeta^A^mathalpha^^MATHEMATICAL SANS-SERIF BOLD CAPITAL BETA
1D758^𝝘^\mathsfbf{\Gamma}^\mbfsansGamma^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD CAPITAL GAMMA
1D759^𝝙^\mathsfbf{\Delta}^\mbfsansDelta^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD CAPITAL DELTA
1D75A^𝝚^^\mbfsansEpsilon^A^mathalpha^^MATHEMATICAL SANS-SERIF BOLD CAPITAL EPSILON
1D75B^𝝛^^\mbfsansZeta^A^mathalpha^^MATHEMATICAL SANS-SERIF BOLD CAPITAL ZETA
1D75C^𝝜^^\mbfsansEta^A^mathalpha^^MATHEMATICAL SANS-SERIF BOLD CAPITAL ETA
1D75D^𝝝^\mathsfbf{\Theta}^\mbfsansTheta^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD CAPITAL THETA
1D75E^𝝞^^\mbfsansIota^A^mathalpha^^MATHEMATICAL SANS-SERIF BOLD CAPITAL IOTA
1D75F^𝝟^^\mbfsansKappa^A^mathalpha^^MATHEMATICAL SANS-SERIF BOLD CAPITAL KAPPA
1D760^𝝠^\mathsfbf{\Lambda}^\mbfsansLambda^A^mathalpha^mathsfbf^mathematical sans-serif bold capital lambda
1D761^𝝡^^\mbfsansMu^A^mathalpha^^MATHEMATICAL SANS-SERIF BOLD CAPITAL MU
1D762^𝝢^^\mbfsansNu^A^mathalpha^^MATHEMATICAL SANS-SERIF BOLD CAPITAL NU
1D763^𝝣^\mathsfbf{\Xi}^\mbfsansXi^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD CAPITAL XI
1D764^𝝤^^\mbfsansOmicron^A^mathalpha^^MATHEMATICAL SANS-SERIF BOLD CAPITAL OMICRON
1D765^𝝥^\mathsfbf{\Pi}^\mbfsansPi^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD CAPITAL PI
1D766^𝝦^^\mbfsansRho^A^mathalpha^^MATHEMATICAL SANS-SERIF BOLD CAPITAL RHO
1D767^𝝧^^\mbfsansvarTheta^A^mathalpha^^MATHEMATICAL SANS-SERIF BOLD CAPITAL THETA SYMBOL
1D768^𝝨^\mathsfbf{\Sigma}^\mbfsansSigma^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD CAPITAL SIGMA
1D769^𝝩^^\mbfsansTau^A^mathalpha^^MATHEMATICAL SANS-SERIF BOLD CAPITAL TAU
1D76A^𝝪^\mathsfbf{\Upsilon}^\mbfsansUpsilon^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD CAPITAL UPSILON
1D76B^𝝫^\mathsfbf{\Phi}^\mbfsansPhi^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD CAPITAL PHI
1D76C^𝝬^^\mbfsansChi^A^mathalpha^^MATHEMATICAL SANS-SERIF BOLD CAPITAL CHI
1D76D^𝝭^\mathsfbf{\Psi}^\mbfsansPsi^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD CAPITAL PSI
1D76E^𝝮^\mathsfbf{\Omega}^\mbfsansOmega^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD CAPITAL OMEGA
1D76F^𝝯^^\mbfsansnabla^A^mathord^^MATHEMATICAL SANS-SERIF BOLD NABLA
1D770^𝝰^\mathsfbf{\alpha}^\mbfsansalpha^A^mathalpha^omlmathsfbf^MATHEMATICAL SANS-SERIF BOLD SMALL ALPHA
1D771^𝝱^\mathsfbf{\beta}^\mbfsansbeta^A^mathalpha^omlmathsfbf^MATHEMATICAL SANS-SERIF BOLD SMALL BETA
1D772^𝝲^\mathsfbf{\gamma}^\mbfsansgamma^A^mathalpha^omlmathsfbf^MATHEMATICAL SANS-SERIF BOLD SMALL GAMMA
1D773^𝝳^\mathsfbf{\delta}^\mbfsansdelta^A^mathalpha^omlmathsfbf^MATHEMATICAL SANS-SERIF BOLD SMALL DELTA
1D774^𝝴^\mathsfbf{\varepsilon}^\mbfsansepsilon^A^mathalpha^omlmathsfbf^MATHEMATICAL SANS-SERIF BOLD SMALL EPSILON
1D775^𝝵^\mathsfbf{\zeta}^\mbfsanszeta^A^mathalpha^omlmathsfbf^MATHEMATICAL SANS-SERIF BOLD SMALL ZETA
1D776^𝝶^\mathsfbf{\eta}^\mbfsanseta^A^mathalpha^omlmathsfbf^MATHEMATICAL SANS-SERIF BOLD SMALL ETA
1D777^𝝷^\mathsfbf{\theta}^\mbfsanstheta^A^mathalpha^omlmathsfbf^MATHEMATICAL SANS-SERIF BOLD SMALL THETA
1D778^𝝸^\mathsfbf{\iota}^\mbfsansiota^A^mathalpha^omlmathsfbf^MATHEMATICAL SANS-SERIF BOLD SMALL IOTA
1D779^𝝹^\mathsfbf{\kappa}^\mbfsanskappa^A^mathalpha^omlmathsfbf^MATHEMATICAL SANS-SERIF BOLD SMALL KAPPA
1D77A^𝝺^\mathsfbf{\lambda}^\mbfsanslambda^A^mathalpha^omlmathsfbf^mathematical sans-serif bold small lambda
1D77B^𝝻^\mathsfbf{\mu}^\mbfsansmu^A^mathalpha^omlmathsfbf^MATHEMATICAL SANS-SERIF BOLD SMALL MU
1D77C^𝝼^\mathsfbf{\nu}^\mbfsansnu^A^mathalpha^omlmathsfbf^MATHEMATICAL SANS-SERIF BOLD SMALL NU
1D77D^𝝽^\mathsfbf{\xi}^\mbfsansxi^A^mathalpha^omlmathsfbf^MATHEMATICAL SANS-SERIF BOLD SMALL XI
1D77E^𝝾^^\mbfsansomicron^A^mathalpha^^MATHEMATICAL SANS-SERIF BOLD SMALL OMICRON
1D77F^𝝿^\mathsfbf{\pi}^\mbfsanspi^A^mathalpha^omlmathsfbf^MATHEMATICAL SANS-SERIF BOLD SMALL PI
1D780^𝞀^\mathsfbf{\rho}^\mbfsansrho^A^mathalpha^omlmathsfbf^MATHEMATICAL SANS-SERIF BOLD SMALL RHO
1D781^𝞁^\mathsfbf{\varsigma}^\mbfsansvarsigma^A^mathalpha^omlmathsfbf^MATHEMATICAL SANS-SERIF BOLD SMALL FINAL SIGMA
1D782^𝞂^\mathsfbf{\sigma}^\mbfsanssigma^A^mathalpha^omlmathsfbf^MATHEMATICAL SANS-SERIF BOLD SMALL SIGMA
1D783^𝞃^\mathsfbf{\tau}^\mbfsanstau^A^mathalpha^omlmathsfbf^MATHEMATICAL SANS-SERIF BOLD SMALL TAU
1D784^𝞄^\mathsfbf{\upsilon}^\mbfsansupsilon^A^mathalpha^omlmathsfbf^MATHEMATICAL SANS-SERIF BOLD SMALL UPSILON
1D785^𝞅^\mathsfbf{\varphi}^\mbfsansphi^A^mathalpha^omlmathsfbf^MATHEMATICAL SANS-SERIF BOLD SMALL PHI
1D786^𝞆^\mathsfbf{\chi}^\mbfsanschi^A^mathalpha^omlmathsfbf^MATHEMATICAL SANS-SERIF BOLD SMALL CHI
1D787^𝞇^\mathsfbf{\psi}^\mbfsanspsi^A^mathalpha^omlmathsfbf^MATHEMATICAL SANS-SERIF BOLD SMALL PSI
1D788^𝞈^\mathsfbf{\omega}^\mbfsansomega^A^mathalpha^omlmathsfbf^MATHEMATICAL SANS-SERIF BOLD SMALL OMEGA
1D789^𝞉^^\mbfsanspartial^A^mathord^^MATHEMATICAL SANS-SERIF BOLD PARTIAL DIFFERENTIAL
1D78A^𝞊^\mathsfbf{\epsilon}^\mbfsansvarepsilon^A^mathalpha^omlmathsfbf^MATHEMATICAL SANS-SERIF BOLD EPSILON SYMBOL
1D78B^𝞋^\mathsfbf{\vartheta}^\mbfsansvartheta^A^mathalpha^omlmathsfbf^MATHEMATICAL SANS-SERIF BOLD THETA SYMBOL
1D78C^𝞌^^\mbfsansvarkappa^A^mathalpha^^MATHEMATICAL SANS-SERIF BOLD KAPPA SYMBOL
1D78D^𝞍^\mathsfbf{\phi}^\mbfsansvarphi^A^mathalpha^omlmathsfbf^MATHEMATICAL SANS-SERIF BOLD PHI SYMBOL
1D78E^𝞎^\mathsfbf{\varrho}^\mbfsansvarrho^A^mathalpha^omlmathsfbf^MATHEMATICAL SANS-SERIF BOLD RHO SYMBOL
1D78F^𝞏^\mathsfbf{\varpi}^\mbfsansvarpi^A^mathalpha^omlmathsfbf^MATHEMATICAL SANS-SERIF BOLD PI SYMBOL
1D790^𝞐^^\mbfitsansAlpha^A^mathalpha^^MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL ALPHA
1D791^𝞑^^\mbfitsansBeta^A^mathalpha^^MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL BETA
1D792^𝞒^\mathsfbfit{\Gamma}^\mbfitsansGamma^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL GAMMA
1D793^𝞓^\mathsfbfit{\Delta}^\mbfitsansDelta^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL DELTA
1D794^𝞔^^\mbfitsansEpsilon^A^mathalpha^^MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL EPSILON
1D795^𝞕^^\mbfitsansZeta^A^mathalpha^^MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL ZETA
1D796^𝞖^^\mbfitsansEta^A^mathalpha^^MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL ETA
1D797^𝞗^\mathsfbfit{\Theta}^\mbfitsansTheta^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL THETA
1D798^𝞘^^\mbfitsansIota^A^mathalpha^^MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL IOTA
1D799^𝞙^^\mbfitsansKappa^A^mathalpha^^MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL KAPPA
1D79A^𝞚^\mathsfbfit{\Lambda}^\mbfitsansLambda^A^mathalpha^isomath^mathematical sans-serif bold italic capital lambda
1D79B^𝞛^^\mbfitsansMu^A^mathalpha^^MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL MU
1D79C^𝞜^^\mbfitsansNu^A^mathalpha^^MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL NU
1D79D^𝞝^\mathsfbfit{\Xi}^\mbfitsansXi^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL XI
1D79E^𝞞^^\mbfitsansOmicron^A^mathalpha^^MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL OMICRON
1D79F^𝞟^\mathsfbfit{\Pi}^\mbfitsansPi^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL PI
1D7A0^𝞠^^\mbfitsansRho^A^mathalpha^^MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL RHO
1D7A1^𝞡^^\mbfitsansvarTheta^A^mathalpha^^MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL THETA SYMBOL
1D7A2^𝞢^\mathsfbfit{\Sigma}^\mbfitsansSigma^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL SIGMA
1D7A3^𝞣^^\mbfitsansTau^A^mathalpha^^MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL TAU
1D7A4^𝞤^\mathsfbfit{\Upsilon}^\mbfitsansUpsilon^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL UPSILON
1D7A5^𝞥^\mathsfbfit{\Phi}^\mbfitsansPhi^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL PHI
1D7A6^𝞦^^\mbfitsansChi^A^mathalpha^^MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL CHI
1D7A7^𝞧^\mathsfbfit{\Psi}^\mbfitsansPsi^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL PSI
1D7A8^𝞨^\mathsfbfit{\Omega}^\mbfitsansOmega^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL OMEGA
1D7A9^𝞩^^\mbfitsansnabla^A^mathord^^MATHEMATICAL SANS-SERIF BOLD ITALIC NABLA
1D7AA^𝞪^\mathsfbfit{\alpha}^\mbfitsansalpha^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL ALPHA
1D7AB^𝞫^\mathsfbfit{\beta}^\mbfitsansbeta^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL BETA
1D7AC^𝞬^\mathsfbfit{\gamma}^\mbfitsansgamma^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL GAMMA
1D7AD^𝞭^\mathsfbfit{\delta}^\mbfitsansdelta^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL DELTA
1D7AE^𝞮^\mathsfbfit{\varepsilon}^\mbfitsansepsilon^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL EPSILON
1D7AF^𝞯^\mathsfbfit{\zeta}^\mbfitsanszeta^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL ZETA
1D7B0^𝞰^\mathsfbfit{\eta}^\mbfitsanseta^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL ETA
1D7B1^𝞱^\mathsfbfit{\theta}^\mbfitsanstheta^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL THETA
1D7B2^𝞲^\mathsfbfit{\iota}^\mbfitsansiota^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL IOTA
1D7B3^𝞳^\mathsfbfit{\kappa}^\mbfitsanskappa^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL KAPPA
1D7B4^𝞴^\mathsfbfit{\lambda}^\mbfitsanslambda^A^mathalpha^isomath^mathematical sans-serif bold italic small lambda
1D7B5^𝞵^\mathsfbfit{\mu}^\mbfitsansmu^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL MU
1D7B6^𝞶^\mathsfbfit{\nu}^\mbfitsansnu^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL NU
1D7B7^𝞷^\mathsfbfit{\xi}^\mbfitsansxi^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL XI
1D7B8^𝞸^^\mbfitsansomicron^A^mathalpha^^MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL OMICRON
1D7B9^𝞹^\mathsfbfit{\pi}^\mbfitsanspi^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL PI
1D7BA^𝞺^\mathsfbfit{\rho}^\mbfitsansrho^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL RHO
1D7BB^𝞻^\mathsfbfit{\varsigma}^\mbfitsansvarsigma^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL FINAL SIGMA
1D7BC^𝞼^\mathsfbfit{\sigma}^\mbfitsanssigma^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL SIGMA
1D7BD^𝞽^\mathsfbfit{\tau}^\mbfitsanstau^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL TAU
1D7BE^𝞾^\mathsfbfit{\upsilon}^\mbfitsansupsilon^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL UPSILON
1D7BF^𝞿^\mathsfbfit{\varphi}^\mbfitsansphi^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL PHI
1D7C0^𝟀^\mathsfbfit{\chi}^\mbfitsanschi^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL CHI
1D7C1^𝟁^\mathsfbfit{\psi}^\mbfitsanspsi^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL PSI
1D7C2^𝟂^\mathsfbfit{\omega}^\mbfitsansomega^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL OMEGA
1D7C3^𝟃^^\mbfitsanspartial^A^mathord^^MATHEMATICAL SANS-SERIF BOLD ITALIC PARTIAL DIFFERENTIAL
1D7C4^𝟄^\mathsfbfit{\epsilon}^\mbfitsansvarepsilon^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC EPSILON SYMBOL
1D7C5^𝟅^\mathsfbfit{\vartheta}^\mbfitsansvartheta^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC THETA SYMBOL
1D7C6^𝟆^^\mbfitsansvarkappa^A^mathalpha^^MATHEMATICAL SANS-SERIF BOLD ITALIC KAPPA SYMBOL
1D7C7^𝟇^\mathsfbfit{\phi}^\mbfitsansvarphi^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC PHI SYMBOL
1D7C8^𝟈^\mathsfbfit{\varrho}^\mbfitsansvarrho^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC RHO SYMBOL
1D7C9^𝟉^\mathsfbfit{\varpi}^\mbfitsansvarpi^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC PI SYMBOL
1D7CA^𝟊^^\mbfDigamma^A^mathalpha^^MATHEMATICAL BOLD CAPITAL DIGAMMA
1D7CB^𝟋^^\mbfdigamma^A^mathalpha^^MATHEMATICAL BOLD SMALL DIGAMMA
1D7CE^𝟎^\mathbf{0}^^N^mathord^^mathematical bold digit 0
1D7CF^𝟏^\mathbf{1}^^N^mathord^^mathematical bold digit 1
1D7D0^𝟐^\mathbf{2}^^N^mathord^^mathematical bold digit 2
1D7D1^𝟑^\mathbf{3}^^N^mathord^^mathematical bold digit 3
1D7D2^𝟒^\mathbf{4}^^N^mathord^^mathematical bold digit 4
1D7D3^𝟓^\mathbf{5}^^N^mathord^^mathematical bold digit 5
1D7D4^𝟔^\mathbf{6}^^N^mathord^^mathematical bold digit 6
1D7D5^𝟕^\mathbf{7}^^N^mathord^^mathematical bold digit 7
1D7D6^𝟖^\mathbf{8}^^N^mathord^^mathematical bold digit 8
1D7D7^𝟗^\mathbf{9}^^N^mathord^^mathematical bold digit 9
1D7D8^𝟘^\mathbb{0}^\Bbbzero^N^mathord^bbold^mathematical double-struck digit 0
1D7D9^𝟙^\mathbb{1}^\Bbbone^N^mathord^bbold fourier^= \mathds{1} (dsfont), mathematical double-struck digit 1
1D7DA^𝟚^\mathbb{2}^\Bbbtwo^N^mathord^bbold^mathematical double-struck digit 2
1D7DB^𝟛^\mathbb{3}^\Bbbthree^N^mathord^bbold^mathematical double-struck digit 3
1D7DC^𝟜^\mathbb{4}^\Bbbfour^N^mathord^bbold^mathematical double-struck digit 4
1D7DD^𝟝^\mathbb{5}^\Bbbfive^N^mathord^bbold^mathematical double-struck digit 5
1D7DE^𝟞^\mathbb{6}^\Bbbsix^N^mathord^bbold^mathematical double-struck digit 6
1D7DF^𝟟^\mathbb{7}^\Bbbseven^N^mathord^bbold^mathematical double-struck digit 7
1D7E0^𝟠^\mathbb{8}^\Bbbeight^N^mathord^bbold^mathematical double-struck digit 8
1D7E1^𝟡^\mathbb{9}^\Bbbnine^N^mathord^bbold^mathematical double-struck digit 9
1D7E2^𝟢^\mathsf{0}^\msanszero^N^mathord^^mathematical sans-serif digit 0
1D7E3^𝟣^\mathsf{1}^\msansone^N^mathord^^mathematical sans-serif digit 1
1D7E4^𝟤^\mathsf{2}^\msanstwo^N^mathord^^mathematical sans-serif digit 2
1D7E5^𝟥^\mathsf{3}^\msansthree^N^mathord^^mathematical sans-serif digit 3
1D7E6^𝟦^\mathsf{4}^\msansfour^N^mathord^^mathematical sans-serif digit 4
1D7E7^𝟧^\mathsf{5}^\msansfive^N^mathord^^mathematical sans-serif digit 5
1D7E8^𝟨^\mathsf{6}^\msanssix^N^mathord^^mathematical sans-serif digit 6
1D7E9^𝟩^\mathsf{7}^\msansseven^N^mathord^^mathematical sans-serif digit 7
1D7EA^𝟪^\mathsf{8}^\msanseight^N^mathord^^mathematical sans-serif digit 8
1D7EB^𝟫^\mathsf{9}^\msansnine^N^mathord^^mathematical sans-serif digit 9
1D7EC^𝟬^\mathsfbf{0}^\mbfsanszero^N^mathord^mathsfbf^mathematical sans-serif bold digit 0
1D7ED^𝟭^\mathsfbf{1}^\mbfsansone^N^mathord^mathsfbf^mathematical sans-serif bold digit 1
1D7EE^𝟮^\mathsfbf{2}^\mbfsanstwo^N^mathord^mathsfbf^mathematical sans-serif bold digit 2
1D7EF^𝟯^\mathsfbf{3}^\mbfsansthree^N^mathord^mathsfbf^mathematical sans-serif bold digit 3
1D7F0^𝟰^\mathsfbf{4}^\mbfsansfour^N^mathord^mathsfbf^mathematical sans-serif bold digit 4
1D7F1^𝟱^\mathsfbf{5}^\mbfsansfive^N^mathord^mathsfbf^mathematical sans-serif bold digit 5
1D7F2^𝟲^\mathsfbf{6}^\mbfsanssix^N^mathord^mathsfbf^mathematical sans-serif bold digit 6
1D7F3^𝟳^\mathsfbf{7}^\mbfsansseven^N^mathord^mathsfbf^mathematical sans-serif bold digit 7
1D7F4^𝟴^\mathsfbf{8}^\mbfsanseight^N^mathord^mathsfbf^mathematical sans-serif bold digit 8
1D7F5^𝟵^\mathsfbf{9}^\mbfsansnine^N^mathord^mathsfbf^mathematical sans-serif bold digit 9
1D7F6^𝟶^\mathtt{0}^\mttzero^N^mathord^^mathematical monospace digit 0
1D7F7^𝟷^\mathtt{1}^\mttone^N^mathord^^mathematical monospace digit 1
1D7F8^𝟸^\mathtt{2}^\mtttwo^N^mathord^^mathematical monospace digit 2
1D7F9^𝟹^\mathtt{3}^\mttthree^N^mathord^^mathematical monospace digit 3
1D7FA^𝟺^\mathtt{4}^\mttfour^N^mathord^^mathematical monospace digit 4
1D7FB^𝟻^\mathtt{5}^\mttfive^N^mathord^^mathematical monospace digit 5
1D7FC^𝟼^\mathtt{6}^\mttsix^N^mathord^^mathematical monospace digit 6
1D7FD^𝟽^\mathtt{7}^\mttseven^N^mathord^^mathematical monospace digit 7
1D7FE^𝟾^\mathtt{8}^\mtteight^N^mathord^^mathematical monospace digit 8
1D7FF^𝟿^\mathtt{9}^\mttnine^N^mathord^^mathematical monospace digit 9
elyxer-1.2.5/src/conf/base.cfg0000644000175000017500000010344712117174744015465 0ustar  chennochenno#! /usr/bin/env python
# -*- coding: utf-8 -*-

#   eLyXer -- convert LyX source files to HTML output.
#
#   Copyright (C) 2009-2010 Alex Fernández
#
#   This program is free software: 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 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
#   GNU General Public License for more details.
#
#   You should have received a copy of the GNU General Public License
#   along with this program.  If not, see .

# --end--


[BibTeXConfig.replaced]
--:—
..:.

[BibStylesConfig.defaulttags]
surname:
authors:
YY:??

[BibStylesConfig.default]
cite:$index
default:$authors: $title.{{ $publisher,} $year.}{ URL $url.}{ $note.}
@article:$authors: “$title”, $journal,{ pp. $pages,} $year.{ URL $url.}{ $note.}
@book:{$authors: }$title{ ($editor, ed.)}.{{ $publisher,} $year.}{ URL $url.}{ $note.}
@booklet:$authors: $title.{{ $publisher,} $year.}{ URL $url.}{ $note.}
@conference:$authors: “$title”, $journal,{ pp. $pages,} $year.{ URL $url.}{ $note.}
@inbook:$authors: $title.{{ $publisher,} $year.}{ URL $url.}{ $note.}
@incollection:$authors: $title{ in $booktitle{ ($editor, ed.)}}.{{ $publisher,} $year.}{ URL $url.}{ $note.}
@inproceedings:$authors: “$title”, $booktitle,{ pp. $pages,} $year.{ URL $url.}{ $note.}
@manual:$authors: $title.{{ $publisher,} $year.}{ URL $url.}{ $note.}
@mastersthesis:$authors: $title.{{ $publisher,} $year.}{ URL $url.}{ $note.}
@misc:$authors: $title.{{ $publisher,}{ $howpublished,} $year.}{ URL $url.}{ $note.}
@phdthesis:$authors: $title.{{ $publisher,} $year.}{ URL $url.}{ $note.}
@proceedings:$authors: “$title”, $journal,{ pp. $pages,} $year.{ URL $url.}{ $note.}
@techreport:$authors: $title, $year.{ URL $url.}{ $note.}
@unpublished:$authors: “$title”, $journal, $year.{ URL $url.}{ $note.}

[BibStylesConfig.abbrvnat]
cite:$surname($year)
default:$authors. $title. $publisher, $year.{ URL $url.}{ $note.}
@article:$authors. $title. $journal,{ {$volume:}$pages,} $month $year.{ doi: $doi.}{ URL $url.}{ $note.}

[BibStylesConfig.alpha]
cite:$Sur$YY
default:$authors. $title.{ $journal,} $year.{ $url.}{ $filename.}{ $note.}
@article:$authors. $title.{ $journal{, {$volume}{($number)}}{: $pages}{, $year}.}{ $url.}{ $filename.}{ $note.}

[BibStylesConfig.authordate2]
cite:$surname, $year
default:$authors. $year. $title. $publisher.{ URL $url.}{ $note.}
@article:$authors. $year. $title. $journal, $volume($number), $pages.{ URL $url.}{ $note.}
@book:$authors. $year. $title. $publisher.{ URL $url.}{ $note.}

[BibStylesConfig.plain]
cite:$index
default:{$authors. }$title.{{ $publisher,} $year.}{ URL $url.}{ $note.}
@article:$authors. $title.{ $journal{, {$volume}{($number)}}{:$pages}{, $year}.}{ URL $url.}{ $note.}
@book:$authors. $title. $publisher,{ $month} $year.{ URL $url.}{ $note.}
@incollection:$authors. $title.{ In $booktitle {($editor, ed.)}.} $publisher,{ $month} $year.{ URL $url.}{ $note.}
@inproceedings:$authors. $title. { $booktitle{, {$volume}{($number)}}{:$pages}{, $year}.}{ URL $url.}{ $note.}

[BibStylesConfig.ieeetr]
cite:$index
default:$authors, “$title”. $year.{ URL $url.}{ $note.}
@article:$authors, “$title”, $journal, vol. $volume, no. $number, pp. $pages, $year.{ URL $url.}{ $note.}
@book:$authors, $title. $publisher, $year.{ URL $url.}{ $note.}

[BibStylesConfig.vancouver]
cite:$index
default:$authors. $title; {$publisher, }$year.{ $howpublished.}{ URL: $url.}{ $note.}
@article:$authors. $title. $journal, $year{;{$volume}{($number)}{:$pages}}.{ URL: $url.}{ $note.}
@book:$authors. $title. {$publisher, }$year.{ URL: $url.}{ $note.}

[ContainerConfig.endings]
Align:\end_layout
BarredText:\bar
BoldText:\series
Cell::>

[EscapeConfig.html]
/>:>

[EscapeConfig.nonunicode]
 : 

[EscapeConfig.iso885915]
 :&#8197;
 : 
 : 

[FormulaConfig.alphacommands]
# italic Greek alphabet
\varGamma:Γ
\varDelta:∆
\varTheta:Θ
\varLambda:Λ
\varXi:Ξ
\varPi:Π
\varSigma:Σ
\varUpsilon:Υ
\varPhi:Φ
\varPsi:Ψ
\varOmega:Ω
\alpha:α
\beta:β
\delta:δ
\epsilon:ϵ
\gamma:γ
\eta:η
\iota:ι
\kappa:κ
\lambda:λ
\mu:μ
\nu:ν
\omega:ω
\phi:φ
\pi:π
\psi:ψ
\rho:ρ
\sigma:σ
\tau:τ
\theta:θ
\upsilon:υ
\varepsilon:ε
\varkappa:ϰ
\varphi:φ
\varpi:ϖ
\varrho:ϱ
\varsigma:ς
\vartheta:ϑ
\xi:ξ
\zeta:ζ
# MarkusKuhn
\oe:œ
\OE:Œ
\ae:æ
\AE:Æ
\aa:å
\AA:Å
\o:ø
\O:Ø
\l:ł
\L:Ł
\ss:ß
\textcrh:ħ
# GünterMilde
\i:ı
\j:ȷ
\imath:ı
\jmath:ȷ
# 20101130 from BibTeXConfig.escaped
\DH:Ð
\TH:Þ
\dh:ð
\th:þ
# 20110108
\AmS:AmS
# Milde 20110709 (http://milde.users.sourceforge.net/LUCR/Math/)
\Koppa:Ϟ
\Stigma:Ϛ
\sampi:ϡ
\Sampi:Ϡ
\koppa:ϟ
\digamma:ϝ
\stigma:ϛ
\varbeta:ϐ
\eth:ð
\Angstroem:Å
\Micro:µ
\tcohm:Ω

[FormulaConfig.array]
begin:\begin
cellseparator:&
end:\end
rowseparator:\\

[FormulaConfig.bigbrackets]
(:[⎛,⎜,⎝]
):[⎞,⎟,⎠]
[:[⎡,⎢,⎣]
]:[⎤,⎥,⎦]
{:[⎧,⎪,⎨,⎩]
}:[⎫,⎪,⎬,⎭]
|:[|]
∥:[∥]

[FormulaConfig.commands]
\!:
\%:%
\,: 
\;: 
\:: 
\CIRCLE:●
\CheckedBox:☑
\Circle:○
\Downarrow:⇓
\Im:ℑ
\LEFTCIRCLE:◖
\LEFTcircle:◐
\Leftarrow:⇐
\Longleftarrow:⟸
\Longrightarrow:⟹
\Pr:Pr
\RIGHTCIRCLE:◗
\RIGHTcircle:◑
\Re:ℜ
\Square:☐
\Uparrow:⇑
\Updownarrow:⇕
\XBox:☒
\\:
\_:_ \aleph:ℵ \amalg:∐ \angle:∠ \aquarius:♒ \arccos:arccos \arcsin:arcsin \arctan:arctan \arg:arg \aries:♈ \ast:∗ \asymp:≍ \backslash:\ \beth:ℶ \bigcap:∩ \bigcirc:○ \bigcup:∪ \bigodot:⊙ \bigoplus:⊕ \bigotimes:⊗ \bigsqcup:⊔ \bigstar:★ \biguplus:⊎ \bigvee:∨ \bigwedge:∧ \blacksmiley:☻ \blacktriangleright:▶ \bot:⊥ \bowtie:⋈ \box:▫ \bullet:• \cancer:♋ \cap:∩ \capricornus:♑ \cdot:⋅ \cdots:⋯ \centerdot:∙ \chi:χ \circ:○ \clubsuit:♣ \cong:≅ \coprod:∐ \cos:cos \cosh:cosh \cot:cot \coth:coth \csc:csc \cup:∪ \dagger:† \daleth:ℸ \dashv:⊣ \ddagger:‡ \ddots:⋱ \deg:deg \det:det \diamond:◇ \diamondsuit:♦ \dim:dim \div:÷ \doteq:≐ \dots:… \downarrow:↓ \earth:♁ \ell:ℓ \emptyset:∅ \exists:∃ \exp:exp \female:♀ \forall:∀ \frownie:☹ \gcd:gcd \gemini:♊ \gets:← \gg:≫ \gimel:ℷ \hbar:ℏ \heartsuit:♥ \hom:hom \hookleftarrow:↩ \hookrightarrow:↪ \imath:ı \inf:inf \infty:∞ \invneg:⌐ \jmath:ȷ \jupiter:♃ \ker:ker \langle:⟨ \ldots:… \leadsto:⇝ \leftharpoondown:↽ \leftharpoonup:↼ \leftmoon:☾ \leftrightarrow:↔ \leo:♌ \lg:lg \libra:♎ \liminf:liminf \limsup:limsup \ll:≪ \ln:ln \log:log \longleftarrow:⟵ \longrightarrow:⟶ \lozenge:◊ \lyxlock: \male:♂ \mapsto:↦ \maltese:✠ \max:max \mercury:☿ \mho:℧ \mid:∣ \min:min \models:⊨ \mp:∓ \nabla:∇ \nearrow:↗ \neg:¬ \neptune:♆ \ni:∋ \nonumber: \not:¬ \nwarrow:↖ \odot:⊙ \oint: \ominus:⊖ \oplus:⊕ \oslash:⊘ \otimes:⊗ \parallel:∥ \partial:∂ \perp:⊥ \pisces:♓ \pluto:♇ \pm:± \prec:≺ \preceq:≼ \prime:′ \prompto:∝ \qquad: \quad: \quarternote:♩ \rangle:⟩ \rightharpooondown:⇁ \rightharpooonup:⇀ \rightleftharpoons:⇌ \rightmoon:☽ \sagittarius:♐ \saturn:♄ \scorpio:♏ \searrow:↘ \sec:sec \setminus:∖ \simeq:≃ \sin:sin \sinh:sinh \slash:∕ \smiley:☺ \spadesuit:♠ \sqcap:⊓ \sqcup:⊔ \sqsubset:⊏ \sqsubseteq:⊑ \sqsupset:⊐ \sqsupseteq:⊒ \square:□ \star:⋆ \succ:≻ \succeq:≽ \sun:☼ \sup:sup \surd:√ \swarrow:↙ \tan:tan \tanh:tanh \taurus:♉ \textbackslash:\ \top:⊤ \triangleleft:⊲ \triangleright:▷ \twonotes:♫ \unlhd:⊴ \unrhl:⊵ \uparrow:↑ \updownarrow:↕ \uplus:⊎ \uranus:♅ \varclubsuit:♧ \vardiamondsuit:♦ \varheartsuit:♥ \varspadesuit:♤ \vdash:⊢ \vee:∨ \virgo:♍ \wedge:∧ \wp:℘ \wr:≀ \{:{ \}:} # MarkusKuhn \Box:□ \|:∥ \triangle:△ \Diamond:◇ \flat:♭ \natural:♮ \sharp:♯ \lhd:⊲ \bigtriangleup:△ \bigtriangledown:▽ \rhd:⊳ \unrhd:⊵ \smile:⌣ \frown:⌢ \Join:⨝ \not<:≮ \not>:≯ \not=:≠ \longleftrightarrow:⟷ \Longleftrightarrow:⟺ \longmapsto:⟼ \rightharpoonup:⇀ \rightharpoondown:⇁ \lbrack:[ \lbrace:{ \lfloor:⌊ \lceil:⌈ \rbrack:] \rbrace:} \rfloor:⌋ \rceil:⌉ \owns:∋ \land:∧ \lor:∨ \lnot:¬ \vert:∣ \Vert:∥ \leq):≤ \geq):≥ \lbrace):{ \rbrace):} \rightarrow):→ \leftarrow):← \ni):∋ \wedge):∧ \vee):∨ \neg):¬ \vdots:⋮ \S:§ \P:¶ \dag:† \ddag:‡ \copyright:© # financial \pounds:£ \euro:€ \yen:¥ \$:$ # 20091028 \checkmark:✓ \blacklozenge:⧫ \blacktriangle:▲ \blacktriangledown:▼ \nexists:∄ \mathcircumflex:^ # 20091128 \varnothing:∅ \backprime:‵ \notin:∉ \hfill: \circledR:® \hslash:ℏ # 20091203 \gtrless:≷ \complement:∁ \measuredangle:∡ \sphericalangle:∢ \nmid:∤ \circeq:≗ \lessgtr:≶ \nparallel:∦ # Jens Nöckel \leftthreetimes:⋋ \rightthreetimes:⋌ \ltimes:⋉ \rtimes:⋊ \divideontimes:⋇ \dotplus:∔ \dotdiv:∸ \oiint: \oiiint: \ointclockwise: \landupint: \ointctrclockwise: \iint: \iiint: \idotsint:∫⋯∫ \barwedge:⊼ \veebar:⊻ \doublebarwedge:⌆ \backepsilon:∍ \therefore:∴ \because:∵ \boxdot:⊡ \circledast:⊛ \circledcirc:⊚ \circleddash:⊝ \EUR:€ \nvdash:⊬ \vDash:⊨ \nvDash:⊭ \Vdash:⊩ \nVDash:⊯ \Vvdash:⊪ \multimap:⊸ \Cup:⋓ \udot:⊍ \Cap:⋒ \Yup:⅄ \nequiv:≢ \triangleq:≜ \Corresponds:≙ \coloneqq:≔ \Coloneqq:⩴ \eqcolon:≕ \eqcirc:≖ \doteqdot:≑ \risingdotseq:≓ \fallingdotseq:≒ \nsimeq:≄ \backsimeq:⋍ \ncong:≇ \nsim:≁ \napprox:≉ \eqsim:≂ \bumpeq:≏ \Bumpeq:≎ \nless:≮ \ngtr:≯ \lll:⋘ \ggg:⋙ \nleqslant:≰ \leqslant:≤ \geqslant:≥ \ngeqslant:≱ \nlessgtr:≸ \ngtrless:≹ \lneqq:≨ \leqq:≦ \geqq:≧ \gneqq:≩ \lnsim:⋦ \lesssim:≲ \gtrsim:≳ \gnsim:⋧ \nprec:⊀ \nsucc:⊁ \ntriangleleft:⋪ \ntriangleright:⋫ \trianglelefteq:⊴ \trianglerighteq:⊵ \ntrianglelefteq:⋬ \ntrianglerighteq:⋭ \preccurlyeq:≼ \succcurlyeq:≽ \nsucccurlyeq:⋡ \precsim:≾ \succsim:≿ \succnsim:⋩ \lesseqgtr:⋛ \gtreqless:⋚ \gtreqqless:⪌ \lesseqqgtr:⪋ \gtrdot:⋗ \lessdot:⋖ \Subset:⋐ \Supset:⋑ \nsupset:⊅ \nsubseteq:⊈ \subseteqq:⫅ \supseteqq:⫆ \subsetneqq:⫋ \supsetneqq:⫌ \nsupseteq:⊉ \nsqsubset:⊏̸ \notni:∌ \pitchfork:⋔ \between:≬ \notslash:⌿ \notbackslash:⍀ \nleftarrow:↚ \nrightarrow:↛ \nleftrightarrow:↮ \lightning:↯ \nLeftrightarrow:⇎ \APLuparrowbox:⍐ \APLdownarrowbox:⍗ \APLleftarrowbox:⍇ \APLrightarrowbox:⍈ \pointer:➪ \nLeftarrow:⇍ \nRightarrow:⇏ \Lleftarrow:⇚ \Rrightarrow:⇛ \Lsh:↰ \Rsh:↱ \curvearrowleft:↶ \curvearrowright:↷ \leftrightarrows:⇆ \rightleftarrows:⇄ \upharpoonleft:↿ \downharpoonleft:⇃ \downharpoonright:⇂ \upharpoonright:↾ \leftarrowtobar:⇤ \rightarrowtobar:⇥ \leftrightharpoons:⇋ \leftleftharpoons:⥢ \rightrightharpoons:⥤ \Mapsfrom:⇐| \Mapsto:|⇒ \mapsfrom:↤ \dashleftarrow:⇠ \upuparrows:⇈ \downdownarrows:⇊ \leftleftarrows:⇇ \rightrightarrows:⇉ \leftarrowtail:↢ \rightarrowtail:↣ \twoheadleftarrow:↞ \twoheadrightarrow:↠ \looparrowleft:↫ \looparrowright:↬ # 20100124 \blacksquare:■ \ :  # non-italic Greek symbols \Gamma:Γ \Delta:Δ \Theta:Θ \Lambda:Λ \Xi:Ξ \Pi:Π \Sigma:Σ \Upsilon:Υ \Phi:Φ \Psi:Ψ \Omega:Ω # 20100509 \diagup:╱ \diagdown:╲ # 20100520 \officialeuro:€ # 20100823 \textasciitilde:~ \textasciicircum:^ \textendash:— \textquotedblleft:“ \textquotedblright:” # 20100912 \textless:< \textgreater:> # 20101130 from BibTeXConfig.escaped \textordfeminine:ª \textregistered:® \textordmasculine:º \texttrademark:™ \&:& \#:# # 20101214 \newline:
# 2011-01-03 from Günther Milde \Game:⅁ # 20110107 \textvisiblespace: # 20110120 \nolimits: # Pascal Francq \textsection:§ \textdegree:° \guillemotleft:« \guillemotright:» \texteuro:€ \textellipsis:… \textquoteright:’ \textrightarrow:→ \texttwosuperior:² \textcopyright:©' \textemdash:— # Milde 20110709 (http://milde.users.sourceforge.net/LUCR/Math/) \rblot:⦊ \rsub:⩥ \sphat: \medbullet:⚫ \biohazard:☣ \Lbag:⟅ \llcorner:⌞ \ExponetialE:ⅇ \sslash:⫽ \boxcircle:⧇ \recycle:♻ \blacktriangleup:▴ \talloblong:⫾ \anchor:⚓ \interleave:⫴ \APLcomment:⍝ \smalltriangleleft:◃ \Lparen:⦅ \AC:∿ \smalltriangleright:▹ \RHD:▶ \circledbslash:⦸ \lblot:⦉ \circledless:⧀ \dsub:⩤ \yinyang:☯ \sixteenthnote:♬ \intercal:⊺ \cat:⁀ \lang:⟪ \APLlog:⍟ \Sun:☉ \curlywedge:⋏ \rimg:⦈ \boxbslash:⧅ \circledgtr:⧁ \boxbar:◫ \Qoppa:Ϙ \ulcorner:⌜ \wasylozenge:⌑ \sptilde:~ \cent:¢ \smallsetminus:∖ \warning:⚠ \APLinv:⌹ \smalltriangleup:▵ \qoppa:ϙ \swords:⚔ \circlearrowright:↻ \diameter:⌀ \Diamonddot:⟐ \eighthnote:♪ \urcorner:⌝ \CapitalDifferentialD:ⅅ \lrcorner:⌟ \boxast:⧆ \boxplus:⊞ \DifferentialD:ⅆ \boxminus:⊟ \Diamondblack:◆ \lgroup:⟮ \fcmp:⨾ \boxtimes:⊠ \limg:⦇ \Finv:Ⅎ \Rbag:⟆ \radiation:☢ \circlearrowleft:↺ \llbracket:⟦ \arrowbullet:➢ \pencil:✎ \LHD:◀ \pointright:☞ \blacktriangleleft:◂ \medcirc:⚪ \boxbox:⧈ \spot:⦁ \Rparen:⦆ \ballotx:✗ \second:″ \ComplexI:ⅈ \Euler:ℇ \ComplexJ:ⅉ \rightangle:∟ \rgroup:⟯ \spddot:¨ \invamp:⅋ \rrbracket:⟧ \third:‴ \smalltriangledown:▿ \curlyvee:⋎ \skull:☠ \fourth:⁗ \steaming:☕ \APLinput:⍞ \rang:⟫ \boxslash:⧄ [FormulaConfig.spacedcommands] \Leftrightarrow:⇔ \Rightarrow:⇒ \approx:≈ \dashrightarrow:⇢ \equiv:≡ \ge:≥ \geq:≥ \implies: ⇒  \in:∈ \le:≤ \leftarrow:← \leq:≤ \ne:≠ \neq:≠ \not\in:∉ \propto:∝ \rightarrow:→ \rightsquigarrow:⇝ \sim:~ \subset:⊂ \subseteq:⊆ \supset:⊃ \supseteq:⊇ \times:× \to:→ # Milde 20110709 (http://milde.users.sourceforge.net/LUCR/Math/) \nsqsupseteq:⋣ \bij:⤖ \nsqsubseteq:⋢ \subsetneq:⊊ \finj:⤕ \llcurly:⪻ \RightArrowBar:⇥ \NestedLessLess:⪡ \curlyeqprec:⋞ \LeftDownTeeVector:⥡ \pfun:⇸ \Doteq:≑ \downuparrows:⇵ \precnsim:⋨ \lnapprox:⪉ \nsubset:⊄ \lneq:⪇ \Equal:⩵ \coloneq:≔ \hash:⋕ \vartriangleleft:⊲ \leftupdownharpoon:⥑ \precnapprox:⪹ \rightslice:⪧ \updownharpoons:⥮ \multimapboth:⧟ \RightTeeVector:⥛ \npreceq:⋠ \Longmapsto:⟾ \leftrightharpoonup:⥎ \Bot:⫫ \dlsh:↲ \Top:⫪ \downupharpoons:⥯ \backsim:∽ \rightleftharpoon:⥋ \nleq:≰ \RightVectorBar:⥓ \NotGreaterTilde:≵ \NestedGreaterGreater:⪢ \MapsUp:↥ \DownLeftVectorBar:⥖ \lessapprox:⪅ \eqslantgtr:⪖ \barrightharpoon:⥭ \barleftharpoon:⥫ \strictif:⥽ \leftarrowtriangle:⇽ \supsetneq:⊋ \gnapprox:⪊ \Swarrow:⇙ \LeftDownVectorBar:⥙ \notasymp:≭ \LeftUpVectorBar:⥘ \gtrapprox:⪆ \nni:∌ \Proportion:∷ \eqslantless:⪕ \succnapprox:⪺ \leftrightharpoondown:⥐ \VDash:⊫ \downdownharpoons:⥥ \approxeq:≊ \ffun:⇻ \leftrightarrowtriangle:⇿ \NotLessTilde:≴ \DownLeftTeeVector:⥞ \updownarrows:⇅ \Nearrow:⇗ \Nwarrow:⇖ \DownArrowBar:⤓ \barin:⋶ \Longmapsfrom:⟽ \multimapdotbothA:⊶ \LeftVectorBar:⥒ \Same:⩶ \RightUpTeeVector:⥜ \succeqq:⪴ \strictfi:⥼ \iddots:⋰ \pinj:⤔ \RightTriangleBar:⧐ \leftbarharpoon:⥪ \ggcurly:⪼ \nsucceq:⋡ \nVdash:⊮ \leftsquigarrow:⇜ \LeftUpTeeVector:⥠ \Searrow:⇘ \multimapdotbothB:⊷ \DownRightTeeVector:⥟ \leftrightsquigarrow:↭ \LeftArrowBar:⇤ \UpArrowBar:⤒ \psur:⤀ \DownRightVectorBar:⥗ \drsh:↳ \LeftTriangleBar:⧏ \RightUpVectorBar:⥔ \LeftTeeVector:⥚ \rightbarharpoon:⥬ \leftslice:⪦ \preceqq:⪳ \gneq:⪈ \rightarrowtriangle:⇾ \precapprox:⪷ \NotGreaterLess:≹ \longmapsfrom:⟻ \vartriangleright:⊳ \rightupdownharpoon:⥏ \ngeq:≱ \RightDownTeeVector:⥝ \RightDownVectorBar:⥕ \leftrightharpoon:⥊ \curlyeqsucc:⋟ \multimapinv:⟜ \succapprox:⪸ \corresponds:≙ \upupharpoons:⥣ \MapsDown:↧ [FormulaConfig.decoratedcommand] # 20101130 from BibTeXConfig.escaped #!`:¡ #?`:¿ [FormulaConfig.decoratingfunctions] \overleftarrow:⟵ \overrightarrow:⟶ \widehat:^ [FormulaConfig.combiningfunctions] \acute:́ \bar:̄ \breve:̆ \c:̧ \check:̌ \dot:̇ \ddot:̈ \dddot:⃛ \grave:̀ \hat:̂ \mathring:̊ \overleftarrow:⃖ \overrightarrow:⃗ \r:̊ \s:̩ \textsubring:̥ \tilde:̃ \vec:⃗ # 20101130 from BibTeXConfig.escaped \`:̀ \':́ \^:̂ \~:̃ \":̈ \textcircled:⃝ \v:̌ [FormulaConfig.environments] align:[r,l] eqnarray:[r,c,l] gathered:[l,l] [FormulaConfig.endings] bracket:} complex:\] endafter:} endbefore:\end{ squarebracket:] [FormulaConfig.fontfunctions] \boldsymbol:b \mathbb:span class="blackboard" \mathbf:b \mathcal:span class="scriptfont" \mathfrak:span class="fraktur" \mathit:i \mathrm:span class="mathrm" \mathsf:span class="mathsf" \mathtt:tt \mathscr:span class="scriptfont" # simplified fonts \mathbb{A}:𝔸 \mathbb{B}:𝔹 \mathbb{C}:ℂ \mathbb{D}:𝔻 \mathbb{E}:𝔼 \mathbb{F}:𝔽 \mathbb{G}:𝔾 \mathbb{H}:ℍ \mathbb{J}:𝕁 \mathbb{K}:𝕂 \mathbb{L}:𝕃 \mathbb{N}:ℕ \mathbb{O}:𝕆 \mathbb{P}:ℙ \mathbb{Q}:ℚ \mathbb{R}:ℝ \mathbb{S}:𝕊 \mathbb{T}:𝕋 \mathbb{W}:𝕎 \mathbb{Z}:ℤ \mathfrak{C}:ℭ \mathfrak{F}:𝔉 \mathfrak{H}:ℌ \mathfrak{I}:ℑ \mathfrak{R}:ℜ \mathfrak{Z}:ℨ \mathring{A}:Å \mathring{U}:Ů \mathring{a}:å \mathring{u}:ů \mathring{w}:ẘ \mathring{y}:ẙ \mathscr{B}:ℬ \mathscr{E}:ℰ \mathscr{F}:ℱ \mathscr{H}:ℋ \mathscr{I}:ℐ \mathscr{L}:ℒ \mathscr{M}:ℳ \mathscr{R}:ℛ \mathcal{B}:ℬ \mathcal{E}:ℰ \mathcal{F}:ℱ \mathcal{H}:ℋ \mathcal{I}:ℐ \mathcal{L}:ℒ \mathcal{M}:ℳ \mathcal{R}:ℛ [FormulaConfig.hybridfunctions] \sqrt:[[$0]{$1},f0{f1{$0}f2{√}f4{(}f3{$1}f4{)}},span class="sqrt",sup class="root",span class="radical",span class="root",span class="ignored"] \unit:[[$0]{$1},$0f0{$1.font},span class="unit"] \frac:[{$1}{$2},f0{f3{(}f1{$1}f3{)/(}f2{$2}f3{)}},span class="fraction",span class="numerator",span class="denominator",span class="ignored"] \cfrac:[[$p!]{$1}{$2},f0{f3{(}f1{$1}f3{)/(}f2{$2}f3{)}},span class="fullfraction",span class="numerator align-$p",span class="denominator",span class="ignored"] \dfrac:[{$1}{$2},f0{f3{(}f1{$1}f3{)/(}f2{$2}f3{)}},span class="fullfraction",span class="numerator",span class="denominator",span class="ignored"] \nicefrac:[{$1}{$2},f0{f1{$1}⁄f2{$2}},span class="fraction",sup class="numerator",sub class="denominator",span class="ignored"] \unitfrac:[[$0]{$1}{$2},$0f0{f1{$1.font}⁄f2{$2.font}},span class="fraction",sup class="unit",sub class="unit"] \binom:[{$1}{$2},f2{(}f0{f1{$1}f1{$2}}f2{)},span class="binom",span class="binomstack",span class="bigsymbol"] \dbinom:[{$1}{$2},(f0{f1{f2{$1}}f1{f2{ }}f1{f2{$2}}}),span class="binomial",span class="binomrow",span class="binomcell"] \tbinom:[{$1}{$2},(f0{f1{f2{$1}}f1{f2{ }}f1{f2{$2}}}),span class="binomial",span class="binomrow",span class="binomcell"] \hspace:[{$p!},f0{ },span class="hspace" style="width: $p;"] \vspace:[{$p!},f0{ },span class="vspace" style="height: $p;"] \raisebox:[{$p!}{$1},f0{$1.font},span class="raisebox" style="vertical-align: $p;"] \leftroot:[{$p!},f0{ },span class="leftroot" style="width: $p;px"] \uproot:[{$p!},f0{ },span class="uproot" style="width: $p;px"] \renewenvironment:[{$1!}{$2!}{$3!},] \color:[{$p!}{$1},f0{$1},span style="color: $p;"] \textcolor:[{$p!}{$1},f0{$1},span style="color: $p;"] \colorbox:[{$p!}{$1},f0{$1},span class="colorbox" style="background: $p;"] \stackrel:[{$1}{$2},f0{f1{$1}f2{$2}},span class="stackrel",span class="upstackrel",span class="downstackrel"] \fbox:[{$1},f0{$1},span class="fbox"] \boxed:[{$1},f0{$1},span class="boxed"] \framebox:[[$p!][$q!]{$1},f0{$1},span class="framebox align-$q" style="width: $p;"] \fcolorbox:[{$p!}{$q!}{$1},f0{$1},span class="boxed" style="border-color: $p; background: $q;"] \url:[{$u!},f0{$u},a href="$u"] \href:[[$o]{$u!}{$t!},f0{$t},a href="$u"] \parbox:[[$p!]{$w!}{$1},f0{1},div class="Boxed" style="width: $w;"] \rule:[[$v!]{$w!}{$h!},f0/,hr class="line" style="width: $w; height: $h;"] \fboxrule:[{$p!},f0{},ignored] \fboxsep:[{$p!},f0{},ignored] \scriptscriptstyle:[{$1},f0{$1},span class="scriptscriptstyle"] \scriptstyle:[{$1},f0{$1},span class="scriptstyle"] \displaystyle:[{$1},f0{$1},span class="displaystyle"] \textstyle:[{$1},f0{$1},span class="textstyle"] \thispagestyle:[{$p!},f0{},ignored] \frontmatter:[,f0{},ignored] \mainmatter:[,f0{},ignored] \backmatter:[,f0{},ignored] \markboth:[{$p!}{$q!},f0{},ignored] \markright:[{$p!},f0{},ignored] \fancyfoot:[[$p!]{$q!},f0{},ignored] \fancyhead:[[$p!]{$q!},f0{},ignored] \addcontentsline:[{$p!}{$q!}{$r!},f0{},ignored] \addtocontents:[{$p!}{$q!},f0{},ignored] [FormulaConfig.hybridsizes] \frac:$1+$2 \cfrac:$1+$2 \dfrac:$1+$2 \binom:$1+$2 \dbinom:$1+$2+1 \tbinom:$1+$2+1 [FormulaConfig.misccommands] \newcommand:MacroDefinition \renewcommand:MacroDefinition \setcounter:SetCounterFunction \tag:FormulaTag \tag*:FormulaTag \limits:LimitPreviousCommand \today:TodayCommand [FormulaConfig.limitcommands] \sum:∑ \int:∫ \intop:∫ \prod:∏ \smallint:∫ \lim:lim # Milde 20110709 (http://milde.users.sourceforge.net/LUCR/Math/) \zproject:⨡ \bigsqcap:⨅ \varprod:⨉ \sqint:⨖ \fint:⨏ \zcmp:⨟ \zpipe:⨠ \zhide:⧹ \biginterleave:⫼ \iiiint:⨌ \varointclockwise:∲ [FormulaConfig.bigsymbols] ∑:[⎲,⎳] ∫:[⌠,⌡] [FormulaConfig.labelfunctions] \label:a name="#" [FormulaConfig.textfunctions] \mbox:span class="mbox" \text:span class="text" \textipa:span class="textipa" \textnormal:span class="textnormal" \textrm:span class="textrm" \textsf:span class="textsf" \texttt:tt \textit:i \textbf:b \textsl:i \textsc:span class="versalitas" \textup:span class="normal" [FormulaConfig.modified] : : &: ':’ +: +  ,:,  -: −  /: ⁄  <: <  =: =  >: >  @: ~: $: [FormulaConfig.onefunctions] \bar:span class="bar" \begin{array}:span class="arraydef" \big:span class="symbol" \Big:span class="bigsymbol" \bigg:span class="largesymbol" \Bigg:span class="hugesymbol" \bigl:span class="bigsymbol" \bigr:span class="bigsymbol" \hphantom:span class="phantom" \overline:span class="overline" \phantom:span class="phantom" \underline:u \vphantom:span class="phantom" \underbrace:span class="underbrace" \overbrace:span class="overbrace" \ensuremath:span class="ensuremath" \noindent:span class="noindent" \centering:span class="align-center" [FormulaConfig.bracketcommands] \left:span class="symbol" \middle:span class="symbol" \right:span class="symbol" # simplified matched brackets \left.: \right.: [FormulaConfig.starts] beginafter:} beginbefore:\begin{ bracket:{ command:\ complex:\[ simple:$ squarebracket:[ unnumbered:* comment:% [FormulaConfig.symbolfunctions] ^:sup _:sub [FormulaConfig.unmodified] characters:[.,*,€,(,),[,],:,·,!,;,|,§,"] [FormulaConfig.urls] googlecharts:http://chart.googleapis.com/chart?cht=tx&chl= [GeneralConfig.version] date:2011-11-22 number:1.2.5 lyxformat:413 [HeaderConfig.parameters] branch:\branch endbranch:\end_branch lstset:\lstset pdftitle:\pdf_title documentclass:\textclass paragraphseparation:\paragraph_separation tocdepth:\tocdepth secnumdepth:\secnumdepth language:\language beginpreamble:\begin_preamble endpreamble:\end_preamble outputchanges:\output_changes [HeaderConfig.styles] article:[article,aastex,aapaper,acmsiggraph,sigplanconf,achemso,amsart,apa,arab-article,armenian-article,article-beamer,chess,dtk,elsarticle,heb-article,IEEEtran,iopart,kluwer,scrarticle-beamer,scrartcl,extarticle,paper,mwart,revtex4,spie,svglobal3,ltugboat,agu-dtd,jgrga,agums,entcs,egs,ijmpc,ijmpd,singlecol-new,doublecol-new,isprs,tarticle,jsarticle,jarticle,jss,literate-article,siamltex,cl2emult,llncs,svglobal,svjog,svprobth] book:[book,amsbook,scrbook,extbook,tufte-book,report,extreport,scrreprt,memoir,tbook,jsbook,jbook,mwbk,svmono,svmult,treport,jreport,mwrep] [ImageConfig.converters] imagemagick:convert[ -density $scale][ -define $format:use-cropbox=true] "$input" "$output" inkscape:inkscape "$input" --export-png="$output" lyx:lyx -C "$input" "$output" [ImageConfig.cropboxformats] .pdf:pdf .eps:ps .ps:ps [ImageConfig.formats] vector:[.svg,.eps] default:.png [LayoutConfig.groupable] allowed:[StringContainer,Constant,TaggedText,Align,TextFamily,EmphaticText,VersalitasText,BarredText,SizeText,ColorText,LangLine,Formula] [NewfangleConfig.constants] startmark:=< startcommand:\ endmark:> chunkref:chunkref{ endcommand:} [NumberingConfig.layouts] ordered:[Chapter,Section,Subsection,Subsubsection,Paragraph] roman:[Part,Book] [NumberingConfig.sequence] symbols:[*,**,†,‡,§,§§,¶,¶¶,#,##] [StyleConfig.quotes] ald:» als:› ard:« ars:‹ eld:“ els:‘ erd:” ers:’ fld:« fls:‹ frd:» frs:› gld:„ gls:‚ grd:“ grs:‘ pld:„ pls:‚ prd:” prs:’ sld:” srd:” [StyleConfig.hspaces] \enskip{}:  \hfill{}: \hspace*{\fill}:  \hspace*{}: \hspace{}:  \negthinspace{}: \qquad{}:   \quad{}:  \space{}:  \thinspace{}:  ~:  [StyleConfig.vspaces] defskip:
smallskip:
medskip:
bigskip:
vfill:
[StyleConfig.size] ignoredtexts:[col,text,line,page,theight,pheight] [StyleConfig.referenceformats] # @ is the label number, # is page number (always 1), ↕ a direction arrow, # $ the title, and ¶ is the part name (like Chapter) # on-page is the string " on page " internationalized. ref:@↕ eqref:(@↕) pageref:#↕ vref:@on-page#↕ vpageref:on-page#↕ formatted:¶↕ nameref:$↕ [TagConfig.barred] under:u [TagConfig.family] sans:span class="sans" typewriter:tt [TagConfig.flex] CharStyle:Code:span class="code" Code:span class="code" CharStyle:MenuItem:span class="menuitem" MenuItem:span class="menuitem" Noun:span class="noun" Strong:span class="strong" [TagConfig.layouts] Center:div Chapter:h? Date:h2 Paragraph:div Part:h1 Quotation:blockquote Quote:blockquote Section:h? Subsection:h? Subsubsection:h? [TagConfig.group] layouts:[Quotation,Quote] [TagConfig.listitems] Enumerate:ol Itemize:ul [TagConfig.notes] Comment: Greyedout:span class="greyedout" Note: [TagConfig.shaped] italic:i slanted:i smallcaps:span class="versalitas" [TagConfig.script] superscript:sup subscript:sub [TOCConfig.extracttitle] allowed:[StringContainer,Constant,Space] cloned:[TextFamily,EmphaticText,VersalitasText,BarredText,SizeText,ColorText,LangLine,Formula] extracted:[PlainLayout,TaggedText,Align,Caption,StandardLayout,FlexInset] [TOCConfig.extractplain] allowed:[StringContainer,Constant,TaggedText,Align,TextFamily,EmphaticText,VersalitasText,BarredText,SizeText,ColorText,LangLine,Formula] cloned:[] extracted:[] [TranslationConfig.constants] abstract:Abstract bibliography:Bibliography references:References index:Index nomenclature:Nomenclature toc:Table of Contents toc-for:Contents for Part:Part Book:Book Chapter:Chapter Section:Section Subsection:Subsection Subsubsection:Subsubsection Paragraph:Paragraph figure:figure float-algorithm:Algorithm float-figure:Figure float-listing:Listing float-table:Table float-tableau:Tableau list-algorithm:List of Algorithms list-figure:List of Figures list-table:List of Tables list-tableau:List of Tableaux on-page: on page jsmath-warning:Warning: jsmath-requires: requires JavaScript to correctly process the mathematics on this page. jsmath-enable:Please enable JavaScript on your browser. next:Next prev:Prev up:Up generated-by:Document generated by generated-on: on main-page:Main page Appendix:Appendix footnotes:Footnotes [TranslationConfig.languages] english:en spanish:es deutsch:de ngerman:de dutch:nl french:fr british:en american:en russian:ru elyxer-1.2.5/src/coalesce.py0000755000175000017500000000753612074107030015264 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20090309 # Coalesces (unifies) all into one file to generate a distributable file. import sys import os.path from elyxer.io.fileline import * from elyxer.util.trace import Trace class Coalescer(object): "Coalesce a set of files into a single file," "so that it can be distributed." "Currently works for Python (.py) and CSS (.css) files." def __init__(self): self.comments = True self.files = [] self.directory = '' self.writer = None self.python = False def convert(self, filename, directory = ''): "Convert the filename adding the appropriate directories." if os.path.exists(filename): return filename newname = os.path.join(self.directory, filename) if os.path.exists(newname): return newname newname = os.path.join(directory, filename) if os.path.exists(newname): return newname Trace.error('Missing file ' + filename) return None def getreader(self, filename): "Get a line reader." if filename in self.files: # already parsed; skip return None self.files.append(filename) return LineReader(filename) def readargs(self, args): "Read arguments from the command line" del args[0] if len(args) == 0: self.usage() return self.filename = self.convert(args[0]) self.directory = os.path.dirname(args[0]) del args[0] fileout = sys.stdout if len(args) > 0: fileout = args[0] del args[0] if len(args) > 0: usage() return self.writer = LineWriter(fileout) def usage(self): Trace.error('Usage: coalesce.py filein [fileout]') return def coalesceall(self): "Coalesce all files from the root reader." if not self.writer: return self.coalesce(self.filename) self.writer.close() def coalesce(self, filename): "Coalesce all files used in filein to fileout" if filename.endswith('.py'): self.python = True reader = self.getreader(filename) if not reader: return while not reader.finished(): line = reader.currentline() included = self.getincluded(line) if included: self.comments = False newname = self.convert(included, os.path.dirname(filename)) if newname: self.coalesce(newname) else: # make imports with no target file work self.writer.writeline(line) elif self.iscomment(line): if self.comments: self.writer.writeline(line) else: self.writer.writeline(line) reader.nextline() reader.close() def getincluded(self, line): "Get the name of the included file, or None." if line.startswith('from'): return line.split()[1].replace('.', '/') + '.py' if line.startswith('@import'): return line.split()[1].replace('"', '').rstrip(';') return None def iscomment(self, line): "Find out if the line is a comment. Only removes Python comments." if self.python and line.startswith('#'): return True return False coalescer = Coalescer() coalescer.readargs(sys.argv) coalescer.coalesceall() elyxer-1.2.5/src/load-elyxer.py0000755000175000017500000000170612074107030015724 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20090308 # eLyXer main script # http://www.nongnu.org/elyxer/ import sys from elyxer.main.convert import * if __name__ == '__main__': main() elyxer-1.2.5/loremipsumize.py0000755000175000017500000020402212117174754015627 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20091210 # Lorem-ipsumize a document: replace all alphanumeric texts longer than two words with "Lorem ipsum" and leave the symbols. import sys import sys import codecs import sys class Trace(object): "A tracing class" debugmode = False quietmode = False showlinesmode = False prefix = None def debug(cls, message): "Show a debug message" if not Trace.debugmode or Trace.quietmode: return Trace.show(message, sys.stdout) def message(cls, message): "Show a trace message" if Trace.quietmode: return if Trace.prefix and Trace.showlinesmode: message = Trace.prefix + message Trace.show(message, sys.stdout) def error(cls, message): "Show an error message" message = '* ' + message if Trace.prefix and Trace.showlinesmode: message = Trace.prefix + message Trace.show(message, sys.stderr) def fatal(cls, message): "Show an error message and terminate" Trace.error('FATAL: ' + message) exit(-1) def show(cls, message, channel): "Show a message out of a channel" if sys.version_info < (3,0): message = message.encode('utf-8') channel.write(message + '\n') debug = classmethod(debug) message = classmethod(message) error = classmethod(error) fatal = classmethod(fatal) show = classmethod(show) class LineReader(object): "Reads a file line by line" def __init__(self, filename): if isinstance(filename, file): self.file = filename else: self.file = codecs.open(filename, 'rU', 'utf-8') self.linenumber = 1 self.lastline = None self.current = None self.mustread = True self.depleted = False try: self.readline() except UnicodeDecodeError: # try compressed file import gzip self.file = gzip.open(filename, 'rb') self.readline() def setstart(self, firstline): "Set the first line to read." for i in range(firstline): self.file.readline() self.linenumber = firstline def setend(self, lastline): "Set the last line to read." self.lastline = lastline def currentline(self): "Get the current line" if self.mustread: self.readline() return self.current def nextline(self): "Go to next line" if self.depleted: Trace.fatal('Read beyond file end') self.mustread = True def readline(self): "Read a line from elyxer.file" self.current = self.file.readline() if not isinstance(self.file, codecs.StreamReaderWriter): self.current = self.current.decode('utf-8') if len(self.current) == 0: self.depleted = True self.current = self.current.rstrip('\n\r') self.linenumber += 1 self.mustread = False Trace.prefix = 'Line ' + unicode(self.linenumber) + ': ' if self.linenumber % 1000 == 0: Trace.message('Parsing') def finished(self): "Find out if the file is finished" if self.lastline and self.linenumber == self.lastline: return True if self.mustread: self.readline() return self.depleted def close(self): self.file.close() class LineWriter(object): "Writes a file as a series of lists" file = False def __init__(self, filename): if isinstance(filename, file): self.file = filename self.filename = None else: self.filename = filename def write(self, strings): "Write a list of strings" for string in strings: if not isinstance(string, basestring): Trace.error('Not a string: ' + unicode(string) + ' in ' + unicode(strings)) return self.writestring(string) def writestring(self, string): "Write a string" if not self.file: self.file = codecs.open(self.filename, 'w', "utf-8") if self.file == sys.stdout and sys.version_info < (3,0): string = string.encode('utf-8') self.file.write(string) def writeline(self, line): "Write a line to file" self.writestring(line + '\n') def close(self): self.file.close() class BibStylesConfig(object): "Configuration class from elyxer.config file" abbrvnat = { u'@article':u'$authors. $title. $journal,{ {$volume:}$pages,} $month $year.{ doi: $doi.}{ URL $url.}{ $note.}', u'cite':u'$surname($year)', u'default':u'$authors. $title. $publisher, $year.{ URL $url.}{ $note.}', } alpha = { u'@article':u'$authors. $title.{ $journal{, {$volume}{($number)}}{: $pages}{, $year}.}{ $url.}{ $filename.}{ $note.}', u'cite':u'$Sur$YY', u'default':u'$authors. $title.{ $journal,} $year.{ $url.}{ $filename.}{ $note.}', } authordate2 = { u'@article':u'$authors. $year. $title. $journal, $volume($number), $pages.{ URL $url.}{ $note.}', u'@book':u'$authors. $year. $title. $publisher.{ URL $url.}{ $note.}', u'cite':u'$surname, $year', u'default':u'$authors. $year. $title. $publisher.{ URL $url.}{ $note.}', } default = { u'@article':u'$authors: “$title”, $journal,{ pp. $pages,} $year.{ URL $url.}{ $note.}', u'@book':u'{$authors: }$title{ ($editor, ed.)}.{{ $publisher,} $year.}{ URL $url.}{ $note.}', u'@booklet':u'$authors: $title.{{ $publisher,} $year.}{ URL $url.}{ $note.}', u'@conference':u'$authors: “$title”, $journal,{ pp. $pages,} $year.{ URL $url.}{ $note.}', u'@inbook':u'$authors: $title.{{ $publisher,} $year.}{ URL $url.}{ $note.}', u'@incollection':u'$authors: $title{ in $booktitle{ ($editor, ed.)}}.{{ $publisher,} $year.}{ URL $url.}{ $note.}', u'@inproceedings':u'$authors: “$title”, $booktitle,{ pp. $pages,} $year.{ URL $url.}{ $note.}', u'@manual':u'$authors: $title.{{ $publisher,} $year.}{ URL $url.}{ $note.}', u'@mastersthesis':u'$authors: $title.{{ $publisher,} $year.}{ URL $url.}{ $note.}', u'@misc':u'$authors: $title.{{ $publisher,}{ $howpublished,} $year.}{ URL $url.}{ $note.}', u'@phdthesis':u'$authors: $title.{{ $publisher,} $year.}{ URL $url.}{ $note.}', u'@proceedings':u'$authors: “$title”, $journal,{ pp. $pages,} $year.{ URL $url.}{ $note.}', u'@techreport':u'$authors: $title, $year.{ URL $url.}{ $note.}', u'@unpublished':u'$authors: “$title”, $journal, $year.{ URL $url.}{ $note.}', u'cite':u'$index', u'default':u'$authors: $title.{{ $publisher,} $year.}{ URL $url.}{ $note.}', } defaulttags = { u'YY':u'??', u'authors':u'', u'surname':u'', } ieeetr = { u'@article':u'$authors, “$title”, $journal, vol. $volume, no. $number, pp. $pages, $year.{ URL $url.}{ $note.}', u'@book':u'$authors, $title. $publisher, $year.{ URL $url.}{ $note.}', u'cite':u'$index', u'default':u'$authors, “$title”. $year.{ URL $url.}{ $note.}', } plain = { u'@article':u'$authors. $title.{ $journal{, {$volume}{($number)}}{:$pages}{, $year}.}{ URL $url.}{ $note.}', u'@book':u'$authors. $title. $publisher,{ $month} $year.{ URL $url.}{ $note.}', u'@incollection':u'$authors. $title.{ In $booktitle {($editor, ed.)}.} $publisher,{ $month} $year.{ URL $url.}{ $note.}', u'@inproceedings':u'$authors. $title. { $booktitle{, {$volume}{($number)}}{:$pages}{, $year}.}{ URL $url.}{ $note.}', u'cite':u'$index', u'default':u'{$authors. }$title.{{ $publisher,} $year.}{ URL $url.}{ $note.}', } vancouver = { u'@article':u'$authors. $title. $journal, $year{;{$volume}{($number)}{:$pages}}.{ URL: $url.}{ $note.}', u'@book':u'$authors. $title. {$publisher, }$year.{ URL: $url.}{ $note.}', u'cite':u'$index', u'default':u'$authors. $title; {$publisher, }$year.{ $howpublished.}{ URL: $url.}{ $note.}', } class BibTeXConfig(object): "Configuration class from elyxer.config file" replaced = { u'--':u'—', u'..':u'.', } class ContainerConfig(object): "Configuration class from elyxer.config file" endings = { u'Align':u'\\end_layout', u'BarredText':u'\\bar', u'BoldText':u'\\series', u'Cell':u'':u'>', } html = { u'/>':u'>', } iso885915 = { u' ':u' ', u' ':u' ', u' ':u' ', } nonunicode = { u' ':u' ', } class FormulaConfig(object): "Configuration class from elyxer.config file" alphacommands = { u'\\AA':u'Å', u'\\AE':u'Æ', u'\\AmS':u'AmS', u'\\Angstroem':u'Å', u'\\DH':u'Ð', u'\\Koppa':u'Ϟ', u'\\L':u'Ł', u'\\Micro':u'µ', u'\\O':u'Ø', u'\\OE':u'Œ', u'\\Sampi':u'Ϡ', u'\\Stigma':u'Ϛ', u'\\TH':u'Þ', u'\\aa':u'å', u'\\ae':u'æ', u'\\alpha':u'α', u'\\beta':u'β', u'\\delta':u'δ', u'\\dh':u'ð', u'\\digamma':u'ϝ', u'\\epsilon':u'ϵ', u'\\eta':u'η', u'\\eth':u'ð', u'\\gamma':u'γ', u'\\i':u'ı', u'\\imath':u'ı', u'\\iota':u'ι', u'\\j':u'ȷ', u'\\jmath':u'ȷ', u'\\kappa':u'κ', u'\\koppa':u'ϟ', u'\\l':u'ł', u'\\lambda':u'λ', u'\\mu':u'μ', u'\\nu':u'ν', u'\\o':u'ø', u'\\oe':u'œ', u'\\omega':u'ω', u'\\phi':u'φ', u'\\pi':u'π', u'\\psi':u'ψ', u'\\rho':u'ρ', u'\\sampi':u'ϡ', u'\\sigma':u'σ', u'\\ss':u'ß', u'\\stigma':u'ϛ', u'\\tau':u'τ', u'\\tcohm':u'Ω', u'\\textcrh':u'ħ', u'\\th':u'þ', u'\\theta':u'θ', u'\\upsilon':u'υ', u'\\varDelta':u'∆', u'\\varGamma':u'Γ', u'\\varLambda':u'Λ', u'\\varOmega':u'Ω', u'\\varPhi':u'Φ', u'\\varPi':u'Π', u'\\varPsi':u'Ψ', u'\\varSigma':u'Σ', u'\\varTheta':u'Θ', u'\\varUpsilon':u'Υ', u'\\varXi':u'Ξ', u'\\varbeta':u'ϐ', u'\\varepsilon':u'ε', u'\\varkappa':u'ϰ', u'\\varphi':u'φ', u'\\varpi':u'ϖ', u'\\varrho':u'ϱ', u'\\varsigma':u'ς', u'\\vartheta':u'ϑ', u'\\xi':u'ξ', u'\\zeta':u'ζ', } array = { u'begin':u'\\begin', u'cellseparator':u'&', u'end':u'\\end', u'rowseparator':u'\\\\', } bigbrackets = { u'(':[u'⎛',u'⎜',u'⎝',], u')':[u'⎞',u'⎟',u'⎠',], u'[':[u'⎡',u'⎢',u'⎣',], u']':[u'⎤',u'⎥',u'⎦',], u'{':[u'⎧',u'⎪',u'⎨',u'⎩',], u'|':[u'|',], u'}':[u'⎫',u'⎪',u'⎬',u'⎭',], u'∥':[u'∥',], } bigsymbols = { u'∑':[u'⎲',u'⎳',], u'∫':[u'⌠',u'⌡',], } bracketcommands = { u'\\left':u'span class="symbol"', u'\\left.':u'', u'\\middle':u'span class="symbol"', u'\\right':u'span class="symbol"', u'\\right.':u'', } combiningfunctions = { u'\\"':u'̈', u'\\\'':u'́', u'\\^':u'̂', u'\\`':u'̀', u'\\acute':u'́', u'\\bar':u'̄', u'\\breve':u'̆', u'\\c':u'̧', u'\\check':u'̌', u'\\dddot':u'⃛', u'\\ddot':u'̈', u'\\dot':u'̇', u'\\grave':u'̀', u'\\hat':u'̂', u'\\mathring':u'̊', u'\\overleftarrow':u'⃖', u'\\overrightarrow':u'⃗', u'\\r':u'̊', u'\\s':u'̩', u'\\textcircled':u'⃝', u'\\textsubring':u'̥', u'\\tilde':u'̃', u'\\v':u'̌', u'\\vec':u'⃗', u'\\~':u'̃', } commands = { u'\\ ':u' ', u'\\!':u'', u'\\#':u'#', u'\\$':u'$', u'\\%':u'%', u'\\&':u'&', u'\\,':u' ', u'\\:':u' ', u'\\;':u' ', u'\\AC':u'∿', u'\\APLcomment':u'⍝', u'\\APLdownarrowbox':u'⍗', u'\\APLinput':u'⍞', u'\\APLinv':u'⌹', u'\\APLleftarrowbox':u'⍇', u'\\APLlog':u'⍟', u'\\APLrightarrowbox':u'⍈', u'\\APLuparrowbox':u'⍐', u'\\Box':u'□', u'\\Bumpeq':u'≎', u'\\CIRCLE':u'●', u'\\Cap':u'⋒', u'\\CapitalDifferentialD':u'ⅅ', u'\\CheckedBox':u'☑', u'\\Circle':u'○', u'\\Coloneqq':u'⩴', u'\\ComplexI':u'ⅈ', u'\\ComplexJ':u'ⅉ', u'\\Corresponds':u'≙', u'\\Cup':u'⋓', u'\\Delta':u'Δ', u'\\Diamond':u'◇', u'\\Diamondblack':u'◆', u'\\Diamonddot':u'⟐', u'\\DifferentialD':u'ⅆ', u'\\Downarrow':u'⇓', u'\\EUR':u'€', u'\\Euler':u'ℇ', u'\\ExponetialE':u'ⅇ', u'\\Finv':u'Ⅎ', u'\\Game':u'⅁', u'\\Gamma':u'Γ', u'\\Im':u'ℑ', u'\\Join':u'⨝', u'\\LEFTCIRCLE':u'◖', u'\\LEFTcircle':u'◐', u'\\LHD':u'◀', u'\\Lambda':u'Λ', u'\\Lbag':u'⟅', u'\\Leftarrow':u'⇐', u'\\Lleftarrow':u'⇚', u'\\Longleftarrow':u'⟸', u'\\Longleftrightarrow':u'⟺', u'\\Longrightarrow':u'⟹', u'\\Lparen':u'⦅', u'\\Lsh':u'↰', u'\\Mapsfrom':u'⇐|', u'\\Mapsto':u'|⇒', u'\\Omega':u'Ω', u'\\P':u'¶', u'\\Phi':u'Φ', u'\\Pi':u'Π', u'\\Pr':u'Pr', u'\\Psi':u'Ψ', u'\\Qoppa':u'Ϙ', u'\\RHD':u'▶', u'\\RIGHTCIRCLE':u'◗', u'\\RIGHTcircle':u'◑', u'\\Rbag':u'⟆', u'\\Re':u'ℜ', u'\\Rparen':u'⦆', u'\\Rrightarrow':u'⇛', u'\\Rsh':u'↱', u'\\S':u'§', u'\\Sigma':u'Σ', u'\\Square':u'☐', u'\\Subset':u'⋐', u'\\Sun':u'☉', u'\\Supset':u'⋑', u'\\Theta':u'Θ', u'\\Uparrow':u'⇑', u'\\Updownarrow':u'⇕', u'\\Upsilon':u'Υ', u'\\Vdash':u'⊩', u'\\Vert':u'∥', u'\\Vvdash':u'⊪', u'\\XBox':u'☒', u'\\Xi':u'Ξ', u'\\Yup':u'⅄', u'\\\\':u'
', u'\\_':u'_', u'\\aleph':u'ℵ', u'\\amalg':u'∐', u'\\anchor':u'⚓', u'\\angle':u'∠', u'\\aquarius':u'♒', u'\\arccos':u'arccos', u'\\arcsin':u'arcsin', u'\\arctan':u'arctan', u'\\arg':u'arg', u'\\aries':u'♈', u'\\arrowbullet':u'➢', u'\\ast':u'∗', u'\\asymp':u'≍', u'\\backepsilon':u'∍', u'\\backprime':u'‵', u'\\backsimeq':u'⋍', u'\\backslash':u'\\', u'\\ballotx':u'✗', u'\\barwedge':u'⊼', u'\\because':u'∵', u'\\beth':u'ℶ', u'\\between':u'≬', u'\\bigcap':u'∩', u'\\bigcirc':u'○', u'\\bigcup':u'∪', u'\\bigodot':u'⊙', u'\\bigoplus':u'⊕', u'\\bigotimes':u'⊗', u'\\bigsqcup':u'⊔', u'\\bigstar':u'★', u'\\bigtriangledown':u'▽', u'\\bigtriangleup':u'△', u'\\biguplus':u'⊎', u'\\bigvee':u'∨', u'\\bigwedge':u'∧', u'\\biohazard':u'☣', u'\\blacklozenge':u'⧫', u'\\blacksmiley':u'☻', u'\\blacksquare':u'■', u'\\blacktriangle':u'▲', u'\\blacktriangledown':u'▼', u'\\blacktriangleleft':u'◂', u'\\blacktriangleright':u'▶', u'\\blacktriangleup':u'▴', u'\\bot':u'⊥', u'\\bowtie':u'⋈', u'\\box':u'▫', u'\\boxast':u'⧆', u'\\boxbar':u'◫', u'\\boxbox':u'⧈', u'\\boxbslash':u'⧅', u'\\boxcircle':u'⧇', u'\\boxdot':u'⊡', u'\\boxminus':u'⊟', u'\\boxplus':u'⊞', u'\\boxslash':u'⧄', u'\\boxtimes':u'⊠', u'\\bullet':u'•', u'\\bumpeq':u'≏', u'\\cancer':u'♋', u'\\cap':u'∩', u'\\capricornus':u'♑', u'\\cat':u'⁀', u'\\cdot':u'⋅', u'\\cdots':u'⋯', u'\\cent':u'¢', u'\\centerdot':u'∙', u'\\checkmark':u'✓', u'\\chi':u'χ', u'\\circ':u'○', u'\\circeq':u'≗', u'\\circlearrowleft':u'↺', u'\\circlearrowright':u'↻', u'\\circledR':u'®', u'\\circledast':u'⊛', u'\\circledbslash':u'⦸', u'\\circledcirc':u'⊚', u'\\circleddash':u'⊝', u'\\circledgtr':u'⧁', u'\\circledless':u'⧀', u'\\clubsuit':u'♣', u'\\coloneqq':u'≔', u'\\complement':u'∁', u'\\cong':u'≅', u'\\coprod':u'∐', u'\\copyright':u'©', u'\\cos':u'cos', u'\\cosh':u'cosh', u'\\cot':u'cot', u'\\coth':u'coth', u'\\csc':u'csc', u'\\cup':u'∪', u'\\curlyvee':u'⋎', u'\\curlywedge':u'⋏', u'\\curvearrowleft':u'↶', u'\\curvearrowright':u'↷', u'\\dag':u'†', u'\\dagger':u'†', u'\\daleth':u'ℸ', u'\\dashleftarrow':u'⇠', u'\\dashv':u'⊣', u'\\ddag':u'‡', u'\\ddagger':u'‡', u'\\ddots':u'⋱', u'\\deg':u'deg', u'\\det':u'det', u'\\diagdown':u'╲', u'\\diagup':u'╱', u'\\diameter':u'⌀', u'\\diamond':u'◇', u'\\diamondsuit':u'♦', u'\\dim':u'dim', u'\\div':u'÷', u'\\divideontimes':u'⋇', u'\\dotdiv':u'∸', u'\\doteq':u'≐', u'\\doteqdot':u'≑', u'\\dotplus':u'∔', u'\\dots':u'…', u'\\doublebarwedge':u'⌆', u'\\downarrow':u'↓', u'\\downdownarrows':u'⇊', u'\\downharpoonleft':u'⇃', u'\\downharpoonright':u'⇂', u'\\dsub':u'⩤', u'\\earth':u'♁', u'\\eighthnote':u'♪', u'\\ell':u'ℓ', u'\\emptyset':u'∅', u'\\eqcirc':u'≖', u'\\eqcolon':u'≕', u'\\eqsim':u'≂', u'\\euro':u'€', u'\\exists':u'∃', u'\\exp':u'exp', u'\\fallingdotseq':u'≒', u'\\fcmp':u'⨾', u'\\female':u'♀', u'\\flat':u'♭', u'\\forall':u'∀', u'\\fourth':u'⁗', u'\\frown':u'⌢', u'\\frownie':u'☹', u'\\gcd':u'gcd', u'\\gemini':u'♊', u'\\geq)':u'≥', u'\\geqq':u'≧', u'\\geqslant':u'≥', u'\\gets':u'←', u'\\gg':u'≫', u'\\ggg':u'⋙', u'\\gimel':u'ℷ', u'\\gneqq':u'≩', u'\\gnsim':u'⋧', u'\\gtrdot':u'⋗', u'\\gtreqless':u'⋚', u'\\gtreqqless':u'⪌', u'\\gtrless':u'≷', u'\\gtrsim':u'≳', u'\\guillemotleft':u'«', u'\\guillemotright':u'»', u'\\hbar':u'ℏ', u'\\heartsuit':u'♥', u'\\hfill':u' ', u'\\hom':u'hom', u'\\hookleftarrow':u'↩', u'\\hookrightarrow':u'↪', u'\\hslash':u'ℏ', u'\\idotsint':u'∫⋯∫', u'\\iiint':u'', u'\\iint':u'', u'\\imath':u'ı', u'\\inf':u'inf', u'\\infty':u'∞', u'\\intercal':u'⊺', u'\\interleave':u'⫴', u'\\invamp':u'⅋', u'\\invneg':u'⌐', u'\\jmath':u'ȷ', u'\\jupiter':u'♃', u'\\ker':u'ker', u'\\land':u'∧', u'\\landupint':u'', u'\\lang':u'⟪', u'\\langle':u'⟨', u'\\lblot':u'⦉', u'\\lbrace':u'{', u'\\lbrace)':u'{', u'\\lbrack':u'[', u'\\lceil':u'⌈', u'\\ldots':u'…', u'\\leadsto':u'⇝', u'\\leftarrow)':u'←', u'\\leftarrowtail':u'↢', u'\\leftarrowtobar':u'⇤', u'\\leftharpoondown':u'↽', u'\\leftharpoonup':u'↼', u'\\leftleftarrows':u'⇇', u'\\leftleftharpoons':u'⥢', u'\\leftmoon':u'☾', u'\\leftrightarrow':u'↔', u'\\leftrightarrows':u'⇆', u'\\leftrightharpoons':u'⇋', u'\\leftthreetimes':u'⋋', u'\\leo':u'♌', u'\\leq)':u'≤', u'\\leqq':u'≦', u'\\leqslant':u'≤', u'\\lessdot':u'⋖', u'\\lesseqgtr':u'⋛', u'\\lesseqqgtr':u'⪋', u'\\lessgtr':u'≶', u'\\lesssim':u'≲', u'\\lfloor':u'⌊', u'\\lg':u'lg', u'\\lgroup':u'⟮', u'\\lhd':u'⊲', u'\\libra':u'♎', u'\\lightning':u'↯', u'\\limg':u'⦇', u'\\liminf':u'liminf', u'\\limsup':u'limsup', u'\\ll':u'≪', u'\\llbracket':u'⟦', u'\\llcorner':u'⌞', u'\\lll':u'⋘', u'\\ln':u'ln', u'\\lneqq':u'≨', u'\\lnot':u'¬', u'\\lnsim':u'⋦', u'\\log':u'log', u'\\longleftarrow':u'⟵', u'\\longleftrightarrow':u'⟷', u'\\longmapsto':u'⟼', u'\\longrightarrow':u'⟶', u'\\looparrowleft':u'↫', u'\\looparrowright':u'↬', u'\\lor':u'∨', u'\\lozenge':u'◊', u'\\lrcorner':u'⌟', u'\\ltimes':u'⋉', u'\\lyxlock':u'', u'\\male':u'♂', u'\\maltese':u'✠', u'\\mapsfrom':u'↤', u'\\mapsto':u'↦', u'\\mathcircumflex':u'^', u'\\max':u'max', u'\\measuredangle':u'∡', u'\\medbullet':u'⚫', u'\\medcirc':u'⚪', u'\\mercury':u'☿', u'\\mho':u'℧', u'\\mid':u'∣', u'\\min':u'min', u'\\models':u'⊨', u'\\mp':u'∓', u'\\multimap':u'⊸', u'\\nLeftarrow':u'⇍', u'\\nLeftrightarrow':u'⇎', u'\\nRightarrow':u'⇏', u'\\nVDash':u'⊯', u'\\nabla':u'∇', u'\\napprox':u'≉', u'\\natural':u'♮', u'\\ncong':u'≇', u'\\nearrow':u'↗', u'\\neg':u'¬', u'\\neg)':u'¬', u'\\neptune':u'♆', u'\\nequiv':u'≢', u'\\newline':u'
', u'\\nexists':u'∄', u'\\ngeqslant':u'≱', u'\\ngtr':u'≯', u'\\ngtrless':u'≹', u'\\ni':u'∋', u'\\ni)':u'∋', u'\\nleftarrow':u'↚', u'\\nleftrightarrow':u'↮', u'\\nleqslant':u'≰', u'\\nless':u'≮', u'\\nlessgtr':u'≸', u'\\nmid':u'∤', u'\\nolimits':u'', u'\\nonumber':u'', u'\\not':u'¬', u'\\not<':u'≮', u'\\not=':u'≠', u'\\not>':u'≯', u'\\notbackslash':u'⍀', u'\\notin':u'∉', u'\\notni':u'∌', u'\\notslash':u'⌿', u'\\nparallel':u'∦', u'\\nprec':u'⊀', u'\\nrightarrow':u'↛', u'\\nsim':u'≁', u'\\nsimeq':u'≄', u'\\nsqsubset':u'⊏̸', u'\\nsubseteq':u'⊈', u'\\nsucc':u'⊁', u'\\nsucccurlyeq':u'⋡', u'\\nsupset':u'⊅', u'\\nsupseteq':u'⊉', u'\\ntriangleleft':u'⋪', u'\\ntrianglelefteq':u'⋬', u'\\ntriangleright':u'⋫', u'\\ntrianglerighteq':u'⋭', u'\\nvDash':u'⊭', u'\\nvdash':u'⊬', u'\\nwarrow':u'↖', u'\\odot':u'⊙', u'\\officialeuro':u'€', u'\\oiiint':u'', u'\\oiint':u'', u'\\oint':u'', u'\\ointclockwise':u'', u'\\ointctrclockwise':u'', u'\\ominus':u'⊖', u'\\oplus':u'⊕', u'\\oslash':u'⊘', u'\\otimes':u'⊗', u'\\owns':u'∋', u'\\parallel':u'∥', u'\\partial':u'∂', u'\\pencil':u'✎', u'\\perp':u'⊥', u'\\pisces':u'♓', u'\\pitchfork':u'⋔', u'\\pluto':u'♇', u'\\pm':u'±', u'\\pointer':u'➪', u'\\pointright':u'☞', u'\\pounds':u'£', u'\\prec':u'≺', u'\\preccurlyeq':u'≼', u'\\preceq':u'≼', u'\\precsim':u'≾', u'\\prime':u'′', u'\\prompto':u'∝', u'\\qoppa':u'ϙ', u'\\qquad':u' ', u'\\quad':u' ', u'\\quarternote':u'♩', u'\\radiation':u'☢', u'\\rang':u'⟫', u'\\rangle':u'⟩', u'\\rblot':u'⦊', u'\\rbrace':u'}', u'\\rbrace)':u'}', u'\\rbrack':u']', u'\\rceil':u'⌉', u'\\recycle':u'♻', u'\\rfloor':u'⌋', u'\\rgroup':u'⟯', u'\\rhd':u'⊳', u'\\rightangle':u'∟', u'\\rightarrow)':u'→', u'\\rightarrowtail':u'↣', u'\\rightarrowtobar':u'⇥', u'\\rightharpoondown':u'⇁', u'\\rightharpoonup':u'⇀', u'\\rightharpooondown':u'⇁', u'\\rightharpooonup':u'⇀', u'\\rightleftarrows':u'⇄', u'\\rightleftharpoons':u'⇌', u'\\rightmoon':u'☽', u'\\rightrightarrows':u'⇉', u'\\rightrightharpoons':u'⥤', u'\\rightthreetimes':u'⋌', u'\\rimg':u'⦈', u'\\risingdotseq':u'≓', u'\\rrbracket':u'⟧', u'\\rsub':u'⩥', u'\\rtimes':u'⋊', u'\\sagittarius':u'♐', u'\\saturn':u'♄', u'\\scorpio':u'♏', u'\\searrow':u'↘', u'\\sec':u'sec', u'\\second':u'″', u'\\setminus':u'∖', u'\\sharp':u'♯', u'\\simeq':u'≃', u'\\sin':u'sin', u'\\sinh':u'sinh', u'\\sixteenthnote':u'♬', u'\\skull':u'☠', u'\\slash':u'∕', u'\\smallsetminus':u'∖', u'\\smalltriangledown':u'▿', u'\\smalltriangleleft':u'◃', u'\\smalltriangleright':u'▹', u'\\smalltriangleup':u'▵', u'\\smile':u'⌣', u'\\smiley':u'☺', u'\\spadesuit':u'♠', u'\\spddot':u'¨', u'\\sphat':u'', u'\\sphericalangle':u'∢', u'\\spot':u'⦁', u'\\sptilde':u'~', u'\\sqcap':u'⊓', u'\\sqcup':u'⊔', u'\\sqsubset':u'⊏', u'\\sqsubseteq':u'⊑', u'\\sqsupset':u'⊐', u'\\sqsupseteq':u'⊒', u'\\square':u'□', u'\\sslash':u'⫽', u'\\star':u'⋆', u'\\steaming':u'☕', u'\\subseteqq':u'⫅', u'\\subsetneqq':u'⫋', u'\\succ':u'≻', u'\\succcurlyeq':u'≽', u'\\succeq':u'≽', u'\\succnsim':u'⋩', u'\\succsim':u'≿', u'\\sun':u'☼', u'\\sup':u'sup', u'\\supseteqq':u'⫆', u'\\supsetneqq':u'⫌', u'\\surd':u'√', u'\\swarrow':u'↙', u'\\swords':u'⚔', u'\\talloblong':u'⫾', u'\\tan':u'tan', u'\\tanh':u'tanh', u'\\taurus':u'♉', u'\\textasciicircum':u'^', u'\\textasciitilde':u'~', u'\\textbackslash':u'\\', u'\\textcopyright':u'©\'', u'\\textdegree':u'°', u'\\textellipsis':u'…', u'\\textemdash':u'—', u'\\textendash':u'—', u'\\texteuro':u'€', u'\\textgreater':u'>', u'\\textless':u'<', u'\\textordfeminine':u'ª', u'\\textordmasculine':u'º', u'\\textquotedblleft':u'“', u'\\textquotedblright':u'”', u'\\textquoteright':u'’', u'\\textregistered':u'®', u'\\textrightarrow':u'→', u'\\textsection':u'§', u'\\texttrademark':u'™', u'\\texttwosuperior':u'²', u'\\textvisiblespace':u' ', u'\\therefore':u'∴', u'\\third':u'‴', u'\\top':u'⊤', u'\\triangle':u'△', u'\\triangleleft':u'⊲', u'\\trianglelefteq':u'⊴', u'\\triangleq':u'≜', u'\\triangleright':u'▷', u'\\trianglerighteq':u'⊵', u'\\twoheadleftarrow':u'↞', u'\\twoheadrightarrow':u'↠', u'\\twonotes':u'♫', u'\\udot':u'⊍', u'\\ulcorner':u'⌜', u'\\unlhd':u'⊴', u'\\unrhd':u'⊵', u'\\unrhl':u'⊵', u'\\uparrow':u'↑', u'\\updownarrow':u'↕', u'\\upharpoonleft':u'↿', u'\\upharpoonright':u'↾', u'\\uplus':u'⊎', u'\\upuparrows':u'⇈', u'\\uranus':u'♅', u'\\urcorner':u'⌝', u'\\vDash':u'⊨', u'\\varclubsuit':u'♧', u'\\vardiamondsuit':u'♦', u'\\varheartsuit':u'♥', u'\\varnothing':u'∅', u'\\varspadesuit':u'♤', u'\\vdash':u'⊢', u'\\vdots':u'⋮', u'\\vee':u'∨', u'\\vee)':u'∨', u'\\veebar':u'⊻', u'\\vert':u'∣', u'\\virgo':u'♍', u'\\warning':u'⚠', u'\\wasylozenge':u'⌑', u'\\wedge':u'∧', u'\\wedge)':u'∧', u'\\wp':u'℘', u'\\wr':u'≀', u'\\yen':u'¥', u'\\yinyang':u'☯', u'\\{':u'{', u'\\|':u'∥', u'\\}':u'}', } decoratedcommand = { } decoratingfunctions = { u'\\overleftarrow':u'⟵', u'\\overrightarrow':u'⟶', u'\\widehat':u'^', } endings = { u'bracket':u'}', u'complex':u'\\]', u'endafter':u'}', u'endbefore':u'\\end{', u'squarebracket':u']', } environments = { u'align':[u'r',u'l',], u'eqnarray':[u'r',u'c',u'l',], u'gathered':[u'l',u'l',], } fontfunctions = { u'\\boldsymbol':u'b', u'\\mathbb':u'span class="blackboard"', u'\\mathbb{A}':u'𝔸', u'\\mathbb{B}':u'𝔹', u'\\mathbb{C}':u'ℂ', u'\\mathbb{D}':u'𝔻', u'\\mathbb{E}':u'𝔼', u'\\mathbb{F}':u'𝔽', u'\\mathbb{G}':u'𝔾', u'\\mathbb{H}':u'ℍ', u'\\mathbb{J}':u'𝕁', u'\\mathbb{K}':u'𝕂', u'\\mathbb{L}':u'𝕃', u'\\mathbb{N}':u'ℕ', u'\\mathbb{O}':u'𝕆', u'\\mathbb{P}':u'ℙ', u'\\mathbb{Q}':u'ℚ', u'\\mathbb{R}':u'ℝ', u'\\mathbb{S}':u'𝕊', u'\\mathbb{T}':u'𝕋', u'\\mathbb{W}':u'𝕎', u'\\mathbb{Z}':u'ℤ', u'\\mathbf':u'b', u'\\mathcal':u'span class="scriptfont"', u'\\mathcal{B}':u'ℬ', u'\\mathcal{E}':u'ℰ', u'\\mathcal{F}':u'ℱ', u'\\mathcal{H}':u'ℋ', u'\\mathcal{I}':u'ℐ', u'\\mathcal{L}':u'ℒ', u'\\mathcal{M}':u'ℳ', u'\\mathcal{R}':u'ℛ', u'\\mathfrak':u'span class="fraktur"', u'\\mathfrak{C}':u'ℭ', u'\\mathfrak{F}':u'𝔉', u'\\mathfrak{H}':u'ℌ', u'\\mathfrak{I}':u'ℑ', u'\\mathfrak{R}':u'ℜ', u'\\mathfrak{Z}':u'ℨ', u'\\mathit':u'i', u'\\mathring{A}':u'Å', u'\\mathring{U}':u'Ů', u'\\mathring{a}':u'å', u'\\mathring{u}':u'ů', u'\\mathring{w}':u'ẘ', u'\\mathring{y}':u'ẙ', u'\\mathrm':u'span class="mathrm"', u'\\mathscr':u'span class="scriptfont"', u'\\mathscr{B}':u'ℬ', u'\\mathscr{E}':u'ℰ', u'\\mathscr{F}':u'ℱ', u'\\mathscr{H}':u'ℋ', u'\\mathscr{I}':u'ℐ', u'\\mathscr{L}':u'ℒ', u'\\mathscr{M}':u'ℳ', u'\\mathscr{R}':u'ℛ', u'\\mathsf':u'span class="mathsf"', u'\\mathtt':u'tt', } hybridfunctions = { u'\\addcontentsline':[u'{$p!}{$q!}{$r!}',u'f0{}',u'ignored',], u'\\addtocontents':[u'{$p!}{$q!}',u'f0{}',u'ignored',], u'\\backmatter':[u'',u'f0{}',u'ignored',], u'\\binom':[u'{$1}{$2}',u'f2{(}f0{f1{$1}f1{$2}}f2{)}',u'span class="binom"',u'span class="binomstack"',u'span class="bigsymbol"',], u'\\boxed':[u'{$1}',u'f0{$1}',u'span class="boxed"',], u'\\cfrac':[u'[$p!]{$1}{$2}',u'f0{f3{(}f1{$1}f3{)/(}f2{$2}f3{)}}',u'span class="fullfraction"',u'span class="numerator align-$p"',u'span class="denominator"',u'span class="ignored"',], u'\\color':[u'{$p!}{$1}',u'f0{$1}',u'span style="color: $p;"',], u'\\colorbox':[u'{$p!}{$1}',u'f0{$1}',u'span class="colorbox" style="background: $p;"',], u'\\dbinom':[u'{$1}{$2}',u'(f0{f1{f2{$1}}f1{f2{ }}f1{f2{$2}}})',u'span class="binomial"',u'span class="binomrow"',u'span class="binomcell"',], u'\\dfrac':[u'{$1}{$2}',u'f0{f3{(}f1{$1}f3{)/(}f2{$2}f3{)}}',u'span class="fullfraction"',u'span class="numerator"',u'span class="denominator"',u'span class="ignored"',], u'\\displaystyle':[u'{$1}',u'f0{$1}',u'span class="displaystyle"',], u'\\fancyfoot':[u'[$p!]{$q!}',u'f0{}',u'ignored',], u'\\fancyhead':[u'[$p!]{$q!}',u'f0{}',u'ignored',], u'\\fbox':[u'{$1}',u'f0{$1}',u'span class="fbox"',], u'\\fboxrule':[u'{$p!}',u'f0{}',u'ignored',], u'\\fboxsep':[u'{$p!}',u'f0{}',u'ignored',], u'\\fcolorbox':[u'{$p!}{$q!}{$1}',u'f0{$1}',u'span class="boxed" style="border-color: $p; background: $q;"',], u'\\frac':[u'{$1}{$2}',u'f0{f3{(}f1{$1}f3{)/(}f2{$2}f3{)}}',u'span class="fraction"',u'span class="numerator"',u'span class="denominator"',u'span class="ignored"',], u'\\framebox':[u'[$p!][$q!]{$1}',u'f0{$1}',u'span class="framebox align-$q" style="width: $p;"',], u'\\frontmatter':[u'',u'f0{}',u'ignored',], u'\\href':[u'[$o]{$u!}{$t!}',u'f0{$t}',u'a href="$u"',], u'\\hspace':[u'{$p!}',u'f0{ }',u'span class="hspace" style="width: $p;"',], u'\\leftroot':[u'{$p!}',u'f0{ }',u'span class="leftroot" style="width: $p;px"',], u'\\mainmatter':[u'',u'f0{}',u'ignored',], u'\\markboth':[u'{$p!}{$q!}',u'f0{}',u'ignored',], u'\\markright':[u'{$p!}',u'f0{}',u'ignored',], u'\\nicefrac':[u'{$1}{$2}',u'f0{f1{$1}⁄f2{$2}}',u'span class="fraction"',u'sup class="numerator"',u'sub class="denominator"',u'span class="ignored"',], u'\\parbox':[u'[$p!]{$w!}{$1}',u'f0{1}',u'div class="Boxed" style="width: $w;"',], u'\\raisebox':[u'{$p!}{$1}',u'f0{$1.font}',u'span class="raisebox" style="vertical-align: $p;"',], u'\\renewenvironment':[u'{$1!}{$2!}{$3!}',u'',], u'\\rule':[u'[$v!]{$w!}{$h!}',u'f0/',u'hr class="line" style="width: $w; height: $h;"',], u'\\scriptscriptstyle':[u'{$1}',u'f0{$1}',u'span class="scriptscriptstyle"',], u'\\scriptstyle':[u'{$1}',u'f0{$1}',u'span class="scriptstyle"',], u'\\sqrt':[u'[$0]{$1}',u'f0{f1{$0}f2{√}f4{(}f3{$1}f4{)}}',u'span class="sqrt"',u'sup class="root"',u'span class="radical"',u'span class="root"',u'span class="ignored"',], u'\\stackrel':[u'{$1}{$2}',u'f0{f1{$1}f2{$2}}',u'span class="stackrel"',u'span class="upstackrel"',u'span class="downstackrel"',], u'\\tbinom':[u'{$1}{$2}',u'(f0{f1{f2{$1}}f1{f2{ }}f1{f2{$2}}})',u'span class="binomial"',u'span class="binomrow"',u'span class="binomcell"',], u'\\textcolor':[u'{$p!}{$1}',u'f0{$1}',u'span style="color: $p;"',], u'\\textstyle':[u'{$1}',u'f0{$1}',u'span class="textstyle"',], u'\\thispagestyle':[u'{$p!}',u'f0{}',u'ignored',], u'\\unit':[u'[$0]{$1}',u'$0f0{$1.font}',u'span class="unit"',], u'\\unitfrac':[u'[$0]{$1}{$2}',u'$0f0{f1{$1.font}⁄f2{$2.font}}',u'span class="fraction"',u'sup class="unit"',u'sub class="unit"',], u'\\uproot':[u'{$p!}',u'f0{ }',u'span class="uproot" style="width: $p;px"',], u'\\url':[u'{$u!}',u'f0{$u}',u'a href="$u"',], u'\\vspace':[u'{$p!}',u'f0{ }',u'span class="vspace" style="height: $p;"',], } hybridsizes = { u'\\binom':u'$1+$2', u'\\cfrac':u'$1+$2', u'\\dbinom':u'$1+$2+1', u'\\dfrac':u'$1+$2', u'\\frac':u'$1+$2', u'\\tbinom':u'$1+$2+1', } labelfunctions = { u'\\label':u'a name="#"', } limitcommands = { u'\\biginterleave':u'⫼', u'\\bigsqcap':u'⨅', u'\\fint':u'⨏', u'\\iiiint':u'⨌', u'\\int':u'∫', u'\\intop':u'∫', u'\\lim':u'lim', u'\\prod':u'∏', u'\\smallint':u'∫', u'\\sqint':u'⨖', u'\\sum':u'∑', u'\\varointclockwise':u'∲', u'\\varprod':u'⨉', u'\\zcmp':u'⨟', u'\\zhide':u'⧹', u'\\zpipe':u'⨠', u'\\zproject':u'⨡', } misccommands = { u'\\limits':u'LimitPreviousCommand', u'\\newcommand':u'MacroDefinition', u'\\renewcommand':u'MacroDefinition', u'\\setcounter':u'SetCounterFunction', u'\\tag':u'FormulaTag', u'\\tag*':u'FormulaTag', u'\\today':u'TodayCommand', } modified = { u'\n':u'', u' ':u'', u'$':u'', u'&':u' ', u'\'':u'’', u'+':u' + ', u',':u', ', u'-':u' − ', u'/':u' ⁄ ', u'<':u' < ', u'=':u' = ', u'>':u' > ', u'@':u'', u'~':u'', } onefunctions = { u'\\Big':u'span class="bigsymbol"', u'\\Bigg':u'span class="hugesymbol"', u'\\bar':u'span class="bar"', u'\\begin{array}':u'span class="arraydef"', u'\\big':u'span class="symbol"', u'\\bigg':u'span class="largesymbol"', u'\\bigl':u'span class="bigsymbol"', u'\\bigr':u'span class="bigsymbol"', u'\\centering':u'span class="align-center"', u'\\ensuremath':u'span class="ensuremath"', u'\\hphantom':u'span class="phantom"', u'\\noindent':u'span class="noindent"', u'\\overbrace':u'span class="overbrace"', u'\\overline':u'span class="overline"', u'\\phantom':u'span class="phantom"', u'\\underbrace':u'span class="underbrace"', u'\\underline':u'u', u'\\vphantom':u'span class="phantom"', } spacedcommands = { u'\\Bot':u'⫫', u'\\Doteq':u'≑', u'\\DownArrowBar':u'⤓', u'\\DownLeftTeeVector':u'⥞', u'\\DownLeftVectorBar':u'⥖', u'\\DownRightTeeVector':u'⥟', u'\\DownRightVectorBar':u'⥗', u'\\Equal':u'⩵', u'\\LeftArrowBar':u'⇤', u'\\LeftDownTeeVector':u'⥡', u'\\LeftDownVectorBar':u'⥙', u'\\LeftTeeVector':u'⥚', u'\\LeftTriangleBar':u'⧏', u'\\LeftUpTeeVector':u'⥠', u'\\LeftUpVectorBar':u'⥘', u'\\LeftVectorBar':u'⥒', u'\\Leftrightarrow':u'⇔', u'\\Longmapsfrom':u'⟽', u'\\Longmapsto':u'⟾', u'\\MapsDown':u'↧', u'\\MapsUp':u'↥', u'\\Nearrow':u'⇗', u'\\NestedGreaterGreater':u'⪢', u'\\NestedLessLess':u'⪡', u'\\NotGreaterLess':u'≹', u'\\NotGreaterTilde':u'≵', u'\\NotLessTilde':u'≴', u'\\Nwarrow':u'⇖', u'\\Proportion':u'∷', u'\\RightArrowBar':u'⇥', u'\\RightDownTeeVector':u'⥝', u'\\RightDownVectorBar':u'⥕', u'\\RightTeeVector':u'⥛', u'\\RightTriangleBar':u'⧐', u'\\RightUpTeeVector':u'⥜', u'\\RightUpVectorBar':u'⥔', u'\\RightVectorBar':u'⥓', u'\\Rightarrow':u'⇒', u'\\Same':u'⩶', u'\\Searrow':u'⇘', u'\\Swarrow':u'⇙', u'\\Top':u'⫪', u'\\UpArrowBar':u'⤒', u'\\VDash':u'⊫', u'\\approx':u'≈', u'\\approxeq':u'≊', u'\\backsim':u'∽', u'\\barin':u'⋶', u'\\barleftharpoon':u'⥫', u'\\barrightharpoon':u'⥭', u'\\bij':u'⤖', u'\\coloneq':u'≔', u'\\corresponds':u'≙', u'\\curlyeqprec':u'⋞', u'\\curlyeqsucc':u'⋟', u'\\dashrightarrow':u'⇢', u'\\dlsh':u'↲', u'\\downdownharpoons':u'⥥', u'\\downuparrows':u'⇵', u'\\downupharpoons':u'⥯', u'\\drsh':u'↳', u'\\eqslantgtr':u'⪖', u'\\eqslantless':u'⪕', u'\\equiv':u'≡', u'\\ffun':u'⇻', u'\\finj':u'⤕', u'\\ge':u'≥', u'\\geq':u'≥', u'\\ggcurly':u'⪼', u'\\gnapprox':u'⪊', u'\\gneq':u'⪈', u'\\gtrapprox':u'⪆', u'\\hash':u'⋕', u'\\iddots':u'⋰', u'\\implies':u' ⇒ ', u'\\in':u'∈', u'\\le':u'≤', u'\\leftarrow':u'←', u'\\leftarrowtriangle':u'⇽', u'\\leftbarharpoon':u'⥪', u'\\leftrightarrowtriangle':u'⇿', u'\\leftrightharpoon':u'⥊', u'\\leftrightharpoondown':u'⥐', u'\\leftrightharpoonup':u'⥎', u'\\leftrightsquigarrow':u'↭', u'\\leftslice':u'⪦', u'\\leftsquigarrow':u'⇜', u'\\leftupdownharpoon':u'⥑', u'\\leq':u'≤', u'\\lessapprox':u'⪅', u'\\llcurly':u'⪻', u'\\lnapprox':u'⪉', u'\\lneq':u'⪇', u'\\longmapsfrom':u'⟻', u'\\multimapboth':u'⧟', u'\\multimapdotbothA':u'⊶', u'\\multimapdotbothB':u'⊷', u'\\multimapinv':u'⟜', u'\\nVdash':u'⊮', u'\\ne':u'≠', u'\\neq':u'≠', u'\\ngeq':u'≱', u'\\nleq':u'≰', u'\\nni':u'∌', u'\\not\\in':u'∉', u'\\notasymp':u'≭', u'\\npreceq':u'⋠', u'\\nsqsubseteq':u'⋢', u'\\nsqsupseteq':u'⋣', u'\\nsubset':u'⊄', u'\\nsucceq':u'⋡', u'\\pfun':u'⇸', u'\\pinj':u'⤔', u'\\precapprox':u'⪷', u'\\preceqq':u'⪳', u'\\precnapprox':u'⪹', u'\\precnsim':u'⋨', u'\\propto':u'∝', u'\\psur':u'⤀', u'\\rightarrow':u'→', u'\\rightarrowtriangle':u'⇾', u'\\rightbarharpoon':u'⥬', u'\\rightleftharpoon':u'⥋', u'\\rightslice':u'⪧', u'\\rightsquigarrow':u'⇝', u'\\rightupdownharpoon':u'⥏', u'\\sim':u'~', u'\\strictfi':u'⥼', u'\\strictif':u'⥽', u'\\subset':u'⊂', u'\\subseteq':u'⊆', u'\\subsetneq':u'⊊', u'\\succapprox':u'⪸', u'\\succeqq':u'⪴', u'\\succnapprox':u'⪺', u'\\supset':u'⊃', u'\\supseteq':u'⊇', u'\\supsetneq':u'⊋', u'\\times':u'×', u'\\to':u'→', u'\\updownarrows':u'⇅', u'\\updownharpoons':u'⥮', u'\\upupharpoons':u'⥣', u'\\vartriangleleft':u'⊲', u'\\vartriangleright':u'⊳', } starts = { u'beginafter':u'}', u'beginbefore':u'\\begin{', u'bracket':u'{', u'command':u'\\', u'comment':u'%', u'complex':u'\\[', u'simple':u'$', u'squarebracket':u'[', u'unnumbered':u'*', } symbolfunctions = { u'^':u'sup', u'_':u'sub', } textfunctions = { u'\\mbox':u'span class="mbox"', u'\\text':u'span class="text"', u'\\textbf':u'b', u'\\textipa':u'span class="textipa"', u'\\textit':u'i', u'\\textnormal':u'span class="textnormal"', u'\\textrm':u'span class="textrm"', u'\\textsc':u'span class="versalitas"', u'\\textsf':u'span class="textsf"', u'\\textsl':u'i', u'\\texttt':u'tt', u'\\textup':u'span class="normal"', } unmodified = { u'characters':[u'.',u'*',u'€',u'(',u')',u'[',u']',u':',u'·',u'!',u';',u'|',u'§',u'"',], } urls = { u'googlecharts':u'http://chart.googleapis.com/chart?cht=tx&chl=', } class GeneralConfig(object): "Configuration class from elyxer.config file" version = { u'date':u'2013-03-10', u'lyxformat':u'413', u'number':u'1.2.5', } class HeaderConfig(object): "Configuration class from elyxer.config file" parameters = { u'beginpreamble':u'\\begin_preamble', u'branch':u'\\branch', u'documentclass':u'\\textclass', u'endbranch':u'\\end_branch', u'endpreamble':u'\\end_preamble', u'language':u'\\language', u'lstset':u'\\lstset', u'outputchanges':u'\\output_changes', u'paragraphseparation':u'\\paragraph_separation', u'pdftitle':u'\\pdf_title', u'secnumdepth':u'\\secnumdepth', u'tocdepth':u'\\tocdepth', } styles = { u'article':[u'article',u'aastex',u'aapaper',u'acmsiggraph',u'sigplanconf',u'achemso',u'amsart',u'apa',u'arab-article',u'armenian-article',u'article-beamer',u'chess',u'dtk',u'elsarticle',u'heb-article',u'IEEEtran',u'iopart',u'kluwer',u'scrarticle-beamer',u'scrartcl',u'extarticle',u'paper',u'mwart',u'revtex4',u'spie',u'svglobal3',u'ltugboat',u'agu-dtd',u'jgrga',u'agums',u'entcs',u'egs',u'ijmpc',u'ijmpd',u'singlecol-new',u'doublecol-new',u'isprs',u'tarticle',u'jsarticle',u'jarticle',u'jss',u'literate-article',u'siamltex',u'cl2emult',u'llncs',u'svglobal',u'svjog',u'svprobth',], u'book':[u'book',u'amsbook',u'scrbook',u'extbook',u'tufte-book',u'report',u'extreport',u'scrreprt',u'memoir',u'tbook',u'jsbook',u'jbook',u'mwbk',u'svmono',u'svmult',u'treport',u'jreport',u'mwrep',], } class ImageConfig(object): "Configuration class from elyxer.config file" converters = { u'imagemagick':u'convert[ -density $scale][ -define $format:use-cropbox=true] "$input" "$output"', u'inkscape':u'inkscape "$input" --export-png="$output"', u'lyx':u'lyx -C "$input" "$output"', } cropboxformats = { u'.eps':u'ps', u'.pdf':u'pdf', u'.ps':u'ps', } formats = { u'default':u'.png', u'vector':[u'.svg',u'.eps',], } class LayoutConfig(object): "Configuration class from elyxer.config file" groupable = { u'allowed':[u'StringContainer',u'Constant',u'TaggedText',u'Align',u'TextFamily',u'EmphaticText',u'VersalitasText',u'BarredText',u'SizeText',u'ColorText',u'LangLine',u'Formula',], } class NewfangleConfig(object): "Configuration class from elyxer.config file" constants = { u'chunkref':u'chunkref{', u'endcommand':u'}', u'endmark':u'>', u'startcommand':u'\\', u'startmark':u'=<', } class NumberingConfig(object): "Configuration class from elyxer.config file" layouts = { u'ordered':[u'Chapter',u'Section',u'Subsection',u'Subsubsection',u'Paragraph',], u'roman':[u'Part',u'Book',], } sequence = { u'symbols':[u'*',u'**',u'†',u'‡',u'§',u'§§',u'¶',u'¶¶',u'#',u'##',], } class StyleConfig(object): "Configuration class from elyxer.config file" hspaces = { u'\\enskip{}':u' ', u'\\hfill{}':u' ', u'\\hspace*{\\fill}':u' ', u'\\hspace*{}':u'', u'\\hspace{}':u' ', u'\\negthinspace{}':u'', u'\\qquad{}':u'  ', u'\\quad{}':u' ', u'\\space{}':u' ', u'\\thinspace{}':u' ', u'~':u' ', } quotes = { u'ald':u'»', u'als':u'›', u'ard':u'«', u'ars':u'‹', u'eld':u'“', u'els':u'‘', u'erd':u'”', u'ers':u'’', u'fld':u'«', u'fls':u'‹', u'frd':u'»', u'frs':u'›', u'gld':u'„', u'gls':u'‚', u'grd':u'“', u'grs':u'‘', u'pld':u'„', u'pls':u'‚', u'prd':u'”', u'prs':u'’', u'sld':u'”', u'srd':u'”', } referenceformats = { u'eqref':u'(@↕)', u'formatted':u'¶↕', u'nameref':u'$↕', u'pageref':u'#↕', u'ref':u'@↕', u'vpageref':u'on-page#↕', u'vref':u'@on-page#↕', } size = { u'ignoredtexts':[u'col',u'text',u'line',u'page',u'theight',u'pheight',], } vspaces = { u'bigskip':u'
', u'defskip':u'
', u'medskip':u'
', u'smallskip':u'
', u'vfill':u'
', } class TOCConfig(object): "Configuration class from elyxer.config file" extractplain = { u'allowed':[u'StringContainer',u'Constant',u'TaggedText',u'Align',u'TextFamily',u'EmphaticText',u'VersalitasText',u'BarredText',u'SizeText',u'ColorText',u'LangLine',u'Formula',], u'cloned':[u'',], u'extracted':[u'',], } extracttitle = { u'allowed':[u'StringContainer',u'Constant',u'Space',], u'cloned':[u'TextFamily',u'EmphaticText',u'VersalitasText',u'BarredText',u'SizeText',u'ColorText',u'LangLine',u'Formula',], u'extracted':[u'PlainLayout',u'TaggedText',u'Align',u'Caption',u'StandardLayout',u'FlexInset',], } class TagConfig(object): "Configuration class from elyxer.config file" barred = { u'under':u'u', } family = { u'sans':u'span class="sans"', u'typewriter':u'tt', } flex = { u'CharStyle:Code':u'span class="code"', u'CharStyle:MenuItem':u'span class="menuitem"', u'Code':u'span class="code"', u'MenuItem':u'span class="menuitem"', u'Noun':u'span class="noun"', u'Strong':u'span class="strong"', } group = { u'layouts':[u'Quotation',u'Quote',], } layouts = { u'Center':u'div', u'Chapter':u'h?', u'Date':u'h2', u'Paragraph':u'div', u'Part':u'h1', u'Quotation':u'blockquote', u'Quote':u'blockquote', u'Section':u'h?', u'Subsection':u'h?', u'Subsubsection':u'h?', } listitems = { u'Enumerate':u'ol', u'Itemize':u'ul', } notes = { u'Comment':u'', u'Greyedout':u'span class="greyedout"', u'Note':u'', } script = { u'subscript':u'sub', u'superscript':u'sup', } shaped = { u'italic':u'i', u'slanted':u'i', u'smallcaps':u'span class="versalitas"', } class TranslationConfig(object): "Configuration class from elyxer.config file" constants = { u'Appendix':u'Appendix', u'Book':u'Book', u'Chapter':u'Chapter', u'Paragraph':u'Paragraph', u'Part':u'Part', u'Section':u'Section', u'Subsection':u'Subsection', u'Subsubsection':u'Subsubsection', u'abstract':u'Abstract', u'bibliography':u'Bibliography', u'figure':u'figure', u'float-algorithm':u'Algorithm ', u'float-figure':u'Figure ', u'float-listing':u'Listing ', u'float-table':u'Table ', u'float-tableau':u'Tableau ', u'footnotes':u'Footnotes', u'generated-by':u'Document generated by ', u'generated-on':u' on ', u'index':u'Index', u'jsmath-enable':u'Please enable JavaScript on your browser.', u'jsmath-requires':u' requires JavaScript to correctly process the mathematics on this page. ', u'jsmath-warning':u'Warning: ', u'list-algorithm':u'List of Algorithms', u'list-figure':u'List of Figures', u'list-table':u'List of Tables', u'list-tableau':u'List of Tableaux', u'main-page':u'Main page', u'next':u'Next', u'nomenclature':u'Nomenclature', u'on-page':u' on page ', u'prev':u'Prev', u'references':u'References', u'toc':u'Table of Contents', u'toc-for':u'Contents for ', u'up':u'Up', } languages = { u'american':u'en', u'british':u'en', u'deutsch':u'de', u'dutch':u'nl', u'english':u'en', u'french':u'fr', u'ngerman':u'de', u'russian':u'ru', u'spanish':u'es', } class Globable(object): """A bit of text which can be globbed (lumped together in bits). Methods current(), skipcurrent(), checkfor() and isout() have to be implemented by subclasses.""" leavepending = False def __init__(self): self.endinglist = EndingList() def checkbytemark(self): "Check for a Unicode byte mark and skip it." if self.finished(): return if ord(self.current()) == 0xfeff: self.skipcurrent() def isout(self): "Find out if we are out of the position yet." Trace.error('Unimplemented isout()') return True def current(self): "Return the current character." Trace.error('Unimplemented current()') return '' def checkfor(self, string): "Check for the given string in the current position." Trace.error('Unimplemented checkfor()') return False def finished(self): "Find out if the current text has finished." if self.isout(): if not self.leavepending: self.endinglist.checkpending() return True return self.endinglist.checkin(self) def skipcurrent(self): "Return the current character and skip it." Trace.error('Unimplemented skipcurrent()') return '' def glob(self, currentcheck): "Glob a bit of text that satisfies a check on the current char." glob = '' while not self.finished() and currentcheck(): glob += self.skipcurrent() return glob def globalpha(self): "Glob a bit of alpha text" return self.glob(lambda: self.current().isalpha()) def globnumber(self): "Glob a row of digits." return self.glob(lambda: self.current().isdigit()) def isidentifier(self): "Return if the current character is alphanumeric or _." if self.current().isalnum() or self.current() == '_': return True return False def globidentifier(self): "Glob alphanumeric and _ symbols." return self.glob(self.isidentifier) def isvalue(self): "Return if the current character is a value character:" "not a bracket or a space." if self.current().isspace(): return False if self.current() in '{}()': return False return True def globvalue(self): "Glob a value: any symbols but brackets." return self.glob(self.isvalue) def skipspace(self): "Skip all whitespace at current position." return self.glob(lambda: self.current().isspace()) def globincluding(self, magicchar): "Glob a bit of text up to (including) the magic char." glob = self.glob(lambda: self.current() != magicchar) + magicchar self.skip(magicchar) return glob def globexcluding(self, excluded): "Glob a bit of text up until (excluding) any excluded character." return self.glob(lambda: self.current() not in excluded) def pushending(self, ending, optional = False): "Push a new ending to the bottom" self.endinglist.add(ending, optional) def popending(self, expected = None): "Pop the ending found at the current position" if self.isout() and self.leavepending: return expected ending = self.endinglist.pop(self) if expected and expected != ending: Trace.error('Expected ending ' + expected + ', got ' + ending) self.skip(ending) return ending def nextending(self): "Return the next ending in the queue." nextending = self.endinglist.findending(self) if not nextending: return None return nextending.ending class EndingList(object): "A list of position endings" def __init__(self): self.endings = [] def add(self, ending, optional = False): "Add a new ending to the list" self.endings.append(PositionEnding(ending, optional)) def pickpending(self, pos): "Pick any pending endings from a parse position." self.endings += pos.endinglist.endings def checkin(self, pos): "Search for an ending" if self.findending(pos): return True return False def pop(self, pos): "Remove the ending at the current position" if pos.isout(): Trace.error('No ending out of bounds') return '' ending = self.findending(pos) if not ending: Trace.error('No ending at ' + pos.current()) return '' for each in reversed(self.endings): self.endings.remove(each) if each == ending: return each.ending elif not each.optional: Trace.error('Removed non-optional ending ' + each) Trace.error('No endings left') return '' def findending(self, pos): "Find the ending at the current position" if len(self.endings) == 0: return None for index, ending in enumerate(reversed(self.endings)): if ending.checkin(pos): return ending if not ending.optional: return None return None def checkpending(self): "Check if there are any pending endings" if len(self.endings) != 0: Trace.error('Pending ' + unicode(self) + ' left open') def __unicode__(self): "Printable representation" string = 'endings [' for ending in self.endings: string += unicode(ending) + ',' if len(self.endings) > 0: string = string[:-1] return string + ']' class PositionEnding(object): "An ending for a parsing position" def __init__(self, ending, optional): self.ending = ending self.optional = optional def checkin(self, pos): "Check for the ending" return pos.checkfor(self.ending) def __unicode__(self): "Printable representation" string = 'Ending ' + self.ending if self.optional: string += ' (optional)' return string class Position(Globable): """A position in a text to parse. Including those in Globable, functions to implement by subclasses are: skip(), identifier(), extract(), isout() and current().""" def __init__(self): Globable.__init__(self) def skip(self, string): "Skip a string" Trace.error('Unimplemented skip()') def identifier(self): "Return an identifier for the current position." Trace.error('Unimplemented identifier()') return 'Error' def extract(self, length): "Extract the next string of the given length, or None if not enough text," "without advancing the parse position." Trace.error('Unimplemented extract()') return None def checkfor(self, string): "Check for a string at the given position." return string == self.extract(len(string)) def checkforlower(self, string): "Check for a string in lower case." extracted = self.extract(len(string)) if not extracted: return False return string.lower() == self.extract(len(string)).lower() def skipcurrent(self): "Return the current character and skip it." current = self.current() self.skip(current) return current def next(self): "Advance the position and return the next character." self.skipcurrent() return self.current() def checkskip(self, string): "Check for a string at the given position; if there, skip it" if not self.checkfor(string): return False self.skip(string) return True def error(self, message): "Show an error message and the position identifier." Trace.error(message + ': ' + self.identifier()) class TextPosition(Position): "A parse position based on a raw text." def __init__(self, text): "Create the position from elyxer.some text." Position.__init__(self) self.pos = 0 self.text = text self.checkbytemark() def skip(self, string): "Skip a string of characters." self.pos += len(string) def identifier(self): "Return a sample of the remaining text." length = 30 if self.pos + length > len(self.text): length = len(self.text) - self.pos return '*' + self.text[self.pos:self.pos + length] + '*' def isout(self): "Find out if we are out of the text yet." return self.pos >= len(self.text) def current(self): "Return the current character, assuming we are not out." return self.text[self.pos] def extract(self, length): "Extract the next string of the given length, or None if not enough text." if self.pos + length > len(self.text): return None return self.text[self.pos : self.pos + length] class FilePosition(Position): "A parse position based on an underlying file." def __init__(self, filename): "Create the position from a file." Position.__init__(self) self.reader = LineReader(filename) self.pos = 0 self.checkbytemark() def skip(self, string): "Skip a string of characters." length = len(string) while self.pos + length > len(self.reader.currentline()): length -= len(self.reader.currentline()) - self.pos + 1 self.nextline() self.pos += length def currentline(self): "Get the current line of the underlying file." return self.reader.currentline() def nextline(self): "Go to the next line." self.reader.nextline() self.pos = 0 def linenumber(self): "Return the line number of the file." return self.reader.linenumber + 1 def identifier(self): "Return the current line and line number in the file." before = self.reader.currentline()[:self.pos - 1] after = self.reader.currentline()[self.pos:] return 'line ' + unicode(self.getlinenumber()) + ': ' + before + '*' + after def isout(self): "Find out if we are out of the text yet." if self.pos > len(self.reader.currentline()): if self.pos > len(self.reader.currentline()) + 1: Trace.error('Out of the line ' + self.reader.currentline() + ': ' + unicode(self.pos)) self.nextline() return self.reader.finished() def current(self): "Return the current character, assuming we are not out." if self.pos == len(self.reader.currentline()): return '\n' if self.pos > len(self.reader.currentline()): Trace.error('Out of the line ' + self.reader.currentline() + ': ' + unicode(self.pos)) return '*' return self.reader.currentline()[self.pos] def extract(self, length): "Extract the next string of the given length, or None if not enough text." if self.pos + length > len(self.reader.currentline()): return None return self.reader.currentline()[self.pos : self.pos + length] files = list() def getreader(filename): "Get a reader for lines" if filename in files: # already parsed; skip return None files.append(filename) return LineReader(filename) def readargs(args): "Read arguments from the command line" del args[0] if len(args) == 0: usage() return None, None if args[0] == '-h' or args[0] == '--help': usage() return None, None reader = getreader(args[0]) del args[0] fileout = sys.stdout if len(args) > 0: fileout = args[0] del args[0] if len(args) > 0: usage() return writer = LineWriter(fileout) return reader, writer def usage(): "Show command line help." Trace.error('Usage: loremipsumize.py filein [fileout]') Trace.error('Mask your document using nonsensical words (Lorem Ipsum).') Trace.error('Part of the eLyXer package (http://elyxer.nongnu.org/).') Trace.error(' Options:') Trace.error(' --help: show this message and quit.') return class LoremIpsumizer(object): starts = '@\\' def loremipsumize(self, reader, writer): "Convert all texts longer than two words to 'lorem ipsum'." if not reader: return while not reader.finished(): line = self.processline(reader.currentline()) writer.writeline(line) reader.nextline() reader.close() def processline(self, line): "Process a single line and return the result." if len(line) == 0: return '' if line[0] in LoremIpsumizer.starts: return line pos = TextPosition(line) result = '' while not pos.finished(): result += self.parsepos(pos) return result def parsepos(self, pos): "Parse the current position, return the result." if pos.current().isalpha() or pos.current().isdigit(): alpha = pos.glob(lambda current: current.isalpha() or current.isspace() or current.isdigit()) if len(alpha.split()) > 2: return "lorem ipsum" return alpha if pos.current().isspace(): return pos.skipspace() return pos.skipcurrent() reader, writer = readargs(sys.argv) if reader: LoremIpsumizer().loremipsumize(reader, writer) writer.close() elyxer-1.2.5/convert-guides0000755000175000017500000000250712074107030015217 0ustar chennochenno#!/bin/bash # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # Alex 20100131: convert all LyX guides # convert all LyX files in the given directory and its subdirectories report="\nConversion errors:\n" function convertall { for file in "$@"; do name=$(dirname "$file")/$(basename "$file" .lyx) ./elyxer.py --quiet --css ../docs/lyx.css "$name.lyx" "$name.html" result=$? if [ $result == "0" ]; then echo "$name.lyx OK"; fi if [ $result != "0" ]; then echo "$name.lyx KO" report="$report conversion of $name.lyx failed\n" fi done } echo "Converting all LyX guides in $1" convertall $1/*.lyx convertall $1/**/*.lyx echo -e $report elyxer-1.2.5/create-version0000755000175000017500000000471312117066524015222 0ustar chennochenno#!/bin/bash # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # Alex 20090316: create a release VERSION=$(./elyxer.py --hardversion) DATE=$(./elyxer.py --versiondate) echo "Creating version $VERSION from $DATE" # Insert version date in changelog src/textchange.py "unreleased" $DATE docs/changelog.lyx ./elyxer.py --title="eLyXer changelog" --css "lyx.css" docs/changelog.lyx docs/changelog.html # Tag and push code git tag -a -m "Version $VERSION from $DATE to be released" $VERSION git push # Add version to setup.py for PyPI cp src/setup.py setup.py src/textchange.py "unknown" $VERSION setup.py # make compressed files rm -rf dist/elyxer-$VERSION mkdir -p dist/elyxer-$VERSION rsync -a --exclude "build" --exclude "dist" \ --exclude ".git" --exclude "samples" \ --exclude "docs/cvs" --exclude "patch" \ --exclude "docs/jsMath" --exclude "docs/MathJax" \ --exclude "extras" --exclude "open-env" \ --exclude "test/*test.html" --exclude "test/subdir/*test.html" \ --exclude "test/parts/*part-test*.html" \ --exclude "docs/#*#" \ . dist/elyxer-$VERSION/ cd dist/elyxer-$VERSION find . -name "*.pyc" | xargs rm -f find . -name "*.swp" | xargs rm -f find . -name "*.lyx~" | xargs rm -f find . -name "#*#" | xargs rm -f cd .. tar -czf elyxer-$VERSION.tar.gz elyxer-$VERSION rm -f elyxer-$VERSION.zip zip -qr elyxer-$VERSION.zip elyxer-$VERSION/* # Sign packages # gpg -b elyxer-$VERSION.tar.gz # gpg -b elyxer-$VERSION.zip # Upload to savannah # scp elyxer-$VERSION.tar.gz elyxer-$VERSION.tar.gz.sig alexfernandez@dl.sv.nongnu.org:/releases/elyxer/ # scp elyxer-$VERSION.zip elyxer-$VERSION.zip.sig alexfernandez@dl.sv.nongnu.org:/releases/elyxer/ # Upload docs cd ../docs ./upload.sh cd .. # Register with the PyPI python setup.py register elyxer-1.2.5/make0000755000175000017500000000627512074107030013204 0ustar chennochenno#!/bin/bash # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # Alex 20090310: make script to generate "binary" # create executable files cd src ./exportconfig.py py ./coalesce.py load-elyxer.py ../elyxer.py ./coalesce.py loremipsumize.py ../loremipsumize.py ./coalesce.py math2html.py ../math2html.py ./licensify.py freebsd-license ../math2html.py cd .. chmod 755 elyxer.py chmod 755 loremipsumize.py chmod 755 math2html.py # create CSS files cd src ./coalesce.py css/master.css ../docs/lyx.css ./coalesce.py css/math.css ../docs/math.css ./licensify.py css/freebsd-license.css ../docs/math.css cd .. # internationalize cd src ./exportconfig.py po cd ../po for file in *.po; do lang=$(basename "$file" .po) mkdir -p locale/$lang/LC_MESSAGES msgfmt -o locale/$lang/LC_MESSAGES/elyxer.mo $lang.po done cd .. # remove artifacts rm -f docs/*.lyx~ rm -f test/*.lyx~ rm -f test/subdir/*.lyx~ # prepare documentation ./elyxer.py --title "eLyXer User Guide" --css "lyx.css" docs/userguide.lyx docs/userguide.html ./elyxer.py --tocfor "userguide.html" --target "contents" --css "toc.css" docs/userguide.lyx docs/userguide-toc.html ./elyxer.py --title="eLyxer Developer Guide" --css "lyx.css" docs/devguide.lyx docs/devguide.html ./elyxer.py --title=eLyXer --css "lyx.css" docs/index.lyx docs/index.html ./elyxer.py --title="eLyXer changelog" --css "lyx.css" docs/changelog.lyx docs/changelog.html ./elyxer.py --title="eLyxer Math Showcase (non-Unicode edition)" --css "lyx.css" docs/math.lyx docs/math.html ./elyxer.py --title="eLyxer Math Showcase (Unicode edition)" --unicode --css "lyx.css" docs/math.lyx docs/math-unicode.html ./elyxer.py --title="eLyxer Math Showcase (ISO-8859-15 edition)" --iso885915 --css "lyx.css" docs/math.lyx docs/math-iso885915.html ./elyxer.py --title="eLyxer Math Showcase (HTML edition)" --html --css "lyx.css" docs/math.lyx docs/math-html.html ./elyxer.py --title="eLyxer Math Showcase (MathJax remote edition)" --mathjax remote --css "lyx.css" docs/math.lyx docs/math-mathjax.html ./elyxer.py --title="eLyxer Math Showcase (MathJax local edition)" --mathjax "./MathJax" --css "lyx.css" docs/math.lyx docs/math-mathjax-local.html ./elyxer.py --title="eLyxer Math Showcase (Google Charts edition)" --googlecharts --css "lyx.css" docs/math.lyx docs/math-googlecharts.html # insert current version VERSION=$(./elyxer.py --hardversion) DATE=$(./elyxer.py --versiondate) cd src ./textchange.py "the latest version" "the latest version $VERSION, created on $DATE," ../docs/index.html cd .. # run the test suite ./run-tests elyxer-1.2.5/forks/0000755000175000017500000000000012117067533013466 5ustar chennochennoelyxer-1.2.5/forks/jras-elyxer/0000755000175000017500000000000012117061350015722 5ustar chennochennoelyxer-1.2.5/forks/jras-elyxer/LICENSE0000644000175000017500000010451312117061342016734 0ustar chennochenno GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. 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 How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software: 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 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 GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: Copyright (C) This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an "about box". You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see . The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read . elyxer-1.2.5/forks/jras-elyxer/po/0000755000175000017500000000000012117061350016340 5ustar chennochennoelyxer-1.2.5/forks/jras-elyxer/po/en.po0000644000175000017500000000477212117061342017315 0ustar chennochenno# English translations for PACKAGE package. # eLyXer version 1.0.4 # Released on 2010-10-16 # Contact: Alex Fernández # This file is distributed under the same license as the eLyXer package. # (C) 2010 chenno . # msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "PO-Revision-Date: 2010-10-16 19:04+0200\n" "Last-Translator: chenno \n" "Language-Team: English\n" "Language: en\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=ASCII\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: Subsubsection msgid "Subsubsection" msgstr "Subsubsection" #: figure msgid "figure" msgstr "figure" #: abstract msgid "Abstract" msgstr "Abstract" #: jsmath-warning msgid "Warning: " msgstr "Warning: " #: up msgid "Up" msgstr "Up" #: Book msgid "Book" msgstr "Book" #: jsmath-enable msgid "Please enable JavaScript on your browser." msgstr "Please enable JavaScript on your browser." #: Subsection msgid "Subsection" msgstr "Subsection" #: list-algorithm msgid "List of Algorithms" msgstr "List of Algorithms" #: Appendix msgid "Appendix" msgstr "Appendix" #: index msgid "Index" msgstr "Index" #: bibliography msgid "Bibliography" msgstr "Bibliography" #: float-algorithm msgid "Algorithm " msgstr "Algorithm " #: next msgid "Next" msgstr "Next" #: list-table msgid "List of Tables" msgstr "List of Tables" #: Part msgid "Part" msgstr "Part" #: generated-by msgid "Document generated by " msgstr "Document generated by " #: toc msgid "Table of Contents" msgstr "Table of Contents" #: prev msgid "Prev" msgstr "Prev" #: Section msgid "Section" msgstr "Section" #: Chapter msgid "Chapter" msgstr "Chapter" #: list-tableau msgid "List of Tableaux" msgstr "List of Tableaux" #: generated-on msgid " on " msgstr " on " #: float-tableau msgid "Tableau " msgstr "Tableau " #: Paragraph msgid "Paragraph" msgstr "Paragraph" #: list-figure msgid "List of Figures" msgstr "List of Figures" #: main-page msgid "Main page" msgstr "Main page" #: float-listing msgid "Listing " msgstr "Listing " #: on-page msgid " on page " msgstr " on page " #: nomenclature msgid "Nomenclature" msgstr "Nomenclature" #: float-table msgid "Table " msgstr "Table " #: float-figure msgid "Figure " msgstr "Figure " #: toc-for msgid "Contents for " msgstr "Contents for " #: jsmath-requires msgid " requires JavaScript to correctly process the mathematics on this page. " msgstr " requires JavaScript to correctly process the mathematics on this page. " elyxer-1.2.5/forks/jras-elyxer/po/nl.po0000644000175000017500000000510712117061342017315 0ustar chennochenno# Dutch translations for PACKAGE package. # eLyXer version 0.42 # Released on 2010-02-15 # Contact: Alex Fernández # This file is distributed under the same license as the eLyXer package. # (C) 2010 Hans Bezemer, Alex Fernández. # msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "PO-Revision-Date: 2010-03-12 21:17+0100\n" "Last-Translator: Hans Bezemer\n" "Language-Team: Dutch\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=ASCII\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: Subsubsection msgid "Subsubsection" msgstr "Subsubsectie" #: figure msgid "figure" msgstr "figuur" #: abstract msgid "Abstract" msgstr "Samenvatting" #: jsmath-warning msgid "Warning: " msgstr "Waarschuwing: " #: up msgid "Up" msgstr "Terug" #: Book msgid "Book" msgstr "Boek" #: jsmath-enable msgid "Please enable JavaScript on your browser." msgstr "Activeer Javascript in uw browser." #: Subsection msgid "Subsection" msgstr "Subsectie" #: list-algorithm msgid "List of Algorithms" msgstr "Lijst van algoritmen" #: index msgid "Index" msgstr "Index" #: bibliography msgid "Bibliography" msgstr "Bibliografie" #: references msgid "References" msgstr "Referenties" #: float-algorithm msgid "Algorithm " msgstr "Algoritme " #: next msgid "Next" msgstr "Volgende" #: list-table msgid "List of Tables" msgstr "Lijst van tabellen" #: Part msgid "Part" msgstr "Deel" #: toc msgid "Table of Contents" msgstr "Inhoudsopgave" #: prev msgid "Prev" msgstr "Vorige" #: Section msgid "Section" msgstr "Sectie" #: Chapter msgid "Chapter" msgstr "Hoofdstuk" #: list-tableau msgid "List of Tableaux" msgstr "Lijst van Tableaux" #: float-tableau msgid "Tableau " msgstr "Tableau " #: Paragraph msgid "Paragraph" msgstr "Paragraaf" #: list-figure msgid "List of Figures" msgstr "Lijst van figuren" #: float-listing msgid "Listing " msgstr "Listing " #: on-page msgid " on page " msgstr " op pagina " #: nomenclature msgid "Nomenclature" msgstr "Verklaring van symbolen" #: float-table msgid "Table " msgstr "Tabel " #: float-figure msgid "Figure " msgstr "Figuur " #: jsmath-requires msgid " requires JavaScript to correctly process the mathematics on this page. " msgstr " om de formules op deze bladzijde correct weer te geven is Javascript benodigd. " #: generated-by msgid "Document generated by " msgstr "Document gegenereerd door " #: generated-on msgid " on " msgstr " op " #: toc-for msgid "Contents for " msgstr "Inhoud van " #: main-page msgid "Main page" msgstr "Hoofdpagina" #: Appendix msgid "Appendix" msgstr "Appendix" elyxer-1.2.5/forks/jras-elyxer/po/createlocale.sh0000755000175000017500000000171412117061342021326 0ustar chennochenno#!/bin/bash # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # Alex 20100218: create locale file # create executable if test -z "$1" then echo "Usage: ./createlocale.sh my, creates my.po for locale my." exit fi msginit --locale=$1 --input=../src/conf/elyxer.pot elyxer-1.2.5/forks/jras-elyxer/po/es.po0000644000175000017500000000522712117061342017316 0ustar chennochenno# Spanish translations for eLyXer package # Traducciones al español para el paquete eLyXer. # eLyXer version 0.40 # Released on 2010-01-12 # Contact: Alex Fernández # This file is distributed under the same license as the eLyXer package. # (C) 2010 chenno . # msgid "" msgstr "" "Project-Id-Version: eLyXer 0.40\n" "PO-Revision-Date: 2010-01-12 23:50+0100\n" "Last-Translator: chenno \n" "Language-Team: Spanish\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: Subsubsection msgid "Subsubsection" msgstr "Subsubsección" #: figure msgid "figure" msgstr "figura" #: abstract msgid "Abstract" msgstr "Resumen" #: jsmath-warning msgid "Warning: " msgstr "Aviso: " #: up msgid "Up" msgstr "Arriba" #: Book msgid "Book" msgstr "Libro" #: jsmath-enable msgid "Please enable JavaScript on your browser." msgstr "Por favor, habilite JavaScript en su navegador." #: Subsection msgid "Subsection" msgstr "Subsección" #: list-algorithm msgid "List of Algorithms" msgstr "Índice de algoritmos" #: index msgid "Index" msgstr "Índice alfabético" #: bibliography msgid "Bibliography" msgstr "Bibliografía" #: references msgid "References" msgstr "Referencias" #: float-algorithm msgid "Algorithm " msgstr "Algoritmo " #: next msgid "Next" msgstr "Siguiente" #: list-table msgid "List of Tables" msgstr "Índice de tablas" #: Part msgid "Part" msgstr "Parte" #: toc msgid "Table of Contents" msgstr "Índice general" #: prev msgid "Prev" msgstr "Anterior" #: Section msgid "Section" msgstr "Sección" #: Chapter msgid "Chapter" msgstr "Capítulo" #: list-tableau msgid "List of Tableaux" msgstr "Lista de tablas" #: float-tableau msgid "Tableau " msgstr "Tabla " #: Paragraph msgid "Paragraph" msgstr "Párrafo" #: list-figure msgid "List of Figures" msgstr "Índice de figuras" #: float-listing msgid "Listing " msgstr "Listado " #: on-page msgid " on page " msgstr " en la página " #: nomenclature msgid "Nomenclature" msgstr "Nomenclatura" #: float-table msgid "Table " msgstr "Tabla " #: float-figure msgid "Figure " msgstr "Figura " #: jsmath-requires msgid " requires JavaScript to correctly process the mathematics on this page. " msgstr " requiere JavaScript para procesar las fórmulas matemáticas de la página. " #: generated-by msgid "Document generated by " msgstr "Documento generado con " #: generated-on msgid " on " msgstr " en " #: toc-for msgid "Contents for " msgstr "Contenido de " #: main-page msgid "Main page" msgstr "Página principal" #: Appendix msgid "Appendix" msgstr "Apéndice" elyxer-1.2.5/forks/jras-elyxer/po/fr.po0000644000175000017500000000515412117061342017315 0ustar chennochenno# French translations for PACKAGE package. # eLyXer version 0.42 # Released on 2010-02-15 # Contact: Alex Fernández # This file is distributed under the same license as the eLyXer package. # (C) 2010 Sara Teinturier, Alex Fernández. # msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "PO-Revision-Date: 2010-02-18 00:13+0100\n" "Last-Translator: Sara Teinturier\n" "Language-Team: French\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" #: Subsubsection msgid "Subsubsection" msgstr "SousSousSection" #: figure msgid "figure" msgstr "Figure" #: abstract msgid "Abstract" msgstr "Résumé" #: jsmath-warning msgid "Warning: " msgstr "Erreur: Javascript est nécessaire pour afficher correctement les fonctionnalités de " #: up msgid "Up" msgstr "Monter d'un niveau" #: Book msgid "Book" msgstr "Livre" #: jsmath-enable msgid "Please enable JavaScript on your browser." msgstr "Merci d'activer JavaScript dans votre navigateur." #: Subsection msgid "Subsection" msgstr "SousSection" #: list-algorithm msgid "List of Algorithms" msgstr "Liste des algorithmes" #: index msgid "Index" msgstr "Index" #: bibliography msgid "Bibliography" msgstr "Bibliographie" #: references msgid "References" msgstr "Références" #: float-algorithm msgid "Algorithm " msgstr "Algorithme " #: next msgid "Next" msgstr "Suivant" #: list-table msgid "List of Tables" msgstr "List des tables" #: Part msgid "Part" msgstr "Partie" #: toc msgid "Table of Contents" msgstr "Table des matières" #: prev msgid "Prev" msgstr "Précédent" #: Section msgid "Section" msgstr "Section" #: Chapter msgid "Chapter" msgstr "Chapitre" #: list-tableau msgid "List of Tableaux" msgstr "Liste des tableaux" #: float-tableau msgid "Tableau " msgstr "Tableau " #: Paragraph msgid "Paragraph" msgstr "Paragraphe" #: list-figure msgid "List of Figures" msgstr "Table des figures" #: float-listing msgid "Listing " msgstr "Listing " #: on-page msgid " on page " msgstr " page " #: nomenclature msgid "Nomenclature" msgstr "Glossaire" #: float-table msgid "Table " msgstr "Table " #: float-figure msgid "Figure " msgstr "Figure " #: jsmath-requires msgid " requires JavaScript to correctly process the mathematics on this page. " msgstr ". " #: generated-by msgid "Document generated by " msgstr "Document generated by " #: generated-on msgid " on " msgstr " le " #: toc-for msgid "Contents for " msgstr "Tables des matières du " #: main-page msgid "Main page" msgstr "Page principale" #: Appendix msgid "Appendix" msgstr "Annexe" elyxer-1.2.5/forks/jras-elyxer/po/de.po0000644000175000017500000000536512117061342017302 0ustar chennochenno# German translations for eLyXer package # Deutsch. # eLyXer version 0.40 # Released on 2010-01-12 # Contact: Alex Fernández # This file is distributed under the same license as the eLyXer package. # (C) 2010 Uwe Stöhr . # msgid "" msgstr "" "Project-Id-Version: eLyXer 0.40\n" "PO-Revision-Date: 2010-01-12 02:37+0100\n" "Last-Translator: Uwe Stöhr \n" "Language-Team: Deutsch de>\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "POT-Creation-Date: \n" "X-Poedit-Language: German\n" "X-Poedit-Country: GERMANY\n" #: Subsubsection msgid "Subsubsection" msgstr "Unterunterabschnitt" #: figure msgid "figure" msgstr "Abbildung" #: abstract msgid "Abstract" msgstr "Abstract" #: jsmath-warning msgid "Warning: " msgstr "Warnung: " #: up msgid "Up" msgstr "Oben" #: Book msgid "Book" msgstr "Buck" #: jsmath-enable msgid "Please enable JavaScript on your browser." msgstr "Bitte aktivieren Sie JavaScript in Ihrem Browser." #: Subsection msgid "Subsection" msgstr "Unterabschnitt" #: list-algorithm msgid "List of Algorithms" msgstr "Verzeichnis der Algorithmen" #: index msgid "Index" msgstr "Stichwortverzeichnis" #: bibliography msgid "Bibliography" msgstr "Bibliografie" #: references msgid "References" msgstr "Literatur" #: float-algorithm msgid "Algorithm" msgstr "Algorithmus" #: next msgid "Next" msgstr "Weiter" #: list-table msgid "List of Tables" msgstr "Tabellenverzeichnis" #: Part msgid "Part" msgstr "Teil" #: toc msgid "Table of Contents" msgstr "Inhaltsverzeichnis" #: prev msgid "Prev" msgstr "Zurück" #: Section msgid "Section" msgstr "Abschnitt" #: Chapter msgid "Chapter" msgstr "Kapitel" #: list-tableau msgid "List of Tableaux" msgstr "Tabellenverzeichnis" #: float-tableau msgid "Tableau " msgstr "Tabelle" #: Paragraph msgid "Paragraph" msgstr "Paragraph" #: list-figure msgid "List of Figures" msgstr "Abbildungsverzeichnis" #: float-listing msgid "Listing " msgstr "Listing " #: nomenclature msgid "Nomenclature" msgstr "Nomenklatur" #: on-page msgid " on page " msgstr " auf Seite " #: float-table msgid "Table " msgstr "Tabelle" #: float-figure msgid "Figure " msgstr "Abbildung " #: jsmath-requires msgid " requires JavaScript to correctly process the mathematics on this page. " msgstr " Benötigt JavaScript um die Formeln auf dieser Seite darstellen zu können. " #: generated-by msgid "Document generated by " msgstr "Dokument wurde erzeugt von " #: generated-on msgid " on " msgstr " am " #: toc-for msgid "Contents for " msgstr "Inhalt für " #: main-page msgid "Main page" msgstr "Hauptseite" #: Appendix msgid "Appendix" msgstr "Anhang" elyxer-1.2.5/forks/jras-elyxer/po/ru.po0000644000175000017500000000564512117061342017341 0ustar chennochennomsgid "" msgstr "" "Project-Id-Version: elyxer 1.2.3\n" "PO-Revision-Date: 2011-11-11 16:24+0300\n" "Last-Translator: Vladimir Ermakov \n" "Language-Team: Russian\n" "Language: ru\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" "POT-Creation-Date: \n" # eLyXer internationalization file. # Created on 2011-08-31 # Contact: Alex Fernandez # http://elyxer.nongnu.org/ # This file is distributed under the same license as the eLyXer package. # (C) 2010 Alex Fernandez . # #: Subsubsection msgid "Subsubsection" msgstr "Подподраздел" #: figure msgid "figure" msgstr "рисунок" #: abstract msgid "Abstract" msgstr "Аннотация" #: jsmath-warning msgid "Warning: " msgstr "" #: up msgid "Up" msgstr "Вверх" #: Book msgid "Book" msgstr "" #: references msgid "References" msgstr "Список литературы" #: Subsection msgid "Subsection" msgstr "Подраздел" #: list-algorithm msgid "List of Algorithms" msgstr "Список алгоритмов" #: Appendix msgid "Appendix" msgstr "Приложение" #: index msgid "Index" msgstr "Предметный указатель" #: bibliography msgid "Bibliography" msgstr "Библиография" #: list-table msgid "List of Tables" msgstr "Список таблиц" #: next msgid "Next" msgstr "След." #: float-algorithm msgid "Algorithm " msgstr "Алгоритм" #: Part msgid "Part" msgstr "Часть" #: generated-by msgid "Document generated by " msgstr "" #: toc msgid "Table of Contents" msgstr "Содержание" #: prev msgid "Prev" msgstr "Пред." #: Section msgid "Section" msgstr "Раздел" #: Chapter msgid "Chapter" msgstr "Глава" #: list-tableau msgid "List of Tableaux" msgstr "" #: generated-on msgid " on " msgstr "" #: float-tableau msgid "Tableau " msgstr "" #: Paragraph msgid "Paragraph" msgstr "Абзац" #: list-figure msgid "List of Figures" msgstr "Список рисунков" #: main-page msgid "Main page" msgstr "Главная" #: float-listing msgid "Listing " msgstr "Листинг " #: on-page msgid " on page " msgstr " на странице " #: nomenclature msgid "Nomenclature" msgstr "Список обозначений" #: float-table msgid "Table " msgstr "Таблица " #: float-figure msgid "Figure " msgstr "Рисунок " #: toc-for msgid "Contents for " msgstr "Содержание " #: jsmath-enable msgid "Please enable JavaScript on your browser." msgstr "Пожалуйста включите JavaScript." #: footnotes msgid "Footnotes" msgstr "Список сносок" #: jsmath-requires msgid " requires JavaScript to correctly process the mathematics on this page. " msgstr "Для формул необходим JavaScript." elyxer-1.2.5/forks/jras-elyxer/po/locale/0000755000175000017500000000000012117061350017577 5ustar chennochennoelyxer-1.2.5/forks/jras-elyxer/po/locale/nl/0000755000175000017500000000000012117061350020210 5ustar chennochennoelyxer-1.2.5/forks/jras-elyxer/po/locale/nl/LC_MESSAGES/0000755000175000017500000000000012117061350021775 5ustar chennochennoelyxer-1.2.5/forks/jras-elyxer/po/locale/nl/LC_MESSAGES/elyxer.mo0000644000175000017500000000376412117061350023654 0ustar chennochenno$<5\01 6H@   '6 ?I N [e)j     P b oz   ! *6? Wa"f     !# $  " on on page requires JavaScript to correctly process the mathematics on this page. AbstractAlgorithm AppendixBibliographyBookChapterContents for Document generated by Figure IndexList of AlgorithmsList of FiguresList of TableauxList of TablesListing Main pageNextNomenclatureParagraphPartPlease enable JavaScript on your browser.PrevReferencesSectionSubsectionSubsubsectionTable Table of ContentsTableau UpWarning: figureProject-Id-Version: PACKAGE VERSION PO-Revision-Date: 2010-03-12 21:17+0100 Last-Translator: Hans Bezemer Language-Team: Dutch MIME-Version: 1.0 Content-Type: text/plain; charset=ASCII Content-Transfer-Encoding: 8bit Plural-Forms: nplurals=2; plural=(n != 1); op op pagina om de formules op deze bladzijde correct weer te geven is Javascript benodigd. SamenvattingAlgoritme AppendixBibliografieBoekHoofdstukInhoud van Document gegenereerd door Figuur IndexLijst van algoritmenLijst van figurenLijst van TableauxLijst van tabellenListing HoofdpaginaVolgendeVerklaring van symbolenParagraafDeelActiveer Javascript in uw browser.VorigeReferentiesSectieSubsectieSubsubsectieTabel InhoudsopgaveTableau TerugWaarschuwing: figuurelyxer-1.2.5/forks/jras-elyxer/po/locale/fr/0000755000175000017500000000000012117061350020206 5ustar chennochennoelyxer-1.2.5/forks/jras-elyxer/po/locale/fr/LC_MESSAGES/0000755000175000017500000000000012117061350021773 5ustar chennochennoelyxer-1.2.5/forks/jras-elyxer/po/locale/fr/LC_MESSAGES/elyxer.mo0000644000175000017500000000402512117061350023641 0ustar chennochenno$<5\01 6H@   '6 ?I N [e)j     ' .<BKd{   1 C O\ dpV !# $  " on on page requires JavaScript to correctly process the mathematics on this page. AbstractAlgorithm AppendixBibliographyBookChapterContents for Document generated by Figure IndexList of AlgorithmsList of FiguresList of TableauxList of TablesListing Main pageNextNomenclatureParagraphPartPlease enable JavaScript on your browser.PrevReferencesSectionSubsectionSubsubsectionTable Table of ContentsTableau UpWarning: figureProject-Id-Version: PACKAGE VERSION PO-Revision-Date: 2010-02-18 00:13+0100 Last-Translator: Sara Teinturier Language-Team: French MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Plural-Forms: nplurals=2; plural=(n > 1); le page . RésuméAlgorithme AnnexeBibliographieLivreChapitreTables des matières du Document generated by Figure IndexListe des algorithmesTable des figuresListe des tableauxList des tablesListing Page principaleSuivantGlossaireParagraphePartieMerci d'activer JavaScript dans votre navigateur.PrécédentRéférencesSectionSousSectionSousSousSectionTable Table des matièresTableau Monter d'un niveauErreur: Javascript est nécessaire pour afficher correctement les fonctionnalités de Figureelyxer-1.2.5/forks/jras-elyxer/po/locale/es/0000755000175000017500000000000012117061350020206 5ustar chennochennoelyxer-1.2.5/forks/jras-elyxer/po/locale/es/LC_MESSAGES/0000755000175000017500000000000012117061350021773 5ustar chennochennoelyxer-1.2.5/forks/jras-elyxer/po/locale/es/LC_MESSAGES/elyxer.mo0000644000175000017500000000402412117061350023640 0ustar chennochenno$<5\01 6H@   '6 ?I N [e)j     M n v    $6? Q [hq/w    !# $  " on on page requires JavaScript to correctly process the mathematics on this page. AbstractAlgorithm AppendixBibliographyBookChapterContents for Document generated by Figure IndexList of AlgorithmsList of FiguresList of TableauxList of TablesListing Main pageNextNomenclatureParagraphPartPlease enable JavaScript on your browser.PrevReferencesSectionSubsectionSubsubsectionTable Table of ContentsTableau UpWarning: figureProject-Id-Version: eLyXer 0.40 PO-Revision-Date: 2010-01-12 23:50+0100 Last-Translator: chenno Language-Team: Spanish MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Plural-Forms: nplurals=2; plural=(n != 1); en en la página requiere JavaScript para procesar las fórmulas matemáticas de la página. ResumenAlgoritmo ApéndiceBibliografíaLibroCapítuloContenido de Documento generado con Figura Índice alfabéticoÍndice de algoritmosÍndice de figurasLista de tablasÍndice de tablasListado Página principalSiguienteNomenclaturaPárrafoPartePor favor, habilite JavaScript en su navegador.AnteriorReferenciasSecciónSubsecciónSubsubsecciónTabla Índice generalTabla ArribaAviso: figuraelyxer-1.2.5/forks/jras-elyxer/po/locale/de/0000755000175000017500000000000012117061350020167 5ustar chennochennoelyxer-1.2.5/forks/jras-elyxer/po/locale/de/LC_MESSAGES/0000755000175000017500000000000012117061350021754 5ustar chennochennoelyxer-1.2.5/forks/jras-elyxer/po/locale/de/LC_MESSAGES/elyxer.mo0000644000175000017500000000421312117061350023621 0ustar chennochenno$<5\01 6H@   &5 >H M Zd)i    up uM    .9Nj   1  ",;OWjr w  !#   "$ on on page requires JavaScript to correctly process the mathematics on this page. AbstractAlgorithmAppendixBibliographyBookChapterContents for Document generated by Figure IndexList of AlgorithmsList of FiguresList of TableauxList of TablesListing Main pageNextNomenclatureParagraphPartPlease enable JavaScript on your browser.PrevReferencesSectionSubsectionSubsubsectionTable Table of ContentsTableau UpWarning: figureProject-Id-Version: eLyXer 0.40 PO-Revision-Date: 2010-01-12 02:37+0100 Last-Translator: Uwe Stöhr Language-Team: Deutsch de> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Plural-Forms: nplurals=2; plural=(n != 1); POT-Creation-Date: X-Poedit-Language: German X-Poedit-Country: GERMANY am auf Seite Benötigt JavaScript um die Formeln auf dieser Seite darstellen zu können. AbstractAlgorithmusAnhangBibliografieBuckKapitelInhalt für Dokument wurde erzeugt von Abbildung StichwortverzeichnisVerzeichnis der AlgorithmenAbbildungsverzeichnisTabellenverzeichnisTabellenverzeichnisListing HauptseiteWeiterNomenklaturParagraphTeilBitte aktivieren Sie JavaScript in Ihrem Browser.ZurückLiteraturAbschnittUnterabschnittUnterunterabschnittTabelleInhaltsverzeichnisTabelleObenWarnung: Abbildungelyxer-1.2.5/forks/jras-elyxer/po/locale/ru/0000755000175000017500000000000012117061350020225 5ustar chennochennoelyxer-1.2.5/forks/jras-elyxer/po/locale/ru/LC_MESSAGES/0000755000175000017500000000000012117061350022012 5ustar chennochennoelyxer-1.2.5/forks/jras-elyxer/po/locale/ru/LC_MESSAGES/elyxer.mo0000644000175000017500000000415112117061350023660 0ustar chennochenno)  H  !. 6D LV\o   )   $69@2$5J cn'!0@ O#Y } 1 ! *: OZ      on page requires JavaScript to correctly process the mathematics on this page. AbstractAlgorithm AppendixBibliographyChapterContents for Figure FootnotesIndexList of AlgorithmsList of FiguresList of TablesListing Main pageNextNomenclatureParagraphPartPlease enable JavaScript on your browser.PrevReferencesSectionSubsectionSubsubsectionTable Table of ContentsUpfigureProject-Id-Version: elyxer 1.2.3 PO-Revision-Date: 2011-11-11 16:24+0300 Last-Translator: Vladimir Ermakov Language-Team: Russian Language: ru MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2); POT-Creation-Date: на странице Для формул необходим JavaScript.АннотацияАлгоритмПриложениеБиблиографияГлаваСодержание Рисунок Список сносокПредметный указательСписок алгоритмовСписок рисунковСписок таблицЛистинг ГлавнаяСлед.Список обозначенийАбзацЧастьПожалуйста включите JavaScript.Пред.Список литературыРазделПодразделПодподразделТаблица СодержаниеВверхрисунокelyxer-1.2.5/forks/jras-elyxer/po/locale/en/0000755000175000017500000000000012117061350020201 5ustar chennochennoelyxer-1.2.5/forks/jras-elyxer/po/locale/en/LC_MESSAGES/0000755000175000017500000000000012117061350021766 5ustar chennochennoelyxer-1.2.5/forks/jras-elyxer/po/locale/en/LC_MESSAGES/elyxer.mo0000644000175000017500000000365012117061350023637 0ustar chennochenno#4/L  Ha ju ~  ! & 3=)Blq y    HA JU ^kp x   )"LQ Y dry !  #  "   on on page requires JavaScript to correctly process the mathematics on this page. AbstractAlgorithm AppendixBibliographyBookChapterContents for Document generated by Figure IndexList of AlgorithmsList of FiguresList of TableauxList of TablesListing Main pageNextNomenclatureParagraphPartPlease enable JavaScript on your browser.PrevSectionSubsectionSubsubsectionTable Table of ContentsTableau UpWarning: figureProject-Id-Version: PACKAGE VERSION PO-Revision-Date: 2010-10-16 19:04+0200 Last-Translator: chenno Language-Team: English Language: en MIME-Version: 1.0 Content-Type: text/plain; charset=ASCII Content-Transfer-Encoding: 8bit Plural-Forms: nplurals=2; plural=(n != 1); on on page requires JavaScript to correctly process the mathematics on this page. AbstractAlgorithm AppendixBibliographyBookChapterContents for Document generated by Figure IndexList of AlgorithmsList of FiguresList of TableauxList of TablesListing Main pageNextNomenclatureParagraphPartPlease enable JavaScript on your browser.PrevSectionSubsectionSubsubsectionTable Table of ContentsTableau UpWarning: figureelyxer-1.2.5/forks/jras-elyxer/README.md0000644000175000017500000001101712117061342017202 0ustar chennochennoeLyXer -- convert LyX source files to HTML output. Introduction ============ eLyXer converts a LyX source file to a HTML page. Full documentation in HTML format can be found at docs/index.html, or on the web: http://www.nongnu.org/elyxer/ Installation ============ Quick installation guide (for the impatient): * download the latest version from http://www.nongnu.org/elyxer/, * decompress the .zip or .tar.gz * and install it using the provided script install.py as root: # ./install.py or on Windows: > python install.py To install eLyXer first download a compressed version from http://www.nongnu.org/elyxer/ You will also need a recent (> 2.4) version of Python on your target machine. For decompression: open a terminal window in the directory that contains the downloaded file and just write at the command line prompt: $ tar -xzf elyxer-[version].tar.gz Or for the .zip version: $ unzip elyxer-[version].zip where [version] should be something like 0.44; the full name might be something like elyxer-0.44.tar.gz. On Windows or Mac OS X you can unzip the file using the graphical tool of your choice. In any case, a directory called elyxer-[version] should appear, where the installer script install.py can be found (along with this README). The recommended installation procedure is to just run this script. On Linux type as root: # ./install.py and similarly for Mac OS X, while for Windows open a console and type: > python install.py Note the you don't need to write the prompt, # or >; the console will print it for you. Double-clicking on install.py should also work if your Python installation is minimally sane. It will tell you as a result to which directory eLyXer has been installed as a binary, which is be the typical result; in this case eLyXer should be run as follows: $ elyxer.py [input file] [output file] or, on Windows: > elyxer.py [input file] [output file] You can test that it works with the --help option: $ elyxer.py --help or, on Windows: > elyxer.py --help Usage and options should then be shown. LyX Integration =============== To integrate eLyXer with LyX you just have to reconfigure LyX, selecting Tools -> Reconfigure from within LyX. For rather old versions of LyX (< 1.6.2) you may have to copy elyxer.py into the LyX directory, and reconfigure it. Later versions will recognize eLyXer automatically, either if you install it using distutils or as a binary. Usage ===== eLyXer can be invoked from the command line as: $ elyxer.py [source file] [destination file] If the source file is omitted then STDIN is used; likewise, if no destination file is specified eLyXer will output to STDOUT. This allows its use in pipes and other flexible configurations. Examples: $ elyxer.py file.lyx file.html converts file.lyx to file.html. Debug messages are shown. $ cat file.lyx | elyxer.py > file.html converts file.lyx to file.html, as before. This time debug messages are not shown. $ elyxer.py file.lyx | grep "
" | wc counts all blockquote paragraphs. $ elyxer.py file.lyx | wget --no-check-certificate --spider -nv -F -i - checks all external links in a document recursively. (Local links will appear as unresolved, but they can be ignored.) Documentation ============= Documentation about eLyXer, including a user guide and a developer guide, can be found in the docs directory. The project is hosted at Savannah.nongnu.org. Be sure to visit the project home page at: http://www.nongnu.org/elyxer/ License ======= eLyXer is Copyright (C) 2009-2011 Alex Fernández. This program is free software: 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 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 GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . math2html (a subset of eLyXer) Copyright (C) 2009-2011 Alex Fernández Released under the terms of the `2-Clause BSD license'_, in short: Copying and distribution of this file, with or without modification, are permitted in any medium without royalty provided the copyright notice and this notice are preserved. This file is offered as-is, without any warranty. .. _2-Clause BSD license: http://www.spdx.org/licenses/BSD-2-Clause Enjoy! elyxer-1.2.5/forks/jras-elyxer/run-tests0000755000175000017500000001462512117061342017625 0ustar chennochenno#!/bin/bash # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # Alex 20090319: run all tests # remove result files from previous test runs rm -f "test/*-test.html" rm -f "test/subdir/*-test.html" # first from the current directory echo "Testing eLyXer -- any text below this line signals an error" for file in test/*.lyx; do name=$(dirname "$file")/$(basename "$file" .lyx) ./elyxer.py --quiet --css ../docs/lyx.css "$name.lyx" "$name-test.html" diff -u --ignore-matching-lines="create-date" "$name-good.html" "$name-test.html" done # now a limited subset of tests from within the directory cd test name="with images-1-5" ../elyxer.py --quiet --css=../docs/lyx.css "$name.lyx" "$name-test.html" diff -u --ignore-matching-lines="create-date" "$name-good.html" "$name-test.html" ../elyxer.py --html --quiet --css ../docs/lyx.css "$name.lyx" "$name-html-test.html" diff -u --ignore-matching-lines="create-date" "$name-html-good.html" "$name-html-test.html" ../elyxer.py --quiet --css ../docs/lyx.css --imageformat ".jpg" "$name.lyx" "$name-jpg-test.html" diff -u --ignore-matching-lines="create-date" "$name-jpg-good.html" "$name-jpg-test.html" ../elyxer.py --quiet --css ../docs/lyx.css --noconvert "$name.lyx" "$name-noconvert-test.html" diff -u --ignore-matching-lines="create-date" "$name-noconvert-good.html" "$name-noconvert-test.html" # test --imageformat copy cd copyimages ../../elyxer.py --quiet --css ../../docs/lyx.css --imageformat "copy" "../$name.lyx" "$name-test.html" diff -u --ignore-matching-lines="create-date" "$name-good.html" "$name-test.html" cd .. # directory tests cd subdir name="image-directory" image="mourning.png" rm -f $image ../../elyxer.py --directory .. --quiet --css ../../docs/lyx.css "$name.lyx" "$name-test.html" diff -u --ignore-matching-lines="create-date" "$name-good.html" "$name-test.html" if [ ! -e $image ]; then echo "$image is missing; bad conversion."; fi name="appendix-1-6" cp -f ../$name.lyx . ../../elyxer.py --copyright --directory .. --quiet --css ../../docs/lyx.css "$name.lyx" "$name-test.html" diff -u --ignore-matching-lines="create-date" "$name-good.html" "$name-test.html" cd .. # test TOC generation name="appendix-1-6" ../elyxer.py --quiet --tocfor "$name-test.html" --css ../docs/toc.css --target contents "$name.lyx" "$name-toc-test.html" diff -u --ignore-matching-lines="create-date" "$name-toc-good.html" "$name-toc-test.html" # test --notoclabels name="toc-book" ../elyxer.py --quiet --notoclabels --css ../docs/lyx.css "$name.lyx" "$name-notoclabels-test.html" diff -u --ignore-matching-lines="create-date" "$name-notoclabels-good.html" "$name-notoclabels-test.html" # test raw generation name="helloworld" ../elyxer.py --quiet --raw "$name.lyx" "$name-raw-test.html" diff -u --ignore-matching-lines="create-date" "$name-raw-good.html" "$name-raw-test.html" # test --css and --embedcss name="helloworld" ../elyxer.py --quiet --css "http://elyxer.nongnu.org/lyx.css" --css ../docs/math.css \ --embedcss test.css "$name.lyx" "$name-embedcss-test.html" diff -u --ignore-matching-lines="create-date" "$name-embedcss-good.html" "$name-embedcss-test.html" # test lowmem generation name="index-1-6" ../elyxer.py --quiet --lowmem --css ../docs/lyx.css "$name.lyx" "$name-lowmem-test.html" diff -u --ignore-matching-lines="create-date" "$name-lowmem-good.html" "$name-lowmem-test.html" # test Python 2.4 generation name="index-1-6" type -P python2.4 &> /dev/null if [ $? = 0 ] ; then python2.4 ../elyxer.py --quiet --css ../docs/lyx.css "$name.lyx" "$name-py2.4-test.html" diff -u --ignore-matching-lines="create-date" "$name-good.html" "$name-py2.4-test.html" else echo "python2.4 not found, cannot test it" fi # test stdin + stdout generation name="footnotes-1-6" cat "$name.lyx" | ../elyxer.py --css ../docs/lyx.css > "$name-stdio-test.html" diff -u --ignore-matching-lines="create-date" "$name-good.html" "$name-stdio-test.html" # test --splitpart generation name="index-1-6" testfiles="parts/$name-part-test*.html" rm -f $testfiles ../elyxer.py --quiet --splitpart 1 --css ../../docs/lyx.css "$name.lyx" "parts/$name-part-test.html" for file in $testfiles; do goodname=${file/"-test"/"-good"} diff -u --ignore-matching-lines="create-date" "$goodname" "$file" done # test TOC generation for --splitpart name="index-1-6" ../elyxer.py --quiet --tocfor "$name-part-test.html" --target "contents" --splitpart 1 --css ../../docs/toc.css "$name.lyx" "parts/$name-toc-test.html" diff -u --ignore-matching-lines="create-date" "parts/$name-toc-good.html" "parts/$name-toc-test.html" # test template generation name="helloworld" ../elyxer.py --quiet --template template.html "$name.lyx" "$name-template-test.html" diff -u --ignore-matching-lines="create-date" "$name-template-good.html" "$name-template-test.html" # test math2html result=$(../math2html.py 'N = \frac{\text{number of apples}}{7}') good='N = (number of apples)/(7)' if [ "$result" != "$good" ] ; then echo "Error in math2html: $result != $good" fi # test title with non-ASCII characters, Debian bug 639712 # http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=639712 name="helloworld" ../elyxer.py --quiet --css ../docs/lyx.css --title "By Fernández" "$name.lyx" "$name-test.html" diff -u --ignore-matching-lines="create-date" --ignore-matching-lines="" "$name-good.html" "$name-test.html" # test simultaneous hover and end in footnotes name="footnotes-1-6" ../elyxer.py --quiet --footnotes hover,end,number --css ../docs/lyx.css "$name.lyx" "$name-hover-end-test.html" diff -u --ignore-matching-lines="create-date" "$name-hover-end-good.html" "$name-hover-end-test.html" �����������������������������������������������������������������������������������������������������������elyxer-1.2.5/forks/jras-elyxer/.gitignore�����������������������������������������������������������0000644�0001750�0001750�00000001102�12117061342�017705� 0����������������������������������������������������������������������������������������������������ustar �chenno��������������������������chenno�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# git-ls-files --others --exclude-from=.git/info/exclude # Lines that start with '#' are comments. # For a project mostly in C, the following would be a good set of # exclude patterns (uncomment them if you want to use them): # *.[oa] *\# *~ *.pyc *.swp *-test.html *-test-*.html po/locale/* test/*.py build/* dist/* samples/* patch/* elyxer.py loremipsumize.py math2html.py setup.py docs/*.html docs/*.css docs/cvs/ docs/MathJax/ docs/jsMath/ config.py elyxer.pot test/copyimages/*.svg test/copyimages/*.png test/copyimages/*.jpg test/copyimages/docs test/subdir/mourning.png ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������elyxer-1.2.5/forks/jras-elyxer/docs/����������������������������������������������������������������0000755�0001750�0001750�00000000000�12117061354�016656� 5����������������������������������������������������������������������������������������������������ustar �chenno��������������������������chenno�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������elyxer-1.2.5/forks/jras-elyxer/docs/index.lyx�������������������������������������������������������0000644�0001750�0001750�00000030334�12117061342�020523� 0����������������������������������������������������������������������������������������������������ustar �chenno��������������������������chenno�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#LyX 1.6.7 created this file. For more info see http://www.lyx.org/ \lyxformat 345 \begin_document \begin_header \textclass article \begin_preamble % eLyXer -- convert LyX source files to HTML output. % % Copyright (C) 2009-2011 Alex Fernández % % This program is free software: 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 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 % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see <http://www.gnu.org/licenses/>. \end_preamble \use_default_options false \language english \inputencoding auto \font_roman default \font_sans default \font_typewriter default \font_default_family default \font_sc false \font_osf false \font_sf_scale 100 \font_tt_scale 100 \graphics default \paperfontsize default \spacing single \use_hyperref false \papersize default \use_geometry false \use_amsmath 1 \use_esint 1 \cite_engine basic \use_bibtopic false \paperorientation portrait \secnumdepth 3 \tocdepth 3 \paragraph_separation indent \defskip medskip \quotes_language english \papercolumns 1 \papersides 1 \paperpagestyle default \tracking_changes false \output_changes false \author "" \author "" \end_header \begin_body \begin_layout Title \begin_inset Graphics filename elyxer.svg lyxscale 50 \end_inset eLyXer \end_layout \begin_layout Quotation \emph on \begin_inset CommandInset href LatexCommand href name "elixir" target "http://www.wordreference.com/definition/elixir" \end_inset , n: a substance believed to cure all ills. \end_layout \begin_layout Standard eLyXer (pronounced \emph on elixir \emph default ) is a LyX to HTML converter. While there are a ton of such projects all over the web, eLyXer has a clear focus on flexibility and elegant output. \end_layout \begin_layout Standard \begin_inset CommandInset href LatexCommand href name "LyX" target "http://www.lyx.org/" \end_inset is a wonderful text editor which produces beautiful PDF files. Internally it exports documents to LaTeX, and from there to PDF. Sadly there is not an equivalent \begin_inset Quotes eld \end_inset export to HTML \begin_inset Quotes erd \end_inset option\SpecialChar \ldots{} Until now! With eLyXer you can convert your master's thesis, learned article, fascinating novel or love letter to a web page that you can then share, publish on the web or import into other text editors. \end_layout \begin_layout Standard The \begin_inset CommandInset href LatexCommand href name "user guide" target "userguide.html" \end_inset can be accessed online. The \begin_inset CommandInset href LatexCommand href name "developer guide" target "devguide.html" \end_inset is recommended reading for people that want to contribute to the development, especially \begin_inset CommandInset href LatexCommand href name "section 3" target "devguide.html#toc-Section-3" \end_inset . For the mathematically inclined: be sure to visit the \begin_inset CommandInset href LatexCommand href name "Math Showcase" target "math.html" \end_inset . \end_layout \begin_layout Subsection* Requirements \end_layout \begin_layout Standard eLyXer is a standalone tool: it does not require that LyX is installed to run. It can convert documents generated with versions of LyX from 1.5.5 through 2.0 (and probably earlier versions). It requires Python 2.3.4, and should work with versions up to 2.6.1. It has been tested to run on Linux, Mac OS X and Windows. \end_layout \begin_layout Standard Resource usage is minimum. Converting UserGuide.lyx ( \begin_inset Formula $154$ \end_inset pages, about \begin_inset Formula $40000$ \end_inset words) takes less than 15 seconds on my Asus EeePC 1000H, which sports an Intel Atom processor at 1.60 GHz. Memory usage is also quite frugal, remaining at about 35 MB even with in-memory processing. \end_layout \begin_layout Standard The output requires XHTML, CSS2 and Unicode; any CSS2-compatible browser should do. Minimum browser versions for some popular programs are: Microsoft Internet Explorer 7, Mozilla Firefox 3, Safari 3 and Chrome 1. \end_layout \begin_layout Subsection* Usage \end_layout \begin_layout Standard eLyXer is a command line tool written in Python. Installation is done using the included installer; just type at the prompt as root: \end_layout \begin_layout LyX-Code \family typewriter \color blue # \color inherit python install.py \end_layout \begin_layout Standard or, on Windows: \end_layout \begin_layout LyX-Code \family typewriter \color blue > \color inherit Python.exe install.py \end_layout \begin_layout Standard Basic usage is as simple as writing at the command line prompt: \end_layout \begin_layout LyX-Code \family typewriter \color blue $ \color inherit elyxer.py document.lyx page.html \end_layout \begin_layout Standard or, on Windows: \end_layout \begin_layout LyX-Code \family typewriter \color blue > \color inherit elyxer.py document.lyx page.html \end_layout \begin_layout Standard where \family typewriter document.lyx \family default is your LyX document, and \family typewriter page.html \family default is the resulting HTML page. Write \end_layout \begin_layout LyX-Code \family typewriter \color blue $ \color inherit elyxer.py --help \end_layout \begin_layout Standard or see the \begin_inset CommandInset href LatexCommand href name "user guide" target "userguide.html" \end_inset for details. \end_layout \begin_layout Subsection* Downloads \end_layout \begin_layout Standard You can download the latest version from the project's \begin_inset CommandInset href LatexCommand href name "download area" target "https://savannah.nongnu.org/files/?group=elyxer" \end_inset . See the \begin_inset CommandInset href LatexCommand href name "change log" target "changelog.html" \end_inset for information about past versions. \end_layout \begin_layout Standard eLyXer (including this page and all accompanying materials) is free software: you can redistribute it and/or modify it under the terms of the \begin_inset CommandInset href LatexCommand href name "GNU General Public License" target "http://www.gnu.org/licenses/gpl-3.0-standalone.html" \end_inset as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. See the \family typewriter LICENSE \family default file for details. \end_layout \begin_layout Standard math2html (and \family typewriter math.css \family default ) is released without warranties or conditions of any kind under the terms of the \begin_inset CommandInset href LatexCommand href name "Apache License, version 2.0" target "http://www.apache.org/licenses/LICENSE-2.0" \end_inset . \end_layout \begin_layout Subsection* Contact \end_layout \begin_layout Standard You can contact the main developer at \begin_inset CommandInset href LatexCommand href name "elyxer@gmail.com" target "elyxer@gmail.com" type "mailto:" \end_inset ; he really likes getting challenging documents and making eLyXer work with them. Any document sample you send will be treated with the utmost confidentiality. \end_layout \begin_layout Standard The author lingers around official LyX mailing lists and monitors for mentions of eLyXer. You can also \begin_inset CommandInset href LatexCommand href name "join" target "http://lists.nongnu.org/mailman/listinfo/elyxer-users" \end_inset the low-volume \begin_inset CommandInset href LatexCommand href name "mailing list" target "elyxer-users@nongnu.org" type "mailto:" \end_inset , where announcements of new versions are always posted. Bugs can be reported at the \begin_inset CommandInset href LatexCommand href name "Savannah page" target "https://savannah.nongnu.org/bugs/?func=additem&group=elyxer" \end_inset ; features can be requested too. Feature requests that fit in will be added to the \begin_inset CommandInset href LatexCommand href name "wish list" target "userguide.html#sub:Wish-List" \end_inset . \end_layout \begin_layout Subsection* Acknowledgments \end_layout \begin_layout Standard This little project is my little contribution back to the wonderful LyX community, for all these years of fruitful use. \end_layout \begin_layout Standard Thanks to \begin_inset CommandInset href LatexCommand href name "Stevan White" target "http://www.zipcon.net/~swhite/resume/" \end_inset for encouraging me to publish the tool. Thanks also to \begin_inset CommandInset href LatexCommand href name "John D. Cook" target "http://www.johndcook.com/" \end_inset , \begin_inset CommandInset href LatexCommand href name "rikal" target "http://community.jedit.org/?q=node/view/1746" \end_inset , \begin_inset CommandInset href LatexCommand href name "Bradley M. Bell" target "http://www.seanet.com/~bradbell/omhelp/stdfun.htm" \end_inset , \begin_inset CommandInset href LatexCommand href name "Markus Kuhn" target "http://www.cl.cam.ac.uk/~mgk25/ucs/examples/TeX.txt" \end_inset , Jens Nöckel, \begin_inset CommandInset href LatexCommand href name "Günter Milde" target "http://milde.users.sourceforge.net/LUCR/Math/" \end_inset and LyX developers Georg Baum, Uwe Stöhr and Jürgen Spitzmüller for their wonderful lists of TeX commands and Unicode equivalents; to \begin_inset CommandInset href LatexCommand href name "FileFormat.info" target "http://www.fileformat.info/" \end_inset for their complete tables of Unicode characters. More thanks go to Christian Ridderström for helping me out right at the start; to Ignacio García for relentless encouragement; to Abdelrazak Younes, Pavel Sanda, Günter Milde, Olivier Ripoll, José Matos, Iain Mac Donald, Uwe Stöhr for their interesting suggestions. Thanks to Uwe Stöhr, Hans Bezemer, Sara Teinturier, Vladimir Ermakov for their translations. Packagers Sven Hoexter (for Debian) and Uwe Stöhr (on Windows) have helped with their work to make it easy to try it out. Olivier Ripoll, Geremy Condra, Simon South, Jack Desert, \begin_inset CommandInset href LatexCommand href name "John Boik" target "http://www.newearthbiomed.org/" \end_inset , Yan Wong, Jose Ramón Álvarez Sánchez, Günter Milde, Pascal Francq, Marco R. Gazzetta have provided quite interesting patches. Davide P. Cervone has been extremely helpful and responsive about jsMath and MathJax integration, while Paul Hunter has also gone beyond the call of duty with his help integrating \begin_inset CommandInset href LatexCommand href name "MathToWeb" target "http://www.mathtoweb.com/" \end_inset (which unfortunately has not been fruitful yet, due to my lack of skill and certainly not to his lack of interest). \end_layout \begin_layout Standard Thanks to Nikos Alexandris, Joachim Kreimer-de Fries (Osnabryg), Richard Talley, Wolfgang Keller, Murray Eisenberg, Robert Orr, a Linux guy in Singapore , Anders Ekberg, Pavel Sanda, Steve Hastings, Sven Hoexter, Xie Chao, Uwe Stöhr, Jürgen Spitzmüller, Olivier Ripoll, Konrad Hofbauer, Eduardo Grosclaude, Ken, Jens Nöckel, \begin_inset CommandInset href LatexCommand href name "Dr Eberhard W Lisse" target "el@lisse.na" type "mailto:" \end_inset , William Crocker, Sara Teinturier, Hans Bezemer, Jack Desert, Hartmut Haase, Rainer Dorsch, Wolfgang Engelmann, Rodrigo Benenson, Stefano Franchi, Steve Litt, Paul Johnson, Yan Wong, Yaron Goland, Francis Girard, Rene de Zwart, Jose Ramón Álvarez Sánchez, Günter Milde, Axel Jacobs, Tiago Pedro Alves-Ferrei ra, Hoy Loper, Bob Alvarez, Tommaso Cucinotta for their testing and bug reporting. \end_layout \begin_layout Standard A silent \begin_inset Quotes eld \end_inset thank you \begin_inset Quotes erd \end_inset goes to all those who downloaded the tool and silently tested it to their satisfaction (or were not bugged enough to write about it). Thanks to those who have criticized the tool for making eLyXer improve every day, if only to prove you wrong. And finally thanks to all those who have helped and yet I am now forgetting about them, for not hating me for it. \end_layout \end_body \end_document ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������elyxer-1.2.5/forks/jras-elyxer/docs/math-unicode.html�����������������������������������������������0000644�0001750�0001750�00000114170�12117061352�022123� 0����������������������������������������������������������������������������������������������������ustar �chenno��������������������������chenno�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> <meta name="generator" content="http://www.nongnu.org/elyxer/"/> <meta name="create-date" content="2013-03-10"/> <link rel="stylesheet" href="lyx.css" type="text/css" media="all"/> <title>eLyxer Math Showcase (Unicode edition)

figure elyxer.png eLyXer Math Showcase

Alex Fernández (elyxer@gmail.com)

1 Introduction

This document is intended as a showcase of the mathematical abilities of eLyXer; for more information be sure to visit the main page.

1.1 Versions

There are several versions of this page:
All of them are generated from the same .lyx source file; they should help you decide which rendering options suit you best.
Also available online is the eLyXer translation of the latest LyX’s detailed Math manual, which contains a lot more examples of LyX maths.

2 Typography

Math formulae use a lot of different symbols and fonts.

2.1 Greek Symbols

Greek symbols are very important in equations: φ, π, Ξ. eLyXer offers a complete set in both upper case: Γ…Ω and lower case: αω. Also the AMS italicized upper case: ΓΩ.

2.2 Math Symbols

eLyXer supports the whole set of math symbols in John D. Cook's list: ∃∂∇ ≥ . It can also render a few more:  ∝  × . You also get all symbols from Markus Kuhn's list: ⊙∐.

2.3 Other Symbols

There are other symbols like arrows:  ←  → , or geometrical shapes: , . eLyXer offers limited support for them. You might also want to use financial symbols in formulae: ¥€$.

2.4 Spacing

Equations look good when items are properly separated. The main separation is the Medium Mathematical Space: x = 3. Note: if you are viewing the non-Unicode version math.html of this page then you are in fact seeing midspaces, which are very similar but not exactly the same: (4)/(18) em for medium mathematical spaces versus (1)/(2) en, where 1 em = 2 en. Try out the Unicode version math-unicode.html — and viceversa. You can check out what version this page is in the page title.
The command \raisebox is useful to, surprisingly, raise a little box,
raisedoverloweredand back.
Like \mbox, it puts its content in a text box. It can also be used just for spacing:
BV.
There are other spacing commands: \hspace: a b, protected space: a b, and (at “block level”) \vspace: a b.
There should be 1 cm of vertical space above this paragraph.

2.5 Fonts

By default, letters denote variables and are taken from the \mathnormal font, which is italic, αx + αy = α(x + y), with the exception of upright capital Greek letters, G ≠ Γ.
Function names should be upright: sin(2π), log(x), tanδ.
Mathematical fonts used in equations include Roman (\mathrm), Sans Serif (\mathsf), Typewriter (\mathtt), Bold (\mathbf), SCRIPT (\mathscr), CALLIGRAPHIC (\mathcal), BLACKBOARD BOLD (\mathbb), and Fraktur (\mathfrak). For the latter, some single characters are translated to their Unicode equivalents: , 𝔽, 𝔉.
Regular text in a formula can be achieved via text font commands like \textrm: 5  to 10, via boxes like \mbox (prevents line breaks): 6  is more than 5, or the AMSmath \text macro (scales like math symbols) basesupersub. The content of an mbox is processed in LaTeX text mode. This allows text font commands, e.g. a switch to sans-serif-bold-italic, or the phonetic alphabet: sfbfit, tipa.
Units should be written upright, either with \mathrm or with macros from the units package, e.g. as simple unit, km, with magnitude, 57 km, with fractional unit, 200 kmh, or with a fraction before the units, 32 km, (7)/(16) s.

3 Numeration

Equations can be numbered, like (1↓)
(1) y = x
And also like (2↓).
(2) x = 3
Some equations can be numbered even if they don’t have a label.
(3) x = 2y
Notice that equation (2↑) comes after (1↑).

4 Simple Structures

Let’s now see a few of the simpler structures that eLyXer can output.

4.1 Fractions

A simple fraction:
(1)/(2).
Inlined: (2)/(3).
A big recursive fraction:
(1)/(1 + (1)/(1 + (1)/(1 + 2x)))
A nice fraction: 56. A non-diminishing fraction containing alignments:
(1)/(1 + (1)/(1 + x) × (1)/(1 + x)).
A similar concept is a binomial coefficient: (A + 1B). It can be prettily presented:
AB + 1.
A symbol can be stacked over another using \stackrel: xR → y. Anything can be stacked:
dx > 3limx,  headheels.

4.2 Limits

limx → ∞f(x) should appear as x → ∞ in italics, and «lim» in plain style. In display mode, a limit must appear below the main symbol:
limx → ∞f(x).
Limits are also used in sums and integrals:
i = 1x,  0f(x) dx
where the sum’s limits should appear below (i = 1) and above () the . The placement of the integral limits depends on the document class: LaTeX standard classes place them right to the . Limits are shown to the right in inline formulae: i = 1x and i = 1x.
The placing of limits can be configured with the \limits and \nolimits macros:
limx → ∞f(x),  i = 1x,  0f(x) dx

4.3 Roots

A square root: (3). A more complex root in a fraction:
(1)/(1 + (2)(1)/(1 + (2)) + ((1)/(2))).
eLyXer can also do higher-order roots: 3(x + y). A devilish case mixing everything we have seen so far:
(78((8)/(4)x) + i = 1x)/(s + 5(((78x + 45y) × (Ω))/(sin(x + 1)) + 38 km)).

5 Complex Structures

In this section we will explore arrays and related constructs.

5.1 Arrays

An inline array a b c d is always shown in the same line. In display mode, the array is shown on its own line:
12 2 3 4 × yx
Apart from that the appearance should be the same.

5.2 Brackets

Arrays are separated by variable-size brackets: a b c d a b c d a b c d a b c d ||| a b c d |||which might also differ on right and left a b c d or use the empty opening a b c d or closing: a b c d |||. There are also fixed-size big brackets, e.g. f.

5.3 Cases

Used to switch between several values.
y =  x i = 0,         x + 1  i < 3 
Cases may have more than two rows:
f(x) =  0  x < 0,         ∞  x = 0        0  x > 0 

5.4 Braces

Values can be underbraced or overbraced.
a − b = b + c + d + e.

6 Macros

Now it’s time for user-defined commands (sometimes called “macros”).
Definitions can be added as macros. Then they can be used in formulae: 1(2). They can accept default parameters. Again, useful in formulae: 4(5).
Other definitions from the preamble can be used: 3(4).
Definitions on the fly are also possible: 7(8), and used with different values: a(b).
elyxer-1.2.5/forks/jras-elyxer/docs/index.html0000644000175000017500000002334112117061354020656 0ustar chennochenno eLyXer

figure elyxer.png eLyXer

elixir, n: a substance believed to cure all ills.
eLyXer (pronounced elixir) is a LyX to HTML converter. While there are a ton of such projects all over the web, eLyXer has a clear focus on flexibility and elegant output.
LyX is a wonderful text editor which produces beautiful PDF files. Internally it exports documents to LaTeX, and from there to PDF. Sadly there is not an equivalent “export to HTML” option… Until now! With eLyXer you can convert your master’s thesis, learned article, fascinating novel or love letter to a web page that you can then share, publish on the web or import into other text editors.
The user guide can be accessed online. The developer guide is recommended reading for people that want to contribute to the development, especially section 3. For the mathematically inclined: be sure to visit the Math Showcase.

Requirements

eLyXer is a standalone tool: it does not require that LyX is installed to run. It can convert documents generated with versions of LyX from 1.5.5 through 2.0 (and probably earlier versions). It requires Python 2.3.4, and should work with versions up to 2.6.1. It has been tested to run on Linux, Mac OS X and Windows.
Resource usage is minimum. Converting UserGuide.lyx (154 pages, about 40000 words) takes less than 15 seconds on my Asus EeePC 1000H, which sports an Intel Atom processor at 1.60 GHz. Memory usage is also quite frugal, remaining at about 35 MB even with in-memory processing.
The output requires XHTML, CSS2 and Unicode; any CSS2-compatible browser should do. Minimum browser versions for some popular programs are: Microsoft Internet Explorer 7, Mozilla Firefox 3, Safari 3 and Chrome 1.

Usage

eLyXer is a command line tool written in Python. Installation is done using the included installer; just type at the prompt as root:
# python install.py
or, on Windows:
> Python.exe install.py
Basic usage is as simple as writing at the command line prompt:
$ elyxer.py document.lyx page.html
or, on Windows:
> elyxer.py document.lyx page.html
where document.lyx is your LyX document, and page.html is the resulting HTML page. Write
$ elyxer.py --help
or see the user guide for details.

Downloads

You can download the latest version 1.2.4, created on 2013-03-10, from the project’s download area. See the change log for information about past versions.
eLyXer (including this page and all accompanying materials) is free software: 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. See the LICENSE file for details.
math2html (and math.css) is released without warranties or conditions of any kind under the terms of the Apache License, version 2.0.

Contact

You can contact the main developer at elyxer@gmail.com; he really likes getting challenging documents and making eLyXer work with them. Any document sample you send will be treated with the utmost confidentiality.
The author lingers around official LyX mailing lists and monitors for mentions of eLyXer. You can also join the low-volume mailing list, where announcements of new versions are always posted. Bugs can be reported at the Savannah page; features can be requested too. Feature requests that fit in will be added to the wish list.

Acknowledgments

This little project is my little contribution back to the wonderful LyX community, for all these years of fruitful use.
Thanks to Stevan White for encouraging me to publish the tool. Thanks also to John D. Cook, rikal, Bradley M. Bell, Markus Kuhn, Jens Nöckel, Günter Milde and LyX developers Georg Baum, Uwe Stöhr and Jürgen Spitzmüller for their wonderful lists of TeX commands and Unicode equivalents; to FileFormat.info for their complete tables of Unicode characters. More thanks go to Christian Ridderström for helping me out right at the start; to Ignacio García for relentless encouragement; to Abdelrazak Younes, Pavel Sanda, Günter Milde, Olivier Ripoll, José Matos, Iain Mac Donald, Uwe Stöhr for their interesting suggestions. Thanks to Uwe Stöhr, Hans Bezemer, Sara Teinturier, Vladimir Ermakov for their translations. Packagers Sven Hoexter (for Debian) and Uwe Stöhr (on Windows) have helped with their work to make it easy to try it out. Olivier Ripoll, Geremy Condra, Simon South, Jack Desert, John Boik, Yan Wong, Jose Ramón Álvarez Sánchez, Günter Milde, Pascal Francq, Marco R. Gazzetta have provided quite interesting patches. Davide P. Cervone has been extremely helpful and responsive about jsMath and MathJax integration, while Paul Hunter has also gone beyond the call of duty with his help integrating MathToWeb (which unfortunately has not been fruitful yet, due to my lack of skill and certainly not to his lack of interest).
Thanks to Nikos Alexandris, Joachim Kreimer-de Fries (Osnabryg), Richard Talley, Wolfgang Keller, Murray Eisenberg, Robert Orr, a Linux guy in Singapore, Anders Ekberg, Pavel Sanda, Steve Hastings, Sven Hoexter, Xie Chao, Uwe Stöhr, Jürgen Spitzmüller, Olivier Ripoll, Konrad Hofbauer, Eduardo Grosclaude, Ken, Jens Nöckel, Dr Eberhard W Lisse, William Crocker, Sara Teinturier, Hans Bezemer, Jack Desert, Hartmut Haase, Rainer Dorsch, Wolfgang Engelmann, Rodrigo Benenson, Stefano Franchi, Steve Litt, Paul Johnson, Yan Wong, Yaron Goland, Francis Girard, Rene de Zwart, Jose Ramón Álvarez Sánchez, Günter Milde, Axel Jacobs, Tiago Pedro Alves-Ferreira, Hoy Loper, Bob Alvarez, Tommaso Cucinotta for their testing and bug reporting.
A silent “thank you” goes to all those who downloaded the tool and silently tested it to their satisfaction (or were not bugged enough to write about it). Thanks to those who have criticized the tool for making eLyXer improve every day, if only to prove you wrong. And finally thanks to all those who have helped and yet I am now forgetting about them, for not hating me for it.
elyxer-1.2.5/forks/jras-elyxer/docs/math.css0000644000175000017500000001116012117061350020314 0ustar chennochenno/* * math2html: convert LaTeX equations to HTML output. * * Copyright (C) 2009,2010 Alex Fernández * * Released under the terms of the `2-Clause BSD license'_, in short: * Copying and distribution of this file, with or without modification, * are permitted in any medium without royalty provided the copyright * notice and this notice are preserved. * This file is offered as-is, without any warranty. * * .. _2-Clause BSD license: http://www.spdx.org/licenses/BSD-2-Clause * * Based on eLyXer: convert LyX source files to HTML output. * http://elyxer.nongnu.org/ */ /* --end-- * CSS file for LaTeX formulas. */ /* Formulas */ .formula { text-align: center; font-family: "DejaVu Serif", serif; margin: 1.2em 0; } span.formula { white-space: nowrap; } div.formula { padding: 0.5ex; margin-left: auto; margin-right: auto; } /* Basic features */ a.eqnumber { display: inline-block; float: right; clear: right; font-weight: bold; } span.unknown { color: #800000; } span.ignored, span.arraydef { display: none; } .formula i { letter-spacing: 0.1ex; } /* Alignment */ .align-left, .align-l { text-align: left; } .align-right, .align-r { text-align: right; } .align-center, .align-c { text-align: center; } /* Structures */ span.overline, span.bar { text-decoration: overline; } .fraction, .fullfraction { display: inline-block; vertical-align: middle; text-align: center; } .fraction .fraction { font-size: 80%; line-height: 100%; } span.numerator { display: block; } span.denominator { display: block; padding: 0ex; border-top: thin solid; } sup.numerator, sup.unit { font-size: 70%; vertical-align: 80%; } sub.denominator, sub.unit { font-size: 70%; vertical-align: -20%; } span.sqrt { display: inline-block; vertical-align: middle; padding: 0.1ex; } sup.root { font-size: 70%; position: relative; left: 1.4ex; } span.radical { display: inline-block; padding: 0ex; font-size: 150%; vertical-align: top; } span.root { display: inline-block; border-top: thin solid; padding: 0ex; vertical-align: middle; } span.symbol { font-size: 125%; } span.bigsymbol { font-size: 150%; } span.largesymbol { font-size: 175%; } span.hugesymbol { font-size: 200%; } span.scripts { display: inline-table; vertical-align: middle; } .script { display: table-row; text-align: left; line-height: 150%; } span.limits { display: inline-table; vertical-align: middle; } .limit { display: table-row; line-height: 95%; } sup.limit, sub.limit { line-height: 150%; } span.symbolover { display: inline-block; text-align: center; position: relative; float: right; right: 100%; bottom: 0.5em; width: 0px; } span.withsymbol { display: inline-block; } span.symbolunder { display: inline-block; text-align: center; position: relative; float: right; right: 80%; top: 0.3em; width: 0px; } /* Environments */ span.array, span.bracketcases, span.binomial, span.environment { display: inline-table; text-align: center; border-collapse: collapse; margin: 0em; vertical-align: middle; } span.arrayrow, span.binomrow { display: table-row; padding: 0ex; border: 0ex; } span.arraycell, span.bracket, span.case, span.binomcell, span.environmentcell { display: table-cell; padding: 0ex 0.2ex; line-height: 99%; border: 0ex; } /* * CSS file for LaTeX formulas, extra stuff: * binomials, vertical braces, stackrel, fonts and colors. */ /* Inline binomials */ span.binom { display: inline-block; vertical-align: middle; text-align: center; font-size: 80%; } span.binomstack { display: block; padding: 0em; } /* Over- and underbraces */ span.overbrace { border-top: 2pt solid; } span.underbrace { border-bottom: 2pt solid; } /* Stackrel */ span.stackrel { display: inline-block; text-align: center; } span.upstackrel { display: block; padding: 0em; font-size: 80%; line-height: 64%; position: relative; top: 0.15em; } span.downstackrel { display: block; vertical-align: bottom; padding: 0em; } /* Fonts */ span.mathsf, span.textsf { font-style: normal; font-family: sans-serif; } span.mathrm, span.textrm { font-style: normal; font-family: serif; } span.text, span.textnormal { font-style: normal; } span.textipa { color: #008080; } span.fraktur { font-family: "Lucida Blackletter", eufm10, blackletter; } span.blackboard { font-family: Blackboard, msbm10, serif; } span.scriptfont { font-family: "Monotype Corsiva", "Apple Chancery", "URW Chancery L", cursive; font-style: italic; } /* Colors */ span.colorbox { display: inline-block; padding: 5px; } span.fbox { display: inline-block; border: thin solid black; padding: 2px; } span.boxed, span.framebox { display: inline-block; border: thin solid black; padding: 5px; } elyxer-1.2.5/forks/jras-elyxer/docs/math-googlecharts.html0000644000175000017500000007254512117061354023171 0ustar chennochenno eLyxer Math Showcase (Google Charts edition)

figure elyxer.png eLyXer Math Showcase

Alex Fernández (elyxer@gmail.com)

1 Introduction

This document is intended as a showcase of the mathematical abilities of eLyXer; for more information be sure to visit the main page.

1.1 Versions

There are several versions of this page:
All of them are generated from the same .lyx source file; they should help you decide which rendering options suit you best.
Also available online is the eLyXer translation of the latest LyX’s detailed Math manual, which contains a lot more examples of LyX maths.

2 Typography

Math formulae use a lot of different symbols and fonts.

2.1 Greek Symbols

Greek symbols are very important in equations: \phi, \pi, \Xi. eLyXer offers a complete set in both upper case: \Gamma\ldots\Omega and lower case: \alpha\ldots\omega. Also the AMS italicized upper case: \varGamma\ldots\varOmega.

2.2 Math Symbols

eLyXer supports the whole set of math symbols in John D. Cook's list: \exists\partial\nabla\geq. It can also render a few more: \propto\times. You also get all symbols from Markus Kuhn's list: \bigodot\amalg.

2.3 Other Symbols

There are other symbols like arrows: \leftarrow\rightarrow, or geometrical shapes: \circ, \square. eLyXer offers limited support for them. You might also want to use financial symbols in formulae: \yen\euro\$.

2.4 Spacing

Equations look good when items are properly separated. The main separation is the Medium Mathematical Space: x=3. Note: if you are viewing the non-Unicode version math.html of this page then you are in fact seeing midspaces, which are very similar but not exactly the same: \frac{4}{18}\mathrm{em} for medium mathematical spaces versus \frac{1}{2}\mathrm{en}, where 1\mathrm{em}=2\mathrm{en}. Try out the Unicode version math-unicode.html — and viceversa. You can check out what version this page is in the page title.
The command \raisebox is useful to, surprisingly, raise a little box,

\raisebox{2mm}{raised}over\raisebox{-2mm}{lowered}\textrm{and back}.
Like \mbox, it puts its content in a text box. It can also be used just for spacing:
\raisebox{5mm}{}B^{V}.
There are other spacing commands: \hspace: a\hspace{4mm}b, protected space: a\ b, and (at “block level”) \vspace: a\vspace{1cm}b.
There should be 1 cm of vertical space above this paragraph.

2.5 Fonts

By default, letters denote variables and are taken from the \mathnormal font, which is italic, \alpha x+\alpha y=\alpha(x+y), with the exception of upright capital Greek letters, G\ne\Gamma.
Function names should be upright: \sin(2\pi),\log(x),\tan\delta.
Mathematical fonts used in equations include \mathrm{Roman} (\mathrm), \mathsf{Sans\: Serif} (\mathsf), \mathtt{Typewriter} (\mathtt), \mathbf{Bold} (\mathbf), \mathscr{SCRIPT} (\mathscr), \mathcal{CALLIGRAPHIC} (\mathcal), \mathbb{BLACKBOARD\: BOLD} (\mathbb), and \mathfrak{Fraktur} (\mathfrak). For the latter, some single characters are translated to their Unicode equivalents: \mathscr{F}, \mathbb{F}, \mathfrak{F}.
Regular text in a formula can be achieved via text font commands like \textrm: 5\:\textrm{to}\:10, via boxes like \mbox (prevents line breaks): 6\mbox{ is more than }5, or the AMSmath \text macro (scales like math symbols) \text{base}_{\text{sub}}^{\text{super}}. The content of an mbox is processed in LaTeX text mode. This allows text font commands, e.g. a switch to sans-serif-bold-italic, or the phonetic alphabet: \mbox{\textbf{\textsf{\textbf{\textit{sfbfit}}}}, \textipa{tipa}}.
Units should be written upright, either with \mathrm or with macros from the units package, e.g. as simple unit, \unit{km}, with magnitude, \unit[57]{km}, with fractional unit, \unitfrac[200]{km}{h}, or with a fraction before the units, \unit[\nicefrac{3}{2}]{km}, \unit[\frac{7}{16}]{s}.

3 Numeration

Equations can be numbered, like () And also like (↓). Some equations can be numbered even if they don’t have a label.
Notice that equation () comes after ().

4 Simple Structures

Let’s now see a few of the simpler structures that eLyXer can output.

4.1 Fractions

A simple fraction:

\frac{1}{2}.
Inlined: \frac{2}{3}.
A big recursive fraction:

\frac{1}{\left(1+\left(\frac{1}{1+\left(\frac{1}{1+2x}\lyxlock\right)}\lyxlock\right)\right)}\lyxlock
A nice fraction: \nicefrac{5}{6}. A non-diminishing fraction containing alignments:

\cfrac{1}{1+\left(\cfrac[l]{1}{1+x}\times\cfrac[r]{1}{1+x}\right)}.
A similar concept is a binomial coefficient: \binom{A+1}{B}. It can be prettily presented:

\dbinom{A}{B+1}.
A symbol can be stacked over another using \stackrel: x\stackrel{R}{\rightarrow}y. Anything can be stacked:

d\stackrel{x>3}{\lim}x,\quad\stackrel{\mathrm{head}}{\mathrm{heels}}.

4.2 Limits

\lim_{x\rightarrow\infty}f(x) should appear as x\rightarrow\infty in italics, and «lim» in plain style. In display mode, a limit must appear below the main symbol:

\lim_{x\rightarrow\infty}\lyxlock f(x).
Limits are also used in sums and integrals:

\sum_{i=1}^{\infty}x,\;\int_{0}^{\infty}f(x)\,\mathrm{d}x
where the sum’s limits should appear below (i=1) and above (\infty) the \sum. The placement of the integral limits depends on the document class: LaTeX standard classes place them right to the \int. Limits are shown to the right in inline formulae: \sum_{i=1}^{\infty}x and \intop_{i=1}^{\infty}x.
The placing of limits can be configured with the \limits and \nolimits macros:

\lim\nolimits _{x\rightarrow\infty}\lyxlock f(x),\;\sum\nolimits _{i=1}^{\infty}x,\;\int\limits _{0}^{\infty}f(x)\,\mathrm{d}x

4.3 Roots

A square root: \sqrt{3}. A more complex root in a fraction:

\frac{1}{\left(1+\sqrt{2}\left(\frac{1}{1+\sqrt{2}}\lyxlock\right)+\sqrt{\frac{1}{2}}\right)}\lyxlock.
eLyXer can also do higher-order roots: \sqrt[3]{x+y}. A devilish case mixing everything we have seen so far:

\frac{\sqrt[\nicefrac{7}{8}]{\frac{8}{4}x}+\sum_{i=1}^{\infty}x}{\sqrt[s+5]{\frac{(78x+45y)\times\sqrt{\Omega}}{\sin(x+1)}+\unit[38]{km}}}\lyxlock.

5 Complex Structures

In this section we will explore arrays and related constructs.

5.1 Arrays

An inline array \left[\begin{array}{cc}
a & b\\
c & d\end{array}\right] is always shown in the same line. In display mode, the array is shown on its own line:

\left[\begin{array}{lc}
12 & 2\\
3 & 4\times y^{x}\end{array}\right]
Apart from that the appearance should be the same.

5.2 Brackets

Arrays are separated by variable-size brackets: \left(\begin{array}{cc}
a & b\\
c & d\end{array}\right) \left[\begin{array}{cc}
a & b\\
c & d\end{array}\right] \left\{ \begin{array}{cc}
a & b\\
c & d\end{array}\right\} \left\langle \begin{array}{cc}
a & b\\
c & d\end{array}\right\rangle \left|\begin{array}{cc}
a & b\\
c & d\end{array}\right|which might also differ on right and left \left(\begin{array}{cc}
a & b\\
c & d\end{array}\right) or use the empty opening \left\{ \begin{array}{cc}
a & b\\
c & d\end{array}\right. or closing: \left.\begin{array}{cc}
a & b\\
c & d\end{array}\right|. There are also fixed-size big brackets, e.g. \bigl\langle f\bigr\rangle.

5.3 Cases

Used to switch between several values.

y=\begin{cases}
x & i=0,\\
x+1 & i<3\end{cases}
Cases may have more than two rows:

f(x)=\begin{cases}
0 & x<0,\\
\infty & x=0\\
0 & x>0\end{cases}

5.4 Braces

Values can be underbraced or overbraced.
\underbrace{a-b}=\overbrace{b+c+d+e}.

6 Macros

Now it’s time for user-defined commands (sometimes called “macros”).
Definitions can be added as macros. Then they can be used in formulae: \stupidroot 12. They can accept default parameters. Again, useful in formulae: \defaultroot.
Other definitions from the preamble can be used: \preambleroot{3}{4}.
Definitions on the fly are also possible: \newcommand{\ontheflyroot}[2]{\sqrt[#1]{#2}}\ontheflyroot{7}{8}, and used with different values: \ontheflyroot{a}{b}.
elyxer-1.2.5/forks/jras-elyxer/docs/math-mathjax-local.html0000644000175000017500000005500112117061354023220 0ustar chennochenno eLyxer Math Showcase (MathJax local edition)

figure elyxer.png eLyXer Math Showcase

Alex Fernández (elyxer@gmail.com)

1 Introduction

This document is intended as a showcase of the mathematical abilities of eLyXer; for more information be sure to visit the main page.

1.1 Versions

There are several versions of this page:
All of them are generated from the same .lyx source file; they should help you decide which rendering options suit you best.
Also available online is the eLyXer translation of the latest LyX’s detailed Math manual, which contains a lot more examples of LyX maths.

2 Typography

Math formulae use a lot of different symbols and fonts.

2.1 Greek Symbols

Greek symbols are very important in equations: , , . eLyXer offers a complete set in both upper case: and lower case: . Also the AMS italicized upper case: .

2.2 Math Symbols

eLyXer supports the whole set of math symbols in John D. Cook's list: . It can also render a few more: . You also get all symbols from Markus Kuhn's list: .

2.3 Other Symbols

There are other symbols like arrows: , or geometrical shapes: , . eLyXer offers limited support for them. You might also want to use financial symbols in formulae: .

2.4 Spacing

Equations look good when items are properly separated. The main separation is the Medium Mathematical Space: . Note: if you are viewing the non-Unicode version math.html of this page then you are in fact seeing midspaces, which are very similar but not exactly the same: for medium mathematical spaces versus , where . Try out the Unicode version math-unicode.html — and viceversa. You can check out what version this page is in the page title.
The command \raisebox is useful to, surprisingly, raise a little box, Like \mbox, it puts its content in a text box. It can also be used just for spacing:
.
There are other spacing commands: \hspace: , protected space: , and (at “block level”) \vspace: .
There should be 1 cm of vertical space above this paragraph.

2.5 Fonts

By default, letters denote variables and are taken from the \mathnormal font, which is italic, , with the exception of upright capital Greek letters, .
Function names should be upright: .
Mathematical fonts used in equations include (\mathrm), (\mathsf), (\mathtt), (\mathbf), (\mathscr), (\mathcal), (\mathbb), and (\mathfrak). For the latter, some single characters are translated to their Unicode equivalents: , , .
Regular text in a formula can be achieved via text font commands like \textrm: , via boxes like \mbox (prevents line breaks): , or the AMSmath \text macro (scales like math symbols) . The content of an mbox is processed in LaTeX text mode. This allows text font commands, e.g. a switch to sans-serif-bold-italic, or the phonetic alphabet: .
Units should be written upright, either with \mathrm or with macros from the units package, e.g. as simple unit, , with magnitude, , with fractional unit, , or with a fraction before the units, , .

3 Numeration

Equations can be numbered, like () And also like (↓). Some equations can be numbered even if they don’t have a label.
Notice that equation () comes after ().

4 Simple Structures

Let’s now see a few of the simpler structures that eLyXer can output.

4.1 Fractions

A simple fraction: Inlined:
A big recursive fraction:
A nice fraction: . A non-diminishing fraction containing alignments:
A similar concept is a binomial coefficient: It can be prettily presented:
A symbol can be stacked over another using \stackrel: . Anything can be stacked:

4.2 Limits

should appear as in italics, and «lim» in plain style. In display mode, a limit must appear below the main symbol:
Limits are also used in sums and integrals: where the sum’s limits should appear below ( ) and above ( ) the . The placement of the integral limits depends on the document class: LaTeX standard classes place them right to the . Limits are shown to the right in inline formulae: and
The placing of limits can be configured with the \limits and \nolimits macros:

4.3 Roots

A square root: A more complex root in a fraction:
eLyXer can also do higher-order roots: . A devilish case mixing everything we have seen so far:

5 Complex Structures

In this section we will explore arrays and related constructs.

5.1 Arrays

An inline array is always shown in the same line. In display mode, the array is shown on its own line: Apart from that the appearance should be the same.

5.2 Brackets

Arrays are separated by variable-size brackets: which might also differ on right and left or use the empty opening or closing: . There are also fixed-size big brackets, e.g. .

5.3 Cases

Used to switch between several values.
Cases may have more than two rows:

5.4 Braces

Values can be underbraced or overbraced.
.

6 Macros

Now it’s time for user-defined commands (sometimes called “macros”).
Definitions can be added as macros. Then they can be used in formulae: . They can accept default parameters. Again, useful in formulae: .
Other definitions from the preamble can be used: .
Definitions on the fly are also possible: , and used with different values: .
elyxer-1.2.5/forks/jras-elyxer/docs/userguide-frameset.html0000644000175000017500000000031412117061342023337 0ustar chennochenno eLyXer User Guide elyxer-1.2.5/forks/jras-elyxer/docs/userguide.lyx0000644000175000017500000032612612117061342021417 0ustar chennochenno#LyX 1.6.7 created this file. For more info see http://www.lyx.org/ \lyxformat 345 \begin_document \begin_header \textclass article \begin_preamble % eLyXer -- convert LyX source files to HTML output. % % Copyright (C) 2009-2011 Alex Fernández % % This program is free software: 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 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 % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . \end_preamble \use_default_options false \language english \inputencoding auto \font_roman default \font_sans default \font_typewriter default \font_default_family default \font_sc false \font_osf false \font_sf_scale 100 \font_tt_scale 100 \graphics default \paperfontsize default \spacing single \use_hyperref false \papersize default \use_geometry false \use_amsmath 1 \use_esint 1 \cite_engine basic \use_bibtopic false \paperorientation portrait \secnumdepth 3 \tocdepth 3 \paragraph_separation indent \defskip medskip \quotes_language english \papercolumns 1 \papersides 1 \paperpagestyle default \tracking_changes false \output_changes false \author "" \author "" \end_header \begin_body \begin_layout Title \begin_inset Graphics filename elyxer.svg lyxscale 50 \end_inset eLyXer User Guide \end_layout \begin_layout Author Alex Fernández (elyxer@gmail.com) \end_layout \begin_layout Standard \begin_inset CommandInset toc LatexCommand tableofcontents \end_inset \end_layout \begin_layout Section The Basics \end_layout \begin_layout Quotation \emph on elixir, n: a substance believed to cure all ills \begin_inset CommandInset citation LatexCommand cite key "wordreference-elixir" \end_inset . \end_layout \begin_layout Standard eLyXer (pronounced \emph on elixir \emph default ) is a LyX to HTML converter. While there are a ton of such projects all over the web, eLyXer has a clear focus on flexibility and elegant output. \end_layout \begin_layout Standard eLyXer (including this guide and all accompanying materials) is licensed under the \begin_inset CommandInset href LatexCommand href name "GPL version 3" target "http://www.gnu.org/licenses/gpl-3.0-standalone.html" \end_inset or, at your option, any later version. See the \family typewriter LICENSE \family default file for details. \end_layout \begin_layout Standard Please visit the \begin_inset CommandInset href LatexCommand href name "main page" target "index.html" \end_inset to find out about the latest developments. \end_layout \begin_layout Subsection System Requirements \end_layout \begin_layout Standard eLyXer requires Python 2.4. \begin_inset Formula $x$ \end_inset , and should work with versions up to 2.6. \begin_inset Formula $y$ \end_inset ; it will convert documents generated by LyX 1.5. \begin_inset Formula $x$ \end_inset to 2.0. It has been tested on the most common operating systems: on Mac OS X, Linux and Windows, with and without CygWin. \end_layout \begin_layout Standard Resource usage should be quite frugal; eLyXer runs quite happily on my 1st-gen Asus Eee, with its puny Celeron@570MHz and 512 MB of RAM. It should also be fast -- the Eee can convert ~200 pages of LyX text in just over 50 seconds. Performance is fairly linear: 200 pages take \begin_inset Formula $10\times$ \end_inset as long as 20, so there are no scalability problems. Memory usage stays low even when processing large documents, and conversion can be done on the fly (with \family typewriter --lowmem \family default ) for even lower memory requirements. \end_layout \begin_layout Subsection Installation \end_layout \begin_layout Standard This section looks at how to install eLyXer on your system, assuming that Python 2.4 to 2.6 is already there. \end_layout \begin_layout Subsubsection* Download eLyXer \end_layout \begin_layout Standard First you will need to fetch the official distribution file from the \begin_inset CommandInset href LatexCommand href name "download area" target "https://savannah.nongnu.org/files/?group=elyxer" \end_inset . Now, there is more than one way to install eLyXe, but all of them start by uncompressing the distributed file to a suitable directory. Just write at the command prompt: \end_layout \begin_layout LyX-Code \family typewriter \color blue $ \color inherit tar -xzf elyxer- \emph on [version] \emph default .tar.gz \end_layout \begin_layout Standard Or for the \family typewriter .zip \family default version: \end_layout \begin_layout LyX-Code \family typewriter \color blue $ \color inherit unzip elyxer- \emph on [version] \emph default .zip \end_layout \begin_layout Standard A directory called \family typewriter elyxer \family default should appear, where the main executable file \family typewriter elyxer.py \family default resides. \end_layout \begin_layout Subsubsection* Using the Installer \end_layout \begin_layout Standard An installer is provided in the root directory, called \family typewriter install.py \family default ; it is the recommended way to install eLyXer. To run it just type in a console as root: \end_layout \begin_layout LyX-Code \family typewriter \color blue # \color inherit python install.py \end_layout \begin_layout Standard On Windows you can type (as a regular user): \end_layout \begin_layout LyX-Code \family typewriter \color blue > \color inherit python.exe install.py \end_layout \begin_layout Standard In any case, the script will install eLyXer as a Python script. Now you can check if it was installed successfully: \end_layout \begin_layout LyX-Code \family typewriter \color blue $ \color inherit elyxer.py --help \end_layout \begin_layout Standard A brief help text and the list of command line options should appear. \end_layout \begin_layout Standard The installer will also copy existing translation files to your hard drive so that they can be used from within eLyXer for internationalization. \end_layout \begin_layout Subsubsection* Prepackaged Versions \end_layout \begin_layout Standard The easiest way to install eLyXer is if someone has prepackaged it for your system. Some Linux distributions include eLyXer: \begin_inset CommandInset href LatexCommand href name "Debian squeeze" target "http://packages.debian.org/squeeze/elyxer" \end_inset and \begin_inset CommandInset href LatexCommand href name "Ubuntu Lucid" target "http://packages.ubuntu.com/lucid/elyxer" \end_inset . Installation is done using apt-get or aptitude, for Debian as root: \end_layout \begin_layout LyX-Code \family typewriter \color blue # \color inherit apt-get install elyxer \end_layout \begin_layout Standard or, for Ubuntu: \end_layout \begin_layout LyX-Code \family typewriter \color blue $ \color inherit sudo aptitude install elyxer \end_layout \begin_layout Standard For both Debian and Ubuntu eLyXer needs to be run as \family typewriter "elyxer" \family default : \end_layout \begin_layout LyX-Code \family typewriter \color blue $ \color inherit elyxer --help \end_layout \begin_layout Standard On Windows, the \begin_inset CommandInset href LatexCommand href name "alternate LyX installer" target "http://wiki.lyx.org/Windows/LyXWinInstaller" \end_inset includes eLyXer in the default installation. See \begin_inset CommandInset ref LatexCommand ref reference "sub:LyX-Integration" \end_inset for LyX integration. \end_layout \begin_layout Subsubsection* Manual Installation \end_layout \begin_layout Standard If the installer did not work for you, you can manually install it as a module. On Linux go to the elyxer directory and type, as root: \end_layout \begin_layout LyX-Code \family typewriter \color blue # \color inherit python setup.py install \end_layout \begin_layout Standard On Windows just type: \end_layout \begin_layout LyX-Code \family typewriter \color blue > \color inherit python.exe setup.py install \end_layout \begin_layout Standard On Mac OS X you can use sudo to get the necessary permissions: \end_layout \begin_layout LyX-Code \family typewriter \color blue % \color inherit sudo python setup.py install \end_layout \begin_layout Standard Now you can run eLyXer as a Python script: \end_layout \begin_layout LyX-Code \family typewriter \color blue $ \color inherit elyxer.py --help \end_layout \begin_layout Standard The list of command line options should appear. You can also manually copy the file \family typewriter elyxer.py \family default to a directory found in the execution path (for instance, \family typewriter /usr/bin \family default on Linux or \family typewriter c: \backslash windows \backslash system32 \family default on Windows). \end_layout \begin_layout Subsection Test Drive \end_layout \begin_layout Standard Now you may want to try to convert the user guide: \end_layout \begin_layout LyX-Code \family typewriter \color blue $ \color inherit elyxer.py --css lyx.css --title "eLyXer User Guide" docs/userguide.lyx docs/usergu ide2.html \end_layout \begin_layout Standard It should generate a working web page identical to the one distributed: \end_layout \begin_layout LyX-Code \family typewriter \color blue $ \color inherit diff docs/userguide.html docs/userguide2.html \end_layout \begin_layout Standard The typical output will contain just the changed lines, which in this case should be only the header with the file creation date. An example is shown on listing \begin_inset CommandInset ref LatexCommand ref reference "alg:diff" \end_inset . \end_layout \begin_layout Standard \begin_inset Float algorithm wide false sideways false status open \begin_layout Quotation \family typewriter 7c7 \end_layout \begin_layout Quotation \family typewriter < \end_layout \begin_layout Quotation \family typewriter --- \end_layout \begin_layout Quotation \family typewriter > \end_layout \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout \begin_inset CommandInset label LatexCommand label name "alg:diff" \end_inset Example of \family typewriter diff \family default output for functionally identical HTML files. \end_layout \end_inset \end_layout \end_inset \end_layout \begin_layout Standard If nothing else appears (i.e. both files are functionally equal) then everything is working fine. If you have \family typewriter bash \family default installed, to test that everything \emph on really \emph default works fine you can just run the included tests: \end_layout \begin_layout LyX-Code \family typewriter \color blue $ \color inherit ./run-tests \end_layout \begin_layout Standard It will run a number of test and check the results, so you can see if everything is well. You also need to have installed the command-line tool \family typewriter diff \family default to show differences between two files. \end_layout \begin_layout Subsection Usage \end_layout \begin_layout Standard eLyXer is a standalone command line tool. It can be invoked from the command line as: \end_layout \begin_layout LyX-Code \family typewriter \color blue $ \color inherit elyxer.py [options] [source file] [destination file] \end_layout \begin_layout Standard If the source file is omitted then \family typewriter STDIN \family default is used; likewise, if no destination file is specified eLyXer will output to \family typewriter STDOUT \family default . This allows its use in pipes and other flexible configurations. Some examples: \end_layout \begin_layout LyX-Code \family typewriter \color blue $ \color inherit elyxer.py file.lyx file.html \end_layout \begin_layout Standard converts \family typewriter file.lyx \family default to \family typewriter file.html \family default . Debug messages are shown. \end_layout \begin_layout LyX-Code \family typewriter \color blue $ \color inherit cat file.lyx | elyxer.py > file.html \end_layout \begin_layout Standard converts \family typewriter file.lyx \family default to \family typewriter file.html \family default , as before. This time debug messages are not shown. \end_layout \begin_layout LyX-Code \family typewriter \color blue $ \color inherit elyxer.py file.lyx | grep "
" | wc \end_layout \begin_layout Standard counts all blockquote paragraphs. \end_layout \begin_layout LyX-Code \family typewriter \color blue $ \color inherit elyxer.py file.lyx | wget --no-check-certificate --spider -nv -F -i - \end_layout \begin_layout Standard checks all external links in a document recursively. (Local links will appear as unresolved, but they can be ignored.) \end_layout \begin_layout Subsection Image Processing \end_layout \begin_layout Standard eLyXer does not convert images directly; it uses the \begin_inset CommandInset href LatexCommand href name "ImageMagick" target "http://www.imagemagick.org/" \end_inset package, in particular the \family typewriter convert \family default tool, to create PNG versions of the images embedded in the original LyX documents, and then it inserts links to those PNG images in the resulting HTML pages. If ImageMagick is not installed eLyXer will show an error message and will not try to convert further images. \end_layout \begin_layout Standard HTML pages, unlike PDF documents, do not contain images in the document file; rather they contain pointers to image locations on disk. (Fortunately, LyX documents do not contain images either.) eLyXer will generate pages that point to the same locations as the original images, when they are PNG images, or to the converted versions otherwise. Image types like Encapsulated PostScript cannot be used directly from within pages. \end_layout \begin_layout Standard Image location is fragile. All images should be placed in the same location (and with the same structure) as the original document; and they should all be referenced relatively to the current document. During conversion from within LyX image locations can be lost, since LyX does not do in-place conversion; instead, LyX copies the original file to a temporary directory, converts the file and then copies everything back to a directory ending in \family typewriter .LyXconv \family default . \end_layout \begin_layout Subsection \begin_inset CommandInset label LatexCommand label name "sub:LyX-Integration" \end_inset LyX Integration \end_layout \begin_layout Standard If you used the eLyXer installer LyX will automatically detect it after reconfiguration. Just make sure that you are running LyX 1.6.5 or later, and click on Tools\SpecialChar \menuseparator Reconfi gure. \end_layout \begin_layout Standard LyX should be able to detect if eLyXer was installed as a script, or even if it has been installed from a Linux distribution. In any case you can verify that it has been recognized by LyX by opening Tools\SpecialChar \menuseparator Preferences\SpecialChar \ldots{} , going to External formats\SpecialChar \menuseparator Converters, and finding the converter for \begin_inset Quotes eld \end_inset LyX -> HTML \begin_inset Quotes erd \end_inset . If eLyXer is there, it worked! Now you can convert your documents using View\SpecialChar \menuseparator HTML. Otherwise try to reinstall eLyXer from scratch and then reconfigure LyX. \end_layout \begin_layout Subsubsection* Installing as a Package or as a Module \end_layout \begin_layout Standard Versions of the eLyXer installer prior to 1.2.0 tried to install eLyXer as a module, so it could be run using \family typewriter "python -m elyxer" \family default . This option is deprecated since a module called \family typewriter elyxer \family default would collide with a Python package of the same name, and there are plans to install eLyXer as a proper Python package in the future (probably in the 1.3.0 time frame). In the interim eLyXer is installed only as a script called \family typewriter elyxer.py \family default . \end_layout \begin_layout Standard LyX (starting with versions 2.0.0 and 1.6.9) has been patched to recognize only the script and disregard the module. \end_layout \begin_layout Section Advanced Use \end_layout \begin_layout Standard There are some advanced uses for eLyXer if you want to extract the most of it. \end_layout \begin_layout Subsection Command Line Options \end_layout \begin_layout Standard eLyXer supports a few command line options: \end_layout \begin_layout Description \family typewriter --help \family default : Show command line help. \end_layout \begin_layout Description \family typewriter --quiet \family default : Be quiet and do not output messages (except errors). This way you can avoid the comforting \begin_inset Quotes eld \end_inset Parsing line 1000 \begin_inset Quotes erd \end_inset messages. When STDIN or STDOUT are used (e.g. in a pipeline) \family typewriter --quiet \family default is always enabled. \end_layout \begin_layout Subsubsection* Advanced Options \end_layout \begin_layout Description \family typewriter --debug \family default : Show debug messages. They may help a developer understand your problem. \end_layout \begin_layout Description \family typewriter --version \family default : Show version number and date. Use to check which version you are actually running. \end_layout \begin_layout Description \family typewriter --lyxformat \family default : Return the highest LyX version that eLyXer understands. This parameter is provided to help with \family typewriter lyx2lyx \family default integration, so that this tool knows if it must convert the file to a lower LyX format. \end_layout \begin_layout Subsubsection* Options to Control HTML output \end_layout \begin_layout Description \family typewriter --title \begin_inset space ~ \end_inset \series bold " \series default title \series bold " \family default \series default : Change the title of the generated web page. \end_layout \begin_layout Description \family typewriter --css \begin_inset space ~ \end_inset \series bold " \series default new.css \series bold " \family default \series default : Change default CSS. See section \begin_inset CommandInset ref LatexCommand ref reference "sub:CSS" \end_inset : CSS. \end_layout \begin_layout Description \family typewriter --embedcss \begin_inset space ~ \end_inset \series bold " \series default file.css \series bold " \family default \series default : Embed the styles in \family typewriter file.css \family default into the resulting HTML document. See section \begin_inset CommandInset ref LatexCommand ref reference "sub:CSS" \end_inset : CSS. \end_layout \begin_layout Description \family typewriter --html \family default : Generate HTML 4.0 (instead of XHTML). The resulting pages should be easier to import from certain word processors. See section \begin_inset CommandInset ref LatexCommand ref reference "sub:HTML-Code" \end_inset : HTML code. \end_layout \begin_layout Description \family typewriter --unicode \family default : Restore full Unicode output. Right now switches midspaces to medium mathematical spaces. See also section \begin_inset CommandInset ref LatexCommand ref reference "sub:HTML-Code" \end_inset : HTML code. \end_layout \begin_layout Description \family typewriter --iso885915 \family default : Generate a document using ISO-8859-1 encoding. Again, see section \begin_inset CommandInset ref LatexCommand ref reference "sub:HTML-Code" \end_inset : HTML code. \end_layout \begin_layout Description \family typewriter --nofooter \family default : Omit the footer message \begin_inset Quotes eld \end_inset Document generated by eLyXer \begin_inset Quotes erd \end_inset (shown at the bottom). \end_layout \begin_layout Subsubsection* Options to Control image output \end_layout \begin_layout Description \family typewriter --directory \begin_inset space ~ \end_inset "images_dir" \family default : Look for images in the directory specified. \end_layout \begin_layout Description \family typewriter --destdirectory \begin_inset space ~ \end_inset "dest_dir" \family default : Converted images will end up into this directory. \end_layout \begin_layout Description \family typewriter --imageformat \begin_inset space ~ \end_inset ".extension" \family default : Force the format implied by the extension (e.g. \family typewriter ".jpg" \family default for JPEG) for output images. Use \family typewriter --imageformat "copy" \family default to make images be copied over instead of converted. \end_layout \begin_layout Description \family typewriter --converter \begin_inset space ~ \end_inset \series bold "program" \family default \series default : \family typewriter \family default Use the given program to convert images. Right now the supported converters are: \family typewriter \series bold imagemagick \family default \series default (default), \family typewriter \series bold inkscape \family default \series default and \family typewriter \series bold lyx \family default \series default itself. With \family typewriter --converter inkscape \family default eLyXer picks Inkscape as the image converter (Inkscape uses some non-standard extensions so it might be needed to convert SVG images to PNG); with \family typewriter --converter lyx \family default the new LyX option \family typewriter lyx -C \family default is used. You can also supply your own converter command line, using \family typewriter $input \family default and \family typewriter $output \family default as variables (note the single quotes): \end_layout \begin_layout LyX-Code \family typewriter \color blue $ \color inherit elyxer.py --converter 'lyx -C $input $output' [source file] [destination file] \end_layout \begin_layout Description \family typewriter --noconvert \family default : Use all images in their original location and do not convert anything. Useful when using images which do not convert well, such as SVG files. \end_layout \begin_layout Subsubsection* Options to Control footnote output \end_layout \begin_layout Description \family typewriter --numberfoot \family default : Number all footnotes using numbers: \begin_inset Quotes eld \end_inset [1] \begin_inset Quotes erd \end_inset , instead of the default \begin_inset Quotes eld \end_inset [A] \begin_inset Quotes erd \end_inset . \end_layout \begin_layout Description \family typewriter --symbolfoot \family default : mark footnotes with symbols (*, **, †, ‡\SpecialChar \ldots{} ). \end_layout \begin_layout Description \family typewriter --hoverfoot \family default : show footnotes as hovering text. This is the default position. \end_layout \begin_layout Description \family typewriter --marginfoot \family default : show footnotes with numbers instead of letters. \end_layout \begin_layout Description \family typewriter --endfoot \family default : show footnotes at the end of the page. \end_layout \begin_layout Description \family typewriter --supfoot \family default : use superscript for footnote markers. This is the default style. \end_layout \begin_layout Description \family typewriter --alignfoot \family default : use aligned text for footnote markers, instead of superscript. \end_layout \begin_layout Description \family typewriter --footnotes \begin_inset space ~ \end_inset "options" \family default : specify several footnotes options at the same time, separated with commas. Available options are: "number", "hover", "margin", "end". See section \begin_inset CommandInset ref LatexCommand ref reference "sub:Footnotes" \end_inset : Footnotes. \end_layout \begin_layout Subsubsection* Advanced Options to Control HTML output \end_layout \begin_layout Description \family typewriter --splitpart \begin_inset space ~ \end_inset \series bold " \series default depth \series bold " \family default \series default : Split the resulting webpage at the given depth. See section \begin_inset CommandInset ref LatexCommand ref reference "sub:Segmenting-Pages" \end_inset : Segmenting Pages. \end_layout \begin_layout Description \family typewriter --tocfor \begin_inset space ~ \end_inset \series bold " \series default original.html \series bold " \family default \series default : Generate just a table of contents with links to the original HTML file. See section \begin_inset CommandInset ref LatexCommand ref reference "sub:TOC" \end_inset : TOC. \end_layout \begin_layout Description \family typewriter --target \begin_inset space ~ \end_inset \series bold " \series default frame \series bold " \family default \series default : Add a \family typewriter target \family default attribute to every link in the generated HTML, making all links point to the provided frame. Again, see section \begin_inset CommandInset ref LatexCommand ref reference "sub:TOC" \end_inset : TOC. \end_layout \begin_layout Description \family typewriter --notoclabels \family default : Omit \begin_inset Quotes eld \end_inset Chapter \begin_inset Quotes erd \end_inset , \begin_inset Quotes eld \end_inset Part \begin_inset Quotes erd \end_inset and similar labels from the TOC; just output part numbers (and separate using a period). For instance, a chapter that without this option is labeled \begin_inset Quotes eld \end_inset Chapter 2: Advanced Use \begin_inset Quotes erd \end_inset in the TOC would now become \begin_inset Quotes eld \end_inset 2. Advanced Use \begin_inset Quotes erd \end_inset , as on the PDF. Option adapted from the wish list: \begin_inset CommandInset ref LatexCommand ref reference "sub:Wish-List" \end_inset . \end_layout \begin_layout Description \family typewriter --lowmem \family default : Activate a low memory mode which does not keep the whole document in memory: conversion is done on the fly. Keep in mind that some features as the TOC will be missing from the generated document. \end_layout \begin_layout Description \family typewriter --numberfoot \family default : \family typewriter \family default Label footnotes using numbers, instead of letters. Useful when bibliographical references are not numbered and therefore cannot be confused with footnotes. \end_layout \begin_layout Description \family typewriter --raw \family default : Generate an HTML page without header or footer. \end_layout \begin_layout Description \family typewriter --mathjax \begin_inset space ~ \end_inset \series bold remote \family default \series default : Use the excellent JavaScript library \begin_inset CommandInset href LatexCommand href name "MathJax" target "http://www.mathjax.org/" \end_inset remotely to pretty-print mathematical equations. See section \begin_inset CommandInset ref LatexCommand ref reference "sub:Math" \end_inset . \end_layout \begin_layout Description \family typewriter --mathjax \begin_inset space ~ \end_inset \series bold " \series default URL \series bold " \family default \series default : Use the excellent JavaScript library \begin_inset CommandInset href LatexCommand href name "MathJax" target "http://www.mathjax.org/" \end_inset at the given URL (usually a local URL is used). See also section \begin_inset CommandInset ref LatexCommand ref reference "sub:Math" \end_inset . \end_layout \begin_layout Description \family typewriter --googlecharts \family default : Use \begin_inset CommandInset href LatexCommand href name "Google Charts" target "http://code.google.com/apis/chart/index.html" \end_inset to generate images for every formula. Again, see \begin_inset CommandInset ref LatexCommand ref reference "sub:Math" \end_inset . \end_layout \begin_layout Description \family typewriter --simplemath \family default : Do not generate fancy math structures such as multi-line Unicode brackets or stacked limits. This option is automatically activated when \family typewriter --html \family default is selected; once more see section \begin_inset CommandInset ref LatexCommand ref reference "sub:Math" \end_inset . \end_layout \begin_layout Description \family typewriter --template \begin_inset space ~ \end_inset \series bold " \series default file \series bold " \family default \series default : Use an HTML template. The raw converted document will be placed where \family typewriter \family default appears in the template. Available variables: \family typewriter \family default , \family typewriter \family default , \family typewriter \family default , \family typewriter \family default , \family typewriter \family default , \family typewriter \family default , \family typewriter \family default , \family typewriter \family default , \family typewriter \family default , \family typewriter \family default , \family typewriter \family default , \family typewriter \family default . \end_layout \begin_layout Description \family typewriter --copyright \family default : Include a copyright notice at the bottom. \end_layout \begin_layout Subsubsection* Deprecated Options \end_layout \begin_layout Description \family typewriter --toc \family default : Generate just a table of contents. Use \family typewriter --tocfor \family default instead. \end_layout \begin_layout Description \family typewriter --toctarget \begin_inset space ~ \end_inset \series bold " \series default original.html \series bold " \family default \series default : Generate a table of contents with links to the original HTML file. Use \family typewriter --tocfor \family default instead. \end_layout \begin_layout Description \family typewriter --nocopy \family default : No effect since the copyright notice is now optional, maintained for backwards compatibility. \end_layout \begin_layout Standard When an option accepts an argument it can be added after a space as \family typewriter --target \begin_inset space ~ \end_inset \series bold " \series default frame \series bold " \family default \series default , or with an equals sign as in \family typewriter --target= \series bold " \series default frame \series bold " \family default \series default . The quotes are optional and can be useful if your arguments include e.g. spaces. \end_layout \begin_layout Subsubsection* Adding Options In LyX \end_layout \begin_layout Standard To add one of these options so that it is used from within LyX, you have to modify the converter line. To this effect open Tools\SpecialChar \menuseparator Preferences\SpecialChar \ldots{} , go to External formats\SpecialChar \menuseparator Converters, find the converter for \begin_inset Quotes eld \end_inset LyX -> HTML \begin_inset Quotes erd \end_inset and edit the converter line. It should read something like this: \end_layout \begin_layout LyX-Code \family typewriter elyxer.py --directory $$r $$i $$o \end_layout \begin_layout Standard If you want to generate pure HTML instead of XHTML, change the line to: \end_layout \begin_layout LyX-Code \family typewriter elyxer.py \family default \series bold --html \family typewriter \series default --directory $$r $$i $$o \end_layout \begin_layout Standard And so on. Figure 1 shows what to do to add the \family typewriter --html \family default option: after editing the line and adding the new option, click on \begin_inset Quotes eld \end_inset Modify \begin_inset Quotes erd \end_inset and then \begin_inset Quotes eld \end_inset Save \begin_inset Quotes erd \end_inset or \begin_inset Quotes eld \end_inset Apply \begin_inset Quotes erd \end_inset the changes. \begin_inset Marginal status open \begin_layout Plain Layout You should never remove the \family typewriter $$i $$o \family default at the end, since it is what tells eLyXer where to find the input and output files. \end_layout \end_inset \end_layout \begin_layout Standard \begin_inset Float figure wide false sideways false status open \begin_layout Plain Layout \align center \begin_inset Graphics filename converters.png \end_inset \end_layout \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout eLyXer converter in LyX 1.6.5. \end_layout \end_inset \end_layout \begin_layout Plain Layout \end_layout \end_inset \end_layout \begin_layout Standard LyX 1.6.5 supports a new \begin_inset Quotes eld \end_inset extra flag \begin_inset Quotes erd \end_inset line; however, at this moment it does not work with eLyXer. \end_layout \begin_layout Subsection CSS \begin_inset CommandInset label LatexCommand label name "sub:CSS" \end_inset \end_layout \begin_layout Standard HTML output, as generated, can fall short in certain situations. Some CSS wizardry can go a long way to customize eLyXer. \end_layout \begin_layout Standard eLyXer tags most elements with the type so you can later modify them using a CSS. The default HTML header is similar to listing \begin_inset CommandInset ref LatexCommand ref reference "alg:CSS" \end_inset , so the default remote CSS file is used. \end_layout \begin_layout Standard \begin_inset Float algorithm wide false sideways false status open \begin_layout Quotation \family typewriter \end_layout \begin_layout Quotation \family typewriter [...] \end_layout \begin_layout Quotation \family typewriter \series bold \end_layout \begin_layout Quotation \family typewriter Your title here \end_layout \begin_layout Quotation \family typewriter \end_layout \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout \begin_inset CommandInset label LatexCommand label name "alg:CSS" \end_inset CSS link automatically added to HTML \end_layout \end_inset \end_layout \end_inset \end_layout \begin_layout Standard This sample CSS file is published on nongnu.org and distributed along with the scripts, \family typewriter docs/lyx.css \family default . (You may have found that your document shows minor changes in its appearance with time -- this is the reason. The main author regularly publishes a new, updated version of \family typewriter lyx.css \family default on nongnu.org, and all documents using it automatically appear with the changes. Backwards compatibility is maintained as much as possible.) \end_layout \begin_layout Standard To give your document a customized appearance (or for pages to be accessible offline) you probably will want to use your own CSS file; to use it first copy it to the directory where your document resides (e.g. renaming it to \family typewriter custom.css \family default ), and customize as needed. Then run \family typewriter elyxer.py \family default with the following option: \end_layout \begin_layout LyX-Code \family typewriter \color blue $ \color inherit elyxer.py --css=custom.css document.lyx page.html \end_layout \begin_layout Standard This will make the generated \family typewriter page.html \family default use your \family typewriter custom.css \family default file. The \family typewriter `=' \family default sign between the constant \family typewriter `--css' \family default and the name of the CSS file is optional. More than one \family typewriter --css \family default option can be added if you want several CSS files to be used in the header. \end_layout \begin_layout Standard Sometimes the styles in a CSS are needed in the HTML document (for offline viewing, or to distribute as stand-alone pages). For these uses there is the option \family typewriter --embedcss \family default : the styles contained in the CSS file passed as an argument will be embedded in the resulting HTML document. For instance: \end_layout \begin_layout LyX-Code \family typewriter \color blue $ \color inherit elyxer.py --embedcss custom.css document.lyx page.html \end_layout \begin_layout Standard This command generates a document \family typewriter page.html \family default where the styles in \family typewriter custom.css \family default are embedded. The CSS to embed must be a file, not a remote URL. Listing \begin_inset CommandInset ref LatexCommand ref reference "alg:embed-CSS" \end_inset shows the resulting HTML header for a test CSS with just one style, \family typewriter div.Standard \family default . Note that the remote CSS is still added by default; to avoid it just add an option with an empty CSS file, \family typewriter --css="" \family default . \end_layout \begin_layout Standard \begin_inset Float algorithm wide false sideways false status open \begin_layout Quotation \family typewriter \end_layout \begin_layout Quotation \family typewriter [...] \end_layout \begin_layout Quotation \family typewriter \end_layout \begin_layout Quotation \family typewriter \end_layout \begin_layout Quotation \family typewriter \series bold \end_layout \begin_layout Quotation \family typewriter Your title here \end_layout \begin_layout Quotation \family typewriter \end_layout \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout \begin_inset CommandInset label LatexCommand label name "alg:embed-CSS" \end_inset CSS embedded into the HTML \end_layout \end_inset \end_layout \end_inset \end_layout \begin_layout Standard As with the \family typewriter --css \family default option, several \family typewriter --embedcss \family default options can be added to embed more than one file. \end_layout \begin_layout Standard The CSS file for eLyXer uses some CSS2 features for math structures (fractions, arrays). This makes the output incompatible with older browsers; it requires Microsoft Internet Explorer 7, Firefox 3, Safari 3 or Chrome 1. Check the \begin_inset CommandInset href LatexCommand href name "Math Showcase" target "math.html" \end_inset to see if your browser can render eLyXer output correctly. \end_layout \begin_layout Subsection Title \end_layout \begin_layout Standard By default the generated web pages have the title \begin_inset Quotes eld \end_inset Converted Document \begin_inset Quotes erd \end_inset . If a PDF title is found then it is used instead. The proper LyX title (a paragraph of type \begin_inset Quotes eld \end_inset Title \begin_inset Quotes erd \end_inset embedded in the text) will also be used if found. But when \family typewriter --lowmem \family default is in use eLyXer does not try to get the proper title, since it may be found in the middle of the document or not be present at all; scanning for it would mean doing two passes, one to look for the title in all the document and another to output the web page, and \family typewriter --lowmem \family default implies on-the-fly conversion to save memory. \end_layout \begin_layout Standard You can change the title of the generated web page with the \family typewriter --title \family default option: \end_layout \begin_layout LyX-Code \family typewriter \color blue $ \color inherit elyxer.py --title "My Beautiful Document" document.lyx page.html \end_layout \begin_layout Subsection Table Of Contents \begin_inset CommandInset label LatexCommand label name "sub:TOC" \end_inset \end_layout \begin_layout Standard A table of contents (or TOC) can be generated for every converted LyX document. You can optionally also add a target frame to every link. The trick is to combine both options to generate a TOC that links to the original document on a different frame. For example, if the original page is called \family typewriter page.html \family default and you generated it with this command: \end_layout \begin_layout LyX-Code \family typewriter \color blue $ \color inherit elyxer.py document.lyx page.html \end_layout \begin_layout Standard you can generate the TOC linking to this page, and at the same time point it to frame \family typewriter contents \family default : \end_layout \begin_layout LyX-Code \family typewriter \color blue $ \color inherit elyxer.py --tocfor page.html --target contents document.lyx page-toc.html \end_layout \begin_layout Standard Then you can put it all together with a simple frameset generated manually. Just remember to place the original document in the frame called \family typewriter contents \family default . \end_layout \begin_layout Standard \begin_inset Float algorithm wide false sideways false status open \begin_layout Plain Layout \family typewriter \end_layout \begin_layout Plain Layout \family typewriter \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \end_layout \begin_layout Plain Layout \family typewriter \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \end_layout \begin_layout Plain Layout \family typewriter \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \end_layout \begin_layout Plain Layout \family typewriter \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \end_layout \begin_layout Plain Layout \family typewriter \end_layout \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout \begin_inset CommandInset label LatexCommand label name "alg:frameset" \end_inset An example frameset for TOC navegation \end_layout \end_inset \end_layout \end_inset \end_layout \begin_layout Standard TOC generation accepts the same options as normal document conversion. For example, if you follow these instructions literally you will notice that the TOC has very wide margins and looks a bit weird; that is because it is using the default CSS. A special CSS file for TOC files is provided in \family typewriter docs/toc.css \family default , so better results should be obtained with the \family typewriter --css \family default option: \end_layout \begin_layout LyX-Code \family typewriter \color blue $ \color inherit elyxer.py --tocfor page.html --css docs/toc.css --target contents document.lyx page-toc.html \end_layout \begin_layout Standard With a little bit of practice you will be able to generate useful (and nice looking) TOC files. You can see an example for the \begin_inset CommandInset href LatexCommand href name "user guide" target "userguide-frameset.html" \end_inset (if you are not already looking at it). \end_layout \begin_layout Subsection Segmenting Pages \begin_inset CommandInset label LatexCommand label name "sub:Segmenting-Pages" \end_inset \end_layout \begin_layout Standard Quite often you don't want a huge monolithic page, but a set of linked pages. To do so you can use the \family typewriter --splitpart \family default option, specifying the level at which eLyXer should split pages. For instance: \end_layout \begin_layout LyX-Code \family typewriter \color blue $ \color inherit elyxer.py --splitpart 1 document.lyx output.html \end_layout \begin_layout Standard will split \family typewriter document.lyx \family default into pages at level 1, using \family typewriter output.html \family default as the root page. Each page will get a number that starts with \family typewriter output \family default and ends with \family typewriter .html \family default , with a suffix that depends on the page -- \family typewriter output-2.html \family default will correspond to the second split part. \end_layout \begin_layout Standard The level corresponding to 1 depends on the document class: books will be split at chapters, but articles will get a section per page. And so on with lower levels. \end_layout \begin_layout Subsection HTML Code \begin_inset CommandInset label LatexCommand label name "sub:HTML-Code" \end_inset \end_layout \begin_layout Standard The HTML code generated is technically XHTML Transitional, version 1.0 \begin_inset CommandInset citation LatexCommand cite key "xhtml" \end_inset , using UTF-8 encoding. Some programs have (in this day and age) trouble importing XHTML, notably some popular word processors. To work around this problem and provide more flexible output in general you can output HTML 4.0: \end_layout \begin_layout LyX-Code \family typewriter \color blue $ \color inherit elyxer.py --html document.lyx page-to-import.html \end_layout \begin_layout Standard Again, technically the code generated is HTML 4.01 Transitional \begin_inset CommandInset citation LatexCommand cite key "html-401" \end_inset using UTF-8 encoding. Both versions should pass the W3C tests \begin_inset CommandInset citation LatexCommand cite key "w3c-validator" \end_inset . If your particular web page doesn't pass the tests, then it is a bug and it will be treated as such. \end_layout \begin_layout Standard The \family typewriter --html \family default option also activates the \family typewriter --simplemath \family default option; see section \begin_inset CommandInset ref LatexCommand ref reference "sub:Math" \end_inset : Math for details. \end_layout \begin_layout Subsubsection* Character Encodings \end_layout \begin_layout Standard For better browser compatibility, medium mathematical spaces are substituted in the output with midspaces -- improving the output for some popular browsers. If you want your mathematical spaces back, just use the \family typewriter --unicode \family default option: \end_layout \begin_layout LyX-Code \family typewriter \color blue $ \color inherit elyxer.py --unicode document.lyx page-to-import.html \end_layout \begin_layout Standard Check out the \begin_inset CommandInset href LatexCommand href name "Math Showcase with Unicode" target "math-unicode.html" \end_inset to see the results. In the future other non-Unicode substitutions might be used. \end_layout \begin_layout Standard In case you want to use the ISO-8859-15 encoding in your generated document, you can add the \family typewriter --iso885915 \family default option: \end_layout \begin_layout LyX-Code \family typewriter \color blue $ \color inherit elyxer.py --iso885915 document.lyx page.html \end_layout \begin_layout Standard This will make eLyXer output a document with all non-ASCII characters encoded as \family typewriter   \family default , \family typewriter   \family default and so on. This encoding is similar to ISO-8859-1, also called Latin-1, but including the Euro sign. The \begin_inset CommandInset href LatexCommand href name "Math Showcase (ISO-8859-15 edition)" target "math-iso885915.html" \end_inset has been generated using this option. \end_layout \begin_layout Standard Both encoding options can be combined with \family typewriter --html \family default at will. \end_layout \begin_layout Subsection Internationalization \end_layout \begin_layout Standard eLyXer is distributed along with a few translation files. They are automatically regenerated every time \family typewriter make \family default is run, and reside in the folder \family typewriter po/ \family default . Internationalization is done using GNU \family typewriter gettext \family default , so every locale is identified by a two-letter code (such as \begin_inset Quotes eld \end_inset en \begin_inset Quotes erd \end_inset for English and \begin_inset Quotes eld \end_inset es \begin_inset Quotes erd \end_inset for Spanish). There are two kinds of files: the text \family typewriter .po \family default file (which can be found in \family typewriter po/my.po \family default for locale \begin_inset Quotes eld \end_inset my \begin_inset Quotes erd \end_inset ), and the binary \family typewriter .mo \family default file (found in \family typewriter po/my/elyxer.po \family default ). \end_layout \begin_layout Standard For internationalization to work properly, Linux distributors should take all binary \family typewriter .mo \family default files and place them in the directory corresponding to locale files, which we will call \family typewriter $localedir \family default . As \begin_inset CommandInset href LatexCommand href name "the Python gettext page" target "http://docs.python.org/library/gettext.html" \end_inset explains, this is distribution-dependent: for example on Debian \family typewriter $localedir \family default is \family typewriter /usr/share/locale \family default , so for locale \begin_inset Quotes eld \end_inset es \begin_inset Quotes erd \end_inset the correct route would be \end_layout \begin_layout LyX-Code \family typewriter /usr/share/locale/es/LC_MESSAGES/elyxer.mo \end_layout \begin_layout Standard Windows distributors on the other hand should place files in \family typewriter %PYTHONHOME% \backslash share \backslash locale \family default , for example for locale \begin_inset Quotes eld \end_inset es \begin_inset Quotes erd \end_inset on a machine where Python is in \family typewriter C: \backslash python \family default : \end_layout \begin_layout LyX-Code \family typewriter C: \backslash python \backslash share \backslash locale \backslash es \backslash LC_MESSAGES \backslash elyxer.mo \end_layout \begin_layout Standard To generate a new translation file (we will use \begin_inset Quotes eld \end_inset my \begin_inset Quotes erd \end_inset as an example locale here, corresponding to Burmese): you need to have the GNU \family typewriter gettext \family default package installed. Then go to the directory where elyxer.pot resides: \end_layout \begin_layout LyX-Code \family typewriter \color blue $ \color inherit cd src/conf \end_layout \begin_layout Standard and generate a \family typewriter .po \family default file for your locale: \end_layout \begin_layout LyX-Code \family typewriter \color blue $ \color inherit msginit --output-file=my.po --locale=my \end_layout \begin_layout Standard Then move the file to the \family typewriter po/ \family default directory: \end_layout \begin_layout LyX-Code \family typewriter \color blue $ \color inherit mv my.po ../../po/ \end_layout \begin_layout Standard and start translating it to Burmese! Once you are done run make from the root directory: \end_layout \begin_layout LyX-Code \family typewriter \color blue $ \color inherit ./make \end_layout \begin_layout Standard and it will generate the file \family typewriter po/my/elyxer.mo \family default . Finally, place this file in \end_layout \begin_layout LyX-Code \family typewriter $localedir/my/LC_MESSAGES/elyxer.mo \end_layout \begin_layout Standard and you are done. \end_layout \begin_layout Subsection Math \begin_inset CommandInset label LatexCommand label name "sub:Math" \end_inset \end_layout \begin_layout Standard Math equations are an important part of what takes LyX apart from other editors, since it supports the full LaTeX feature set -- that is, about everything under the sun. Unfortunately, math support is hard to get right. Many developers are focusing on MathML, but at the time of this writing (Q2 2010) support on some common browsers is still missing. \end_layout \begin_layout Standard eLyXer follows its usual minimalistic approach and doesn't try to be everything to everybody -- instead, it supports out of the box a set of usual constructs (fraction, square root) and tries to simulate others (binomial, overbrace). See the \begin_inset CommandInset href LatexCommand href name "Math showcase" target "math.html" \end_inset for yourself and learn what eLyXer supports and what not. \end_layout \begin_layout Standard For more sophisticated math equations there are a couple of advanced features. \end_layout \begin_layout Subsubsection* MathJax \end_layout \begin_layout Standard The first option is to use \begin_inset CommandInset href LatexCommand href name "MathJax" target "http://www.mathjax.org/" \end_inset , which is as simple as using the option \family typewriter --mathjax \family default : \end_layout \begin_layout LyX-Code \family typewriter \color blue $ \color inherit elyxer.py --mathjax \family default \series bold remote \family typewriter \series default math.lyx math- \family default mathjax-remote \family typewriter .html \end_layout \begin_layout Standard The \family typewriter \series bold remote \family default \series default argument tells MathJax to access the MathJax library remotely on the MathJax CDN. (You should always comply with their \begin_inset CommandInset href LatexCommand href name "terms of service" target "http://www.mathjax.org/download/mathjax-cdn-terms-of-service/" \end_inset .) See the \begin_inset CommandInset href LatexCommand href name "Math showcase (MathJax remote edition)" target "math-mathjax-remote.html" \end_inset to check the results. \end_layout \begin_layout Standard In case you need to go outside the terms of service, or you want the content to be accessible offline, you can always use a local copy of MathJax. Just use the URL of the repository as an argument to the \family typewriter --mathjax \family default option: \end_layout \begin_layout LyX-Code \family typewriter \color blue $ \color inherit elyxer.py --mathjax MathJax/ math.lyx math- \family default mathjax-local \family typewriter .html \end_layout \begin_layout Standard This way eLyXer uses the given URL (in the example \family typewriter MathJax/ \family default ) to load MathJax from and set it up. Although some code needs to be hosted on the same site as the pages, MathJax uses a feature called web-fonts which can be downloaded from a public server; this is quite easier to host. See the \begin_inset CommandInset href LatexCommand href name "Math showcase (MathJax edition)" target "math-mathjax.html" \end_inset to see how MathJax fares with eLyXer. \end_layout \begin_layout Standard Something to note is that MathJax is a JavaScript library; all rendering is done client-side by the user's browser. This has quite a few advantages: \end_layout \begin_layout Itemize Math processing on the server is quite light; equations are basically surrounded by a special tag and left in TeX form. \end_layout \begin_layout Itemize For developers: integration of these libraries is very easy. It took just a few days to integrate both libraries with eLyXer. \end_layout \begin_layout Itemize MathJax is improving all the time thanks to the efforts of Davide P. Cervone and the rest of the developer team; eLyXer and its users reap the benefits readily. \end_layout \begin_layout Itemize The client browser already knows its abilities, and can choose the rendering method it considers to be the best. MathJax can even choose between MathML and HTML+CSS \emph on at page rendering time \emph default , showing MathML on fancier browsers and simpler HTML where it is not available. \end_layout \begin_layout Standard It also brings some disadvantages: \end_layout \begin_layout Itemize With the \family typewriter remote \family default argument, JavaScript code resides at \begin_inset CommandInset href LatexCommand href name "a remote server" target "http://cdn.mathjax.org/" \end_inset and your users will need online access to view the maths. \end_layout \begin_layout Itemize If MathJax is accessed locally you need to also host the code for MathJax. (Web fonts used in MathJax can at least be hosted elsewhere, so publishers do not need to also host the fonts package, but this hasn't still been used in eLyXer.) \end_layout \begin_layout Itemize And of course it takes some time to render everything on the client, which can degrade the user experience on older machines. \end_layout \begin_layout Standard Publishers should carefully consider pros and cons before deciding what to use. \end_layout \begin_layout Subsubsection* Google Charts \end_layout \begin_layout Standard \begin_inset CommandInset href LatexCommand href name "Google Charts" target "http://code.google.com/apis/chart/index.html" \end_inset is an online service which generates images that contain charts and other stuff; it can also generate TeX formulas. eLyXer can use it using the option \family typewriter --googlecharts \family default : \end_layout \begin_layout LyX-Code \family typewriter \color blue $ \color inherit elyxer.py --googlecharts math.lyx math-googlecharts.html \end_layout \begin_layout Standard There are some limitations to Google Charts: no macros, formulas cannot exceed 200 characters, and the supported command set is limited (commands in text mode, for instance, are out of bounds). Also, generated images can be hard to align vertically -- by default they are middle-aligned, but some small characters or superscripted formulas can look weird. But this option can be a quick&dirty way of showing math for older or unsupport ed browsers. \end_layout \begin_layout Subsubsection* Brackets and Limits \end_layout \begin_layout Standard Fancy math structures are generated by default: arrays and binomials are surrounded by multi-line Unicode brackets, limits in display mode are stacked above / below the symbol, and so on. When the option \family typewriter --simplemath \family default is used eLyXer avoids such structures and just outputs enlarged regular symbols. It is also included in the \family typewriter --html \family default option. \end_layout \begin_layout Standard Check out the \begin_inset CommandInset href LatexCommand href name "Math showcase (HTML edition)" target "math-html.html" \end_inset to see the results. \end_layout \begin_layout Subsection Footnotes \begin_inset CommandInset label LatexCommand label name "sub:Footnotes" \end_inset \end_layout \begin_layout Standard Footnote generation is surprisingly hard to get right in an HTML document. eLyXer has a fairly complete set of command line options to customize how footnotes are generated. Here we will use the aggregated option \family typewriter --footnotes "options" \family default which can be used to specify any combination, but they can be turned on independently using \family typewriter --\SpecialChar \ldots{} foot \family default . For instance: \family typewriter --footnotes number,margin \family default is equivalent to \family typewriter --numberfoot --marginfoot \family default . \end_layout \begin_layout Subsubsection* Markers \end_layout \begin_layout Standard The footnote is attached to a point of the text (the \emph on referring \emph default text) which is usually marked by a bit of text. The default behavior for the marker is to use a superscript letter surrounded by square brackets, in blue: \color blue \begin_inset Formula $^{\text{[A]}}$ \end_inset \color inherit . The text can be changed to aligned text with \family typewriter --footnotes align \family default : \color blue [A] \color inherit , so markers are not mistaken with other superscript constructs such as exponents (like \begin_inset Formula $e^{a}$ \end_inset ). \end_layout \begin_layout Standard Markers can also be converted to numbers using \family typewriter --footnotes number \family default : \color blue \begin_inset Formula $^{\text{[1]}}$ \end_inset . \color inherit Or, they can be switched over to symbols using \family typewriter --footnotes symbol \family default : \color blue * \color inherit . Available symbols are rotated from this sequence: * ** † ‡ § §§ ¶ ¶¶ # ##. All options can be combined. For instance, symbol markers look best when shown aligned; \family typewriter --footnotes align,symbol \family default will show aligned symbolic markers such as \color blue * \color inherit or \color blue † \color inherit . \end_layout \begin_layout Subsubsection* Position \end_layout \begin_layout Standard Footnotes are supposed to appear at the foot of the page, but that is not always possible or practical in web pages. Huge pages make scrolling up and down quite uncomfortable, and remove the immediacy of having the note in the same page as the referring text. \end_layout \begin_layout Standard There are a few alternatives: use the margin, show hovering text, or link to the note at the bottom of the page. eLyXer can use all three. \family typewriter --footnotes margin \family default will place the notes at the margin, just as margin notes but with the addition of the footnote marker. While \family typewriter --footnotes hover \family default will show hovering text when the mouse is placed on the marker; this is the default behavior. Note that hovering notes are converted into margin notes when printing. \end_layout \begin_layout Standard When footnotes are shown at the end of the page with \family typewriter --footnotes end \family default , footnote markers turn into links. The actual footnote at the end then contains a link back to the marker. \end_layout \begin_layout Standard The most interesting part is that these three options can be combined at will: \family typewriter --footnotes margin,hover,end \family default will show footnotes at the three possible locations. The most practical combination is probably \family typewriter --footnotes hover,end \family default , which will show notes as hovering text and also at the end of the page. Note however that in this case notes will be printed twice (at the margin instead of hovering and at the end). \end_layout \begin_layout Section Work in Progress \end_layout \begin_layout Standard As you can see eLyXer is a mature and tried package, but it has some rough edges. \end_layout \begin_layout Subsection Known Issues \end_layout \begin_layout Standard The following issues (including bugs and missing features) are acknowledged. Some of them should be solved soon; others may take longer. \end_layout \begin_layout Enumerate On Mac OS X the output of a message with Unicode characters may cause an error. Workaround: run \family typewriter elyxer.py \family default with the \family typewriter --quiet \family default option. \end_layout \begin_layout Enumerate Some phonetic alphabet symbols are not well supported -- if generated with LyX they only appear in a different color: \begin_inset Formula $\text{\textipa{[sample]}}$ \end_inset . \begin_inset Note Note status open \begin_layout Plain Layout This happens only in the HTML file converted with eLyXer, not from within LyX. \end_layout \end_inset \begin_inset Note Comment status open \begin_layout Plain Layout By the way, the previous note (and this one) should not appear on the HTML. \end_layout \end_inset \end_layout \begin_layout Enumerate Multi-column layouts are lost. This one is almost impossible to get right in CSS, so there are no plans to even try. \end_layout \begin_layout Enumerate Many BibTeX styles are missing. (They are quite trivial to add though.) \end_layout \begin_layout Enumerate ERT (bare TeX code) is ignored. \end_layout \begin_layout Enumerate Many AMS environments (like \family typewriter alignat \family default , \family typewriter gather \family default \SpecialChar \ldots{} ) are not working or look strange -- some non-AMS environments too. \end_layout \begin_layout Enumerate Images are never scaled above their nominal resolution. This is seldom needed if at all, so there are no plans to change it; if people really need the feature just let the author know so it can be added as an option. \end_layout \begin_layout Subsection Wish List \begin_inset CommandInset label LatexCommand label name "sub:Wish-List" \end_inset \end_layout \begin_layout Standard The following features have been requested by users; specific people are referenced by a couple of initials so they can recognize themselves while keeping some anonymity. (If you prefer that your initials do not to appear here at all just let me know.) \end_layout \begin_layout Standard Queued features will be added at the next big release -- the priority for each feature will be set by the number of users requesting it and date requested. Pending features need some assessment. Those marked as too complex have been evaluated as requiring too much work, but the decision might be reversed if there are enough people interested or a simple way to implement them is found. Once done, features are marked with the first release where they appear. \end_layout \begin_layout Standard \begin_inset Tabular \begin_inset Text \begin_layout Plain Layout Feature \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Date \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Users \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Status \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Understand \backslash setcounter{section}{1} \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 2010-05-15 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout JB \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 1.1.0 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \family roman \series medium \shape up \size normal \emph off \bar no \noun off \color none Option to turn off title prefixes in TOC \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \family roman \series medium \shape up \size normal \emph off \bar no \noun off \color none 2010-07-10 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout YG \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 1.1.0 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Use BibLaTeX with eLyXer \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 2010-09-14 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout PJ, WE \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Pending \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Render change tracking: "Show changes in output" \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 2010-09-18 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout YG \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 1.1.0 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Option for footnotes at the margin \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 2010-09-21 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout A \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 1.1.0 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Output SVG as \family typewriter \family default tags ( \begin_inset CommandInset ref LatexCommand ref reference "sub:Output-SVG-as" \end_inset ) \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 2010-09-22 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout YG \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Pending \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout EPUB output format ( \begin_inset CommandInset ref LatexCommand ref reference "sub:EPUB-output-format" \end_inset ) \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 2010-09-23 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout MJ, MG \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Too complex \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Option for footnotes at the end of each section \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 2010-09-23 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout MJ \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 1.1.0 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Add more controls for image conversion ( \begin_inset CommandInset ref LatexCommand ref reference "sub:More-controls-for" \end_inset ) \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 2010-10-02 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout WE \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 1.1.0 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Support for format 401 (Insert Horizontal Line) \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 2010-10-06 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout US \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 1.1.2 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Parse contents of ERTs \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 2010-10-06 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout US, JW \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 1.2.0 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Correct scaling of tables with relative sizes (e.g. \family typewriter %col \family default ) \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 2010-10-09 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout US \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Pending \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout BibTeX: parse math formulas inside BibTeX files \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 2010-10-16 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout JA \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 1.1.1 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout BibTeX: display \family typewriter \backslash url{} \family default as an URL \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 2010-10-16 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout JA \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 1.1.1 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Do not label bibliography items in comments \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 2010-10-21 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout JA \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Pending \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Unit tests should warn if ImageMagick not installed \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 2010-10-24 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout JA \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Pending \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Unit tests should run fine without PNG conversion tools \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 2010-10-30 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout JA \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Pending \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Option \family typewriter --imageformat copy \family default to avoid converting images \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 2010-11-12 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout JD \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 1.1.1 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Option to embed the CSS in the HTML file \begin_inset CommandInset ref LatexCommand ref reference "sub:CSS-controls" \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 2010-11-23 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout GM, JA \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 1.1.1 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Display sub- and superscript aligned vertically (as in integrals) \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 2010-11-23 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout GM \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 1.1.1 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Use Unicode large characters for sums, integrals, matrices\SpecialChar \ldots{} \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 2010-12-07 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout GM \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 1.1.2 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Do not number captions in code listings \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 2010-12-08 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout DC \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 1.2.0 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Support brushes for \begin_inset CommandInset href LatexCommand href name "SyntaxHighlighter" target "http://alexgorbatchev.com/SyntaxHighlighter/manual/api/autoloader.html" \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 2010-12-10 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout DC \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Pending \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Generate formula images using Google Charts \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 2011-01-07 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout ET \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 1.2.1 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Output reference arrows as CSS pseudo-elements \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 2011-01-12 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout GM \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Pending \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Include part names in \family typewriter --splitpart \family default navigation header \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 2011-01-15 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout AJ \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 1.2.1 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Merge options \family typewriter --toc \family default and \family typewriter --toctarget \family default into \family typewriter --tocfor \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 2010-01-17 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout JA \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 1.2.1 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Make \family typewriter --splitpart \family default and \family typewriter --tocfor \family default work together \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 2010-01-17 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout JA, TP \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 1.2.1 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Generate named references (equivalent to \family typewriter \backslash nameref \family default ) \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 2011-01-19 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout TP \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 1.2.1 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Do not generate entries when index or nomenclature are missing \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 2011-01-19 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout TP \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Queued \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Do not output unknown commands in red except in \family typewriter --debug \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 2011-02-22 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout JA \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Queued \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Output equations as images \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 2011-05-31 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout GK \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Pending \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Parse modules for custom Flex CharStyles \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 2011-06-08 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout MG \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Pending \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Convert several files with a single command \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 2011-06-01 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout PF \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Pending \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Export slides as HTML5 presentation \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 2011-06-28 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout RK \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Pending \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Add an option to remove navigation bars \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 2011-06-29 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout AH \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Pending \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Support for External Material: PDF, Date \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 2011-10-22 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout MI \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Pending \end_layout \end_inset \end_inset \end_layout \begin_layout Standard Some features require further explanations. \end_layout \begin_layout Subsubsection* EPUB output format \begin_inset CommandInset label LatexCommand label name "sub:EPUB-output-format" \end_inset \end_layout \begin_layout Standard The EPUB management package \begin_inset CommandInset href LatexCommand href name "calibre" target "http://calibre-ebook.com/user_manual/conversion.html" \end_inset does not output valid EPUB documents when converted from eLyXer HTML files, at least according to the \begin_inset CommandInset href LatexCommand href name "Threepress validator" target "http://threepress.org/document/epub-validate" \end_inset . \end_layout \begin_layout Standard This is a complex feature request; calibre does minimal formatting in its EPUB conversion, so making it generate valid EPUB documents requires changing deeply how eLyXer outputs XHTML. Lots of help would be needed to get this working. \end_layout \begin_layout Standard That said, EPUB readers are often much less strict than the official format and they readily accept eLyXer output. Just convert your LyX document to HTML using eLyXer, and then import the resulting HTML document into your EPUB reader. Let us know how it goes for you. \end_layout \begin_layout Subsubsection* Output SVG as \family typewriter \family default tags \begin_inset CommandInset label LatexCommand label name "sub:Output-SVG-as" \end_inset \end_layout \begin_layout Standard This feature would be most welcome from the part of the author. Unfortunately, Firefox alone from the major browsers refuses to render \family typewriter \family default tags correctly for SVG. According to \begin_inset CommandInset href LatexCommand href name "bug #276431" target "https://bugzilla.mozilla.org/show_bug.cgi?id=276431" \end_inset , this was fixed on 2010-09-08, so the next version should do the right thing; at that point this feature will be queued for inclusion. \end_layout \begin_layout Standard You can check out how your browser does with SVG images with this \begin_inset CommandInset href LatexCommand href name "SVG test page" target "svg/svg-test.html" \end_inset . \end_layout \begin_layout Subsubsection* More controls for image conversion \begin_inset CommandInset label LatexCommand label name "sub:More-controls-for" \end_inset \end_layout \begin_layout Standard eLyXer uses ImageMagick to convert images. Some images (in EPS format, for example) do have blank borders, or they come in varied sizes. It would be nice to remove blank borders and have some kind of unified resolution in the conversion, which would be passed to ImageMagick. \end_layout \begin_layout Standard As of 1.1.0, the improvements include using \family typewriter ps:use-cropbox=true \family default in ImageMagick for PostScript and EPS images. Unified resolution has not been added as it might collide with picture density, but suggestions are welcome. \end_layout \begin_layout Subsubsection* CSS controls \begin_inset CommandInset label LatexCommand label name "sub:CSS-controls" \end_inset \end_layout \begin_layout Standard Proposed by JRAS on the elyxer-users mailing list, the following is a direct quote of \begin_inset CommandInset href LatexCommand href name "his message" target "http://www.mail-archive.com/elyxer-users@nongnu.org/msg00194.html" \end_inset . \end_layout \begin_layout Standard \begin_inset Quotes eld \end_inset [\SpecialChar \ldots{} ]A mixed solution for CSS styles: \end_layout \begin_layout Enumerate The essential minimum css for math formatting (a compacted version of a \family typewriter math.css \family default subset) included directly inside HTML head. \end_layout \begin_layout Enumerate Then a call to download the on-line full CSS, that can repeat the minimum already included \family typewriter math.css \family default (from item 1) plus some other styles. The default can be changed by \family typewriter --css \family default command line option. \end_layout \begin_layout Enumerate A new option ( \family typewriter --addcss \family default ) to add another CSS defined by the user. For example, to only redefine some styles from the default, etc. \end_layout \begin_layout Standard The styles should be included in that order (using the "cascading" property). Item 1 is fixed in every HTML file. Item 2 is always added and by default pointing to the eLyXer on-line css, but it can be changed by option \family typewriter --css \family default to another url or file. Item 3 is optional and its url would be added after the other two items, only if the \family typewriter --addcss \family default option was used in conversion. \begin_inset Quotes erd \end_inset \end_layout \begin_layout Standard As of 1.1.1, an option \family typewriter --embedcss \family default has been added which allows embedding one or more custom CSS files into the resulting HTML document. Also, \family typewriter --css \family default can be repeated as many times as desired to use several CSS files. \end_layout \begin_layout Subsection Contact Information \end_layout \begin_layout Standard If your problem does not appear in the above list, please let the author know; you can find him at \begin_inset CommandInset href LatexCommand href name "elyxer@gmail.com" target "mailto:elyxer@gmail.com" type "mailto:" \end_inset . In the words of Rich Talley: \begin_inset Quotes eld \end_inset the tool's author really likes getting challenging documents and making eLyXer work with them \begin_inset Quotes erd \end_inset . You can send your sample documents and we will try to make eLyXer convert them acceptably. Any documents sent will be treated with the utmost confidentiality. \end_layout \begin_layout Standard You can also join the \begin_inset CommandInset href LatexCommand href name "mailing list" target "http://lists.nongnu.org/mailman/listinfo/elyxer-users" \end_inset to discuss any information related to eLyXer. The author monitors the official LyX lists for mentions of eLyXer. Bugs can also be reported at the \begin_inset CommandInset href LatexCommand href name "Savannah page" target "https://savannah.nongnu.org/bugs/?func=additem&group=elyxer" \end_inset . \end_layout \begin_layout Subsection Extending eLyXer \end_layout \begin_layout Standard eLyXer should now support most LyX features; but sometimes it will ignore a command, sometimes it will signal it, and it might even refuse to work with certain documents. What can you do if eLyXer does not work with your LyX file? Worry not! Its flexible approach to processing allows anyone to write support for the missing commands. \end_layout \begin_layout Standard eLyXer is written in Python so that it does not need to be compiled; its code is interpreted on the fly. See the accompanying \begin_inset CommandInset href LatexCommand href name "developer guide" target "devguide.html" \end_inset to learn how to extend eLyXer for your own purposes. If you know how to program in Python it should not be difficult to support other LyX features. If you don't your best bet is to ask the author. \end_layout \begin_layout Section FAQ \end_layout \begin_layout Description Q: What versions of LyX are supported? \end_layout \begin_layout Description A: The tool should work with all LyX versions from 1.5.5 to the latest and greatest. It has been tested on Linux, Mac OS X and Windows. \end_layout \begin_layout Description Q: There are indeed \emph on a ton \emph default of similar projects over the web. Why add another one? \end_layout \begin_layout Description A: The four tools supported by LyX (tex4ht, hevea, tth and latex2html) gave inferior results in 2009, and were quite inflexible. The author found the need for a good converter, while at the same time acknowledging the difficulty of the problem. \end_layout \begin_layout Description Q: Speaking of that: why build a LyX to HTML converter, instead of a more generic LaTeX to HTML converter? \end_layout \begin_layout Description A: The problem space is quite simplified, and therefore progress is much faster. To make it even easier eLyXer has historically centered on the subset of LyX functionality that is useful to most LyX users, leaving the rest for a later stage. Nowadays eLyXer aims to support the full LyX feature set. \end_layout \begin_layout Description Q: What can we expect from the tool in the future? \end_layout \begin_layout Description A: eLyXer should fulfill the needs of 99% of LyX users in the short term. It has also learned a couple of tricks of its own such as page segmenting. Eventually it could be distributed along with LyX as part of the standard installer. \end_layout \begin_layout Description Q: Why did you leave out my favorite feature \emph on \emph default ? \end_layout \begin_layout Description A: In short, because nobody asked for it. Every feature which has been requested (either to me personally or to the list) has been tended to, unless it was too far out or I forgot about it. At this point of development every missing LyX feature will be considered a high priority item for the next version, if at all possible to implement. \end_layout \begin_layout Description Q: My document changed its appearance without my intervention. Was it black magic, elves or what? \end_layout \begin_layout Description A: It probably uses the online CSS file, which is regularly updated. See section \begin_inset CommandInset ref LatexCommand ref reference "sub:CSS" \end_inset for details. \end_layout \begin_layout Description Q: Why use an online CSS, instead of placing the CSS file in the same directory as the converted file? \end_layout \begin_layout Description A: There were pros and cons. An online CSS resource allowed me to update it for everyone at the same time, but might make it more difficult for people without an internet connectio n; local CSS files are more flexible but can also be confusing to novice users. In the end the online solution was preferred, with the \family typewriter --css \family default option as a fallback. \end_layout \begin_layout Description Q: My MathJax pages are not rendering correctly; equations are silently ignored. \end_layout \begin_layout Description A: Check that MathJax is installed on the same server as your pages; for security reasons the browser's \begin_inset Quotes eld \end_inset same-origin \begin_inset Quotes erd \end_inset policy mandates that JavaScript can only be loaded from the same site as the original page. Also make sure that JavaScript is enabled on the browser. \end_layout \begin_layout Description Q: How can I disable hovering notes? Isn't there a \family typewriter --nohover \family default option? \end_layout \begin_layout Description A: It can be done using \family typewriter --footnotes margin \family default . This will disable hovering text but keep footnotes in the margin. \end_layout \begin_layout Description Q: I found a bug, what should I do? \end_layout \begin_layout Description A: Just send it to the author at \begin_inset CommandInset href LatexCommand href name "elyxer@gmail.com" target "mailto:elyxer@gmail.com" type "mailto:" \end_inset . You can also report it to the \begin_inset CommandInset href LatexCommand href name "Savannah interface" target "https://savannah.nongnu.org/bugs/?func=additem&group=elyxer" \end_inset . \end_layout \begin_layout Bibliography \begin_inset CommandInset bibitem LatexCommand bibitem key "wordreference-elixir" \end_inset WordReference.com: \begin_inset Quotes eld \end_inset definition of elixir \begin_inset Quotes erd \end_inset , accessed March 2009. \begin_inset Flex URL status collapsed \begin_layout Plain Layout http://www.wordreference.com/definition/elixir \end_layout \end_inset \end_layout \begin_layout Bibliography \begin_inset CommandInset bibitem LatexCommand bibitem key "xhtml" \end_inset W3C: \begin_inset Quotes eld \end_inset XHTML™ 1.0 The Extensible HyperText Markup Language (Second Edition) \begin_inset Quotes erd \end_inset , revised 1 August 2002. \begin_inset Flex URL status collapsed \begin_layout Plain Layout http://www.w3.org/TR/xhtml1/ \end_layout \end_inset \end_layout \begin_layout Bibliography \begin_inset CommandInset bibitem LatexCommand bibitem key "html-401" \end_inset W3C: \begin_inset Quotes eld \end_inset HTML 4.01 Specification \begin_inset Quotes erd \end_inset , 24 December 1999. \begin_inset Flex URL status collapsed \begin_layout Plain Layout http://www.w3.org/TR/REC-html40/ \end_layout \end_inset \end_layout \begin_layout Bibliography \begin_inset CommandInset bibitem LatexCommand bibitem key "w3c-validator" \end_inset W3C: \begin_inset Quotes eld \end_inset Markup Validation Service \begin_inset Quotes erd \end_inset , accessed March 2009. \begin_inset Flex URL status collapsed \begin_layout Plain Layout http://validator.w3.org/ \end_layout \end_inset \end_layout \end_body \end_document elyxer-1.2.5/forks/jras-elyxer/docs/pipeline.png0000644000175000017500000001312712117061342021172 0ustar chennochennoPNG  IHDR%bKGD1 pHYsdd vpAga6IDATxyxT@LSZB E  "BP@@AAيd"aP-,E#V}_ET(ńr?~;3l7s2ޙy,w{3s=M4 DD0DZ*DCbR "RBDJE]h(YZP89}زh蚘%C%/سZP80yZX?DCbR "RBDJ1TH) )P!"*DCbR "RBDJ1TH) )P!"*DCO?U&F6kgMn?Oicl.?/<%^=uk`8S'`Wcͭ^'L~hʸ[iQgٳ4MVDE5kex~ׁ9s -Y[7&7ҀiӀɓDyˁ)S1c hgfk~n+VHm*࣏G6oN&Nyش ؾ(_qxvwr%::x֮F9x1_8sF@AС/y4- */oGu]uk-)SW^ʖ99!nV7޽#۷Sv,̜ $'fʷـ}jU ?(h*\8xP13Q?Yn,&?{{ ;XQhp˗i&n߲Z?2R-㸔)~YOk>`s5ĉءi:hE+д(:?k͜i;k+hښ5vku]M+UqoU+#umߢǏ/zVq ~L>}t4w}`NiSѢ_q;lm/;>~dqq I>x+W/Ja]`2ϯSKjTKYzhN8ZXNЯ,?upYE-*J'&Fag̐uJƎUW~rRݏ?J7ӟx-Z5zU}8 Ԫ0xu7lsn.в[]vm]u CBڷ7drE)op_Uu2\vZzʕٳY`ǧOȐܱccLӲ޶{IX׮xU`. |dM&ξ)p@*6ț.!\V ڥRc*[׼MVL I-TH) )P!"*DCbR "RBDJ1TH) )eig͚] '@׮F,*W]""RBDJ1TH) )P!"*DCbR "RBDJ1TH) )P!"*D%O}p*pѵ O] % ہKF-YP!,*e@&FOk@c*DCbR "RBDJ1TH) )P!"*DCbR "RBDJ1TH) )P!"L}7۷5DŽ @v60>iFow8p4Mθ׸ѵ$2Mܺ8-OӀQ$X7yHJ ~fΔ#:ScYYӦ]K2+ӄ?+_pPSO-u` 'GnGGGQQ{,ЭЦ 0oD:-M>p')/G/Lƌ22{,_gfh׮3fyy+VHŝ,՗I4 @n<>x><h0i^ uqԯS' D=oв%opܷ{??\ϗV[J P*ߖ11@^(0}l6-+^n /@Z/LRСе+@ll_B`y[s8qdg{>}%r2P;wMGҥZD}KYzhN{Vw},'O~[g,yi٨,LL3be\c~֭]I۶@.rfzՂc1PrE)op 9wsٵj`.}l;x^m/p=sc?#oeIwTϗݬ FׄxaR @zǎ;v]+"c1TPnxL'҃"RBDJ1TH) )P!"*DCbR "RBDJYrr~卮]jt (X2T7s|5'0j,* ȅ̇c*DCbR "RBDJ1TH) )P!"*DCbR "RBDJ1TH) )P!"*DCbR "RBDJ1TH) )P!"*DCbR "RBDJ1TH) )P!"*DCbR "RBDJ1TH) )P!"*D&iBd5 Cv6j/F&+P5 C] ,] ԩctmBOǎ?]0TH́|}{kzt‚5I`*~T;GH`k+@ҭpѵ]]]1TH%CZݺ>jt-c =x衢=BaA`Lkaс=bROYYF\6Rq^Sc}l eF=bR/52~ѝ7b 0rkk'.֔>|ӄJr!w[Z9&&P]|&T,1D?,Z+gtMu2 X7j ciBL^rs?5P=5+ק=xC%?4lHX 8vLxB#|/yaR%K榻x[9nk W5&f2tJd>0)ФU7CKEa6&|l&As̖t.̝+ǣ\Wȑ@>OQr$sDЯ0{6KjTהݟo%/X!KLG KeBox.w 9.A`/uU 'Bʔ}V_7 ܼ)/\̙#LT`bvm_oV2TBPժu@jmٺGq\w>sc.m rZM.mʮPgIר!Z&M_Er/;-t<8/gq#PLsk476L8*Un{ų=*!]y-]ɓe|c\;qs4ܼ 9bt9^&5UZs[ȶ[7|Ykfd_{ѝˁO>퓩/~`vM*6^Jz%6~IjGFEUIef9(1/OE2^gP``Na{7bb|^ ᓘ(c2`xg?(k;SҚ/eˀ?s ̮'5i"c;˷g^0p Ыs?(XgKhw|ԪY#鎼 /ȷܯ L ~`C)2g[#8*Tc2~} TWٻΊ}7Nu={iƹ+kԐVRi@Ԡ뛸[弩&9߼Y=bE`s:y1uℴcc / 98;+K S r;"B۶I𭷀+m``YMFRߗ1I7feʘ7ny~,9Yn.]ܟ"]SSsVvNO@ٱL2rW_ϟ.;έlDڵq?AΡ:a5jՀߖ>+J(~5}_)0{hHH@+V_.%EZG /"_ݟiu2b:i*ѣ[Ic RSeP ߷]Ҳ=RRB=v\<-|y[+ a|+]SSTJdOW r2ZgRSV[isn"Ǻ|]a΅ѳ,IB=9[HԬ)~A[yMi͟/MpoP[ѷ/p\vOZ._23]{灕of| =oRzYiϛ Vrn$-YL}L*[KS|FY -M9Bd=o ')J7Թ 8(ɞzO)Ba *v箨-\zOq=:dFII\箨-\zOF~=%&A:=ho{F4soByϛ |oG+;+/ؾ]Z+qq;TҶ;܍aV]y"IocݺorΘ! 2 k?׆ @VE?Pih6[&SR k/eIo'vr/=ȋprz:  {gʷ7XCƍ].e"R-I^kaz:-N/E7\eZ[MO& =;0&1|!hR!v&'y:kr "7‬&\~B_^"R{H) )P!"*DCbR "RBDJ1TH) )v@3%tEXtdate:create2009-11-19T00:47:59+01:00q%tEXtdate:modify2009-11-19T00:47:59+01:00uBtEXtsvg:base-urifile:///home/chenno/projects/elyxer/docs/pipeline.svgDIENDB`elyxer-1.2.5/forks/jras-elyxer/docs/elyxer.png0000644000175000017500000010234312117061342020674 0ustar chennochennoPNG  IHDR_nbKGD X pHYsdd vpAgIDATx}w|iջdɽWt 5!$@H $! ͗PrC rS$Z l{%]q|Z gvfvvy9(Gr!q>r!ӅC9!-rC9[0r`90n#ra"G9øEs!qC}nv۷ottttttJRT… .\̜9s̙sᣍ~@x<x^{5oxcqM7X,xӦM6m_׿50}ӧ!b{o xgy Rp8l6f qؿBP(<3>8]N%X,:uԩSzAhrFٶT*J,^xOӟ{rÍ,}w}z5׈jZV B“W6&D|^>>[nݺu89C:rNQz^೟g?Y3f̘1Cl+Zbz„ &Lo߾}M0\`׾}k^X#ɖ͛7o<`֭[n=ݣCnpPYYYYYyG3> // @@"qF0N,8Q"ljjjjj:묳:ԟo9|#8|ÇE-3-8dIr'[5838Cw99hxㆍ6nn馛nr(#GGqA%fk׮]_$r =p8,Rm."JٳgϞ ̝;wܹms#q ̕ :eZ[[[[[E5믿?ݣCM{ pǎ;vH_/wp`0 ?NG^{}rxqD=BDI:Xexȗ9p,{99|Ks=sb3qx,ǀD2LAV@JR Dqat9ʋ0N5M ywySH$' )gKޠjI!O[t\. CP8}{6dlgȮ]v\r%\r n&nx'H|#W >H>^]۲USؽ{ݻ}s瀫ꪫ:ݣs7s4b2K:N$Ï;-r?9kNh}+_W\p\pV=CP0Ę%x<uH$8tFC ņXAWJljh :@5B<O8_AorDqŸ%@Νc$w$Dwwq{87Fc]+sk7F{--@0lLħFv`}60uqK$@ɖ?ªHėL9o B^/eL9L$B!Z~gNdr8> @3NMa8Csx``OwOwOg$"z[oN;ZZzz\.Z ==N{tp:=@Fcx"8F^Q6ɨ7v֖0aByy~>-mqca?Hr<"})/ 1/2T5fIY%H(X%>(~O\O||>ut w77w> KK+\n7f3{`Lz=i4)P4 `$8mOTV \yg6L~Lt==OvZ( H&c1"HzA{&@h j]PzBҳ8xqK 87567 bx" X,FN,Z4uje%0yrUUa!`Lǚ ? vdb_yE8)AP(J">RZ P(J$7onoVZaȑ~sp^PRRTK~]p՗_>e PPp~7FjTlEcјD>QYOvRbjG"776+WnDxW+_.ILZVI9[irU;zW;Z46 'Vضs"($ .; -) I.ٞ@cAUؒ?4ЬJ%/ZK rV՚@QQQ"~. kp2}D?ڵ֭;vtwC]qt"h(Iq̀Vk4׋9hb`65K/KEaґĵk| o܉ʀYKK`J2+٬k4@UJ%I0iD2IR<hFDbd2-Blk˾JR߫V[{7v`-+w Mm#=Շw:?=UW ɚ YNsDS?Z +*****F}-[}ZZfϮΊ8Rl7Xĉ'N*2l`<d a[`-0 9뮻ɌFcx}q @_Sgח ee!p۳\7L ,P"cbDUWs@_/ ^lTj5:0w~|艏1n .ᅣQvrªU{V\ӫ,,<'%>(G?oF<jl z!.nǭ.]|~`Ŋ+{/뮛>">}iʄ\t(&l b1zaA`fc'_G^O5F r*L:G'd2k׬YBbŋ/ 5W׿h<<ˆqK555555믽k/7ܱhX` ʉU JKm6,G(lB*4^N8>Ea7&eBPXeg"KPr 1z p:~߸Esc悂+>. Ri4aFfh4juxp  7pu3fU4X7FgR-;%%:ߏ 0޳g&薽 ^@ uPzQ]Uէ?կĉf*@کD'MM>D4_׬ M;= p$֖-U^-ȆrcȾcǮ]==d|Km%?yoV{ϣu T$a={zz)/z j.ۏYFlϦΙ3sfi)pyg]SYnX/jjk'LN22f/NG7H"Àӹe˻JtD.W_?V[,v;`6N8 bdkVrDˣ\nO3355TWrz0ɽ,y71A2fS}am:;r/TjupIf̸jihZ|$ |>_4JI+**(3;omBQPd JRT|xmׯXZl08aoX Z^PM'Es䕀^_RRUED' +ަ={#Gx}3f~jq4q'9̂-[P(;Z O8;4D<HdF__kDKx1*c,O-3W"ql4L|`EnXwyɫd/~fL&`Ui2Z`ܹ_sʹiuz2e9sn%R5{WI{er"^$x4tBu5%<6/PbyrT׮_xǀ/&`ڴ|#,Xz玖fS/[;?)N {kى!kabx9aq}^Ri zEŋ}}vZr\ٳYawtwG痉ٖ7})EE…WT+%l{͙S_L#~PU^~?js} ݗZ":m9sPM&EJpx}嗁w |O~~~&Ӌ7< }rc{IE",`0Ղ &y72y 4Kx|!ό+,r4|'m):o8nߗCbK/zdE""9[l;kP^p$J(ɃHھ]BtGmt>_Kˁ"b4y@/.N OmA&˟xڱcZ`˯XUNr(Ljlۓ8$E}rfiVUYcdKL\͈` DPUzad+Yg{WB޻>,ӱl#IRFE#;sY()"8УuFQoAo'R6n|MRY/׭{5 xϱd<hf]pF|8 ѱtق`¿ujbih9Sz2G% <ާ:(GG ue(*cKL@$r,Ejm6%#o|@XvÆtK~\_~2V/o6LNT__P^Eh2F"n|@w7 qΝPRl6W]OWy]x]۷*pHsݔ!~ 孒Iz1BE.)).XrI 's޼y^]N#"A```ݺ_WZ pnL)_p0$N2L&`(-$G}X\}}D|3:ٿ͋o*QZ*prǣ(?(c(vhj/;=&B7V:XR \哟Iʷ3oXq^:q\$HZNG=7(WoojsfΤ:]&fϟ:8%KN9碋(~1s:ɶ:8Hb8,RJdOq(0x,lv՘A {z$UJHuڱc: D"lS*5RY&wTE0u+O>  &ΙL@4j4g\6⓯#8xu0zx$⳥Y,6ĉ@__ooKKLFJZ{@?DJ"dpe/5])"_ VQU*P,>uۺW:/v8"rL-`ʔ"/o tz@omfssڵԸna3#͊%GXΝQ٪+|*+{!I[JdcN71=67wu9@⨱ >0P\&`0kkº:1vM;8 }tÆ'뮻ʩSPRGA_TE[{;vVfR`WXZ,WTdL@^y9>%HQ,ٹCCTvlLuȑ@xJ}|A&zTU}<]q7ڇ] t:E 3OZZIih:֖꫁l4~:lG͛Q|3^;}:pphLR\"Pb)Jںy3wȆ ںe &n"-[xܽGKZģUHz0 ,Ued߿mp={„f}T`Ҥ)Svؾ}ӦnԔ~ .¡u6ShTd2si%%?yf'L+*Uh#GF'AeZMha`vv (_HP 9(|?otf{'Ϝ}NMg>̚UZdɇ_ ;:$F{z3\X'Ϛum@OOwwK =5:75ҋ.jhniq(JS=? @'L&2Uj,8o}Kx&'PsswuIu. ?ȑ  Ob1)14xi!m `XZ֮4iR ~ ꫧwsΩpALώw㜹?1xqmן{48^ cpyٵkE;˓e5{zm_>{vx7F4 uu+Wگ~4665h~rP^^V\~UW}{O}kywݻWBA}m={eFhmݴTw<>wu.׶mk*̙W\h4_ԑZ(bH6p8`0dظnᦦXlz=LՁV/XCK|o[7( ÆqKk*;&M,(s'OِHbCC޽۷o$Jԏ:U9Ef;㌯|j L҆ ZظaPP@ѱe VӎÏ7MM}mFCJ%Gňh2i4dHIBlm=r$6n\k$@@]7PEQFwr 0"*c@8|HlRS Js$(Tc*BA6چ8xpa  (>@a2Io=ZOjz n _N⊥K*=>+(u*x]v٢E RWT9eݺ={ہUvlkBg/ r`T'*ahtwG"@oogg4J )V#"J}K];٬坂lwt(J%WTZsz.gO~̸!p8 ;iR)6*Ѩ̚E&a'\3mR #‹/Ry"A6,ʢqpR TW:$Q*EؔFѐhT"dp8"Jٽ.$SUuPX%'BqJ/BJ>kyT!Kz>kp0YBd8q2Gb1}I T )jMU~M&p/~v-,X|S~'9Bx{/֯߿or`۶ë=J= Jnj/ >}˴bm<( >cQ ۠ /F#"X 0&&I (DT 72`  Ӧ>0sf~>`it [>rٳu+wt $S\v ^r  â$>VJTRQx Wju:l|j5*P\\Zj0-/z{~'7o‚`PJ|,*"t:ry"Et[UU0sfYم<'G^w;;Kׯ`۟SdTV>JT&"e.tf~^O·onu}>RiB"~h4 //?_%O Iq9Z-NfJEq( `ggPTBmoomP0Iz1JˮJGU>E3"RaƬrQ6$ZhT!Z6*Idɮ7&O6nEEڿxزeffh)L&c1tn'U2.W_/I%.䱪S(P[A 55uuf30{y0s9yy驆,:4 v  B()``NP(ZjԪ 74Og9dopz W__0HHfQ*ɓb0 j5e )DR' j4B!z}RT0 E۾{vn3ibMCKO r+|n`׮ěBQ(x\F?Y 5p8 o>ݣz^x lFXLp:Is損#Fi11j+@Q%PIecf'AGGk/kϞ;)LǁŽlljȬ`#$*VD@8];+Wٹ! ?&BCL!" '@wwGG O*<;gXu# ,)-ٵkhT~[LLulZ-5~>^=kOKLH^CGuum<ҥ_DiHdω!H x, ~xnj_yDyG?NTUVĘ'N*{9ۉ8.m`v SQ B}0^dVFYfU!4I@t|1ft>J%_X$b$h&2"BoIYU%ekkK xd\^b֮]b 'On]ORʜ h}{$AS*ǶZ-ۻ曁 .hhE18M5͛z Wz/ єnFLMW%BRX鮻A1_oϼ 2g9A^?}{_g>N2PPihx|۶F/ ӠP'GIIi()"77{-7 o8_Z|=5xgd(ϴ_cyQ R8GDDŽ( ,9J0F/ -J3E]۶ TT?ϦOn_N-[6n<\Q*M&^n@'O;ڵ-_<ҥwTT8& Ru  2zaT#FBQ[ 8&ӝwm8Ip#m|9?TPhӦ/Y:Qj[,ƶ> .rZT@AAq^O*\2 dZVL74$Dj5BP@XrD^bjMl:y8}=tCN*ቜ`,KmBeN  1 /?"(/2EBDz=6 vSbfY;J'4~dR>|U5?[3i#M| ׿z۾ TTLzhӛZ2PXRTR̤*2b0k$PVr=_رM9i\Z{@2cbHm}4 %1zn*6@ l~Z-ep@磔.A|DtVB^[*P* I62%A":@A U|:y>؋G,AJeDT;R^^Yi0&"fhŠ{zC!੧x. `ƌ3v5(i<ġF"ΝnYg6^_Twliۿ{/} | /x ^OKӛ"}{熆~ʭ[FOp 7l>qr0sfU~W'+TORgSU3}_;+X*<>X2E! @jٴZ``/NA Ϫ4KDR"H$,WGIU%! RYF2I*'-(µIR '(*HU9ABVKN^f 8CG"dZhQZm;TxUJJJJt:!ɳ`pX=}` ??H4 SUV-\HFOzAC/WqJJ %Kv]:q2&5=Aw:OJ8p#'H9ƫ$g4vwl9BەJ 3v Y5|]  T;v]G6)RyS%d}t@߁~ʰ`FkJ԰La)T[tD*1r聁P$&"t"@n)$S&{dD+g"Z8KR%@2 QJ|&HZ"@ ǁPHHbaɯ;yOvZ$PPP\l0nEȚ9]]_>e׿/[v]"s$/m66;zJR&qn|+5J,LJu޽$9&hTyWZ5DPGT#;E|| .4?8`45YPA\6@s:[ZK.O T$N?-%>NPFi dcbgYH$u MXlLP, TD`*%^)%@X"#M.踉K"PNlMgN!$g65<Թ"^d԰FF =D+O06[^HIЉݻd@ƙ0N9]o߲ebɨ*,4)=YqzcDP=P*H9~(UrB*FC.KD\ɤqih &^1NǍPJJVoqϋֶm`4mJ 46D BdvldfG}3\ Ι^̦ `@`-Gְ75?2*hLiiyHHWI"epdmfŢVSj pLț6_tjuuT@mCCN'[K}xCDJll߿wߒ-[S>;v{G:$9KIy95xD%~PZJ, vMy  U?XBiDp?M ~` Q'87yR@IɊ5Ւ$w?p DJK'Oa;:LIUؤ!5IH/B;dKg@dnxTOPJ[(D&K<$Ad:/a; S|9U(JޟcmTsu{ PmڨڂA47*S٤!@b8X2: hnܺ4૯n닊J"zb(RJlTeW*dYY$Iңb0h BtV+ U|}]JUPl|,!21TJWTeAe $T.i`7D#g NR؊<:' OF5zhȟI2a0t;)R!NdddI ==ԎHH,ѵ81 ZFTTTWSYf*T_:;NXm>s>F/6;s {9QJeEi?>_El:sv Iy$}{AZVFD@Smy=*5m4(YU8B3DRdB!U~L{eRY"[H2I&@MGBa6j5Zttju^lStHZN @ns{~qr}1IQ6KK:;'M8_B~L0p^oX\Z({R?D8|!c$ IhҔiDj4 \bJ|lz'*K V*bNh繐j4JĞ)%dN6iJpߧ`;JR<^T*-XHE"4j%G^U<^T(L6L7?  Kw0r'?TN ."k(Dc̉L<*Hq r! JI׋WS y4AGKŒ+4%D5ĒIH_\.RWG,r> ddxhQTeh4_I It_89%'4X hnnj2щ%k}h ܩϓVKϪ5+k!YJPL$V9rxd5b` l3o߫>tSXC8sܹ4řc0h&'M*i&',J@ydp륪!΋E7GVeF"HB@(DK ;bT y(\QRIi?4e ӕRXI(TE%B(T%l\D}K:/pRɃT49#K-ORN|&B^τGi=%gyy: ($6*P3q$|f/1{;x<ce4z{C!a ;-_tnNDǑ~,DVS}EzstY#5e8`0M jmo~3mM4DE,Qqݥf|H#$=yGj"P(lOW5<`RNnl`c{ 'vԼSx< %FJ:* 9^-U*T9U*)5,sNUǤIV<1Ye@/%TL 8N0UU6""? b!I$+&>}rqv>n7IB"'$@~ޥrgiJ=?,#uNI`.h8(HBVL$nڲe?iij{A{* όVj3yDTa'"Y:X.GMڀj 91Q*8ZRAu:D(xVXLxh(Cի)BΓbjK( 񥄗}:eȽ,tDC#cI/l7,ҁD|Lrp _BN2A\4rUZlHU'aM7D\c(G/t0Z-9J+V<T?ko߼()۫iY$~ vǶL<Z#].%OkKi,FUV6iWRR^NKxs3RD~Ng2Q|"DJB^lė:AK|3R,R9P<]-Z2/oɍ bI&+v6-$@&}SCn4 FC2#9];S#֥*/{}Z2c-t:K*-2SJJHjiz.ZF#ߧRYPOkΛF7oӟ/{H/*yp]6 &KANxY,qcd#OSHǪn(DҺR MRﱔ4ӥ-1&]!ᴍ 382|}+)O/֠OH#pB`0śTzLCdBFB: VVr[ʽ{ ?*1Rl0)ҿ=SA94*>qƍ}G5i<ѨVϞ-p< /] ;2?F6}Pz< FKτ;zER9Fcc=WYᣉ@^ ەXiJ RQAuV$B^hqwma%2wX,)DJ-*H"Vyt:A:-Y ?$kbω`2鴣ߝFX(HA_*Rĉ{g~\, UEvVYF`XbɖpPА-ˏ̽ h,*@HRe44l@cYgu$NR%%FwK8ҥhqUe;bة {z߱Ty]rY~hVBD"ҏT@5ZKK?a2i4v `x8^x"7h!̈́ɬ*Ht A^ c|(%%[JE>EeE?6-z2`P#jJ-m h?};,'p(セ1ADJ$wcv`'zƩkEE9rQDRE!+`dqHX2eܦ'Ɨzq:Z-OZہ P6FdpE9M%H~@r=xkkI=NXHRtLldbjkt"XHt:=㱥UV⋀^WRRU iZNq(䁜)_X,`0PCFla6F٬5?cÇNNWT 8Dª7K^MqVU z<ҥZM9UUz=Ida*1:W`vq3K_8L,Yd[ @6Czf!L&S(D}*>'tY>__KS>pz}Qi #r"}uqhI$@Yu OMj6fA=#Դ2hB )3`t:b2YkV T`#'.u?vu:*uri~x8liiy ȑ;j?ni`@jj|>"&GU(Dd~ImP<+_>C*!& S(rr'L0hVj)m%T Xk# e`B$Y !¯JDx\Η$H&nBJKȴnk'ʺq#EV*IEDZ"nN;#o-*|Yu-553g<`AAUUmmm]v" |iJp̜Iq~ TRUbq>?vfsYىd:Dcxbd"DE#ܷ{`u̵׺\j5p?meeݟ[V+TB6S9<*+kjF`'_JEeL&Q .`Pt5yA4e #?ݝPq :T;x< eEu25TEy7:;>>K~逩^\>89^ӈZtS.X(r$d vvw[;.L៩~쟤7$<#ҚF"c~rHU{loip/⭷\py@II~P$ \w(Fs|BhQ9m#[N?%pn6{K^MX(m"AeZ/]fޟwzz#G={:;{$a`"O.V% @&' --@4g? I"|DO&MIJ4Z-`v;0}̙f3@yZ- d [J %pD,f`Lz}SbD 2)7olI뼬(H\B-/O9p}Q,B {Mk/l|G;kFAɳfz= ]xRm(,u Ӓ|, Jņiaȝ&%\nj0z0FJ|ttum~w={zG3oEN!ذa޶6`Φƞn"YU˩w DƍN:=$IPrȶakWGǪU R C]ڨ8|h^{hmA pV@yUUF#I^옪Ȼ54@iiYNTWqW6ljez^r: GU)lDK.tK! #s+WbKZJ or$TVJ3g8טWJ-zfauO&¨fKŵu31[$\t[jŋUr2Mq>paUƍ#ѨѨEcҥT';M,2"Bi@Ԯ4a18ON-Cj H؋ӯAD'I&KyJ|]]pÛ.<|1Ό<sΙ6M,N'rAAa`@$@iIg; С3hޠT*RACzzl )SiO)i0ş\1I0UU*[[Rw72k֜9V+x [JaljPȄjG/Re\6KHxS)%+B);tI$@aaQNG6Pv<^:b^΅PY2TDB I=l{$HV!co/ Xp3Ϥ N5b ++kC^07XRDtL 0 T*Rْ&i~JPg9HW==D4k;'}Wx߳ /GB08448ʕ?P*zDJJK' L^wwv]Kہbry:`DRՏX|(Ǜؾ}ŏ=xxg[,D%I~8MdDK|KcBSSOvZEH6B~BcF3 yq@N _4YF*5m#0WM{ >55f-Xp,h{JIq~vIdhhOnJN4&rg41F l?'vLؾRp* csZ~lLjp`I2z5Zb:FHx)vW(h$˜VӧSRYQ{"%wزԃ'o~SS#4={v ׬q+!:! $h4xU]8%C*u=g8Yt%Vs]7mS،$?燎gSXxH2~:_$^75Ӧ{ɈQ'M9Ng*~?tM 7߃RQEpO# YT:r x3e0Q eeTh2^.{.SJK]8Y@$y<=/'c„S`ɏl\:]& g̡C==\v;U>Ldqj2އBC`0(BBb]IrRK]/]‡"#E& Tdj?Y’K*1WnfIKIӦLvl>0 Q^zEԁO5TR6Gk>;2"yyBq )?!эFi [Z n1+--"p:} P=ɶ>jK,WIFMG7n|s{4A'qϞe˞zh?e@2I u:!4!B!S`8& 0k0ejjtK)*, k!AjuK|I=_x2jt9^hRh%KV˯xMM=*,0+l}m!./! FjbTﱨDɋt DE18HpX*@M 90Y\wnRR2G0.AKjk9UU?80m 7qo]K>%I|PyS&x?UEE',~2Q$EM6s}ܹf3tRh$7{RPas*f1 /y4!ǒW(CF**lGG{{8  PZZZRsAxzYVtd`s!Abbft*FÒ?1p- @f?X0 `ʔ9sK./} 0O@gmu[԰|NǮ]O>@4>bOϞ=[Tn`0$Rl&۞NG̑oյwxa p8j Z-{{)0yǎwZ[Lh:u:n*x6_i)l~ʿ-uwXhʶn| (-\**@.lp`a'ѦV+l6MExs?j2!†(H364f3UTh I˶! FEuk` #I1?JP(:S(W X Y/E=+=d2[cמyX!ipY4z=%ld0)BҜI^JmCM Hi(x}j-uƷDFC //۵cӟ.ՕI3/,-R*>J :;ID0 RRbO'W@2Ҁ]cǕ>1BM/(=^__ooWrĉWW"MD%U-v[N Vat:ZWU @M IDeeZ-e 9Mf .((,s!3Kiy*ytTl6Tde%|`9ϧ;%75F)Ӆ{q_bi sx {zIp)Kn2~憻,'Vqzڀ^OnشiMp]6Evzz]K'T0SG f:2h+us:6:\M/Jp0.6" c^{DeLd0gpDrbd㔼VJY(Jaƌ'._\q1j8t:nMoJJ,ڹsF cR'h@JEejJr D:A* )`D}9RbsS0`kJ7 dv«Jٹi;;wֲeb'W=\YcDTTSL⥑>nL5Rl媶j˥.0ֶn]Gw!G|3dDό|R*IsFIuum^Db2E"c;,5 iixTqb,) )t @TiqWS3a> [PqI"xSonO?hO1"&LX1kVs}qbD/h9_ⷿ ф}~~7mHu9epb{0v@8gO(vHe0Rɽr/S$U{Es Fܗ^\8*ǁΎzޔ {}}]] F#Kσ|U*N60y8^IՕ:rpR| k׶ڦ:lQ(Hh|o"[}餶՜k)nWH [Z_ճ{En/*ߗfR#![j`gg B􍊊*VGD\܀$3)$BAvSMƷd^+8oRT.'٪&L>s_1󥗞xxeo~s@{vgjN?tH&hh0lF#_[k6Fwi"R5f*tؘ'"3^  xrښɓ.eM]8Z2=eG "LUYq3ŨtZ-RR=.WkkOb˯_Lq#W\t)޾`}@7IsOtbdAA2V Px B9t|&<&'Y^_ R4J{mm]gV%[wo>/nQ '@[*Uy@E>_?XA5Vr2ߚ)S[s'wկ`zu#cHL,ÔN)MfsQ 64XNGHٛ+CdOZomm@oΝl")綱kjjoO=V)#b63?~:qF&N>7<M{hfwW2ifi^bV1K(((*R)CmDBZLzF<'u4'%{_s$$Bg dTP({|~>z{{zb1{)xG̹xɑ}B9T0NrԜ'? |snoӟ+W>? x\Llr3[U&XJ2 47Q̘QXt"ud:ommkh\\V*1r"L?gFVKe,&$T\Rmx6ML blSsG&*#mm@WlGRՍFϿ.70|p5ӧ;@MM^ތ_w+=6̘̙p!l19溧ԌFʵM$HӑK98,lU|J|RA Cx|wP)/Wn/g|S-N;2Zf.{Gᢋ x{vׁ޾tHNt"d)%nQlrhC%m.6HP\. *񉭀TRRY>n:͖=a.R5=9TrTz6eLp[Iv=~UZf+~Lp饟{g./brJGn طoښ'NL̙$2qlv;U:fJTwI)Hj3(:RsYpST^$/59mD?"dqw::(0zma ),|]o|yep,p̩;QfϾjή.@d$gV2mE"=kٜfj)_<D"dA M=l*g3$(*Zq7󟓄*-x<Ν/@0#ȽY" DŽ 4)=Y!!|>_j5OZ\KNQ;&8s'LF*() 8|xRJR(D01Ll{qg{(@To<IS*oOtົ;:q`ݺիC!P(.+_.kL&;9'lc NN8Fc+<46C7 |Nunsj@*{zdL|oD^/PJxߗ~f |0.ߟ{nM  RэghDQvh .30 }j8|]nu&K-^ÿ=3K_~:kɒS~$vK}+wZD׮Ofxx" u:t;L;9 )qR\EػKKqfH z$p=0gT6mk+` s3ޟUUyyӎ2\{p]7LD#UISc'/A᱈G S__(+>}޼3y763̆t[`vJ> hFF_0x@ t|ُmKv9poo/|xBӟ_߱gHd; $mmKEE60y) 0u*j)$9W!2<؎M|ݱx@8 45ZBlֶlf 8Hb[fJe,sM(..- jX BA8NQ\rq;8ߟH(`4Je~~c#־ PR<{p0pS6>H$(+7~/X._Dc%̟E|+?|T⬫;.7y y>nyݞdTFOq_ /]{^N`֎W_}=-[u\@;H&'NI"ˤksȶiJnJ%׃ *6@2pUUW +*IqZhh(('>6`"\ԧիW^F8^[Xs*omYg.Y|hzzdžիہw}^N nl8MFWxׁөD2]]5Œ)IDATOc#47a @(|G%Qֳ^VMޠј̀Ţ9$UVVk}PVf?tn|΁Kի6nܺu۶LG&cUyJJop%?ħ>$r_z閛/صOSJIc%%Βb٠x룏>M+V<r![E٬T{B…3ft7TTqƩq@sHA, @o]7I]6M0e PR2gYgQt_E99!->?d9Ç9!-rC9[0r`90n#ra"G9øEs!qC9!-rC9[0r&dk8%tEXtdate:create2009-08-31T01:36:31+02:00p+T%tEXtdate:modify2009-08-31T01:36:31+02:00@tEXtsvg:base-urifile:///home/chenno/projects/elyxer/docs/elyxer.svg|)IENDB`elyxer-1.2.5/forks/jras-elyxer/docs/math-html.html0000644000175000017500000007715712117061354021460 0ustar chennochenno eLyxer Math Showcase (HTML edition)

figure elyxer.png eLyXer Math Showcase

Alex Fernández (elyxer@gmail.com)

1 Introduction

This document is intended as a showcase of the mathematical abilities of eLyXer; for more information be sure to visit the main page.

1.1 Versions

There are several versions of this page:
All of them are generated from the same .lyx source file; they should help you decide which rendering options suit you best.
Also available online is the eLyXer translation of the latest LyX’s detailed Math manual, which contains a lot more examples of LyX maths.

2 Typography

Math formulae use a lot of different symbols and fonts.

2.1 Greek Symbols

Greek symbols are very important in equations: φ, π, Ξ. eLyXer offers a complete set in both upper case: Γ…Ω and lower case: αω. Also the AMS italicized upper case: ΓΩ.

2.2 Math Symbols

eLyXer supports the whole set of math symbols in John D. Cook's list: ∃∂∇ ≥ . It can also render a few more:  ∝  × . You also get all symbols from Markus Kuhn's list: ⊙∐.

2.3 Other Symbols

There are other symbols like arrows:  ←  → , or geometrical shapes: , . eLyXer offers limited support for them. You might also want to use financial symbols in formulae: ¥€$.

2.4 Spacing

Equations look good when items are properly separated. The main separation is the Medium Mathematical Space: x = 3. Note: if you are viewing the non-Unicode version math.html of this page then you are in fact seeing midspaces, which are very similar but not exactly the same: (4)/(18) em for medium mathematical spaces versus (1)/(2) en, where 1 em = 2 en. Try out the Unicode version math-unicode.html — and viceversa. You can check out what version this page is in the page title.
The command \raisebox is useful to, surprisingly, raise a little box,
raisedoverloweredand back.
Like \mbox, it puts its content in a text box. It can also be used just for spacing:
BV.
There are other spacing commands: \hspace: a b, protected space: a b, and (at “block level”) \vspace: a b.
There should be 1 cm of vertical space above this paragraph.

2.5 Fonts

By default, letters denote variables and are taken from the \mathnormal font, which is italic, αx + αy = α(x + y), with the exception of upright capital Greek letters, G ≠ Γ.
Function names should be upright: sin(2π), log(x), tanδ.
Mathematical fonts used in equations include Roman (\mathrm), Sans Serif (\mathsf), Typewriter (\mathtt), Bold (\mathbf), SCRIPT (\mathscr), CALLIGRAPHIC (\mathcal), BLACKBOARD BOLD (\mathbb), and Fraktur (\mathfrak). For the latter, some single characters are translated to their Unicode equivalents: , 𝔽, 𝔉.
Regular text in a formula can be achieved via text font commands like \textrm: 5  to 10, via boxes like \mbox (prevents line breaks): 6  is more than 5, or the AMSmath \text macro (scales like math symbols) basesubsuper. The content of an mbox is processed in LaTeX text mode. This allows text font commands, e.g. a switch to sans-serif-bold-italic, or the phonetic alphabet: sfbfit, tipa.
Units should be written upright, either with \mathrm or with macros from the units package, e.g. as simple unit, km, with magnitude, 57 km, with fractional unit, 200 kmh, or with a fraction before the units, 32 km, (7)/(16) s.

3 Numeration

Equations can be numbered, like (1↓)
(1) y = x
And also like (2↓).
(2) x = 3
Some equations can be numbered even if they don’t have a label.
(3) x = 2y
Notice that equation (2↑) comes after (1↑).

4 Simple Structures

Let’s now see a few of the simpler structures that eLyXer can output.

4.1 Fractions

A simple fraction:
(1)/(2).
Inlined: (2)/(3).
A big recursive fraction:
(1)/((1 + ((1)/(1 + ((1)/(1 + 2x))))))
A nice fraction: 56. A non-diminishing fraction containing alignments:
(1)/(1 + ((1)/(1 + x) × (1)/(1 + x))).
A similar concept is a binomial coefficient: (A + 1B). It can be prettily presented:
(AB + 1).
A symbol can be stacked over another using \stackrel: xR → y. Anything can be stacked:
dx > 3limx,  headheels.

4.2 Limits

limx → ∞f(x) should appear as x → ∞ in italics, and «lim» in plain style. In display mode, a limit must appear below the main symbol:
limx → ∞f(x).
Limits are also used in sums and integrals:
i = 1x,  0f(x) dx
where the sum’s limits should appear below (i = 1) and above () the . The placement of the integral limits depends on the document class: LaTeX standard classes place them right to the . Limits are shown to the right in inline formulae: i = 1x and i = 1x.
The placing of limits can be configured with the \limits and \nolimits macros:
limx → ∞f(x),  i = 1x,  0f(x) dx

4.3 Roots

A square root: (3). A more complex root in a fraction:
(1)/((1 + (2)((1)/(1 + (2))) + ((1)/(2)))).
eLyXer can also do higher-order roots: 3(x + y). A devilish case mixing everything we have seen so far:
(78((8)/(4)x) + i = 1x)/(s + 5(((78x + 45y) × (Ω))/(sin(x + 1)) + 38 km)).

5 Complex Structures

In this section we will explore arrays and related constructs.

5.1 Arrays

An inline array [ a b c d ] is always shown in the same line. In display mode, the array is shown on its own line:
[ 12 2 3 4 × yx ]
Apart from that the appearance should be the same.

5.2 Brackets

Arrays are separated by variable-size brackets: ( a b c d ) [ a b c d ] { a b c d } a b c d | a b c d |which might also differ on right and left ( a b c d ) or use the empty opening { a b c d or closing: a b c d |. There are also fixed-size big brackets, e.g. f.

5.3 Cases

Used to switch between several values.
y =  x i = 0,         x + 1  i < 3 
Cases may have more than two rows:
f(x) =  0  x < 0,         ∞  x = 0        0  x > 0 

5.4 Braces

Values can be underbraced or overbraced.
a − b = b + c + d + e.

6 Macros

Now it’s time for user-defined commands (sometimes called “macros”).
Definitions can be added as macros. Then they can be used in formulae: 1(2). They can accept default parameters. Again, useful in formulae: 4(5).
Other definitions from the preamble can be used: 3(4).
Definitions on the fly are also possible: 7(8), and used with different values: a(b).
elyxer-1.2.5/forks/jras-elyxer/docs/toc.css0000644000175000017500000000101412117061342020146 0ustar chennochenno/* * Styles for lyx TOC. */ body { font: small sans-serif; background: #f9f9f9; color: black; margin: 0; padding: 0; } #globalWrapper { font-size: 115%; margin: 5px 20px 5px 20px; padding: 0px; background: #ffffff; line-height: 1.5em; overflow: hidden; } a { text-decoration: none; color: #0030c0; background: none; } a:visited { color: #603090; } a:active { color: #ffa000; } a:hover { text-decoration: underline; } div.tocindent { padding: 0 0 0 2em; } div.toc { margin: 0.5em 0; font-size: 0.95em; } elyxer-1.2.5/forks/jras-elyxer/docs/container.svg0000644000175000017500000003147612117061342021371 0ustar chennochenno image/svg+xml Container parser output contents LyX HTML elyxer-1.2.5/forks/jras-elyxer/docs/math-mathjax.html0000644000175000017500000005456212117061354022143 0ustar chennochenno eLyxer Math Showcase (MathJax remote edition)

figure elyxer.png eLyXer Math Showcase

Alex Fernández (elyxer@gmail.com)

1 Introduction

This document is intended as a showcase of the mathematical abilities of eLyXer; for more information be sure to visit the main page.

1.1 Versions

There are several versions of this page:
All of them are generated from the same .lyx source file; they should help you decide which rendering options suit you best.
Also available online is the eLyXer translation of the latest LyX’s detailed Math manual, which contains a lot more examples of LyX maths.

2 Typography

Math formulae use a lot of different symbols and fonts.

2.1 Greek Symbols

Greek symbols are very important in equations: , , . eLyXer offers a complete set in both upper case: and lower case: . Also the AMS italicized upper case: .

2.2 Math Symbols

eLyXer supports the whole set of math symbols in John D. Cook's list: . It can also render a few more: . You also get all symbols from Markus Kuhn's list: .

2.3 Other Symbols

There are other symbols like arrows: , or geometrical shapes: , . eLyXer offers limited support for them. You might also want to use financial symbols in formulae: .

2.4 Spacing

Equations look good when items are properly separated. The main separation is the Medium Mathematical Space: . Note: if you are viewing the non-Unicode version math.html of this page then you are in fact seeing midspaces, which are very similar but not exactly the same: for medium mathematical spaces versus , where . Try out the Unicode version math-unicode.html — and viceversa. You can check out what version this page is in the page title.
The command \raisebox is useful to, surprisingly, raise a little box, Like \mbox, it puts its content in a text box. It can also be used just for spacing:
.
There are other spacing commands: \hspace: , protected space: , and (at “block level”) \vspace: .
There should be 1 cm of vertical space above this paragraph.

2.5 Fonts

By default, letters denote variables and are taken from the \mathnormal font, which is italic, , with the exception of upright capital Greek letters, .
Function names should be upright: .
Mathematical fonts used in equations include (\mathrm), (\mathsf), (\mathtt), (\mathbf), (\mathscr), (\mathcal), (\mathbb), and (\mathfrak). For the latter, some single characters are translated to their Unicode equivalents: , , .
Regular text in a formula can be achieved via text font commands like \textrm: , via boxes like \mbox (prevents line breaks): , or the AMSmath \text macro (scales like math symbols) . The content of an mbox is processed in LaTeX text mode. This allows text font commands, e.g. a switch to sans-serif-bold-italic, or the phonetic alphabet: .
Units should be written upright, either with \mathrm or with macros from the units package, e.g. as simple unit, , with magnitude, , with fractional unit, , or with a fraction before the units, , .

3 Numeration

Equations can be numbered, like () And also like (↓). Some equations can be numbered even if they don’t have a label.
Notice that equation () comes after ().

4 Simple Structures

Let’s now see a few of the simpler structures that eLyXer can output.

4.1 Fractions

A simple fraction: Inlined:
A big recursive fraction:
A nice fraction: . A non-diminishing fraction containing alignments:
A similar concept is a binomial coefficient: It can be prettily presented:
A symbol can be stacked over another using \stackrel: . Anything can be stacked:

4.2 Limits

should appear as in italics, and «lim» in plain style. In display mode, a limit must appear below the main symbol:
Limits are also used in sums and integrals: where the sum’s limits should appear below ( ) and above ( ) the . The placement of the integral limits depends on the document class: LaTeX standard classes place them right to the . Limits are shown to the right in inline formulae: and
The placing of limits can be configured with the \limits and \nolimits macros:

4.3 Roots

A square root: A more complex root in a fraction:
eLyXer can also do higher-order roots: . A devilish case mixing everything we have seen so far:

5 Complex Structures

In this section we will explore arrays and related constructs.

5.1 Arrays

An inline array is always shown in the same line. In display mode, the array is shown on its own line: Apart from that the appearance should be the same.

5.2 Brackets

Arrays are separated by variable-size brackets: which might also differ on right and left or use the empty opening or closing: . There are also fixed-size big brackets, e.g. .

5.3 Cases

Used to switch between several values.
Cases may have more than two rows:

5.4 Braces

Values can be underbraced or overbraced.
.

6 Macros

Now it’s time for user-defined commands (sometimes called “macros”).
Definitions can be added as macros. Then they can be used in formulae: . They can accept default parameters. Again, useful in formulae: .
Other definitions from the preamble can be used: .
Definitions on the fly are also possible: , and used with different values: .
elyxer-1.2.5/forks/jras-elyxer/docs/changelog.lyx0000644000175000017500000025663512117061342021361 0ustar chennochenno#LyX 2.0 created this file. For more info see http://www.lyx.org/ \lyxformat 413 \begin_document \begin_header \textclass article \begin_preamble % eLyXer -- convert LyX source files to HTML output. % % Copyright (C) 2009-2011 Alex Fernández % % This program is free software: 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 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 % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . \usepackage{mathrsfs} \usepackage{mathabx} \renewcommand{\varGamma}{\Gamma} \renewcommand{\varOmega}{\Omega} \usepackage{color} \usepackage[gennarrow]{eurosym} \usepackage{upgreek} \end_preamble \use_default_options false \maintain_unincluded_children false \language english \language_package default \inputencoding auto \fontencoding global \font_roman default \font_sans default \font_typewriter default \font_default_family default \use_non_tex_fonts false \font_sc false \font_osf false \font_sf_scale 100 \font_tt_scale 100 \graphics default \default_output_format default \output_sync 0 \bibtex_command default \index_command default \paperfontsize default \spacing single \use_hyperref false \papersize default \use_geometry false \use_amsmath 1 \use_esint 1 \use_mhchem 1 \use_mathdots 1 \cite_engine basic \use_bibtopic false \use_indices false \paperorientation portrait \suppress_date false \use_refstyle 0 \index Index \shortcut idx \color #008000 \end_index \secnumdepth 3 \tocdepth 3 \paragraph_separation indent \paragraph_indentation default \quotes_language english \papercolumns 1 \papersides 1 \paperpagestyle default \tracking_changes false \output_changes false \html_math_output 0 \html_css_as_file 0 \html_be_strict false \end_header \begin_body \begin_layout Title \begin_inset Graphics filename elyxer.svg lyxscale 50 \end_inset eLyXer Changelog \end_layout \begin_layout Standard This document lists all public versions, the date they were released on and the changes they contain. For more information about eLyXer visit the \begin_inset CommandInset href LatexCommand href name "main page" target "index.html" \end_inset . \end_layout \begin_layout Itemize 1.2.4 (unreleased): \end_layout \begin_deeper \begin_layout Itemize Implemented generic converters, and \family typewriter lyx -C \family default as an image converter (thanks, Tommaso!). \end_layout \begin_layout Itemize Implemented command \family typewriter \backslash today \family default : \begin_inset ERT status open \begin_layout Plain Layout \backslash today \end_layout \end_inset . \end_layout \begin_layout Itemize Added a Russian translation (thanks, Vladimir!). \end_layout \begin_layout Itemize Solved a bug when parsing a BibTeX entry with a trailing comma (thanks, Bob!). \end_layout \begin_layout Itemize BibTeX: correctly use booktitle instead of journal in an \family typewriter @inproceedings \family default entry (thanks, Pascal!). \end_layout \begin_layout Itemize Expose language information as additional markup (using the \family typewriter lang \family default attribute in HTML). \end_layout \begin_layout Itemize Fix by Guenter Milde for \family typewriter math2html \family default under Python 3.0. \end_layout \begin_layout Itemize Convert em-dash only when surrounded by spaces (thanks, Robert). \end_layout \begin_layout Itemize Fix by José Ramón Álvarez Sánchez of problem in simultaneous use of \family typewriter hover \family default and \family typewriter end \family default options for footnotes (thanks, Tim!). \end_layout \end_deeper \begin_layout Itemize 1.2.3 (2011-08-31): \end_layout \begin_deeper \begin_layout Itemize Changed the license for math2html from Apache v2 to FreeBSD 2-clause license, to better suit integration with DocUtils. \end_layout \begin_layout Itemize Removed a false positive error which appeared during the tests: \begin_inset Quotes eld \end_inset * No title in \begin_inset Quotes erd \end_inset . \end_layout \begin_layout Itemize Added most commands in Günter Milde's excellent \begin_inset CommandInset href LatexCommand href name "list" target "http://milde.users.sourceforge.net/LUCR/Math/" \end_inset of Unicode to LaTeX commands, except categories mathaccent, mathfence, mathradical, mathover and mathunder. Examples: \family typewriter \backslash hash as \family default \family typewriter \begin_inset Formula $\hash$ \end_inset , \backslash smalltriangleleft \family default as \begin_inset Formula $\smalltriangleleft$ \end_inset . \end_layout \begin_layout Itemize Deprecated option \family typewriter --jsmath \family default , users are encouraged to use \family typewriter --mathjax \family default instead. \end_layout \begin_layout Itemize Added argument \family typewriter --mathjax remote \family default to access the MathJax CDN instead of hit a local copy. Changed the Math showcase to work \begin_inset CommandInset href LatexCommand href name "remotely" target "math-mathjax.html" \end_inset by default. \end_layout \begin_layout Itemize Solved \begin_inset CommandInset href LatexCommand href name "Debian bug 639712" target "http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=639712" \end_inset : eLyXer didn't accept Unicode characters in \family typewriter --title \family default option, added test. \end_layout \begin_layout Itemize Solved \begin_inset CommandInset href LatexCommand href name "Savannah bug 33961" target "https://savannah.nongnu.org/bugs/index.php?33961" \end_inset : eLyXer didn't support sub- or superscript insets as used in LyX 2.0, added test. \end_layout \begin_layout Itemize Solved installation problem when \family typewriter $PATH \family default contains a directory which does not exist; the eLyXer binary was created with the same name as said directory. Now \family typewriter install.py \family default should just ignore the directory. (Thanks, Jack!) \end_layout \end_deeper \begin_layout Itemize 1.2.2 (2011-06-12): \end_layout \begin_deeper \begin_layout Itemize Bug in description: when a (non-empty) ERT is the first element of a description , use it as first word and make it bold. \end_layout \begin_layout Itemize Proper support for \backslash scriptstyle and \backslash scriptscriptstyle: \begin_inset Formula ${\scriptstyle \text{script}},{\scriptscriptstyle \text{scriptscript}}$ \end_inset . \end_layout \begin_layout Itemize \begin_inset CommandInset href LatexCommand href name "Bug #33156" target "https://savannah.nongnu.org/bugs/index.php?33156" \end_inset : CSS specification as in \family typewriter --css=lyx.css \family default was not working, solved now. \end_layout \begin_layout Itemize Support for \family typewriter \backslash noindent \family default and \family typewriter \backslash centering \family default in ERTs. \end_layout \begin_layout Itemize Ignore BibTeX entries which are not publication entries. Show a debug message for non-referenced entries. \end_layout \begin_layout Itemize Understand command \family typewriter \backslash & \family default in BibTeX files. \end_layout \begin_layout Itemize Bumped Lyx format supported ( \family typewriter --lyxformat \family default ) to 413 (LyX 2.0.0). \end_layout \begin_layout Itemize Solved error when parsing display formulas generated with LyX 2.0: \family typewriter "Formula beginning \backslash begin_inset Formula is unknown" \family default (thanks, Pascal!). Added test case. \end_layout \begin_layout Itemize Added a bunch of new symbols, including \family typewriter \backslash textsection \family default \begin_inset ERT status open \begin_layout Plain Layout \backslash textsection \end_layout \end_inset , \family typewriter \backslash textemdash \family default \begin_inset ERT status open \begin_layout Plain Layout \backslash textemdash \end_layout \end_inset or \family typewriter \backslash v{z} \family default \begin_inset ERT status open \begin_layout Plain Layout \backslash v{z} \end_layout \end_inset (thanks again, Pascal!). \end_layout \begin_layout Itemize Changed output characters for English quotes, from Unicode “ and ‘ to HTML entities \family typewriter “ \family default and \family typewriter ‘ \family default (thanks, Marco!). \end_layout \begin_layout Itemize Make Flex styles in titles work (thanks, Tiago!). \end_layout \begin_layout Itemize Make custom Flex CharStyles work: generate HTML spans of the same class as the Flex type (thanks again, Marco!). \end_layout \end_deeper \begin_layout Itemize 1.2.1 (2011-03-07): \end_layout \begin_deeper \begin_layout Itemize Wish list: support for formatted references (showing the part name and number) and named references (showing the part title, equivalent to \family typewriter \backslash nameref \family default ). \end_layout \begin_layout Itemize Wish list: include part titles in \family typewriter --splitpart \family default navigation header. \end_layout \begin_layout Itemize Changed literal for previous page in \family typewriter --splitpart \family default : now it's \begin_inset Quotes eld \end_inset Prev \begin_inset Quotes erd \end_inset instead of \begin_inset Quotes eld \end_inset Previous \begin_inset Quotes erd \end_inset . \end_layout \begin_layout Itemize Bug in \family typewriter --notoclabels \family default : removed the \begin_inset Quotes eld \end_inset . \begin_inset Quotes erd \end_inset after the part number but before the title shown in the TOC. \begin_inset Quotes eld \end_inset 5. \begin_inset space \quad{} \end_inset How to Make Friends \begin_inset Quotes erd \end_inset is now \begin_inset Quotes eld \end_inset 5 \begin_inset space \quad{} \end_inset How to Make Friends \begin_inset Quotes erd \end_inset (thanks, José Ramón!). \end_layout \begin_layout Itemize Allow \family typewriter math2html \family default to be invoked using parameters (like \family typewriter --debug \family default ). \end_layout \begin_layout Itemize Bugs in ERT parsing: brackets \family typewriter {} \family default are not parsed correctly across different ERTs. The TeX parser was being thrown off by escaped brackets as in \family typewriter { \backslash { \backslash }} \family default , added test. Comments are ignored now. \end_layout \begin_layout Itemize Solved conflict in CSS between \family typewriter .script \family default (used to properly layout super- and subscripts) and \family typewriter span.script \family default (used for the script-type \family typewriter \backslash mathscr \family default and \family typewriter \backslash mathcal \family default fonts). Changed the latter to \family typewriter span.scriptfont \family default , forcing an incompatible but unavoidable change in the CSS. \end_layout \begin_layout Itemize Forced \family typewriter span.scriptfont \family default to be shown as italic so it's properly displayed on Firefox. \end_layout \begin_layout Itemize Wish list: new option \family typewriter --googlecharts \family default adds support for formula images generated using Google Charts. \end_layout \begin_layout Itemize Wish list: merged options \family typewriter --toc \family default and \family typewriter --toctarget \family default into \family typewriter --tocfor \family default . \end_layout \begin_layout Itemize Wish list: options \family typewriter --splitpart \family default and \family typewriter --tocfor \family default (previously \family typewriter --toc \family default ) now work together. Also: the separate TOC has a link to the main page. \end_layout \begin_layout Itemize Bug in \family typewriter --splitpart \family default combined with \family typewriter --notoclabels \family default : unnumbered parts displayed an ugly colon as in \begin_inset Quotes eld \end_inset Next : Section \begin_inset Quotes erd \end_inset , now removed (thanks, José Ramón!). \end_layout \begin_layout Itemize Modified the spacing in formulas so that words in the mathnormal font now appear separated, as a product of variables. \end_layout \begin_layout Itemize Do not show limit symbols such as \begin_inset Formula $\sum$ \end_inset or \begin_inset Formula $\int$ \end_inset in a larger font than the rest for inline formulas. \end_layout \begin_layout Itemize Added support for \backslash textcircled: \begin_inset Formula $\textcircled w$ \end_inset . \end_layout \end_deeper \begin_layout Itemize 1.2.0 (2011-01-30): \end_layout \begin_deeper \begin_layout Itemize Bumped LyX version support to 410. \end_layout \begin_layout Itemize Correctly create big brackets for environments with odd alignments such as matrix (thanks, Günther!). \end_layout \begin_layout Itemize Create and use big brackets for fractions and other structures, if needed. \end_layout \begin_layout Itemize Added option \family typewriter --simplemath \family default to avoid fancy math structures: do not \emph on \emph default generate multi-line Unicode brackets or stacked limits. \end_layout \begin_layout Itemize eLyXer is now a proper Python package, instead of just a coalesced script \family typewriter elyxer.py \family default containing everything. However only the script is installed right now. \end_layout \begin_layout Itemize Interpret TeXCode (previously known as Evil Red Text) as TeX commands and formulas. \end_layout \begin_layout Itemize Support for TeX commands \family typewriter \backslash textvisiblespace \family default , \family typewriter \backslash AmS \family default , \family typewriter \backslash parbox \family default , \family typewriter \backslash tag \family default , \family typewriter \backslash rule \family default , and more: \begin_inset ERT status open \begin_layout Plain Layout \backslash textvisiblespace \end_layout \end_inset , \begin_inset ERT status open \begin_layout Plain Layout \backslash AmS \end_layout \end_inset . \end_layout \begin_layout Itemize Support for \family typewriter \backslash Game \family default : \family roman \series medium \shape up \size normal \emph off \bar no \noun off \color none \begin_inset Formula $\Game$ \end_inset . \end_layout \begin_layout Itemize Changed the navigation header for \family typewriter --splitpart \family default so that the left and right spans overflow (thanks, Axel!). \end_layout \begin_layout Itemize Bug in \family typewriter --notoclabels \family default : labels such as \begin_inset Quotes eld \end_inset Figure \begin_inset Quotes erd \end_inset should be omitted in the TOC, but not in captions (thanks again, Axel!). \end_layout \begin_layout Itemize Bug in \family typewriter --splitpart \family default : empty navigation links caused the header to look unbalanced, fixed now with a non-breaking space. Also, up link in the main page used to point to itself; now it's an empty link (more thanks, Axel!). \end_layout \begin_layout Itemize Support for \family typewriter \backslash limits \family default and \family typewriter \backslash nolimits \family default : control if the last symbol should show limits above or below the symbol or not. \end_layout \begin_layout Itemize Bug in \family typewriter \backslash vspace \family default : add the vertical space after the command, not before; or at least try to. \end_layout \begin_layout Itemize Bug in \family typewriter \backslash raisebox \family default : parse and display the contents as text mode. \end_layout \begin_layout Itemize Wish list: do not number captions in code listings. \end_layout \begin_layout Itemize Do not install as a module (to run as \family typewriter python -m elyxer \family default ) but only as a script (to run as \family typewriter elyxer.py \family default ). \end_layout \end_deeper \begin_layout Itemize 1.1.2 (2010-12-23): \end_layout \begin_deeper \begin_layout Itemize Wish list: display large Unicode symbols for sums and integrals in display mode. \end_layout \begin_layout Itemize Also in display mode, place limits for commands that take them above or below the symbol, instead of to the right. \end_layout \begin_layout Itemize Support for new Flex insets: Code, MenuItem, Noun, Strong; new Argument, Phantom and line (ruler) insets; new style \family typewriter \backslash strikeout \family default ; new LaTeX commands \family typewriter \backslash href \family default , \family typewriter \backslash newline \family default . \end_layout \begin_layout Itemize BibTeX: apply a combining function only to the following character, not to the next word. \end_layout \begin_layout Itemize Added reference format for \family typewriter vpageref \family default ( \begin_inset Quotes eld \end_inset on page # \begin_inset Quotes erd \end_inset ). \end_layout \begin_layout Itemize Improved math macro parsing: optional parameters, literal parameters, single-let ter parameters, parameter defaults with operations. \end_layout \begin_layout Itemize Display math cases, full-sized binomials ( \family typewriter \backslash dbinom \family default ) and array brackets using Unicode bracket pieces. \end_layout \begin_layout Itemize Change all table-type elements in formulas to spans and do the formatting in the CSS, to generate valid XHTML. \end_layout \begin_layout Itemize Support graceful degradation of fractions and roots when the CSS is not present. \end_layout \begin_layout Itemize Adjusted roots to insert the root power inside the radical symbol. \end_layout \begin_layout Itemize Adjusted nice fractions ( \begin_inset Formula $\nicefrac{3}{4}$ \end_inset ) to improve their appearance. \end_layout \begin_layout Itemize Support for all upright Greek letters: \begin_inset Formula $\upmu$ \end_inset , \begin_inset Formula $\uptau$ \end_inset . \end_layout \end_deeper \begin_layout Itemize 1.1.1 (2010-12-13): \end_layout \begin_deeper \begin_layout Itemize Wish list: understand \family typewriter \backslash url{} \family default in BibTeX files. \end_layout \begin_layout Itemize Wish list: parse math formulas in BibTeX files. \end_layout \begin_layout Itemize Improved support for dotless i and j as \family typewriter \backslash imath \family default and \family typewriter \backslash jmath \family default : \begin_inset Formula $\imath$ \end_inset , \begin_inset Formula $\jmath$ \end_inset . \end_layout \begin_layout Itemize Solved bug when parsing a quoted string inside a BibTeX file containing a comma. \end_layout \begin_layout Itemize Added math environments \family typewriter equation* \family default and \family typewriter matrix \family default . \end_layout \begin_layout Itemize Do not break inline formulas at whitespace (thanks, José Ramón!). \end_layout \begin_layout Itemize Break up the CSS into pieces, and generate an independent \family typewriter math.css \family default for use within \family typewriter math2html.py \family default . \end_layout \begin_layout Itemize Ignore hyphens in option names, so e.g. \family typewriter --split-part \family default is equivalent to \family typewriter --splitpart \family default . \end_layout \begin_layout Itemize Changed \family typewriter --forceformat \family default to \family typewriter --imageformat \family default (kept the old option for backwards compatibility). \end_layout \begin_layout Itemize Wish list: added \family typewriter --imageformat "copy" \family default to just copy images instead of converting them. \end_layout \begin_layout Itemize Wish list: added option \family typewriter --embedcss "file.css" \family default to embed the CSS styles in \family typewriter file.css \family default into the resulting HTML. \end_layout \begin_layout Itemize Wish list: more than one \family typewriter --css \family default options can be added to use several CSS files. \end_layout \begin_layout Itemize Wish list: display sub- and superscript aligned vertically (as in integrals). \end_layout \end_deeper \begin_layout Itemize 1.1.0 (2010-11-23): \end_layout \begin_deeper \begin_layout Itemize Wish list: understand \family typewriter \backslash setcounter \family default in the preamble to set the number of the first Chapter or Section. \end_layout \begin_layout Itemize Generate a new \family typewriter math2html.py \family default file with an API to convert raw LaTeX code to HTML, and a command line utility. \end_layout \begin_layout Itemize Wish list: new option \family typewriter --notoclabels \family default to omit part labels in the TOC. \end_layout \begin_layout Itemize Wish list: make \begin_inset Quotes eld \end_inset show changes in the output \begin_inset Quotes erd \end_inset work for change tracking. \end_layout \begin_layout Itemize Solve an existing issue with Description and List layouts: correct splitting of first words when intermixing styles. \end_layout \begin_layout Itemize Show decorations using Unicode combining characters, whenever possible. \end_layout \begin_layout Itemize Support for \family typewriter \backslash dddot \family default : \begin_inset Formula $\dddot{o}$ \end_inset (with combining character) and \family typewriter \backslash widehat \family default : \begin_inset Formula $\widehat{abc}$ \end_inset (with character on top). \end_layout \begin_layout Itemize Wish list: add several options for \begin_inset CommandInset href LatexCommand href name "footnote generation" target "userguide.html#sub:Footnotes" \end_inset (align markers instead of using superscript, place markers at the bottom of the page, use symbols for markers\SpecialChar \ldots{} ). Also added a generic \family typewriter --footnotes \family default option to aggregate them all. \end_layout \begin_layout Itemize Wish list: use \family typewriter ps:use-cropbox=true \family default in ImageMagick for PostScript and EPS images. \end_layout \begin_layout Itemize Support for dotless i and j: \begin_inset Formula $\text{ı}$ \end_inset , \begin_inset Formula $\text{ȷ}$ \end_inset . \end_layout \end_deeper \begin_layout Itemize 1.0.4 (2010-10-29): \end_layout \begin_deeper \begin_layout Itemize Solved \begin_inset CommandInset href LatexCommand href name "bug #31342" target "https://savannah.nongnu.org/bugs/index.php?31342" \end_inset : detect appendices as they appear instead of looking at the containing layout. \end_layout \begin_layout Itemize Also reported in \begin_inset CommandInset href LatexCommand href name "bug #31342" target "https://savannah.nongnu.org/bugs/index.php?31342" \end_inset : set part name to \begin_inset Quotes eld \end_inset Appendix A-Z \begin_inset Quotes erd \end_inset in the TOC for appendices, instead of showing them as regular chapters or sections. \end_layout \begin_layout Itemize Also reported in \begin_inset CommandInset href LatexCommand href name "bug #31342" target "https://savannah.nongnu.org/bugs/index.php?31342" \end_inset : number parts and books using roman numerals, as in \begin_inset Quotes eld \end_inset Part I \begin_inset Quotes erd \end_inset or \begin_inset Quotes eld \end_inset Book IV \begin_inset Quotes erd \end_inset . \end_layout \begin_layout Itemize Fixed bug due to wrapped float placement not being mandatory anymore, despite what \family typewriter EmbeddedObjects.lyx \family default says (thanks, Hans!). \end_layout \begin_layout Itemize Solved \begin_inset CommandInset href LatexCommand href name "bug #31351" target "https://savannah.nongnu.org/bugs/index.php?31351" \end_inset : do not number (or add to the TOC) any document parts inside comments. \end_layout \begin_layout Itemize Also in \begin_inset CommandInset href LatexCommand href name "bug #31351" target "https://savannah.nongnu.org/bugs/index.php?31351" \end_inset : the bibliography should be added to the TOC if so configured (and not inside a comment), and split into its own page with \family typewriter --splitpart \family default . \end_layout \begin_layout Itemize Also in \begin_inset CommandInset href LatexCommand href name "bug #31351" target "https://savannah.nongnu.org/bugs/index.php?31351" \end_inset : show the bibliography in regular size, not smaller than the main text as before. \end_layout \begin_layout Itemize Changed header from \begin_inset Quotes eld \end_inset Bibliography \begin_inset Quotes erd \end_inset to \begin_inset Quotes eld \end_inset References \begin_inset Quotes erd \end_inset for document classes other than book and report. \end_layout \begin_layout Itemize Solved \begin_inset CommandInset href LatexCommand href name "bug #31414" target "https://savannah.nongnu.org/bugs/index.php?31414" \end_inset : bootstrap creation of \family typewriter conf/config.py \family default . \end_layout \begin_layout Itemize Also in \begin_inset CommandInset href LatexCommand href name "bug #31414" target "https://savannah.nongnu.org/bugs/index.php?31414" \end_inset : remodeled unit tests to try out Python 2.4 only if present, and to remove test files from previous runs. \end_layout \begin_layout Itemize Show the \begin_inset Quotes eld \end_inset Abstract \begin_inset Quotes erd \end_inset header only for the first Abstract layout (thanks, Yaron!). \end_layout \begin_layout Itemize Do not separate consecutive Abstract paragraphs, and display the abstract in slightly smaller font size. \end_layout \begin_layout Itemize Solved \begin_inset CommandInset href LatexCommand href name "bug #31345" target "https://savannah.nongnu.org/bugs/index.php?31345" \end_inset : ignore preamble and comments in BibTeX files. Use string definitions ( \family typewriter @string \family default ) in other entries. \end_layout \begin_layout Itemize Also in \begin_inset CommandInset href LatexCommand href name "bug #31345" target "https://savannah.nongnu.org/bugs/index.php?31345" \end_inset : avoid endless loops for undesired characters in BibTeX entries. \end_layout \begin_layout Itemize Support for \family typewriter \backslash fbox \family default , \family typewriter \backslash boxed \family default , \family typewriter \backslash framebox \family default and \family typewriter \backslash fcolorbox \family default : \begin_inset Formula $\fbox{\ensuremath{fbox}}$ \end_inset , \begin_inset Formula $\boxed{boxed}$ \end_inset , \begin_inset Formula $\framebox[25mm][l]{framebox}$ \end_inset . \end_layout \end_deeper \begin_layout Itemize 1.0.3 (2010-10-15): \end_layout \begin_deeper \begin_layout Itemize Do not hide errors when parsing child documents. \end_layout \begin_layout Itemize Correctly convert documents even when images are not found. \end_layout \begin_layout Itemize Do not center the content in figure or table floats by default. \end_layout \begin_layout Itemize Correctly convert child documents even when inserted in layouts. \end_layout \begin_layout Itemize Generate navigation bars for first page created with \family typewriter --splitpart \family default . \end_layout \begin_layout Itemize Added wishlist to the user guide to keep track of requested features. \end_layout \begin_layout Itemize Solved \begin_inset CommandInset href LatexCommand href name "bug #31243" target "https://savannah.nongnu.org/bugs/index.php?31243" \end_inset : spaces and comments in formulas (command definitions, empty formulas\SpecialChar \ldots{} ). \end_layout \begin_layout Itemize Also reported in \begin_inset CommandInset href LatexCommand href name "bug #31243" target "https://savannah.nongnu.org/bugs/index.php?31243" \end_inset : do not add numbering twice to child documents, and ignore child documents in comments. \end_layout \begin_layout Itemize Added support for \family typewriter \backslash stackrel \family default : \begin_inset Formula $x\stackrel{R}{\rightarrow}y$ \end_inset (thanks, José Ramón!). \end_layout \begin_layout Itemize Added a lot of escaped characters to BibTeX parsing: \family typewriter \backslash ~n \family default , \family typewriter \backslash '{ \backslash i} \family default \SpecialChar \ldots{} Also added a field \family typewriter note \family default to all BibTeX styles. \end_layout \begin_layout Itemize Show all references (even those not cited) in the bibliography if configured to do so. \end_layout \begin_layout Itemize Understand relative sizes (e.g. \family typewriter 10col% \family default ) in spaces (thanks, Uwe!). \end_layout \end_deeper \begin_layout Itemize 1.0.2 (2010-09-20): \end_layout \begin_deeper \begin_layout Itemize Updated \begin_inset CommandInset href LatexCommand href name "MathJax" target "http://www.mathjax.org/" \end_inset to version 1.0.1 -- no changes to eLyXer documents are necessary. \end_layout \begin_layout Itemize Added option \family typewriter --noconvert \family default to use images in their original formats, and avoid converting images altogether. \end_layout \begin_layout Itemize Output \family typewriter \family default tags for SVG images. Size information is not used as it causes problems on Firefox. \end_layout \begin_layout Itemize BibTeX: include \family typewriter booktitle \family default tag for the \family typewriter @incollection \family default format. \end_layout \begin_layout Itemize BibTex: added a tag \family typewriter \family default around all bibliographical cites, so they can be e.g. superscripted. \end_layout \begin_layout Itemize Show footnotes as hovering text instead of as marginal notes. Make the default footnote marker a bluish superscript letter in brackets: \begin_inset Foot status open \begin_layout Plain Layout like this \end_layout \end_inset . \end_layout \begin_layout Itemize Updated \family typewriter --lyxformat \family default to 398 (2.0alpha5); added warning if document version is bigger than that. \end_layout \begin_layout Itemize Support for \family typewriter \backslash textless \family default and \family typewriter \backslash textgreater \family default : \begin_inset Formula $\textless$ \end_inset , \begin_inset Formula $\textgreater$ \end_inset . \end_layout \begin_layout Itemize Added adjustments for better printing to default CSS. \end_layout \begin_layout Itemize Added languages \begin_inset Quotes eld \end_inset british \begin_inset Quotes erd \end_inset and \begin_inset Quotes eld \end_inset american \begin_inset Quotes erd \end_inset (which translate to plain English). \end_layout \begin_layout Itemize Avoid extracting indexes out of the containing layout if there is anything else in there (thanks, Amy!). This bug caused some content to be lost (e.g. child documents) if they were inside the same layout as e.g. an alphabetical index. \end_layout \end_deeper \begin_layout Itemize 1.0.1 (2010-09-01): \end_layout \begin_deeper \begin_layout Itemize BibTeX: more robust parsing, specifically: correctly parse entries separated by commas. Support all TeX commands already available in math formulae. \end_layout \begin_layout Itemize Support for \family typewriter \backslash textasciitilde \family default : \begin_inset Formula $\textasciitilde$ \end_inset , \family typewriter \backslash textasciicircum \family default : \begin_inset Formula $\textasciicircum$ \end_inset and a few other \family typewriter \backslash text\SpecialChar \ldots{} \family default symbols. Also, \family typewriter \backslash textrm \family default , \family typewriter \backslash textsf \family default and \family typewriter \backslash textnormal \family default should be working now in equations: \begin_inset Formula $a+\textrm{roman}+\textsf{sans-serif}+\textnormal{normal}+b$ \end_inset . \end_layout \begin_layout Itemize Improved support for custom horizontal and vertical spaces; absolute measures can now be used. \end_layout \begin_layout Itemize Support for sizes in table columns, figures and boxes. \end_layout \begin_layout Itemize Solved bug in \family typewriter --nofooter \family default which required a dummy argument (thanks, Yan!). \end_layout \begin_layout Itemize Corrected box styling: \family typewriter
\family default is now indeed frameless, while \family typewriter
\family default no longer has a double border. \end_layout \begin_layout Itemize Solved bug in text handling which separated consecutive centered lines with a space. \end_layout \begin_layout Itemize Basic support for LyX change tracking. \end_layout \end_deeper \begin_layout Itemize 1.0.0 (2010-07-21): \end_layout \begin_deeper \begin_layout Itemize Replicate the navigation bar for \family typewriter --splitpart \family default at the bottom of pages. Use translated strings for \begin_inset Quotes eld \end_inset Previous \begin_inset Quotes erd \end_inset , \begin_inset Quotes eld \end_inset Up \begin_inset Quotes erd \end_inset and \begin_inset Quotes eld \end_inset Next \begin_inset Quotes erd \end_inset links. Also added an explanatory text to the \begin_inset Quotes eld \end_inset up \begin_inset Quotes erd \end_inset link in the navigation bar, as in: \begin_inset Quotes eld \end_inset Up: Chapter 1 \begin_inset Quotes erd \end_inset . \end_layout \begin_layout Itemize Added partial table of contents to pages generated with \family typewriter --splitpart \family default . \end_layout \begin_layout Itemize Dependency cleanup between code modules. \end_layout \begin_layout Itemize Child documents of type \begin_inset Quotes eld \end_inset verbatim input \begin_inset Quotes erd \end_inset are now correctly converted on versions of Python built without universal newline support. \end_layout \begin_layout Itemize Include Index and Nomenclature in the Table of Contents. \end_layout \begin_layout Itemize When an Index, TOC, List of Figures\SpecialChar \ldots{} and the like is embedded in another layout, do not follow the style of the layout (thanks, Yaron!). \end_layout \begin_layout Itemize Solved a couple of XHTML validation errors: removed asterisks (*) in anchor names, avoid empty rows in arrays or case statements. \end_layout \begin_layout Itemize Make index entries work in Descriptions. Also, mixed styles should work again within Descriptions. \end_layout \begin_layout Itemize Group certain layouts together, such as Quote and Quotation. \end_layout \begin_layout Itemize Improved output for algorithms: do not run lines together, and do not separate other lines with double space. \end_layout \begin_layout Itemize List of algorithms does now correctly extract the text from the caption. \end_layout \begin_layout Itemize Increased line height for h2 in the main CSS (thanks, Wolfgang!). \end_layout \begin_layout Itemize Better color support in formulas: \family typewriter \backslash color \family default , \family typewriter \backslash textcolor \family default , \family typewriter \backslash colorbox \family default . \begin_inset Formula ${\color{blue}blue}$ \end_inset , \begin_inset Formula $\colorbox{yellow}{\color{blue}blue}$ \end_inset . \end_layout \begin_layout Itemize Formulas and formula labels are not colored by default. \end_layout \begin_layout Itemize Improved Index output: there is only one anchor for each entry, and entries are not shown in italics. \end_layout \begin_layout Itemize Allow hierarchical index entries, of the form \begin_inset Quotes eld \end_inset Main ! Secondary ! Final \begin_inset Quotes erd \end_inset . \end_layout \end_deeper \begin_layout Itemize 0.99 (2010-06-24): \end_layout \begin_deeper \begin_layout Itemize Added \family typewriter --splitpart \family default to online help (thanks, Sven!). \end_layout \begin_layout Itemize Restored compatibility with Python 2.4 (lost in 0.98 by mistake), added test to ensure it does not happen again. \end_layout \begin_layout Itemize BibTeX: improved template definitions for Vancouver style. \end_layout \begin_layout Itemize BibTeX: better parsing of braces (in templates) and quotes (in \family typewriter .bib \family default files). Nested braces in templates are supported. \end_layout \begin_layout Itemize BibTeX: variable citing styles. Enclose cites in brackets instead of using superscripts. \end_layout \begin_layout Itemize BibTeX: export all BibTeX variables in \family typewriter bib-\SpecialChar \ldots{} \family default spans. \end_layout \begin_layout Itemize BibTeX: limited author parsing, support for surname abbreviations as in style \emph on alpha \emph default . \end_layout \begin_layout Itemize BibTeX: use the \family typewriter file \family default tag to show a link to the local file. \end_layout \begin_layout Itemize Added \family typewriter \backslash oint \family default and friends as a bigsymbol: \begin_inset Formula $\oint x\text{·}dx$ \end_inset . \end_layout \begin_layout Itemize Support for \family typewriter \backslash officialeuro \family default : \begin_inset Formula $\officialeuro$ \end_inset . \end_layout \begin_layout Itemize Fix captions in lists of figures which use standard layouts (thanks, Hans!). \end_layout \begin_layout Itemize Added option \family typewriter --template \family default to use an HTML template and substitute \family typewriter \family default , \family typewriter \family default \SpecialChar \ldots{} \end_layout \begin_layout Itemize Added option \family typewriter --copyright \family default to add a copyright notice at the bottom (no longer generated by default). Deprecated old option \family typewriter --nocopy \family default . \end_layout \begin_layout Itemize Added support for including files as a code listing. \end_layout \end_deeper \begin_layout Itemize 0.98 (2010-05-13): \end_layout \begin_deeper \begin_layout Itemize MathJax: workaround bug in MSIE, that causes it to fail to render anything. \end_layout \begin_layout Itemize Add a margin to LyX-Code. Also improve line break separation inside LyX-Code. \end_layout \begin_layout Itemize Coalesce Python code: use relative paths when importing (thanks, Jack!). \end_layout \begin_layout Itemize Experimental installation script. \end_layout \begin_layout Itemize Avoid postprocessing child documents twice (thanks, Rainer!). \end_layout \begin_layout Itemize Solved bug when loading images from child documents in subdirectories (thanks, Rainer!). \end_layout \begin_layout Itemize Solved bug in image scaling when only one dimension is set (thanks, Wolfgang!). \end_layout \begin_layout Itemize Corrected issue with one-liner \family typewriter \backslash lstset \family default (thanks again, Rainer!). \end_layout \begin_layout Itemize Improved lists of figures, tables and algorithms: use short title, better labeling of floats. \end_layout \begin_layout Itemize Solved weird bug in float numbering when a chapter has only one layout. \end_layout \begin_layout Itemize Added \family typewriter \backslash diagup \family default and \family typewriter \backslash diagdown \family default : \begin_inset Formula $\diagup$ \end_inset , \begin_inset Formula $\diagdown$ \end_inset . \end_layout \begin_layout Itemize First public release of option \family typewriter --splitpart [level] \family default : split resulting web page at the given level. \end_layout \begin_layout Itemize Support for macros, both in LyX macro inset and as \family typewriter \backslash newcommand \family default . \end_layout \begin_layout Itemize Added URLs to most BibTeX formats. \end_layout \begin_layout Itemize Added BibTeX style \begin_inset Quotes eld \end_inset vancouver \begin_inset Quotes erd \end_inset for articles (thanks, John!). \end_layout \begin_layout Itemize Added a footer detailing eLyXer version and conversion date; it can be turned off with \family typewriter --nofooter \family default . \end_layout \end_deeper \begin_layout Itemize 0.43 (2010-04-10): \end_layout \begin_deeper \begin_layout Itemize Many BibTeX improvements: new style \emph on abbrvnat \emph default , conditional formatting, look up types in lowercase, understand \begin_inset Quotes eld \end_inset -- \begin_inset Quotes erd \end_inset as dash. \end_layout \begin_layout Itemize Added options for mathematical equations: \family typewriter --jsmath \family default to use \begin_inset CommandInset href LatexCommand href name "jsMath" target "math-jsmath.html" \end_inset and \family typewriter --mathjax \family default to use \begin_inset CommandInset href LatexCommand href name "MathJax" target "math-jsmath.html" \end_inset . \end_layout \begin_layout Itemize Added command help to \family typewriter loremipsumize.py \family default so it can be used outside of eLyXer. \end_layout \begin_layout Itemize Include internationalization files in \family typewriter .zip \family default file. \end_layout \begin_layout Itemize Solved bug in table parsing: separate different plain layouts (thanks, Sara!). \end_layout \begin_layout Itemize eLyXer compressed files now contain a single directory called \family typewriter elyxer-$VERSION \family default , instead of just \family typewriter elyxer \family default . \end_layout \begin_layout Itemize Added italicized uppercase Greek letters: \begin_inset Formula $\varGamma\varOmega$ \end_inset . De-italicized regular uppercase Greek letters: \begin_inset Formula $\Gamma\Omega$ \end_inset . \end_layout \end_deeper \begin_layout Itemize 0.42 (2010-03-17): \end_layout \begin_deeper \begin_layout Itemize Changed author everywhere to the real name, to avoid any copyleft uncertainties. \end_layout \begin_layout Itemize Remove hook in the main text ( \color green [D→] \color inherit ) from margin notes. \end_layout \begin_layout Itemize Do not crash when BibTeX files are not found, just show an error. \end_layout \begin_layout Itemize Added support for some IPA characters, including \begin_inset Formula $\textcrh$ \end_inset . Better parsing of \family typewriter \backslash textipa \family default text. \end_layout \begin_layout Itemize Added option \family typewriter --numberfoot \family default to label footnotes with numbers instead of letters. \end_layout \begin_layout Itemize Solved bug in assignment of default formatting to references (thanks, Hans!). \end_layout \begin_layout Itemize Added option \family typewriter --raw \family default to output raw HTML without header or footer. \end_layout \begin_layout Itemize Added French and Dutch translations. \end_layout \begin_layout Itemize Solved indenting problem for lists: only the first line was being indented. \end_layout \end_deeper \begin_layout Itemize 0.41 (2010-02-11): \end_layout \begin_deeper \begin_layout Itemize Select the translation based on document language. \end_layout \begin_layout Itemize Added em-dash --- such as in this sentence, \begin_inset Formula $\blacksquare$ \end_inset , \family typewriter \backslash textup \family default . \end_layout \begin_layout Itemize Added option \family typewriter --converter inkscape \family default to use Inkscape as SVG converter. \end_layout \begin_layout Itemize Solved bug when numbering unordered unique parts such as Part* (thanks, Geremy!). \end_layout \begin_layout Itemize Show error instead of crashing when included document does not exist. \end_layout \begin_layout Itemize Support for all box styles. In CSS: switched to \family typewriter outline-style \family default instead of \family typewriter border \family default for boxes. \end_layout \begin_layout Itemize Support for vertical space insets. \end_layout \begin_layout Itemize Support for references inside paragraphs and formatted references. \end_layout \begin_layout Itemize Listings are now converted using \family typewriter
\family default
 tags, instead of 
\family typewriter

\family default
.
 They are also justified left.
\end_layout

\begin_layout Itemize
Solved bug that prevented numbered listings to appear numbered (thanks,
 Sam!).
\end_layout

\begin_layout Itemize
Support for generic Flex insets, incuding 
\family typewriter
Flex CharStyle:MenuItem
\family default
.
\end_layout

\begin_layout Itemize
All 
\family typewriter
 
\family default
 entities are now generated as the Unicode U+00A0 character.
\end_layout

\begin_layout Itemize
New option 
\family typewriter
--iso885915
\family default
 to generate a document with ISO-8859-15 encoding.
\end_layout

\begin_layout Itemize
Support for Sam Liddicott's 
\begin_inset CommandInset href
LatexCommand href
name "Newfangle module"
target "http://repo.or.cz/w/newfangle.git/blob_plain/master:/www/docs/newfangle.html"

\end_inset

 for literate programming.
\end_layout

\begin_layout Itemize
Updated the developer guide for potential contributors; added link from
 the main page.
\end_layout

\begin_layout Itemize
Support for 
\family typewriter

\backslash
underbrace
\family default
 and 
\family typewriter

\backslash
overbrace
\family default
 (as bars and without sub/superscripts).
\end_layout

\end_deeper
\begin_layout Itemize
0.40 (2010-01-19):
\end_layout

\begin_deeper
\begin_layout Itemize
Faster (about 25%) BibTeX file parsing.
\end_layout

\begin_layout Itemize
Show version number after a crash.
\end_layout

\begin_layout Itemize
Imported Jens Nöckel's contributed list of LaTeX to Unicode mappings: 
\begin_inset Formula $\divideontimes$
\end_inset

, 
\begin_inset Formula $\backepsilon$
\end_inset

 and many more.
\end_layout

\begin_layout Itemize
Added support for compressed documents (Document\SpecialChar \menuseparator
Compressed).
\end_layout

\begin_layout Itemize
Added configurable alignment support for equation environments (thanks,
 Jens!).
 Multiple labels per formula are correctly processed.
\end_layout

\begin_layout Itemize
Added a couple of note insets for Tufte document classes, appearing as side
 notes without a reference (thanks, Joachim!).
\end_layout

\begin_layout Itemize
Support for escaped characters in BibTeX files, added German umlauts for
 starters.
\end_layout

\begin_layout Itemize
Support for internationalization using GNU gettext files.
 Added Spanish and German translations in the 
\family typewriter
po/
\family default
 folder.
\end_layout

\begin_layout Itemize
Support for verbatim includes.
\end_layout

\end_deeper
\begin_layout Itemize
0.39 (2009-12-20):
\end_layout

\begin_deeper
\begin_layout Itemize
Avoid oversized images on IE6.
\end_layout

\begin_layout Itemize
Solved several crashes with the LyX documentation (thanks, Uwe!).
\end_layout

\begin_layout Itemize
Created script to lorem-ipsumize texts, found in 
\family typewriter
src/loremipsumize.py
\family default
.
\end_layout

\begin_layout Itemize
Solved some issues with BibTeX parsing; now it should work with most real-world
 files (thanks, Ken!).
 Also improved error reporting and implemented a new way of line-by-line
 parsing from file, activated with 
\family typewriter
--lowmem
\family default
.
\end_layout

\begin_layout Itemize
Support for binomial coefficients: 
\begin_inset Formula $\binom{A}{B}$
\end_inset

.
 Ignore commands 
\family typewriter

\backslash
leftroot
\family default
, 
\family typewriter

\backslash
uproot
\family default
.
 Generic support for variable commands in math mode.
\end_layout

\begin_layout Itemize
Support for omitted aligned brackets: 
\begin_inset Formula $\left.right\right)$
\end_inset

 (thanks, Jens!).
\end_layout

\begin_layout Itemize
Solved bug with image conversion from directories (thanks, Olivier!).
\end_layout

\end_deeper
\begin_layout Itemize
0.38 (2009-12-03):
\end_layout

\begin_deeper
\begin_layout Itemize
Resized all logos in the documentation.
\end_layout

\begin_layout Itemize
Solved bug in paragraph indentation that indented all formula spans and
 elements.
\end_layout

\begin_layout Itemize
Solved a couple of bugs in image scaling: wraps with images, images in figures.
\end_layout

\begin_layout Itemize
Solved bug in TOC generation: article-class documents had their TOC depth
 off-by-one.
\end_layout

\begin_layout Itemize
Solved bug with listings inserted in documents using LyX 1.6, and improved
 their looks.
\end_layout

\begin_layout Itemize
Slight font size reduction on Firefox, and huge reduction on some other
 proprietary browsers.
 Now global font size specification is done using percents.
\end_layout

\begin_layout Itemize
New commands: 
\family typewriter

\backslash
gtrless
\family default
: 
\begin_inset Formula $\gtrless$
\end_inset

, 
\family typewriter

\backslash
complement
\family default
: 
\begin_inset Formula $\complement$
\end_inset

, 
\family typewriter

\backslash
measuredangle
\family default
: 
\begin_inset Formula $\measuredangle$
\end_inset

, 
\family typewriter

\backslash
sphericalangle
\family default
: 
\begin_inset Formula $\sphericalangle$
\end_inset

, 
\family typewriter

\backslash
nmid
\family default
: 
\begin_inset Formula $\nmid$
\end_inset

, 
\family typewriter

\backslash
circeq
\family default
: 
\begin_inset Formula $\circeq$
\end_inset

, 
\family typewriter

\backslash
lessgtr
\family default
: 
\begin_inset Formula $\lessgtr$
\end_inset

, 
\family typewriter

\backslash
nparallel
\family default
: 
\begin_inset Formula $\nparallel$
\end_inset

.
\end_layout

\end_deeper
\begin_layout Itemize
0.37 (2009-11-30):
\end_layout

\begin_deeper
\begin_layout Itemize
Further improvements in float manipulation: figures enclosing other figures
 have their own tweaked CSS class (thanks, Olivier).
\end_layout

\begin_layout Itemize
PNG and JPEG images are not rescaled anymore, and never shown above their
 maximum size.
 Width and height are set using CSS properties.
\end_layout

\begin_layout Itemize
TOC generation for unordered entries (like 
\family typewriter
Section*
\family default
) and entries inserted in other layouts.
 Max TOC depth and max numbering depth are honored.
 Also solved bug in tagging of unordered parts.
\end_layout

\begin_layout Itemize
Implemented indented paragraphs when specified in the document.
\end_layout

\begin_layout Itemize
Horizontal fill is now shown as a fixed-width space.
\end_layout

\begin_layout Itemize
Simplified postprocessing code.
 Inclusion of child documents is now done inside a Standard layout.
\end_layout

\begin_layout Itemize
Support for commands 
\family typewriter

\backslash
varkappa
\family default
: 
\begin_inset Formula $\varkappa$
\end_inset

, 
\family typewriter

\backslash
varnothing
\family default
: 
\begin_inset Formula $\varnothing$
\end_inset

, 
\family typewriter

\backslash
mathring
\family default
: 
\begin_inset Formula $\mathring{A}$
\end_inset

, 
\family typewriter

\backslash
backprime
\family default
: 
\begin_inset Formula $\backprime$
\end_inset

, 
\family typewriter

\backslash
notin
\family default
: 
\begin_inset Formula $\notin$
\end_inset

, 
\family typewriter

\backslash
hfill
\family default
: 
\begin_inset Formula $\hfill$
\end_inset

, 
\family typewriter

\backslash
circledR
\family default
: 
\begin_inset Formula $\circledR$
\end_inset

, 
\family typewriter

\backslash
hslash
\family default
: 
\begin_inset Formula $\hslash$
\end_inset

.
\end_layout

\begin_layout Itemize
New option 
\family typewriter
--splitpart
\family default
 to split the output in multiple pages, one page per part; needs more tweaking.
\end_layout

\end_deeper
\begin_layout Itemize
0.36 (2009-11-19):
\end_layout

\begin_deeper
\begin_layout Itemize
New in-memory processing of a document before file output, activated by
 default.
 It includes: TOC generation (TOC entries admit typefaces, colors, weights,
 spaces, short titles but restrict most other content), sequential numbering
 to bibliography entries, lists of floats (figures, tables, algorithms),
 correct labeling of references and use of the embedded title as HTML title.
\end_layout

\begin_layout Itemize
New option 
\family typewriter
--lowmem
\family default
 to do one-pass filtering only, to preserve memory (keeping the old behavior).
\end_layout

\begin_layout Itemize
Updated the 
\begin_inset CommandInset href
LatexCommand href
name "developer guide"
target "devguide.html"

\end_inset

.
\end_layout

\begin_layout Itemize
Change the postprocessing of equation labels so that only one anchor is
 used for the whole equation.
\end_layout

\begin_layout Itemize
Added 
\family typewriter

\backslash
mathscr
\family default
 and a few script fonts: 
\begin_inset Formula $\mathscr{hello}$
\end_inset

.
 Added several characters for math script (
\family typewriter

\backslash
mathscr
\family default
), fraktur (
\family typewriter

\backslash
mathfrak
\family default
) and blackboard (
\family typewriter

\backslash
mathbb
\family default
) fonts, and implemented the translation to Unicode chars: 
\begin_inset Formula $\mathscr{F}$
\end_inset

, 
\begin_inset Formula $\mathfrak{F}$
\end_inset

, 
\begin_inset Formula $\mathbb{F}$
\end_inset

.
\end_layout

\begin_layout Itemize
New math commands: 
\family typewriter

\backslash
dfrac
\family default
, implemented as 
\family typewriter

\backslash
cfrac
\family default
; 
\family typewriter

\backslash
c
\family default
 for cedilla, already implemented as characters and now as decoration: 
\begin_inset Formula $\c{G}$
\end_inset

; thick space 
\family typewriter

\backslash
;
\family default
 and quotes 
\family typewriter
"
\family default
: 
\begin_inset Formula $"\;"$
\end_inset

; 
\family typewriter

\backslash
hspace
\family default
 for horizontal space and 
\family typewriter

\backslash
vspace
\family default
 for vertical space; and a few size commands: 
\family typewriter

\backslash
big
\family default
, 
\family typewriter

\backslash
Big
\family default
, 
\family typewriter

\backslash
bigg
\family default
, 
\family typewriter

\backslash
Bigg
\family default
, 
\family typewriter

\backslash
middle
\family default
.
\end_layout

\begin_layout Itemize
Added a 
\family typewriter
parent
\family default
 attribute to every 
\family typewriter
Container
\family default
, for easier processing.
\end_layout

\begin_layout Itemize
Image conversion and display: process width and height in an image if both
 are present; use % width of image within a float to scale the float; set
 max scaling of images to 100% with 
\family typewriter
max-width
\family default
 CSS attribute.
 (Thanks, Olivier and Uwe.)
\end_layout

\begin_layout Itemize
Subfloats are numbered (a), (b) (instead of 
\begin_inset Formula $x.y$
\end_inset

a, 
\begin_inset Formula $x.y$
\end_inset

b).
\end_layout

\begin_layout Itemize
Convert all pathnames for image conversion using 
\family typewriter
sys.getfilesystemencoding()
\family default
.
\end_layout

\end_deeper
\begin_layout Itemize
0.35 (2009-11-05):
\end_layout

\begin_deeper
\begin_layout Itemize
Added new characters: 
\family typewriter

\backslash
checkmark
\family default
 
\begin_inset Formula $\checkmark$
\end_inset

, 
\family typewriter

\backslash
blacklozenge
\family default
 
\begin_inset Formula $\blacklozenge$
\end_inset

, 
\family typewriter

\backslash
nexists
\family default
 
\begin_inset Formula $\nexists$
\end_inset

, 
\family typewriter

\backslash
mathcircumflex
\family default
 
\begin_inset Formula $\mathcircumflex$
\end_inset

.
\end_layout

\begin_layout Itemize
Updated all documentation to LyX 1.6.
\end_layout

\begin_layout Itemize
Solved CSS validation error in 
\family typewriter
table.align
\family default
 (thanks, Olivier).
\end_layout

\begin_layout Itemize
Solved XHTML validation error in greyed out note, removing useless 
\family typewriter
div
\family default
s.
\end_layout

\begin_layout Itemize
Add a space after a fraction and before the units: 
\begin_inset Formula $\unit[\nicefrac{3}{2}]{km}$
\end_inset

, 
\begin_inset Formula $\unit[\frac{7}{16}]{s}$
\end_inset

.
\end_layout

\begin_layout Itemize
Corrected display of float within a float (thanks again, Olivier!).
\end_layout

\begin_layout Itemize
Modified the meaning of 
\family typewriter
--toc
\family default
 to be an on/off switch; the old behavior is now under 
\family typewriter
--toctarget
\family default
.
\end_layout

\begin_layout Itemize
Changed the 2009-11-05 option 
\family typewriter
--cutpart
\family default
 to 
\family typewriter
--splitpart
\family default
: new option to split the output file in parts.
 Not yet working correctly (for instance, links are not redirected).
\end_layout

\begin_layout Itemize
eLyXer now understands and processes new Graphics options: 
\family typewriter
width 50col%
\family default
, 
\family typewriter
height 50theight%
\family default
 and friends (thanks, Uwe).
\end_layout

\begin_layout Itemize
PDF images are cropped before conversion to PNG (thanks, Uwe).
\end_layout

\begin_layout Itemize
Included child documents can be inserted using firstline and lastline (as
 seen in 
\family typewriter
EmbeddedObjects.lyx
\family default
).
\end_layout

\end_deeper
\begin_layout Itemize
0.34 (2009-10-28):
\end_layout

\begin_deeper
\begin_layout Itemize
Support for child document inclusion (Insert\SpecialChar \menuseparator
File\SpecialChar \menuseparator
Child Document\SpecialChar \ldots{}
).
\end_layout

\begin_layout Itemize
Avoid generating images on different directories (relative paths starting
 with 
\family typewriter
../
\family default
).
\end_layout

\begin_layout Itemize
Added 
\family typewriter

\backslash
maltese
\family default
 
\begin_inset Formula $\maltese$
\end_inset

 and financial symbols $, €, ¥.
\end_layout

\begin_layout Itemize
Removed annoying message 
\begin_inset Quotes eld
\end_inset

Unexpected end of bracket
\begin_inset Quotes erd
\end_inset

 when parsing empty brackets.
\end_layout

\begin_layout Itemize
Support for 
\family typewriter

\backslash
raisebox
\family default
.
\end_layout

\begin_layout Itemize
Created new structure of 
\family typewriter
Writer
\family default
s, preparing for document segmentation and TOC generation.
\end_layout

\end_deeper
\begin_layout Itemize
0.33 (2009-10-19):
\end_layout

\begin_deeper
\begin_layout Itemize
New TOC generation process based on an already-generated HTML document,
 not ready for prime time yet.
\end_layout

\begin_layout Itemize
Adapted 
\family typewriter
--help
\family default
 option so that it shows the executable file as invoked (
\family typewriter
elyxer.py
\family default
, 
\family typewriter
elyxer
\family default
 or whatever).
 Expanded online help from this command.
\end_layout

\begin_layout Itemize
Support for new text commands 
\family typewriter

\backslash
textsf
\family default
, 
\family typewriter

\backslash
texttt
\family default
, 
\family typewriter

\backslash
textit
\family default
, 
\family typewriter

\backslash
textbf
\family default
, 
\family typewriter

\backslash
textsl
\family default
, 
\family typewriter

\backslash
textsc
\family default
.
\end_layout

\begin_layout Itemize
Properly parse all text commands 
\family typewriter

\backslash
text\SpecialChar \ldots{}

\family default
, including 
\family typewriter

\backslash
textipa
\family default
.
\end_layout

\begin_layout Itemize
Support for 
\family typewriter

\backslash
cfrac
\family default
.
 Now regular 
\family typewriter

\backslash
frac
\family default
 shows embedded formulas smaller.
\end_layout

\begin_layout Itemize
Do not number equations containing 
\family typewriter
*
\family default
, like in 
\family typewriter

\backslash
begin{align*}
\family default
.
 (Once more, thanks Uwe.)
\end_layout

\begin_layout Itemize
Properly align equations for AMS align environment.
 Other environments are parsed but not necessarily honored.
\end_layout

\begin_layout Itemize
Correctly distinguish 
\family typewriter

\backslash
epsilon
\family default
 
\begin_inset Formula $\epsilon$
\end_inset

 from 
\family typewriter

\backslash
varepsilon
\family default
 
\begin_inset Formula $\varepsilon$
\end_inset

.
\end_layout

\begin_layout Itemize
Added TeX-to-Unicode mappings from 
\begin_inset CommandInset href
LatexCommand href
name "Markus Kuhn"
target "http://www.cl.cam.ac.uk/~mgk25/ucs/examples/TeX.txt"

\end_inset

.
\end_layout

\begin_layout Itemize
Support for 
\family typewriter

\backslash
unitfrac
\family default
.
\end_layout

\begin_layout Itemize
Added 
\family typewriter

\backslash
dots
\family default
: 
\begin_inset Formula $\dots$
\end_inset

.
\end_layout

\end_deeper
\begin_layout Itemize
0.32 (2009-10-05):
\end_layout

\begin_deeper
\begin_layout Itemize
Fixed unit processing.
 Now units appear separated by a space after the number.
\end_layout

\begin_layout Itemize
Repaired use of 
\family typewriter
AlphaCommand
\family default
s.
 Decorations so defined in the configuration file appear again as a single
 symbol: 
\begin_inset Formula $\hat{a}$
\end_inset

.
\end_layout

\begin_layout Itemize
Added option 
\family typewriter
--lyxformat
\family default
 to return the highest LyX format that eLyXer understands.
 Should help when integrating with 
\family typewriter
lyx2lyx
\family default
.
\end_layout

\begin_layout Itemize
Improved TOC (table of contents) generation.
 Modified option 
\family typewriter
--toc
\family default
 to accept an URL, and documented it.
\end_layout

\begin_layout Itemize
Added option 
\family typewriter
--target
\family default
 to add a target frame to every link.
\end_layout

\begin_layout Itemize
Corrected equation numbering error: now all 
\family typewriter

\backslash
begin{equation}\SpecialChar \ldots{}

\backslash
end{equation}
\family default
 formulae are numbered.
 (Thanks once more, Uwe.)
\end_layout

\end_deeper
\begin_layout Itemize
0.31 (2009-09-27):
\end_layout

\begin_deeper
\begin_layout Itemize
Modified image parsing code to remove dependency on Python 2.5, expurging
 
\family typewriter
os.SEEK_CUR
\family default
.
\end_layout

\begin_layout Itemize
Removed the ill-fated 
\family typewriter
elyxerconv.py
\family default
 library file (but kept 
\family typewriter
io/convert.py
\family default
), see 
\begin_inset CommandInset href
LatexCommand href
name "lyx-devel thread"
target "http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg154647.html"

\end_inset

.
 Now the file 
\family typewriter
elyxer.py
\family default
 itself can be installed as a library, and run as a module with 
\family typewriter
python -m
\family default
.; see also 
\begin_inset CommandInset href
LatexCommand href
name "lyx-devel thread"
target "http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg154749.html"

\end_inset

.
\end_layout

\begin_layout Itemize
eLyXer was added to the Python Package Index (
\begin_inset CommandInset href
LatexCommand href
name "PyPI"
target "http://pypi.python.org/pypi"

\end_inset

) starting with 0.30.
 Now it should be automatically registered for each release.
\end_layout

\begin_layout Itemize
Updated documentation (
\begin_inset CommandInset href
LatexCommand href
name "user guide"
target "userguide.html"

\end_inset

, 
\family typewriter
README
\family default
 file) with details of distutils installation.
\end_layout

\begin_layout Itemize
Modified single string 
\family typewriter
Container
\family default
s (
\family typewriter
StringContainer
\family default
, 
\family typewriter
Constant
\family default
) so that they appear as empty 
\family typewriter
Container
\family default
s -- should speed up postprocessing.
\end_layout

\begin_layout Itemize
Solved bug when parsing BibTeX files with incorrect lines.
\end_layout

\begin_layout Itemize
Modified postprocessing to correctly process lists within tables.
\end_layout

\begin_layout Itemize
In the process refactored postprocessing completely: now instead of unconditiona
l postprocessor stages, each stage can add a postprocessing hook.
 Should be faster -- but is indeed a bit slower.
\end_layout

\end_deeper
\begin_layout Itemize
0.30 (2009-09-13):
\end_layout

\begin_deeper
\begin_layout Itemize
Removed most comments from the final distributed file 
\family typewriter
elyxer.py
\family default
.
\end_layout

\begin_layout Itemize
Added 
\begin_inset CommandInset href
LatexCommand href
name "distutils"
target "http://docs.python.org/distutils/index.html"

\end_inset

 support for cross-platform distribution.
 The library 
\family typewriter
elyxerconv
\family default
 is added to local Python libraries.
\end_layout

\begin_layout Itemize
Added command line option 
\family typewriter
--forceformat
\family default
: force eLyXer to convert all images to the given output format.
\end_layout

\begin_layout Itemize
Switched all options in command line help to quotes: 
\family typewriter
--title
\begin_inset space ~
\end_inset


\series bold
<
\series default
title
\series bold
>
\family default
\series default
 is now 
\family typewriter
--title
\begin_inset space ~
\end_inset


\series bold
"
\series default
title
\series bold
"
\family default
\series default
.
\end_layout

\begin_layout Itemize
Solved bug reported by Uwe Stöhr when reading Windows BibTeX file generated
 by JabRef.
 Now eLyXer tries several encodings for each file, initially UTF-8 and Cp1252.
\end_layout

\begin_layout Itemize
Another bug, also reported by Uwe Stöhr, in branch selection.
 Added test 
\family typewriter
branches.lyx
\family default
.
\end_layout

\end_deeper
\begin_layout Itemize
0.29 (2009-09-08):
\end_layout

\begin_deeper
\begin_layout Itemize
Preliminary support for BibTeX.
 Configurable output styles (albeit cumbersome and quite primitive).
\end_layout

\begin_layout Itemize
Added new cite commands 
\family typewriter
citep
\family default
, 
\family typewriter
citet
\family default
, 
\family typewriter
citealt
\family default
; and reference command 
\family typewriter
prettyref
\family default
.
\end_layout

\begin_layout Itemize
A couple of new math commands: 
\family typewriter

\backslash
ldots
\family default
, 
\family typewriter

\backslash
qquad
\family default
.
\end_layout

\end_deeper
\begin_layout Itemize
0.28 (2009-09-05):
\end_layout

\begin_deeper
\begin_layout Itemize
Various fixes related to Windows integration.
\end_layout

\begin_layout Itemize
Documented integration with LyX in the user guide.
\end_layout

\end_deeper
\begin_layout Itemize
0.27 (2009-06-17):
\end_layout

\begin_deeper
\begin_layout Itemize
Units without the magnitude (the number) are working.
\end_layout

\begin_layout Itemize
Complex roots now working, added to the math showcase.
\end_layout

\begin_layout Itemize
Leave JPEG images untransformed instead of converting them to PNG (or at
 least transform them to JPEG).
 Read JPEG image sizes.
\end_layout

\begin_layout Itemize
More flexible configuration options for lists of values.
\end_layout

\begin_layout Itemize
Added 
\family typewriter
--destdirectory
\family default
 option to convert images into.
\end_layout

\begin_layout Itemize
Image conversion from a different directory (or even with absolute paths)
 should work now.
\end_layout

\begin_layout Itemize
Changed the whole infrastructure for formulae parsing.
 More structured parsing should now be possible, e.g.
 square brackets are first-class citizens.
\end_layout

\begin_layout Itemize
Implemented nice fractions: 
\begin_inset Formula $\nicefrac{7}{8}$
\end_inset

.
\end_layout

\begin_layout Itemize
Redid basic typography: default font is now sans-serif, which looks better
 on your average browser.
 Formulae have a bit more space around.
\end_layout

\begin_layout Itemize
Imported the complete symbol list from the 
\family typewriter
unicodesymbols
\family default
 file in LyX.
\end_layout

\end_deeper
\begin_layout Itemize
0.26 (2009-06-10):
\end_layout

\begin_deeper
\begin_layout Itemize
Added a lot of new LaTeX commands, both for Unicode symbols and for math
 functions.
\end_layout

\begin_layout Itemize
New mechanism to include new lists of 
\begin_inset Quotes eld
\end_inset

command:Unicode
\begin_inset Quotes erd
\end_inset

 equivalents.
\end_layout

\begin_layout Itemize
New decoration command 
\family typewriter

\backslash
overrightarrow
\family default
, to show a long arrow above some text.
\end_layout

\begin_layout Itemize
Solved bug: 
\family typewriter
--directory
\family default
 option was not working.
 A new test for this option added.
\end_layout

\end_deeper
\begin_layout Itemize
0.25 (2009-06-08):
\end_layout

\begin_deeper
\begin_layout Itemize
Added new characters: German dash separator, a few arrows, horizontal ellipsis.
\end_layout

\begin_layout Itemize
Automatic insertion of release date in the changelog upon version release.
\end_layout

\begin_layout Itemize
New formula commands: phantom text (for spacing), mbox (literal text).
\end_layout

\begin_layout Itemize
Solved two bugs in URLs: make FlexURLs point to the link in their contents,
 and do not show 
\begin_inset Quotes eld
\end_inset

mailto:
\begin_inset Quotes erd
\end_inset

 in email links.
\end_layout

\begin_layout Itemize
Properly display Date layouts as 
\family typewriter

\family default . \end_layout \begin_layout Itemize Display a FATAL error (and terminate) when trying to read beyond the end of the document. \end_layout \begin_layout Itemize Cross-platform support for newlines. Besides the Unix \family typewriter \backslash n \family default , now supports Windows ( \family typewriter \backslash r \backslash n \family default ) and Mac OS X ( \family typewriter \backslash r \family default ) newlines. \end_layout \begin_layout Itemize Support for \family typewriter \backslash unit \family default command, showing units for a magnitude. \end_layout \begin_layout Itemize New format for formulae (instead of \family typewriter $\SpecialChar \ldots{} $ \family default or \family typewriter \backslash [\SpecialChar \ldots{} \backslash ] \family default ): \family typewriter \backslash command{\SpecialChar \ldots{} } \family default . \end_layout \end_deeper \begin_layout Itemize 0.24 (2009-06-02): \end_layout \begin_deeper \begin_layout Itemize Show sum and integral limits correctly in Konqueror, Safari and Chrome. \end_layout \begin_layout Itemize Also show roots and arrays correctly in those browsers. Larger radical symbol looks better. \end_layout \begin_layout Itemize Added \begin_inset CommandInset href LatexCommand href name "Math Showcase" target "math.html" \end_inset to test on \begin_inset CommandInset href LatexCommand href name "browsershots.org" target "http://browsershots.org/" \end_inset . \end_layout \begin_layout Itemize Substituted medium mathematical spaces with midspaces for better browser compatibility. \end_layout \begin_layout Itemize Added \family typewriter --unicode \family default option to switch on full Unicode output; right now only re-adds medium mathematical spaces. \end_layout \begin_layout Itemize Included all Greek letters, upper and lower case; and common math symbols. \end_layout \begin_layout Itemize Make title from command line option prevail over PDF title. \end_layout \begin_layout Itemize Specified minimum browser versions in the user guide and in the requirements. \end_layout \begin_layout Itemize Documented option \family typewriter --directory \family default (it existed already but was not in the docs). \end_layout \begin_layout Itemize Option \family typewriter --toc \family default can generate a Table Of Contents. Not documented because it is only a start for bigger things. \end_layout \begin_layout Itemize Repaired configuration export to \family typewriter base.cfg \family default : now all objects in \family typewriter config.py \family default are automatically exported. \end_layout \end_deeper \begin_layout Itemize 0.23 (2009-05-24): \end_layout \begin_deeper \begin_layout Itemize Corrected numbering and appearance of subfloats. \end_layout \begin_layout Itemize Plain layouts are not reflected in HTML output. \end_layout \begin_layout Itemize Unified table parsing, moved table starts to configuration file. \end_layout \begin_layout Itemize Use unicode output in debug and error messages. \end_layout \begin_layout Itemize Automated testing now shows unified diff, to show the file that doesn't pass the tests. \end_layout \begin_layout Itemize Finally got UTF-8 output right (hopefully). \end_layout \begin_layout Itemize Display floats with tables properly aligned, and on a white background. Listings are working too. \end_layout \begin_layout Itemize Show warning when document is created with LyX 1.4. \begin_inset Formula $x$ \end_inset . \end_layout \begin_layout Itemize Transform \family typewriter \backslash newpage \family default to an empty paragraph. \end_layout \begin_layout Itemize Standard layouts can be \family typewriter
\family default or nothing at all, generating valid XHTML. \end_layout \begin_layout Itemize Added nomenclature commands for 1.5. \begin_inset Formula $x$ \end_inset . \end_layout \begin_layout Itemize Got Index and nomenclature working again, added test file so they don't break anymore. \end_layout \end_deeper \begin_layout Itemize 0.22 (2009-05-15): \end_layout \begin_deeper \begin_layout Itemize Modified user guide to explain \family typewriter --html \family default option. \end_layout \begin_layout Itemize Solved a few bugs manifested when exporting to HTML 4.0 with \family typewriter --html \family default . \end_layout \begin_layout Itemize More configurable containers: quote types, barred text, boxes, info insets\SpecialChar \ldots{} \end_layout \begin_layout Itemize Added note on the main page about slow mirrors and latest versions. \end_layout \begin_layout Itemize Standard layouts can now be translated to \family typewriter
\family default or to \family typewriter \family default , depending on the context. \end_layout \begin_layout Itemize Command endings can be deduced from starts in configuration file. \end_layout \begin_layout Itemize A bunch of new math symbols: nu, angle brackets. \end_layout \begin_layout Itemize Generalized big brackets of several types. Consolidated parameter parsing in formulas. \end_layout \begin_layout Itemize Equation numbering is working. \end_layout \begin_layout Itemize Unknown commands are shown in red: \begin_inset Formula $\unknown$ \end_inset . \end_layout \end_deeper \begin_layout Itemize 0.21 (2009-05-11): \end_layout \begin_deeper \begin_layout Itemize Command line option \family typewriter --html \family default to export to HTML 4.0. \end_layout \begin_layout Itemize Container endings are now configurable from the main config file. \end_layout \begin_layout Itemize Styles can be mixed and matched at will (like \family typewriter typewriter \series bold bold \color blue in blue \family default \series default \color inherit ). \end_layout \begin_layout Itemize All constant strings (such as \begin_inset Quotes eld \end_inset Table of contents \begin_inset Quotes erd \end_inset ) should now be configurable. \end_layout \begin_layout Itemize Added a few more colors: \color green green \color inherit , \color magenta magenta \color inherit , \color cyan cyan \color inherit , \color yellow yellow \color inherit , \color white white \color inherit (those two were yellow and white). \end_layout \end_deeper \begin_layout Itemize 0.20 (2009-05-09): \end_layout \begin_deeper \begin_layout Itemize Command line option \family typewriter --version \family default to show the current version number and date. \end_layout \begin_layout Itemize Release date is now automatically added to the configuration. \end_layout \begin_layout Itemize Preliminary support for inset boxes. \end_layout \begin_layout Itemize Support for numbered listings. \end_layout \begin_layout Itemize Added \family typewriter \family default tag for \family typewriter Content-Type \family default , to ease importing into word processors. \end_layout \begin_layout Itemize Automated version generation, taking version number and date from config, and updating current version in the main page. \end_layout \end_deeper \begin_layout Itemize 0.19 (2009-05-07): \end_layout \begin_deeper \begin_layout Itemize More powerful configuration file manipulation: export to generic config and Python files. \end_layout \begin_layout Itemize Start lines for every parsed structure can now be configured in the global \family typewriter base.cfg \family default file. \end_layout \begin_layout Itemize New Info types \family typewriter package \family default and \family typewriter textclass \family default . \end_layout \begin_layout Itemize New formula symbols: up and down arrows, long double arrows, Gamma and Upsilon, mu, backslash. \end_layout \begin_layout Itemize Show line number and current line for generic errors. \end_layout \begin_layout Itemize Listings and document abstracts are displayed properly. \end_layout \end_deeper \begin_layout Itemize 0.18 (2009-05-04): \end_layout \begin_deeper \begin_layout Itemize Wrap floats are separated by a bit of space (two exes, actually) from the text. \end_layout \begin_layout Itemize Solved bug when running without any arguments. \end_layout \begin_layout Itemize Main executable file is now changed from \family typewriter elyxer \family default to \family typewriter elyxer.py \family default , to prevent problems on platforms that require the extension; main source file has changed from \family typewriter elyxer.py \family default to \family typewriter principal.py \family default , to avoid confusion. \end_layout \begin_layout Itemize Moved all parsing code to the new package \family typewriter parse \family default , and configuration files to package \family typewriter conf \family default . \end_layout \begin_layout Itemize All configuration is now read from (and written to) plain text files. \end_layout \end_deeper \begin_layout Itemize 0.17 (2009-04-27): \end_layout \begin_deeper \begin_layout Itemize Alignment of table cells is now respected, both horizontally and vertically. \end_layout \begin_layout Itemize Wrap floats are actually floated left or right. \end_layout \begin_layout Itemize Correctly interpret symbols in formulae: \begin_inset Formula $!$ \end_inset , \begin_inset Formula $;$ \end_inset , \begin_inset Formula $\leq$ \end_inset , \begin_inset Formula $\geq$ \end_inset , \begin_inset Formula $\neq,$ \end_inset \begin_inset Formula $\in$ \end_inset , \begin_inset Formula $\ddots$ \end_inset , and a few spaces. \end_layout \begin_layout Itemize In formulae, \family typewriter \backslash displaystyle \family default and friends are ignored. \end_layout \begin_layout Itemize Square roots are again displayed correctly, and even better than before! \end_layout \begin_layout Itemize Cases are working (not perfect: with a bar instead of a bracket, but working). \end_layout \end_deeper \begin_layout Itemize 0.16 (2009-04-22): \end_layout \begin_deeper \begin_layout Itemize Document date is shown centered. \end_layout \begin_layout Itemize Special rows in a longtable are properly ignored. \end_layout \begin_layout Itemize Multicolumn cells are properly interpreted. \end_layout \begin_layout Itemize Sums and integral limits are properly displayed with respect to the symbol: \begin_inset Formula $\sum_{i=1}^{\infty}$ \end_inset . \end_layout \end_deeper \begin_layout Itemize 0.15 (2009-04-19): \end_layout \begin_deeper \begin_layout Itemize Info insets (containing shortcuts) are now interpreted and shown. \end_layout \begin_layout Itemize LyX-Code is interpreted as a \family typewriter
\family default
 tag.
\end_layout

\begin_layout Itemize
Reorganized code into a few packages.
\end_layout

\begin_layout Itemize
Line numbers are not shown for utility classes.
\end_layout

\begin_layout Itemize
Floats (figures, tables and algorithms) are now numbered.
\end_layout

\begin_layout Itemize
Float links point to the start of the table or figure, not to the caption.
\end_layout

\end_deeper
\begin_layout Itemize
0.14 (2009-04-13):
\end_layout

\begin_deeper
\begin_layout Itemize
Deeper layouts (of any kind, not just in lists) are now supported.
\end_layout

\begin_layout Itemize
Appendices are numbered correctly (as A, B, C\SpecialChar \ldots{}
).
\end_layout

\begin_layout Itemize
Sections in deeper layouts are numbered correctly too.
\end_layout

\begin_layout Itemize
Double dash does not catch Unix-style options: --css is not converted --
 while the version with spaces is.
\end_layout

\begin_layout Itemize
Corrected serious bug in formula parsing affecting inline arrays.
\end_layout

\begin_layout Itemize
Arrays with vertical alignment are correctly parsed.
\end_layout

\end_deeper
\begin_layout Itemize
0.13 (2009-04-12):
\end_layout

\begin_deeper
\begin_layout Itemize
Lists are correctly displayed, instead of one list per item.
\end_layout

\begin_layout Itemize
Lists can contain nested layouts.
\end_layout

\begin_layout Itemize

\family typewriter
List
\family default
 layouts (not to mistake with 
\family typewriter
Enumerate
\family default
 or 
\family typewriter
Itemize
\family default
 lists) are processed correctly.
\end_layout

\begin_layout Itemize
Changelog moved to separate document.
\end_layout

\begin_layout Itemize
Read image sizes correctly on big-endian architectures (e.g.
 Mac OS X on PowerPC).
\end_layout

\begin_layout Itemize
Numeration of chapters, sections\SpecialChar \ldots{}
 is working.
\end_layout

\begin_layout Itemize
Error messages now show the line where they happen.
\end_layout

\end_deeper
\begin_layout Itemize
0.12 (2009-04-05):
\end_layout

\begin_deeper
\begin_layout Itemize
Arrays are parsed correctly and displayed acceptably.
\end_layout

\begin_layout Itemize
Numbers and units are correctly separated.
\end_layout

\begin_layout Itemize
Text decorations (such as 
\begin_inset Formula $\hat{a}$
\end_inset

) are shown in line.
\end_layout

\begin_layout Itemize
Variables are italicized.
\end_layout

\begin_layout Itemize
Notes and comments are not output at all, greyed-out notes are shown in
 grey.
\end_layout

\begin_layout Itemize
LyX guides parse completely.
\end_layout

\end_deeper
\begin_layout Itemize
0.11 (2009-03-27):
\end_layout

\begin_deeper
\begin_layout Itemize
Arrays are at least well parsed (but still show wrong).
\end_layout

\begin_layout Itemize
Integrals and sums appear as large characters.
\end_layout

\begin_layout Itemize
Appendices are separated from the main document.
\end_layout

\begin_layout Itemize
The bibliography appears separated with a title.
\end_layout

\begin_layout Itemize
Floats appear centered on-screen.
\end_layout

\end_deeper
\begin_layout Itemize
0.10 (2009-03-23):
\end_layout

\begin_deeper
\begin_layout Itemize
Better handling of footnotes and margin notes: not overlapping and with
 a reference in the text.
\end_layout

\begin_layout Itemize
Better parsing of first word in a Description.
\end_layout

\begin_layout Itemize
Short titles are ignored.
\end_layout

\begin_layout Itemize
Added a few font families for equations.
 Not that they display too well\SpecialChar \ldots{}

\end_layout

\end_deeper
\begin_layout Itemize
0.9 (2009-03-21):
\end_layout

\begin_deeper
\begin_layout Itemize
Better formula parsing (including line breaks).
 Supports a few math fonts.
\end_layout

\begin_layout Itemize
Supports menu separator, text with bar, nomenclature and many more quote
 types.
\end_layout

\begin_layout Itemize
Single configuration file 
\family typewriter
general.py
\family default
.
\end_layout

\begin_layout Itemize
Layout of type Space is not shown.
\end_layout

\begin_layout Itemize
Supports branches.
 Inactive branches are not shown.
\end_layout

\begin_layout Itemize
New symbols: greek letters, shapes: bullet, right triangle.
\end_layout

\begin_layout Itemize
Added support for new style (1.6.
\begin_inset Formula $x$
\end_inset

) index entries.
\end_layout

\begin_layout Itemize
From LyX documentation: 
\family typewriter
UserGuide.lyx
\family default
 is now working (except for some math functions).
\end_layout

\end_deeper
\begin_layout Itemize
0.8 (2009-03-20):
\end_layout

\begin_deeper
\begin_layout Itemize
Can be run from other directories than the one with the document.
\end_layout

\begin_layout Itemize
Tables have light grey separations.
 Table spacing is now better adjusted.
\end_layout

\begin_layout Itemize
Descriptions appear with the first word in bold), but only within the first
 text style.
 Changing style in the middle of a word may distract the algorithm.
\end_layout

\begin_layout Itemize
Added support for Lyx notes (not rendered in the HTML), margin notes, pretty
 quotes ‘’, weird spaces.
\end_layout

\begin_layout Itemize
Added support for new style (1.6.
\begin_inset Formula $x$
\end_inset

) hyperlinks, labels and references, TOC, index.
\end_layout

\begin_layout Itemize
Uses PDF title if present.
\end_layout

\begin_layout Itemize
From LyX documentation: 
\family typewriter
Intro.lyx
\family default
 is now working.
\end_layout

\end_deeper
\begin_layout Itemize
0.7 (2009-03-16):
\end_layout

\begin_deeper
\begin_layout Itemize
Images referenced by absolute path are converted to relative PNGs.
\end_layout

\begin_layout Itemize
Range of supported quotes is greater.
 Unknown quotes are now marked as errors but do not make the tool fail.
\end_layout

\begin_layout Itemize
Default CSS is always on 
\begin_inset CommandInset href
LatexCommand href
name "nongnu.org"
target "http://www.nongnu.org/elyxer/lyx.css"

\end_inset

, it can be changed via command line option 
\family typewriter
--css
\family default
.
\end_layout

\begin_layout Itemize
Reinstated layout classes for unknown types.
\end_layout

\begin_layout Itemize
Updated documentation to include how to run on Windows.
\end_layout

\begin_layout Itemize
Added meta generator tag to all pages.
\end_layout

\begin_layout Itemize
Added option 
\family typewriter
--title
\family default
 to change the default page title.
\end_layout

\begin_layout Itemize
Phonetic symbols appear in dark cyan: 
\begin_inset Formula $\text{\textipa{[sample]}}$
\end_inset

.
\end_layout

\begin_layout Itemize
Lots of small fixes and improvements to correctly parse the official LyX
 guides (
\family typewriter
UserGuide.lyx
\family default
, 
\family typewriter
EmbeddedObjects.lyx
\family default
 and 
\family typewriter
Math.lyx
\family default
).
\end_layout

\end_deeper
\begin_layout Itemize
0.6 (2009-03-15):
\end_layout

\begin_deeper
\begin_layout Itemize
Added Flex URLs, Flex code.
\end_layout

\begin_layout Itemize
Works with Python 2.3.5, but not yet Mac OS X terminal.
\end_layout

\begin_layout Itemize
Alignment now works right (and center and left).
\end_layout

\begin_layout Itemize
Modified license files to comply with Savannah policies.
\end_layout

\begin_layout Itemize
Added index page and logo.
\end_layout

\end_deeper
\begin_layout Itemize
0.5 (2009-03-14):
\end_layout

\begin_deeper
\begin_layout Itemize
Inset parameters are all parsed correctly (including spaces in image paths).
\end_layout

\begin_layout Itemize
Formulae and tables should work again (including complex formatting).
\end_layout

\begin_layout Itemize
Modified to (mostly) run under Python 2.3.5 (Mac OS X Tiger).
\end_layout

\begin_layout Itemize
Processes layouts ending in `*' (like `Section*').
\end_layout

\begin_layout Itemize
Runtime options for help and to disable the copyright notice, debug, quietness.
\end_layout

\begin_layout Itemize
Accepts scaling for images.
\end_layout

\begin_layout Itemize
Nested lists working.
\end_layout

\end_deeper
\begin_layout Itemize
0.4 (2009-03-12):
\end_layout

\begin_deeper
\begin_layout Itemize
When images do not exist warns but does not fail.
\end_layout

\begin_layout Itemize
Author and title containing tags are properly processed.
\end_layout

\begin_layout Itemize
Slanted text translated to italics.
\end_layout

\begin_layout Itemize
Title no longer necessary to have a working document.
\end_layout

\begin_layout Itemize
ERT is ignored.
 Status line (open/collapsed) is ignored.
\end_layout

\begin_layout Itemize
Supports footnotes, newlines, bibitem entries and citations.
\end_layout

\begin_layout Itemize
Dev guide includes a 
\family typewriter
Container
\family default
 tutorial.
\end_layout

\end_deeper
\begin_layout Itemize
0.3 (2009-03-11): Now works with generic Insets.
\end_layout

\begin_layout Itemize
0.2 (2009-03-11): ImageMagick is not required anymore.
\end_layout

\begin_layout Itemize
0.1 (2009-03-10): first public version.
\end_layout

\end_body
\end_document
elyxer-1.2.5/forks/jras-elyxer/docs/parse tree.svg0000644000175000017500000005140612117061342021434 0ustar  chennochenno


  
    
      
    
    
      
    
    
      
    
    
      
    
    
  
  
  
    
      
        image/svg+xml
        
      
    
  
  
    
      
      \begin_inset
    
    
      
      Graphics
    
    
      
      Text
    
    
      
      LatexCommand
    
    
      
      Inset
    
    
      
      label
    
    
      
      ref
    
    
    
    
    
    
      
      Image
    
    
      
      Reference
    
    
      
      Label
    
    
    
    
    
    
    
      
      InsetText
    
    
  

elyxer-1.2.5/forks/jras-elyxer/docs/upload.sh0000755000175000017500000000241212117061342020475 0ustar  chennochenno#!/bin/bash

#   eLyXer -- convert LyX source files to HTML output.
#
#   Copyright (C) 2009 Alex Fernández
#
#   This program is free software: 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 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
#   GNU General Public License for more details.
#
#   You should have received a copy of the GNU General Public License
#   along with this program.  If not, see .

# Alex 20090315: upload generated documentation to Savannah CVS

# download current docs
mkdir cvs
cd cvs
#rm -Rf elyxer
#cvs -z3 -d:ext:alexfernandez@cvs.savannah.nongnu.org:/web/elyxer co elyxer
cvs  -z3 -d:ext:alexfernandez@cvs.savannah.nongnu.org:/web/elyxer update elyxer
# overwrite with current docs
cp ../*.html elyxer/
cp ../*.png elyxer/
cp ../*.css elyxer/
# remove MathJaX and jsMath (comment if they are updated)
#rm -Rf elyxer/MathJax
#rm -Rf elyxer/jsMath
# commit
cd elyxer
cvs commit -m "Automatic upload"

elyxer-1.2.5/forks/jras-elyxer/docs/lyx.css0000644000175000017500000003751612117061350020214 0ustar  chennochenno/*
*   eLyXer -- convert LyX source files to HTML output.
*
*   Copyright (C) 2009-2010 Alex Fernández
*
*   This program is free software: 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 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
*   GNU General Public License for more details.
*
*   You should have received a copy of the GNU General Public License
*   along with this program.  If not, see http://www.gnu.org/licenses/.
*/
/* --end--
* Global CSS file for LyX documents.
*/

body {
	font: 90% sans-serif;
	background: #f9f9f9;
	color: black;
	margin: 0;
	padding: 0;
}

#globalWrapper {
	margin: 10px 5%;
	padding: 20px;
	background: #ffffff;
	line-height: 1.5em;
}

/* Basic styles */
a {
	text-decoration: none;
	background: none;
}
a:link {
	color: #0030c0;
}
a:visited {
	color: #603090;
}
a:active {
	color: #ffa000;
}
a:hover {
	text-decoration: underline;
}
h1 {
	margin-top: 1em;
	line-height: 1.5em;
}
h1.Part {
	text-align: center;
}
h1.Part- {
	text-align: center;
}
sup {
	font-size: 0.75em;
	line-height: 0.5em;
	vertical-align: text-top;
}
sub {
	font-size: 0.75em;
	line-height: 0.5em;
	vertical-align: text-bottom;
}
div.Standard {
	margin: 1em 0;
}
div.Unindented {
	margin: 0;
}
div.Indented {
	text-indent: 30pt;
	margin: 0;
}
div.Indented * {
	text-indent: 0pt;
}
p.dir {
	float: right;
}
p.printindex {
	font-size: 0.90em;
}
a.printindex {
	color: black;
}
table {
	display: inline-table;
	text-align: center;
	border-collapse: collapse;
	margin-top: 1em;
	margin-bottom: 1em;
}
tr.header {
	border-bottom: thin solid #c0c0c0;
	background: #ffffff;
	font-weight: bold;
}
td {
	padding: 1ex;
	border: thin solid #f0f0f0;
}
td div.Standard {
	margin: 0ex;
	padding: 0ex;
}
div.caption div.Standard, div.table div.Standard {
	margin: 0ex;
	padding: 0ex;
}
td.numeric {
	text-align: right;
}
td.empty {
	text-align: center;
}
div.right {
	text-align: right;
}
div.center {
	text-align: center;
	margin-left: auto;
	margin-right: auto;
}
p.biblio {
}
div.Paragraph, div.Paragraph- {
	font-weight: bold;
	font-size: 103%;
}
span.versalitas, span.noun {
	font-variant: small-caps;
}
span.sans {
	font-family: sans-serif;
}
span.code {
	font-family: monospace;
}
div.Plain {
	display: inline;
	width: auto;
}
h2 {
	line-height: 1.4em;
}
span.Description-entry {
	font-weight: bold;
}
span.List-entry {
	display: inline-block;
	width: 25%;
	vertical-align: text-top;
}
span.List-contents {
	display: inline-block;
	width: 75%;
	vertical-align: text-top;
}
div.Space {
	display: none;
}
span.appendix {
	display: none;
}
h1.biblio {
}
span.greyedout {
	color: #808080;
}
div.Description, div.List, li {
	margin: 1em 0;
}
li.nested {
	list-style-type: none;
}
span.Info {
	background: #f0f0f0;
	border: thin solid #c0c0c0;
}
pre {
	padding: 0em;
	margin: 0em;
	width: auto;
	font-family: monospace;
	line-height: 1.5em;
}
pre.LyX-Code {
	margin: 0.5em 3em;
}
a.Label {
	text-decoration: none;
	color: #000000;
}
span.phantom {
	color: #ffffff;
}
a.biblioentry {
	color: black;
}
span.menuitem {
	font-size: 105%;
}
span.normal {
	font-style: normal;
}
div.PlainVisible {
	width: auto;
}
div.indexgroup {
	margin-left: 2em;
}
span.strong {
	font-weight: bold;
}

/* Figures and Tables */
img.embedded {
	width: 100%;
	_width: auto;
}
div.float {
	margin-top: 1ex;
	margin-bottom: 1ex;
	text-align: center;
}
span.float {
	margin-top: 1ex;
	margin-bottom: 1ex;
	text-align: center;
}
div.figure {
	display: inline-block;
	text-align: left;
	padding: 1ex;
	margin-left: auto;
	margin-right: auto;
	border: thin solid #c0c0c0;
}
div.table {
	display: inline-block;
	text-align: left;
	padding: 1ex;
	margin-left: auto;
	margin-right: auto;
	border: thin solid #c0c0c0;
}
div.algorithm {
	display: inline-block;
	text-align: left;
	padding: 1ex;
	margin-left: auto;
	margin-right: auto;
	border: thin solid #c0c0c0;
}
div.caption {
	text-align: center;
	font-family: sans-serif;
	margin-left: auto;
	margin-right: auto;
	padding: 0.5ex;
}
img.figure {
	width: 100%;
	_width: auto;
}
div.multifigure {
	padding: 1ex;
	width: 100%;
}
div.multitable {
	display: inline-block;
	padding: 1ex;
	margin-left: auto;
	margin-right: auto;
	border: thin solid #c0c0c0;
}
div.multialgorithm {
	display: inline-block;
	padding: 1ex;
	margin-left: auto;
	margin-right: auto;
	border: thin solid #c0c0c0;
}
div.wrap-l, div.wrap-o, div.wrap-i {
	margin: 2ex;
	float: left;
}
div.wrap-r {
	margin: 2ex;
	float: right;
}
div.listing {
	display: inline-block;
	text-align: left;
	margin-left: auto;
	margin-right: auto;
	padding: 0.5ex;
	border: thin solid #c0c0c0;
}
span.number-left {
	float: left;
	background: #f0f0f0;
	width: 3em;
	text-align: right;
	margin-right: 1em;
}
span.number-right {
	float: right;
	background: #f0f0f0;
	width: 3em;
	text-align: right;
	margin-left: 1em;
}

/* Header */
h1.title {
	text-align: center;
}
h2.author {
	text-align: center;
}
h2.Date {
	text-align: center;
}
div.abstract {
	margin: 1em 3em;
	text-align: left;
	font-size: 0.95em;
}
p.abstract-message {
	text-align: center;
	font-weight: bold;
}
div.tocheader {
	margin: 1em 0;
	font-size: large;
}
a.toc {
	color: black;
}
div.tocindent {
	padding: 0 0 0 2em;
}
div.toc {
	margin: 0.5em 0;
	font-size: 0.95em;
}
div.fulltoc {
	padding: 1em;
}
div.warning {
	font-size: 120%;
	color:#cc0000;
}
div.Institute {
	text-align: center;
}
/*
* Extras: colors, footnotes, boxes, spaces...
*/

/* Raw colors */
span.red {
	color: #c00000;
}
span.blue {
	color: #0000c0;
}
span.green {
	color: #00c000;
}
span.magenta {
	color: #c000c0;
}
span.cyan {
	color: #00c0c0;
}
span.yellow {
	color: #c0c000;
}
span.white {
	color: #ffffff;
}

/* Footnotes */
span.SupFootMarker {
	color: #0030c0;
	font-size: 0.75em;
	line-height: 0.5em;
	vertical-align: text-top;
}
span.AlignFootMarker {
	color: #0030c0;
}
div.EndFoot {
	margin: 0.2ex;
	background: #ffffff;
	padding: 0.5ex;
	font-size: small;
	font-weight: normal;
	line-height: 1.5em;
	text-align: left;
}
span.MarginFoot {
	float: right;
	clear: right;
	margin: 0.2ex;
	border: thin solid #c0c0c0;
	background: #ffffff;
	width: 30%;
	padding: 0.5ex;
	font-size: small;
	font-weight: normal;
	line-height: 1.5em;
	text-align: left;
}
span.HoverFoot {
	margin: 0.2ex;
	border: thin solid #c0c0c0;
	background: #ffffff;
	padding: 0.5ex;
	font-size: small;
	font-weight: normal;
	line-height: 1.5em;
	text-align: left;
}
span.FootOuter .HoverFoot {
	display: none;
	position: absolute;
}
span.FootOuter:hover .HoverFoot {
	display: inline;
	float: none;
}
span.Marginal {
	float: right;
	clear: right;
	margin: 0.2ex;
	border: thin solid #c0c0c0;
	background: #ffffff;
	width: 30%;
	padding: 0.5ex;
	font-size: small;
	font-weight: normal;
	line-height: 1.5em;
	text-align: left;
}
span.Note {
	display: none;
}

/* Boxes */
div.framed {
	outline-style: solid;
}
div.frameless {
}
div.Frameless {
}
div.Boxed {
	outline-width: thin;
	outline-style: solid;
}
div.Framed {
	outline-width: thin;
	outline-style: solid;
	line-height: 200%;
}
div.Doublebox {
	outline-style: double;
}
div.Shadowbox {
	outline-style: outset;
}
div.Shaded {
	outline-style: inset;
}
div.ovalbox {
	outline-style: groove;
}
div.Ovalbox {
	outline-style: ridge;
}
hr.line {
	display: inline-block;
}

/* Spaces */
span.hspace {
	display: inline-block;
}
span.vspace {
	display: inline-block;
	vertical-align: text-top;
}
span.hfill {
	display: inline-block;
	margin-left: auto;
	margin-right: auto;
	min-width: 20mm;
	background: #fff0f0;
}
div.defskip {
	display: block;
	height: 1em;
}
div.smallskip {
	display: block;
	height: 0.5em;
}
div.medskip {
	display: block;
	height: 1em;
}
div.bigskip {
	display: block;
	height: 2em;
}
div.vfill {
	display: block;
	height: 30em;
}

/* Sizes */
span.scriptstyle {
	font-size: 0.75em;
}
span.scriptscriptstyle {
	font-size: 0.60em;
}

/* Chunks */
div.chunk {
	width: auto;
}
span.chunkleft span.chunkright {
	font-style: normal;
}
span.chunkdecl {
	font-style: italic;
	padding: 0em 2em;
}
span.chunkref {
	font-style: italic;
}

/* Split Part Navigation */
div.splitheader {
	margin: 0em;
	padding: 0.1em;
	text-align: center;
	background: #f9f9f9;
	overflow: auto;
}
span.next {
	float: right;
	width: 30%;
	text-align: right;
}
span.up {
	display: inline-block;
	width: 30%;
	text-align: center;
}
span.prev {
	float: left;
	width: 30%;
	text-align: left;
}
hr.footer {
	margin-top: 2em;
}
div.footer {
	font-size: 0.90em;
	margin: 1em 0;
}

/* Change Tracking */
span.inserted {
	color: #0000ff;
}
span.deleted {
	color: #ff0000;
	text-decoration: line-through;
}

/* Google Charts */
img.chart {
	vertical-align: middle;
}
/* --end--
* CSS file for LaTeX formulas.
*/

/* Formulas */
.formula {
	text-align: center;
	font-family: "DejaVu Serif", serif;
	margin: 1.2em 0;
}
span.formula {
	white-space: nowrap;
}
div.formula {
	padding: 0.5ex;
	margin-left: auto;
	margin-right: auto;
}

/* Basic features */
a.eqnumber {
	display: inline-block;
	float: right;
	clear: right;
	font-weight: bold;
}
span.unknown {
	color: #800000;
}
span.ignored, span.arraydef {
	display: none;
}
.formula i {
	letter-spacing: 0.1ex;
}

/* Alignment */
.align-left, .align-l {
	text-align: left;
}
.align-right, .align-r {
	text-align: right;
}
.align-center, .align-c {
	text-align: center;
}

/* Structures */
span.overline, span.bar {
	text-decoration: overline;
}
.fraction, .fullfraction {
	display: inline-block;
	vertical-align: middle;
	text-align: center;
}
.fraction .fraction {
	font-size: 80%;
	line-height: 100%;
}
span.numerator {
	display: block;
}
span.denominator {
	display: block;
	padding: 0ex;
	border-top: thin solid;
}
sup.numerator, sup.unit {
	font-size: 70%;
	vertical-align: 80%;
}
sub.denominator, sub.unit {
	font-size: 70%;
	vertical-align: -20%;
}
span.sqrt {
	display: inline-block;
	vertical-align: middle;
	padding: 0.1ex;
}
sup.root {
	font-size: 70%;
	position: relative;
	left: 1.4ex;
}
span.radical {
	display: inline-block;
	padding: 0ex;
	font-size: 150%;
	vertical-align: top;
}
span.root {
	display: inline-block;
	border-top: thin solid;
	padding: 0ex;
	vertical-align: middle;
}
span.symbol {
	font-size: 125%;
}
span.bigsymbol {
	font-size: 150%;
}
span.largesymbol {
	font-size: 175%;
}
span.hugesymbol {
	font-size: 200%;
}
span.scripts {
	display: inline-table;
	vertical-align: middle;
}
.script {
	display: table-row;
	text-align: left;
	line-height: 150%;
}
span.limits {
	display: inline-table;
	vertical-align: middle;
}
.limit {
	display: table-row;
	line-height: 95%;
}
sup.limit, sub.limit {
	line-height: 150%;
}
span.symbolover {
	display: inline-block;
	text-align: center;
	position: relative;
	float: right;
	right: 100%;
	bottom: 0.5em;
	width: 0px;
}
span.withsymbol {
	display: inline-block;
}
span.symbolunder {
	display: inline-block;
	text-align: center;
	position: relative;
	float: right;
	right: 80%;
	top: 0.3em;
	width: 0px;
}

/* Environments */
span.array, span.bracketcases, span.binomial, span.environment {
	display: inline-table;
	text-align: center;
	border-collapse: collapse;
	margin: 0em;
	vertical-align: middle;
}
span.arrayrow, span.binomrow {
	display: table-row;
	padding: 0ex;
	border: 0ex;
}
span.arraycell, span.bracket, span.case, span.binomcell, span.environmentcell {
	display: table-cell;
	padding: 0ex 0.2ex;
	line-height: 99%;
	border: 0ex;
}
/*
* CSS file for LaTeX formulas, extra stuff:
* binomials, vertical braces, stackrel, fonts and colors.
*/

/* Inline binomials */
span.binom {
	display: inline-block;
	vertical-align: middle;
	text-align: center;
	font-size: 80%;
}
span.binomstack {
	display: block;
	padding: 0em;
}

/* Over- and underbraces */
span.overbrace {
	border-top: 2pt solid;
}
span.underbrace {
	border-bottom: 2pt solid;
}

/* Stackrel */
span.stackrel {
	display: inline-block;
	text-align: center;
}
span.upstackrel {
	display: block;
	padding: 0em;
	font-size: 80%;
	line-height: 64%;
	position: relative;
	top: 0.15em;

}
span.downstackrel {
	display: block;
	vertical-align: bottom;
	padding: 0em;
}

/* Fonts */
span.mathsf, span.textsf {
	font-style: normal;
	font-family: sans-serif;
}
span.mathrm, span.textrm {
	font-style: normal;
	font-family: serif;
}
span.text, span.textnormal {
	font-style: normal;
}
span.textipa {
	color: #008080;
}
span.fraktur {
	font-family: "Lucida Blackletter", eufm10, blackletter;
}
span.blackboard {
	font-family: Blackboard, msbm10, serif;
}
span.scriptfont {
	font-family: "Monotype Corsiva", "Apple Chancery", "URW Chancery L", cursive;
	font-style: italic;
}

/* Colors */
span.colorbox {
	display: inline-block;
	padding: 5px;
}
span.fbox {
	display: inline-block;
	border: thin solid black;
	padding: 2px;
}
span.boxed, span.framebox {
	display: inline-block;
	border: thin solid black;
	padding: 5px;
}

/*
* Obsolete definitions, kept for backwards compatibility.
*/

/* Footnotes */
span.FootMarker {
	color: #0030c0;
	font-size: 0.75em;
	line-height: 0.5em;
	vertical-align: text-top;
}
span.Foot {
	margin: 0.2ex;
	border: thin solid #c0c0c0;
	background: #ffffff;
	padding: 0.5ex;
	font-size: small;
	font-weight: normal;
	line-height: 1.5em;
	text-align: left;
}
span.FootOuter .Foot {
	display: none;
	position: absolute;
}
span.FootOuter:hover .Foot {
	display: inline;
	float: none;
}

/* Dotted box */
span.dotted {
	border-top: thin dotted;
}

/* Obsolete aligned structures */
span.numerator-l {
	display: block;
	text-align: left;
}
span.numerator-r {
	display: block;
	text-align: right;
}
span.numeratorl {
	display: block;
	text-align: left;
}
span.numeratorr {
	display: block;
	text-align: right;
}
span.framebox- {
	display: inline-block;
	border: thin solid black;
	text-align: center;
	padding: 5px;
}
span.framebox-l {
	display: inline-block;
	border: thin solid black;
	text-align: left;
	padding: 5px;
}
span.framebox-r {
	display: inline-block;
	border: thin solid black;
	text-align: right;
	padding: 5px;
}
td.formula-l {
	text-align: left;
	padding: 0.2ex;
	border: 0ex;
}
td.formula-c {
	text-align: center;
	padding: 0.2ex;
	border: 0ex;
}
td.formula-r {
	text-align: right;
	padding: 0.2ex;
	border: 0ex;
}

/* Obsolete limits */
sub.bigsymbol {
	display: table-row;
	text-align: left;
	line-height: 150%;
}
sup.bigsymbol {
	display: table-row;
	text-align: left;
	line-height: 150%;
}

/* Obsolete cases */
table.cases {
	display: inline-block;
	text-align: center;
	border-collapse: collapse;
	margin: 0.2em;
	border-left: thin solid;
	vertical-align: middle;
}
table.cases tr td {
	padding-left: 1ex;
	padding-right: 1em;
}

/* Obsolete binomials */
span.fullbinom {
	display: inline-block;
	vertical-align: middle;
	text-align: center;
}
span.upbinom {
	display: block;
	padding: 0em;
}
span.downbinom {
	display: block;
	padding: 0em;
}

/* Obsolete environments */
table.formula {
	display: inline-block;
	text-align: center;
	border-collapse: collapse;
	margin: 0em;
	vertical-align: middle;
}
td.formula {
	padding: 0.2ex;
	border: 0ex;
}
table.environment {
	display: inline-block;
	text-align: right;
	margin: 0;
	vertical-align: middle;
}
table.environment tr td {
	padding: 0 1em;
}
/*
* CSS section for print.
*/
@media print {
body {
	font: 90% serif;
	background: #ffffff;
	color: black;
	margin: 0;
	padding: 0;
}
#globalWrapper {
	width: 100%;
	margin: 0px;
	padding: 0px;
	background: #ffffff;
	line-height: 1.5em;
}
span.FootOuter .Foot {
	display: block;
	position: relative;
	float: right;
	clear: right;
	margin: 0.2ex;
	border: thin solid #c0c0c0;
	background: #ffffff;
	width: 30%;
	padding: 0.5ex;
	font-size: small;
	font-weight: normal;
	line-height: 1.5em;
	text-align: left;
}
span.FootOuter .HoverFoot {
	display: block;
	position: relative;
	float: right;
	clear: right;
	margin: 0.2ex;
	border: thin solid #c0c0c0;
	background: #ffffff;
	width: 30%;
	padding: 0.5ex;
	font-size: small;
	font-weight: normal;
	line-height: 1.5em;
	text-align: left;
}
a:visited {
	color: #0030c0;
}
/* end of print CSS */
}
elyxer-1.2.5/forks/jras-elyxer/docs/pipeline.svg0000644000175000017500000002656712117061342021221 0ustar  chennochenno


  
    
      
    
    
      
    
    
      
    
    
      
    
    
  
  
  
    
      
        image/svg+xml
        
      
    
  
  
    
    
      
      elyxer
    
    
      
      LyX file
    
    
      
      singleHTML file
    
    
      
      
      
      multipleHTML files
    
    
    
      
      elyxer --splitpart
    
    
    
  

elyxer-1.2.5/forks/jras-elyxer/docs/math.lyx0000644000175000017500000005212112117061342020343 0ustar  chennochenno#LyX 1.6.7 created this file. For more info see http://www.lyx.org/
\lyxformat 345
\begin_document
\begin_header
\textclass article
\begin_preamble
%   eLyXer -- convert LyX source files to HTML output.
%
%   Copyright (C) 2009-2011 Alex Fernández
%
%   This program is free software: 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 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
%   GNU General Public License for more details.
%
%   You should have received a copy of the GNU General Public License
%   along with this program.  If not, see .

% DO NOT ALTER THIS PREAMBLE!!!
%
% This preamble is designed to ensure that the User's Guide prints
% out as advertised. If you mess with this preamble,
% parts of the User's Guide may not print out as expected.  If you
% have problems LaTeXing this file, please contact 
% the documentation team
% email: lyx-docs@lists.lyx.org

\usepackage{ifpdf} % part of the hyperref bundle
\ifpdf % if pdflatex is used

 % set fonts for nicer pdf view
 \IfFileExists{lmodern.sty}{\usepackage{lmodern}}{}

\fi % end if pdflatex is used

% for correct jump positions whe clicking on a link to a float
\usepackage[figure]{hypcap}


% redefine the \LyX macro for PDF bookmarks
\def\LyX{\texorpdfstring{%
  L\kern-.1667em\lower.25em\hbox{Y}\kern-.125emX\@}
  {LyX}}


% test macro with two arguments
\newcommand{\preambleroot}[2]{\sqrt[#1]{#2}}

% redefine the greyed out note

\usepackage{mathrsfs}
\usepackage{eurosym}
\end_preamble
\options intoc,bibtotoc,idxtotoc,BCOR7mm,tablecaptionabove
\use_default_options false
\language english
\inputencoding utf8
\font_roman default
\font_sans default
\font_typewriter default
\font_default_family default
\font_sc false
\font_osf false
\font_sf_scale 100
\font_tt_scale 100

\graphics default
\paperfontsize 12
\spacing single
\use_hyperref true
\pdf_title "eLyXer Math Showcase"
\pdf_author "Alex Fernández"
\pdf_subject "The amazing all-time-wonder eLyXer Math Showcase"
\pdf_keywords "LyX"
\pdf_bookmarks true
\pdf_bookmarksnumbered false
\pdf_bookmarksopen false
\pdf_bookmarksopenlevel 1
\pdf_breaklinks false
\pdf_pdfborder false
\pdf_colorlinks false
\pdf_backref false
\pdf_pdfusetitle true
\papersize default
\use_geometry false
\use_amsmath 1
\use_esint 0
\cite_engine basic
\use_bibtopic false
\paperorientation portrait
\branch Pregunta
\selected 1
\color #00ff00
\end_branch
\branch Respuesta
\selected 0
\color #aa55ff
\end_branch
\secnumdepth 3
\tocdepth 3
\paragraph_separation indent
\defskip medskip
\quotes_language english
\papercolumns 1
\papersides 2
\paperpagestyle default
\tracking_changes false
\output_changes false
\author "" 
\author "" 
\end_header

\begin_body

\begin_layout Title
\begin_inset Graphics
	filename elyxer.svg
	lyxscale 50

\end_inset

eLyXer Math Showcase
\end_layout

\begin_layout Author
Alex Fernández (elyxer@gmail.com)
\end_layout

\begin_layout Standard
\begin_inset CommandInset toc
LatexCommand tableofcontents

\end_inset


\end_layout

\begin_layout Section
Introduction
\end_layout

\begin_layout Standard
This document is intended as a showcase of the mathematical abilities of
 eLyXer; for more information be sure to visit the 
\begin_inset CommandInset href
LatexCommand href
name "main page"
target "index.html"

\end_inset

.
\end_layout

\begin_layout Subsection
Versions
\end_layout

\begin_layout Standard
There are several versions of this page:
\end_layout

\begin_layout Itemize
A 
\begin_inset CommandInset href
LatexCommand href
name "non-Unicode version"
target "math.html"

\end_inset

 of this page with midspaces.
\end_layout

\begin_layout Itemize
A 
\begin_inset CommandInset href
LatexCommand href
name "Unicode version"
target "math-unicode.html"

\end_inset

 with mathematical spaces (generated with 
\family typewriter
--unicode
\family default
).
\end_layout

\begin_layout Itemize
An 
\begin_inset CommandInset href
LatexCommand href
name "ISO-8859-15 version"
target "math-iso885915.html"

\end_inset

 (generated with 
\family typewriter
--iso885915
\family default
).
\end_layout

\begin_layout Itemize
An 
\begin_inset CommandInset href
LatexCommand href
name "HTML version"
target "math-html.html"

\end_inset

 (generated with 
\family typewriter
--html
\family default
).
\end_layout

\begin_layout Itemize
A 
\begin_inset CommandInset href
LatexCommand href
name "MathJax remote version"
target "math-mathjax.html"

\end_inset

 with 
\begin_inset CommandInset href
LatexCommand href
name "MathJax"
target "http://www.mathjax.org/"

\end_inset

 (generated with 
\family typewriter
--mathjax remote
\family default
).
\end_layout

\begin_layout Itemize
A 
\begin_inset CommandInset href
LatexCommand href
name "MathJax local version"
target "math-mathjax-local.html"

\end_inset

 with 
\begin_inset CommandInset href
LatexCommand href
name "MathJax"
target "http://www.mathjax.org/"

\end_inset

 (generated with 
\family typewriter
--mathjax
\family default
 and a local URL).
\end_layout

\begin_layout Itemize
A 
\begin_inset CommandInset href
LatexCommand href
name "Google Charts version"
target "math-googlecharts.html"

\end_inset

 with 
\begin_inset CommandInset href
LatexCommand href
name "Google Charts"
target "http://code.google.com/apis/chart/index.html"

\end_inset

 (generated with 
\family typewriter
--googlecharts
\family default
).
\end_layout

\begin_layout Standard
All of them are generated from the same 
\family typewriter
.lyx
\family default
 source file; they should help you decide which rendering options suit you
 best.
\end_layout

\begin_layout Standard
Also available online is the eLyXer translation of the latest 
\begin_inset CommandInset href
LatexCommand href
name "LyX’s detailed Math manual"
target "http://elyxer.nongnu.org/lyx/Math.html"

\end_inset

, which contains a lot more examples of LyX maths.
\end_layout

\begin_layout Section
Typography
\end_layout

\begin_layout Standard
Math formulae use a lot of different symbols and fonts.
\end_layout

\begin_layout Subsection
Greek Symbols
\end_layout

\begin_layout Standard
Greek symbols are very important in equations: 
\begin_inset Formula $\phi$
\end_inset

, 
\begin_inset Formula $\pi$
\end_inset

, 
\begin_inset Formula $\Xi$
\end_inset

.
 eLyXer offers a complete set in both upper case: 
\begin_inset Formula $\Gamma\ldots\Omega$
\end_inset

 and lower case: 
\begin_inset Formula $\alpha\ldots\omega$
\end_inset

.
 Also the AMS italicized upper case: 
\begin_inset Formula $\varGamma\ldots\varOmega$
\end_inset

.
\end_layout

\begin_layout Subsection
Math Symbols
\end_layout

\begin_layout Standard
eLyXer supports the whole set of math symbols in 
\begin_inset CommandInset href
LatexCommand href
name "John D. Cook's list"
target "http://www.johndcook.com/math_symbols.html"

\end_inset

: 
\begin_inset Formula $\exists\partial\nabla\geq$
\end_inset

.
 It can also render a few more: 
\begin_inset Formula $\propto\times$
\end_inset

.
\begin_inset Note Note
status collapsed

\begin_layout Plain Layout
The 
\backslash
propto symbol is rendered as 
\begin_inset Formula $\mu$
\end_inset

 in the LyX 1.6.8 window.
 LyX bug?
\end_layout

\end_inset

 You also get all symbols from 
\begin_inset CommandInset href
LatexCommand href
name "Markus Kuhn's list"
target "http://www.cl.cam.ac.uk/~mgk25/ucs/examples/TeX.txt"

\end_inset

: 
\begin_inset Formula $\bigodot\amalg$
\end_inset

.
\end_layout

\begin_layout Subsection
Other Symbols
\end_layout

\begin_layout Standard
There are other symbols like arrows: 
\begin_inset Formula $\leftarrow\rightarrow$
\end_inset

, or geometrical shapes: 
\begin_inset Formula $\circ$
\end_inset

, 
\begin_inset Formula $\square$
\end_inset

.
 eLyXer offers limited support for them.
 You might also want to use financial symbols in formulae: 
\begin_inset Formula $\yen\euro\$$
\end_inset

.
\end_layout

\begin_layout Subsection
Spacing
\end_layout

\begin_layout Standard
Equations look good when items are properly separated.
 The main separation is the Medium Mathematical Space: 
\begin_inset Formula $x=3$
\end_inset

.
 
\begin_inset Note Greyedout
status open

\begin_layout Plain Layout
Note: if you are viewing the non-Unicode version 
\begin_inset Flex URL
status collapsed

\begin_layout Plain Layout

math.html
\end_layout

\end_inset

 of this page then you are in fact seeing midspaces, which are very similar
 but not exactly the same: 
\begin_inset Formula $\frac{4}{18}\mathrm{em}$
\end_inset

 for medium mathematical spaces versus 
\begin_inset Formula $\frac{1}{2}\mathrm{en}$
\end_inset

, where 
\begin_inset Formula $1\mathrm{em}=2\mathrm{en}$
\end_inset

.
 Try out the Unicode version 
\begin_inset Flex URL
status collapsed

\begin_layout Plain Layout

math-unicode.html
\end_layout

\end_inset

 -- and viceversa.
 You can check out what version this page is in the page title.
\end_layout

\end_inset


\end_layout

\begin_layout Standard
The command 
\family typewriter

\backslash
raisebox
\family default
 is useful to, surprisingly, raise a little box, 
\begin_inset Formula \[
\raisebox{2mm}{raised}over\raisebox{-2mm}{lowered}\textrm{and back}.\]

\end_inset

Like 
\family typewriter

\backslash
mbox
\family default
, it puts its content in a text box.
 It can also be used just for spacing:
\begin_inset Newline newline
\end_inset

 
\begin_inset Formula $\raisebox{5mm}{}B^{V}$
\end_inset

.
\end_layout

\begin_layout Standard
There are other spacing commands: 
\family typewriter

\backslash
hspace
\family default
: 
\begin_inset Formula $a\hspace{4mm}b$
\end_inset

, protected space: 
\begin_inset Formula $a\ b$
\end_inset

, and (at 
\begin_inset Quotes eld
\end_inset

block level
\begin_inset Quotes erd
\end_inset

)
\family typewriter
 
\backslash
vspace
\family default
: 
\begin_inset Formula $a\vspace{1cm}b$
\end_inset

.
\end_layout

\begin_layout Standard
There should be 1
\begin_inset space ~
\end_inset

cm of vertical space above this paragraph.
\end_layout

\begin_layout Subsection
Fonts
\end_layout

\begin_layout Standard
By default, letters denote variables and are taken from the 
\family typewriter

\backslash
mathnormal
\family default
 font, which is italic, 
\begin_inset Formula $\alpha x+\alpha y=\alpha(x+y)$
\end_inset

, with the exception of upright capital Greek letters, 
\begin_inset Formula $G\ne\Gamma$
\end_inset

.
\end_layout

\begin_layout Standard
Function names should be upright: 
\begin_inset Formula $\sin(2\pi),\log(x),\tan\delta$
\end_inset

.
\end_layout

\begin_layout Standard
Mathematical fonts used in equations include 
\begin_inset Formula $\mathrm{Roman}$
\end_inset

 (
\family typewriter

\backslash
mathrm
\family default
), 
\begin_inset Formula $\mathsf{Sans\: Serif}$
\end_inset

 (
\family typewriter

\backslash
mathsf
\family default
), 
\begin_inset Formula $\mathtt{Typewriter}$
\end_inset

 (
\family typewriter

\backslash
mathtt
\family default
), 
\begin_inset Formula $\mathbf{Bold}$
\end_inset

 (
\family typewriter

\backslash
mathbf
\family default
), 
\begin_inset Formula $\mathscr{SCRIPT}$
\end_inset

 (
\family typewriter

\backslash
mathscr
\family default
), 
\begin_inset Formula $\mathcal{CALLIGRAPHIC}$
\end_inset

 (
\family typewriter

\backslash
mathcal
\family default
), 
\begin_inset Formula $\mathbb{BLACKBOARD\: BOLD}$
\end_inset

 (
\family typewriter
\noun on

\backslash

\noun default
mathbb
\family default
), and 
\begin_inset Formula $\mathfrak{Fraktur}$
\end_inset

 (
\family typewriter

\backslash
mathfrak
\family default
).
 For the latter, some single characters are translated to their Unicode
 equivalents: 
\begin_inset Formula $\mathscr{F}$
\end_inset

, 
\begin_inset Formula $\mathbb{F}$
\end_inset

, 
\begin_inset Formula $\mathfrak{F}$
\end_inset

.
\end_layout

\begin_layout Standard
Regular text in a formula can be achieved via text font commands like 
\family typewriter

\backslash
textrm
\family default
: 
\begin_inset Formula $5\:\textrm{to}\:10$
\end_inset

, via boxes like 
\backslash
mbox (prevents line breaks): 
\begin_inset Formula $6\mbox{ is more than }5$
\end_inset

, or the AMSmath 
\family typewriter

\backslash
text
\family default
 macro (scales like math symbols) 
\begin_inset Formula $\text{base}_{\text{sub}}^{\text{super}}$
\end_inset

.
 The content of an mbox is processed in LaTeX text mode.
 This allows text font commands, e.g.
 a switch to 
\family sans
\series bold
\shape italic
sans-serif-bold-italic
\family default
\series default
\shape default
, or the phonetic alphabet: 
\begin_inset Formula $\mbox{\textbf{\textsf{\textbf{\textit{sfbfit}}}}, \textipa{tipa}}$
\end_inset

.
\end_layout

\begin_layout Standard
Units should be written upright, either with 
\family typewriter

\backslash
mathrm
\family default
 or with macros from the 
\family typewriter
units
\family default
 package, e.g.
 as simple unit, 
\begin_inset Formula $\unit{km}$
\end_inset

, with magnitude, 
\begin_inset Formula $\unit[57]{km}$
\end_inset

, with fractional unit, 
\begin_inset Formula $\unitfrac[200]{km}{h}$
\end_inset

, or with a fraction before the units, 
\begin_inset Formula $\unit[\nicefrac{3}{2}]{km}$
\end_inset

, 
\begin_inset Formula $\unit[\frac{7}{16}]{s}$
\end_inset

.
\end_layout

\begin_layout Section
Numeration
\end_layout

\begin_layout Standard
Equations can be numbered, like (
\begin_inset CommandInset ref
LatexCommand ref
reference "eq:first"

\end_inset

) 
\begin_inset Formula \begin{equation}
y=x\label{eq:first}\end{equation}

\end_inset

 And also like 
\begin_inset CommandInset ref
LatexCommand eqref
reference "eq:second"

\end_inset

.
 
\begin_inset Formula \begin{equation}
x=3\label{eq:second}\end{equation}

\end_inset

 Some equations can be numbered even if they don't have a label.
\end_layout

\begin_layout Standard
\begin_inset Formula \begin{equation}
x=2y\end{equation}

\end_inset

 Notice that equation (
\begin_inset CommandInset ref
LatexCommand ref
reference "eq:second"

\end_inset

) comes after (
\begin_inset CommandInset ref
LatexCommand ref
reference "eq:first"

\end_inset

).
\end_layout

\begin_layout Section
Simple Structures
\end_layout

\begin_layout Standard
Let's now see a few of the simpler structures that eLyXer can output.
\end_layout

\begin_layout Subsection
Fractions
\end_layout

\begin_layout Standard
A simple fraction: 
\begin_inset Formula \[
\frac{1}{2}.\]

\end_inset

Inlined: 
\begin_inset Formula $\frac{2}{3}.$
\end_inset


\end_layout

\begin_layout Standard
A big recursive fraction: 
\begin_inset Formula \[
\frac{1}{\left(1+\left(\frac{1}{1+\left(\frac{1}{1+2x}\lyxlock\right)}\lyxlock\right)\right)}\lyxlock\]

\end_inset


\end_layout

\begin_layout Standard
A nice fraction: 
\begin_inset Formula $\nicefrac{5}{6}$
\end_inset

.
 A non-diminishing fraction containing alignments:
\begin_inset Formula \[
\cfrac{1}{1+\left(\cfrac[l]{1}{1+x}\times\cfrac[r]{1}{1+x}\right)}.\]

\end_inset


\end_layout

\begin_layout Standard
A similar concept is a binomial coefficient: 
\begin_inset Formula $\binom{A+1}{B}.$
\end_inset

 It can be prettily presented: 
\begin_inset Formula \[
\dbinom{A}{B+1}.\]

\end_inset


\end_layout

\begin_layout Standard
A symbol can be stacked over another using 
\family typewriter

\backslash
stackrel
\family default
: 
\begin_inset Formula $x\stackrel{R}{\rightarrow}y$
\end_inset

.
 Anything can be stacked: 
\begin_inset Formula \[
d\stackrel{x>3}{\lim}x,\quad\stackrel{\mathrm{head}}{\mathrm{heels}}.\]

\end_inset


\end_layout

\begin_layout Subsection
Limits
\end_layout

\begin_layout Standard
\begin_inset Formula $\lim_{x\rightarrow\infty}f(x)$
\end_inset

 should appear as 
\begin_inset Formula $x\rightarrow\infty$
\end_inset

 in italics, and 
\begin_inset Quotes fld
\end_inset

lim
\begin_inset Quotes frd
\end_inset

 in plain style.
 In display mode, a limit must appear below the main symbol: 
\begin_inset Formula \[
\lim_{x\rightarrow\infty}\lyxlock f(x).\]

\end_inset


\end_layout

\begin_layout Standard
Limits are also used in sums and integrals: 
\begin_inset Formula \[
\sum_{i=1}^{\infty}x,\;\int_{0}^{\infty}f(x)\,\mathrm{d}x\]

\end_inset

where the sum's limits should appear below (
\begin_inset Formula $i=1$
\end_inset

) and above (
\begin_inset Formula $\infty$
\end_inset

) the 
\begin_inset Formula $\sum$
\end_inset

.
 The placement of the integral limits depends on the document class: LaTeX
 standard classes place them right to the 
\begin_inset Formula $\int$
\end_inset

.
 Limits are shown to the right in inline formulae: 
\begin_inset Formula $\sum_{i=1}^{\infty}x$
\end_inset

 and 
\begin_inset Formula $\intop_{i=1}^{\infty}x.$
\end_inset


\end_layout

\begin_layout Standard
The placing of limits can be configured with the 
\family typewriter

\backslash
limits
\family default
 and 
\family typewriter

\backslash
nolimits
\family default
 macros: 
\begin_inset Formula \[
\lim\nolimits _{x\rightarrow\infty}\lyxlock f(x),\;\sum\nolimits _{i=1}^{\infty}x,\;\int\limits _{0}^{\infty}f(x)\,\mathrm{d}x\]

\end_inset


\end_layout

\begin_layout Subsection
Roots
\end_layout

\begin_layout Standard
A square root: 
\begin_inset Formula $\sqrt{3}.$
\end_inset

 A more complex root in a fraction:
\begin_inset Formula \[
\frac{1}{\left(1+\sqrt{2}\left(\frac{1}{1+\sqrt{2}}\lyxlock\right)+\sqrt{\frac{1}{2}}\right)}\lyxlock.\]

\end_inset


\end_layout

\begin_layout Standard
eLyXer can also do higher-order roots: 
\begin_inset Formula $\sqrt[3]{x+y}$
\end_inset

.
 A devilish case mixing everything we have seen so far:
\begin_inset Formula \[
\frac{\sqrt[\nicefrac{7}{8}]{\frac{8}{4}x}+\sum_{i=1}^{\infty}x}{\sqrt[s+5]{\frac{(78x+45y)\times\sqrt{\Omega}}{\sin(x+1)}+\unit[38]{km}}}\lyxlock.\]

\end_inset


\end_layout

\begin_layout Section
Complex Structures
\end_layout

\begin_layout Standard
In this section we will explore arrays and related constructs.
\end_layout

\begin_layout Subsection
Arrays
\end_layout

\begin_layout Standard
An inline array 
\begin_inset Formula $\left[\begin{array}{cc}
a & b\\
c & d\end{array}\right]$
\end_inset

 is always shown in the same line.
 In display mode, the array is shown on its own line: 
\begin_inset Formula \[
\left[\begin{array}{lc}
12 & 2\\
3 & 4\times y^{x}\end{array}\right]\]

\end_inset

Apart from that the appearance should be the same.
\end_layout

\begin_layout Subsection
Brackets
\end_layout

\begin_layout Standard
Arrays are separated by variable-size brackets: 
\begin_inset Formula $\left(\begin{array}{cc}
a & b\\
c & d\end{array}\right)$
\end_inset

 
\begin_inset Formula $\left[\begin{array}{cc}
a & b\\
c & d\end{array}\right]$
\end_inset

 
\begin_inset Formula $\left\{ \begin{array}{cc}
a & b\\
c & d\end{array}\right\} $
\end_inset

 
\begin_inset Formula $\left\langle \begin{array}{cc}
a & b\\
c & d\end{array}\right\rangle $
\end_inset

 
\begin_inset Formula $\left|\begin{array}{cc}
a & b\\
c & d\end{array}\right|$
\end_inset

which might also differ on right and left 
\begin_inset Formula $\left(\begin{array}{cc}
a & b\\
c & d\end{array}\right)$
\end_inset

 or use the empty opening 
\begin_inset Formula $\left\{ \begin{array}{cc}
a & b\\
c & d\end{array}\right.$
\end_inset

 or closing: 
\begin_inset Formula $\left.\begin{array}{cc}
a & b\\
c & d\end{array}\right|$
\end_inset

.
 There are also fixed-size big brackets, e.g.
 
\begin_inset Formula $\bigl\langle f\bigr\rangle$
\end_inset

.
\end_layout

\begin_layout Subsection
Cases
\end_layout

\begin_layout Standard
Used to switch between several values.
\end_layout

\begin_layout Standard
\begin_inset Formula \[
y=\begin{cases}
x & i=0,\\
x+1 & i<3\end{cases}\]

\end_inset


\end_layout

\begin_layout Standard
Cases may have more than two rows:
\end_layout

\begin_layout Standard
\begin_inset Formula \[
f(x)=\begin{cases}
0 & x<0,\\
\infty & x=0\\
0 & x>0\end{cases}\]

\end_inset


\end_layout

\begin_layout Subsection
Braces
\end_layout

\begin_layout Standard
Values can be underbraced or overbraced.
\end_layout

\begin_layout Standard
\begin_inset Formula $\underbrace{a-b}=\overbrace{b+c+d+e}$
\end_inset

.
\end_layout

\begin_layout Section
Macros
\end_layout

\begin_layout Standard
Now it's time for user-defined commands (sometimes called 
\begin_inset Quotes eld
\end_inset

macros
\begin_inset Quotes erd
\end_inset

).
\end_layout

\begin_layout Standard
Definitions can be added as macros
\begin_inset FormulaMacro
\newcommand{\stupidroot}[2]{\sqrt[#1]{#2}}
{\sqrt[#1]{#2}}
\end_inset

.
 Then they can be used in formulae: 
\begin_inset Formula $\stupidroot 12$
\end_inset

.
 They can accept default parameters
\begin_inset FormulaMacro
\newcommand{\defaultroot}[2][4][5]{\sqrt[#1]{#2}}
{#1\sqrt{#2}}
\end_inset

.
 Again, useful in formulae: 
\begin_inset Formula $\defaultroot$
\end_inset

.
\end_layout

\begin_layout Standard
Other definitions from the preamble can be used: 
\begin_inset Formula $\preambleroot{3}{4}$
\end_inset

.
\end_layout

\begin_layout Standard
Definitions on the fly are also possible: 
\begin_inset Formula $\newcommand{\ontheflyroot}[2]{\sqrt[#1]{#2}}\ontheflyroot{7}{8}$
\end_inset

, and used with different values: 
\begin_inset Formula $\ontheflyroot{a}{b}$
\end_inset

.
\end_layout

\end_body
\end_document
elyxer-1.2.5/forks/jras-elyxer/docs/userguide-toc.html0000644000175000017500000001655512117061351022334 0ustar  chennochenno







Converted document


elyxer-1.2.5/forks/jras-elyxer/docs/userguide.html0000644000175000017500000023450512117061350021545 0ustar chennochenno eLyXer User Guide

figure elyxer.png eLyXer User Guide

Alex Fernández (elyxer@gmail.com)

Table of Contents

1 The Basics

elixir, n: a substance believed to cure all ills[1].
eLyXer (pronounced elixir) is a LyX to HTML converter. While there are a ton of such projects all over the web, eLyXer has a clear focus on flexibility and elegant output.
eLyXer (including this guide and all accompanying materials) is licensed under the GPL version 3 or, at your option, any later version. See the LICENSE file for details.
Please visit the main page to find out about the latest developments.

1.1 System Requirements

eLyXer requires Python 2.4.x, and should work with versions up to 2.6.y; it will convert documents generated by LyX 1.5.x to 2.0. It has been tested on the most common operating systems: on Mac OS X, Linux and Windows, with and without CygWin.
Resource usage should be quite frugal; eLyXer runs quite happily on my 1st-gen Asus Eee, with its puny Celeron@570MHz and 512 MB of RAM. It should also be fast — the Eee can convert ~200 pages of LyX text in just over 50 seconds. Performance is fairly linear: 200 pages take 10 ×  as long as 20, so there are no scalability problems. Memory usage stays low even when processing large documents, and conversion can be done on the fly (with --lowmem) for even lower memory requirements.

1.2 Installation

This section looks at how to install eLyXer on your system, assuming that Python 2.4 to 2.6 is already there.

Download eLyXer

First you will need to fetch the official distribution file from the download area. Now, there is more than one way to install eLyXe, but all of them start by uncompressing the distributed file to a suitable directory. Just write at the command prompt:
$ tar -xzf elyxer-[version].tar.gz
Or for the .zip version:
$ unzip elyxer-[version].zip
A directory called elyxer should appear, where the main executable file elyxer.py resides.

Using the Installer

An installer is provided in the root directory, called install.py; it is the recommended way to install eLyXer. To run it just type in a console as root:
# python install.py
On Windows you can type (as a regular user):
> python.exe install.py
In any case, the script will install eLyXer as a Python script. Now you can check if it was installed successfully:
$ elyxer.py --help
A brief help text and the list of command line options should appear.
The installer will also copy existing translation files to your hard drive so that they can be used from within eLyXer for internationalization.

Prepackaged Versions

The easiest way to install eLyXer is if someone has prepackaged it for your system. Some Linux distributions include eLyXer: Debian squeeze and Ubuntu Lucid. Installation is done using apt-get or aptitude, for Debian as root:
# apt-get install elyxer
or, for Ubuntu:
$ sudo aptitude install elyxer
For both Debian and Ubuntu eLyXer needs to be run as "elyxer":
$ elyxer --help
On Windows, the alternate LyX installer includes eLyXer in the default installation. See 1.6↓ for LyX integration.

Manual Installation

If the installer did not work for you, you can manually install it as a module. On Linux go to the elyxer directory and type, as root:
# python setup.py install
On Windows just type:
> python.exe setup.py install
On Mac OS X you can use sudo to get the necessary permissions:
% sudo python setup.py install
Now you can run eLyXer as a Python script:
$ elyxer.py --help
The list of command line options should appear. You can also manually copy the file elyxer.py to a directory found in the execution path (for instance, /usr/bin on Linux or c:\windows\system32 on Windows).

1.3 Test Drive

Now you may want to try to convert the user guide:
$ elyxer.py --css lyx.css --title "eLyXer User Guide" docs/userguide.lyx docs/userguide2.html
It should generate a working web page identical to the one distributed:
$ diff docs/userguide.html docs/userguide2.html
The typical output will contain just the changed lines, which in this case should be only the header with the file creation date. An example is shown on listing 1↓.
7c7
< <meta name="create-date" content="2009-09-11"/>
---
> <meta name="create-date" content="2009-09-12"/>
Algorithm 1 Example of diff output for functionally identical HTML files.
If nothing else appears (i.e. both files are functionally equal) then everything is working fine. If you have bash installed, to test that everything really works fine you can just run the included tests:
$ ./run-tests
It will run a number of test and check the results, so you can see if everything is well. You also need to have installed the command-line tool diff to show differences between two files.

1.4 Usage

eLyXer is a standalone command line tool. It can be invoked from the command line as:
$ elyxer.py [options] [source file] [destination file]
If the source file is omitted then STDIN is used; likewise, if no destination file is specified eLyXer will output to STDOUT. This allows its use in pipes and other flexible configurations. Some examples:
$ elyxer.py file.lyx file.html
converts file.lyx to file.html. Debug messages are shown.
$ cat file.lyx | elyxer.py > file.html
converts file.lyx to file.html, as before. This time debug messages are not shown.
$ elyxer.py file.lyx | grep "<blockquote>" | wc
counts all blockquote paragraphs.
$ elyxer.py file.lyx | wget --no-check-certificate --spider -nv -F -i -
checks all external links in a document recursively. (Local links will appear as unresolved, but they can be ignored.)

1.5 Image Processing

eLyXer does not convert images directly; it uses the ImageMagick package, in particular the convert tool, to create PNG versions of the images embedded in the original LyX documents, and then it inserts links to those PNG images in the resulting HTML pages. If ImageMagick is not installed eLyXer will show an error message and will not try to convert further images.
HTML pages, unlike PDF documents, do not contain images in the document file; rather they contain pointers to image locations on disk. (Fortunately, LyX documents do not contain images either.) eLyXer will generate pages that point to the same locations as the original images, when they are PNG images, or to the converted versions otherwise. Image types like Encapsulated PostScript cannot be used directly from within pages.
Image location is fragile. All images should be placed in the same location (and with the same structure) as the original document; and they should all be referenced relatively to the current document. During conversion from within LyX image locations can be lost, since LyX does not do in-place conversion; instead, LyX copies the original file to a temporary directory, converts the file and then copies everything back to a directory ending in .LyXconv.

1.6 LyX Integration

If you used the eLyXer installer LyX will automatically detect it after reconfiguration. Just make sure that you are running LyX 1.6.5 or later, and click on Tools ▷ Reconfigure.
LyX should be able to detect if eLyXer was installed as a script, or even if it has been installed from a Linux distribution. In any case you can verify that it has been recognized by LyX by opening Tools ▷ Preferences…, going to External formats ▷ Converters, and finding the converter for “LyX -> HTML”. If eLyXer is there, it worked! Now you can convert your documents using View ▷ HTML. Otherwise try to reinstall eLyXer from scratch and then reconfigure LyX.

Installing as a Package or as a Module

Versions of the eLyXer installer prior to 1.2.0 tried to install eLyXer as a module, so it could be run using "python -m elyxer". This option is deprecated since a module called elyxer would collide with a Python package of the same name, and there are plans to install eLyXer as a proper Python package in the future (probably in the 1.3.0 time frame). In the interim eLyXer is installed only as a script called elyxer.py.
LyX (starting with versions 2.0.0 and 1.6.9) has been patched to recognize only the script and disregard the module.

2 Advanced Use

There are some advanced uses for eLyXer if you want to extract the most of it.

2.1 Command Line Options

eLyXer supports a few command line options:
--help: Show command line help.
--quiet: Be quiet and do not output messages (except errors). This way you can avoid the comforting “Parsing line 1000” messages. When STDIN or STDOUT are used (e.g. in a pipeline) --quiet is always enabled.

Advanced Options

--debug: Show debug messages. They may help a developer understand your problem.
--version: Show version number and date. Use to check which version you are actually running.
--lyxformat: Return the highest LyX version that eLyXer understands. This parameter is provided to help with lyx2lyx integration, so that this tool knows if it must convert the file to a lower LyX format.

Options to Control HTML output

--title "title": Change the title of the generated web page.
--css "new.css": Change default CSS. See section 2.2↓: CSS.
--embedcss "file.css": Embed the styles in file.css into the resulting HTML document. See section 2.2↓: CSS.
--html: Generate HTML 4.0 (instead of XHTML). The resulting pages should be easier to import from certain word processors. See section 2.6↓: HTML code.
--unicode: Restore full Unicode output. Right now switches midspaces to medium mathematical spaces. See also section 2.6↓: HTML code.
--iso885915: Generate a document using ISO-8859-1 encoding. Again, see section 2.6↓: HTML code.
--nofooter: Omit the footer message “Document generated by eLyXer” (shown at the bottom).

Options to Control image output

--directory "images_dir": Look for images in the directory specified.
--destdirectory "dest_dir": Converted images will end up into this directory.
--imageformat ".extension": Force the format implied by the extension (e.g. ".jpg" for JPEG) for output images. Use --imageformat "copy" to make images be copied over instead of converted.
--converter "program":Use the given program to convert images. Right now the supported converters are: imagemagick (default), inkscape and lyx itself. With --converter inkscape eLyXer picks Inkscape as the image converter (Inkscape uses some non-standard extensions so it might be needed to convert SVG images to PNG); with --converter lyx the new LyX option lyx -C is used. You can also supply your own converter command line, using $input and $output as variables (note the single quotes):
$ elyxer.py --converter ’lyx -C $input $output’ [source file] [destination file]
--noconvert: Use all images in their original location and do not convert anything. Useful when using images which do not convert well, such as SVG files.

Options to Control footnote output

--numberfoot: Number all footnotes using numbers: “[1]”, instead of the default “[A]”.
--symbolfoot: mark footnotes with symbols (*, **, †, ‡…).
--hoverfoot: show footnotes as hovering text. This is the default position.
--marginfoot: show footnotes with numbers instead of letters.
--endfoot: show footnotes at the end of the page.
--supfoot: use superscript for footnote markers. This is the default style.
--alignfoot: use aligned text for footnote markers, instead of superscript.
--footnotes "options": specify several footnotes options at the same time, separated with commas. Available options are: "number", "hover", "margin", "end". See section 2.9↓: Footnotes.

Advanced Options to Control HTML output

--splitpart "depth": Split the resulting webpage at the given depth. See section 2.5↓: Segmenting Pages.
--tocfor "original.html": Generate just a table of contents with links to the original HTML file. See section 2.4↓: TOC.
--target "frame": Add a target attribute to every link in the generated HTML, making all links point to the provided frame. Again, see section 2.4↓: TOC.
--notoclabels: Omit “Chapter”, “Part” and similar labels from the TOC; just output part numbers (and separate using a period). For instance, a chapter that without this option is labeled “Chapter 2: Advanced Use” in the TOC would now become “2. Advanced Use”, as on the PDF. Option adapted from the wish list: 3.2↓.
--lowmem: Activate a low memory mode which does not keep the whole document in memory: conversion is done on the fly. Keep in mind that some features as the TOC will be missing from the generated document.
--numberfoot:Label footnotes using numbers, instead of letters. Useful when bibliographical references are not numbered and therefore cannot be confused with footnotes.
--raw: Generate an HTML page without header or footer.
--mathjax remote: Use the excellent JavaScript library MathJax remotely to pretty-print mathematical equations. See section 2.8↓.
--mathjax "URL": Use the excellent JavaScript library MathJax at the given URL (usually a local URL is used). See also section 2.8↓.
--googlecharts: Use Google Charts to generate images for every formula. Again, see 2.8↓.
--simplemath: Do not generate fancy math structures such as multi-line Unicode brackets or stacked limits. This option is automatically activated when --html is selected; once more see section 2.8↓.
--template "file": Use an HTML template. The raw converted document will be placed where <!--$content--> appears in the template. Available variables: <!--$content-->, <!--$title-->, <!--$author-->, <!--$encoding-->, <!--$css-->, <!--$navigation-->, <!--$year-->, <!--$date-->, <!--$datetime-->, <!--$version-->, <!--$script-->, <!--$mathjax-->.
--copyright: Include a copyright notice at the bottom.

Deprecated Options

--toc: Generate just a table of contents. Use --tocfor instead.
--toctarget "original.html": Generate a table of contents with links to the original HTML file. Use --tocfor instead.
--nocopy: No effect since the copyright notice is now optional, maintained for backwards compatibility.
When an option accepts an argument it can be added after a space as --target "frame", or with an equals sign as in --target="frame". The quotes are optional and can be useful if your arguments include e.g. spaces.

Adding Options In LyX

To add one of these options so that it is used from within LyX, you have to modify the converter line. To this effect open Tools ▷ Preferences…, go to External formats ▷ Converters, find the converter for “LyX -> HTML” and edit the converter line. It should read something like this:
elyxer.py --directory $$r $$i $$o
If you want to generate pure HTML instead of XHTML, change the line to:
elyxer.py --html --directory $$r $$i $$o
And so on. Figure 1 shows what to do to add the --html option: after editing the line and adding the new option, click on “Modify” and then “Save” or “Apply” the changes. You should never remove the $$i $$o at the end, since it is what tells eLyXer where to find the input and output files.
figure converters.png
Figure 1 eLyXer converter in LyX 1.6.5.
LyX 1.6.5 supports a new “extra flag” line; however, at this moment it does not work with eLyXer.

2.2 CSS

HTML output, as generated, can fall short in certain situations. Some CSS wizardry can go a long way to customize eLyXer.
eLyXer tags most elements with the type so you can later modify them using a CSS. The default HTML header is similar to listing 2↓, so the default remote CSS file is used.
<head>
[...]
<link rel="stylesheet" href="http://elyxer.nongnu.org/lyx.css" type="text/css" media="all"/>
<title>Your title here</title>
</head>
Algorithm 2 CSS link automatically added to HTML
This sample CSS file is published on nongnu.org and distributed along with the scripts, docs/lyx.css. (You may have found that your document shows minor changes in its appearance with time — this is the reason. The main author regularly publishes a new, updated version of lyx.css on nongnu.org, and all documents using it automatically appear with the changes. Backwards compatibility is maintained as much as possible.)
To give your document a customized appearance (or for pages to be accessible offline) you probably will want to use your own CSS file; to use it first copy it to the directory where your document resides (e.g. renaming it to custom.css), and customize as needed. Then run elyxer.py with the following option:
$ elyxer.py --css=custom.css document.lyx page.html
This will make the generated page.html use your custom.css file. The ‘=’ sign between the constant ‘--css’ and the name of the CSS file is optional. More than one --css option can be added if you want several CSS files to be used in the header.
Sometimes the styles in a CSS are needed in the HTML document (for offline viewing, or to distribute as stand-alone pages). For these uses there is the option --embedcss: the styles contained in the CSS file passed as an argument will be embedded in the resulting HTML document. For instance:
$ elyxer.py --embedcss custom.css document.lyx page.html
This command generates a document page.html where the styles in custom.css are embedded. The CSS to embed must be a file, not a remote URL. Listing 3↓ shows the resulting HTML header for a test CSS with just one style, div.Standard. Note that the remote CSS is still added by default; to avoid it just add an option with an empty CSS file, --css="".
<head>
[...]
<head>
<link rel="stylesheet" href="http://elyxer.nongnu.org/lyx.css" type="text/css" media="all"/>
<style type="text/css">
<!--
/* Embedded CSS */
div.Standard {
  background: #909090;
}
-->
</style>
<title>Your title here</title>
</head>
Algorithm 3 CSS embedded into the HTML
As with the --css option, several --embedcss options can be added to embed more than one file.
The CSS file for eLyXer uses some CSS2 features for math structures (fractions, arrays). This makes the output incompatible with older browsers; it requires Microsoft Internet Explorer 7, Firefox 3, Safari 3 or Chrome 1. Check the Math Showcase to see if your browser can render eLyXer output correctly.

2.3 Title

By default the generated web pages have the title “Converted Document”. If a PDF title is found then it is used instead. The proper LyX title (a paragraph of type “Title” embedded in the text) will also be used if found. But when --lowmem is in use eLyXer does not try to get the proper title, since it may be found in the middle of the document or not be present at all; scanning for it would mean doing two passes, one to look for the title in all the document and another to output the web page, and --lowmem implies on-the-fly conversion to save memory.
You can change the title of the generated web page with the --title option:
$ elyxer.py --title "My Beautiful Document" document.lyx page.html

2.4 Table Of Contents

A table of contents (or TOC) can be generated for every converted LyX document. You can optionally also add a target frame to every link. The trick is to combine both options to generate a TOC that links to the original document on a different frame. For example, if the original page is called page.html and you generated it with this command:
$ elyxer.py document.lyx page.html
you can generate the TOC linking to this page, and at the same time point it to frame contents:
$ elyxer.py --tocfor page.html --target contents document.lyx page-toc.html
Then you can put it all together with a simple frameset generated manually. Just remember to place the original document in the frame called contents.
<html>
  <frameset cols="30%,70%">
    <frame name="toc" src="page-toc.html" />
    <frame name="contents" src="page.html" />
  </frameset>
</html>
Algorithm 4 An example frameset for TOC navegation
TOC generation accepts the same options as normal document conversion. For example, if you follow these instructions literally you will notice that the TOC has very wide margins and looks a bit weird; that is because it is using the default CSS. A special CSS file for TOC files is provided in docs/toc.css, so better results should be obtained with the --css option:
$ elyxer.py --tocfor page.html --css docs/toc.css --target contents document.lyx page-toc.html
With a little bit of practice you will be able to generate useful (and nice looking) TOC files. You can see an example for the user guide (if you are not already looking at it).

2.5 Segmenting Pages

Quite often you don’t want a huge monolithic page, but a set of linked pages. To do so you can use the --splitpart option, specifying the level at which eLyXer should split pages. For instance:
$ elyxer.py --splitpart 1 document.lyx output.html
will split document.lyx into pages at level 1, using output.html as the root page. Each page will get a number that starts with output and ends with .html, with a suffix that depends on the page — output-2.html will correspond to the second split part.
The level corresponding to 1 depends on the document class: books will be split at chapters, but articles will get a section per page. And so on with lower levels.

2.6 HTML Code

The HTML code generated is technically XHTML Transitional, version 1.0 [2], using UTF-8 encoding. Some programs have (in this day and age) trouble importing XHTML, notably some popular word processors. To work around this problem and provide more flexible output in general you can output HTML 4.0:
$ elyxer.py --html document.lyx page-to-import.html
Again, technically the code generated is HTML 4.01 Transitional [3] using UTF-8 encoding. Both versions should pass the W3C tests [4]. If your particular web page doesn’t pass the tests, then it is a bug and it will be treated as such.
The --html option also activates the --simplemath option; see section 2.8↓: Math for details.

Character Encodings

For better browser compatibility, medium mathematical spaces are substituted in the output with midspaces — improving the output for some popular browsers. If you want your mathematical spaces back, just use the --unicode option:
$ elyxer.py --unicode document.lyx page-to-import.html
Check out the Math Showcase with Unicode to see the results. In the future other non-Unicode substitutions might be used.
In case you want to use the ISO-8859-15 encoding in your generated document, you can add the --iso885915 option:
$ elyxer.py --iso885915 document.lyx page.html
This will make eLyXer output a document with all non-ASCII characters encoded as &nbsp;, &#x2005; and so on. This encoding is similar to ISO-8859-1, also called Latin-1, but including the Euro sign. The Math Showcase (ISO-8859-15 edition) has been generated using this option.
Both encoding options can be combined with --html at will.

2.7 Internationalization

eLyXer is distributed along with a few translation files. They are automatically regenerated every time make is run, and reside in the folder po/. Internationalization is done using GNU gettext, so every locale is identified by a two-letter code (such as “en” for English and “es” for Spanish). There are two kinds of files: the text .po file (which can be found in po/my.po for locale “my”), and the binary .mo file (found in po/my/elyxer.po).
For internationalization to work properly, Linux distributors should take all binary .mo files and place them in the directory corresponding to locale files, which we will call $localedir. As the Python gettext page explains, this is distribution-dependent: for example on Debian $localedir is /usr/share/locale, so for locale “es” the correct route would be
/usr/share/locale/es/LC_MESSAGES/elyxer.mo
Windows distributors on the other hand should place files in %PYTHONHOME%\share\locale, for example for locale “es” on a machine where Python is in C:\python:
C:\python\share\locale\es\LC_MESSAGES\elyxer.mo
To generate a new translation file (we will use “my” as an example locale here, corresponding to Burmese): you need to have the GNU gettext package installed. Then go to the directory where elyxer.pot resides:
$ cd src/conf
and generate a .po file for your locale:
$ msginit --output-file=my.po --locale=my
Then move the file to the po/ directory:
$ mv my.po ../../po/
and start translating it to Burmese! Once you are done run make from the root directory:
$ ./make
and it will generate the file po/my/elyxer.mo. Finally, place this file in
$localedir/my/LC_MESSAGES/elyxer.mo
and you are done.

2.8 Math

Math equations are an important part of what takes LyX apart from other editors, since it supports the full LaTeX feature set — that is, about everything under the sun. Unfortunately, math support is hard to get right. Many developers are focusing on MathML, but at the time of this writing (Q2 2010) support on some common browsers is still missing.
eLyXer follows its usual minimalistic approach and doesn’t try to be everything to everybody — instead, it supports out of the box a set of usual constructs (fraction, square root) and tries to simulate others (binomial, overbrace). See the Math showcase for yourself and learn what eLyXer supports and what not.
For more sophisticated math equations there are a couple of advanced features.

MathJax

The first option is to use MathJax, which is as simple as using the option --mathjax:
$ elyxer.py --mathjax remote math.lyx math-mathjax-remote.html
The remote argument tells MathJax to access the MathJax library remotely on the MathJax CDN. (You should always comply with their terms of service.) See the Math showcase (MathJax remote edition) to check the results.
In case you need to go outside the terms of service, or you want the content to be accessible offline, you can always use a local copy of MathJax. Just use the URL of the repository as an argument to the --mathjax option:
$ elyxer.py --mathjax MathJax/ math.lyx math-mathjax-local.html
This way eLyXer uses the given URL (in the example MathJax/) to load MathJax from and set it up. Although some code needs to be hosted on the same site as the pages, MathJax uses a feature called web-fonts which can be downloaded from a public server; this is quite easier to host. See the Math showcase (MathJax edition) to see how MathJax fares with eLyXer.
Something to note is that MathJax is a JavaScript library; all rendering is done client-side by the user’s browser. This has quite a few advantages:
  • Math processing on the server is quite light; equations are basically surrounded by a special tag and left in TeX form.
  • For developers: integration of these libraries is very easy. It took just a few days to integrate both libraries with eLyXer.
  • MathJax is improving all the time thanks to the efforts of Davide P. Cervone and the rest of the developer team; eLyXer and its users reap the benefits readily.
  • The client browser already knows its abilities, and can choose the rendering method it considers to be the best. MathJax can even choose between MathML and HTML+CSS at page rendering time, showing MathML on fancier browsers and simpler HTML where it is not available.
It also brings some disadvantages:
  • With the remote argument, JavaScript code resides at a remote server and your users will need online access to view the maths.
  • If MathJax is accessed locally you need to also host the code for MathJax. (Web fonts used in MathJax can at least be hosted elsewhere, so publishers do not need to also host the fonts package, but this hasn’t still been used in eLyXer.)
  • And of course it takes some time to render everything on the client, which can degrade the user experience on older machines.
Publishers should carefully consider pros and cons before deciding what to use.

Google Charts

Google Charts is an online service which generates images that contain charts and other stuff; it can also generate TeX formulas. eLyXer can use it using the option --googlecharts:
$ elyxer.py --googlecharts math.lyx math-googlecharts.html
There are some limitations to Google Charts: no macros, formulas cannot exceed 200 characters, and the supported command set is limited (commands in text mode, for instance, are out of bounds). Also, generated images can be hard to align vertically — by default they are middle-aligned, but some small characters or superscripted formulas can look weird. But this option can be a quick&dirty way of showing math for older or unsupported browsers.

Brackets and Limits

Fancy math structures are generated by default: arrays and binomials are surrounded by multi-line Unicode brackets, limits in display mode are stacked above / below the symbol, and so on. When the option --simplemath is used eLyXer avoids such structures and just outputs enlarged regular symbols. It is also included in the --html option.
Check out the Math showcase (HTML edition) to see the results.

2.9 Footnotes

Footnote generation is surprisingly hard to get right in an HTML document. eLyXer has a fairly complete set of command line options to customize how footnotes are generated. Here we will use the aggregated option --footnotes "options" which can be used to specify any combination, but they can be turned on independently using --…foot. For instance: --footnotes number,margin is equivalent to --numberfoot --marginfoot.

Markers

The footnote is attached to a point of the text (the referring text) which is usually marked by a bit of text. The default behavior for the marker is to use a superscript letter surrounded by square brackets, in blue: [A]. The text can be changed to aligned text with --footnotes align: [A], so markers are not mistaken with other superscript constructs such as exponents (like ea).
Markers can also be converted to numbers using --footnotes number: [1]. Or, they can be switched over to symbols using --footnotes symbol: *. Available symbols are rotated from this sequence: * ** † ‡ § §§ ¶ ¶¶ # ##. All options can be combined. For instance, symbol markers look best when shown aligned; --footnotes align,symbol will show aligned symbolic markers such as * or .

Position

Footnotes are supposed to appear at the foot of the page, but that is not always possible or practical in web pages. Huge pages make scrolling up and down quite uncomfortable, and remove the immediacy of having the note in the same page as the referring text.
There are a few alternatives: use the margin, show hovering text, or link to the note at the bottom of the page. eLyXer can use all three. --footnotes margin will place the notes at the margin, just as margin notes but with the addition of the footnote marker. While --footnotes hover will show hovering text when the mouse is placed on the marker; this is the default behavior. Note that hovering notes are converted into margin notes when printing.
When footnotes are shown at the end of the page with --footnotes end, footnote markers turn into links. The actual footnote at the end then contains a link back to the marker.
The most interesting part is that these three options can be combined at will: --footnotes margin,hover,end will show footnotes at the three possible locations. The most practical combination is probably --footnotes hover,end, which will show notes as hovering text and also at the end of the page. Note however that in this case notes will be printed twice (at the margin instead of hovering and at the end).

3 Work in Progress

As you can see eLyXer is a mature and tried package, but it has some rough edges.

3.1 Known Issues

The following issues (including bugs and missing features) are acknowledged. Some of them should be solved soon; others may take longer.
  1. On Mac OS X the output of a message with Unicode characters may cause an error. Workaround: run elyxer.py with the --quiet option.
  2. Some phonetic alphabet symbols are not well supported — if generated with LyX they only appear in a different color: [sample].
  3. Multi-column layouts are lost. This one is almost impossible to get right in CSS, so there are no plans to even try.
  4. Many BibTeX styles are missing. (They are quite trivial to add though.)
  5. ERT (bare TeX code) is ignored.
  6. Many AMS environments (like alignat, gather…) are not working or look strange — some non-AMS environments too.
  7. Images are never scaled above their nominal resolution. This is seldom needed if at all, so there are no plans to change it; if people really need the feature just let the author know so it can be added as an option.

3.2 Wish List

The following features have been requested by users; specific people are referenced by a couple of initials so they can recognize themselves while keeping some anonymity. (If you prefer that your initials do not to appear here at all just let me know.)
Queued features will be added at the next big release — the priority for each feature will be set by the number of users requesting it and date requested. Pending features need some assessment. Those marked as too complex have been evaluated as requiring too much work, but the decision might be reversed if there are enough people interested or a simple way to implement them is found. Once done, features are marked with the first release where they appear.
Feature Date Users Status
Understand \setcounter{section}{1} 2010-05-15 JB 1.1.0
Option to turn off title prefixes in TOC 2010-07-10 YG 1.1.0
Use BibLaTeX with eLyXer 2010-09-14 PJ, WE Pending
Render change tracking: "Show changes in output" 2010-09-18 YG 1.1.0
Option for footnotes at the margin 2010-09-21 A 1.1.0
Output SVG as <img> tags (20↓) 2010-09-22 YG Pending
EPUB output format (19↓) 2010-09-23 MJ, MG Too complex
Option for footnotes at the end of each section 2010-09-23 MJ 1.1.0
Add more controls for image conversion (21↓) 2010-10-02 WE 1.1.0
Support for format 401 (Insert Horizontal Line) 2010-10-06 US 1.1.2
Parse contents of ERTs 2010-10-06 US, JW 1.2.0
Correct scaling of tables with relative sizes (e.g. %col) 2010-10-09 US Pending
BibTeX: parse math formulas inside BibTeX files 2010-10-16 JA 1.1.1
BibTeX: display \url{} as an URL 2010-10-16 JA 1.1.1
Do not label bibliography items in comments 2010-10-21 JA Pending
Unit tests should warn if ImageMagick not installed 2010-10-24 JA Pending
Unit tests should run fine without PNG conversion tools 2010-10-30 JA Pending
Option --imageformat copy to avoid converting images 2010-11-12 JD 1.1.1
Option to embed the CSS in the HTML file22↓ 2010-11-23 GM, JA 1.1.1
Display sub- and superscript aligned vertically (as in integrals) 2010-11-23 GM 1.1.1
Use Unicode large characters for sums, integrals, matrices… 2010-12-07 GM 1.1.2
Do not number captions in code listings 2010-12-08 DC 1.2.0
Support brushes for SyntaxHighlighter 2010-12-10 DC Pending
Generate formula images using Google Charts 2011-01-07 ET 1.2.1
Output reference arrows as CSS pseudo-elements 2011-01-12 GM Pending
Include part names in --splitpart navigation header 2011-01-15 AJ 1.2.1
Merge options --toc and --toctarget into --tocfor 2010-01-17 JA 1.2.1
Make --splitpart and --tocfor work together 2010-01-17 JA, TP 1.2.1
Generate named references (equivalent to \nameref) 2011-01-19 TP 1.2.1
Do not generate entries when index or nomenclature are missing 2011-01-19 TP Queued
Do not output unknown commands in red except in --debug 2011-02-22 JA Queued
Output equations as images 2011-05-31 GK Pending
Parse modules for custom Flex CharStyles 2011-06-08 MG Pending
Convert several files with a single command 2011-06-01 PF Pending
Export slides as HTML5 presentation 2011-06-28 RK Pending
Add an option to remove navigation bars 2011-06-29 AH Pending
Support for External Material: PDF, Date 2011-10-22 MI Pending
Some features require further explanations.

EPUB output format

The EPUB management package calibre does not output valid EPUB documents when converted from eLyXer HTML files, at least according to the Threepress validator.
This is a complex feature request; calibre does minimal formatting in its EPUB conversion, so making it generate valid EPUB documents requires changing deeply how eLyXer outputs XHTML. Lots of help would be needed to get this working.
That said, EPUB readers are often much less strict than the official format and they readily accept eLyXer output. Just convert your LyX document to HTML using eLyXer, and then import the resulting HTML document into your EPUB reader. Let us know how it goes for you.

Output SVG as <img> tags

This feature would be most welcome from the part of the author. Unfortunately, Firefox alone from the major browsers refuses to render <img> tags correctly for SVG. According to bug #276431, this was fixed on 2010-09-08, so the next version should do the right thing; at that point this feature will be queued for inclusion.
You can check out how your browser does with SVG images with this SVG test page.

More controls for image conversion

eLyXer uses ImageMagick to convert images. Some images (in EPS format, for example) do have blank borders, or they come in varied sizes. It would be nice to remove blank borders and have some kind of unified resolution in the conversion, which would be passed to ImageMagick.
As of 1.1.0, the improvements include using ps:use-cropbox=true in ImageMagick for PostScript and EPS images. Unified resolution has not been added as it might collide with picture density, but suggestions are welcome.

CSS controls

Proposed by JRAS on the elyxer-users mailing list, the following is a direct quote of his message.
“[…]A mixed solution for CSS styles:
  1. The essential minimum css for math formatting (a compacted version of a math.css subset) included directly inside HTML head.
  2. Then a call to download the on-line full CSS, that can repeat the minimum already included math.css (from item 1) plus some other styles. The default can be changed by --css command line option.
  3. A new option (--addcss) to add another CSS defined by the user. For example, to only redefine some styles from the default, etc.
The styles should be included in that order (using the "cascading" property). Item 1 is fixed in every HTML file. Item 2 is always added and by default pointing to the eLyXer on-line css, but it can be changed by option --css to another url or file. Item 3 is optional and its url would be added after the other two items, only if the --addcss option was used in conversion.”
As of 1.1.1, an option --embedcss has been added which allows embedding one or more custom CSS files into the resulting HTML document. Also, --css can be repeated as many times as desired to use several CSS files.

3.3 Contact Information

If your problem does not appear in the above list, please let the author know; you can find him at elyxer@gmail.com. In the words of Rich Talley: “the tool’s author really likes getting challenging documents and making eLyXer work with them”. You can send your sample documents and we will try to make eLyXer convert them acceptably. Any documents sent will be treated with the utmost confidentiality.
You can also join the mailing list to discuss any information related to eLyXer. The author monitors the official LyX lists for mentions of eLyXer. Bugs can also be reported at the Savannah page.

3.4 Extending eLyXer

eLyXer should now support most LyX features; but sometimes it will ignore a command, sometimes it will signal it, and it might even refuse to work with certain documents. What can you do if eLyXer does not work with your LyX file? Worry not! Its flexible approach to processing allows anyone to write support for the missing commands.
eLyXer is written in Python so that it does not need to be compiled; its code is interpreted on the fly. See the accompanying developer guide to learn how to extend eLyXer for your own purposes. If you know how to program in Python it should not be difficult to support other LyX features. If you don’t your best bet is to ask the author.

4 FAQ

Q: What versions of LyX are supported?
A: The tool should work with all LyX versions from 1.5.5 to the latest and greatest. It has been tested on Linux, Mac OS X and Windows.
Q: There are indeed a ton of similar projects over the web. Why add another one?
A: The four tools supported by LyX (tex4ht, hevea, tth and latex2html) gave inferior results in 2009, and were quite inflexible. The author found the need for a good converter, while at the same time acknowledging the difficulty of the problem.
Q: Speaking of that: why build a LyX to HTML converter, instead of a more generic LaTeX to HTML converter?
A: The problem space is quite simplified, and therefore progress is much faster. To make it even easier eLyXer has historically centered on the subset of LyX functionality that is useful to most LyX users, leaving the rest for a later stage. Nowadays eLyXer aims to support the full LyX feature set.
Q: What can we expect from the tool in the future?
A: eLyXer should fulfill the needs of 99% of LyX users in the short term. It has also learned a couple of tricks of its own such as page segmenting. Eventually it could be distributed along with LyX as part of the standard installer.
Q: Why did you leave out my favorite feature <insert random LyX command here>?
A: In short, because nobody asked for it. Every feature which has been requested (either to me personally or to the list) has been tended to, unless it was too far out or I forgot about it. At this point of development every missing LyX feature will be considered a high priority item for the next version, if at all possible to implement.
Q: My document changed its appearance without my intervention. Was it black magic, elves or what?
A: It probably uses the online CSS file, which is regularly updated. See section 2.2↑ for details.
Q: Why use an online CSS, instead of placing the CSS file in the same directory as the converted file?
A: There were pros and cons. An online CSS resource allowed me to update it for everyone at the same time, but might make it more difficult for people without an internet connection; local CSS files are more flexible but can also be confusing to novice users. In the end the online solution was preferred, with the --css option as a fallback.
Q: My MathJax pages are not rendering correctly; equations are silently ignored.
A: Check that MathJax is installed on the same server as your pages; for security reasons the browser’s “same-origin” policy mandates that JavaScript can only be loaded from the same site as the original page. Also make sure that JavaScript is enabled on the browser.
Q: How can I disable hovering notes? Isn’t there a --nohover option?
A: It can be done using --footnotes margin. This will disable hovering text but keep footnotes in the margin.
Q: I found a bug, what should I do?
A: Just send it to the author at elyxer@gmail.com. You can also report it to the Savannah interface.

References

[1] WordReference.com: “definition of elixir”, accessed March 2009. http://www.wordreference.com/definition/elixir

[2] W3C: “XHTML™ 1.0 The Extensible HyperText Markup Language (Second Edition)”, revised 1 August 2002. http://www.w3.org/TR/xhtml1/

[3] W3C: “HTML 4.01 Specification”, 24 December 1999. http://www.w3.org/TR/REC-html40/

[4] W3C: “Markup Validation Service”, accessed March 2009. http://validator.w3.org/

elyxer-1.2.5/forks/jras-elyxer/docs/math.html0000644000175000017500000011417412117061352020503 0ustar chennochenno eLyxer Math Showcase (non-Unicode edition)

figure elyxer.png eLyXer Math Showcase

Alex Fernández (elyxer@gmail.com)

1 Introduction

This document is intended as a showcase of the mathematical abilities of eLyXer; for more information be sure to visit the main page.

1.1 Versions

There are several versions of this page:
All of them are generated from the same .lyx source file; they should help you decide which rendering options suit you best.
Also available online is the eLyXer translation of the latest LyX’s detailed Math manual, which contains a lot more examples of LyX maths.

2 Typography

Math formulae use a lot of different symbols and fonts.

2.1 Greek Symbols

Greek symbols are very important in equations: φ, π, Ξ. eLyXer offers a complete set in both upper case: Γ…Ω and lower case: αω. Also the AMS italicized upper case: ΓΩ.

2.2 Math Symbols

eLyXer supports the whole set of math symbols in John D. Cook's list: ∃∂∇ ≥ . It can also render a few more:  ∝  × . You also get all symbols from Markus Kuhn's list: ⊙∐.

2.3 Other Symbols

There are other symbols like arrows:  ←  → , or geometrical shapes: , . eLyXer offers limited support for them. You might also want to use financial symbols in formulae: ¥€$.

2.4 Spacing

Equations look good when items are properly separated. The main separation is the Medium Mathematical Space: x = 3. Note: if you are viewing the non-Unicode version math.html of this page then you are in fact seeing midspaces, which are very similar but not exactly the same: (4)/(18) em for medium mathematical spaces versus (1)/(2) en, where 1 em = 2 en. Try out the Unicode version math-unicode.html — and viceversa. You can check out what version this page is in the page title.
The command \raisebox is useful to, surprisingly, raise a little box,
raisedoverloweredand back.
Like \mbox, it puts its content in a text box. It can also be used just for spacing:
BV.
There are other spacing commands: \hspace: a b, protected space: a b, and (at “block level”) \vspace: a b.
There should be 1 cm of vertical space above this paragraph.

2.5 Fonts

By default, letters denote variables and are taken from the \mathnormal font, which is italic, αx + αy = α(x + y), with the exception of upright capital Greek letters, G ≠ Γ.
Function names should be upright: sin(2π), log(x), tanδ.
Mathematical fonts used in equations include Roman (\mathrm), Sans Serif (\mathsf), Typewriter (\mathtt), Bold (\mathbf), SCRIPT (\mathscr), CALLIGRAPHIC (\mathcal), BLACKBOARD BOLD (\mathbb), and Fraktur (\mathfrak). For the latter, some single characters are translated to their Unicode equivalents: , 𝔽, 𝔉.
Regular text in a formula can be achieved via text font commands like \textrm: 5  to 10, via boxes like \mbox (prevents line breaks): 6  is more than 5, or the AMSmath \text macro (scales like math symbols) basesupersub. The content of an mbox is processed in LaTeX text mode. This allows text font commands, e.g. a switch to sans-serif-bold-italic, or the phonetic alphabet: sfbfit, tipa.
Units should be written upright, either with \mathrm or with macros from the units package, e.g. as simple unit, km, with magnitude, 57 km, with fractional unit, 200 kmh, or with a fraction before the units, 32 km, (7)/(16) s.

3 Numeration

Equations can be numbered, like (1↓)
(1) y = x
And also like (2↓).
(2) x = 3
Some equations can be numbered even if they don’t have a label.
(3) x = 2y
Notice that equation (2↑) comes after (1↑).

4 Simple Structures

Let’s now see a few of the simpler structures that eLyXer can output.

4.1 Fractions

A simple fraction:
(1)/(2).
Inlined: (2)/(3).
A big recursive fraction:
(1)/(1 + (1)/(1 + (1)/(1 + 2x)))
A nice fraction: 56. A non-diminishing fraction containing alignments:
(1)/(1 + (1)/(1 + x) × (1)/(1 + x)).
A similar concept is a binomial coefficient: (A + 1B). It can be prettily presented:
AB + 1.
A symbol can be stacked over another using \stackrel: xR → y. Anything can be stacked:
dx > 3limx,  headheels.

4.2 Limits

limx → ∞f(x) should appear as x → ∞ in italics, and «lim» in plain style. In display mode, a limit must appear below the main symbol:
limx → ∞f(x).
Limits are also used in sums and integrals:
i = 1x,  0f(x) dx
where the sum’s limits should appear below (i = 1) and above () the . The placement of the integral limits depends on the document class: LaTeX standard classes place them right to the . Limits are shown to the right in inline formulae: i = 1x and i = 1x.
The placing of limits can be configured with the \limits and \nolimits macros:
limx → ∞f(x),  i = 1x,  0f(x) dx

4.3 Roots

A square root: (3). A more complex root in a fraction:
(1)/(1 + (2)(1)/(1 + (2)) + ((1)/(2))).
eLyXer can also do higher-order roots: 3(x + y). A devilish case mixing everything we have seen so far:
(78((8)/(4)x) + i = 1x)/(s + 5(((78x + 45y) × (Ω))/(sin(x + 1)) + 38 km)).

5 Complex Structures

In this section we will explore arrays and related constructs.

5.1 Arrays

An inline array a b c d is always shown in the same line. In display mode, the array is shown on its own line:
12 2 3 4 × yx
Apart from that the appearance should be the same.

5.2 Brackets

Arrays are separated by variable-size brackets: a b c d a b c d a b c d a b c d ||| a b c d |||which might also differ on right and left a b c d or use the empty opening a b c d or closing: a b c d |||. There are also fixed-size big brackets, e.g. f.

5.3 Cases

Used to switch between several values.
y =  x i = 0,         x + 1  i < 3 
Cases may have more than two rows:
f(x) =  0  x < 0,         ∞  x = 0        0  x > 0 

5.4 Braces

Values can be underbraced or overbraced.
a − b = b + c + d + e.

6 Macros

Now it’s time for user-defined commands (sometimes called “macros”).
Definitions can be added as macros. Then they can be used in formulae: 1(2). They can accept default parameters. Again, useful in formulae: 4(5).
Other definitions from the preamble can be used: 3(4).
Definitions on the fly are also possible: 7(8), and used with different values: a(b).
elyxer-1.2.5/forks/jras-elyxer/docs/converters.png0000644000175000017500000016106512117061342021564 0ustar chennochennoPNG  IHDR-F6|sRGB pHYs  tIME ,܆J IDATxwXSW7 ʒ=d8@-"ZD'.AQ@TsZAAT* ZJ+*Qd+1e>499ܛk8nߌ"@ $)Ti() B!BmxD!zt:FitSPrr@IB/`:iHt&5c20V69l`B!by؍Id+ޑ9+@h|vhp@_L xx!BKW (b\*L@lP$Ň$-w]z{b2j25MВE!W$UVP4Dq MJK#l6(t.Rs@,|S.(r|'5%ͭWo[O}SIQUUFvSz8C!$+{^~ؘ')қPv興e@ )lJh^Vh0e4q<`e/;PwrabIt@P]]o>Jz l6?!BIW^ڪ5k4Eߗd_#iDR/.2(.&A⫝̸Tڡ[E݀ZO`\H(1FMMYOQIɔH+*J}=|HMơB!$d髫9:*((H1#j"o*8t?s[dI.">>;m*Ax@0? (*3JTXT' %(KKAl˗'N(BmF VWW++ed Zmv ))#xfl\RnSt0X@]o&l`0]s!RSvVN^.OGG_ 5:ʏ\tDk&al6 l 0˜ؿҘR,iY\$| 4`Ё)li` ZW))ϞןSbujd@@ƅv_wmq*/@&yo^yWc FX‚͘m @؛,_ΐ]<~0rWĨ/jYзo^}7mN_3~\{#Y- C%& ^&<=nn⇟v}7uΓGӭA\3>E;PI>;Ξ<0NUUe3e8GÂwї~󡴞j5g9q]f16,v;}Aں΋WhiworLIqa/'WN!:ҷotLhP 1]I#㈈ KćqLQO>·W*I5>E:Ƥ]VNqQ2~fuq UǿҀ/D%];`7ONVw޻mXN;q*뗣/fb6X&U>~ӕ'"/>‚n*f9Q7níxÿ>wtu._:x9q]oء˒U ZsԹqw;{aUUeyiiC0R$IzV MJ`2Y,i< FC@H$y|>ɀO ,ćQbTP} \T&.+ @L< $1B%B.·~>QVZ zo ozsBX%f I/Jz!#+;zJ/_r—{JɰdX^=wK`|- Z;t ˭&JyL0S%+P?ݾ寧v-쵨2rnϒqB*7]@@2bH \> 4fH3S$> <6!.Sފ~&9Yl2@oOglWRUY.C>!yU9sv`bIg;z]Vzwޗ>v*eA~~O oݜOE6ו-O="={YG>O)Z;i`4> @@W"0Z~uUnzy©Qzt<,}Wbir6FD5#Dø0>guK5\l. g2AFFڍ QcH<!ԉQ[aw_p*qYoLcs+"<$ָN7e<&qҟ6x55STwk?VȣMT~]P3J%22SM~ޯw7]]KOO@ ZPM1՚ޡhM|G!#ʥߊGOKMh>~޾e:Т߀AO$Wߊuj]Oμu1WAK.]|j0b>_PPpG ɀʚÀ x~~PTen">\ƨvQQ^|>0 +J|n܊jCGY!Թhob¿ TًɞAf-&N_Z7&~WnG_ۼ6 8t&U&!UKΓ^Rs {6Q4VT&RdEkҙ4&0{q♫V }ɩc `>iio!лi*쾌!{FI TT@t:9eeo=J+疫iQ#"p \aV6AŃTsXf⿷LyW*h!#R:FQMGﲤXZOTKLiD?Hly9Jw*՚US2rb!I*WPRVQ3! V/&ٓ#++EtF "7555..ݻԈS>  r3_*Rh @4>j\Q^}#/MU#fTU ߦfW2m&͑0$测cD~ ׆(/{uTnv7== CZ_YY^TT]=ÇQSf\,)cCp0HLI.Rg6qW$RV8$sX & *+yx|kiCFXKcV$Wā r2z<S%M:A޹*1LUU Uӻ̇q#RRsRin}DKuIB$*_ fg=;6QZqa.VUcbffn#B!$ѳo>R/`J˪i?"}"J:ab*9G ƃZ8mWUU >`02,4B!ƚ2""jFSD٧R3?/  z]hh| PT}LB!hˆS>·AlIσgTUB!c*y @lu*h!B&6`\]xWB!jM!r]A\0B!PA#l&l6·!B>&&jB1> !B`|B!P0Bva!BB!Ƈ!BC!j'B!>0> !B]`|B!P0Bva!BB!Ƈ!BC!j'r,j |<!$D+ŇP }qϟǃBHb|Ix|3a!$h|&>^>B!j?xB!U V.·!B+f?ƇсGpy@h˒͘hIII$hcǎ+++:tHղ"o !BT3.S~ѢEwܩ=z3e``gB!>KLJ; (KKK+++{񪫫KKKɃByח,((pwwr労ٳlr;v۷͛={-֞:uʕ+K$I޽{Ϟ=YYY4r>>aaa111zzzu.\`_U̦E^xqҤI|G߾}{ҥ\.wݺu 6x jVjK֚{]F;yKz [n hjaÆm۶_¶mvǏ{zzzܹseee>>>ukĈΥ)((Pbii ֭kO `BuPm?<𫉳`hhH=544S.?\zpxƍ )))vvvL&sn]EEE]]nyJJʨQDKtrB}+gRQQׯ_SO߼y&r9rV|>_SS~99oN>Y{KHHHSBYk7o$yyy[[e˖%''sSN Xrenn&wﮥr#G7k?ϟsesssjP9B!fmֲ`7[[[ѧԕͰŋX,a WCBǎO<),d0={ׯKJJfΜ9f&/F6mZ~~rB}2>ew5Or& 111u<ٳg%M`X۷o߾}{tB!ɇK"B 6YB!ćk@}C!׮Qp> !B_si!2> B!$:e|·!BHćkl 8:k6 >lxiA$+>~Yt[<1_MH\LY@jjZ?S 1DwV!al0F$TkhhBQ$I۳X,Zy/͆zƟ|M[88P3$yqf;yƱ㧨qy?S7o;#!Mi軛3>ê:ݨzߝBCuf7:f3gو*}aO622b2:::zw^F4005.I.\0tP& fffp&ǎSEEeƍurrQrrr+++{!Z(%%ߝŒ7~Pzo{8~Po51^=jƟwn@zFfSq_9e/:9xKlmƟ<)M}wz<///kmTTw'Pf?ao!Ց01322݋ 88G}M&~~~۶m;wn\\\ɓ'PVVFUhJM Ǝv! <|RRٳE }N]o-t|%ZQ^]O)--VRաCkj㧼֯6_UUeE N:qwu8aZMxb:Ww'^s|>_VVf;.s8rxB"65>lW1?Iuu5x>77k׮wސKKKpppHOO"~G;;;nذ\]]w]BSCFFFGG_ݹsٳرc$Ih41TUY,ֿ)&=7\VT-\G[ @XMKSz@ѩ,Ԅqc]a9bԕ+< gۥ?6]kA޼yd2UUUwXﮑ?lKuq~;tut8͝d;OHF4>Ym τ ;wn=zXzy %%eԨQիW& j\sgO>uvv{{:#CTEEeŊbFkX]~Y?+C=6ddd@FV- EnĥLaI+inn^YyQN u䙡V1֫w'BUEWFk~s7kV2dLJ (Ϟ=2997om޼1;;ccc M4-\0,,,...""Dʂ.+T/yd?x*?67k4ng0_ii/v j4*Dk>vmH2vΧ$u7v /\#&2RSޤ}FW/~t(Fp+su[%WUVIIIɰlD}u$;>lٲe...AAAO>}޽{W^ |>ҤIgΜ),,$b=<}BdƇ*Zy8PкϟǃB_ !o!P%B!ډH0C!jC"a_!B/B!:;C!j'dyyʕ+ KAAA;m$Y,V  E!$?lũ'O޽۷oM^G;55522R>w$''.vCxB = v٘AΉ'455pWUUy8CELKh7Q4>Y2ᶙ022p8A'x7%%%VVVAAAz>3gάYm$I޽{Ϟ=YYY4rvyܹscff ݯ\"--={@6MF~j=}wJJƍ]]1fp!$y5B- ova 6l̘1&M211ϫmذaO]II wB 5q ~kO7XC?EM81###66 _u۶m{qrrΈ㏳g{۷RKKab`Æ JJJ%%%b/]ddd4p[8qB~|>p8]vœ!P-/yxڑh0:.my?OсNxx8F333[zuttիW222zMUSQQYbFR())))FS"_t:]CCCꩡavvU;wȑ#fffW^e2x6#B$xϞ=P!V<OMMMxbAA˭;QVV%kddd$$$)xQ***k7oԄ溺LNN͛EEE7ovttáAђDKߟVK.Q k؈vXVg1Ŀz|fKRSS9Ξ={VNKKr'~!x"$SVV1cƌ3Μ9ŋ''QFijj:::]ÇiiiVew-v999/_677?r䈘f]lYrrr\\?0wF[ϟ4iҙ3g `Xx26WWĨ(H1rHBfff\\~qqq;&Ii񻨫O>[n]fMzz:EYXXxzz֭vZ PRR-~˗!I 7mڴbŊw)**ڵ lBĉ,--O>] ___6mڴ|]]]www* [x)rppSY[[HCCR^^>((hՙzzzx26eeeeeeS##ZO>MI/>ʕ+]kŊϟwssrJhhh|||BBB݋_~hc `hh=~x<-j~혣%?Ň5;233Aaa#G,k݅7oi$)kbm߾=''秦nܸ j\Qݿk={_~ILL,X_~=sL<;3f:uJGFFNgϞZxcnjLƍ҄$ɟYOOOJJW^{{Ϛ5k6?~-5>./:uJKKKFF޾){(z]F]paСL&S__?22*Ν2d433ÇPXXnݺ#G 6Vs999}􁚨/UUaPfC3zk.734yT%$I>JJ}~+[.0> /4ߊ9޼y$B|oՑcƌVSS{yxxx b%Iрzs$d%%%ooo0a󝜜D/2RzIrwwOHHsqq\xmC|}}Ml2www__cǎEFFIKKS XjUVVV`޼ycƌ9t?-CJ\\eV :yyߘ Ld2e2^$&M8jh[*â qr !jF@II%Æ }Makkkggׂ}_~,[,۷o57ohBVVV-Κ5WX׻;&W^t-5eܫW)9=z0W>9>?* 0> EJJs!C Ƌ/z[yjͮ!jy’SF=}7/_ST\L=h\2H~|XJJ̙3 ֭[|& BFڵJ9&++;bĈʾ}6l ##!1?Od^~(-f9"/'?^_U*##oy􌲲i<16\Bć1k$g>,==}Сcƌ9{aÆ>ԺRHս}vklfxo/ymWɯR45554_%>Jt/vqViUQ#G\x g-L6MHl|؆ FyqwSSS z{{rR:uIf l(6j^EyYUէrF /үOQF)*2L[AE8hz%$/Ij*CӧOn 䔔.]Jy UhjħO9xcB9ٙoSS^*|$ɼ_>yWߗR;P .kbb"Zb_~Ν !m۶s988x{{gddcoBaxG'.M6FE֛޿ҥ$jݕ[zzz 4n?H%<v+B·5ջHԩI֖~UUUC ޽;R円٢[SW^55s޽ãGWi !j{3>L. MIUȺ$9>LZZzʔ)۷o… O>566o~5U555+yݼyh͎ssiVZ}.]j^/_쐐aIjj*ٳgOiii666MZHgXMyShѿyWW/{X,֨Q$''7~'OPM|m}:|5ު? $<ߝ;wO~gϞ.YDSSS^^vٲeqqq?ܹsE6Z'Mt̙B X,,J&&&&&&FEE@b#G6ԤO>[n]f @ Xhgk׮]bECC 1RSS###񒓓[k˗/i_|y-))){{{a—444Z EWxH·a|X& ݻn:;;r}}֭^ [x)rppռ p-((hՙzzzV2FLYYYYYYȨ)VXqy77+W'$$]*׏=:qD v Z*((DGG?Ki`` z۷.]rX;v,]tƌs̩7jredWW׳g߿?88<>>~ɒ%T'O14.jUnh̙r''gϞ0dȐ[$)J_rǢEEEE7nٳn5 ^xqҤI|Hj0<|&> `ٶ6Cq8=zPïF[ݻ7$$Ӄ_xd2SRRߢ?ޣGђ}QY]4[l2e/rԮGCoXXg-/cǎmzpRZu> X;a̛7oDG%%%^^^PZZhr{xx\|ȑ#$I.YDII&L0|''Z{IrwwOHHsqq/<P j5WH*2!"1!;;'@ `0'?x`ٍ0 ;}AƇ &pٸjF۵kW@@ʎ1}6lв|J!E^$?>,**$p+++)) 39!1YYYɑ${펶{666 CRa}0ɞ-h M5&?CEBR·IY[l+++EK>}ȈdPQ:uJKKKFF޾VWǎZlܸ*\z3$I~7!!!uBa|XI',)**rpp twwf֞{nzzp_ رc:㓑f͊6y٫Wf͚B6ah|&>^>>U]]y<ñڵ+Ҿ}?p?^4&r~ZTT=ztʔ)x!jc89ćkl ?OjIjjjΝ;r䈦իWL&Rݵ焭u嬬w),hf:}4?~ C!p>s`lda5&]YY͛76o蘝MTw9a+1Q&رc\ߟVK.5˗l6[4j055ٳn崴4FpY\]]cccl(YLPP|&/ :N,I'Mt̙B X,,RݵD6ҥKSkH"&&&&&&RWk9&}ٺu5kE,,,<==V^v+Zh~/_˦JLL|eTTr̙3+**._,YYYy1 !Z :N,}0aBfff5僂V^!oQkYZZ:[[KWWZWZK45|<$p8bZXbnnn$ILJ]O׏==l4?Btt<,T*SLxxٳUufccs a7n!#BKΡ3Ƈ5)^~}KFFF9 ׯ_Ϝ9S-//FFFvM'l>|(,,\lٕ+W\pg55AO0QoFOYOOOJJW^{N9~]5kikkm~q[[[j|D*%i4څ d2###ɓ'׺^gx.(L.]ҙ3glmmCk~m֚n_ⱲEjjZIMMgj!$ɕt$|N_[|Xky`$i(Mx>z۷o7mMCرcӦM'N3gNoܸaaa!Z҂D*ٹPC qF&l;]B4Y̤Iϝ;ϟo#>SG{)ÇqO[ܛ|EΎ?/_8-LJLמw^.]8$ICiJۻw},--֯_+ &RUUUoϟCTjٰakIIpP[*5zS={fhhxN> IDATϟ7=sL['M'B#ć 0}K 4mqoJJ+/jhjjH$a-+''4%⥤5Jx󠗗pڵk~zAAO?ToZqf-HR@4 wQCX2x$FCd1ͻ~z~~3gMkZ#J:|En~q֣EWR? 9tXmUU B;a3=!`Ǯ=xQHjpsGѺu97HL1ccc PXXnݺ#G߻wns99Z)ZHYRpk|}}œd1ڿ%j=a>Ĥ_5G],+/QE+Ç'~;t`B௿uFu_(=x0a;1\_gLoݙ>'C*׉pDRo1ϟsess#G$d%%%ooo0a󝜜D/2RzIjY"Fs8uuuժ###njcmmZWNE`Cbty6mDnjB#̇iqcG_ 11L UVVv'殷Z}}{_ #ϭq֣5FzMkMY){p)ûv҉>&C6*׉MS"iӴ-[{رȰ0P`` AV*..NeTgiiY7qF-QQQ;wtqqy?(:W,ѱxƌRRRx!J:HcDG$I?ǍEɢ]_yF{ CL4mxko צL\h|&> ^cW9ׯ_ٻlYWEӠX۷o߾Xj޼y% ͚5WX׻;&W^M"ftegg(wu}\·Po<{kKJ YYJo= j))oobމ' ɡs0:!C0/^V޿ٳg7Z\:|F7vOQRR} #--eb=A6`3;'N̽=o¨wOu5UmM`0:]n5aJ@ snt=:k.*X4j߾}6l<'q֩i.JRn񖓓6q@e`ӜYwMrhF-'˟MDØ#<6jD֍i zŎFWC#IʼnTecc3`<Iv{>`h9(** N_7qߝj+| ԷqCN1u|XFƨꚸzkt=:&33N?Bt++N97sF\>*!駟(-^~P0]e$]vu]JJĉx!P5 3dee&w9DØ0`BEGI*w($lnndIO<166.++!ʞݻk׮P33gϞս!!Dw>J|/^k-3W; U|Et^ jnVXmӳgZniicZe\]]w ;w.3F!I|c5qPy?vF h4h j%SJd޽RCURSSyBu:_I|X^aO[[t5'RK /_ WA_O߿޼*.]j˗/lvHH$55ٳn崴4 Np[\]]ccc[ AhެhMtD[S-//_rPWWwqq)((էg^|_zFj0zS[&,[n]f v@ Xhgk׮]b=4e˗/o\LѥcbbZZǭn/^Ó'O})))ӦMѣ_zG=׮]-QF}!jˏI? Ѧà{ƭ[3//o۶mѥmddєUH\paAAСC}}}@)+++++ 61ʊ+Ο?vʕ;~ѣG'N=l4cBttpY[[>}zРAӋ/>ʕ+JhgϞ*8qBSS3++KKKKXgĈ4޽{Ԥ׵k-Zt)d2={VQQ㰶8aA!𐶆6 j i`06o޼yfaɜ9s@d<(ޥK&O,;w>Hرc>>>)))K,ٲeKSNݻwٳ'++K__ӓF1p;vjkkm~q[[[j|dll|ɕ+W8p@tLR WΟ?C;wN>&O/ɓ'3V:3f._@dd}saǭGDDQin444~())QǏ?x`ذaݺuJ ݯ\"--={@6M3gάYm͚5yyy&&&@mǁ3DNH$>YֺKu=>~ٻt5DImM6ED(FQ)R(ݕJV7V*!k}vbZեtCQiYg6fyf93Ϝs/,..%Jzxxܺu޽{/vuu\+>>رc'O3f̝;w<<<ڰ:::QQQ˗/~v.Y\b]]]ϟ?rGlA͜93,,%[l\n"-ȈdSy֭[ǎ[n]o6{1ٳg/\}?~-vAƍ&M077z*6333޽o߾R{S!;k,aw<|X9""_YXX,ZNP(t:=<<\UUܼ}Z566ppp7[mIITYYYGG/cKbcc)S9r$33="(**z +ѩ㹒ltVXXaÆb=~A / ;;4F5kV9?apn]`AMMMnn՝;w&Ms߽{wڵ#,--^oB_|r\\ޔ)SˆWHV\ֶj}:{l@ׇI V{ Ї؟|ltttmm-ͮ /@ N&&&ӧOVYYܹswUSStڵ7n444܌]&}ƆG=!wsGxɌ3RSSKKKn``] 4SVV~W/_<==`W{qf_~B"&Om۶ׯ_z5<<_366p8w޽y&6t_UUU-GbUtuu_xq) 쎀@͇C\&a}X;b@L˗k׮MNN驩BRRR|PSSSTTjlltvv133KJJ.//?=z=5=y {;  Fhhhrr2J511z̙׮][xq/ZoeX΅x bqlddtСYfasWƍ TUUFؠɓ'Xr|+ 쎀̇ B?LuH^z؈]jii6gnnnmm+WO~ biiDR1ƍb[܊t 6qB3j * &ann>o<└.W?v mڴiā#x nVIIi˗/?w\IIIvv6J;w:w/^433J,--/^M|bY7n|N߹s'ϕy8Ab|YQF،?^[[Դx([tƍBCCO:"iooߺuk&&&ĨW!GGGsssccc---b^CӍgtAѢ]\\*++x>+V(}to6bkk_/YDIIٳ<[]a!bĊaÆϝ;7$$///{paq}&U y&B,׍%K8 A}T<D@Q>Wsss!1'0o_XXW_}kdX ήnذap24`>L, p~I~w`0*yyy'ND=IǝSOEEŋ'NPWWZ[[oݺfb.^9#H<A<|L&'$$% WUUYYY WpLѮofo~0z U\p'eddd=%.//f0X&*&L ۾}6^n;vS}||lrʼkG;KԉE0zXBfMMM===555mѣGvI 0B \~}VVVRR҃ >y$??̙3c!`]]Ç_~( OeeeOWMUva>L߯7__7o466nܸ1++L&S(ˆ ɓ'+VS3HJF---=~CadJJ}8gO%Ŵ4 !C566 CuItҥYfIII3&##+|eϳX-߶m_c#S̯z t՞0-0 )|%;vɓtNTTT@@ VZų͛7eBB•+W~jWW^0222..˗/vqq gΜynSP䈈]]ݨyhͅ?~WĂƘ1_ΘӧM{[!XI!:tPllo||H QYYܹs(wڅQ]v-11ƍ AAA<777B K쁾>ƆG=!w 88LdƌÇ700HNNfWH${{ӧOK Xhjnnhllhloh,Ql\? OϦprޠY\b'K9t7v&%4/.ۿ]83uu/ yӒ~{Zdmya+%k?\x7/? |"%%\<]MMMQQB,)))"""''|=z=V}5=ySd[[v/'2d*jbb".Mh46maa +biyvԂW,_tt.m'}3jB֭MgzJJ#6wdiiz ![v}^nW#LMfٜ?#.ӮΚ9C]MU&0А㏿_>R^^N|3HXNNN:::wqqR!KKK'''*ZPP0tPbqUWWO2/qss;|pGGM|qB ތd^t)..ݽ8vjjjzxxY p녳c|t=pvK~AT8x7g!$H.1MͯBZZS-M͆|kn2x7HDu0u )dCCCI$ҥK뵵vuԩ?SVV,&&fĉ[noĄN/Y/qtt477oiiJLL$n̯|^:nllWF޴itv pi244 +~W D:~YzEDaB쏑|={**[gGk#j=SR'8袅 <-]]|CJ\Kr<|'dddW[[YQQg)))GGiӦ >ٳg#{{,b_|֖1rH؄;/իW bmmZJ DL:K +q$-%XGUsW:aP(&Cã2J<9344P640$b5o4PäEng|o̙%%%/~ݻGvDK0ޞGτ0biVWj*+/YD,]FZZzw7`$Bk#˖~7b>D"1 Pfwtt`x#BDDڿdd̙{!C>''Ȉx$`0).KPZZzƭxĈcxڸðLp}أG}X011p8w鋷4iR_SSz%%b "3_m=ɓtcH$ȑ#a]SΠ ii)S%Po!,B&}X/(+9 IDATDWFS~)>>~$ WUUYYY Wp~}X__驡!))G '//wݿ_.6_!N֯_u!CL6p׮]K< IQQ_!w.<xb/^*//f0 L0!,,lVVVl6{ݺuFFF^^^رcn3#rʼOu3c]]̙3>SYY5}w*++Ottt8N]]]JJInn7|#' +.. 1I&ݻwK<kGSSSOOOMM sMIIIII m'oogee%%%=x𠨨'OϜ91=62ï_w}}sNmm7n` ,X`aa{Outt}off&))k.le'3}?l`ևu QRR200000iժU,߾}Ez Y |N:RVV6bww`aNϞ=3fDLII100 JJJ9vikkkl|%~8{-[C@~=$ HyyyZZZ˖-Cؤv;{AEEb&yYFL$--`kkWVV][eF##644eeeʮ\2&&L&X={ϯ^211?~|]XlllDDDssG}oߺ>Lv󁘈)''gС aCPtzxxB۷N!TRR"%%UVVcKbcc)S9r$33=EGGЪlVXXaÆb!w 6)|3_|r\\ޔ)S°˻?޽{ƌsA*s׮]X`g???UUU, >As0d  *((pvv/% ʵkoܸAR¸777c p[ڡC<ø((( \Daʌ3f̘QWWc``?;;;kii盙˓z g 6x!TSS7w#]Ff!ޗX܋9g_'ȅxڵktzjjSilltvv133KJJ.//%GX4QF<궶6xJ0];T*Ą+L&^d2W^/A>>Ç-,,dee31B\EE!RQQ644xzzb!fy,mw#W^566bⶴt{I [[[{ʕӧ8qḻ+**#,--T*"#fܸq77":bcccL=!B ތdfddϛ7OEE8%%˕SPDDDUUܹs333~o8])o9;;/{E)((X[[oܸѣGt:}Νؽk֬ٱcG^^^UU֭[sssdaBo޼;ыn[] S0uͨQmll---MMMyS9uTFFƟ)++m3qĭ[9:dܼ*111 ytqh4ZttM숷Cvr@77Z55%K?<Q.GL&gggÒ7l`hh(## noo_`Akkqzz:DRWW ޼ywܹtRϖևnR'h"B {f\Ѹ|Z%ݝ͌T<D@Q>Wssst:o0Oa޼ye^<1L/!;&,.߱n|ԷbA{{;ŋZ@̜9SRR/~ݻDpA.`}Xonٲ˻"81qI @"ߏ3gN_Kllݻ ?>~]&`3Y+aÆg~K.=1qI`bb"//pܹoaee5iҤ~D}A@,s0糳N:s挺g444zNIe2P%I$GgZ7sСϟO2eͫWp8Rl_;9bRSSjjj[NFG|m@LOO/++SSS۳gO8')v`). ,GM;ۡC᪪@??޵/ipǎ;wȑ#[XX(:1tަ&777e /I"Y":)5JӺ,\P]]244w hGp2 jjjrssܹ3i$<Ԑ02NEP _$tLqu8q"1w/i0_p႓ɓ'Om۶7n̟?{ԨQV@ϫrsر۶mstt`` T~ɏ$8wL55ON-ǯ}H3ϐrvv&^Ė|X,a mmmuVSSS``5kǀ0)̖&(MKƌںk} =NBט pxbE.ĕ+Ԁ"u֬/^\~KZgABSRRZ|ϝ;WRRMRΝ.:q ˹s…Νklllooy~[QQ ! ?ؼ>}#G?lm}!=?|N%)SGbj/A_w!*>>߮]8ڵkf͚JRBRk_;H4s)))ϟ?1bTooodz(3~*((m۶ӧGNMM+ȏ?޵KJZ`Llv&il| ͥ]C߼Y|{cO-]`X8^ rs}Xgxq#/_.^8f??pWK###o߾} ,rrrQQQQQQ/NP cs~==|mmB${￿XXo}}&MR3fKX>mzCS_[ɰlsahևs|*ZRRb W^=gK TƍS:{۷_ 2*;sۦYOlھ}gc#qQSiiIa:AD\&Xm,r;os"#??6ss/_jhh899s]Ҏ|^a\z\ZZיm'bc*HvttrWWU`jk[ӏ̘9ɓMii%y/k&?~rq-9w{nm=.7xa~e555RRR؎|^p8gϖ,_>ARRbSR NwÆ)#G`6^r5k.~ِV}V_}}R%˗O H˖M8w!AQ? $ٳ%99kIHn( 䒓ۗsNh\ySӥ.ϼIS:q?Hj /b@4 >nH,(}M\ujj!ĞD"[75d#^-;~'&UZZf4=*˷#`&?>KaF= l9{r-72~`nVR3W~[[Y=wdvݧHK+ٴi`f~eE|*`zn̙ѩ>}ݻwz葾~X~`PήVVjll'xύܹS[[ƍ! XXX޽;)) !B*~Dfjd={Fa0t@@m\\\YYq{:ydBimm Ϟ=e˖&kkD%%%|cu 90 jocvE$D"& &!!g|͔)S9hKr8R }X7F%''ߥ+++))EEEE=<Kf̘ZZZ:|p~F޽{XaÆ?/;;6[l)((زe  jz4ea` /5Af-,,Fggg33 #44499JC7ۙ3g7ݴiUaևEyyy)Vhhhfl=qwwWTTGYZZ:99QTLfFFyTTTSRRƎ hllD)++z{{1={,^6.--dݻNḊa}=bmmOb={:uTFFFrr,VsMFEGGTVV ڧ ڹs'QԩSC 1cԩS544~.$$$0pǏGFFr ? a@4 02uԉ'bO >\@y|tO2 H74N|y%qwwwww`7oḊX@X,Vkkkbb"qi|ɸAȯ#>ķ2ύM} .}:t(Bt `>L<ևIÐz%`LFt)TTT+255WRRQt z:CA&vԏxFץpԨQ"Ţ[$iȑ AXa%?sѣGKKK?СC;t)===)))ee={^ti֬YRRRcƌ@uvvihhHKKO2;Zl+-p8FFFgΜևZ#a/_e||cNJJ݂ÇG}D(>$ xIEEB9x(wd ϗaA,և 377ʕ+ӧO?qDZp8^jllܵkBEJoݺ5##XqssۺukVV֋/_ba„ aaa۷oFuyyyf7X,g1l62 CC}F?44D"-]^[[ͭGcQFHKK[ZZ677zIݻzux׮]gڵ f RpZ oogee%%%=x𠨨pQ=<{l'''8=M0&?~ e555\DOOO<}41koܸijxɌ3RSSKKKn``ǏTWW寭%mٲ`˖-ab?LX$]hl6+llltvv133KJJᮋR!2d*jbb֓'O޼y3m4555SSSl >88vӦM¬  aRև!HAp\yrS,Ǽǚ5k9KfaiiDR ʯq&yҥRwwb~ѼDJJJ`[Ώ?ŷp8...vvvQQQ3fػwo@@ _RIϞ=WD:u*###99YVV+iooߺui4ZttKee} ;wvQ &!!`?~<222??D C?$χ1UQQ:u*{ѱzÇ?{Aŋ(-ޫfcwwwwww챁10@&6`jmmMLL$.iiiQ`ЃAXa= ?vbZ&=w6p$2c999CP(;n/)&>L?֭KϾz>sfXa>>7+1ejjZ__4aDaAL&Y0¾srwT۸i E=D9r䀏~DabA, 9&--lل?ˍ32&%2lȑrέxvWSO\5~ 27w_Qy2}G,uAAfد-[*+LG6mp-//k|Pk.iUB˗O(-dkjN`>L, aZZÆ *,#vtt6B%'ێA2%"uΜ/jclڨQ/=j:ypR}iiIرӧk;Vrwv$GG 2wǎYX#;wuɓB^\*CNZ֏[^KHX8WB0 ð1&x7@^pǕ:ݷW 5,,ȑÇB4c ҼycBׯ?zڴiWW?{ԩݧafKqu.o-LiiIIIDkkǹs 7o @H0&:~Y; Fݽo,%?XcǍ'O'O(f q߳JVxGG;n`cǎOcʣG|H&𒊊 rAQ$___8%S0 <~Ν"#c7G,y4ÇƏW2E=<|E[ͭinnKL\RdvbǏOVfiRR/˫&() !:::߽ʢe„ aaa۷oFuyyyf7X,) ѣG6opS>L< aͳg۷oŋ+e**s^uvLL\XPyT n>7kvQPJJAJJ`۶m!c``qF777IIɔ$MMMM=x𠢢FJJaeeUYYYZZg ɓ'2dSDDDDLW^upp(**RWWϟ?~^^޸q$@0%螽=FrZ>~{IGG'*** `VG4P੺c%%%gΜIKK U\\\޽{GR80D / Ǜ6m FC{l'''8=M>LΝ;bGrիWǍ÷IHH`0222Ǐχs@Oqe$EHEEeԩ'NĞ::::::7>|gϺ-^xץqS33<qwwwww`7oḊB0X?WXDk`>L,ׇ a$^B}^'p8vvv2221lv{; 999CP(;ṅ0th4.>>>=}ߊ=p} SSz%% "/0F3QFEDD}GsC"F s}$8p`Ǐ?tPɓ'#@ vvv򊊊5D H$O?)//,''GԩSzzzRRR{v6ZZZG abaC]|ߖǎ;ydeee@@dd$q#Z[[t:ƍ>~Bݻw۷o߻wرcAAA/^,**8Sl<8~*+++ sB<X `~~i̘1]U ĂX#NNNW\>}'m`mmqG;wzzq׮][ٹps566;&L}j^n4`<|vvvwWرc'۹2 ABzK}}}7oiø8(^z)NinnΆ `>L,e>J".]Z__憍INNްaCHHHwԨQ666͚zzzjjj߿WPP۶mӧOG\~}VVVRR҃xΆ?~\]]~^ɓ'5OIIIII >GTWWwׯ_>U/͛7/==}ԩثiVV8Qa}ćad$5H.Lr8{6222쬨سgZ!eeϿ{իW&MO=}Mccƍd2Ba0߿Ƕ﫪:;;ML}ڵ7n444k`aC 1 <Yo׮]555+V]ֆu5.ìd*jbb O3gvttdgg_v @|xatQ^^^JjjjzxxYḻ+**#,--TjKKKߚ_Yf1bÆ =l\Z-:~#[:o…;n8,TͭN9 ޥ ۰L&3##|޼y***)))]~$Ҥ۴iPX0&`}]Y[[wkA.M:99aN?eee'nݺ׉Optt uqq֜9sH$%bȑ_:w &&&t:}ɒ%xyKKUbb/ Ys<,xtccn$hM6qY?+V:tg8Ḋ0OכTH_ AݛK8pF\_q GPGO?tosss{KKKEa޼y΂7c2}7@3+C?a@ֻ_%WQ!6%g,=11mP~3gJJJtY.:^~}ݣGv% yq+C/)CR>133322")9HGFF?~\NNnΜ9ݻw2FzD@ SSz%%OZ[s8mm;wZ&M"`tD"9rɓ'C_0~+C#?a 80 jocvjF`=A5AH$<]`>$ xIEEB9x w8s{ K8;߇#vw3n8))C.X޽{p?C1/ @L0!,,lXfF6n:###nh4x۷>2`… gΜY̙3>>>YYYZZZ&&&pR?C1 : $흙~ob?gjJiS )E$%D\"[B!ܯk$.Kv7ʒBW*eia40s>ϙs^sιЇ>yD---744|Q'(ŗPӦMݻA߿/zvx=***֬Ysq|QA> ϟ?rHP(l׮s9RNNn߾}7o\f… ?[r"bXǏ777g:UB_~i޼ŶmۄBçLSGurJ+}޽իH hkkӇxԨQ'O2{>?/;_("={v۶mNZ鴟P(ܽ{w@@ذaMF0􌌌,**"Ǐ|ӓ|ӦM+W0`1c!333=====ٳgӧOoժ ׭[?Qpp޽{<+W._|ƍƍ?.NBBݻw'M$^ı|%"ziyy[JJJ_5d) r[hiӦl)CJY(6믿^r⣤[TMFG,H֥K==QFp®].]vZ5ʼnTXXX^'$$+""68jԨpWW׃nܸR j۶իW\ѧOnPΐ'dgggggyٳgĉ_3?>eʔ͛73%FFFݺubII2iߐ{B]#c%+cR"*ίB‚Bph V6v諸3xQB|{mK6ݕ|wKB3x7dϗ G~ CȇȆx>ambC> - IDAT;B> @& d0@> @& à(ܧ1wjirBp¥QWoܿN +*(`ECu=e[Ч;a;6}it9grIn%40#݋ޤw1\OO_oZ|Vy9 P~v7χ+O<Zm/]6ڽw߬nѲG~C΀>?/YPH_];qКUwwDt(歔:'I.]ݾW- ݛ44f`CH PCb0|8\ 4\)goE)^~sEffm,̚~E`S'hkiׇMBD%R+NѤ3 ee#fhkkQI)u55I^XPҿzaШijhhkiIԄyKD͚}736 LDlk)tu&l6ysSS]? @6ND))͛QJjW)t9WDoB H?QͿz aբ!`gq[-uNPXPPe[0 B棼|En^+Ղ|@5]I&G4ŷkN3՝:555fY6d^n&M++/533u +.uaf*deLDq |>_4 wە.nˣ'9o~|I%1rm<E`ux$4fص`!? @6d0@> @6à1 C#@$9-"|+FF}°E6 03顾Cy)736vl)h+P6ilua2|la<4X 3."*ILLTQQٺu+b(00%ə3g*(^a77L,M6k׮]parr2 ɓ'Ϛ5 )S"##(#'''f7o|ɓ'l6-譥eѹsgӧϝ;|g̟??999""BagΜ9}t99}o~͚56m 566FsISȑ#׬Y\$Ǐ{xxss0􌌌,**"Ǐ|ӓ|ӦM+W0`1cVP|xʪ#ۗ3&\2tPכC@> @.]1!:TCCCill,IHH(++C[A|^ibbDٽ{wqsb0(E7 #QQQqQх vuҥ,Ե}utttTܑ#GFDDB$V ͡6pD06y%|˒bKŅ)|ĉ/^x-2ѭ[ׯ_pkP<_zJ-+0[[[cccs8" 3f\|9N0+&&FUU@/MN>K.<_@[F̥ɀ &0:~;w͛7mv޼ywF30Fm۶'qsh\|I:wܶm[qƍ'>zjj*aiiY?5@%~0$vO|=? 3nݺ~|c}rttbn   F;@7s4@|IzOC9}4vOc>F;@}c|4f;q/l|4f8 Cȇa2|l  ȇa SPH:vُ@W ђ}_hB!@ 60""n+|gȇa!ca\.aX_T^U}\"|>eINy3uwti߱{awPXZV&s|||U|:¾~W}|9DԻw;v|ߪ@&ċ񈏎4icr쭛77i¸}mg#urX_ŋJJɸjjj.^EE[ǎhR &p~=|c>K\b஝;m\K玖-zHJ7Jb|8\.z_5aK'.}{~7CD9s,leͺKֶQWo0Ŧc]EDsrzQ=cw&"Px~m:9 yp8sk[K {cu֛:Qbb}uT(/͛7ضm=ϟ?rHѐڵ 9۷o޽{/_R:~y.se*<tR===EEž}xhҤ蒥xmIeee"z9cǎr)kKx]SU;wȇAQZZjaRP^^TAA/8?l  wo˗.u޹wh+QL%9͓φ&c8y&ps'gL޾s}Jv7k=@Dbʫ3 ihΒݻ_^r7n(322?~KOOOWW1cx{{{yy/Z^׭[?|:!!!gϞyfrr)S藮[o߿=zԩS!B0'Oٳ_~yM;6ׯ߱c֭[+V^D!?~ԩx]]ѣG:'NyK]bŊOlK3O>Dm۶ RfͪHiz 0hԄ%~ZXXxK3ksEN2ѲZSC ȱ@ ;<߽><; $cǙJO8@_Ҥ9$,m۶oޣG##cOuEOO/22<8tP "ڸqWڷo?a„VlٲѣG|:۷oԩݻO:UPPPDķDvZkkk55 &I\K3g-[tSjUN:44t&&&Cъo gϞuۛmݺ˫ҍdΜ9dii٩Sk9rӒؼy3mٲԩS˥T/Dz;oȇAcExayy1D%f͌fYY ly گυ BsÇ2))}m[gc>2558c5E޽{>ZtiJJSQQQq)WVV;wnLLܹsEU)UYXXT5[f^XYY &*#oy]դk|⯥2oڊl߾[CbEGGϯ!Aff&hтyۢEONKr8˗/g̘1gRf J@|4f N{~M\%5E:--۷o ?JIIy̵H@"^zСg.//lUR7L>tuuH[MIx~<66Vb !|}}KJ!:::D2o_z'~-2l0浜Wjjr)kfU}e%^C> ;3?o;_L8::***=oJJJ~ekʒֶZSUk݇1I":mc=zۣNY(yyL`&L{gv;>>>Ǐg\(z{{{xx[U1<>cOے>,..f^zwRʥ&U}i%ozϗݛ=waI pℱ'g>]z5Gw4鵱YAnv:EI"=svb͙8''@_oaS4S_nTs"ݲ-:5|LӧW=0׶D9#G(((߿[nҥgb,Y]KKy;nܸ>} 8p׮]UM[PcKKKZ,^l֬Y޽СCU?Ml3l0`@aaa="""X,V_Mfkk0v5kH_zKoذaĉD4gΜ}I)TUJX>W 1׸ΠJS(]/* E45 wر{}9jNji5b_dUXe&U}KJx'iiqȇ41>p׮]# iX}P t-UUUؑ+++;OON27@=|@UӘ; lI333j&&&;6*hIzL,x0"<!bDnp\s0(F*F@ckaqģ0y%|.a Ә;a h0 gd0@> @F d0)($ P;w7ȇ+xvȇ4`xVt2"a2|l  #ȇaYZXgBayyBͦ% -\uF̤O8fff8!@;6UgȤɃyGΩo/]x0"262>'Ddhh6ɇ?øeyC~YD46[O^Dԥ[ofk[K {Μ0ӦcN;B?"G vqug]]BMLLx9%&øAc2x?"`?е <oɲU4"wh{͚6Nne^:Ґн&DTՈ?px҅ϟ>e]Q44f`w\.0h 15mi'0uVC8){"Ҳ#L5r 􈨤W+++KБE rt "3-ZE]M{V@}|ijhhkiI:Lz:`Ê[b$kjj¼PTPrي6ռͪ155e sۖ-ͱ? *99!8;9۰P0ly|e@-s9FUbV-IX# ÐFMjjbb?" +sqϦ|>?4lh|‚ܼ-ۂٖ8rߙYo],25hJ%OcGx5V0۱Ys33Snݨ4l9 8&Lvx( `~ﴥQrsl BD C> n9jkV-߹ʼ>}XUzOxz|Z(GzSS'1ofdh(p0:A}d¿***⟿ؾ3m`4 @"v0<_6eRii䩾9:CB$@KHE ^0o6@C|d`@dCaȇ4(Oc>F;Yȇ4L;w8&  d0@> @F d0@> @Fm)h  0hlːd0@> @6d0@> @6àKNyu[w G =ɋfy 5§1w|scff߹etaИguUUGn\XX4oɢRlldTPMo4lȇAm{pΝ6_bȲUӧNRVg獍>=礩1wF2ux>1#>M Ͽx9j1LWҷGp8D;wN]֬XZV cmku Sl:v?pإQD4gO+W3{gn" 7ݦې BK {cu֛:Ts>dYUo3g/ rؽ뎠Pfۃt{ڬdѸzxzt~j@#7/==¢x<-[_qdخ?u8hߖ/]x=s^+`7W|>%y0Dt,'twڻ SfpQLyuFtq󴶵vVU .LNne^:ҐнDQ;l:s򘦦ƂD ]ydx&D4g|:uDD1bocO@wD@_lq6D4h`cǙ){"$IWgObjLVUUfR?Cz(++gҬhGD%%<"ğ nޚ,wyPT2{֌-͉h萁{٨jݱkfào<2 ۵}T^^>{,CC}"jC򽙱qVfh0#C \pGwӑbSS&zO]CSS\QHSCC[K:m"~l6y&3>P?v>L̜1*à FAAqϯmzѹk7⟿la\IKD))T--MѸ,ph>T\\ԫS}F혷 >픈(_DJi+"lm!Ξ &-s+'77(8lYU5٨N:0hfϸKD2!=Nj{|wK/ la2|l  ȇa2|l  ȇa2|l  ȇ|'A!ah:hgG24a5^Ocrȇ|OBPwLȇa|4j j0 aO3R$[ZXgbbaG?}☙WuX>-ʇqhhDU2VͧOo־a~3|Z'&&ՠ/K\f'l0Ok[{m҅ף;.]ݾW- ݛ!鳡[~5&t,'twڻ=G1}]{..^bt%__g$vo޺Ы_ff=%)9Eww ;gdO'Nv6պ/S/\642ڥc之}tra.&!Rg/f>=?"R]$6lphƆy 8AD.]abpx9&_~}B###CCM6~ΝD ֽ{l,@,K(:aʰoi3M2ѲyۡD~dIf\ [0'"KF_PP"w`CDOKK?~\ .Z07gqmX݉Z|tG鳸~<`?е ~ɲU4) Ⱦ.XCw>Xdńct՗{:`,kˬ9 ߿=062{y<މ1]1?!{Ws[SeE?_Qzcwq˄}/Yz]rJ"jҤIll,DI2]]]PO? 0@W0"YCf^(*(?5q=pRUf?d͚Qn^))}DgݶnNx.1,,Zb5$lW[6D2z>Zy;n֭Z 8~9t1svr?WzcZҼ~<ش*J:_묊J"262z>;/?S]M{W׾P(7ogݻgee|r"bٟ>9NgsTfvvG[g?^JJnanFDl.m߲Ѧ};mFƻ¢3>ULaB+K7g+Q\$ӭ_"f5onZT׸ѫ6E++)s]O킄5D4ǩ.32559hҼ!G?y(+KG}z#Cb{#^_D헍:v&f~a+1'Ż5??^GG~g77hiiQVV>eff2@wŪ {ZԟL ‚ܼ$bѴmZx~9|u~()O@s^ccø+V2xH ?oQTTnEX Mܺ}gEnC9N &- VjoM#>G;gIUBCJ5+)qʪy#NOOW⡋t2n”ko ]DI'tϿ~lEvv]txR"RV6'1+0Q]]Ν;DݱcGl)/ 3|U*rUMM >sp8_=M4̧CM2s-4Ӷkμ99zF#*/ Ovve9f,Zk!aX\۶Ԩf~~.3nrh>_4Q*۱ HNN\ß=z45ۀ~{jg]9|[4lmerTEI6V_:KR]$6&ŲlJ_Owͺ #"gkWv`SVZ&//U$tee%-gs~?~Ɨ& NXXXpQF1M<߿C۶m –ReKcIrdff*z=KwyG>F7s_LAп_߃ǎUnɓg^z)p?vDYS^0wV=6[k;e9`OGiodd(~F__3gϟ<~D(._,iKK9Ts8Yqϳ*}KVw6t r]׈g[HqiYqȇAcgۃvm\ڬ˄ uؿ۴f}% e5r! ?}zR\ ;4IM2tT]]ݾZ8}׭@Ø?Na}gr:1{"V.a_~@@MuS:#]hدa~fթfjC7WWST{tXYdXudf!d0iBDNvF#8 ʐ d0@> @F d0@> @Fm)h  0hːd0@> @6daOcRJ> 7ZɇL! Laa|L  ȇa|L  ȇa|L<Ʈ zsYi{,r#K|U>,Qtl0F"7a|Laa|L  #VrrrFFN***_TP(rrrXmP|>?_(q&p/_{JT\f=fz_7[}@İ!ޓl6Yڟ>q̴nGK>glmm"0??.eկ$7/gL u͂ѣ01iԉ<ȵ`<]zJiڦ ]iiI]^ش^v]nޠӭ; ͬ7+L,þNiI^AL̡Wՠ6/ TǫGj[^PVҷׯ4򖔔9ғfЯ mܵsWwѲ˖,~򴨨XUUuѿ&F߻DYsm,#~?IDs|''"w99V-3,B\wt6;TU?4x Ocɱ2"b͞c`h\Zu҉_*:Ɍ~ğ͌vX_v%/^5mΦcߍ>$7'+'78ߺ}+mnj˱XU7nׇy{4x;6mXՑ/G{'meٚ:`Í+(puYOQA.\}ghJri=%"Pۡxild?)>o;?G$,.)ʒ46..#[zx!EEFD ԥ[Jr=;u~l!+:b?G_clY1u>ٻMǮ$(u[[@x֝[7475Ҍ}ucǎt]Zoaz&o߽2]ʥz+y2Ɩ/3knr%9^'驡~,C=*]hzo޿pIqA- ? -["/,?A|/Yz]1%706޳}Gx7/==~ͭMꪊvcb5uBNA&Jrgc=WVV:)sX}}r^]NO<3fpөO90/u 31i6uܹ ubhO'YTIDM5LM **߱X/LML dg֋]Inn޻wwxZKSÑ3=_ٳX-#D:)͖{"E s5 f]g ]|"336VsfM?{"s:M TTT(++|**M?FWWg'y ?^rT[r> B?9ØDoh`l@׻'&jT֦\  SR#f-^xZZZ*ihe%^VFj~^NUkjf{P XYY٫ז-275nk;ɹ0?ݻkjl\yŋ JŮ"ڱc޽qcffeOKy%JBPHl6[NrXe eB°# r**OtuHF\^^>{,{LIvN.5k8+34CG׮dҬُ^? rs%䔉>b~}YKa͌toݼnl2c.3sy99%l:w nZ(jSRQf滲24QV,vi)J_^A6@Wu8TRRTRR$(/%"uMuuIm eaK˻ux[_v%/^$8;;9y,[+ve<"%"UUU&Diy^X?ĩ36 ԩS״Iugy䝝ۖv#EijQJJj&DID%JJ=;|g-뢣}F>ۻ¢[ Y=_R( JDdٺձc{tWdfeE]ʲ]s%6--]NN"'=B&ǎf׹N6mTŦ逿P زe?j 31h2޽344\Ӷkμ99zFc-.wxto=}w%%l/M;+~|yYiNvfֻZv릫g,PVV/a(s g*q}z祢& rޥtrUՏ?O ñigץBE ?MRXu駣g( ߥQmDE5@еKAT_v%=  YaQ1h޼\A~nW0JJJLL?tM?zsyusqsVP^^~v'}]/ Œd&b/.7;37;SD H,^I\U@'2&g zVԗ{1Kף]Iڛן}˼y.OX(Z VvZR\T+雓U> yȨ"i's풛J|{c@mjx{ ;b{Qa~r"3gX+)7Vv>gw[;)|zw@ lم}oܧeEϟӀ.sK<7·2Ѩv@*^!D<8D.q,8%.q9ajKG!>x_p |2XF]|T #~ C|*z>^:a3gLqxD<">a|sp/Enl0""<q-oa %eW'x<@-vxWk#>:b 9c y<>G|p9pp0t>8\qsIDATN#yCyȇn'ɇG|@v>xD|~ .Lf'(x|"" .MD\gj3ݛ-5_LerNX[^nV"0Dy* image/svg+xml elyxer-1.2.5/forks/jras-elyxer/docs/svg/svg-test.html0000644000175000017500000000331712117061342022120 0ustar chennochenno SVG Test

SVG Test

1: Object with size. Object with size information equal to the SVG.
2: Object with half size. Object with size information half the SVG.
3: Object without size. Object without size information.
4: Img with size Img with size information equal to the SVG.
5: Img with half size Img with size information half the SVG.
6: Img without size Img without size information.
elyxer-1.2.5/forks/jras-elyxer/docs/elyxer.svg0000644000175000017500000015524512117061342020720 0ustar chennochenno image/svg+xml elyxer-1.2.5/forks/jras-elyxer/docs/parse tree.png0000644000175000017500000002715512117061342021425 0ustar chennochennoPNG  IHDR|bKGD1 pHYsdd vpAgH-HIDATxytT>gXBdYBdY"b~Q[l%AAYde)* 7ܭV~T Uhay<;mrCf3's޹Nfy]=vDDD$(<# """ƒ8 """(<# """ƒ8 """(<# """ƒ8 """Tr"ΝΜq.ƒ؂@Ӧn$nۥQxڴq$/;<# """ƒ8 """(<# """ƒ8y$f֮q$Ĺs]  E p119@R%'ƌq"l!"""(<# """ƒb|./\_r""RuWt{?/Ӂ-c~""IA\ \M]*) 5[H8fM`=~ ԭ H<o۬p"'#HI㱯gd V>2 u L6oON45v,sCɓOK6liS`l^z0k,Ã ej|9~=PWb {ogxK,ee,`0YY@n1 .а!֬a?ΙMss  7+V|ݻ:zzzn//YL P׬]"!ψ؂dfNc {'V۽/*3goOO>q殻Q/:eKяSk~=>lLlc~0m[{Ɯ9co=k̢E%{ܒ$Mc5&7ט'4ȑ=T 1e'}VGԦWo`jMKRz WEU8}pм9aCv*hEYy e?ρ@>E=_ߞ6[KZ5Ο=_t4p-IJr~Yŋ..Θ1ԩ-DJ-f{\ .{ta)S&M_?^="-1'RJ^=`?OC,]V?#ɓ)/^w7w(D™:LJJK.]b-B9.erժe Y;Q@)6F ǁm}IIuvL o9s8ud,w䧟_m0)k޼۸8`ժ[б#k,;w8ebu4h^s|`@`JnϚ `t 'AZ恼<[|˰t)f5G۝??y'p%;N 7b{|P>kת٢,,\בABSYG{8Tσ 5[# """ƒ8 """(<#)w9-/JAQDĢ ׮|x;)ϟ'EˋHQ$nɞ,'XKr9!\>(\ylNOU]2ȡ Y`ξ)G.HQxvk\YA.z {7Ű,Pp \.%+Y32W@wڵ } };WUpW=ѥ lI6ud""*e iE/>n풉H Hxt9`>Q#JKS{(?~ o4i^ <0ED$Ty1BaVoivi1.Zp!p{ԅVDDGE9s4Ǟ1X!%qd"".ʉ<`6dgO?%krd""na2Zj  t !DD4"7tl~˖qHi))8HPC8~',‹s>}(K&""Kegsӧ.paf,""K%.K&֡`8t)""O}Dvr2p]\"{  A7ݺM},_4lvDDDJN!ܙ4T'u׹]2!a?7xࡇ[o10Ź]qF NP&"C= L2P6x1?o1"IJr$Ę1n@DBߏÇ.fZ`@^^ٞvx1J`>+ cH7<̙\qEdV9Ѳ=@L m[ɓ }iil|~C| g:C77\;eYS# DD yE ;ذY曁9bw)[:ZVZD(-ΟEo-::4á/PxS9G| g+Q6?,yR*\GěUQpվj٬O9z.G|^R229%u=#풉?C@b"o_ YUVH)ޡC~/gަOG1={reXS{%K?֭>}|ϟd?},ԩVy;&L;0`H״)M]2T]ǥ,UrrZ5k6ƾ>v,~h}^ܹ@˖@۶S 'z`PoR`,>ϟ.^FG>`_c,?8rQ͛u8 in? {/л7< \ӻ70t(in.0s&@B鵖r1u1پ=kw;w+ԭkLt1o13`1ԨarߥKƤdLJt`ʕ<-1gM7S1 Iεz1^},^\T:_rlnbc23}ok7̙/ƴicu?;zϟ?wms{{zŊlZc|ۿѥ1ݺ9<`V.,UO8sAKn,[foXΞ5fѢ>)R`V5o*޽Mr ~;|%~kز  <0x)keUI/_E֮ey׮8agv!C \lΪy$=[? f9w~sSxKv6wobbs~ZpU > ^lGip ,aٽۮyصMIV-PuǡuknH#Sk/Ə}h)oJ=⡇tl?/fG4cr`zV-OKc59?>k3ݛᣴ:*➓۾UzuVZqreoK@ǎmCm0>[ޏ[cڜ8@fEN'<{qP>_#9g |t_sre>pעE8xO%=I۶1@>ڵL.bHC+ux~{h̾ޢ?̂ևо}@VR :Wݺ55dQg@Nnk׎ꈖ}wPj5eb"'4׃Oᇁ=ESlほf9q>GyX_USM5}yHytY!`mQ#4-X8s&= S}Ϟ@zĉn]%].0jotq)1^7kHpTVHI]f kxή޻w{G#k0Uޏeɿ8NU\tqϩzu6ň;4Jĉ;Qk D޷akogF[D~y0XkX7ѣ甿%…DxR.\ """""">BA"[Z\LCVËb""$uEDD"p48_@8{`9q½DD$S q#燘HKڶu$Dz:;KRxPqqv35Nfu.H?ڷs$Dr%lFƾ} ˖q#8S D|<;TQ2"DD)r&!?!bph5 K'""@ᡜQC0lx1CDj*pۥ ,IOx,pPY!b>v,[<{gF3B!BDD)<+qԜ9v.H[hT ]x,]9RVx8rޗǿ8!Cs~Vr/RR씒,\Xp5m8UP U 6kgo?K'R6z:wt˖&\v /u|7e ϳy3k2lKx{q`l^=+Tj[,Lj#h()V9cg;I8%7DUl,?5:ux{Nq3в%/^ \= gу/.d? {/лN > |3k%*T`̙@n.MHX R"V1?g`m".sU{gn5hǏ}f&>UPebPIu^Yk$Ξewxx0KLyw$~U\׀~{>%1 !ESR֫!3s'?ش E}ع o֭< VOתo{ !mGMw/k4hypX[u]{<\8\wXc-:!$(ko$M4yR[MFoĴil:!".11Pb ~Kn~MNf߇\^o҄6t8~I{-$o{MX۶a oV%&#'eEkrY!#ϦNeSnNxu={|$n p>y[ǎ|{OK.]b E`9g&lW5V<&-ͮ10N޾gU2y2QCĨQ m<|8Uv ElտX 7on?~8`ժ=+y=%cAVx{߾[ovt48X͟[nG?ao[NσālX=G~Z!B>ڒ9m9f 32GViK'""CA*1c32]1cFNi""$(4`'d;!bLK'""N(:vtƒƍ,q Ç3D}p!#)Xq3;6ڵc3X@۶:H8Rxd&bP1f S\PF"ѣ!a.ppv];5.H !iS.Q1x0Deo""Cv6¦MvXZv|W)SxЬvM\g^"IN5 x#vBÆnXDSxr\fXfM3pВlcGDp{k5Х ays`Jv8 Lʚ'`{  G>lQ2_q!CZ2"~+ays7X1q"Я0e {ԇSYBkSW`Ю\kA#eD"JDh_ѧ0y2k""._f6l`'д)B׮y @jnXDc1nB"/p`^~K`3۶W34=4'X?.wzu]w p}w?VAn,LL cԯϪtqfbNޮG@oԭvD$2W.:i6)품}N""iUMqDADDDQxG5v)lwsa٬;{Frt(")v xaPԬ͵{l̇Nn{{ycu3f^cޘm1߯1]s1W_m̚5}+'sɘcjeȑϩkWC^YY;:߭u+a$$pߤIԮm̻s1}dLz`CD$(}kdhՊnYkpRx]US'6c}욊-[kK<h ƢeK)"AADʌ>o~<{7CŖ-\w9}K@Ŋ@F M\T)?K ʕ Z}Ծ='Ab6^ne-ZV[.;." "V hߞo/*mcl-8uk.`U ?Ӧ])ƒ5o[Vk*laش X8{ԱG}nG.&$D$l4hw۷]ַla'mۀ?,`NvIDBjDDSDDxGÆ\ `@HNWbvy(.TN0t(_``z}s͝fO?uٹO"R.M :v)c\Iwo`X` `E {* }ժf1Zo;Ձ~VCADʥc/֯jvZW1JYiтkX*NH`mEl,? v5U LZo՜9 Sp'W^aH-fÆ=<Э;ǚǁeˀÇKV1_P@c?ä-*US*Tm֍g~_'#m7aCkn.k@~#?'уn].WB0v9LN侔~}`Hn4i;)_~ɜd8 " ;w͛۷ժov>q8t(<W׮dIիCȈqj~bmOw}^{'#Nk``sW""t?L`.nۥ*wgz>1o9/>X9Pk0Y,_J%0t8gtTRVǎ'%W%?Q}o䓲;qaRDʝªU ?ys5Y`8^>kbc}٧b\^?ặbW~lо+Wr`^?8ؑrP>Q'dETo'` ">Jߘ1(< """eNADDDQxGDDDqDADDD<"jO_vIĉJd yzD$bt[nB$BDDDQxGDDDqDADDDQxGDDD ""aQ 5RD\x1킊HP8 """(<# """ƒ8 """(<# """ƒ8 """(<# """ƒ8 """g_ ^ޫ%tEXtdate:create2009-08-31T01:36:31+02:00p+T%tEXtdate:modify2009-08-31T01:36:31+02:00FtEXtsvg:base-urifile:///home/chenno/projects/elyxer/docs/parse%20tree.svgM^.IENDB`elyxer-1.2.5/forks/jras-elyxer/docs/math-iso885915.html0000644000175000017500000011764212117061353022003 0ustar chennochenno eLyxer Math Showcase (ISO-8859-15 edition)

figure elyxer.png eLyXer Math Showcase

Alex Fernández (elyxer@gmail.com)

1 Introduction

This document is intended as a showcase of the mathematical abilities of eLyXer; for more information be sure to visit the main page.

1.1 Versions

There are several versions of this page:
All of them are generated from the same .lyx source file; they should help you decide which rendering options suit you best.
Also available online is the eLyXer translation of the latest LyX’s detailed Math manual, which contains a lot more examples of LyX maths.

2 Typography

Math formulae use a lot of different symbols and fonts.

2.1 Greek Symbols

Greek symbols are very important in equations: φ, π, Ξ. eLyXer offers a complete set in both upper case: Γ…Ω and lower case: αω. Also the AMS italicized upper case: ΓΩ.

2.2 Math Symbols

eLyXer supports the whole set of math symbols in John D. Cook's list: ∃∂∇ ≥ . It can also render a few more:  ∝  × . You also get all symbols from Markus Kuhn's list: ⊙∐.

2.3 Other Symbols

There are other symbols like arrows:  ←  → , or geometrical shapes: , . eLyXer offers limited support for them. You might also want to use financial symbols in formulae: ¥€$.

2.4 Spacing

Equations look good when items are properly separated. The main separation is the Medium Mathematical Space: x = 3. Note: if you are viewing the non-Unicode version math.html of this page then you are in fact seeing midspaces, which are very similar but not exactly the same: (4)/(18) em for medium mathematical spaces versus (1)/(2) en, where 1 em = 2 en. Try out the Unicode version math-unicode.html — and viceversa. You can check out what version this page is in the page title.
The command \raisebox is useful to, surprisingly, raise a little box,
raisedoverloweredand back.
Like \mbox, it puts its content in a text box. It can also be used just for spacing:
BV.
There are other spacing commands: \hspace: a b, protected space: a b, and (at “block level”) \vspace: a b.
There should be 1 cm of vertical space above this paragraph.

2.5 Fonts

By default, letters denote variables and are taken from the \mathnormal font, which is italic, αx + αy = α(x + y), with the exception of upright capital Greek letters, G ≠ Γ.
Function names should be upright: sin(2π), log(x), tanδ.
Mathematical fonts used in equations include Roman (\mathrm), Sans Serif (\mathsf), Typewriter (\mathtt), Bold (\mathbf), SCRIPT (\mathscr), CALLIGRAPHIC (\mathcal), BLACKBOARD BOLD (\mathbb), and Fraktur (\mathfrak). For the latter, some single characters are translated to their Unicode equivalents: , 𝔽, 𝔉.
Regular text in a formula can be achieved via text font commands like \textrm: 5  to 10, via boxes like \mbox (prevents line breaks): 6  is more than 5, or the AMSmath \text macro (scales like math symbols) basesupersub. The content of an mbox is processed in LaTeX text mode. This allows text font commands, e.g. a switch to sans-serif-bold-italic, or the phonetic alphabet: sfbfit, tipa.
Units should be written upright, either with \mathrm or with macros from the units package, e.g. as simple unit, km, with magnitude, 57 km, with fractional unit, 200 kmh, or with a fraction before the units, 32 km, (7)/(16) s.

3 Numeration

Equations can be numbered, like (1↓)
(1) y = x
And also like (2↓).
(2) x = 3
Some equations can be numbered even if they don’t have a label.
(3) x = 2y
Notice that equation (2↑) comes after (1↑).

4 Simple Structures

Let’s now see a few of the simpler structures that eLyXer can output.

4.1 Fractions

A simple fraction:
(1)/(2).
Inlined: (2)/(3).
A big recursive fraction:
(1)/(1 + (1)/(1 + (1)/(1 + 2x)))
A nice fraction: 56. A non-diminishing fraction containing alignments:
(1)/(1 + (1)/(1 + x) × (1)/(1 + x)).
A similar concept is a binomial coefficient: (A + 1B). It can be prettily presented:
AB + 1.
A symbol can be stacked over another using \stackrel: xR → y. Anything can be stacked:
dx > 3limx,  headheels.

4.2 Limits

limx → ∞f(x) should appear as x → ∞ in italics, and «lim» in plain style. In display mode, a limit must appear below the main symbol:
limx → ∞f(x).
Limits are also used in sums and integrals:
i = 1x,  0f(x) dx
where the sum’s limits should appear below (i = 1) and above () the . The placement of the integral limits depends on the document class: LaTeX standard classes place them right to the . Limits are shown to the right in inline formulae: i = 1x and i = 1x.
The placing of limits can be configured with the \limits and \nolimits macros:
limx → ∞f(x),  i = 1x,  0f(x) dx

4.3 Roots

A square root: (3). A more complex root in a fraction:
(1)/(1 + (2)(1)/(1 + (2)) + ((1)/(2))).
eLyXer can also do higher-order roots: 3(x + y). A devilish case mixing everything we have seen so far:
(78((8)/(4)x) + i = 1x)/(s + 5(((78x + 45y) × (Ω))/(sin(x + 1)) + 38 km)).

5 Complex Structures

In this section we will explore arrays and related constructs.

5.1 Arrays

An inline array a b c d is always shown in the same line. In display mode, the array is shown on its own line:
12 2 3 4 × yx
Apart from that the appearance should be the same.

5.2 Brackets

Arrays are separated by variable-size brackets: a b c d a b c d a b c d a b c d ||| a b c d |||which might also differ on right and left a b c d or use the empty opening a b c d or closing: a b c d |||. There are also fixed-size big brackets, e.g. f.

5.3 Cases

Used to switch between several values.
y =  x i = 0,         x + 1  i < 3 
Cases may have more than two rows:
f(x) =  0  x < 0,         ∞  x = 0        0  x > 0 

5.4 Braces

Values can be underbraced or overbraced.
a − b = b + c + d + e.

6 Macros

Now it’s time for user-defined commands (sometimes called “macros”).
Definitions can be added as macros. Then they can be used in formulae: 1(2). They can accept default parameters. Again, useful in formulae: 4(5).
Other definitions from the preamble can be used: 3(4).
Definitions on the fly are also possible: 7(8), and used with different values: a(b).
elyxer-1.2.5/forks/jras-elyxer/docs/container.png0000644000175000017500000001225212117061342021345 0ustar chennochennoPNG  IHDRM7bKGD1 pHYsdd vpAgMIDATx{pTgcRx(⥌"ScVED!S(DZPGGUGĢ[ VBH(%9I!yn=N\o۞A$ TBhB oRe*Kv9b|HN7$HJ{IcH4$ծ4zt!+I9Mp@hB"*֮u]jZ3U@ ~gEhpriҽڕMl/) $ "48#l-[3}Wx&zFrs*裥_LikB1C5wGh"isg $]x1HݺJJnƏzO~+ خ]}WXؙА?>Ə,vtv2A &uh_; !C={|"4[:ᄺ]*-&3vh>wԪUcI4ywX#lw5)=fgK]$uT8o`{S'o|cO)epi6;߆ĩ>Lzqk}W\M= ֝;$Xawut啾I.&RUWK.]Iz~?<ɆDJζsgzQEh",\hw>㍔,l%ZeaذA: U@ҺrihUUq#oUs}YgH_iF\HKc$-B8!4 Mp@hB&8 4 Mp@hB&8 4]ʤqiӤ W_:Hڶ(m[[Gݻ>}뮳e+WJO?-M.JގOHғOJ/ { -W_o*76$k'XMmhTH۾=&OO[RLRwA˃ 3s6]U. R{zut.+(6kTTcǧ-$/Fx ^gVV8L:PiNi&ۥ_?k6TVJm/O=U ֭۫mϱmEE6FƷ]$i"֭?}| ä5k,4v | cbwpwX~4D\JKJvI/JG۲eˤ 7mJ۷ѩu_'téoդIf˗Śѣal̙ҵJ#UWKb6o(ٹ-ѡaSnf͒{wzϟx@c8q>&iFDm~1]8Du`_4=Mp@hB&8 4a{HWH-fmd {t%ֱ!4#wOΝ}޲{4 z1яΓ7GgFɾ+R O>P|)\R S6g8_o1i={^fϖyG:o:v]]]+u Di`&NRU_t LI1wAl"͝[wޢEv 6PX^4|tiWBClU4]wo~ZzT줓 >w@BPضM1\2iv$"RZR92.X~~ԭjEf8d;w٪J9SZBS] )"#bך5E}B)WQEh"ddH{K]QEh"< e\J*SNJGN4z*͈۹S:xiXߕ$}Wd98 4 Mp@hB4:'#åN={ڐY yӜ=ۺz9gO!/O;f|^4N^=q3y˖I&:#GZ SJf{ :t4`3ΨQaYgӏ>j{ާtusm^_n++m];)?_ζ+ӥRرCz Vwo7J!y-/;|eSEc6bbF6ôiȑRaKZK'`S5**ݻ]{tҁtemn~yyCp &hmNm+vΝ=XgeI$Ͷn<6fӧWƬMsۗ^;^|Q꫺IC$)HnX,vn=4JJ+.pz꫃} h:.:tV6]Ѷۨlg9vls}{LlG m`V5Ə[o j[n iR{ysdg7 k<ߵ  (-WAni rN䓥?_ןa{:0h)Y#I?w{GK6}7Opl̙wUb1i8i֬q7MIl7ǁ=%i;/YP`UU6]U%M.1B81 O榿FVVC?زe҄ 6pffx/:I|PwޢE-6˞=O-3w/bpBPyy펫_]snbFH5cϚe;MOj)$i;uq1c̙ҵJcO9Ŗ[XoTwfo }ne=gm.GݹsX/W]e{ݵ|UH&Ssuc־MBvv=\"׾d?mw r!K<9~}`X ;SI[gmVW[`\YcYSFfc'=pAg1ѦgͲ n,Ӿ$},+6ls}L)%B[QBFqp}J޷Uwvv*)/c>pxS@K#4 QY)[ fXFU"8)-[QEh3ΰ!2ʤ/) ;]*6c ߕ qU_*Z%]|ukֹs8? .Tzm] !z+ߧVڶo1o}w~Гk;7w5&ZFHug+С'軺޽~@K!4_H \R"eٷ⧃LS;w=<"-YbCIx~z;v0z8} Q{B3Vf϶a +q}>㩨H:s}WDy~I_~)uq95ylJMChFHv6ڵoו&O18B3b΢U͈;@&8 4 Mp@hB&8 4 M$=S}?BIen/wHҌҲe6YIO>rTQ!}4uY^.NX!=3jTfnt)i҂ҫ۶Gcx|:'TA1 ,ȦMCix[f~ƦkŤ)S; O7bh 4#.١J99-[lOĦeeRVV8L:P}7 D+22=^֭?}䑾9D܌!Mg87Ӻ}=_~YYv_\pPZTڵKz};'9ztÅ MA]xe]}ᥰЂ?=M*9sC w);۞O$ ,-_n?z4lX9͈9DKxf4pxM$[HŤ~|W(&^Ҟ= {&8 4 Mp@hB;$UT$}t+I_- .}:M I4dۈ߄&<̔{/5Kvׇc!C۶R.f.]|W`͈; W|W.!+@H)>D M bڵ]k$i,{wgjӧ4 A@I{.~n(\)'mۤwZ D\vaE?zzI  ͗_z^{h9h矯{?Ie@;)O:ɽݥݻ]vzK2e'҈vsA"G\D*)XĽ ۫|y.*>F i"-;vHJm= J?a|_}{)'րvhʔhK&Rܹ+]+rsϷYYڿ=wߕxCz eLyxer Developer Guide

figure elyxer.png eLyXer Developer Guide

Alex Fernández (elyxer@gmail.com)

1 The Basics

This document should help you get started if you want to understand how eLyXer works, and maybe extending its functionality. The package (including this guide and all accompanying materials) is licensed under the GPL version 3 or, at your option, any later version. See the LICENSE file for details. Also visit the main page to find out about the latest developments.
In this first section we will outline how eLyXer performs the basic tasks. Next section will be devoted to more arcane matters. The third section explains how to contribute to eLyXer, while the fourth one deals with future planned extensions. The fifth section includes things that will probably not be implemented. Finally there is a FAQ that contains answers to questions asked privately and on the lyx-devel list [7].

1.1 Getting eLyXer

If you are interested in eLyXer from a developer perspective the first thing to do is fetch the code. It is included in the standard distribution, so just navigate to the src/ folder and take a look at the .py Python code files.
For more serious use, or if your distribution did not carry the source code, or perhaps to get the latest copy of the code: you need to install the tool git, created by Linus Torvalds (of Linux fame) [8]. You will also need to have Python installed; versions at or above 2.4 should be fine [9]. The code is hosted in Savannah [1], a GNU project for hosting non-GNU projects. So first you have to fetch the code:
$ git clone git://git.sv.gnu.org/elyxer.git
You should see some output similar to this:
Initialized empty Git repository in /home/user/install/elyxer/.git/
remote: Counting objects: 528, done.
remote: Compressing objects: 100% (157/157), done.
remote: Total 528 (delta 371), reused 528 (delta 371)
Receiving objects: 100% (528/528), 150.00 KiB | 140 KiB/s, done.
Resolving deltas: 100% (371/371), done. 
Now enter the directory that git has created.
$ cd elyxer
Your first task is to create the main executable file:
$ ./make
The build system for eLyXer will compile it for you, and even run some basic tests. (We will see later on section 3.1↓ how this “compilation” is done.) Now you can try it out:
$ cd docs/
$ ../elyxer.py devguide.lyx devguide2.html
You have just created your first eLyXer page! The result is in devguide2.html; to view it in Firefox:
$ firefox-bin devguide2.html
If you want to debug eLyXer then it is better to run it from the source code folder, instead of the compiled version. For this you need to make just a small change, instead of elyxer.py run src/principal.py:
$ ../src/principal.py --debug devguide.lyx devguide2.html
and you will see the internal debug messages.
Note for Windows developers: on Windows eLyXer needs to be invoked using the Python executable, and of course changing the slashes to backward-slashes:
> Python ..\elyxer.py devguide.lyx devguide2.html
or for the source code version:
> Python ..\src\elyxer.py devguide.lyx devguide2.html
If you want to install the created version you just have to run the provided install script as root:
# ./install
Once eLyXer has been installed it can be invoked as any other Unix command:
$ elyxer.py devguide.lyx devguide3.html
In the rest of this section we will delve a little bit into how eLyXer works.

1.2Containers

The basic code artifact (or ‘class’ in Python talk) is the Container, located in the gen package (file src/gen/Container.py). Its responsibility is to take a bit of LyX code and generate working HTML code. This includes (with the aid of some helper classes): reading from file a few lines, converting it to HTML, and writing the lines back to a second file.
The following figure 1↓ shows how a Container works. Each type of Container should have a parser and an output, and a list of contents. The parser object receives LyX input and produces a list of contents that is stored in the Container. The output object then converts those contents to a portion of valid HTML code.
figure container.png
Figure 1 Container structure.
Two important class attributes of a Container are:
  • start: a string of text containing the LyX command that we are about to process;
  • and ending, which is used on some Containers to determine when to stop parsing.
A class called ContainerFactory has the responsibility of creating the appropriate containers, as the strings in their start attributes are found.
The basic method of a Container is:
  • process(): called after parsing the LyX text and before outputting the HTML result. Here the Container can alter its contents as needed, once everything has been read and before it is output.
Now we will see each subordinate class in detail.

1.3Parsers

The package parse contains almost all parsing code; it has been isolated on purpose so that LyX format changes can be tackled just by changing the code in that directory.
A Parser has two main methods: parseheader() and parse().
parseheader(): parses the first line and returns the contents as a list of words. This method is common for all Parsers. For example, for the command ’\\emph on’ the Parser will return a list [’\\emph’,’on’]. This list will end up in the Container as an attribute header.
parse(): parses all the remaining lines of the command. They will end up in the Container as an attribute contents. This method depends on the particular Parser employed.
Basic Parsers reside in the file parser.py. Among them are the following usual classes:
LoneCommand: parses a single line containing a LyX command.
BoundedParser: reads until it finds the ending. For each line found within, the BoundedParser will call the ContainerFactory to recursively parse its contents. The parser then returns everything found inside as a list.

1.4 Outputs

Common outputs reside in output.py. They have just one method:
gethtml(): processes the contents of a Container and returns a list with file lines. Carriage returns \n must be added manually at the desired points; eLyXer will just merge all lines and write them to file.
Outputs do not however inherit from a common class; all you need is an object with a method gethtml(self,container) that processes the Container’s contents (as a list attribute). An output can also use all attributes of a Container to do their job.

1.5 Tutorial: Adding Your Own Container

If you want to add your own Container to the processing you do not need to modify all these files. You just need to create your own source file that includes the Container, the Parser and the output (or reuse existing ones). Once it is added to the types in the ContainerFactory eLyXer will happily start matching it against LyX commands as they are parsed.
There are good examples of parsing commands in just one file in image.py and formula.py. But let us build our own container BibitemInset here. We want to parse the LyX command in listing 1↓. In the resulting HTML we will generate an anchor: a single tag <a name="mykey"> with fixed text "[ref]".
\begin_inset CommandInset bibitem
LatexCommand bibitem
key "mykey"
\end_inset
Algorithm 1 The LyX command to parse.
We will call the Container BibitemInset, and it will process precisely the inset that we have here. We will place the class in bibitem.py. So this file starts as shown in listing 2↓.
class BibitemInset(Container):
  "An inset containing a bibitem command"
  
  start = ’\\begin_inset CommandInset bibitem’
  ending = ’\\end_inset’
Algorithm 2 Class definition for BibitemInset.
We can use the parser for a bounded command with start and ending, BoundedParser. For the output we will generate a single HTML tag <a>, so the TagOutput() is appropriate. Finally we will set the breaklines attribute to False, so that the output shows the tag in the same line as the contents: <a …>[ref]</a>. Listing 3↓ shows the constructor.
  def __init__(self):
    self.parser = BoundedParser()
    self.output = TagOutput()
    self.tag = ’a’
    self.breaklines = False
Algorithm 3 Constructor for BibitemInset.
The BoundedParser will automatically parse the header and the contents. In the process() method we will discard the first line with the LatexCommand, and place the key from the second line as link destination. The class StringContainer holds string constants; in our case we will have to isolate the key by splitting the string around the double quote ", and then access the anchor with the same name. The contents will be set to the fixed string [ref]. The result is shown in listing 4↓.
  def process(self):
    #skip first line
    del self.contents[0]
    # parse second line: fixed string
    string = self.contents[0]
    # split around the "
    key = string.contents[0].split(’"’)[1]
    # make tag and contents
    self.tag = ’a name="’ + key + ’"’
    string.contents[0] = ’[ref] ’
Algorithm 4 Processing for BibitemInset.
And then we have to add the new class to the types parsed by the ContainerFactory; this has to be done outside the class definition. The complete file is shown in listing 5↓.
from parser import *
from output import *
from container import *
  
class BibitemInset(Container):
  "An inset containing a bibitem command"
  
  start = ’\\begin_inset CommandInset bibitem’
  ending = ’\\end_inset’
  
  def __init__(self):
    self.parser = BoundedParser()
    self.output = TagOutput()
    self.breaklines = False
  
  def process(self):
    #skip first line
    del self.contents[0]
    # parse second line: fixed string
    string = self.contents[0]
    # split around the "
    key = string.contents[0].split(’"’)[1]
    # make tag and contents
    self.tag = ’a name="’ + key + ’"’
    string.contents[0] = ’[ref] ’
  
ContainerFactory.types.append(BibitemInset)
Algorithm 5 Full listing for BibitemInset.
The end result of processing the command in listing 1↑ is a valid anchor:
<a name="mykey">[ref] </a>
The final touch is to make sure that the class is run, importing it in the file gen/factory.py, as shown in listing 6↓. This ensures that the ContainerFactory will know what to do when it finds an element that corresponds to the BibitemInset.

from structure import *
from bibitem import *
from container import *
Algorithm 6 Importing the BibitemInset from the factory file.
Now this Container is not too refined: the link text is fixed, and we need to do additional processing on the bibitem entry to show consecutive numbers. The approach is not very flexible either: e.g. anchor text is fixed. But in less than 20 lines we have parsed a new LyX command and have outputted valid, working XHTML code. The actual code is a bit different but follows the same principles; it can be found in src/bib/biblio.py: in the classes BiblioCite and BiblioEntry, and it processes bibliography entries and citations (with all our missing bits) in about 50 lines.

2 Advanced Features

This section tackles other, more complex features; all of them are included in current versions.

2.1 Parse Tree

On initialization of the ContainerFactory, a ParseTree is created to quickly pass each incoming LyX command to the appropriate containers, which are created on demand. For example, when the ContainerFactory finds a command:
\\emph on
it will create and initialize an EmphaticText object. The ParseTree works with words: it creates a tree where each keyword has its own node. At that node there may be a leaf, which is a Container class, and/or additional branches that point to other nodes. If the tree finds a Container leaf at the last node then it has found the right point; otherwise it must backtrack to the last node with a Container leaf.
Figure 2↓ shows a piece of the actual parse tree. You can see how if the string to parse is \begin_inset LatexCommand, at the node for the second keyword LatexCommand there is no leaf, just two more branches label and ref. In this case the ParseTree would backtrack to begin_inset, and choose the generic Inset.
figure parse tree.png
Figure 2 Portion of the parse tree.
Parsing is much faster this way, but there are disadvantages; for one, parsing can only be done using whole words and not prefixes. SGML tags (such as <lyxtabular>) pose particular problems: sometimes they may appear with attributes (as in <lyxtabular version="3">), and in this case the starting word is <lyxtabular without the trailing ’>’ character. So the parse tree removes any trailing ’>’, and the start string would be just <lyxtabular; this way both starting words <lyxtabular> and <lyxtabular are recognized.

2.2 Postprocessors

Some post-processing of the resulting HTML page can make the results look much better. The main stage in the postprocessing pipeline inserts a title “Bibliography” before the first bibliographical entry. But more can be added to alter the result. As eLyXer parses a LyX document it automatically numbers all chapters and sections. This is also done in the postprocessor.
The package post contains most postprocessing code, although some postprocessors are located in the classes of their containers for easy access.

2.3 Mathematical Formulae

Formulae in LyX are rendered beautifully into TeX and PDF documents. For HTML the conversion is not so simple. There are basically three options:
  • render the formula as an image (GIF or PNG), then import the image;
  • export a specific language called MathML
  • or render using a variety of Unicode characters, HTML and CSS wizardry [2].
eLyXer employs the third technique, with varied results. Basic fractions and square roots should be rendered fine, albeit at the moment there may be some issues pending. Complex fractions with several levels do not come out right. (But see subsection 2.4↓.)

2.4 MathML

There are two options in place to generate MathML, as suggested by Günther Milne and Abdelrazak Younes [4, 5]. Both rely on some JavaScript page manipulations, and they need to be hosted on the same server as the documents. MathJax is less mature but it has grown faster so it has become the preferred option.
To use this last option in your own pages you just have to add the --mathjax option:
$ elyxer.py --mathjax ./MathJax math.lyx math.html
You will notice that the --mathjax option requires an argument: the directory where MathJax resides. MathJax needs to live on your server; after downloading the package, deploy it to your server and give the installation directory as an argument to --mathjax.
In principle you might think of using some external installation of MathJax to avoid downloading it and serving it from your server, e.g. from Savannah:
$ elyxer.py --mathjax http://elyxer.nongnu.org/MathJax/ math.lyx math.html
This approach may not work on certain browsers for two reasons: JavaScript loaded from a different site may not work, and WebFonts are also subject to this same-origin policy. If you have made it work it would be great to hear about it.

2.5 Baskets

eLyXer supports a few distinct modes of operation. In each incarnation the tasks to do are quite different:
  • A pure filter: read from disk and write to disk each Container, keeping no context in memory.
  • In-memory processing: read a complete file, process it and write it all to disk.
  • TOC generation: output just a table of contents for a LyX document.
  • Split document generation: separates each chapter, section or subsection in a different file.
How can it do so many different tasks without changing a lot of code? The answer is in the file gen/basket.py. A Basket is an object that keeps Containers. Once a batch is ready, the Basket outputs them to disk or to some other Basket, but it may decide to just wait a little longer.
The basic Basket is the WriterBasket: it writes everything that it gets to disk immediately and then forgets about it. Some bits of state are kept around, like for example which biliography entries have been found so far, but the bulk of the memory is released.
Another more complex object is the TOCBasket: it checks if the Container is worthy to appear in a TOC, and otherwise just discards it. For chapters, sections and so on it converts them to TOC entries and outputs them to disk.
The MemoryBasket does most of its work in memory: it stores all Containers until they have all been read, then does some further processing on them and outputs an improved version of the document, at the cost of using quite more memory. This allows us for example to generate a list of figures or to set consecutive labels for bibliography entries (instead of just numbering them as they appear in the text).
The most complex kind of Basket is the SplittingBasket: it writes each document part to a separate file, choosing what parts to split depending on the configuration passed in the --splitpart option. By default it creates a TOC at the top of each page.

2.6 Hybrid Functions

Math processing is very configurable; most of it is based on configuration options found in src/conf/base.cfg. Parsing can be done using a few simple functions: commands (contained in [FormulaConfig.commands]) output some content and don’t have any parameters, while one-parameter functions (in [FormulaConfig.onefunctions]) take exactly one parameter and output an HTML tag. Thus, the definition for \bar is:
\bar:span class="bar"
Whenever eLyXer finds the command it parses a parameter, then outputs the tag <span class="bar"> surrounding the parameter. For instance: e.g. \bar{38} becomes <span class="bar">38</span> in the output. Decorating functions (in [FormulaConfig.decoratingfunctions]) place a symbol from in the definition above the parameter, and so on.
Such simple processing is not always enough; there is a generic mechanism for producing complex output from a number of parameters. They are called hybrid functions.
Each definition for a hybrid function contains: parser definition, output definition and a number of function tags. The parser definition tells eLyXer what to parse. Hybrid functions can have any number of optional parameters, denoted as [$p]; mandatory parameters are shown as {$p}. Each parameter consists of the symbol $ followed by a letter or number: $0, $p.
The output definition contains regular text, plus parameters and functions. Each function consists of the letter f plus a number, such as f0; and each is associated with a tagged HTML element. These function tags are the last part of the definition. Presently there can be as many as 10 function tags (from f0 to f9).
Let us see a simple example, equivalent to the above formula — a one-parameter, one-tag hybrid function:
\fun:[{$p},f0{$p},span class="fun"]
The only function tag f0 generates the HTML tag <span class="fun">. Whenever eLyXer finds \fun in a math formula, it will parse one parameter and put it into $p. Then it will generate f0{$p}, i.e. apply the tag <span class="fun">. Putting it all together: \fun{38} becomes <span class="fun">38</span>.
Parameters can be parsed as a literal, in which case eLyXer will take everything between the brackets without parsing it. Literal parameters can be used within a tag definition. A real life hybrid function with literal parameters:
\raisebox:[{$p!}{$1},f0{$1},span class="raisebox" style="vertical-align: $p;"]
In this case there are two mandatory parameters, the first one literal and the second one a regular TeX expression. The output is just one function tag, in this case using the first mandatory parameter. For instance, \raisebox{3cm}{5} would generate:
<span class="raisebox" style="vertical-align: 3cm;">5</span>
The parameter $p is parsed as 3cm, which is not parsed further.
Hybrid functions are easy to configure once you get the hang of it. Adding new TeX commands, even complex ones, becomes simply a matter of configuration.

3 Developing and Contributing

This chapter will show you how to further develop eLyXer and how to contribute your own code.

3.1 Distribution

You will notice that in the src/ folder there are several Python files, while in the main directory there is just a big one called elyxer.py. The reason is that before distributing the source code is coalesced and placed on the main directory, so that users can run it without worrying about libraries, directories and the such. (They need of course to have Python 2.5 installed.) And the weapon is a little Python script called coalesce.py that does the dirty job of parsing dependencies and inserting them into the main file. There is also a make Bash script that takes care of permissions and generates the documentation. Just type
$ ./make
at the prompt. This coalesces all code and configuration into elyxer.py. It is a primitive way perhaps to generate the “binary” (ok, not really a binary but a distributable Python file), but it works great.
The make script also runs all of the included tests to check that no functionality has been lost from one release to the next. These tests can also be run independently using the run-tests script:
$ ./run-tests
They are used to verify that no functionality is lost from one version to the next — although issues can certainly slip undetected if there is no test for them.
At the moment there is no way to do this packaging on non-Unix operating systems with a single script, e.g. a Windows .bat script. However the steps themselves are trivial.

3.2 Debugging

Code problems are quite difficult to debug using the full elyxer.py file. It is much better to use the uncoalesced version instead, since it is quite modular and neatly divided. To do so you just need to locate the file src/principal.py and run that instead of elyxer.py. For example, if you are in the docs/ directory and you want to convert math.lyx you can run eLyXer as:
$ ../src/principal.py math.lyx math.html
For extra debugging information you can activate the --debug option:
$ ../src/principal.py --debug math.lyx math.html
This will make any traces more meaningful and will let you follow the code much more easily.

3.3 Configuration

The make script does not just construct a single .py file from all sources; it is also used to extract the configuration in human-readable form and create a Python file which is then coalesced with all the rest. The original configuration file (the one you should modify) is called base.cfg, while the resulting Python file is called config.py.
The original configuration file uses this format:
[ContainerConfig.startendings]
\begin_deeper:\end_deeper
\begin_inset:\end_inset
\begin_layout:\end_layout
where each section header is enclosed in square brackets; it contains an object name and a section name. In the example above the object is called ContainerConfig, while the section is called startendings. Inside each section there are a number of key:value pairs separated by a colon; the key is used to reference the value in other Python code.
To create config.py go to the src/ folder and type:
$ ./exportconfig py
This will create all configuration objects to be used inside your Python code, where each section will become an object attribute containing a map. For instance, to access the first value above \end_deeper you would write in your Python code:
ContainerConfig.startendings[’\begin_deeper’]
Each section can contain as many values as needed.

3.4 License

eLyXer is published under the GPL, version 3 or later [3]. This basically means that you can modify the code and distribute the result as desired, as long as you publish your modifications under the same license. But consult a lawyer if you want an authoritative opinion.

3.5 Contributions

All contributions will be published under this same license, so if you send them this way you implicitly give your consent. An explicit license grant would be even better and may be required for larger contributions.
Please send any suggestions, patches, ideas and whatever else related to development to the mailing list. (Alternatively you may contact elyxer@gmail.com privately.) If you are willing to create a patch and submit it, you should patch against the proper sources in src/ and send it to the list. This will make everyone’s lives better than if you patch against elyxer.py.
The first external patches have started arriving during late 2009 and early 2010 (provided by Olivier Ripoll, Geremy Condra and Simon South). You can join in the fun!

4 Roadmap

You can see what user features are planned for the near feature in the wish list.
After the release of eLyXer 1.0, the goal is full LyX document support; any deviation from the output of LyX on e.g. PDF will be considered as bugs. (Keep in mind that some deviations arise in an inherent limitation in the design of eLyXer, and these will logically not be considered as bugs.)
For eLyXer 1.3.0 there are plans to convert it into a proper Python package so it can be installed using full source code (and not a coalesced script elyxer.py that contains everything). Also, once ERTs are parsed, eLyXer might be extended for 1.3.0 to translate generic LaTeX documents.
All this within the usual constraints: day job, family, etc.

5 Discarded Bits

Some features suggested for eLyXer have been discarded; they do not fit with the design of eLyXer or are too much effort for the proposed gains.

5.1 Spellchecking

LyX can use a spellchecker to verify the words used. However it is not interactive so you may forget to run it before generating a version. It is possible to integrate eLyXer with a spellchecker and verify the spelling before generating the HTML, but it is not clear that it can be done cleanly.

5.2 URL Checking

Another fun possibility is to make eLyXer check all the external URLs embedded in the document. However the Python facilities for URL checking are not very mature, at least with Python 2.5: some of them do not return errors, others throw complex exceptions that have to be parsed… It is far easier to just create the HTML page and use wget (or a similar tool) to recursively check all links in the page.

5.3 Use of lyx2lyx Framework

Abdelrazak Younes suggests using the lyx2lyx framework, which after all already knows about LyX formats [5]. It is an interesting suggestion, but one that for now does not fit well with the design of eLyXer: a standalone tool to convert between two formats, or as Kernighan and Plauger put it, a standalone filter [6]. Long-term maintenance might result a bit heavier with this approach though, especially if LyX changes to a different file format in the future.

6 FAQ

Q: I don’t like how your tool outputs my document, what can I do?
A: First make sure that you are using the proper CSS file, i.e. copy the existing docs/lyx.css file to your web page directory. Next try to customize the CSS file to your liking; it is a flexible approach that requires no code changes. Then try changing the code (and submitting the patch back).
Q: How is the code maintained?
A: It is kept in a git repository on Savannah. Patches in git format are welcome (but keep in mind that my knowledge of git is even shallower than my Python skills).
Q: I found a bug, what should I do?
A: Just report it to the Savannah interface, to the mailing list or directly to the main author.

Nomenclature

class A self-contained piece of code that hosts attributes (values) and methods (functions).
filter A type of program that reads from a file and writes to another file, keeping in memory only what is needed short term.
TOC Table of contents

References

[1] Free Software Foundation, Inc.: eLyXer summary. https://savannah.nongnu.org/projects/elyxer/

[2] S White: “Math in HTML with CSS”, accessed March 2009. http://www.zipcon.net/~swhite/docs/math/math.html

[3] R S Stallman et al: “GNU GENERAL PUBLIC LICENSE” version 3, 20070629. http://www.gnu.org/copyleft/gpl.html

[4] G Milde: “Re: eLyXer: LyX to HTML converter”, message to list lyx-devel, 20090309. http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg148627.html

[5] A Younes: “Re: eLyXer: LyX to HTML converter”, message to list lyx-devel, 20090309. http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg148634.html

[6] B W Kernighan, P J Plauger: “Software Tools”, ed. Addison-Wesley Professional 1976, p. 35.

[7] Various authors: “lyx-devel mailing list”, accessed November 2009. http://www.mail-archive.com/lyx-devel@lists.lyx.org/

[8] S Chacon: “Git — Download”, accessed November 2009. http://git-scm.com/download

[9] Python community: “Download Python”, accessed November 2009. http://www.python.org/download/

elyxer-1.2.5/forks/jras-elyxer/docs/devguide.lyx0000644000175000017500000017172212117061342021217 0ustar chennochenno#LyX 1.6.7 created this file. For more info see http://www.lyx.org/ \lyxformat 345 \begin_document \begin_header \textclass article \begin_preamble % eLyXer -- convert LyX source files to HTML output. % % Copyright (C) 2009-2011 Alex Fernández % % This program is free software: 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 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 % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . \end_preamble \use_default_options false \language english \inputencoding auto \font_roman default \font_sans default \font_typewriter default \font_default_family default \font_sc false \font_osf false \font_sf_scale 100 \font_tt_scale 100 \graphics default \paperfontsize default \spacing single \use_hyperref false \papersize default \use_geometry false \use_amsmath 1 \use_esint 1 \cite_engine basic \use_bibtopic false \paperorientation portrait \secnumdepth 3 \tocdepth 3 \paragraph_separation indent \defskip medskip \quotes_language english \papercolumns 1 \papersides 1 \paperpagestyle default \tracking_changes false \output_changes false \author "" \author "" \end_header \begin_body \begin_layout Title \begin_inset Graphics filename elyxer.svg lyxscale 50 \end_inset eLyXer Developer Guide \end_layout \begin_layout Author Alex Fernández (elyxer@gmail.com) \end_layout \begin_layout Standard \begin_inset CommandInset toc LatexCommand tableofcontents \end_inset \end_layout \begin_layout Section The Basics \end_layout \begin_layout Standard This document should help you get started if you want to understand how eLyXer works, and maybe extending its functionality. The package (including this guide and all accompanying materials) is licensed under the \begin_inset CommandInset href LatexCommand href name "GPL version 3" target "http://www.gnu.org/licenses/gpl-3.0-standalone.html" \end_inset or, at your option, any later version. See the \family typewriter LICENSE \family default file for details. Also visit the \begin_inset CommandInset href LatexCommand href name "main page" target "index.html" \end_inset to find out about the latest developments. \end_layout \begin_layout Standard In this first section we will outline how eLyXer performs the basic tasks. Next section will be devoted to more arcane matters. The third section explains how to contribute to eLyXer, while the fourth one deals with future planned extensions. The fifth section includes things that will probably \emph on not \emph default be implemented. Finally there is a FAQ that contains answers to questions asked privately and on the lyx-devel list \begin_inset CommandInset citation LatexCommand cite key "lyx-devel" \end_inset . \end_layout \begin_layout Subsection Getting eLyXer \end_layout \begin_layout Standard If you are interested in eLyXer from a developer perspective the first thing to do is fetch the code. It is included in the standard distribution, so just navigate to the \family typewriter src/ \family default folder and take a look at the \family typewriter .py \family default Python code files. \end_layout \begin_layout Standard For more serious use, or if your distribution did not carry the source code, or perhaps to get the latest copy of the code: you need to install the tool \family typewriter git \family default , created by Linus Torvalds (of Linux fame) \begin_inset CommandInset citation LatexCommand cite key "git-download" \end_inset . You will also need to have Python installed; versions at or above 2.4 should be fine \begin_inset CommandInset citation LatexCommand cite key "python-download" \end_inset . The code is hosted in Savannah \begin_inset CommandInset citation LatexCommand cite key "savannah-elyxer" \end_inset , a GNU project for hosting non-GNU projects. So first you have to fetch the code: \end_layout \begin_layout LyX-Code \color blue $ \color inherit git clone git://git.sv.gnu.org/elyxer.git \end_layout \begin_layout Standard You should see some output similar to this: \end_layout \begin_layout LyX-Code Initialized empty Git repository in /home/user/install/elyxer/.git/ \end_layout \begin_layout LyX-Code remote: Counting objects: 528, done. \end_layout \begin_layout LyX-Code remote: Compressing objects: 100% (157/157), done. \end_layout \begin_layout LyX-Code remote: Total 528 (delta 371), reused 528 (delta 371) \end_layout \begin_layout LyX-Code Receiving objects: 100% (528/528), 150.00 KiB | 140 KiB/s, done. \end_layout \begin_layout LyX-Code Resolving deltas: 100% (371/371), done. \end_layout \begin_layout Standard Now enter the directory that \family typewriter git \family default has created. \end_layout \begin_layout LyX-Code \color blue $ \color inherit cd elyxer \end_layout \begin_layout Standard Your first task is to create the main executable file: \end_layout \begin_layout LyX-Code \color blue $ \color inherit ./make \end_layout \begin_layout Standard The build system for eLyXer will compile it for you, and even run some basic tests. (We will see later on section \begin_inset CommandInset ref LatexCommand ref reference "sub:Distribution" \end_inset how this \begin_inset Quotes eld \end_inset compilation \begin_inset Quotes erd \end_inset is done.) Now you can try it out: \end_layout \begin_layout LyX-Code \color blue $ \color inherit cd docs/ \end_layout \begin_layout LyX-Code \color blue $ \color inherit ../elyxer.py devguide.lyx devguide2.html \end_layout \begin_layout Standard You have just created your first eLyXer page! The result is in \family typewriter devguide2.html \family default ; to view it in Firefox: \end_layout \begin_layout LyX-Code \color blue $ \color inherit firefox-bin devguide2.html \end_layout \begin_layout Standard If you want to debug eLyXer then it is better to run it from the source code folder, instead of the compiled version. For this you need to make just a small change, instead of \family typewriter elyxer.py \family default run \family typewriter src/principal.py \family default : \end_layout \begin_layout LyX-Code \color blue $ \color inherit ../src/principal.py --debug devguide.lyx devguide2.html \end_layout \begin_layout Standard and you will see the internal debug messages. \end_layout \begin_layout Standard Note for Windows developers: on Windows eLyXer needs to be invoked using the Python executable, and of course changing the slashes to backward-slashes: \end_layout \begin_layout LyX-Code \color blue > \color inherit Python .. \backslash elyxer.py devguide.lyx devguide2.html \end_layout \begin_layout Standard or for the source code version: \end_layout \begin_layout LyX-Code \color blue > \color inherit Python .. \backslash src \backslash elyxer.py devguide.lyx devguide2.html \end_layout \begin_layout Standard If you want to install the created version you just have to run the provided install script as root: \end_layout \begin_layout LyX-Code \color blue # \color inherit ./install \end_layout \begin_layout Standard Once eLyXer has been installed it can be invoked as any other Unix command: \end_layout \begin_layout LyX-Code \color blue $ \color inherit elyxer.py devguide.lyx devguide3.html \end_layout \begin_layout Standard In the rest of this section we will delve a little bit into how eLyXer works. \end_layout \begin_layout Subsection \family typewriter Container \family default s \end_layout \begin_layout Standard The basic code artifact (or `class \begin_inset CommandInset nomenclature LatexCommand nomenclature symbol "class" description "A self-contained piece of code that hosts attributes (values) and methods (functions)." \end_inset ' in Python talk) is the \family typewriter Container \family default , located in the \family typewriter gen \family default package (file \family typewriter src/gen/Container.py \family default ). Its responsibility is to take a bit of LyX code and generate working HTML code. This includes (with the aid of some helper classes): reading from file a few lines, converting it to HTML, and writing the lines back to a second file. \end_layout \begin_layout Standard The following figure \begin_inset CommandInset ref LatexCommand ref reference "fig:Container-structure" \end_inset shows how a \family typewriter Container \family default works. Each type of \family typewriter Container \family default should have a \family typewriter parser \family default and an \family typewriter output \family default , and a list of \family typewriter contents \family default . The \family typewriter parser \family default object receives LyX input and produces a list of \family typewriter contents \family default that is stored in the \family typewriter Container \family default . The \family typewriter output \family default object then converts those \family typewriter contents \family default to a portion of valid HTML code. \end_layout \begin_layout Standard \begin_inset Float figure wide false sideways false status open \begin_layout Plain Layout \align center \begin_inset Graphics filename container.svg \end_inset \end_layout \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout \begin_inset CommandInset label LatexCommand label name "fig:Container-structure" \end_inset Container structure. \end_layout \end_inset \end_layout \end_inset \end_layout \begin_layout Standard Two important class attributes of a \family typewriter Container \family default are: \end_layout \begin_layout Itemize \family typewriter start \family default : a string of text containing the LyX command that we are about to process; \end_layout \begin_layout Itemize and \family typewriter ending \family default , which is used on some \family typewriter Container \family default s to determine when to stop parsing. \end_layout \begin_layout Standard A class called \family typewriter ContainerFactory \family default has the responsibility of creating the appropriate containers, as the strings in their \family typewriter start \family default attributes are found. \end_layout \begin_layout Standard The basic method of a \family typewriter Container \family default is: \end_layout \begin_layout Itemize \family typewriter process() \family default : called after parsing the LyX text and before outputting the HTML result. Here the \family typewriter Container \family default can alter its \family typewriter contents \family default as needed, once everything has been read and before it is output. \end_layout \begin_layout Standard Now we will see each subordinate class in detail. \end_layout \begin_layout Subsection \family typewriter Parser \family default s \end_layout \begin_layout Standard The package \family typewriter parse \family default contains almost all parsing code; it has been isolated on purpose so that LyX format changes can be tackled just by changing the code in that directory. \end_layout \begin_layout Standard A \family typewriter Parser \family default has two main methods: \family typewriter parseheader() \family default and \family typewriter parse() \family default . \end_layout \begin_layout Description \family typewriter parseheader() \family default : parses the first line and returns the contents as a list of words. This method is common for all \family typewriter Parser \family default s. For example, for the command \family typewriter ' \backslash \backslash emph on' \family default the \family typewriter Parser \family default will return a list \family typewriter [' \backslash \backslash emph','on'] \family default . This list will end up in the \family typewriter Container \family default as an attribute \family typewriter header \family default . \end_layout \begin_layout Description \family typewriter parse() \family default : parses all the remaining lines of the command. They will end up in the \family typewriter Container \family default as an attribute \family typewriter contents \family default . This method depends on the particular \family typewriter Parser \family default employed. \end_layout \begin_layout Standard Basic \family typewriter Parser \family default s reside in the file \family typewriter parser.py \family default . Among them are the following usual classes: \end_layout \begin_layout Description \family typewriter LoneCommand \family default : parses a single line containing a LyX command. \end_layout \begin_layout Description \family typewriter BoundedParser \family default : reads until it finds the \family typewriter ending \family default . For each line found within, the \family typewriter BoundedParser \family default will call the \family typewriter ContainerFactory \family default to recursively parse its contents. The parser then returns everything found inside as a list. \end_layout \begin_layout Subsection Outputs \end_layout \begin_layout Standard Common outputs reside in \family typewriter output.py \family default . They have just one method: \end_layout \begin_layout Description \family typewriter gethtml() \family default : processes the contents of a \family typewriter Container \family default and returns a list with file lines. Carriage returns \family typewriter \backslash n \family default must be added manually at the desired points; eLyXer will just merge all lines and write them to file. \end_layout \begin_layout Standard Outputs do not however inherit from a common class; all you need is an object with a method \family typewriter gethtml(self,container) \family default that processes the \family typewriter Container \family default 's \family typewriter contents \family default (as a list attribute). An output can also use all attributes of a \family typewriter Container \family default to do their job. \end_layout \begin_layout Subsection Tutorial: Adding Your Own \family typewriter Container \end_layout \begin_layout Standard If you want to add your own \family typewriter Container \family default to the processing you do not need to modify all these files. You just need to create your own source file that includes the \family typewriter Container \family default , the \family typewriter Parser \family default and the \family typewriter output \family default (or reuse existing ones). Once it is added to the \family typewriter types \family default in the \family typewriter ContainerFactory \family default eLyXer will happily start matching it against LyX commands as they are parsed. \end_layout \begin_layout Standard There are good examples of parsing commands in just one file in \family typewriter image.py \family default and \family typewriter formula.py \family default . But let us build our own container \family typewriter BibitemInset \family default here. We want to parse the LyX command in listing \begin_inset CommandInset ref LatexCommand ref reference "alg:bibitem-command" \end_inset . In the resulting HTML we will generate an anchor: a single tag \family typewriter \family default with fixed text \family typewriter "[ref]" \family default . \end_layout \begin_layout Standard \begin_inset Float algorithm wide false sideways false status open \begin_layout Quotation \family typewriter \backslash begin_inset CommandInset bibitem \end_layout \begin_layout Quotation \family typewriter LatexCommand bibitem \end_layout \begin_layout Quotation \family typewriter key "mykey" \end_layout \begin_layout Quotation \family typewriter \backslash end_inset \end_layout \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout \begin_inset CommandInset label LatexCommand label name "alg:bibitem-command" \end_inset The LyX command to parse. \end_layout \end_inset \end_layout \end_inset \end_layout \begin_layout Standard We will call the \family typewriter Container \family default \family typewriter BibitemInset \family default , and it will process precisely the inset that we have here. We will place the class in \family typewriter bibitem.py \family default . So this file starts as shown in listing \begin_inset CommandInset ref LatexCommand ref reference "alg:bibitem-class" \end_inset . \end_layout \begin_layout Standard \begin_inset Float algorithm wide false sideways false status open \begin_layout Quotation \family typewriter class BibitemInset(Container): \end_layout \begin_layout Quotation \family typewriter \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset "An inset containing a bibitem command" \end_layout \begin_layout Quotation \family typewriter \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \end_layout \begin_layout Quotation \family typewriter \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset start = ' \backslash \backslash begin_inset CommandInset bibitem' \end_layout \begin_layout Quotation \family typewriter \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset ending = ' \backslash \backslash end_inset' \end_layout \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout \begin_inset CommandInset label LatexCommand label name "alg:bibitem-class" \end_inset Class definition for \family typewriter BibitemInset \family default . \end_layout \end_inset \end_layout \end_inset \end_layout \begin_layout Standard We can use the parser for a bounded command with start and ending, \family typewriter BoundedParser \family default . For the output we will generate a single HTML tag \family typewriter \family default , so the \family typewriter TagOutput() \family default is appropriate. Finally we will set the \family typewriter breaklines \family default attribute to \family typewriter False \family default , so that the output shows the tag in the same line as the contents: \family typewriter [ref] \family default . Listing \begin_inset CommandInset ref LatexCommand ref reference "alg:bibitem-init" \end_inset shows the constructor. \end_layout \begin_layout Standard \begin_inset Float algorithm wide false sideways false status open \begin_layout Quotation \family typewriter \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset def __init__(self): \end_layout \begin_layout Quotation \family typewriter \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset self.parser = BoundedParser() \end_layout \begin_layout Quotation \family typewriter \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset self.output = TagOutput() \end_layout \begin_layout Quotation \family typewriter \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset self.tag = 'a' \end_layout \begin_layout Quotation \family typewriter \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset self.breaklines = False \end_layout \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout \begin_inset CommandInset label LatexCommand label name "alg:bibitem-init" \end_inset Constructor for \family typewriter BibitemInset \family default . \end_layout \end_inset \end_layout \end_inset \end_layout \begin_layout Standard The \family typewriter BoundedParser \family default will automatically parse the header and the contents. In the \family typewriter process() \family default method we will discard the first line with the \family typewriter LatexCommand \family default , and place the key from the second line as link destination. The class \family typewriter StringContainer \family default holds string constants; in our case we will have to isolate the key by splitting the string around the double quote \family typewriter " \family default , and then access the anchor with the same name. The contents will be set to the fixed string \family typewriter [ref] \family default . The result is shown in listing \begin_inset CommandInset ref LatexCommand ref reference "alg:bibitem-process" \end_inset . \end_layout \begin_layout Standard \begin_inset Float algorithm wide false sideways false status open \begin_layout Quotation \family typewriter \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset def process(self): \end_layout \begin_layout Quotation \family typewriter \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset #skip first line \end_layout \begin_layout Quotation \family typewriter \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset del self.contents[0] \end_layout \begin_layout Quotation \family typewriter \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset # parse second line: fixed string \end_layout \begin_layout Quotation \family typewriter \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset string = self.contents[0] \end_layout \begin_layout Quotation \family typewriter \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset # split around the " \end_layout \begin_layout Quotation \family typewriter \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset key = string.contents[0].split('"')[1] \end_layout \begin_layout Quotation \family typewriter \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset # make tag and contents \end_layout \begin_layout Quotation \family typewriter \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset self.tag = 'a name="' + key + '"' \end_layout \begin_layout Quotation \family typewriter \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset string.contents[0] = '[ref] ' \end_layout \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout \begin_inset CommandInset label LatexCommand label name "alg:bibitem-process" \end_inset Processing for \family typewriter BibitemInset \family default . \end_layout \end_inset \end_layout \end_inset \end_layout \begin_layout Standard And then we have to add the new class to the types parsed by the \family typewriter ContainerFactory \family default ; this has to be done outside the class definition. The complete file is shown in listing \begin_inset CommandInset ref LatexCommand ref reference "alg:bibitem-complete" \end_inset . \end_layout \begin_layout Standard \begin_inset Float algorithm wide false sideways false status open \begin_layout Quotation \family typewriter from parser import * \end_layout \begin_layout Quotation \family typewriter from output import * \end_layout \begin_layout Quotation \family typewriter from container import * \end_layout \begin_layout Quotation \family typewriter \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \end_layout \begin_layout Quotation \family typewriter class BibitemInset(Container): \end_layout \begin_layout Quotation \family typewriter \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset "An inset containing a bibitem command" \end_layout \begin_layout Quotation \family typewriter \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \end_layout \begin_layout Quotation \family typewriter \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset start = ' \backslash \backslash begin_inset CommandInset bibitem' \end_layout \begin_layout Quotation \family typewriter \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset ending = ' \backslash \backslash end_inset' \end_layout \begin_layout Quotation \family typewriter \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \end_layout \begin_layout Quotation \family typewriter \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset def __init__(self): \end_layout \begin_layout Quotation \family typewriter \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset self.parser = BoundedParser() \end_layout \begin_layout Quotation \family typewriter \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset self.output = TagOutput() \end_layout \begin_layout Quotation \family typewriter \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset self.breaklines = False \end_layout \begin_layout Quotation \family typewriter \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \end_layout \begin_layout Quotation \family typewriter \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset def process(self): \end_layout \begin_layout Quotation \family typewriter \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset #skip first line \end_layout \begin_layout Quotation \family typewriter \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset del self.contents[0] \end_layout \begin_layout Quotation \family typewriter \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset # parse second line: fixed string \end_layout \begin_layout Quotation \family typewriter \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset string = self.contents[0] \end_layout \begin_layout Quotation \family typewriter \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset # split around the " \end_layout \begin_layout Quotation \family typewriter \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset key = string.contents[0].split('"')[1] \end_layout \begin_layout Quotation \family typewriter \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset # make tag and contents \end_layout \begin_layout Quotation \family typewriter \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset self.tag = 'a name="' + key + '"' \end_layout \begin_layout Quotation \family typewriter \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset string.contents[0] = '[ref] ' \end_layout \begin_layout Quotation \family typewriter \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \end_layout \begin_layout Quotation \family typewriter ContainerFactory.types.append(BibitemInset) \end_layout \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout \begin_inset CommandInset label LatexCommand label name "alg:bibitem-complete" \end_inset Full listing for \family typewriter BibitemInset \family default . \end_layout \end_inset \end_layout \end_inset \end_layout \begin_layout Standard The end result of processing the command in listing \begin_inset CommandInset ref LatexCommand ref reference "alg:bibitem-command" \end_inset is a valid anchor: \end_layout \begin_layout Quotation \family typewriter [ref] \end_layout \begin_layout Standard The final touch is to make sure that the class is run, importing it in the file \family typewriter gen/factory.py \family default , as shown in listing \begin_inset CommandInset ref LatexCommand ref reference "alg:bibitem-include" \end_inset . This ensures that the \family typewriter ContainerFactory \family default will know what to do when it finds an element that corresponds to the \family typewriter BibitemInset \family default . \end_layout \begin_layout Standard \begin_inset Float algorithm wide false sideways false status open \begin_layout Quotation \family typewriter \SpecialChar \ldots{} \end_layout \begin_layout Quotation \family typewriter from structure import * \end_layout \begin_layout Quotation \family typewriter \series bold from bibitem import * \end_layout \begin_layout Quotation \family typewriter from container import * \end_layout \begin_layout Quotation \family typewriter \SpecialChar \ldots{} \end_layout \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout \begin_inset CommandInset label LatexCommand label name "alg:bibitem-include" \end_inset Importing the \family typewriter BibitemInset \family default from the factory file. \end_layout \end_inset \end_layout \end_inset \end_layout \begin_layout Standard Now this \series bold Container \series default is not too refined: the link text is fixed, and we need to do additional processing on the bibitem entry to show consecutive numbers. The approach is not very flexible either: e.g. anchor text is fixed. But in less than 20 lines we have parsed a new LyX command and have outputted valid, working XHTML code. The actual code is a bit different but follows the same principles; it can be found in \family typewriter src/bib/biblio.py \family default : in the classes \family typewriter BiblioCite \family default and \family typewriter BiblioEntry \family default , and it processes bibliography entries and citations (with all our missing bits) in about 50 lines. \end_layout \begin_layout Section Advanced Features \end_layout \begin_layout Standard This section tackles other, more complex features; all of them are included in current versions. \end_layout \begin_layout Subsection Parse Tree \begin_inset CommandInset label LatexCommand label name "sub:Parse-Tree" \end_inset \end_layout \begin_layout Standard On initialization of the \family typewriter ContainerFactory \family default , a \family typewriter ParseTree \family default is created to quickly pass each incoming LyX command to the appropriate containers, which are created on demand. For example, when the \family typewriter ContainerFactory \family default finds a command: \end_layout \begin_layout Quotation \family typewriter \backslash \backslash emph on \end_layout \begin_layout Standard it will create and initialize an \family typewriter EmphaticText \family default object. The \family typewriter ParseTree \family default works with words: it creates a tree where each keyword has its own node. At that node there may be a leaf, which is a \family typewriter Container \family default class, and/or additional branches that point to other nodes. If the tree finds a \family typewriter Container \family default leaf at the last node then it has found the right point; otherwise it must backtrack to the last node with a \family typewriter Container \family default leaf. \end_layout \begin_layout Standard Figure \begin_inset CommandInset ref LatexCommand ref reference "fig:parsetree" \end_inset shows a piece of the actual parse tree. You can see how if the string to parse is \family typewriter \backslash begin_inset LatexCommand \family default , at the node for the second keyword \family typewriter LatexCommand \family default there is no leaf, just two more branches \family typewriter label \family default and \family typewriter ref \family default . In this case the \family typewriter ParseTree \family default would backtrack to \family typewriter begin_inset \family default , and choose the generic \family typewriter Inset \family default . \end_layout \begin_layout Standard \begin_inset Float figure wide false sideways false status open \begin_layout Plain Layout \align center \begin_inset Graphics filename parse tree.svg \end_inset \end_layout \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout \begin_inset CommandInset label LatexCommand label name "fig:parsetree" \end_inset Portion of the parse tree. \end_layout \end_inset \end_layout \end_inset \end_layout \begin_layout Standard Parsing is much faster this way, but there are disadvantages; for one, parsing can only be done using whole words and not prefixes. SGML tags (such as \family typewriter \family default ) pose particular problems: sometimes they may appear with attributes (as in \family typewriter \family default ), and in this case the starting word is \family typewriter ' \family default character. So the parse tree removes any trailing \family typewriter '>' \family default , and the start string would be just \family typewriter \family default and \family typewriter \family default surrounding the parameter. For instance: e.g. \family typewriter \backslash bar{38} \family default becomes \family typewriter 38 \family default in the output. Decorating functions (in \family typewriter [FormulaConfig.decoratingfunctions] \family default ) place a symbol from in the definition above the parameter, and so on. \end_layout \begin_layout Standard Such simple processing is not always enough; there is a generic mechanism for producing complex output from a number of parameters. They are called hybrid functions. \end_layout \begin_layout Standard Each definition for a hybrid function contains: parser definition, output definition and a number of function tags. The parser definition tells eLyXer what to parse. Hybrid functions can have any number of optional parameters, denoted as \family typewriter [$p] \family default ; mandatory parameters are shown as \family typewriter {$p} \family default . Each parameter consists of the symbol \family typewriter $ \family default followed by a letter or number: \family typewriter $0 \family default , \family typewriter $p \family default . \end_layout \begin_layout Standard The output definition contains regular text, plus parameters and functions. Each function consists of the letter \family typewriter f \family default plus a number, such as \family typewriter f0 \family default ; and each is associated with a tagged HTML element. These function tags are the last part of the definition. Presently there can be as many as 10 function tags (from \family typewriter f0 \family default to \family typewriter f9 \family default ). \end_layout \begin_layout Standard Let us see a simple example, equivalent to the above formula -- a one-parameter, one-tag hybrid function: \end_layout \begin_layout Standard \begin_inset listings inline false status open \begin_layout Plain Layout \backslash fun:[{$p},f0{$p},span class="fun"] \end_layout \end_inset \end_layout \begin_layout Standard The only function tag \family typewriter f0 \family default generates the HTML tag \family typewriter \family default . Whenever eLyXer finds \family typewriter \backslash fun \family default in a math formula, it will parse one parameter and put it into \family typewriter $p \family default . Then it will generate \family typewriter f0{$p} \family default , i.e. apply the tag \family typewriter \family default . Putting it all together: \family typewriter \backslash fun{38} \family default becomes \family typewriter 38 \family default . \end_layout \begin_layout Standard Parameters can be parsed as a literal, in which case eLyXer will take everything between the brackets without parsing it. Literal parameters can be used within a tag definition. A real life hybrid function with literal parameters: \end_layout \begin_layout Standard \begin_inset listings inline false status open \begin_layout Plain Layout \backslash raisebox:[{$p!}{$1},f0{$1},span class="raisebox" style="vertical-align: $p;"] \end_layout \end_inset \end_layout \begin_layout Standard In this case there are two mandatory parameters, the first one literal and the second one a regular TeX expression. The output is just one function tag, in this case using the first mandatory parameter. For instance, \family typewriter \backslash raisebox{3cm}{5} \family default would generate: \end_layout \begin_layout Standard \begin_inset listings inline false status open \begin_layout Plain Layout 5 \end_layout \end_inset \end_layout \begin_layout Standard The parameter \family typewriter $p \family default is parsed as \family typewriter 3cm \family default , which is not parsed further. \end_layout \begin_layout Standard Hybrid functions are easy to configure once you get the hang of it. Adding new TeX commands, even complex ones, becomes simply a matter of configuration. \end_layout \begin_layout Section Developing and Contributing \end_layout \begin_layout Standard This chapter will show you how to further develop eLyXer and how to contribute your own code. \end_layout \begin_layout Subsection Distribution \begin_inset CommandInset label LatexCommand label name "sub:Distribution" \end_inset \end_layout \begin_layout Standard You will notice that in the \family typewriter src/ \family default folder there are several Python files, while in the main directory there is just a big one called \family typewriter elyxer.py \family default . The reason is that before distributing the source code is coalesced and placed on the main directory, so that users can run it without worrying about libraries, directories and the such. (They need of course to have Python 2.5 installed.) And the weapon is a little Python script called \family typewriter coalesce.py \family default that does the dirty job of parsing dependencies and inserting them into the main file. There is also a \family typewriter make \family default Bash script that takes care of permissions and generates the documentation. Just type \end_layout \begin_layout Quotation \family typewriter \color blue $ \color inherit ./make \end_layout \begin_layout Standard at the prompt. This coalesces all code and configuration into \family typewriter elyxer.py \family default . It is a primitive way perhaps to generate the \begin_inset Quotes eld \end_inset binary \begin_inset Quotes erd \end_inset (ok, not really a binary but a distributable Python file), but it works great. \end_layout \begin_layout Standard The \family typewriter make \family default script also runs all of the included tests to check that no functionality has been lost from one release to the next. These tests can also be run independently using the run-tests script: \end_layout \begin_layout Quotation \family typewriter \color blue $ \color inherit ./run-tests \end_layout \begin_layout Standard They are used to verify that no functionality is lost from one version to the next -- although issues can certainly slip undetected if there is no test for them. \end_layout \begin_layout Standard At the moment there is no way to do this packaging on non-Unix operating systems with a single script, e.g. a Windows \family typewriter .bat \family default script. However the steps themselves are trivial. \end_layout \begin_layout Subsection Debugging \end_layout \begin_layout Standard Code problems are quite difficult to debug using the full \family typewriter elyxer.py \family default file. It is much better to use the uncoalesced version instead, since it is quite modular and neatly divided. To do so you just need to locate the file \family typewriter src/principal.py \family default and run that instead of \family typewriter elyxer.py \family default . For example, if you are in the \family typewriter docs/ \family default directory and you want to convert \family typewriter math.lyx \family default you can run eLyXer as: \end_layout \begin_layout Quotation \family typewriter \color blue $ \color inherit ../src/principal.py math.lyx math.html \end_layout \begin_layout Standard For extra debugging information you can activate the --debug option: \end_layout \begin_layout Quotation \family typewriter \color blue $ \color inherit ../src/principal.py --debug math.lyx math.html \end_layout \begin_layout Standard This will make any traces more meaningful and will let you follow the code much more easily. \end_layout \begin_layout Subsection Configuration \begin_inset CommandInset label LatexCommand label name "sub:Configuration" \end_inset \end_layout \begin_layout Standard The make script does not just construct a single \family typewriter .py \family default file from all sources; it is also used to extract the configuration in human-readable form and create a Python file which is then coalesced with all the rest. The original configuration file (the one you should modify) is called \family typewriter base.cfg \family default , while the resulting Python file is called \family typewriter config.py \family default . \end_layout \begin_layout Standard The original configuration file uses this format: \end_layout \begin_layout Standard \begin_inset listings inline false status open \begin_layout Plain Layout [ContainerConfig.startendings] \end_layout \begin_layout Plain Layout \backslash begin_deeper: \backslash end_deeper \end_layout \begin_layout Plain Layout \backslash begin_inset: \backslash end_inset \end_layout \begin_layout Plain Layout \backslash begin_layout: \backslash end_layout \end_layout \end_inset \end_layout \begin_layout Standard where each section header is enclosed in square brackets; it contains an object name and a section name. In the example above the object is called \family typewriter ContainerConfig \family default , while the section is called \family typewriter startendings \family default . Inside each section there are a number of \family typewriter key:value \family default pairs separated by a colon; the key is used to reference the value in other Python code. \end_layout \begin_layout Standard To create \family typewriter config.py \family default go to the \family typewriter src/ \family default folder and type: \end_layout \begin_layout Quotation \family typewriter \color blue $ \color inherit ./exportconfig py \end_layout \begin_layout Standard This will create all configuration objects to be used inside your Python code, where each section will become an object attribute containing a map. For instance, to access the first value above \family typewriter \backslash end_deeper \family default you would write in your Python code: \end_layout \begin_layout Quotation \family typewriter ContainerConfig.startendings[' \backslash begin_deeper'] \end_layout \begin_layout Standard Each section can contain as many values as needed. \end_layout \begin_layout Subsection License \end_layout \begin_layout Standard eLyXer is published under the GPL, version 3 or later \begin_inset CommandInset citation LatexCommand cite key "stallman-gplv3" \end_inset . This basically means that you can modify the code and distribute the result as desired, as long as you publish your modifications under the same license. But consult a lawyer if you want an authoritative opinion. \end_layout \begin_layout Subsection Contributions \end_layout \begin_layout Standard All contributions will be published under this same license, so if you send them this way you implicitly give your consent. An explicit license grant would be even better and may be required for larger contributions. \end_layout \begin_layout Standard Please send any suggestions, patches, ideas and whatever else related to development to the \begin_inset CommandInset href LatexCommand href name "mailing list" target "elyxer-users@nongnu.org" type "mailto:" \end_inset . (Alternatively you may contact \begin_inset CommandInset href LatexCommand href name "elyxer@gmail.com" target "elyxer@gmail.com" type "mailto:" \end_inset privately.) If you are willing to create a patch and submit it, you should patch against the proper sources in \family typewriter src/ \family default and send it to the list. This will make everyone's lives better than if you patch against \family typewriter elyxer.py \family default . \end_layout \begin_layout Standard The first external patches have started arriving during late 2009 and early 2010 (provided by Olivier Ripoll, Geremy Condra and Simon South). You can join in the fun! \end_layout \begin_layout Section Roadmap \end_layout \begin_layout Standard You can see what user features are planned for the near feature in the \begin_inset CommandInset href LatexCommand href name "wish list" target "userguide.html#sub:Wish-List" \end_inset . \end_layout \begin_layout Standard After the release of eLyXer 1.0, the goal is full LyX document support; any deviation from the output of LyX on e.g. PDF will be considered as bugs. (Keep in mind that some deviations arise in an inherent limitation in the design of eLyXer, and these will logically not be considered as bugs.) \end_layout \begin_layout Standard For eLyXer 1.3.0 there are plans to convert it into a proper Python package so it can be installed using full source code (and not a coalesced script \family typewriter elyxer.py \family default that contains everything). Also, once ERTs are parsed, eLyXer might be extended for 1.3.0 to translate generic LaTeX documents. \end_layout \begin_layout Standard All this within the usual constraints: day job, family, etc. \end_layout \begin_layout Section Discarded Bits \end_layout \begin_layout Standard Some features suggested for eLyXer have been discarded; they do not fit with the design of eLyXer or are too much effort for the proposed gains. \end_layout \begin_layout Subsection Spellchecking \end_layout \begin_layout Standard LyX can use a spellchecker to verify the words used. However it is not interactive so you may forget to run it before generating a version. It is possible to integrate eLyXer with a spellchecker and verify the spelling before generating the HTML, but it is not clear that it can be done cleanly. \end_layout \begin_layout Subsection URL Checking \end_layout \begin_layout Standard Another fun possibility is to make eLyXer check all the external URLs embedded in the document. However the Python facilities for URL checking are not very mature, at least with Python 2.5: some of them do not return errors, others throw complex exceptions that have to be parsed\SpecialChar \ldots{} It is far easier to just create the HTML page and use wget (or a similar tool) to recursively check all links in the page. \end_layout \begin_layout Subsection Use of \family typewriter lyx2lyx \family default Framework \end_layout \begin_layout Standard Abdelrazak Younes suggests using the \family typewriter lyx2lyx \family default framework, which after all already knows about LyX formats \begin_inset CommandInset citation LatexCommand cite key "younes-elyxer" \end_inset . It is an interesting suggestion, but one that for now does not fit well with the design of eLyXer: a standalone tool to convert between two formats, or as Kernighan and Plauger put it, a standalone \emph on filter \emph default \begin_inset CommandInset citation LatexCommand cite key "kernighan-filters" \end_inset . Long-term maintenance might result a bit heavier with this approach though, especially if LyX changes to a different file format in the future. \end_layout \begin_layout Section FAQ \end_layout \begin_layout Description Q: I don't like how your tool outputs my document, what can I do? \end_layout \begin_layout Description A: First make sure that you are using the proper CSS file, i.e. copy the existing \family typewriter docs/lyx.css \family default file to your web page directory. Next try to customize the CSS file to your liking; it is a flexible approach that requires no code changes. Then try changing the code (and submitting the patch back). \end_layout \begin_layout Description Q: How is the code maintained? \end_layout \begin_layout Description A: It is kept in a \family typewriter git \family default repository \begin_inset CommandInset href LatexCommand href name "on Savannah" target "http://git.savannah.gnu.org/cgit/elyxer.git/" \end_inset . Patches in \family typewriter git \family default format are welcome (but keep in mind that my knowledge of \family typewriter git \family default is even shallower than my Python skills). \end_layout \begin_layout Description Q: I found a bug, what should I do? \end_layout \begin_layout Description A: Just report it to the \begin_inset CommandInset href LatexCommand href name "Savannah interface" target "https://savannah.nongnu.org/bugs/?func=additem&group=elyxer" \end_inset , to the \begin_inset CommandInset href LatexCommand href name "mailing list" target "elyxer-users@nongnu.org" type "mailto:" \end_inset or directly to the \begin_inset CommandInset href LatexCommand href name "main author" target "mailto:elyxer@gmail.com" type "mailto:" \end_inset . \end_layout \begin_layout Standard \begin_inset CommandInset nomencl_print LatexCommand printnomenclature \end_inset \end_layout \begin_layout Bibliography \begin_inset CommandInset bibitem LatexCommand bibitem key "savannah-elyxer" \end_inset Free Software Foundation, Inc.: eLyXer summary. \begin_inset Flex URL status collapsed \begin_layout Plain Layout https://savannah.nongnu.org/projects/elyxer/ \end_layout \end_inset \end_layout \begin_layout Bibliography \begin_inset CommandInset bibitem LatexCommand bibitem key "white-math" \end_inset S White: \begin_inset Quotes eld \end_inset Math in HTML with CSS \begin_inset Quotes erd \end_inset , accessed March 2009. \begin_inset Flex URL status collapsed \begin_layout Plain Layout http://www.zipcon.net/~swhite/docs/math/math.html \end_layout \end_inset \end_layout \begin_layout Bibliography \begin_inset CommandInset bibitem LatexCommand bibitem key "stallman-gplv3" \end_inset R S Stallman \emph on et al \emph default : \begin_inset Quotes eld \end_inset GNU GENERAL PUBLIC LICENSE \begin_inset Quotes erd \end_inset version 3, 20070629. \begin_inset Flex URL status collapsed \begin_layout Plain Layout http://www.gnu.org/copyleft/gpl.html \end_layout \end_inset \end_layout \begin_layout Bibliography \begin_inset CommandInset bibitem LatexCommand bibitem key "milde-mathml" \end_inset G Milde: \begin_inset Quotes eld \end_inset Re: eLyXer: LyX to HTML converter \begin_inset Quotes erd \end_inset , message to list \emph on lyx-devel \emph default , 20090309. \begin_inset Flex URL status collapsed \begin_layout Plain Layout http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg148627.html \end_layout \end_inset \end_layout \begin_layout Bibliography \begin_inset CommandInset bibitem LatexCommand bibitem key "younes-elyxer" \end_inset A Younes: \begin_inset Quotes eld \end_inset Re: eLyXer: LyX to HTML converter \begin_inset Quotes erd \end_inset , message to list \emph on lyx-devel \emph default , 20090309. \begin_inset Flex URL status collapsed \begin_layout Plain Layout http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg148634.html \end_layout \end_inset \end_layout \begin_layout Bibliography \begin_inset CommandInset bibitem LatexCommand bibitem key "kernighan-filters" \end_inset B W Kernighan, P J Plauger: \begin_inset Quotes eld \end_inset Software Tools \begin_inset Quotes erd \end_inset , ed. Addison-Wesley Professional 1976, p. 35. \end_layout \begin_layout Bibliography \begin_inset CommandInset bibitem LatexCommand bibitem key "lyx-devel" \end_inset Various authors: \begin_inset Quotes eld \end_inset lyx-devel mailing list \begin_inset Quotes erd \end_inset , accessed November 2009. \begin_inset Flex URL status collapsed \begin_layout Plain Layout http://www.mail-archive.com/lyx-devel@lists.lyx.org/ \end_layout \end_inset \end_layout \begin_layout Bibliography \begin_inset CommandInset bibitem LatexCommand bibitem key "git-download" \end_inset S Chacon: \begin_inset Quotes eld \end_inset Git -- Download \begin_inset Quotes erd \end_inset , accessed November 2009. \begin_inset Flex URL status collapsed \begin_layout Plain Layout http://git-scm.com/download \end_layout \end_inset \end_layout \begin_layout Bibliography \begin_inset CommandInset bibitem LatexCommand bibitem key "python-download" \end_inset Python community: \begin_inset Quotes eld \end_inset Download Python \begin_inset Quotes erd \end_inset , accessed November 2009. \begin_inset Flex URL status collapsed \begin_layout Plain Layout http://www.python.org/download/ \end_layout \end_inset \end_layout \end_body \end_document elyxer-1.2.5/forks/jras-elyxer/docs/changelog.html0000644000175000017500000016447312117061351021507 0ustar chennochenno eLyXer changelog

figure elyxer.png eLyXer Changelog

This document lists all public versions, the date they were released on and the changes they contain. For more information about eLyXer visit the main page.
  • 1.2.4 (unreleased):
    • Implemented generic converters, and lyx -C as an image converter (thanks, Tommaso!).
    • Implemented command \today: Mar 10, 2013.
    • Added a Russian translation (thanks, Vladimir!).
    • Solved a bug when parsing a BibTeX entry with a trailing comma (thanks, Bob!).
    • BibTeX: correctly use booktitle instead of journal in an @inproceedings entry (thanks, Pascal!).
    • Expose language information as additional markup (using the lang attribute in HTML).
    • Fix by Guenter Milde for math2html under Python 3.0.
    • Convert em-dash only when surrounded by spaces (thanks, Robert).
    • Fix by José Ramón Álvarez Sánchez of problem in simultaneous use of hover and end options for footnotes (thanks, Tim!).
  • 1.2.3 (2011-08-31):
    • Changed the license for math2html from Apache v2 to FreeBSD 2-clause license, to better suit integration with DocUtils.
    • Removed a false positive error which appeared during the tests: “* No title in”.
    • Added most commands in Günter Milde’s excellent list of Unicode to LaTeX commands, except categories mathaccent, mathfence, mathradical, mathover and mathunder. Examples: \hash as  ⋕ , \smalltriangleleft as .
    • Deprecated option --jsmath, users are encouraged to use --mathjax instead.
    • Added argument --mathjax remote to access the MathJax CDN instead of hit a local copy. Changed the Math showcase to work remotely by default.
    • Solved Debian bug 639712: eLyXer didn’t accept Unicode characters in --title option, added test.
    • Solved Savannah bug 33961: eLyXer didn’t support sub- or superscript insets as used in LyX 2.0, added test.
    • Solved installation problem when $PATH contains a directory which does not exist; the eLyXer binary was created with the same name as said directory. Now install.py should just ignore the directory. (Thanks, Jack!)
  • 1.2.2 (2011-06-12):
    • Bug in description: when a (non-empty) ERT is the first element of a description, use it as first word and make it bold.
    • Proper support for \scriptstyle and \scriptscriptstyle: script, scriptscript.
    • Bug #33156: CSS specification as in --css=lyx.css was not working, solved now.
    • Support for \noindent and \centering in ERTs.
    • Ignore BibTeX entries which are not publication entries. Show a debug message for non-referenced entries.
    • Understand command \& in BibTeX files.
    • Bumped Lyx format supported (--lyxformat) to 413 (LyX 2.0.0).
    • Solved error when parsing display formulas generated with LyX 2.0: "Formula beginning \begin_inset Formula is unknown" (thanks, Pascal!). Added test case.
    • Added a bunch of new symbols, including \textsection §, \textemdash — or \v{z} ž (thanks again, Pascal!).
    • Changed output characters for English quotes, from Unicode “ and ‘ to HTML entities &ldquo; and &lsquo; (thanks, Marco!).
    • Make Flex styles in titles work (thanks, Tiago!).
    • Make custom Flex CharStyles work: generate HTML spans of the same class as the Flex type (thanks again, Marco!).
  • 1.2.1 (2011-03-07):
    • Wish list: support for formatted references (showing the part name and number) and named references (showing the part title, equivalent to \nameref).
    • Wish list: include part titles in --splitpart navigation header.
    • Changed literal for previous page in --splitpart: now it’s “Prev” instead of “Previous”.
    • Bug in --notoclabels: removed the “.” after the part number but before the title shown in the TOC. “5. How to Make Friends” is now “5 How to Make Friends” (thanks, José Ramón!).
    • Allow math2html to be invoked using parameters (like --debug).
    • Bugs in ERT parsing: brackets {} are not parsed correctly across different ERTs. The TeX parser was being thrown off by escaped brackets as in {\{\}}, added test. Comments are ignored now.
    • Solved conflict in CSS between .script (used to properly layout super- and subscripts) and span.script (used for the script-type \mathscr and \mathcal fonts). Changed the latter to span.scriptfont, forcing an incompatible but unavoidable change in the CSS.
    • Forced span.scriptfont to be shown as italic so it’s properly displayed on Firefox.
    • Wish list: new option --googlecharts adds support for formula images generated using Google Charts.
    • Wish list: merged options --toc and --toctarget into --tocfor.
    • Wish list: options --splitpart and --tocfor (previously --toc) now work together. Also: the separate TOC has a link to the main page.
    • Bug in --splitpart combined with --notoclabels: unnumbered parts displayed an ugly colon as in “Next : Section”, now removed (thanks, José Ramón!).
    • Modified the spacing in formulas so that words in the mathnormal font now appear separated, as a product of variables.
    • Do not show limit symbols such as or in a larger font than the rest for inline formulas.
    • Added support for \textcircled: w⃝.
  • 1.2.0 (2011-01-30):
    • Bumped LyX version support to 410.
    • Correctly create big brackets for environments with odd alignments such as matrix (thanks, Günther!).
    • Create and use big brackets for fractions and other structures, if needed.
    • Added option --simplemath to avoid fancy math structures: do not generate multi-line Unicode brackets or stacked limits.
    • eLyXer is now a proper Python package, instead of just a coalesced script elyxer.py containing everything. However only the script is installed right now.
    • Interpret TeXCode (previously known as Evil Red Text) as TeX commands and formulas.
    • Support for TeX commands \textvisiblespace, \AmS, \parbox, \tag, \rule, and more: , AmS.
    • Support for \Game: .
    • Changed the navigation header for --splitpart so that the left and right spans overflow (thanks, Axel!).
    • Bug in --notoclabels: labels such as “Figure” should be omitted in the TOC, but not in captions (thanks again, Axel!).
    • Bug in --splitpart: empty navigation links caused the header to look unbalanced, fixed now with a non-breaking space. Also, up link in the main page used to point to itself; now it’s an empty link (more thanks, Axel!).
    • Support for \limits and \nolimits: control if the last symbol should show limits above or below the symbol or not.
    • Bug in \vspace: add the vertical space after the command, not before; or at least try to.
    • Bug in \raisebox: parse and display the contents as text mode.
    • Wish list: do not number captions in code listings.
    • Do not install as a module (to run as python -m elyxer) but only as a script (to run as elyxer.py).
  • 1.1.2 (2010-12-23):
    • Wish list: display large Unicode symbols for sums and integrals in display mode.
    • Also in display mode, place limits for commands that take them above or below the symbol, instead of to the right.
    • Support for new Flex insets: Code, MenuItem, Noun, Strong; new Argument, Phantom and line (ruler) insets; new style \strikeout; new LaTeX commands \href, \newline.
    • BibTeX: apply a combining function only to the following character, not to the next word.
    • Added reference format for vpageref (“on page #”).
    • Improved math macro parsing: optional parameters, literal parameters, single-letter parameters, parameter defaults with operations.
    • Display math cases, full-sized binomials (\dbinom) and array brackets using Unicode bracket pieces.
    • Change all table-type elements in formulas to spans and do the formatting in the CSS, to generate valid XHTML.
    • Support graceful degradation of fractions and roots when the CSS is not present.
    • Adjusted roots to insert the root power inside the radical symbol.
    • Adjusted nice fractions (34) to improve their appearance.
    • Support for all upright Greek letters: μ, τ.
  • 1.1.1 (2010-12-13):
    • Wish list: understand \url{} in BibTeX files.
    • Wish list: parse math formulas in BibTeX files.
    • Improved support for dotless i and j as \imath and \jmath: ı, ȷ.
    • Solved bug when parsing a quoted string inside a BibTeX file containing a comma.
    • Added math environments equation* and matrix.
    • Do not break inline formulas at whitespace (thanks, José Ramón!).
    • Break up the CSS into pieces, and generate an independent math.css for use within math2html.py.
    • Ignore hyphens in option names, so e.g. --split-part is equivalent to --splitpart.
    • Changed --forceformat to --imageformat (kept the old option for backwards compatibility).
    • Wish list: added --imageformat "copy" to just copy images instead of converting them.
    • Wish list: added option --embedcss "file.css" to embed the CSS styles in file.css into the resulting HTML.
    • Wish list: more than one --css options can be added to use several CSS files.
    • Wish list: display sub- and superscript aligned vertically (as in integrals).
  • 1.1.0 (2010-11-23):
    • Wish list: understand \setcounter in the preamble to set the number of the first Chapter or Section.
    • Generate a new math2html.py file with an API to convert raw LaTeX code to HTML, and a command line utility.
    • Wish list: new option --notoclabels to omit part labels in the TOC.
    • Wish list: make “show changes in the output” work for change tracking.
    • Solve an existing issue with Description and List layouts: correct splitting of first words when intermixing styles.
    • Show decorations using Unicode combining characters, whenever possible.
    • Support for \dddot: o⃛ (with combining character) and \widehat: ^abc (with character on top).
    • Wish list: add several options for footnote generation (align markers instead of using superscript, place markers at the bottom of the page, use symbols for markers…). Also added a generic --footnotes option to aggregate them all.
    • Wish list: use ps:use-cropbox=true in ImageMagick for PostScript and EPS images.
    • Support for dotless i and j: ı, ȷ.
  • 1.0.4 (2010-10-29):
    • Solved bug #31342: detect appendices as they appear instead of looking at the containing layout.
    • Also reported in bug #31342: set part name to “Appendix A-Z” in the TOC for appendices, instead of showing them as regular chapters or sections.
    • Also reported in bug #31342: number parts and books using roman numerals, as in “Part I” or “Book IV”.
    • Fixed bug due to wrapped float placement not being mandatory anymore, despite what EmbeddedObjects.lyx says (thanks, Hans!).
    • Solved bug #31351: do not number (or add to the TOC) any document parts inside comments.
    • Also in bug #31351: the bibliography should be added to the TOC if so configured (and not inside a comment), and split into its own page with --splitpart.
    • Also in bug #31351: show the bibliography in regular size, not smaller than the main text as before.
    • Changed header from “Bibliography” to “References” for document classes other than book and report.
    • Solved bug #31414: bootstrap creation of conf/config.py.
    • Also in bug #31414: remodeled unit tests to try out Python 2.4 only if present, and to remove test files from previous runs.
    • Show the “Abstract” header only for the first Abstract layout (thanks, Yaron!).
    • Do not separate consecutive Abstract paragraphs, and display the abstract in slightly smaller font size.
    • Solved bug #31345: ignore preamble and comments in BibTeX files. Use string definitions (@string) in other entries.
    • Also in bug #31345: avoid endless loops for undesired characters in BibTeX entries.
    • Support for \fbox, \boxed, \framebox and \fcolorbox: fbox, boxed, framebox.
  • 1.0.3 (2010-10-15):
    • Do not hide errors when parsing child documents.
    • Correctly convert documents even when images are not found.
    • Do not center the content in figure or table floats by default.
    • Correctly convert child documents even when inserted in layouts.
    • Generate navigation bars for first page created with --splitpart.
    • Added wishlist to the user guide to keep track of requested features.
    • Solved bug #31243: spaces and comments in formulas (command definitions, empty formulas…).
    • Also reported in bug #31243: do not add numbering twice to child documents, and ignore child documents in comments.
    • Added support for \stackrel: xR → y (thanks, José Ramón!).
    • Added a lot of escaped characters to BibTeX parsing: \~n, \’{\i}… Also added a field note to all BibTeX styles.
    • Show all references (even those not cited) in the bibliography if configured to do so.
    • Understand relative sizes (e.g. 10col%) in spaces (thanks, Uwe!).
  • 1.0.2 (2010-09-20):
    • Updated MathJax to version 1.0.1 — no changes to eLyXer documents are necessary.
    • Added option --noconvert to use images in their original formats, and avoid converting images altogether.
    • Output <object> tags for SVG images. Size information is not used as it causes problems on Firefox.
    • BibTeX: include booktitle tag for the @incollection format.
    • BibTex: added a tag <span class="bibcites"> around all bibliographical cites, so they can be e.g. superscripted.
    • Show footnotes as hovering text instead of as marginal notes. Make the default footnote marker a bluish superscript letter in brackets:  [A]  [A] like this.
    • Updated --lyxformat to 398 (2.0alpha5); added warning if document version is bigger than that.
    • Support for \textless and \textgreater: <, >.
    • Added adjustments for better printing to default CSS.
    • Added languages “british” and “american” (which translate to plain English).
    • Avoid extracting indexes out of the containing layout if there is anything else in there (thanks, Amy!). This bug caused some content to be lost (e.g. child documents) if they were inside the same layout as e.g. an alphabetical index.
  • 1.0.1 (2010-09-01):
    • BibTeX: more robust parsing, specifically: correctly parse entries separated by commas. Support all TeX commands already available in math formulae.
    • Support for \textasciitilde: ~, \textasciicircum: ^ and a few other \text… symbols. Also, \textrm, \textsf and \textnormal should be working now in equations: a + roman + sans-serif + normal + b.
    • Improved support for custom horizontal and vertical spaces; absolute measures can now be used.
    • Support for sizes in table columns, figures and boxes.
    • Solved bug in --nofooter which required a dummy argument (thanks, Yan!).
    • Corrected box styling: <div class="Frameless"> is now indeed frameless, while <div class="Framed"> no longer has a double border.
    • Solved bug in text handling which separated consecutive centered lines with a space.
    • Basic support for LyX change tracking.
  • 1.0.0 (2010-07-21):
    • Replicate the navigation bar for --splitpart at the bottom of pages. Use translated strings for “Previous”, “Up” and “Next” links. Also added an explanatory text to the “up” link in the navigation bar, as in: “Up: Chapter 1”.
    • Added partial table of contents to pages generated with --splitpart.
    • Dependency cleanup between code modules.
    • Child documents of type “verbatim input” are now correctly converted on versions of Python built without universal newline support.
    • Include Index and Nomenclature in the Table of Contents.
    • When an Index, TOC, List of Figures… and the like is embedded in another layout, do not follow the style of the layout (thanks, Yaron!).
    • Solved a couple of XHTML validation errors: removed asterisks (*) in anchor names, avoid empty rows in arrays or case statements.
    • Make index entries work in Descriptions. Also, mixed styles should work again within Descriptions.
    • Group certain layouts together, such as Quote and Quotation.
    • Improved output for algorithms: do not run lines together, and do not separate other lines with double space.
    • List of algorithms does now correctly extract the text from the caption.
    • Increased line height for h2 in the main CSS (thanks, Wolfgang!).
    • Better color support in formulas: \color, \textcolor, \colorbox. blue, blue.
    • Formulas and formula labels are not colored by default.
    • Improved Index output: there is only one anchor for each entry, and entries are not shown in italics.
    • Allow hierarchical index entries, of the form “Main ! Secondary ! Final”.
  • 0.99 (2010-06-24):
    • Added --splitpart to online help (thanks, Sven!).
    • Restored compatibility with Python 2.4 (lost in 0.98 by mistake), added test to ensure it does not happen again.
    • BibTeX: improved template definitions for Vancouver style.
    • BibTeX: better parsing of braces (in templates) and quotes (in .bib files). Nested braces in templates are supported.
    • BibTeX: variable citing styles. Enclose cites in brackets instead of using superscripts.
    • BibTeX: export all BibTeX variables in bib-… spans.
    • BibTeX: limited author parsing, support for surname abbreviations as in style alpha.
    • BibTeX: use the file tag to show a link to the local file.
    • Added \oint and friends as a bigsymbol: x·dx.
    • Support for \officialeuro: .
    • Fix captions in lists of figures which use standard layouts (thanks, Hans!).
    • Added option --template to use an HTML template and substitute <!--$content-->, <!--$title-->
    • Added option --copyright to add a copyright notice at the bottom (no longer generated by default). Deprecated old option --nocopy.
    • Added support for including files as a code listing.
  • 0.98 (2010-05-13):
    • MathJax: workaround bug in MSIE, that causes it to fail to render anything.
    • Add a margin to LyX-Code. Also improve line break separation inside LyX-Code.
    • Coalesce Python code: use relative paths when importing (thanks, Jack!).
    • Experimental installation script.
    • Avoid postprocessing child documents twice (thanks, Rainer!).
    • Solved bug when loading images from child documents in subdirectories (thanks, Rainer!).
    • Solved bug in image scaling when only one dimension is set (thanks, Wolfgang!).
    • Corrected issue with one-liner \lstset (thanks again, Rainer!).
    • Improved lists of figures, tables and algorithms: use short title, better labeling of floats.
    • Solved weird bug in float numbering when a chapter has only one layout.
    • Added \diagup and \diagdown: , .
    • First public release of option --splitpart [level]: split resulting web page at the given level.
    • Support for macros, both in LyX macro inset and as \newcommand.
    • Added URLs to most BibTeX formats.
    • Added BibTeX style “vancouver” for articles (thanks, John!).
    • Added a footer detailing eLyXer version and conversion date; it can be turned off with --nofooter.
  • 0.43 (2010-04-10):
    • Many BibTeX improvements: new style abbrvnat, conditional formatting, look up types in lowercase, understand “--” as dash.
    • Added options for mathematical equations: --jsmath to use jsMath and --mathjax to use MathJax.
    • Added command help to loremipsumize.py so it can be used outside of eLyXer.
    • Include internationalization files in .zip file.
    • Solved bug in table parsing: separate different plain layouts (thanks, Sara!).
    • eLyXer compressed files now contain a single directory called elyxer-$VERSION, instead of just elyxer.
    • Added italicized uppercase Greek letters: ΓΩ. De-italicized regular uppercase Greek letters: ΓΩ.
  • 0.42 (2010-03-17):
    • Changed author everywhere to the real name, to avoid any copyleft uncertainties.
    • Remove hook in the main text ([D→]) from margin notes.
    • Do not crash when BibTeX files are not found, just show an error.
    • Added support for some IPA characters, including ħ. Better parsing of \textipa text.
    • Added option --numberfoot to label footnotes with numbers instead of letters.
    • Solved bug in assignment of default formatting to references (thanks, Hans!).
    • Added option --raw to output raw HTML without header or footer.
    • Added French and Dutch translations.
    • Solved indenting problem for lists: only the first line was being indented.
  • 0.41 (2010-02-11):
    • Select the translation based on document language.
    • Added em-dash — such as in this sentence, , \textup.
    • Added option --converter inkscape to use Inkscape as SVG converter.
    • Solved bug when numbering unordered unique parts such as Part* (thanks, Geremy!).
    • Show error instead of crashing when included document does not exist.
    • Support for all box styles. In CSS: switched to outline-style instead of border for boxes.
    • Support for vertical space insets.
    • Support for references inside paragraphs and formatted references.
    • Listings are now converted using <pre> tags, instead of <code>. They are also justified left.
    • Solved bug that prevented numbered listings to appear numbered (thanks, Sam!).
    • Support for generic Flex insets, incuding Flex CharStyle:MenuItem.
    • All &nbsp; entities are now generated as the Unicode U+00A0 character.
    • New option --iso885915 to generate a document with ISO-8859-15 encoding.
    • Support for Sam Liddicott’s Newfangle module for literate programming.
    • Updated the developer guide for potential contributors; added link from the main page.
    • Support for \underbrace and \overbrace (as bars and without sub/superscripts).
  • 0.40 (2010-01-19):
    • Faster (about 25%) BibTeX file parsing.
    • Show version number after a crash.
    • Imported Jens Nöckel’s contributed list of LaTeX to Unicode mappings: , and many more.
    • Added support for compressed documents (Document ▷ Compressed).
    • Added configurable alignment support for equation environments (thanks, Jens!). Multiple labels per formula are correctly processed.
    • Added a couple of note insets for Tufte document classes, appearing as side notes without a reference (thanks, Joachim!).
    • Support for escaped characters in BibTeX files, added German umlauts for starters.
    • Support for internationalization using GNU gettext files. Added Spanish and German translations in the po/ folder.
    • Support for verbatim includes.
  • 0.39 (2009-12-20):
    • Avoid oversized images on IE6.
    • Solved several crashes with the LyX documentation (thanks, Uwe!).
    • Created script to lorem-ipsumize texts, found in src/loremipsumize.py.
    • Solved some issues with BibTeX parsing; now it should work with most real-world files (thanks, Ken!). Also improved error reporting and implemented a new way of line-by-line parsing from file, activated with --lowmem.
    • Support for binomial coefficients: (AB). Ignore commands \leftroot, \uproot. Generic support for variable commands in math mode.
    • Support for omitted aligned brackets: right) (thanks, Jens!).
    • Solved bug with image conversion from directories (thanks, Olivier!).
  • 0.38 (2009-12-03):
    • Resized all logos in the documentation.
    • Solved bug in paragraph indentation that indented all formula spans and elements.
    • Solved a couple of bugs in image scaling: wraps with images, images in figures.
    • Solved bug in TOC generation: article-class documents had their TOC depth off-by-one.
    • Solved bug with listings inserted in documents using LyX 1.6, and improved their looks.
    • Slight font size reduction on Firefox, and huge reduction on some other proprietary browsers. Now global font size specification is done using percents.
    • New commands: \gtrless: , \complement: , \measuredangle: , \sphericalangle: , \nmid: , \circeq: , \lessgtr: , \nparallel: .
  • 0.37 (2009-11-30):
    • Further improvements in float manipulation: figures enclosing other figures have their own tweaked CSS class (thanks, Olivier).
    • PNG and JPEG images are not rescaled anymore, and never shown above their maximum size. Width and height are set using CSS properties.
    • TOC generation for unordered entries (like Section*) and entries inserted in other layouts. Max TOC depth and max numbering depth are honored. Also solved bug in tagging of unordered parts.
    • Implemented indented paragraphs when specified in the document.
    • Horizontal fill is now shown as a fixed-width space.
    • Simplified postprocessing code. Inclusion of child documents is now done inside a Standard layout.
    • Support for commands \varkappa: ϰ, \varnothing: , \mathring: , \backprime: , \notin: , \hfill: , \circledR: ®, \hslash: .
    • New option --splitpart to split the output in multiple pages, one page per part; needs more tweaking.
  • 0.36 (2009-11-19):
    • New in-memory processing of a document before file output, activated by default. It includes: TOC generation (TOC entries admit typefaces, colors, weights, spaces, short titles but restrict most other content), sequential numbering to bibliography entries, lists of floats (figures, tables, algorithms), correct labeling of references and use of the embedded title as HTML title.
    • New option --lowmem to do one-pass filtering only, to preserve memory (keeping the old behavior).
    • Updated the developer guide.
    • Change the postprocessing of equation labels so that only one anchor is used for the whole equation.
    • Added \mathscr and a few script fonts: hello. Added several characters for math script (\mathscr), fraktur (\mathfrak) and blackboard (\mathbb) fonts, and implemented the translation to Unicode chars: , 𝔉, 𝔽.
    • New math commands: \dfrac, implemented as \cfrac; \c for cedilla, already implemented as characters and now as decoration: ; thick space \; and quotes ": " "; \hspace for horizontal space and \vspace for vertical space; and a few size commands: \big, \Big, \bigg, \Bigg, \middle.
    • Added a parent attribute to every Container, for easier processing.
    • Image conversion and display: process width and height in an image if both are present; use % width of image within a float to scale the float; set max scaling of images to 100% with max-width CSS attribute. (Thanks, Olivier and Uwe.)
    • Subfloats are numbered (a), (b) (instead of x.ya, x.yb).
    • Convert all pathnames for image conversion using sys.getfilesystemencoding().
  • 0.35 (2009-11-05):
    • Added new characters: \checkmark , \blacklozenge , \nexists , \mathcircumflex ^.
    • Updated all documentation to LyX 1.6.
    • Solved CSS validation error in table.align (thanks, Olivier).
    • Solved XHTML validation error in greyed out note, removing useless divs.
    • Add a space after a fraction and before the units: 32 km, (7)/(16) s.
    • Corrected display of float within a float (thanks again, Olivier!).
    • Modified the meaning of --toc to be an on/off switch; the old behavior is now under --toctarget.
    • Changed the 2009-11-05 option --cutpart to --splitpart: new option to split the output file in parts. Not yet working correctly (for instance, links are not redirected).
    • eLyXer now understands and processes new Graphics options: width 50col%, height 50theight% and friends (thanks, Uwe).
    • PDF images are cropped before conversion to PNG (thanks, Uwe).
    • Included child documents can be inserted using firstline and lastline (as seen in EmbeddedObjects.lyx).
  • 0.34 (2009-10-28):
    • Support for child document inclusion (Insert ▷ File ▷ Child Document…).
    • Avoid generating images on different directories (relative paths starting with ../).
    • Added \maltese and financial symbols $, €, ¥.
    • Removed annoying message “Unexpected end of bracket” when parsing empty brackets.
    • Support for \raisebox.
    • Created new structure of Writers, preparing for document segmentation and TOC generation.
  • 0.33 (2009-10-19):
    • New TOC generation process based on an already-generated HTML document, not ready for prime time yet.
    • Adapted --help option so that it shows the executable file as invoked (elyxer.py, elyxer or whatever). Expanded online help from this command.
    • Support for new text commands \textsf, \texttt, \textit, \textbf, \textsl, \textsc.
    • Properly parse all text commands \text…, including \textipa.
    • Support for \cfrac. Now regular \frac shows embedded formulas smaller.
    • Do not number equations containing *, like in \begin{align*}. (Once more, thanks Uwe.)
    • Properly align equations for AMS align environment. Other environments are parsed but not necessarily honored.
    • Correctly distinguish \epsilon ϵ from \varepsilon ε.
    • Added TeX-to-Unicode mappings from Markus Kuhn.
    • Support for \unitfrac.
    • Added \dots: .
  • 0.32 (2009-10-05):
    • Fixed unit processing. Now units appear separated by a space after the number.
    • Repaired use of AlphaCommands. Decorations so defined in the configuration file appear again as a single symbol: .
    • Added option --lyxformat to return the highest LyX format that eLyXer understands. Should help when integrating with lyx2lyx.
    • Improved TOC (table of contents) generation. Modified option --toc to accept an URL, and documented it.
    • Added option --target to add a target frame to every link.
    • Corrected equation numbering error: now all \begin{equation}…\end{equation} formulae are numbered. (Thanks once more, Uwe.)
  • 0.31 (2009-09-27):
    • Modified image parsing code to remove dependency on Python 2.5, expurging os.SEEK_CUR.
    • Removed the ill-fated elyxerconv.py library file (but kept io/convert.py), see lyx-devel thread. Now the file elyxer.py itself can be installed as a library, and run as a module with python -m.; see also lyx-devel thread.
    • eLyXer was added to the Python Package Index (PyPI) starting with 0.30. Now it should be automatically registered for each release.
    • Updated documentation (user guide, README file) with details of distutils installation.
    • Modified single string Containers (StringContainer, Constant) so that they appear as empty Containers — should speed up postprocessing.
    • Solved bug when parsing BibTeX files with incorrect lines.
    • Modified postprocessing to correctly process lists within tables.
    • In the process refactored postprocessing completely: now instead of unconditional postprocessor stages, each stage can add a postprocessing hook. Should be faster — but is indeed a bit slower.
  • 0.30 (2009-09-13):
    • Removed most comments from the final distributed file elyxer.py.
    • Added distutils support for cross-platform distribution. The library elyxerconv is added to local Python libraries.
    • Added command line option --forceformat: force eLyXer to convert all images to the given output format.
    • Switched all options in command line help to quotes: --title <title> is now --title "title".
    • Solved bug reported by Uwe Stöhr when reading Windows BibTeX file generated by JabRef. Now eLyXer tries several encodings for each file, initially UTF-8 and Cp1252.
    • Another bug, also reported by Uwe Stöhr, in branch selection. Added test branches.lyx.
  • 0.29 (2009-09-08):
    • Preliminary support for BibTeX. Configurable output styles (albeit cumbersome and quite primitive).
    • Added new cite commands citep, citet, citealt; and reference command prettyref.
    • A couple of new math commands: \ldots, \qquad.
  • 0.28 (2009-09-05):
    • Various fixes related to Windows integration.
    • Documented integration with LyX in the user guide.
  • 0.27 (2009-06-17):
    • Units without the magnitude (the number) are working.
    • Complex roots now working, added to the math showcase.
    • Leave JPEG images untransformed instead of converting them to PNG (or at least transform them to JPEG). Read JPEG image sizes.
    • More flexible configuration options for lists of values.
    • Added --destdirectory option to convert images into.
    • Image conversion from a different directory (or even with absolute paths) should work now.
    • Changed the whole infrastructure for formulae parsing. More structured parsing should now be possible, e.g. square brackets are first-class citizens.
    • Implemented nice fractions: 78.
    • Redid basic typography: default font is now sans-serif, which looks better on your average browser. Formulae have a bit more space around.
    • Imported the complete symbol list from the unicodesymbols file in LyX.
  • 0.26 (2009-06-10):
    • Added a lot of new LaTeX commands, both for Unicode symbols and for math functions.
    • New mechanism to include new lists of “command:Unicode” equivalents.
    • New decoration command \overrightarrow, to show a long arrow above some text.
    • Solved bug: --directory option was not working. A new test for this option added.
  • 0.25 (2009-06-08):
    • Added new characters: German dash separator, a few arrows, horizontal ellipsis.
    • Automatic insertion of release date in the changelog upon version release.
    • New formula commands: phantom text (for spacing), mbox (literal text).
    • Solved two bugs in URLs: make FlexURLs point to the link in their contents, and do not show “mailto:” in email links.
    • Properly display Date layouts as <h2>.
    • Display a FATAL error (and terminate) when trying to read beyond the end of the document.
    • Cross-platform support for newlines. Besides the Unix \n, now supports Windows (\r\n) and Mac OS X (\r) newlines.
    • Support for \unit command, showing units for a magnitude.
    • New format for formulae (instead of $…$ or \[…\]): \command{…}.
  • 0.24 (2009-06-02):
    • Show sum and integral limits correctly in Konqueror, Safari and Chrome.
    • Also show roots and arrays correctly in those browsers. Larger radical symbol looks better.
    • Added Math Showcase to test on browsershots.org.
    • Substituted medium mathematical spaces with midspaces for better browser compatibility.
    • Added --unicode option to switch on full Unicode output; right now only re-adds medium mathematical spaces.
    • Included all Greek letters, upper and lower case; and common math symbols.
    • Make title from command line option prevail over PDF title.
    • Specified minimum browser versions in the user guide and in the requirements.
    • Documented option --directory (it existed already but was not in the docs).
    • Option --toc can generate a Table Of Contents. Not documented because it is only a start for bigger things.
    • Repaired configuration export to base.cfg: now all objects in config.py are automatically exported.
  • 0.23 (2009-05-24):
    • Corrected numbering and appearance of subfloats.
    • Plain layouts are not reflected in HTML output.
    • Unified table parsing, moved table starts to configuration file.
    • Use unicode output in debug and error messages.
    • Automated testing now shows unified diff, to show the file that doesn’t pass the tests.
    • Finally got UTF-8 output right (hopefully).
    • Display floats with tables properly aligned, and on a white background. Listings are working too.
    • Show warning when document is created with LyX 1.4.x.
    • Transform \newpage to an empty paragraph.
    • Standard layouts can be <div> or nothing at all, generating valid XHTML.
    • Added nomenclature commands for 1.5.x.
    • Got Index and nomenclature working again, added test file so they don’t break anymore.
  • 0.22 (2009-05-15):
    • Modified user guide to explain --html option.
    • Solved a few bugs manifested when exporting to HTML 4.0 with --html.
    • More configurable containers: quote types, barred text, boxes, info insets…
    • Added note on the main page about slow mirrors and latest versions.
    • Standard layouts can now be translated to <div> or to <span>, depending on the context.
    • Command endings can be deduced from starts in configuration file.
    • A bunch of new math symbols: nu, angle brackets.
    • Generalized big brackets of several types. Consolidated parameter parsing in formulas.
    • Equation numbering is working.
    • Unknown commands are shown in red: \unknown.
  • 0.21 (2009-05-11):
    • Command line option --html to export to HTML 4.0.
    • Container endings are now configurable from the main config file.
    • Styles can be mixed and matched at will (like typewriter bold in blue).
    • All constant strings (such as “Table of contents”) should now be configurable.
    • Added a few more colors: green, magenta, cyan, yellow, white (those two were yellow and white).
  • 0.20 (2009-05-09):
    • Command line option --version to show the current version number and date.
    • Release date is now automatically added to the configuration.
    • Preliminary support for inset boxes.
    • Support for numbered listings.
    • Added <meta> tag for Content-Type, to ease importing into word processors.
    • Automated version generation, taking version number and date from config, and updating current version in the main page.
  • 0.19 (2009-05-07):
    • More powerful configuration file manipulation: export to generic config and Python files.
    • Start lines for every parsed structure can now be configured in the global base.cfg file.
    • New Info types package and textclass.
    • New formula symbols: up and down arrows, long double arrows, Gamma and Upsilon, mu, backslash.
    • Show line number and current line for generic errors.
    • Listings and document abstracts are displayed properly.
  • 0.18 (2009-05-04):
    • Wrap floats are separated by a bit of space (two exes, actually) from the text.
    • Solved bug when running without any arguments.
    • Main executable file is now changed from elyxer to elyxer.py, to prevent problems on platforms that require the extension; main source file has changed from elyxer.py to principal.py, to avoid confusion.
    • Moved all parsing code to the new package parse, and configuration files to package conf.
    • All configuration is now read from (and written to) plain text files.
  • 0.17 (2009-04-27):
    • Alignment of table cells is now respected, both horizontally and vertically.
    • Wrap floats are actually floated left or right.
    • Correctly interpret symbols in formulae: !, ;,  ≤ ,  ≥ ,  ≠ ,   ∈ , , and a few spaces.
    • In formulae, \displaystyle and friends are ignored.
    • Square roots are again displayed correctly, and even better than before!
    • Cases are working (not perfect: with a bar instead of a bracket, but working).
  • 0.16 (2009-04-22):
    • Document date is shown centered.
    • Special rows in a longtable are properly ignored.
    • Multicolumn cells are properly interpreted.
    • Sums and integral limits are properly displayed with respect to the symbol: i = 1.
  • 0.15 (2009-04-19):
    • Info insets (containing shortcuts) are now interpreted and shown.
    • LyX-Code is interpreted as a <pre> tag.
    • Reorganized code into a few packages.
    • Line numbers are not shown for utility classes.
    • Floats (figures, tables and algorithms) are now numbered.
    • Float links point to the start of the table or figure, not to the caption.
  • 0.14 (2009-04-13):
    • Deeper layouts (of any kind, not just in lists) are now supported.
    • Appendices are numbered correctly (as A, B, C…).
    • Sections in deeper layouts are numbered correctly too.
    • Double dash does not catch Unix-style options: --css is not converted -- while the version with spaces is.
    • Corrected serious bug in formula parsing affecting inline arrays.
    • Arrays with vertical alignment are correctly parsed.
  • 0.13 (2009-04-12):
    • Lists are correctly displayed, instead of one list per item.
    • Lists can contain nested layouts.
    • List layouts (not to mistake with Enumerate or Itemize lists) are processed correctly.
    • Changelog moved to separate document.
    • Read image sizes correctly on big-endian architectures (e.g. Mac OS X on PowerPC).
    • Numeration of chapters, sections… is working.
    • Error messages now show the line where they happen.
  • 0.12 (2009-04-05):
    • Arrays are parsed correctly and displayed acceptably.
    • Numbers and units are correctly separated.
    • Text decorations (such as ) are shown in line.
    • Variables are italicized.
    • Notes and comments are not output at all, greyed-out notes are shown in grey.
    • LyX guides parse completely.
  • 0.11 (2009-03-27):
    • Arrays are at least well parsed (but still show wrong).
    • Integrals and sums appear as large characters.
    • Appendices are separated from the main document.
    • The bibliography appears separated with a title.
    • Floats appear centered on-screen.
  • 0.10 (2009-03-23):
    • Better handling of footnotes and margin notes: not overlapping and with a reference in the text.
    • Better parsing of first word in a Description.
    • Short titles are ignored.
    • Added a few font families for equations. Not that they display too well…
  • 0.9 (2009-03-21):
    • Better formula parsing (including line breaks). Supports a few math fonts.
    • Supports menu separator, text with bar, nomenclature and many more quote types.
    • Single configuration file general.py.
    • Layout of type Space is not shown.
    • Supports branches. Inactive branches are not shown.
    • New symbols: greek letters, shapes: bullet, right triangle.
    • Added support for new style (1.6.x) index entries.
    • From LyX documentation: UserGuide.lyx is now working (except for some math functions).
  • 0.8 (2009-03-20):
    • Can be run from other directories than the one with the document.
    • Tables have light grey separations. Table spacing is now better adjusted.
    • Descriptions appear with the first word in bold), but only within the first text style. Changing style in the middle of a word may distract the algorithm.
    • Added support for Lyx notes (not rendered in the HTML), margin notes, pretty quotes ‘’, weird spaces.
    • Added support for new style (1.6.x) hyperlinks, labels and references, TOC, index.
    • Uses PDF title if present.
    • From LyX documentation: Intro.lyx is now working.
  • 0.7 (2009-03-16):
    • Images referenced by absolute path are converted to relative PNGs.
    • Range of supported quotes is greater. Unknown quotes are now marked as errors but do not make the tool fail.
    • Default CSS is always on nongnu.org, it can be changed via command line option --css.
    • Reinstated layout classes for unknown types.
    • Updated documentation to include how to run on Windows.
    • Added meta generator tag to all pages.
    • Added option --title to change the default page title.
    • Phonetic symbols appear in dark cyan: [sample].
    • Lots of small fixes and improvements to correctly parse the official LyX guides (UserGuide.lyx, EmbeddedObjects.lyx and Math.lyx).
  • 0.6 (2009-03-15):
    • Added Flex URLs, Flex code.
    • Works with Python 2.3.5, but not yet Mac OS X terminal.
    • Alignment now works right (and center and left).
    • Modified license files to comply with Savannah policies.
    • Added index page and logo.
  • 0.5 (2009-03-14):
    • Inset parameters are all parsed correctly (including spaces in image paths).
    • Formulae and tables should work again (including complex formatting).
    • Modified to (mostly) run under Python 2.3.5 (Mac OS X Tiger).
    • Processes layouts ending in ‘*’ (like ‘Section*’).
    • Runtime options for help and to disable the copyright notice, debug, quietness.
    • Accepts scaling for images.
    • Nested lists working.
  • 0.4 (2009-03-12):
    • When images do not exist warns but does not fail.
    • Author and title containing tags are properly processed.
    • Slanted text translated to italics.
    • Title no longer necessary to have a working document.
    • ERT is ignored. Status line (open/collapsed) is ignored.
    • Supports footnotes, newlines, bibitem entries and citations.
    • Dev guide includes a Container tutorial.
  • 0.3 (2009-03-11): Now works with generic Insets.
  • 0.2 (2009-03-11): ImageMagick is not required anymore.
  • 0.1 (2009-03-10): first public version.
elyxer-1.2.5/forks/jras-elyxer/install.py0000755000175000017500000001074712117061342017757 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20100411 # eLyXer multi-platform installation import platform import sys import os import shutil import gettext class Installer(object): "The eLyXer installer." elyxer = 'elyxer.py' separators = {'Linux':':', 'Windows':';', 'Darwin':':'} preferredstarts = ['/usr/bin', 'c:\\windows\\system', '/usr/local/bin'] def error(self, string): "Print an error string." self.show(string, sys.stderr) def show(self, message, channel = sys.stdout): "Show a message out of a channel" channel.write(message + '\n') def usage(self): "Show usage and requirements." self.error('Usage: python install.py') self.error('Requirements: Python version 2.3 and above, Python 3 not supported.') exit() def copybin(self): "Check permissions, try to copy binary file to any system path." for path in self.sortpaths(): try: shutil.copy2(Installer.elyxer, path) self.show('eLyXer installed as a binary in ' + path) self.show('Please run as "elyxer.py [options] input.lyx output.html" to use it') return except IOError: pass self.error('eLyXer not installed') def sortpaths(self): "Sort the environment variable PATH, place those containing 'python' first." "Remove a dot directory." system = platform.system() if not system in Installer.separators: self.error('Unknown operating system ' + system + '; aborting') self.usage() separator = Installer.separators[system] paths = os.environ['PATH'].split(separator) withpython = [] preferred = [] rest = [] while len(paths) > 0: path = paths.pop() if 'python' in path.lower(): withpython.append(path) elif self.ispreferred(path): preferred.append(path) elif path != '.': rest.append(path + '/') return withpython + preferred + rest def ispreferred(self, path): "Find out if the path starts with one of the preferred paths." for preferredstart in Installer.preferredstarts: if path.lower().startswith(preferredstart): return True return False def installmodule(self): "Install eLyXer as a module." return if not self.checkpermissions('install as a Python module'): return sys.argv.append('install') import setup self.show('eLyXer installed as a module.') self.show('You can also run eLyXer as "python -m elyxer [options] input.lyx output.html"') def installtranslations(self): "Install the translation files." destination = gettext.bindtextdomain('elyxer') self.copy('po/locale', destination) def copy(self, source, destination): "Recursively copy a file or directory into another." if not self.checkpermissions('install translation modules'): return if os.path.isfile(source): shutil.copy2(source, destination) return if not os.path.exists(destination): shutil.copytree(source, destination) return for filename in os.listdir(source): self.copy(os.path.join(source, filename), os.path.join(destination, filename)) def checkpermissions(self, purpose): "Check if the user has permissions as root to do something." if platform.system() == 'Linux': if os.getuid() != 0: self.error('Need to be root to ' + purpose) return False return True def checkversion(self): "Check the current version." version = platform.python_version_tuple() if int(version[0]) != 2: self.error('Invalid Python version ' + version[0] + '.' + version[1]) self.usage() if int(version[1]) < 3: self.usage() self.copybin() if int(version[1]) > 3: self.installmodule() self.installtranslations() Installer().checkversion() elyxer-1.2.5/forks/jras-elyxer/gpl-3.0-standalone.html0000644000175000017500000010764212117061342022031 0ustar chennochenno GNU General Public License - GNU Project - Free Software Foundation (FSF)

GNU GENERAL PUBLIC LICENSE

Version 3, 29 June 2007

Copyright © 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

How to Apply These Terms to Your New Programs

If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms.

To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the “copyright” line and a pointer to where the full notice is found.

    <one line to give the program's name and a brief idea of what it does.>
    Copyright (C) <year>  <name of author>

    This program is free software: 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 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
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

Also add information on how to contact you by electronic and paper mail.

If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode:

    <program>  Copyright (C) <year>  <name of author>
    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
    This is free software, and you are welcome to redistribute it
    under certain conditions; type `show c' for details.

The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an “about box”.

You should also get your employer (if you work as a programmer) or school, if any, to sign a “copyright disclaimer” for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see <http://www.gnu.org/licenses/>.

The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read <http://www.gnu.org/philosophy/why-not-lgpl.html>.

elyxer-1.2.5/forks/jras-elyxer/math2html.py0000755000175000017500000054343012117061350020210 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # math2html: convert LaTeX equations to HTML output. # # Copyright (C) 2009-2011 Alex Fernández # # Released under the terms of the `2-Clause BSD license'_, in short: # Copying and distribution of this file, with or without modification, # are permitted in any medium without royalty provided the copyright # notice and this notice are preserved. # This file is offered as-is, without any warranty. # # .. _2-Clause BSD license: http://www.spdx.org/licenses/BSD-2-Clause # Based on eLyXer: convert LyX source files to HTML output. # http://elyxer.nongnu.org/ # --end-- # Alex 20101110 # eLyXer standalone formula conversion to HTML. import sys class Trace(object): "A tracing class" debugmode = False quietmode = False showlinesmode = False prefix = None def debug(cls, message): "Show a debug message" if not Trace.debugmode or Trace.quietmode: return Trace.show(message, sys.stdout) def message(cls, message): "Show a trace message" if Trace.quietmode: return if Trace.prefix and Trace.showlinesmode: message = Trace.prefix + message Trace.show(message, sys.stdout) def error(cls, message): "Show an error message" message = '* ' + message if Trace.prefix and Trace.showlinesmode: message = Trace.prefix + message Trace.show(message, sys.stderr) def fatal(cls, message): "Show an error message and terminate" Trace.error('FATAL: ' + message) exit(-1) def show(cls, message, channel): "Show a message out of a channel" if sys.version_info < (3,0): message = message.encode('utf-8') channel.write(message + '\n') debug = classmethod(debug) message = classmethod(message) error = classmethod(error) fatal = classmethod(fatal) show = classmethod(show) import os.path import sys class BibStylesConfig(object): "Configuration class from elyxer.config file" abbrvnat = { u'@article':u'$authors. $title. $journal,{ {$volume:}$pages,} $month $year.{ doi: $doi.}{ URL $url.}{ $note.}', u'cite':u'$surname($year)', u'default':u'$authors. $title. $publisher, $year.{ URL $url.}{ $note.}', } alpha = { u'@article':u'$authors. $title.{ $journal{, {$volume}{($number)}}{: $pages}{, $year}.}{ $url.}{ $filename.}{ $note.}', u'cite':u'$Sur$YY', u'default':u'$authors. $title.{ $journal,} $year.{ $url.}{ $filename.}{ $note.}', } authordate2 = { u'@article':u'$authors. $year. $title. $journal, $volume($number), $pages.{ URL $url.}{ $note.}', u'@book':u'$authors. $year. $title. $publisher.{ URL $url.}{ $note.}', u'cite':u'$surname, $year', u'default':u'$authors. $year. $title. $publisher.{ URL $url.}{ $note.}', } default = { u'@article':u'$authors: “$title”, $journal,{ pp. $pages,} $year.{ URL $url.}{ $note.}', u'@book':u'{$authors: }$title{ ($editor, ed.)}.{{ $publisher,} $year.}{ URL $url.}{ $note.}', u'@booklet':u'$authors: $title.{{ $publisher,} $year.}{ URL $url.}{ $note.}', u'@conference':u'$authors: “$title”, $journal,{ pp. $pages,} $year.{ URL $url.}{ $note.}', u'@inbook':u'$authors: $title.{{ $publisher,} $year.}{ URL $url.}{ $note.}', u'@incollection':u'$authors: $title{ in $booktitle{ ($editor, ed.)}}.{{ $publisher,} $year.}{ URL $url.}{ $note.}', u'@inproceedings':u'$authors: “$title”, $booktitle,{ pp. $pages,} $year.{ URL $url.}{ $note.}', u'@manual':u'$authors: $title.{{ $publisher,} $year.}{ URL $url.}{ $note.}', u'@mastersthesis':u'$authors: $title.{{ $publisher,} $year.}{ URL $url.}{ $note.}', u'@misc':u'$authors: $title.{{ $publisher,}{ $howpublished,} $year.}{ URL $url.}{ $note.}', u'@phdthesis':u'$authors: $title.{{ $publisher,} $year.}{ URL $url.}{ $note.}', u'@proceedings':u'$authors: “$title”, $journal,{ pp. $pages,} $year.{ URL $url.}{ $note.}', u'@techreport':u'$authors: $title, $year.{ URL $url.}{ $note.}', u'@unpublished':u'$authors: “$title”, $journal, $year.{ URL $url.}{ $note.}', u'cite':u'$index', u'default':u'$authors: $title.{{ $publisher,} $year.}{ URL $url.}{ $note.}', } defaulttags = { u'YY':u'??', u'authors':u'', u'surname':u'', } ieeetr = { u'@article':u'$authors, “$title”, $journal, vol. $volume, no. $number, pp. $pages, $year.{ URL $url.}{ $note.}', u'@book':u'$authors, $title. $publisher, $year.{ URL $url.}{ $note.}', u'cite':u'$index', u'default':u'$authors, “$title”. $year.{ URL $url.}{ $note.}', } plain = { u'@article':u'$authors. $title.{ $journal{, {$volume}{($number)}}{:$pages}{, $year}.}{ URL $url.}{ $note.}', u'@book':u'$authors. $title. $publisher,{ $month} $year.{ URL $url.}{ $note.}', u'@incollection':u'$authors. $title.{ In $booktitle {($editor, ed.)}.} $publisher,{ $month} $year.{ URL $url.}{ $note.}', u'@inproceedings':u'$authors. $title. { $booktitle{, {$volume}{($number)}}{:$pages}{, $year}.}{ URL $url.}{ $note.}', u'cite':u'$index', u'default':u'{$authors. }$title.{{ $publisher,} $year.}{ URL $url.}{ $note.}', } vancouver = { u'@article':u'$authors. $title. $journal, $year{;{$volume}{($number)}{:$pages}}.{ URL: $url.}{ $note.}', u'@book':u'$authors. $title. {$publisher, }$year.{ URL: $url.}{ $note.}', u'cite':u'$index', u'default':u'$authors. $title; {$publisher, }$year.{ $howpublished.}{ URL: $url.}{ $note.}', } class BibTeXConfig(object): "Configuration class from elyxer.config file" replaced = { u'--':u'—', u'..':u'.', } class ContainerConfig(object): "Configuration class from elyxer.config file" endings = { u'Align':u'\\end_layout', u'BarredText':u'\\bar', u'BoldText':u'\\series', u'Cell':u'':u'>', } html = { u'/>':u'>', } iso885915 = { u' ':u' ', u' ':u' ', u' ':u' ', } nonunicode = { u' ':u' ', } class FormulaConfig(object): "Configuration class from elyxer.config file" alphacommands = { u'\\AA':u'Å', u'\\AE':u'Æ', u'\\AmS':u'AmS', u'\\Angstroem':u'Å', u'\\DH':u'Ð', u'\\Koppa':u'Ϟ', u'\\L':u'Ł', u'\\Micro':u'µ', u'\\O':u'Ø', u'\\OE':u'Œ', u'\\Sampi':u'Ϡ', u'\\Stigma':u'Ϛ', u'\\TH':u'Þ', u'\\aa':u'å', u'\\ae':u'æ', u'\\alpha':u'α', u'\\beta':u'β', u'\\delta':u'δ', u'\\dh':u'ð', u'\\digamma':u'ϝ', u'\\epsilon':u'ϵ', u'\\eta':u'η', u'\\eth':u'ð', u'\\gamma':u'γ', u'\\i':u'ı', u'\\imath':u'ı', u'\\iota':u'ι', u'\\j':u'ȷ', u'\\jmath':u'ȷ', u'\\kappa':u'κ', u'\\koppa':u'ϟ', u'\\l':u'ł', u'\\lambda':u'λ', u'\\mu':u'μ', u'\\nu':u'ν', u'\\o':u'ø', u'\\oe':u'œ', u'\\omega':u'ω', u'\\phi':u'φ', u'\\pi':u'π', u'\\psi':u'ψ', u'\\rho':u'ρ', u'\\sampi':u'ϡ', u'\\sigma':u'σ', u'\\ss':u'ß', u'\\stigma':u'ϛ', u'\\tau':u'τ', u'\\tcohm':u'Ω', u'\\textcrh':u'ħ', u'\\th':u'þ', u'\\theta':u'θ', u'\\upsilon':u'υ', u'\\varDelta':u'∆', u'\\varGamma':u'Γ', u'\\varLambda':u'Λ', u'\\varOmega':u'Ω', u'\\varPhi':u'Φ', u'\\varPi':u'Π', u'\\varPsi':u'Ψ', u'\\varSigma':u'Σ', u'\\varTheta':u'Θ', u'\\varUpsilon':u'Υ', u'\\varXi':u'Ξ', u'\\varbeta':u'ϐ', u'\\varepsilon':u'ε', u'\\varkappa':u'ϰ', u'\\varphi':u'φ', u'\\varpi':u'ϖ', u'\\varrho':u'ϱ', u'\\varsigma':u'ς', u'\\vartheta':u'ϑ', u'\\xi':u'ξ', u'\\zeta':u'ζ', } array = { u'begin':u'\\begin', u'cellseparator':u'&', u'end':u'\\end', u'rowseparator':u'\\\\', } bigbrackets = { u'(':[u'⎛',u'⎜',u'⎝',], u')':[u'⎞',u'⎟',u'⎠',], u'[':[u'⎡',u'⎢',u'⎣',], u']':[u'⎤',u'⎥',u'⎦',], u'{':[u'⎧',u'⎪',u'⎨',u'⎩',], u'|':[u'|',], u'}':[u'⎫',u'⎪',u'⎬',u'⎭',], u'∥':[u'∥',], } bigsymbols = { u'∑':[u'⎲',u'⎳',], u'∫':[u'⌠',u'⌡',], } bracketcommands = { u'\\left':u'span class="symbol"', u'\\left.':u'', u'\\middle':u'span class="symbol"', u'\\right':u'span class="symbol"', u'\\right.':u'', } combiningfunctions = { u'\\"':u'̈', u'\\\'':u'́', u'\\^':u'̂', u'\\`':u'̀', u'\\acute':u'́', u'\\bar':u'̄', u'\\breve':u'̆', u'\\c':u'̧', u'\\check':u'̌', u'\\dddot':u'⃛', u'\\ddot':u'̈', u'\\dot':u'̇', u'\\grave':u'̀', u'\\hat':u'̂', u'\\mathring':u'̊', u'\\overleftarrow':u'⃖', u'\\overrightarrow':u'⃗', u'\\r':u'̊', u'\\s':u'̩', u'\\textcircled':u'⃝', u'\\textsubring':u'̥', u'\\tilde':u'̃', u'\\v':u'̌', u'\\vec':u'⃗', u'\\~':u'̃', } commands = { u'\\ ':u' ', u'\\!':u'', u'\\#':u'#', u'\\$':u'$', u'\\%':u'%', u'\\&':u'&', u'\\,':u' ', u'\\:':u' ', u'\\;':u' ', u'\\AC':u'∿', u'\\APLcomment':u'⍝', u'\\APLdownarrowbox':u'⍗', u'\\APLinput':u'⍞', u'\\APLinv':u'⌹', u'\\APLleftarrowbox':u'⍇', u'\\APLlog':u'⍟', u'\\APLrightarrowbox':u'⍈', u'\\APLuparrowbox':u'⍐', u'\\Box':u'□', u'\\Bumpeq':u'≎', u'\\CIRCLE':u'●', u'\\Cap':u'⋒', u'\\CapitalDifferentialD':u'ⅅ', u'\\CheckedBox':u'☑', u'\\Circle':u'○', u'\\Coloneqq':u'⩴', u'\\ComplexI':u'ⅈ', u'\\ComplexJ':u'ⅉ', u'\\Corresponds':u'≙', u'\\Cup':u'⋓', u'\\Delta':u'Δ', u'\\Diamond':u'◇', u'\\Diamondblack':u'◆', u'\\Diamonddot':u'⟐', u'\\DifferentialD':u'ⅆ', u'\\Downarrow':u'⇓', u'\\EUR':u'€', u'\\Euler':u'ℇ', u'\\ExponetialE':u'ⅇ', u'\\Finv':u'Ⅎ', u'\\Game':u'⅁', u'\\Gamma':u'Γ', u'\\Im':u'ℑ', u'\\Join':u'⨝', u'\\LEFTCIRCLE':u'◖', u'\\LEFTcircle':u'◐', u'\\LHD':u'◀', u'\\Lambda':u'Λ', u'\\Lbag':u'⟅', u'\\Leftarrow':u'⇐', u'\\Lleftarrow':u'⇚', u'\\Longleftarrow':u'⟸', u'\\Longleftrightarrow':u'⟺', u'\\Longrightarrow':u'⟹', u'\\Lparen':u'⦅', u'\\Lsh':u'↰', u'\\Mapsfrom':u'⇐|', u'\\Mapsto':u'|⇒', u'\\Omega':u'Ω', u'\\P':u'¶', u'\\Phi':u'Φ', u'\\Pi':u'Π', u'\\Pr':u'Pr', u'\\Psi':u'Ψ', u'\\Qoppa':u'Ϙ', u'\\RHD':u'▶', u'\\RIGHTCIRCLE':u'◗', u'\\RIGHTcircle':u'◑', u'\\Rbag':u'⟆', u'\\Re':u'ℜ', u'\\Rparen':u'⦆', u'\\Rrightarrow':u'⇛', u'\\Rsh':u'↱', u'\\S':u'§', u'\\Sigma':u'Σ', u'\\Square':u'☐', u'\\Subset':u'⋐', u'\\Sun':u'☉', u'\\Supset':u'⋑', u'\\Theta':u'Θ', u'\\Uparrow':u'⇑', u'\\Updownarrow':u'⇕', u'\\Upsilon':u'Υ', u'\\Vdash':u'⊩', u'\\Vert':u'∥', u'\\Vvdash':u'⊪', u'\\XBox':u'☒', u'\\Xi':u'Ξ', u'\\Yup':u'⅄', u'\\\\':u'
', u'\\_':u'_', u'\\aleph':u'ℵ', u'\\amalg':u'∐', u'\\anchor':u'⚓', u'\\angle':u'∠', u'\\aquarius':u'♒', u'\\arccos':u'arccos', u'\\arcsin':u'arcsin', u'\\arctan':u'arctan', u'\\arg':u'arg', u'\\aries':u'♈', u'\\arrowbullet':u'➢', u'\\ast':u'∗', u'\\asymp':u'≍', u'\\backepsilon':u'∍', u'\\backprime':u'‵', u'\\backsimeq':u'⋍', u'\\backslash':u'\\', u'\\ballotx':u'✗', u'\\barwedge':u'⊼', u'\\because':u'∵', u'\\beth':u'ℶ', u'\\between':u'≬', u'\\bigcap':u'∩', u'\\bigcirc':u'○', u'\\bigcup':u'∪', u'\\bigodot':u'⊙', u'\\bigoplus':u'⊕', u'\\bigotimes':u'⊗', u'\\bigsqcup':u'⊔', u'\\bigstar':u'★', u'\\bigtriangledown':u'▽', u'\\bigtriangleup':u'△', u'\\biguplus':u'⊎', u'\\bigvee':u'∨', u'\\bigwedge':u'∧', u'\\biohazard':u'☣', u'\\blacklozenge':u'⧫', u'\\blacksmiley':u'☻', u'\\blacksquare':u'■', u'\\blacktriangle':u'▲', u'\\blacktriangledown':u'▼', u'\\blacktriangleleft':u'◂', u'\\blacktriangleright':u'▶', u'\\blacktriangleup':u'▴', u'\\bot':u'⊥', u'\\bowtie':u'⋈', u'\\box':u'▫', u'\\boxast':u'⧆', u'\\boxbar':u'◫', u'\\boxbox':u'⧈', u'\\boxbslash':u'⧅', u'\\boxcircle':u'⧇', u'\\boxdot':u'⊡', u'\\boxminus':u'⊟', u'\\boxplus':u'⊞', u'\\boxslash':u'⧄', u'\\boxtimes':u'⊠', u'\\bullet':u'•', u'\\bumpeq':u'≏', u'\\cancer':u'♋', u'\\cap':u'∩', u'\\capricornus':u'♑', u'\\cat':u'⁀', u'\\cdot':u'⋅', u'\\cdots':u'⋯', u'\\cent':u'¢', u'\\centerdot':u'∙', u'\\checkmark':u'✓', u'\\chi':u'χ', u'\\circ':u'○', u'\\circeq':u'≗', u'\\circlearrowleft':u'↺', u'\\circlearrowright':u'↻', u'\\circledR':u'®', u'\\circledast':u'⊛', u'\\circledbslash':u'⦸', u'\\circledcirc':u'⊚', u'\\circleddash':u'⊝', u'\\circledgtr':u'⧁', u'\\circledless':u'⧀', u'\\clubsuit':u'♣', u'\\coloneqq':u'≔', u'\\complement':u'∁', u'\\cong':u'≅', u'\\coprod':u'∐', u'\\copyright':u'©', u'\\cos':u'cos', u'\\cosh':u'cosh', u'\\cot':u'cot', u'\\coth':u'coth', u'\\csc':u'csc', u'\\cup':u'∪', u'\\curlyvee':u'⋎', u'\\curlywedge':u'⋏', u'\\curvearrowleft':u'↶', u'\\curvearrowright':u'↷', u'\\dag':u'†', u'\\dagger':u'†', u'\\daleth':u'ℸ', u'\\dashleftarrow':u'⇠', u'\\dashv':u'⊣', u'\\ddag':u'‡', u'\\ddagger':u'‡', u'\\ddots':u'⋱', u'\\deg':u'deg', u'\\det':u'det', u'\\diagdown':u'╲', u'\\diagup':u'╱', u'\\diameter':u'⌀', u'\\diamond':u'◇', u'\\diamondsuit':u'♦', u'\\dim':u'dim', u'\\div':u'÷', u'\\divideontimes':u'⋇', u'\\dotdiv':u'∸', u'\\doteq':u'≐', u'\\doteqdot':u'≑', u'\\dotplus':u'∔', u'\\dots':u'…', u'\\doublebarwedge':u'⌆', u'\\downarrow':u'↓', u'\\downdownarrows':u'⇊', u'\\downharpoonleft':u'⇃', u'\\downharpoonright':u'⇂', u'\\dsub':u'⩤', u'\\earth':u'♁', u'\\eighthnote':u'♪', u'\\ell':u'ℓ', u'\\emptyset':u'∅', u'\\eqcirc':u'≖', u'\\eqcolon':u'≕', u'\\eqsim':u'≂', u'\\euro':u'€', u'\\exists':u'∃', u'\\exp':u'exp', u'\\fallingdotseq':u'≒', u'\\fcmp':u'⨾', u'\\female':u'♀', u'\\flat':u'♭', u'\\forall':u'∀', u'\\fourth':u'⁗', u'\\frown':u'⌢', u'\\frownie':u'☹', u'\\gcd':u'gcd', u'\\gemini':u'♊', u'\\geq)':u'≥', u'\\geqq':u'≧', u'\\geqslant':u'≥', u'\\gets':u'←', u'\\gg':u'≫', u'\\ggg':u'⋙', u'\\gimel':u'ℷ', u'\\gneqq':u'≩', u'\\gnsim':u'⋧', u'\\gtrdot':u'⋗', u'\\gtreqless':u'⋚', u'\\gtreqqless':u'⪌', u'\\gtrless':u'≷', u'\\gtrsim':u'≳', u'\\guillemotleft':u'«', u'\\guillemotright':u'»', u'\\hbar':u'ℏ', u'\\heartsuit':u'♥', u'\\hfill':u' ', u'\\hom':u'hom', u'\\hookleftarrow':u'↩', u'\\hookrightarrow':u'↪', u'\\hslash':u'ℏ', u'\\idotsint':u'∫⋯∫', u'\\iiint':u'', u'\\iint':u'', u'\\imath':u'ı', u'\\inf':u'inf', u'\\infty':u'∞', u'\\intercal':u'⊺', u'\\interleave':u'⫴', u'\\invamp':u'⅋', u'\\invneg':u'⌐', u'\\jmath':u'ȷ', u'\\jupiter':u'♃', u'\\ker':u'ker', u'\\land':u'∧', u'\\landupint':u'', u'\\lang':u'⟪', u'\\langle':u'⟨', u'\\lblot':u'⦉', u'\\lbrace':u'{', u'\\lbrace)':u'{', u'\\lbrack':u'[', u'\\lceil':u'⌈', u'\\ldots':u'…', u'\\leadsto':u'⇝', u'\\leftarrow)':u'←', u'\\leftarrowtail':u'↢', u'\\leftarrowtobar':u'⇤', u'\\leftharpoondown':u'↽', u'\\leftharpoonup':u'↼', u'\\leftleftarrows':u'⇇', u'\\leftleftharpoons':u'⥢', u'\\leftmoon':u'☾', u'\\leftrightarrow':u'↔', u'\\leftrightarrows':u'⇆', u'\\leftrightharpoons':u'⇋', u'\\leftthreetimes':u'⋋', u'\\leo':u'♌', u'\\leq)':u'≤', u'\\leqq':u'≦', u'\\leqslant':u'≤', u'\\lessdot':u'⋖', u'\\lesseqgtr':u'⋛', u'\\lesseqqgtr':u'⪋', u'\\lessgtr':u'≶', u'\\lesssim':u'≲', u'\\lfloor':u'⌊', u'\\lg':u'lg', u'\\lgroup':u'⟮', u'\\lhd':u'⊲', u'\\libra':u'♎', u'\\lightning':u'↯', u'\\limg':u'⦇', u'\\liminf':u'liminf', u'\\limsup':u'limsup', u'\\ll':u'≪', u'\\llbracket':u'⟦', u'\\llcorner':u'⌞', u'\\lll':u'⋘', u'\\ln':u'ln', u'\\lneqq':u'≨', u'\\lnot':u'¬', u'\\lnsim':u'⋦', u'\\log':u'log', u'\\longleftarrow':u'⟵', u'\\longleftrightarrow':u'⟷', u'\\longmapsto':u'⟼', u'\\longrightarrow':u'⟶', u'\\looparrowleft':u'↫', u'\\looparrowright':u'↬', u'\\lor':u'∨', u'\\lozenge':u'◊', u'\\lrcorner':u'⌟', u'\\ltimes':u'⋉', u'\\lyxlock':u'', u'\\male':u'♂', u'\\maltese':u'✠', u'\\mapsfrom':u'↤', u'\\mapsto':u'↦', u'\\mathcircumflex':u'^', u'\\max':u'max', u'\\measuredangle':u'∡', u'\\medbullet':u'⚫', u'\\medcirc':u'⚪', u'\\mercury':u'☿', u'\\mho':u'℧', u'\\mid':u'∣', u'\\min':u'min', u'\\models':u'⊨', u'\\mp':u'∓', u'\\multimap':u'⊸', u'\\nLeftarrow':u'⇍', u'\\nLeftrightarrow':u'⇎', u'\\nRightarrow':u'⇏', u'\\nVDash':u'⊯', u'\\nabla':u'∇', u'\\napprox':u'≉', u'\\natural':u'♮', u'\\ncong':u'≇', u'\\nearrow':u'↗', u'\\neg':u'¬', u'\\neg)':u'¬', u'\\neptune':u'♆', u'\\nequiv':u'≢', u'\\newline':u'
', u'\\nexists':u'∄', u'\\ngeqslant':u'≱', u'\\ngtr':u'≯', u'\\ngtrless':u'≹', u'\\ni':u'∋', u'\\ni)':u'∋', u'\\nleftarrow':u'↚', u'\\nleftrightarrow':u'↮', u'\\nleqslant':u'≰', u'\\nless':u'≮', u'\\nlessgtr':u'≸', u'\\nmid':u'∤', u'\\nolimits':u'', u'\\nonumber':u'', u'\\not':u'¬', u'\\not<':u'≮', u'\\not=':u'≠', u'\\not>':u'≯', u'\\notbackslash':u'⍀', u'\\notin':u'∉', u'\\notni':u'∌', u'\\notslash':u'⌿', u'\\nparallel':u'∦', u'\\nprec':u'⊀', u'\\nrightarrow':u'↛', u'\\nsim':u'≁', u'\\nsimeq':u'≄', u'\\nsqsubset':u'⊏̸', u'\\nsubseteq':u'⊈', u'\\nsucc':u'⊁', u'\\nsucccurlyeq':u'⋡', u'\\nsupset':u'⊅', u'\\nsupseteq':u'⊉', u'\\ntriangleleft':u'⋪', u'\\ntrianglelefteq':u'⋬', u'\\ntriangleright':u'⋫', u'\\ntrianglerighteq':u'⋭', u'\\nvDash':u'⊭', u'\\nvdash':u'⊬', u'\\nwarrow':u'↖', u'\\odot':u'⊙', u'\\officialeuro':u'€', u'\\oiiint':u'', u'\\oiint':u'', u'\\oint':u'', u'\\ointclockwise':u'', u'\\ointctrclockwise':u'', u'\\ominus':u'⊖', u'\\oplus':u'⊕', u'\\oslash':u'⊘', u'\\otimes':u'⊗', u'\\owns':u'∋', u'\\parallel':u'∥', u'\\partial':u'∂', u'\\pencil':u'✎', u'\\perp':u'⊥', u'\\pisces':u'♓', u'\\pitchfork':u'⋔', u'\\pluto':u'♇', u'\\pm':u'±', u'\\pointer':u'➪', u'\\pointright':u'☞', u'\\pounds':u'£', u'\\prec':u'≺', u'\\preccurlyeq':u'≼', u'\\preceq':u'≼', u'\\precsim':u'≾', u'\\prime':u'′', u'\\prompto':u'∝', u'\\qoppa':u'ϙ', u'\\qquad':u' ', u'\\quad':u' ', u'\\quarternote':u'♩', u'\\radiation':u'☢', u'\\rang':u'⟫', u'\\rangle':u'⟩', u'\\rblot':u'⦊', u'\\rbrace':u'}', u'\\rbrace)':u'}', u'\\rbrack':u']', u'\\rceil':u'⌉', u'\\recycle':u'♻', u'\\rfloor':u'⌋', u'\\rgroup':u'⟯', u'\\rhd':u'⊳', u'\\rightangle':u'∟', u'\\rightarrow)':u'→', u'\\rightarrowtail':u'↣', u'\\rightarrowtobar':u'⇥', u'\\rightharpoondown':u'⇁', u'\\rightharpoonup':u'⇀', u'\\rightharpooondown':u'⇁', u'\\rightharpooonup':u'⇀', u'\\rightleftarrows':u'⇄', u'\\rightleftharpoons':u'⇌', u'\\rightmoon':u'☽', u'\\rightrightarrows':u'⇉', u'\\rightrightharpoons':u'⥤', u'\\rightthreetimes':u'⋌', u'\\rimg':u'⦈', u'\\risingdotseq':u'≓', u'\\rrbracket':u'⟧', u'\\rsub':u'⩥', u'\\rtimes':u'⋊', u'\\sagittarius':u'♐', u'\\saturn':u'♄', u'\\scorpio':u'♏', u'\\searrow':u'↘', u'\\sec':u'sec', u'\\second':u'″', u'\\setminus':u'∖', u'\\sharp':u'♯', u'\\simeq':u'≃', u'\\sin':u'sin', u'\\sinh':u'sinh', u'\\sixteenthnote':u'♬', u'\\skull':u'☠', u'\\slash':u'∕', u'\\smallsetminus':u'∖', u'\\smalltriangledown':u'▿', u'\\smalltriangleleft':u'◃', u'\\smalltriangleright':u'▹', u'\\smalltriangleup':u'▵', u'\\smile':u'⌣', u'\\smiley':u'☺', u'\\spadesuit':u'♠', u'\\spddot':u'¨', u'\\sphat':u'', u'\\sphericalangle':u'∢', u'\\spot':u'⦁', u'\\sptilde':u'~', u'\\sqcap':u'⊓', u'\\sqcup':u'⊔', u'\\sqsubset':u'⊏', u'\\sqsubseteq':u'⊑', u'\\sqsupset':u'⊐', u'\\sqsupseteq':u'⊒', u'\\square':u'□', u'\\sslash':u'⫽', u'\\star':u'⋆', u'\\steaming':u'☕', u'\\subseteqq':u'⫅', u'\\subsetneqq':u'⫋', u'\\succ':u'≻', u'\\succcurlyeq':u'≽', u'\\succeq':u'≽', u'\\succnsim':u'⋩', u'\\succsim':u'≿', u'\\sun':u'☼', u'\\sup':u'sup', u'\\supseteqq':u'⫆', u'\\supsetneqq':u'⫌', u'\\surd':u'√', u'\\swarrow':u'↙', u'\\swords':u'⚔', u'\\talloblong':u'⫾', u'\\tan':u'tan', u'\\tanh':u'tanh', u'\\taurus':u'♉', u'\\textasciicircum':u'^', u'\\textasciitilde':u'~', u'\\textbackslash':u'\\', u'\\textcopyright':u'©\'', u'\\textdegree':u'°', u'\\textellipsis':u'…', u'\\textemdash':u'—', u'\\textendash':u'—', u'\\texteuro':u'€', u'\\textgreater':u'>', u'\\textless':u'<', u'\\textordfeminine':u'ª', u'\\textordmasculine':u'º', u'\\textquotedblleft':u'“', u'\\textquotedblright':u'”', u'\\textquoteright':u'’', u'\\textregistered':u'®', u'\\textrightarrow':u'→', u'\\textsection':u'§', u'\\texttrademark':u'™', u'\\texttwosuperior':u'²', u'\\textvisiblespace':u' ', u'\\therefore':u'∴', u'\\third':u'‴', u'\\top':u'⊤', u'\\triangle':u'△', u'\\triangleleft':u'⊲', u'\\trianglelefteq':u'⊴', u'\\triangleq':u'≜', u'\\triangleright':u'▷', u'\\trianglerighteq':u'⊵', u'\\twoheadleftarrow':u'↞', u'\\twoheadrightarrow':u'↠', u'\\twonotes':u'♫', u'\\udot':u'⊍', u'\\ulcorner':u'⌜', u'\\unlhd':u'⊴', u'\\unrhd':u'⊵', u'\\unrhl':u'⊵', u'\\uparrow':u'↑', u'\\updownarrow':u'↕', u'\\upharpoonleft':u'↿', u'\\upharpoonright':u'↾', u'\\uplus':u'⊎', u'\\upuparrows':u'⇈', u'\\uranus':u'♅', u'\\urcorner':u'⌝', u'\\vDash':u'⊨', u'\\varclubsuit':u'♧', u'\\vardiamondsuit':u'♦', u'\\varheartsuit':u'♥', u'\\varnothing':u'∅', u'\\varspadesuit':u'♤', u'\\vdash':u'⊢', u'\\vdots':u'⋮', u'\\vee':u'∨', u'\\vee)':u'∨', u'\\veebar':u'⊻', u'\\vert':u'∣', u'\\virgo':u'♍', u'\\warning':u'⚠', u'\\wasylozenge':u'⌑', u'\\wedge':u'∧', u'\\wedge)':u'∧', u'\\wp':u'℘', u'\\wr':u'≀', u'\\yen':u'¥', u'\\yinyang':u'☯', u'\\{':u'{', u'\\|':u'∥', u'\\}':u'}', } decoratedcommand = { } decoratingfunctions = { u'\\overleftarrow':u'⟵', u'\\overrightarrow':u'⟶', u'\\widehat':u'^', } endings = { u'bracket':u'}', u'complex':u'\\]', u'endafter':u'}', u'endbefore':u'\\end{', u'squarebracket':u']', } environments = { u'align':[u'r',u'l',], u'eqnarray':[u'r',u'c',u'l',], u'gathered':[u'l',u'l',], } fontfunctions = { u'\\boldsymbol':u'b', u'\\mathbb':u'span class="blackboard"', u'\\mathbb{A}':u'𝔸', u'\\mathbb{B}':u'𝔹', u'\\mathbb{C}':u'ℂ', u'\\mathbb{D}':u'𝔻', u'\\mathbb{E}':u'𝔼', u'\\mathbb{F}':u'𝔽', u'\\mathbb{G}':u'𝔾', u'\\mathbb{H}':u'ℍ', u'\\mathbb{J}':u'𝕁', u'\\mathbb{K}':u'𝕂', u'\\mathbb{L}':u'𝕃', u'\\mathbb{N}':u'ℕ', u'\\mathbb{O}':u'𝕆', u'\\mathbb{P}':u'ℙ', u'\\mathbb{Q}':u'ℚ', u'\\mathbb{R}':u'ℝ', u'\\mathbb{S}':u'𝕊', u'\\mathbb{T}':u'𝕋', u'\\mathbb{W}':u'𝕎', u'\\mathbb{Z}':u'ℤ', u'\\mathbf':u'b', u'\\mathcal':u'span class="scriptfont"', u'\\mathcal{B}':u'ℬ', u'\\mathcal{E}':u'ℰ', u'\\mathcal{F}':u'ℱ', u'\\mathcal{H}':u'ℋ', u'\\mathcal{I}':u'ℐ', u'\\mathcal{L}':u'ℒ', u'\\mathcal{M}':u'ℳ', u'\\mathcal{R}':u'ℛ', u'\\mathfrak':u'span class="fraktur"', u'\\mathfrak{C}':u'ℭ', u'\\mathfrak{F}':u'𝔉', u'\\mathfrak{H}':u'ℌ', u'\\mathfrak{I}':u'ℑ', u'\\mathfrak{R}':u'ℜ', u'\\mathfrak{Z}':u'ℨ', u'\\mathit':u'i', u'\\mathring{A}':u'Å', u'\\mathring{U}':u'Ů', u'\\mathring{a}':u'å', u'\\mathring{u}':u'ů', u'\\mathring{w}':u'ẘ', u'\\mathring{y}':u'ẙ', u'\\mathrm':u'span class="mathrm"', u'\\mathscr':u'span class="scriptfont"', u'\\mathscr{B}':u'ℬ', u'\\mathscr{E}':u'ℰ', u'\\mathscr{F}':u'ℱ', u'\\mathscr{H}':u'ℋ', u'\\mathscr{I}':u'ℐ', u'\\mathscr{L}':u'ℒ', u'\\mathscr{M}':u'ℳ', u'\\mathscr{R}':u'ℛ', u'\\mathsf':u'span class="mathsf"', u'\\mathtt':u'tt', } hybridfunctions = { u'\\addcontentsline':[u'{$p!}{$q!}{$r!}',u'f0{}',u'ignored',], u'\\addtocontents':[u'{$p!}{$q!}',u'f0{}',u'ignored',], u'\\backmatter':[u'',u'f0{}',u'ignored',], u'\\binom':[u'{$1}{$2}',u'f2{(}f0{f1{$1}f1{$2}}f2{)}',u'span class="binom"',u'span class="binomstack"',u'span class="bigsymbol"',], u'\\boxed':[u'{$1}',u'f0{$1}',u'span class="boxed"',], u'\\cfrac':[u'[$p!]{$1}{$2}',u'f0{f3{(}f1{$1}f3{)/(}f2{$2}f3{)}}',u'span class="fullfraction"',u'span class="numerator align-$p"',u'span class="denominator"',u'span class="ignored"',], u'\\color':[u'{$p!}{$1}',u'f0{$1}',u'span style="color: $p;"',], u'\\colorbox':[u'{$p!}{$1}',u'f0{$1}',u'span class="colorbox" style="background: $p;"',], u'\\dbinom':[u'{$1}{$2}',u'(f0{f1{f2{$1}}f1{f2{ }}f1{f2{$2}}})',u'span class="binomial"',u'span class="binomrow"',u'span class="binomcell"',], u'\\dfrac':[u'{$1}{$2}',u'f0{f3{(}f1{$1}f3{)/(}f2{$2}f3{)}}',u'span class="fullfraction"',u'span class="numerator"',u'span class="denominator"',u'span class="ignored"',], u'\\displaystyle':[u'{$1}',u'f0{$1}',u'span class="displaystyle"',], u'\\fancyfoot':[u'[$p!]{$q!}',u'f0{}',u'ignored',], u'\\fancyhead':[u'[$p!]{$q!}',u'f0{}',u'ignored',], u'\\fbox':[u'{$1}',u'f0{$1}',u'span class="fbox"',], u'\\fboxrule':[u'{$p!}',u'f0{}',u'ignored',], u'\\fboxsep':[u'{$p!}',u'f0{}',u'ignored',], u'\\fcolorbox':[u'{$p!}{$q!}{$1}',u'f0{$1}',u'span class="boxed" style="border-color: $p; background: $q;"',], u'\\frac':[u'{$1}{$2}',u'f0{f3{(}f1{$1}f3{)/(}f2{$2}f3{)}}',u'span class="fraction"',u'span class="numerator"',u'span class="denominator"',u'span class="ignored"',], u'\\framebox':[u'[$p!][$q!]{$1}',u'f0{$1}',u'span class="framebox align-$q" style="width: $p;"',], u'\\frontmatter':[u'',u'f0{}',u'ignored',], u'\\href':[u'[$o]{$u!}{$t!}',u'f0{$t}',u'a href="$u"',], u'\\hspace':[u'{$p!}',u'f0{ }',u'span class="hspace" style="width: $p;"',], u'\\leftroot':[u'{$p!}',u'f0{ }',u'span class="leftroot" style="width: $p;px"',], u'\\mainmatter':[u'',u'f0{}',u'ignored',], u'\\markboth':[u'{$p!}{$q!}',u'f0{}',u'ignored',], u'\\markright':[u'{$p!}',u'f0{}',u'ignored',], u'\\nicefrac':[u'{$1}{$2}',u'f0{f1{$1}⁄f2{$2}}',u'span class="fraction"',u'sup class="numerator"',u'sub class="denominator"',u'span class="ignored"',], u'\\parbox':[u'[$p!]{$w!}{$1}',u'f0{1}',u'div class="Boxed" style="width: $w;"',], u'\\raisebox':[u'{$p!}{$1}',u'f0{$1.font}',u'span class="raisebox" style="vertical-align: $p;"',], u'\\renewenvironment':[u'{$1!}{$2!}{$3!}',u'',], u'\\rule':[u'[$v!]{$w!}{$h!}',u'f0/',u'hr class="line" style="width: $w; height: $h;"',], u'\\scriptscriptstyle':[u'{$1}',u'f0{$1}',u'span class="scriptscriptstyle"',], u'\\scriptstyle':[u'{$1}',u'f0{$1}',u'span class="scriptstyle"',], u'\\sqrt':[u'[$0]{$1}',u'f0{f1{$0}f2{√}f4{(}f3{$1}f4{)}}',u'span class="sqrt"',u'sup class="root"',u'span class="radical"',u'span class="root"',u'span class="ignored"',], u'\\stackrel':[u'{$1}{$2}',u'f0{f1{$1}f2{$2}}',u'span class="stackrel"',u'span class="upstackrel"',u'span class="downstackrel"',], u'\\tbinom':[u'{$1}{$2}',u'(f0{f1{f2{$1}}f1{f2{ }}f1{f2{$2}}})',u'span class="binomial"',u'span class="binomrow"',u'span class="binomcell"',], u'\\textcolor':[u'{$p!}{$1}',u'f0{$1}',u'span style="color: $p;"',], u'\\textstyle':[u'{$1}',u'f0{$1}',u'span class="textstyle"',], u'\\thispagestyle':[u'{$p!}',u'f0{}',u'ignored',], u'\\unit':[u'[$0]{$1}',u'$0f0{$1.font}',u'span class="unit"',], u'\\unitfrac':[u'[$0]{$1}{$2}',u'$0f0{f1{$1.font}⁄f2{$2.font}}',u'span class="fraction"',u'sup class="unit"',u'sub class="unit"',], u'\\uproot':[u'{$p!}',u'f0{ }',u'span class="uproot" style="width: $p;px"',], u'\\url':[u'{$u!}',u'f0{$u}',u'a href="$u"',], u'\\vspace':[u'{$p!}',u'f0{ }',u'span class="vspace" style="height: $p;"',], } hybridsizes = { u'\\binom':u'$1+$2', u'\\cfrac':u'$1+$2', u'\\dbinom':u'$1+$2+1', u'\\dfrac':u'$1+$2', u'\\frac':u'$1+$2', u'\\tbinom':u'$1+$2+1', } labelfunctions = { u'\\label':u'a name="#"', } limitcommands = { u'\\biginterleave':u'⫼', u'\\bigsqcap':u'⨅', u'\\fint':u'⨏', u'\\iiiint':u'⨌', u'\\int':u'∫', u'\\intop':u'∫', u'\\lim':u'lim', u'\\prod':u'∏', u'\\smallint':u'∫', u'\\sqint':u'⨖', u'\\sum':u'∑', u'\\varointclockwise':u'∲', u'\\varprod':u'⨉', u'\\zcmp':u'⨟', u'\\zhide':u'⧹', u'\\zpipe':u'⨠', u'\\zproject':u'⨡', } misccommands = { u'\\limits':u'LimitPreviousCommand', u'\\newcommand':u'MacroDefinition', u'\\renewcommand':u'MacroDefinition', u'\\setcounter':u'SetCounterFunction', u'\\tag':u'FormulaTag', u'\\tag*':u'FormulaTag', u'\\today':u'TodayCommand', } modified = { u'\n':u'', u' ':u'', u'$':u'', u'&':u' ', u'\'':u'’', u'+':u' + ', u',':u', ', u'-':u' − ', u'/':u' ⁄ ', u'<':u' < ', u'=':u' = ', u'>':u' > ', u'@':u'', u'~':u'', } onefunctions = { u'\\Big':u'span class="bigsymbol"', u'\\Bigg':u'span class="hugesymbol"', u'\\bar':u'span class="bar"', u'\\begin{array}':u'span class="arraydef"', u'\\big':u'span class="symbol"', u'\\bigg':u'span class="largesymbol"', u'\\bigl':u'span class="bigsymbol"', u'\\bigr':u'span class="bigsymbol"', u'\\centering':u'span class="align-center"', u'\\ensuremath':u'span class="ensuremath"', u'\\hphantom':u'span class="phantom"', u'\\noindent':u'span class="noindent"', u'\\overbrace':u'span class="overbrace"', u'\\overline':u'span class="overline"', u'\\phantom':u'span class="phantom"', u'\\underbrace':u'span class="underbrace"', u'\\underline':u'u', u'\\vphantom':u'span class="phantom"', } spacedcommands = { u'\\Bot':u'⫫', u'\\Doteq':u'≑', u'\\DownArrowBar':u'⤓', u'\\DownLeftTeeVector':u'⥞', u'\\DownLeftVectorBar':u'⥖', u'\\DownRightTeeVector':u'⥟', u'\\DownRightVectorBar':u'⥗', u'\\Equal':u'⩵', u'\\LeftArrowBar':u'⇤', u'\\LeftDownTeeVector':u'⥡', u'\\LeftDownVectorBar':u'⥙', u'\\LeftTeeVector':u'⥚', u'\\LeftTriangleBar':u'⧏', u'\\LeftUpTeeVector':u'⥠', u'\\LeftUpVectorBar':u'⥘', u'\\LeftVectorBar':u'⥒', u'\\Leftrightarrow':u'⇔', u'\\Longmapsfrom':u'⟽', u'\\Longmapsto':u'⟾', u'\\MapsDown':u'↧', u'\\MapsUp':u'↥', u'\\Nearrow':u'⇗', u'\\NestedGreaterGreater':u'⪢', u'\\NestedLessLess':u'⪡', u'\\NotGreaterLess':u'≹', u'\\NotGreaterTilde':u'≵', u'\\NotLessTilde':u'≴', u'\\Nwarrow':u'⇖', u'\\Proportion':u'∷', u'\\RightArrowBar':u'⇥', u'\\RightDownTeeVector':u'⥝', u'\\RightDownVectorBar':u'⥕', u'\\RightTeeVector':u'⥛', u'\\RightTriangleBar':u'⧐', u'\\RightUpTeeVector':u'⥜', u'\\RightUpVectorBar':u'⥔', u'\\RightVectorBar':u'⥓', u'\\Rightarrow':u'⇒', u'\\Same':u'⩶', u'\\Searrow':u'⇘', u'\\Swarrow':u'⇙', u'\\Top':u'⫪', u'\\UpArrowBar':u'⤒', u'\\VDash':u'⊫', u'\\approx':u'≈', u'\\approxeq':u'≊', u'\\backsim':u'∽', u'\\barin':u'⋶', u'\\barleftharpoon':u'⥫', u'\\barrightharpoon':u'⥭', u'\\bij':u'⤖', u'\\coloneq':u'≔', u'\\corresponds':u'≙', u'\\curlyeqprec':u'⋞', u'\\curlyeqsucc':u'⋟', u'\\dashrightarrow':u'⇢', u'\\dlsh':u'↲', u'\\downdownharpoons':u'⥥', u'\\downuparrows':u'⇵', u'\\downupharpoons':u'⥯', u'\\drsh':u'↳', u'\\eqslantgtr':u'⪖', u'\\eqslantless':u'⪕', u'\\equiv':u'≡', u'\\ffun':u'⇻', u'\\finj':u'⤕', u'\\ge':u'≥', u'\\geq':u'≥', u'\\ggcurly':u'⪼', u'\\gnapprox':u'⪊', u'\\gneq':u'⪈', u'\\gtrapprox':u'⪆', u'\\hash':u'⋕', u'\\iddots':u'⋰', u'\\implies':u' ⇒ ', u'\\in':u'∈', u'\\le':u'≤', u'\\leftarrow':u'←', u'\\leftarrowtriangle':u'⇽', u'\\leftbarharpoon':u'⥪', u'\\leftrightarrowtriangle':u'⇿', u'\\leftrightharpoon':u'⥊', u'\\leftrightharpoondown':u'⥐', u'\\leftrightharpoonup':u'⥎', u'\\leftrightsquigarrow':u'↭', u'\\leftslice':u'⪦', u'\\leftsquigarrow':u'⇜', u'\\leftupdownharpoon':u'⥑', u'\\leq':u'≤', u'\\lessapprox':u'⪅', u'\\llcurly':u'⪻', u'\\lnapprox':u'⪉', u'\\lneq':u'⪇', u'\\longmapsfrom':u'⟻', u'\\multimapboth':u'⧟', u'\\multimapdotbothA':u'⊶', u'\\multimapdotbothB':u'⊷', u'\\multimapinv':u'⟜', u'\\nVdash':u'⊮', u'\\ne':u'≠', u'\\neq':u'≠', u'\\ngeq':u'≱', u'\\nleq':u'≰', u'\\nni':u'∌', u'\\not\\in':u'∉', u'\\notasymp':u'≭', u'\\npreceq':u'⋠', u'\\nsqsubseteq':u'⋢', u'\\nsqsupseteq':u'⋣', u'\\nsubset':u'⊄', u'\\nsucceq':u'⋡', u'\\pfun':u'⇸', u'\\pinj':u'⤔', u'\\precapprox':u'⪷', u'\\preceqq':u'⪳', u'\\precnapprox':u'⪹', u'\\precnsim':u'⋨', u'\\propto':u'∝', u'\\psur':u'⤀', u'\\rightarrow':u'→', u'\\rightarrowtriangle':u'⇾', u'\\rightbarharpoon':u'⥬', u'\\rightleftharpoon':u'⥋', u'\\rightslice':u'⪧', u'\\rightsquigarrow':u'⇝', u'\\rightupdownharpoon':u'⥏', u'\\sim':u'~', u'\\strictfi':u'⥼', u'\\strictif':u'⥽', u'\\subset':u'⊂', u'\\subseteq':u'⊆', u'\\subsetneq':u'⊊', u'\\succapprox':u'⪸', u'\\succeqq':u'⪴', u'\\succnapprox':u'⪺', u'\\supset':u'⊃', u'\\supseteq':u'⊇', u'\\supsetneq':u'⊋', u'\\times':u'×', u'\\to':u'→', u'\\updownarrows':u'⇅', u'\\updownharpoons':u'⥮', u'\\upupharpoons':u'⥣', u'\\vartriangleleft':u'⊲', u'\\vartriangleright':u'⊳', } starts = { u'beginafter':u'}', u'beginbefore':u'\\begin{', u'bracket':u'{', u'command':u'\\', u'comment':u'%', u'complex':u'\\[', u'simple':u'$', u'squarebracket':u'[', u'unnumbered':u'*', } symbolfunctions = { u'^':u'sup', u'_':u'sub', } textfunctions = { u'\\mbox':u'span class="mbox"', u'\\text':u'span class="text"', u'\\textbf':u'b', u'\\textipa':u'span class="textipa"', u'\\textit':u'i', u'\\textnormal':u'span class="textnormal"', u'\\textrm':u'span class="textrm"', u'\\textsc':u'span class="versalitas"', u'\\textsf':u'span class="textsf"', u'\\textsl':u'i', u'\\texttt':u'tt', u'\\textup':u'span class="normal"', } unmodified = { u'characters':[u'.',u'*',u'€',u'(',u')',u'[',u']',u':',u'·',u'!',u';',u'|',u'§',u'"',], } urls = { u'googlecharts':u'http://chart.googleapis.com/chart?cht=tx&chl=', } class GeneralConfig(object): "Configuration class from elyxer.config file" version = { u'date':u'2013-03-10', u'lyxformat':u'413', u'number':u'1.2.4', } class HeaderConfig(object): "Configuration class from elyxer.config file" parameters = { u'beginpreamble':u'\\begin_preamble', u'branch':u'\\branch', u'documentclass':u'\\textclass', u'endbranch':u'\\end_branch', u'endpreamble':u'\\end_preamble', u'language':u'\\language', u'lstset':u'\\lstset', u'outputchanges':u'\\output_changes', u'paragraphseparation':u'\\paragraph_separation', u'pdftitle':u'\\pdf_title', u'secnumdepth':u'\\secnumdepth', u'tocdepth':u'\\tocdepth', } styles = { u'article':[u'article',u'aastex',u'aapaper',u'acmsiggraph',u'sigplanconf',u'achemso',u'amsart',u'apa',u'arab-article',u'armenian-article',u'article-beamer',u'chess',u'dtk',u'elsarticle',u'heb-article',u'IEEEtran',u'iopart',u'kluwer',u'scrarticle-beamer',u'scrartcl',u'extarticle',u'paper',u'mwart',u'revtex4',u'spie',u'svglobal3',u'ltugboat',u'agu-dtd',u'jgrga',u'agums',u'entcs',u'egs',u'ijmpc',u'ijmpd',u'singlecol-new',u'doublecol-new',u'isprs',u'tarticle',u'jsarticle',u'jarticle',u'jss',u'literate-article',u'siamltex',u'cl2emult',u'llncs',u'svglobal',u'svjog',u'svprobth',], u'book':[u'book',u'amsbook',u'scrbook',u'extbook',u'tufte-book',u'report',u'extreport',u'scrreprt',u'memoir',u'tbook',u'jsbook',u'jbook',u'mwbk',u'svmono',u'svmult',u'treport',u'jreport',u'mwrep',], } class ImageConfig(object): "Configuration class from elyxer.config file" converters = { u'imagemagick':u'convert[ -density $scale][ -define $format:use-cropbox=true] "$input" "$output"', u'inkscape':u'inkscape "$input" --export-png="$output"', u'lyx':u'lyx -C "$input" "$output"', } cropboxformats = { u'.eps':u'ps', u'.pdf':u'pdf', u'.ps':u'ps', } formats = { u'default':u'.png', u'vector':[u'.svg',u'.eps',], } class LayoutConfig(object): "Configuration class from elyxer.config file" groupable = { u'allowed':[u'StringContainer',u'Constant',u'TaggedText',u'Align',u'TextFamily',u'EmphaticText',u'VersalitasText',u'BarredText',u'SizeText',u'ColorText',u'LangLine',u'Formula',], } class NewfangleConfig(object): "Configuration class from elyxer.config file" constants = { u'chunkref':u'chunkref{', u'endcommand':u'}', u'endmark':u'>', u'startcommand':u'\\', u'startmark':u'=<', } class NumberingConfig(object): "Configuration class from elyxer.config file" layouts = { u'ordered':[u'Chapter',u'Section',u'Subsection',u'Subsubsection',u'Paragraph',], u'roman':[u'Part',u'Book',], } sequence = { u'symbols':[u'*',u'**',u'†',u'‡',u'§',u'§§',u'¶',u'¶¶',u'#',u'##',], } class StyleConfig(object): "Configuration class from elyxer.config file" hspaces = { u'\\enskip{}':u' ', u'\\hfill{}':u' ', u'\\hspace*{\\fill}':u' ', u'\\hspace*{}':u'', u'\\hspace{}':u' ', u'\\negthinspace{}':u'', u'\\qquad{}':u'  ', u'\\quad{}':u' ', u'\\space{}':u' ', u'\\thinspace{}':u' ', u'~':u' ', } quotes = { u'ald':u'»', u'als':u'›', u'ard':u'«', u'ars':u'‹', u'eld':u'“', u'els':u'‘', u'erd':u'”', u'ers':u'’', u'fld':u'«', u'fls':u'‹', u'frd':u'»', u'frs':u'›', u'gld':u'„', u'gls':u'‚', u'grd':u'“', u'grs':u'‘', u'pld':u'„', u'pls':u'‚', u'prd':u'”', u'prs':u'’', u'sld':u'”', u'srd':u'”', } referenceformats = { u'eqref':u'(@↕)', u'formatted':u'¶↕', u'nameref':u'$↕', u'pageref':u'#↕', u'ref':u'@↕', u'vpageref':u'on-page#↕', u'vref':u'@on-page#↕', } size = { u'ignoredtexts':[u'col',u'text',u'line',u'page',u'theight',u'pheight',], } vspaces = { u'bigskip':u'
', u'defskip':u'
', u'medskip':u'
', u'smallskip':u'
', u'vfill':u'
', } class TOCConfig(object): "Configuration class from elyxer.config file" extractplain = { u'allowed':[u'StringContainer',u'Constant',u'TaggedText',u'Align',u'TextFamily',u'EmphaticText',u'VersalitasText',u'BarredText',u'SizeText',u'ColorText',u'LangLine',u'Formula',], u'cloned':[u'',], u'extracted':[u'',], } extracttitle = { u'allowed':[u'StringContainer',u'Constant',u'Space',], u'cloned':[u'TextFamily',u'EmphaticText',u'VersalitasText',u'BarredText',u'SizeText',u'ColorText',u'LangLine',u'Formula',], u'extracted':[u'PlainLayout',u'TaggedText',u'Align',u'Caption',u'StandardLayout',u'FlexInset',], } class TagConfig(object): "Configuration class from elyxer.config file" barred = { u'under':u'u', } family = { u'sans':u'span class="sans"', u'typewriter':u'tt', } flex = { u'CharStyle:Code':u'span class="code"', u'CharStyle:MenuItem':u'span class="menuitem"', u'Code':u'span class="code"', u'MenuItem':u'span class="menuitem"', u'Noun':u'span class="noun"', u'Strong':u'span class="strong"', } group = { u'layouts':[u'Quotation',u'Quote',], } layouts = { u'Center':u'div', u'Chapter':u'h?', u'Date':u'h2', u'Paragraph':u'div', u'Part':u'h1', u'Quotation':u'blockquote', u'Quote':u'blockquote', u'Section':u'h?', u'Subsection':u'h?', u'Subsubsection':u'h?', } listitems = { u'Enumerate':u'ol', u'Itemize':u'ul', } notes = { u'Comment':u'', u'Greyedout':u'span class="greyedout"', u'Note':u'', } script = { u'subscript':u'sub', u'superscript':u'sup', } shaped = { u'italic':u'i', u'slanted':u'i', u'smallcaps':u'span class="versalitas"', } class TranslationConfig(object): "Configuration class from elyxer.config file" constants = { u'Appendix':u'Appendix', u'Book':u'Book', u'Chapter':u'Chapter', u'Paragraph':u'Paragraph', u'Part':u'Part', u'Section':u'Section', u'Subsection':u'Subsection', u'Subsubsection':u'Subsubsection', u'abstract':u'Abstract', u'bibliography':u'Bibliography', u'figure':u'figure', u'float-algorithm':u'Algorithm ', u'float-figure':u'Figure ', u'float-listing':u'Listing ', u'float-table':u'Table ', u'float-tableau':u'Tableau ', u'footnotes':u'Footnotes', u'generated-by':u'Document generated by ', u'generated-on':u' on ', u'index':u'Index', u'jsmath-enable':u'Please enable JavaScript on your browser.', u'jsmath-requires':u' requires JavaScript to correctly process the mathematics on this page. ', u'jsmath-warning':u'Warning: ', u'list-algorithm':u'List of Algorithms', u'list-figure':u'List of Figures', u'list-table':u'List of Tables', u'list-tableau':u'List of Tableaux', u'main-page':u'Main page', u'next':u'Next', u'nomenclature':u'Nomenclature', u'on-page':u' on page ', u'prev':u'Prev', u'references':u'References', u'toc':u'Table of Contents', u'toc-for':u'Contents for ', u'up':u'Up', } languages = { u'american':u'en', u'british':u'en', u'deutsch':u'de', u'dutch':u'nl', u'english':u'en', u'french':u'fr', u'ngerman':u'de', u'russian':u'ru', u'spanish':u'es', } class CommandLineParser(object): "A parser for runtime options" def __init__(self, options): self.options = options def parseoptions(self, args): "Parse command line options" if len(args) == 0: return None while len(args) > 0 and args[0].startswith('--'): key, value = self.readoption(args) if not key: return 'Option ' + value + ' not recognized' if not value: return 'Option ' + key + ' needs a value' setattr(self.options, key, value) return None def readoption(self, args): "Read the key and value for an option" arg = args[0][2:] del args[0] if '=' in arg: key = self.readequalskey(arg, args) else: key = arg.replace('-', '') if not hasattr(self.options, key): return None, key current = getattr(self.options, key) if isinstance(current, bool): return key, True # read value if len(args) == 0: return key, None if args[0].startswith('"'): initial = args[0] del args[0] return key, self.readquoted(args, initial) value = args[0].decode('utf-8') del args[0] if isinstance(current, list): current.append(value) return key, current return key, value def readquoted(self, args, initial): "Read a value between quotes" Trace.error('Oops') value = initial[1:] while len(args) > 0 and not args[0].endswith('"') and not args[0].startswith('--'): Trace.error('Appending ' + args[0]) value += ' ' + args[0] del args[0] if len(args) == 0 or args[0].startswith('--'): return None value += ' ' + args[0:-1] return value def readequalskey(self, arg, args): "Read a key using equals" split = arg.split('=', 1) key = split[0] value = split[1] args.insert(0, value) return key class Options(object): "A set of runtime options" instance = None location = None nocopy = False copyright = False debug = False quiet = False version = False hardversion = False versiondate = False html = False help = False showlines = True unicode = False iso885915 = False css = [] title = None directory = None destdirectory = None toc = False toctarget = '' tocfor = None forceformat = None lyxformat = False target = None splitpart = None memory = True lowmem = False nobib = False converter = 'imagemagick' raw = False jsmath = None mathjax = None nofooter = False simplemath = False template = None noconvert = False notoclabels = False letterfoot = True numberfoot = False symbolfoot = False hoverfoot = True marginfoot = False endfoot = False supfoot = True alignfoot = False footnotes = None imageformat = None copyimages = False googlecharts = False embedcss = [] branches = dict() def parseoptions(self, args): "Parse command line options" Options.location = args[0] del args[0] parser = CommandLineParser(Options) result = parser.parseoptions(args) if result: Trace.error(result) self.usage() self.processoptions() def processoptions(self): "Process all options parsed." if Options.help: self.usage() if Options.version: self.showversion() if Options.hardversion: self.showhardversion() if Options.versiondate: self.showversiondate() if Options.lyxformat: self.showlyxformat() if Options.splitpart: try: Options.splitpart = int(Options.splitpart) if Options.splitpart <= 0: Trace.error('--splitpart requires a number bigger than zero') self.usage() except: Trace.error('--splitpart needs a numeric argument, not ' + Options.splitpart) self.usage() if Options.lowmem or Options.toc or Options.tocfor: Options.memory = False self.parsefootnotes() if Options.forceformat and not Options.imageformat: Options.imageformat = Options.forceformat if Options.imageformat == 'copy': Options.copyimages = True if Options.css == []: Options.css = ['http://elyxer.nongnu.org/lyx.css'] if Options.html: Options.simplemath = True if Options.toc and not Options.tocfor: Trace.error('Option --toc is deprecated; use --tocfor "page" instead') Options.tocfor = Options.toctarget if Options.nocopy: Trace.error('Option --nocopy is deprecated; it is no longer needed') if Options.jsmath: Trace.error('Option --jsmath is deprecated; use --mathjax instead') # set in Trace if necessary for param in dir(Trace): if param.endswith('mode'): setattr(Trace, param, getattr(self, param[:-4])) def usage(self): "Show correct usage" Trace.error('Usage: ' + os.path.basename(Options.location) + ' [options] [filein] [fileout]') Trace.error('Convert LyX input file "filein" to HTML file "fileout".') Trace.error('If filein (or fileout) is not given use standard input (or output).') Trace.error('Main program of the eLyXer package (http://elyxer.nongnu.org/).') self.showoptions() def parsefootnotes(self): "Parse footnotes options." if not Options.footnotes: return Options.marginfoot = False Options.letterfoot = False Options.hoverfoot = False options = Options.footnotes.split(',') for option in options: footoption = option + 'foot' if hasattr(Options, footoption): setattr(Options, footoption, True) else: Trace.error('Unknown footnotes option: ' + option) if not Options.endfoot and not Options.marginfoot and not Options.hoverfoot: Options.hoverfoot = True if not Options.numberfoot and not Options.symbolfoot: Options.letterfoot = True def showoptions(self): "Show all possible options" Trace.error(' Common options:') Trace.error(' --help: show this online help') Trace.error(' --quiet: disables all runtime messages') Trace.error('') Trace.error(' Advanced options:') Trace.error(' --debug: enable debugging messages (for developers)') Trace.error(' --version: show version number and release date') Trace.error(' --lyxformat: return the highest LyX version supported') Trace.error(' Options for HTML output:') Trace.error(' --title "title": set the generated page title') Trace.error(' --css "file.css": use a custom CSS file') Trace.error(' --embedcss "file.css": embed styles from a CSS file into the output') Trace.error(' --html: output HTML 4.0 instead of the default XHTML') Trace.error(' --unicode: full Unicode output') Trace.error(' --iso885915: output a document with ISO-8859-15 encoding') Trace.error(' --nofooter: remove the footer "generated by eLyXer"') Trace.error(' --simplemath: do not generate fancy math constructions') Trace.error(' Options for image output:') Trace.error(' --directory "img_dir": look for images in the specified directory') Trace.error(' --destdirectory "dest": put converted images into this directory') Trace.error(' --imageformat ".ext": image output format, or "copy" to copy images') Trace.error(' --noconvert: do not convert images, use in original locations') Trace.error(' --converter "inkscape": use an alternative program to convert images') Trace.error(' Options for footnote display:') Trace.error(' --numberfoot: mark footnotes with numbers instead of letters') Trace.error(' --symbolfoot: mark footnotes with symbols (*, **...)') Trace.error(' --hoverfoot: show footnotes as hovering text (default)') Trace.error(' --marginfoot: show footnotes on the page margin') Trace.error(' --endfoot: show footnotes at the end of the page') Trace.error(' --supfoot: use superscript for footnote markers (default)') Trace.error(' --alignfoot: use aligned text for footnote markers') Trace.error(' --footnotes "options": specify several comma-separated footnotes options') Trace.error(' Available options are: "number", "symbol", "hover", "margin", "end",') Trace.error(' "sup", "align"') Trace.error(' Advanced output options:') Trace.error(' --splitpart "depth": split the resulting webpage at the given depth') Trace.error(' --tocfor "page": generate a TOC that points to the given page') Trace.error(' --target "frame": make all links point to the given frame') Trace.error(' --notoclabels: omit the part labels in the TOC, such as Chapter') Trace.error(' --lowmem: do the conversion on the fly (conserve memory)') Trace.error(' --raw: generate HTML without header or footer.') Trace.error(' --mathjax remote: use MathJax remotely to display equations') Trace.error(' --mathjax "URL": use MathJax from the given URL to display equations') Trace.error(' --googlecharts: use Google Charts to generate formula images') Trace.error(' --template "file": use a template, put everything in ') Trace.error(' --copyright: add a copyright notice at the bottom') Trace.error(' Deprecated options:') Trace.error(' --toc: (deprecated) create a table of contents') Trace.error(' --toctarget "page": (deprecated) generate a TOC for the given page') Trace.error(' --nocopy: (deprecated) maintained for backwards compatibility') Trace.error(' --jsmath "URL": use jsMath from the given URL to display equations') sys.exit() def showversion(self): "Return the current eLyXer version string" string = 'eLyXer version ' + GeneralConfig.version['number'] string += ' (' + GeneralConfig.version['date'] + ')' Trace.error(string) sys.exit() def showhardversion(self): "Return just the version string" Trace.message(GeneralConfig.version['number']) sys.exit() def showversiondate(self): "Return just the version dte" Trace.message(GeneralConfig.version['date']) sys.exit() def showlyxformat(self): "Return just the lyxformat parameter" Trace.message(GeneralConfig.version['lyxformat']) sys.exit() class BranchOptions(object): "A set of options for a branch" def __init__(self, name): self.name = name self.options = {'color':'#ffffff'} def set(self, key, value): "Set a branch option" if not key.startswith(ContainerConfig.string['startcommand']): Trace.error('Invalid branch option ' + key) return key = key.replace(ContainerConfig.string['startcommand'], '') self.options[key] = value def isselected(self): "Return if the branch is selected" if not 'selected' in self.options: return False return self.options['selected'] == '1' def __unicode__(self): "String representation" return 'options for ' + self.name + ': ' + unicode(self.options) import urllib class Cloner(object): "An object used to clone other objects." def clone(cls, original): "Return an exact copy of an object." "The original object must have an empty constructor." return cls.create(original.__class__) def create(cls, type): "Create an object of a given class." clone = type.__new__(type) clone.__init__() return clone clone = classmethod(clone) create = classmethod(create) class ContainerExtractor(object): "A class to extract certain containers." def __init__(self, config): "The config parameter is a map containing three lists: allowed, copied and extracted." "Each of the three is a list of class names for containers." "Allowed containers are included as is into the result." "Cloned containers are cloned and placed into the result." "Extracted containers are looked into." "All other containers are silently ignored." self.allowed = config['allowed'] self.cloned = config['cloned'] self.extracted = config['extracted'] def extract(self, container): "Extract a group of selected containers from elyxer.a container." list = [] locate = lambda c: c.__class__.__name__ in self.allowed + self.cloned recursive = lambda c: c.__class__.__name__ in self.extracted process = lambda c: self.process(c, list) container.recursivesearch(locate, recursive, process) return list def process(self, container, list): "Add allowed containers, clone cloned containers and add the clone." name = container.__class__.__name__ if name in self.allowed: list.append(container) elif name in self.cloned: list.append(self.safeclone(container)) else: Trace.error('Unknown container class ' + name) def safeclone(self, container): "Return a new container with contents only in a safe list, recursively." clone = Cloner.clone(container) clone.output = container.output clone.contents = self.extract(container) return clone class Parser(object): "A generic parser" def __init__(self): self.begin = 0 self.parameters = dict() def parseheader(self, reader): "Parse the header" header = reader.currentline().split() reader.nextline() self.begin = reader.linenumber return header def parseparameter(self, reader): "Parse a parameter" if reader.currentline().strip().startswith('<'): key, value = self.parsexml(reader) self.parameters[key] = value return split = reader.currentline().strip().split(' ', 1) reader.nextline() if len(split) == 0: return key = split[0] if len(split) == 1: self.parameters[key] = True return if not '"' in split[1]: self.parameters[key] = split[1].strip() return doublesplit = split[1].split('"') self.parameters[key] = doublesplit[1] def parsexml(self, reader): "Parse a parameter in xml form: " strip = reader.currentline().strip() reader.nextline() if not strip.endswith('>'): Trace.error('XML parameter ' + strip + ' should be <...>') split = strip[1:-1].split() if len(split) == 0: Trace.error('Empty XML parameter <>') return None, None key = split[0] del split[0] if len(split) == 0: return key, dict() attrs = dict() for attr in split: if not '=' in attr: Trace.error('Erroneous attribute for ' + key + ': ' + attr) attr += '="0"' parts = attr.split('=') attrkey = parts[0] value = parts[1].split('"')[1] attrs[attrkey] = value return key, attrs def parseending(self, reader, process): "Parse until the current ending is found" if not self.ending: Trace.error('No ending for ' + unicode(self)) return while not reader.currentline().startswith(self.ending): process() def parsecontainer(self, reader, contents): container = self.factory.createcontainer(reader) if container: container.parent = self.parent contents.append(container) def __unicode__(self): "Return a description" return self.__class__.__name__ + ' (' + unicode(self.begin) + ')' class LoneCommand(Parser): "A parser for just one command line" def parse(self,reader): "Read nothing" return [] class TextParser(Parser): "A parser for a command and a bit of text" stack = [] def __init__(self, container): Parser.__init__(self) self.ending = None if container.__class__.__name__ in ContainerConfig.endings: self.ending = ContainerConfig.endings[container.__class__.__name__] self.endings = [] def parse(self, reader): "Parse lines as long as they are text" TextParser.stack.append(self.ending) self.endings = TextParser.stack + [ContainerConfig.endings['Layout'], ContainerConfig.endings['Inset'], self.ending] contents = [] while not self.isending(reader): self.parsecontainer(reader, contents) return contents def isending(self, reader): "Check if text is ending" current = reader.currentline().split() if len(current) == 0: return False if current[0] in self.endings: if current[0] in TextParser.stack: TextParser.stack.remove(current[0]) else: TextParser.stack = [] return True return False class ExcludingParser(Parser): "A parser that excludes the final line" def parse(self, reader): "Parse everything up to (and excluding) the final line" contents = [] self.parseending(reader, lambda: self.parsecontainer(reader, contents)) return contents class BoundedParser(ExcludingParser): "A parser bound by a final line" def parse(self, reader): "Parse everything, including the final line" contents = ExcludingParser.parse(self, reader) # skip last line reader.nextline() return contents class BoundedDummy(Parser): "A bound parser that ignores everything" def parse(self, reader): "Parse the contents of the container" self.parseending(reader, lambda: reader.nextline()) # skip last line reader.nextline() return [] class StringParser(Parser): "Parses just a string" def parseheader(self, reader): "Do nothing, just take note" self.begin = reader.linenumber + 1 return [] def parse(self, reader): "Parse a single line" contents = reader.currentline() reader.nextline() return contents class InsetParser(BoundedParser): "Parses a LyX inset" def parse(self, reader): "Parse inset parameters into a dictionary" startcommand = ContainerConfig.string['startcommand'] while reader.currentline() != '' and not reader.currentline().startswith(startcommand): self.parseparameter(reader) return BoundedParser.parse(self, reader) class ContainerOutput(object): "The generic HTML output for a container." def gethtml(self, container): "Show an error." Trace.error('gethtml() not implemented for ' + unicode(self)) def isempty(self): "Decide if the output is empty: by default, not empty." return False class EmptyOutput(ContainerOutput): def gethtml(self, container): "Return empty HTML code." return [] def isempty(self): "This output is particularly empty." return True class FixedOutput(ContainerOutput): "Fixed output" def gethtml(self, container): "Return constant HTML code" return container.html class ContentsOutput(ContainerOutput): "Outputs the contents converted to HTML" def gethtml(self, container): "Return the HTML code" html = [] if container.contents == None: return html for element in container.contents: if not hasattr(element, 'gethtml'): Trace.error('No html in ' + element.__class__.__name__ + ': ' + unicode(element)) return html html += element.gethtml() return html class TaggedOutput(ContentsOutput): "Outputs an HTML tag surrounding the contents." tag = None breaklines = False empty = False def settag(self, tag, breaklines=False, empty=False): "Set the value for the tag and other attributes." self.tag = tag if breaklines: self.breaklines = breaklines if empty: self.empty = empty return self def setbreaklines(self, breaklines): "Set the value for breaklines." self.breaklines = breaklines return self def gethtml(self, container): "Return the HTML code." if self.empty: return [self.selfclosing(container)] html = [self.open(container)] html += ContentsOutput.gethtml(self, container) html.append(self.close(container)) return html def open(self, container): "Get opening line." if not self.checktag(): return '' open = '<' + self.tag + '>' if self.breaklines: return open + '\n' return open def close(self, container): "Get closing line." if not self.checktag(): return '' close = '' if self.breaklines: return '\n' + close + '\n' return close def selfclosing(self, container): "Get self-closing line." if not self.checktag(): return '' selfclosing = '<' + self.tag + '/>' if self.breaklines: return selfclosing + '\n' return selfclosing def checktag(self): "Check that the tag is valid." if not self.tag: Trace.error('No tag in ' + unicode(container)) return False if self.tag == '': return False return True class FilteredOutput(ContentsOutput): "Returns the output in the contents, but filtered:" "some strings are replaced by others." def __init__(self): "Initialize the filters." self.filters = [] def addfilter(self, original, replacement): "Add a new filter: replace the original by the replacement." self.filters.append((original, replacement)) def gethtml(self, container): "Return the HTML code" result = [] html = ContentsOutput.gethtml(self, container) for line in html: result.append(self.filter(line)) return result def filter(self, line): "Filter a single line with all available filters." for original, replacement in self.filters: if original in line: line = line.replace(original, replacement) return line class StringOutput(ContainerOutput): "Returns a bare string as output" def gethtml(self, container): "Return a bare string" return [container.string] import sys import codecs class LineReader(object): "Reads a file line by line" def __init__(self, filename): if isinstance(filename, file): self.file = filename else: self.file = codecs.open(filename, 'rU', 'utf-8') self.linenumber = 1 self.lastline = None self.current = None self.mustread = True self.depleted = False try: self.readline() except UnicodeDecodeError: # try compressed file import gzip self.file = gzip.open(filename, 'rb') self.readline() def setstart(self, firstline): "Set the first line to read." for i in range(firstline): self.file.readline() self.linenumber = firstline def setend(self, lastline): "Set the last line to read." self.lastline = lastline def currentline(self): "Get the current line" if self.mustread: self.readline() return self.current def nextline(self): "Go to next line" if self.depleted: Trace.fatal('Read beyond file end') self.mustread = True def readline(self): "Read a line from elyxer.file" self.current = self.file.readline() if not isinstance(self.file, codecs.StreamReaderWriter): self.current = self.current.decode('utf-8') if len(self.current) == 0: self.depleted = True self.current = self.current.rstrip('\n\r') self.linenumber += 1 self.mustread = False Trace.prefix = 'Line ' + unicode(self.linenumber) + ': ' if self.linenumber % 1000 == 0: Trace.message('Parsing') def finished(self): "Find out if the file is finished" if self.lastline and self.linenumber == self.lastline: return True if self.mustread: self.readline() return self.depleted def close(self): self.file.close() class LineWriter(object): "Writes a file as a series of lists" file = False def __init__(self, filename): if isinstance(filename, file): self.file = filename self.filename = None else: self.filename = filename def write(self, strings): "Write a list of strings" for string in strings: if not isinstance(string, basestring): Trace.error('Not a string: ' + unicode(string) + ' in ' + unicode(strings)) return self.writestring(string) def writestring(self, string): "Write a string" if not self.file: self.file = codecs.open(self.filename, 'w', "utf-8") if self.file == sys.stdout and sys.version_info < (3,0): string = string.encode('utf-8') self.file.write(string) def writeline(self, line): "Write a line to file" self.writestring(line + '\n') def close(self): self.file.close() class Globable(object): """A bit of text which can be globbed (lumped together in bits). Methods current(), skipcurrent(), checkfor() and isout() have to be implemented by subclasses.""" leavepending = False def __init__(self): self.endinglist = EndingList() def checkbytemark(self): "Check for a Unicode byte mark and skip it." if self.finished(): return if ord(self.current()) == 0xfeff: self.skipcurrent() def isout(self): "Find out if we are out of the position yet." Trace.error('Unimplemented isout()') return True def current(self): "Return the current character." Trace.error('Unimplemented current()') return '' def checkfor(self, string): "Check for the given string in the current position." Trace.error('Unimplemented checkfor()') return False def finished(self): "Find out if the current text has finished." if self.isout(): if not self.leavepending: self.endinglist.checkpending() return True return self.endinglist.checkin(self) def skipcurrent(self): "Return the current character and skip it." Trace.error('Unimplemented skipcurrent()') return '' def glob(self, currentcheck): "Glob a bit of text that satisfies a check on the current char." glob = '' while not self.finished() and currentcheck(): glob += self.skipcurrent() return glob def globalpha(self): "Glob a bit of alpha text" return self.glob(lambda: self.current().isalpha()) def globnumber(self): "Glob a row of digits." return self.glob(lambda: self.current().isdigit()) def isidentifier(self): "Return if the current character is alphanumeric or _." if self.current().isalnum() or self.current() == '_': return True return False def globidentifier(self): "Glob alphanumeric and _ symbols." return self.glob(self.isidentifier) def isvalue(self): "Return if the current character is a value character:" "not a bracket or a space." if self.current().isspace(): return False if self.current() in '{}()': return False return True def globvalue(self): "Glob a value: any symbols but brackets." return self.glob(self.isvalue) def skipspace(self): "Skip all whitespace at current position." return self.glob(lambda: self.current().isspace()) def globincluding(self, magicchar): "Glob a bit of text up to (including) the magic char." glob = self.glob(lambda: self.current() != magicchar) + magicchar self.skip(magicchar) return glob def globexcluding(self, excluded): "Glob a bit of text up until (excluding) any excluded character." return self.glob(lambda: self.current() not in excluded) def pushending(self, ending, optional = False): "Push a new ending to the bottom" self.endinglist.add(ending, optional) def popending(self, expected = None): "Pop the ending found at the current position" if self.isout() and self.leavepending: return expected ending = self.endinglist.pop(self) if expected and expected != ending: Trace.error('Expected ending ' + expected + ', got ' + ending) self.skip(ending) return ending def nextending(self): "Return the next ending in the queue." nextending = self.endinglist.findending(self) if not nextending: return None return nextending.ending class EndingList(object): "A list of position endings" def __init__(self): self.endings = [] def add(self, ending, optional = False): "Add a new ending to the list" self.endings.append(PositionEnding(ending, optional)) def pickpending(self, pos): "Pick any pending endings from a parse position." self.endings += pos.endinglist.endings def checkin(self, pos): "Search for an ending" if self.findending(pos): return True return False def pop(self, pos): "Remove the ending at the current position" if pos.isout(): Trace.error('No ending out of bounds') return '' ending = self.findending(pos) if not ending: Trace.error('No ending at ' + pos.current()) return '' for each in reversed(self.endings): self.endings.remove(each) if each == ending: return each.ending elif not each.optional: Trace.error('Removed non-optional ending ' + each) Trace.error('No endings left') return '' def findending(self, pos): "Find the ending at the current position" if len(self.endings) == 0: return None for index, ending in enumerate(reversed(self.endings)): if ending.checkin(pos): return ending if not ending.optional: return None return None def checkpending(self): "Check if there are any pending endings" if len(self.endings) != 0: Trace.error('Pending ' + unicode(self) + ' left open') def __unicode__(self): "Printable representation" string = 'endings [' for ending in self.endings: string += unicode(ending) + ',' if len(self.endings) > 0: string = string[:-1] return string + ']' class PositionEnding(object): "An ending for a parsing position" def __init__(self, ending, optional): self.ending = ending self.optional = optional def checkin(self, pos): "Check for the ending" return pos.checkfor(self.ending) def __unicode__(self): "Printable representation" string = 'Ending ' + self.ending if self.optional: string += ' (optional)' return string class Position(Globable): """A position in a text to parse. Including those in Globable, functions to implement by subclasses are: skip(), identifier(), extract(), isout() and current().""" def __init__(self): Globable.__init__(self) def skip(self, string): "Skip a string" Trace.error('Unimplemented skip()') def identifier(self): "Return an identifier for the current position." Trace.error('Unimplemented identifier()') return 'Error' def extract(self, length): "Extract the next string of the given length, or None if not enough text," "without advancing the parse position." Trace.error('Unimplemented extract()') return None def checkfor(self, string): "Check for a string at the given position." return string == self.extract(len(string)) def checkforlower(self, string): "Check for a string in lower case." extracted = self.extract(len(string)) if not extracted: return False return string.lower() == self.extract(len(string)).lower() def skipcurrent(self): "Return the current character and skip it." current = self.current() self.skip(current) return current def next(self): "Advance the position and return the next character." self.skipcurrent() return self.current() def checkskip(self, string): "Check for a string at the given position; if there, skip it" if not self.checkfor(string): return False self.skip(string) return True def error(self, message): "Show an error message and the position identifier." Trace.error(message + ': ' + self.identifier()) class TextPosition(Position): "A parse position based on a raw text." def __init__(self, text): "Create the position from elyxer.some text." Position.__init__(self) self.pos = 0 self.text = text self.checkbytemark() def skip(self, string): "Skip a string of characters." self.pos += len(string) def identifier(self): "Return a sample of the remaining text." length = 30 if self.pos + length > len(self.text): length = len(self.text) - self.pos return '*' + self.text[self.pos:self.pos + length] + '*' def isout(self): "Find out if we are out of the text yet." return self.pos >= len(self.text) def current(self): "Return the current character, assuming we are not out." return self.text[self.pos] def extract(self, length): "Extract the next string of the given length, or None if not enough text." if self.pos + length > len(self.text): return None return self.text[self.pos : self.pos + length] class FilePosition(Position): "A parse position based on an underlying file." def __init__(self, filename): "Create the position from a file." Position.__init__(self) self.reader = LineReader(filename) self.pos = 0 self.checkbytemark() def skip(self, string): "Skip a string of characters." length = len(string) while self.pos + length > len(self.reader.currentline()): length -= len(self.reader.currentline()) - self.pos + 1 self.nextline() self.pos += length def currentline(self): "Get the current line of the underlying file." return self.reader.currentline() def nextline(self): "Go to the next line." self.reader.nextline() self.pos = 0 def linenumber(self): "Return the line number of the file." return self.reader.linenumber + 1 def identifier(self): "Return the current line and line number in the file." before = self.reader.currentline()[:self.pos - 1] after = self.reader.currentline()[self.pos:] return 'line ' + unicode(self.getlinenumber()) + ': ' + before + '*' + after def isout(self): "Find out if we are out of the text yet." if self.pos > len(self.reader.currentline()): if self.pos > len(self.reader.currentline()) + 1: Trace.error('Out of the line ' + self.reader.currentline() + ': ' + unicode(self.pos)) self.nextline() return self.reader.finished() def current(self): "Return the current character, assuming we are not out." if self.pos == len(self.reader.currentline()): return '\n' if self.pos > len(self.reader.currentline()): Trace.error('Out of the line ' + self.reader.currentline() + ': ' + unicode(self.pos)) return '*' return self.reader.currentline()[self.pos] def extract(self, length): "Extract the next string of the given length, or None if not enough text." if self.pos + length > len(self.reader.currentline()): return None return self.reader.currentline()[self.pos : self.pos + length] class Container(object): "A container for text and objects in a lyx file" partkey = None parent = None begin = None def __init__(self): self.contents = list() def process(self): "Process contents" pass def gethtml(self): "Get the resulting HTML" html = self.output.gethtml(self) if isinstance(html, basestring): Trace.error('Raw string ' + html) html = [html] return self.escapeall(html) def escapeall(self, lines): "Escape all lines in an array according to the output options." result = [] for line in lines: if Options.html: line = self.escape(line, EscapeConfig.html) if Options.iso885915: line = self.escape(line, EscapeConfig.iso885915) line = self.escapeentities(line) elif not Options.unicode: line = self.escape(line, EscapeConfig.nonunicode) result.append(line) return result def escape(self, line, replacements = EscapeConfig.entities): "Escape a line with replacements from elyxer.a map" pieces = replacements.keys() # do them in order pieces.sort() for piece in pieces: if piece in line: line = line.replace(piece, replacements[piece]) return line def escapeentities(self, line): "Escape all Unicode characters to HTML entities." result = '' pos = TextPosition(line) while not pos.finished(): if ord(pos.current()) > 128: codepoint = hex(ord(pos.current())) if codepoint == '0xd835': codepoint = hex(ord(pos.next()) + 0xf800) result += '&#' + codepoint[1:] + ';' else: result += pos.current() pos.skipcurrent() return result def searchall(self, type): "Search for all embedded containers of a given type" list = [] self.searchprocess(type, lambda container: list.append(container)) return list def searchremove(self, type): "Search for all containers of a type and remove them" list = self.searchall(type) for container in list: container.parent.contents.remove(container) return list def searchprocess(self, type, process): "Search for elements of a given type and process them" self.locateprocess(lambda container: isinstance(container, type), process) def locateprocess(self, locate, process): "Search for all embedded containers and process them" for container in self.contents: container.locateprocess(locate, process) if locate(container): process(container) def recursivesearch(self, locate, recursive, process): "Perform a recursive search in the container." for container in self.contents: if recursive(container): container.recursivesearch(locate, recursive, process) if locate(container): process(container) def extracttext(self): "Extract all text from elyxer.allowed containers." result = '' constants = ContainerExtractor(ContainerConfig.extracttext).extract(self) for constant in constants: result += constant.string return result def group(self, index, group, isingroup): "Group some adjoining elements into a group" if index >= len(self.contents): return if hasattr(self.contents[index], 'grouped'): return while index < len(self.contents) and isingroup(self.contents[index]): self.contents[index].grouped = True group.contents.append(self.contents[index]) self.contents.pop(index) self.contents.insert(index, group) def remove(self, index): "Remove a container but leave its contents" container = self.contents[index] self.contents.pop(index) while len(container.contents) > 0: self.contents.insert(index, container.contents.pop()) def tree(self, level = 0): "Show in a tree" Trace.debug(" " * level + unicode(self)) for container in self.contents: container.tree(level + 1) def getparameter(self, name): "Get the value of a parameter, if present." if not name in self.parameters: return None return self.parameters[name] def getparameterlist(self, name): "Get the value of a comma-separated parameter as a list." paramtext = self.getparameter(name) if not paramtext: return [] return paramtext.split(',') def hasemptyoutput(self): "Check if the parent's output is empty." current = self.parent while current: if current.output.isempty(): return True current = current.parent return False def __unicode__(self): "Get a description" if not self.begin: return self.__class__.__name__ return self.__class__.__name__ + '@' + unicode(self.begin) class BlackBox(Container): "A container that does not output anything" def __init__(self): self.parser = LoneCommand() self.output = EmptyOutput() self.contents = [] class LyXFormat(BlackBox): "Read the lyxformat command" def process(self): "Show warning if version < 276" version = int(self.header[1]) if version < 276: Trace.error('Warning: unsupported old format version ' + str(version)) if version > int(GeneralConfig.version['lyxformat']): Trace.error('Warning: unsupported new format version ' + str(version)) class StringContainer(Container): "A container for a single string" parsed = None def __init__(self): self.parser = StringParser() self.output = StringOutput() self.string = '' def process(self): "Replace special chars from elyxer.the contents." if self.parsed: self.string = self.replacespecial(self.parsed) self.parsed = None def replacespecial(self, line): "Replace all special chars from elyxer.a line" replaced = self.escape(line, EscapeConfig.entities) replaced = self.changeline(replaced) if ContainerConfig.string['startcommand'] in replaced and len(replaced) > 1: # unprocessed commands if self.begin: message = 'Unknown command at ' + unicode(self.begin) + ': ' else: message = 'Unknown command: ' Trace.error(message + replaced.strip()) return replaced def changeline(self, line): line = self.escape(line, EscapeConfig.chars) if not ContainerConfig.string['startcommand'] in line: return line line = self.escape(line, EscapeConfig.commands) return line def extracttext(self): "Return all text." return self.string def __unicode__(self): "Return a printable representation." result = 'StringContainer' if self.begin: result += '@' + unicode(self.begin) ellipsis = '...' if len(self.string.strip()) <= 15: ellipsis = '' return result + ' (' + self.string.strip()[:15] + ellipsis + ')' class Constant(StringContainer): "A constant string" def __init__(self, text): self.contents = [] self.string = text self.output = StringOutput() def __unicode__(self): return 'Constant: ' + self.string class TaggedText(Container): "Text inside a tag" output = None def __init__(self): self.parser = TextParser(self) self.output = TaggedOutput() def complete(self, contents, tag, breaklines=False): "Complete the tagged text and return it" self.contents = contents self.output.tag = tag self.output.breaklines = breaklines return self def constant(self, text, tag, breaklines=False): "Complete the tagged text with a constant" constant = Constant(text) return self.complete([constant], tag, breaklines) def __unicode__(self): "Return a printable representation." if not hasattr(self.output, 'tag'): return 'Emtpy tagged text' if not self.output.tag: return 'Tagged ' return 'Tagged <' + self.output.tag + '>' class DocumentParameters(object): "Global parameters for the document." pdftitle = None indentstandard = False tocdepth = 10 startinglevel = 0 maxdepth = 10 language = None bibliography = None outputchanges = False displaymode = False class FormulaParser(Parser): "Parses a formula" def parseheader(self, reader): "See if the formula is inlined" self.begin = reader.linenumber + 1 type = self.parsetype(reader) if not type: reader.nextline() type = self.parsetype(reader) if not type: Trace.error('Unknown formula type in ' + reader.currentline().strip()) return ['unknown'] return [type] def parsetype(self, reader): "Get the formula type from the first line." if reader.currentline().find(FormulaConfig.starts['simple']) >= 0: return 'inline' if reader.currentline().find(FormulaConfig.starts['complex']) >= 0: return 'block' if reader.currentline().find(FormulaConfig.starts['unnumbered']) >= 0: return 'block' if reader.currentline().find(FormulaConfig.starts['beginbefore']) >= 0: return 'numbered' return None def parse(self, reader): "Parse the formula until the end" formula = self.parseformula(reader) while not reader.currentline().startswith(self.ending): stripped = reader.currentline().strip() if len(stripped) > 0: Trace.error('Unparsed formula line ' + stripped) reader.nextline() reader.nextline() return formula def parseformula(self, reader): "Parse the formula contents" simple = FormulaConfig.starts['simple'] if simple in reader.currentline(): rest = reader.currentline().split(simple, 1)[1] if simple in rest: # formula is $...$ return self.parsesingleliner(reader, simple, simple) # formula is multiline $...$ return self.parsemultiliner(reader, simple, simple) if FormulaConfig.starts['complex'] in reader.currentline(): # formula of the form \[...\] return self.parsemultiliner(reader, FormulaConfig.starts['complex'], FormulaConfig.endings['complex']) beginbefore = FormulaConfig.starts['beginbefore'] beginafter = FormulaConfig.starts['beginafter'] if beginbefore in reader.currentline(): if reader.currentline().strip().endswith(beginafter): current = reader.currentline().strip() endsplit = current.split(beginbefore)[1].split(beginafter) startpiece = beginbefore + endsplit[0] + beginafter endbefore = FormulaConfig.endings['endbefore'] endafter = FormulaConfig.endings['endafter'] endpiece = endbefore + endsplit[0] + endafter return startpiece + self.parsemultiliner(reader, startpiece, endpiece) + endpiece Trace.error('Missing ' + beginafter + ' in ' + reader.currentline()) return '' begincommand = FormulaConfig.starts['command'] beginbracket = FormulaConfig.starts['bracket'] if begincommand in reader.currentline() and beginbracket in reader.currentline(): endbracket = FormulaConfig.endings['bracket'] return self.parsemultiliner(reader, beginbracket, endbracket) Trace.error('Formula beginning ' + reader.currentline() + ' is unknown') return '' def parsesingleliner(self, reader, start, ending): "Parse a formula in one line" line = reader.currentline().strip() if not start in line: Trace.error('Line ' + line + ' does not contain formula start ' + start) return '' if not line.endswith(ending): Trace.error('Formula ' + line + ' does not end with ' + ending) return '' index = line.index(start) rest = line[index + len(start):-len(ending)] reader.nextline() return rest def parsemultiliner(self, reader, start, ending): "Parse a formula in multiple lines" formula = '' line = reader.currentline() if not start in line: Trace.error('Line ' + line.strip() + ' does not contain formula start ' + start) return '' index = line.index(start) line = line[index + len(start):].strip() while not line.endswith(ending): formula += line + '\n' reader.nextline() line = reader.currentline() formula += line[:-len(ending)] reader.nextline() return formula class MacroParser(FormulaParser): "A parser for a formula macro." def parseheader(self, reader): "See if the formula is inlined" self.begin = reader.linenumber + 1 return ['inline'] def parse(self, reader): "Parse the formula until the end" formula = self.parsemultiliner(reader, self.parent.start, self.ending) reader.nextline() return formula class FormulaBit(Container): "A bit of a formula" type = None size = 1 original = '' def __init__(self): "The formula bit type can be 'alpha', 'number', 'font'." self.contents = [] self.output = ContentsOutput() def setfactory(self, factory): "Set the internal formula factory." self.factory = factory return self def add(self, bit): "Add any kind of formula bit already processed" self.contents.append(bit) self.original += bit.original bit.parent = self def skiporiginal(self, string, pos): "Skip a string and add it to the original formula" self.original += string if not pos.checkskip(string): Trace.error('String ' + string + ' not at ' + pos.identifier()) def computesize(self): "Compute the size of the bit as the max of the sizes of all contents." if len(self.contents) == 0: return 1 self.size = max([element.size for element in self.contents]) return self.size def clone(self): "Return a copy of itself." return self.factory.parseformula(self.original) def __unicode__(self): "Get a string representation" return self.__class__.__name__ + ' read in ' + self.original class TaggedBit(FormulaBit): "A tagged string in a formula" def constant(self, constant, tag): "Set the constant and the tag" self.output = TaggedOutput().settag(tag) self.add(FormulaConstant(constant)) return self def complete(self, contents, tag, breaklines = False): "Set the constant and the tag" self.contents = contents self.output = TaggedOutput().settag(tag, breaklines) return self def selfcomplete(self, tag): "Set the self-closing tag, no contents (as in
)." self.output = TaggedOutput().settag(tag, empty = True) return self class FormulaConstant(Constant): "A constant string in a formula" def __init__(self, string): "Set the constant string" Constant.__init__(self, string) self.original = string self.size = 1 self.type = None def computesize(self): "Compute the size of the constant: always 1." return self.size def clone(self): "Return a copy of itself." return FormulaConstant(self.original) def __unicode__(self): "Return a printable representation." return 'Formula constant: ' + self.string class RawText(FormulaBit): "A bit of text inside a formula" def detect(self, pos): "Detect a bit of raw text" return pos.current().isalpha() def parsebit(self, pos): "Parse alphabetic text" alpha = pos.globalpha() self.add(FormulaConstant(alpha)) self.type = 'alpha' class FormulaSymbol(FormulaBit): "A symbol inside a formula" modified = FormulaConfig.modified unmodified = FormulaConfig.unmodified['characters'] def detect(self, pos): "Detect a symbol" if pos.current() in FormulaSymbol.unmodified: return True if pos.current() in FormulaSymbol.modified: return True return False def parsebit(self, pos): "Parse the symbol" if pos.current() in FormulaSymbol.unmodified: self.addsymbol(pos.current(), pos) return if pos.current() in FormulaSymbol.modified: self.addsymbol(FormulaSymbol.modified[pos.current()], pos) return Trace.error('Symbol ' + pos.current() + ' not found') def addsymbol(self, symbol, pos): "Add a symbol" self.skiporiginal(pos.current(), pos) self.contents.append(FormulaConstant(symbol)) class FormulaNumber(FormulaBit): "A string of digits in a formula" def detect(self, pos): "Detect a digit" return pos.current().isdigit() def parsebit(self, pos): "Parse a bunch of digits" digits = pos.glob(lambda: pos.current().isdigit()) self.add(FormulaConstant(digits)) self.type = 'number' class Comment(FormulaBit): "A LaTeX comment: % to the end of the line." start = FormulaConfig.starts['comment'] def detect(self, pos): "Detect the %." return pos.current() == self.start def parsebit(self, pos): "Parse to the end of the line." self.original += pos.globincluding('\n') class WhiteSpace(FormulaBit): "Some white space inside a formula." def detect(self, pos): "Detect the white space." return pos.current().isspace() def parsebit(self, pos): "Parse all whitespace." self.original += pos.skipspace() def __unicode__(self): "Return a printable representation." return 'Whitespace: *' + self.original + '*' class Bracket(FormulaBit): "A {} bracket inside a formula" start = FormulaConfig.starts['bracket'] ending = FormulaConfig.endings['bracket'] def __init__(self): "Create a (possibly literal) new bracket" FormulaBit.__init__(self) self.inner = None def detect(self, pos): "Detect the start of a bracket" return pos.checkfor(self.start) def parsebit(self, pos): "Parse the bracket" self.parsecomplete(pos, self.innerformula) return self def parsetext(self, pos): "Parse a text bracket" self.parsecomplete(pos, self.innertext) return self def parseliteral(self, pos): "Parse a literal bracket" self.parsecomplete(pos, self.innerliteral) return self def parsecomplete(self, pos, innerparser): "Parse the start and end marks" if not pos.checkfor(self.start): Trace.error('Bracket should start with ' + self.start + ' at ' + pos.identifier()) return None self.skiporiginal(self.start, pos) pos.pushending(self.ending) innerparser(pos) self.original += pos.popending(self.ending) self.computesize() def innerformula(self, pos): "Parse a whole formula inside the bracket" while not pos.finished(): self.add(self.factory.parseany(pos)) def innertext(self, pos): "Parse some text inside the bracket, following textual rules." specialchars = FormulaConfig.symbolfunctions.keys() specialchars.append(FormulaConfig.starts['command']) specialchars.append(FormulaConfig.starts['bracket']) specialchars.append(Comment.start) while not pos.finished(): if pos.current() in specialchars: self.add(self.factory.parseany(pos)) if pos.checkskip(' '): self.original += ' ' else: self.add(FormulaConstant(pos.skipcurrent())) def innerliteral(self, pos): "Parse a literal inside the bracket, which does not generate HTML." self.literal = '' while not pos.finished() and not pos.current() == self.ending: if pos.current() == self.start: self.parseliteral(pos) else: self.literal += pos.skipcurrent() self.original += self.literal class SquareBracket(Bracket): "A [] bracket inside a formula" start = FormulaConfig.starts['squarebracket'] ending = FormulaConfig.endings['squarebracket'] def clone(self): "Return a new square bracket with the same contents." bracket = SquareBracket() bracket.contents = self.contents return bracket class MathsProcessor(object): "A processor for a maths construction inside the FormulaProcessor." def process(self, contents, index): "Process an element inside a formula." Trace.error('Unimplemented process() in ' + unicode(self)) def __unicode__(self): "Return a printable description." return 'Maths processor ' + self.__class__.__name__ class FormulaProcessor(object): "A processor specifically for formulas." processors = [] def process(self, bit): "Process the contents of every formula bit, recursively." self.processcontents(bit) self.processinsides(bit) self.traversewhole(bit) def processcontents(self, bit): "Process the contents of a formula bit." if not isinstance(bit, FormulaBit): return bit.process() for element in bit.contents: self.processcontents(element) def processinsides(self, bit): "Process the insides (limits, brackets) in a formula bit." if not isinstance(bit, FormulaBit): return for index, element in enumerate(bit.contents): for processor in self.processors: processor.process(bit.contents, index) # continue with recursive processing self.processinsides(element) def traversewhole(self, formula): "Traverse over the contents to alter variables and space units." last = None for bit, contents in self.traverse(formula): if bit.type == 'alpha': self.italicize(bit, contents) elif bit.type == 'font' and last and last.type == 'number': bit.contents.insert(0, FormulaConstant(u' ')) last = bit def traverse(self, bit): "Traverse a formula and yield a flattened structure of (bit, list) pairs." for element in bit.contents: if hasattr(element, 'type') and element.type: yield (element, bit.contents) elif isinstance(element, FormulaBit): for pair in self.traverse(element): yield pair def italicize(self, bit, contents): "Italicize the given bit of text." index = contents.index(bit) contents[index] = TaggedBit().complete([bit], 'i') class Formula(Container): "A LaTeX formula" def __init__(self): self.parser = FormulaParser() self.output = TaggedOutput().settag('span class="formula"') def process(self): "Convert the formula to tags" if self.header[0] == 'inline': DocumentParameters.displaymode = False else: DocumentParameters.displaymode = True self.output.settag('div class="formula"', True) if Options.jsmath: self.jsmath() elif Options.mathjax: self.mathjax() elif Options.googlecharts: self.googlecharts() else: self.classic() def jsmath(self): "Make the contents for jsMath." if self.header[0] != 'inline': self.output = TaggedOutput().settag('div class="math"') else: self.output = TaggedOutput().settag('span class="math"') self.contents = [Constant(self.parsed)] def mathjax(self): "Make the contents for MathJax." self.output.tag = 'span class="MathJax_Preview"' tag = 'script type="math/tex' if self.header[0] != 'inline': tag += ';mode=display' self.contents = [TaggedText().constant(self.parsed, tag + '"', True)] def googlecharts(self): "Make the contents using Google Charts http://code.google.com/apis/chart/." url = FormulaConfig.urls['googlecharts'] + urllib.quote_plus(self.parsed) img = '' + self.parsed + '' self.contents = [Constant(img)] def classic(self): "Make the contents using classic output generation with XHTML and CSS." whole = FormulaFactory().parseformula(self.parsed) FormulaProcessor().process(whole) whole.parent = self self.contents = [whole] def parse(self, pos): "Parse using a parse position instead of self.parser." if pos.checkskip('$$'): self.parsedollarblock(pos) elif pos.checkskip('$'): self.parsedollarinline(pos) elif pos.checkskip('\\('): self.parseinlineto(pos, '\\)') elif pos.checkskip('\\['): self.parseblockto(pos, '\\]') else: pos.error('Unparseable formula') self.process() return self def parsedollarinline(self, pos): "Parse a $...$ formula." self.header = ['inline'] self.parsedollar(pos) def parsedollarblock(self, pos): "Parse a $$...$$ formula." self.header = ['block'] self.parsedollar(pos) if not pos.checkskip('$'): pos.error('Formula should be $$...$$, but last $ is missing.') def parsedollar(self, pos): "Parse to the next $." pos.pushending('$') self.parsed = pos.globexcluding('$') pos.popending('$') def parseinlineto(self, pos, limit): "Parse a \\(...\\) formula." self.header = ['inline'] self.parseupto(pos, limit) def parseblockto(self, pos, limit): "Parse a \\[...\\] formula." self.header = ['block'] self.parseupto(pos, limit) def parseupto(self, pos, limit): "Parse a formula that ends with the given command." pos.pushending(limit) self.parsed = pos.glob(lambda: True) pos.popending(limit) def __unicode__(self): "Return a printable representation." if self.partkey and self.partkey.number: return 'Formula (' + self.partkey.number + ')' return 'Unnumbered formula' class WholeFormula(FormulaBit): "Parse a whole formula" def detect(self, pos): "Not outside the formula is enough." return not pos.finished() def parsebit(self, pos): "Parse with any formula bit" while not pos.finished(): self.add(self.factory.parseany(pos)) class FormulaFactory(object): "Construct bits of formula" # bit types will be appended later types = [FormulaSymbol, RawText, FormulaNumber, Bracket, Comment, WhiteSpace] skippedtypes = [Comment, WhiteSpace] defining = False def __init__(self): "Initialize the map of instances." self.instances = dict() def detecttype(self, type, pos): "Detect a bit of a given type." if pos.finished(): return False return self.instance(type).detect(pos) def instance(self, type): "Get an instance of the given type." if not type in self.instances or not self.instances[type]: self.instances[type] = self.create(type) return self.instances[type] def create(self, type): "Create a new formula bit of the given type." return Cloner.create(type).setfactory(self) def clearskipped(self, pos): "Clear any skipped types." while not pos.finished(): if not self.skipany(pos): return return def skipany(self, pos): "Skip any skipped types." for type in self.skippedtypes: if self.instance(type).detect(pos): return self.parsetype(type, pos) return None def parseany(self, pos): "Parse any formula bit at the current location." for type in self.types + self.skippedtypes: if self.detecttype(type, pos): return self.parsetype(type, pos) Trace.error('Unrecognized formula at ' + pos.identifier()) return FormulaConstant(pos.skipcurrent()) def parsetype(self, type, pos): "Parse the given type and return it." bit = self.instance(type) self.instances[type] = None returnedbit = bit.parsebit(pos) if returnedbit: return returnedbit.setfactory(self) return bit def parseformula(self, formula): "Parse a string of text that contains a whole formula." pos = TextPosition(formula) whole = self.create(WholeFormula) if whole.detect(pos): whole.parsebit(pos) return whole # no formula found if not pos.finished(): Trace.error('Unknown formula at: ' + pos.identifier()) whole.add(TaggedBit().constant(formula, 'span class="unknown"')) return whole import unicodedata import gettext class Translator(object): "Reads the configuration file and tries to find a translation." "Otherwise falls back to the messages in the config file." instance = None def translate(cls, key): "Get the translated message for a key." return cls.instance.getmessage(key) translate = classmethod(translate) def __init__(self): self.translation = None self.first = True def findtranslation(self): "Find the translation for the document language." self.langcodes = None if not DocumentParameters.language: Trace.error('No language in document') return if not DocumentParameters.language in TranslationConfig.languages: Trace.error('Unknown language ' + DocumentParameters.language) return if TranslationConfig.languages[DocumentParameters.language] == 'en': return langcodes = [TranslationConfig.languages[DocumentParameters.language]] try: self.translation = gettext.translation('elyxer', None, langcodes) except IOError: Trace.error('No translation for ' + unicode(langcodes)) def getmessage(self, key): "Get the translated message for the given key." if self.first: self.findtranslation() self.first = False message = self.getuntranslated(key) if not self.translation: return message try: message = self.translation.ugettext(message) except IOError: pass return message def getuntranslated(self, key): "Get the untranslated message." if not key in TranslationConfig.constants: Trace.error('Cannot translate ' + key) return key return TranslationConfig.constants[key] Translator.instance = Translator() class NumberCounter(object): "A counter for numbers (by default)." "The type can be changed to return letters, roman numbers..." name = None value = None mode = None master = None letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' symbols = NumberingConfig.sequence['symbols'] romannumerals = [ ('M', 1000), ('CM', 900), ('D', 500), ('CD', 400), ('C', 100), ('XC', 90), ('L', 50), ('XL', 40), ('X', 10), ('IX', 9), ('V', 5), ('IV', 4), ('I', 1) ] def __init__(self, name): "Give a name to the counter." self.name = name def setmode(self, mode): "Set the counter mode. Can be changed at runtime." self.mode = mode return self def init(self, value): "Set an initial value." self.value = value def gettext(self): "Get the next value as a text string." return unicode(self.value) def getletter(self): "Get the next value as a letter." return self.getsequence(self.letters) def getsymbol(self): "Get the next value as a symbol." return self.getsequence(self.symbols) def getsequence(self, sequence): "Get the next value from elyxer.a sequence." return sequence[(self.value - 1) % len(sequence)] def getroman(self): "Get the next value as a roman number." result = '' number = self.value for numeral, value in self.romannumerals: if number >= value: result += numeral * (number / value) number = number % value return result def getvalue(self): "Get the current value as configured in the current mode." if not self.mode or self.mode in ['text', '1']: return self.gettext() if self.mode == 'A': return self.getletter() if self.mode == 'a': return self.getletter().lower() if self.mode == 'I': return self.getroman() if self.mode == '*': return self.getsymbol() Trace.error('Unknown counter mode ' + self.mode) return self.gettext() def getnext(self): "Increase the current value and get the next value as configured." if not self.value: self.value = 0 self.value += 1 return self.getvalue() def reset(self): "Reset the counter." self.value = 0 def __unicode__(self): "Return a printable representation." result = 'Counter ' + self.name if self.mode: result += ' in mode ' + self.mode return result class DependentCounter(NumberCounter): "A counter which depends on another one (the master)." def setmaster(self, master): "Set the master counter." self.master = master self.last = self.master.getvalue() return self def getnext(self): "Increase or, if the master counter has changed, restart." if self.last != self.master.getvalue(): self.reset() value = NumberCounter.getnext(self) self.last = self.master.getvalue() return value def getvalue(self): "Get the value of the combined counter: master.dependent." return self.master.getvalue() + '.' + NumberCounter.getvalue(self) class NumberGenerator(object): "A number generator for unique sequences and hierarchical structures. Used in:" " * ordered part numbers: Chapter 3, Section 5.3." " * unique part numbers: Footnote 15, Bibliography cite [15]." " * chaptered part numbers: Figure 3.15, Equation (8.3)." " * unique roman part numbers: Part I, Book IV." chaptered = None generator = None romanlayouts = [x.lower() for x in NumberingConfig.layouts['roman']] orderedlayouts = [x.lower() for x in NumberingConfig.layouts['ordered']] counters = dict() appendix = None def deasterisk(self, type): "Remove the possible asterisk in a layout type." return type.replace('*', '') def isunique(self, type): "Find out if the layout type corresponds to a unique part." return self.isroman(type) def isroman(self, type): "Find out if the layout type should have roman numeration." return self.deasterisk(type).lower() in self.romanlayouts def isinordered(self, type): "Find out if the layout type corresponds to an (un)ordered part." return self.deasterisk(type).lower() in self.orderedlayouts def isnumbered(self, type): "Find out if the type for a layout corresponds to a numbered layout." if '*' in type: return False if self.isroman(type): return True if not self.isinordered(type): return False if self.getlevel(type) > DocumentParameters.maxdepth: return False return True def isunordered(self, type): "Find out if the type contains an asterisk, basically." return '*' in type def getlevel(self, type): "Get the level that corresponds to a layout type." if self.isunique(type): return 0 if not self.isinordered(type): Trace.error('Unknown layout type ' + type) return 0 type = self.deasterisk(type).lower() level = self.orderedlayouts.index(type) + 1 return level - DocumentParameters.startinglevel def getparttype(self, type): "Obtain the type for the part: without the asterisk, " "and switched to Appendix if necessary." if NumberGenerator.appendix and self.getlevel(type) == 1: return 'Appendix' return self.deasterisk(type) def generate(self, type): "Generate a number for a layout type." "Unique part types such as Part or Book generate roman numbers: Part I." "Ordered part types return dot-separated tuples: Chapter 5, Subsection 2.3.5." "Everything else generates unique numbers: Bibliography [1]." "Each invocation results in a new number." return self.getcounter(type).getnext() def getcounter(self, type): "Get the counter for the given type." type = type.lower() if not type in self.counters: self.counters[type] = self.create(type) return self.counters[type] def create(self, type): "Create a counter for the given type." if self.isnumbered(type) and self.getlevel(type) > 1: index = self.orderedlayouts.index(type) above = self.orderedlayouts[index - 1] master = self.getcounter(above) return self.createdependent(type, master) counter = NumberCounter(type) if self.isroman(type): counter.setmode('I') return counter def getdependentcounter(self, type, master): "Get (or create) a counter of the given type that depends on another." if not type in self.counters or not self.counters[type].master: self.counters[type] = self.createdependent(type, master) return self.counters[type] def createdependent(self, type, master): "Create a dependent counter given the master." return DependentCounter(type).setmaster(master) def startappendix(self): "Start appendices here." firsttype = self.orderedlayouts[DocumentParameters.startinglevel] counter = self.getcounter(firsttype) counter.setmode('A').reset() NumberGenerator.appendix = True class ChapteredGenerator(NumberGenerator): "Generate chaptered numbers, as in Chapter.Number." "Used in equations, figures: Equation (5.3), figure 8.15." def generate(self, type): "Generate a number which goes with first-level numbers (chapters). " "For the article classes a unique number is generated." if DocumentParameters.startinglevel > 0: return NumberGenerator.generator.generate(type) chapter = self.getcounter('Chapter') return self.getdependentcounter(type, chapter).getnext() NumberGenerator.chaptered = ChapteredGenerator() NumberGenerator.generator = NumberGenerator() class ContainerSize(object): "The size of a container." width = None height = None maxwidth = None maxheight = None scale = None def set(self, width = None, height = None): "Set the proper size with width and height." self.setvalue('width', width) self.setvalue('height', height) return self def setmax(self, maxwidth = None, maxheight = None): "Set max width and/or height." self.setvalue('maxwidth', maxwidth) self.setvalue('maxheight', maxheight) return self def readparameters(self, container): "Read some size parameters off a container." self.setparameter(container, 'width') self.setparameter(container, 'height') self.setparameter(container, 'scale') self.checkvalidheight(container) return self def setparameter(self, container, name): "Read a size parameter off a container, and set it if present." value = container.getparameter(name) self.setvalue(name, value) def setvalue(self, name, value): "Set the value of a parameter name, only if it's valid." value = self.processparameter(value) if value: setattr(self, name, value) def checkvalidheight(self, container): "Check if the height parameter is valid; otherwise erase it." heightspecial = container.getparameter('height_special') if self.height and self.extractnumber(self.height) == '1' and heightspecial == 'totalheight': self.height = None def processparameter(self, value): "Do the full processing on a parameter." if not value: return None if self.extractnumber(value) == '0': return None for ignored in StyleConfig.size['ignoredtexts']: if ignored in value: value = value.replace(ignored, '') return value def extractnumber(self, text): "Extract the first number in the given text." result = '' decimal = False for char in text: if char.isdigit(): result += char elif char == '.' and not decimal: result += char decimal = True else: return result return result def checkimage(self, width, height): "Check image dimensions, set them if possible." if width: self.maxwidth = unicode(width) + 'px' if self.scale and not self.width: self.width = self.scalevalue(width) if height: self.maxheight = unicode(height) + 'px' if self.scale and not self.height: self.height = self.scalevalue(height) if self.width and not self.height: self.height = 'auto' if self.height and not self.width: self.width = 'auto' def scalevalue(self, value): "Scale the value according to the image scale and return it as unicode." scaled = value * int(self.scale) / 100 return unicode(int(scaled)) + 'px' def removepercentwidth(self): "Remove percent width if present, to set it at the figure level." if not self.width: return None if not '%' in self.width: return None width = self.width self.width = None if self.height == 'auto': self.height = None return width def addstyle(self, container): "Add the proper style attribute to the output tag." if not isinstance(container.output, TaggedOutput): Trace.error('No tag to add style, in ' + unicode(container)) if not self.width and not self.height and not self.maxwidth and not self.maxheight: # nothing to see here; move along return tag = ' style="' tag += self.styleparameter('width') tag += self.styleparameter('maxwidth') tag += self.styleparameter('height') tag += self.styleparameter('maxheight') if tag[-1] == ' ': tag = tag[:-1] tag += '"' container.output.tag += tag def styleparameter(self, name): "Get the style for a single parameter." value = getattr(self, name) if value: return name.replace('max', 'max-') + ': ' + value + '; ' return '' class QuoteContainer(Container): "A container for a pretty quote" def __init__(self): self.parser = BoundedParser() self.output = FixedOutput() def process(self): "Process contents" self.type = self.header[2] if not self.type in StyleConfig.quotes: Trace.error('Quote type ' + self.type + ' not found') self.html = ['"'] return self.html = [StyleConfig.quotes[self.type]] class LyXLine(Container): "A Lyx line" def __init__(self): self.parser = LoneCommand() self.output = FixedOutput() def process(self): self.html = ['
'] class EmphaticText(TaggedText): "Text with emphatic mode" def process(self): self.output.tag = 'i' class ShapedText(TaggedText): "Text shaped (italic, slanted)" def process(self): self.type = self.header[1] if not self.type in TagConfig.shaped: Trace.error('Unrecognized shape ' + self.header[1]) self.output.tag = 'span' return self.output.tag = TagConfig.shaped[self.type] class VersalitasText(TaggedText): "Text in versalitas" def process(self): self.output.tag = 'span class="versalitas"' class ColorText(TaggedText): "Colored text" def process(self): self.color = self.header[1] self.output.tag = 'span class="' + self.color + '"' class SizeText(TaggedText): "Sized text" def process(self): self.size = self.header[1] self.output.tag = 'span class="' + self.size + '"' class BoldText(TaggedText): "Bold text" def process(self): self.output.tag = 'b' class TextFamily(TaggedText): "A bit of text from elyxer.a different family" def process(self): "Parse the type of family" self.type = self.header[1] if not self.type in TagConfig.family: Trace.error('Unrecognized family ' + type) self.output.tag = 'span' return self.output.tag = TagConfig.family[self.type] class Hfill(TaggedText): "Horizontall fill" def process(self): self.output.tag = 'span class="hfill"' class BarredText(TaggedText): "Text with a bar somewhere" def process(self): "Parse the type of bar" self.type = self.header[1] if not self.type in TagConfig.barred: Trace.error('Unknown bar type ' + self.type) self.output.tag = 'span' return self.output.tag = TagConfig.barred[self.type] class LangLine(TaggedText): "A line with language information" def process(self): "Only generate a span with lang info when the language is recognized." lang = self.header[1] if not lang in TranslationConfig.languages: self.output = ContentsOutput() return isolang = TranslationConfig.languages[lang] self.output = TaggedOutput().settag('span lang="' + isolang + '"', False) class InsetLength(BlackBox): "A length measure inside an inset." def process(self): self.length = self.header[1] class Space(Container): "A space of several types" def __init__(self): self.parser = InsetParser() self.output = FixedOutput() def process(self): self.type = self.header[2] if self.type not in StyleConfig.hspaces: Trace.error('Unknown space type ' + self.type) self.html = [' '] return self.html = [StyleConfig.hspaces[self.type]] length = self.getlength() if not length: return self.output = TaggedOutput().settag('span class="hspace"', False) ContainerSize().set(length).addstyle(self) def getlength(self): "Get the space length from elyxer.the contents or parameters." if len(self.contents) == 0 or not isinstance(self.contents[0], InsetLength): return None return self.contents[0].length class VerticalSpace(Container): "An inset that contains a vertical space." def __init__(self): self.parser = InsetParser() self.output = FixedOutput() def process(self): "Set the correct tag" self.type = self.header[2] if self.type not in StyleConfig.vspaces: self.output = TaggedOutput().settag('div class="vspace" style="height: ' + self.type + ';"', True) return self.html = [StyleConfig.vspaces[self.type]] class Align(Container): "Bit of aligned text" def __init__(self): self.parser = ExcludingParser() self.output = TaggedOutput().setbreaklines(True) def process(self): self.output.tag = 'div class="' + self.header[1] + '"' class Newline(Container): "A newline" def __init__(self): self.parser = LoneCommand() self.output = FixedOutput() def process(self): "Process contents" self.html = ['
\n'] class NewPage(Newline): "A new page" def process(self): "Process contents" self.html = ['


\n

\n'] class Separator(Container): "A separator string which is not extracted by extracttext()." def __init__(self, constant): self.output = FixedOutput() self.contents = [] self.html = [constant] class StrikeOut(TaggedText): "Striken out text." def process(self): "Set the output tag to strike." self.output.tag = 'strike' class StartAppendix(BlackBox): "Mark to start an appendix here." "From this point on, all chapters become appendices." def process(self): "Activate the special numbering scheme for appendices, using letters." NumberGenerator.generator.startappendix() class Link(Container): "A link to another part of the document" anchor = None url = None type = None page = None target = None destination = None title = None def __init__(self): "Initialize the link, add target if configured." self.contents = [] self.parser = InsetParser() self.output = LinkOutput() if Options.target: self.target = Options.target def complete(self, text, anchor = None, url = None, type = None, title = None): "Complete the link." self.contents = [Constant(text)] if anchor: self.anchor = anchor if url: self.url = url if type: self.type = type if title: self.title = title return self def computedestination(self): "Use the destination link to fill in the destination URL." if not self.destination: return self.url = '' if self.destination.anchor: self.url = '#' + self.destination.anchor if self.destination.page: self.url = self.destination.page + self.url def setmutualdestination(self, destination): "Set another link as destination, and set its destination to this one." self.destination = destination destination.destination = self def __unicode__(self): "Return a printable representation." result = 'Link' if self.anchor: result += ' #' + self.anchor if self.url: result += ' to ' + self.url return result class URL(Link): "A clickable URL" def process(self): "Read URL from elyxer.parameters" target = self.escape(self.getparameter('target')) self.url = target type = self.getparameter('type') if type: self.url = self.escape(type) + target name = self.getparameter('name') if not name: name = target self.contents = [Constant(name)] class FlexURL(URL): "A flexible URL" def process(self): "Read URL from elyxer.contents" self.url = self.extracttext() class LinkOutput(ContainerOutput): "A link pointing to some destination" "Or an anchor (destination)" def gethtml(self, link): "Get the HTML code for the link" type = link.__class__.__name__ if link.type: type = link.type tag = 'a class="' + type + '"' if link.anchor: tag += ' name="' + link.anchor + '"' if link.destination: link.computedestination() if link.url: tag += ' href="' + link.url + '"' if link.target: tag += ' target="' + link.target + '"' if link.title: tag += ' title="' + link.title + '"' return TaggedOutput().settag(tag).gethtml(link) class Postprocessor(object): "Postprocess a container keeping some context" stages = [] def __init__(self): self.stages = StageDict(Postprocessor.stages, self) self.current = None self.last = None def postprocess(self, next): "Postprocess a container and its contents." self.postrecursive(self.current) result = self.postcurrent(next) self.last = self.current self.current = next return result def postrecursive(self, container): "Postprocess the container contents recursively" if not hasattr(container, 'contents'): return if len(container.contents) == 0: return if hasattr(container, 'postprocess'): if not container.postprocess: return postprocessor = Postprocessor() contents = [] for element in container.contents: post = postprocessor.postprocess(element) if post: contents.append(post) # two rounds to empty the pipeline for i in range(2): post = postprocessor.postprocess(None) if post: contents.append(post) container.contents = contents def postcurrent(self, next): "Postprocess the current element taking into account next and last." stage = self.stages.getstage(self.current) if not stage: return self.current return stage.postprocess(self.last, self.current, next) class StageDict(object): "A dictionary of stages corresponding to classes" def __init__(self, classes, postprocessor): "Instantiate an element from elyxer.each class and store as a dictionary" instances = self.instantiate(classes, postprocessor) self.stagedict = dict([(x.processedclass, x) for x in instances]) def instantiate(self, classes, postprocessor): "Instantiate an element from elyxer.each class" stages = [x.__new__(x) for x in classes] for element in stages: element.__init__() element.postprocessor = postprocessor return stages def getstage(self, element): "Get the stage for a given element, if the type is in the dict" if not element.__class__ in self.stagedict: return None return self.stagedict[element.__class__] class Label(Link): "A label to be referenced" names = dict() lastlayout = None def __init__(self): Link.__init__(self) self.lastnumbered = None def process(self): "Process a label container." key = self.getparameter('name') self.create(' ', key) self.lastnumbered = Label.lastlayout def create(self, text, key, type = 'Label'): "Create the label for a given key." self.key = key self.complete(text, anchor = key, type = type) Label.names[key] = self if key in Reference.references: for reference in Reference.references[key]: reference.destination = self return self def findpartkey(self): "Get the part key for the latest numbered container seen." numbered = self.numbered(self) if numbered and numbered.partkey: return numbered.partkey return '' def numbered(self, container): "Get the numbered container for the label." if container.partkey: return container if not container.parent: if self.lastnumbered: return self.lastnumbered return None return self.numbered(container.parent) def __unicode__(self): "Return a printable representation." if not hasattr(self, 'key'): return 'Unnamed label' return 'Label ' + self.key class Reference(Link): "A reference to a label." references = dict() key = 'none' def process(self): "Read the reference and set the arrow." self.key = self.getparameter('reference') if self.key in Label.names: self.direction = u'↑' label = Label.names[self.key] else: self.direction = u'↓' label = Label().complete(' ', self.key, 'preref') self.destination = label self.formatcontents() if not self.key in Reference.references: Reference.references[self.key] = [] Reference.references[self.key].append(self) def formatcontents(self): "Format the reference contents." formatkey = self.getparameter('LatexCommand') if not formatkey: formatkey = 'ref' self.formatted = u'↕' if formatkey in StyleConfig.referenceformats: self.formatted = StyleConfig.referenceformats[formatkey] else: Trace.error('Unknown reference format ' + formatkey) self.replace(u'↕', self.direction) self.replace('#', '1') self.replace('on-page', Translator.translate('on-page')) partkey = self.destination.findpartkey() # only if partkey and partkey.number are not null, send partkey.number self.replace('@', partkey and partkey.number) self.replace(u'¶', partkey and partkey.tocentry) if not '$' in self.formatted or not partkey or not partkey.titlecontents: # there is a $ left, but it should go away on preprocessing self.contents = [Constant(self.formatted)] return pieces = self.formatted.split('$') self.contents = [Constant(pieces[0])] for piece in pieces[1:]: self.contents += partkey.titlecontents self.contents.append(Constant(piece)) def replace(self, key, value): "Replace a key in the format template with a value." if not key in self.formatted: return if not value: value = '' self.formatted = self.formatted.replace(key, value) def __unicode__(self): "Return a printable representation." return 'Reference ' + self.key class FormulaCommand(FormulaBit): "A LaTeX command inside a formula" types = [] start = FormulaConfig.starts['command'] commandmap = None def detect(self, pos): "Find the current command." return pos.checkfor(FormulaCommand.start) def parsebit(self, pos): "Parse the command." command = self.extractcommand(pos) bit = self.parsewithcommand(command, pos) if bit: return bit if command.startswith('\\up') or command.startswith('\\Up'): upgreek = self.parseupgreek(command, pos) if upgreek: return upgreek if not self.factory.defining: Trace.error('Unknown command ' + command) self.output = TaggedOutput().settag('span class="unknown"') self.add(FormulaConstant(command)) return None def parsewithcommand(self, command, pos): "Parse the command type once we have the command." for type in FormulaCommand.types: if command in type.commandmap: return self.parsecommandtype(command, type, pos) return None def parsecommandtype(self, command, type, pos): "Parse a given command type." bit = self.factory.create(type) bit.setcommand(command) returned = bit.parsebit(pos) if returned: return returned return bit def extractcommand(self, pos): "Extract the command from elyxer.the current position." if not pos.checkskip(FormulaCommand.start): pos.error('Missing command start ' + FormulaCommand.start) return if pos.finished(): return self.emptycommand(pos) if pos.current().isalpha(): # alpha command command = FormulaCommand.start + pos.globalpha() # skip mark of short command pos.checkskip('*') return command # symbol command return FormulaCommand.start + pos.skipcurrent() def emptycommand(self, pos): """Check for an empty command: look for command disguised as ending. Special case against '{ \{ \} }' situation.""" command = '' if not pos.isout(): ending = pos.nextending() if ending and pos.checkskip(ending): command = ending return FormulaCommand.start + command def parseupgreek(self, command, pos): "Parse the Greek \\up command.." if len(command) < 4: return None if command.startswith('\\up'): upcommand = '\\' + command[3:] elif pos.checkskip('\\Up'): upcommand = '\\' + command[3:4].upper() + command[4:] else: Trace.error('Impossible upgreek command: ' + command) return upgreek = self.parsewithcommand(upcommand, pos) if upgreek: upgreek.type = 'font' return upgreek class CommandBit(FormulaCommand): "A formula bit that includes a command" def setcommand(self, command): "Set the command in the bit" self.command = command if self.commandmap: self.original += command self.translated = self.commandmap[self.command] def parseparameter(self, pos): "Parse a parameter at the current position" self.factory.clearskipped(pos) if pos.finished(): return None parameter = self.factory.parseany(pos) self.add(parameter) return parameter def parsesquare(self, pos): "Parse a square bracket" self.factory.clearskipped(pos) if not self.factory.detecttype(SquareBracket, pos): return None bracket = self.factory.parsetype(SquareBracket, pos) self.add(bracket) return bracket def parseliteral(self, pos): "Parse a literal bracket." self.factory.clearskipped(pos) if not self.factory.detecttype(Bracket, pos): if not pos.isvalue(): Trace.error('No literal parameter found at: ' + pos.identifier()) return None return pos.globvalue() bracket = Bracket().setfactory(self.factory) self.add(bracket.parseliteral(pos)) return bracket.literal def parsesquareliteral(self, pos): "Parse a square bracket literally." self.factory.clearskipped(pos) if not self.factory.detecttype(SquareBracket, pos): return None bracket = SquareBracket().setfactory(self.factory) self.add(bracket.parseliteral(pos)) return bracket.literal def parsetext(self, pos): "Parse a text parameter." self.factory.clearskipped(pos) if not self.factory.detecttype(Bracket, pos): Trace.error('No text parameter for ' + self.command) return None bracket = Bracket().setfactory(self.factory).parsetext(pos) self.add(bracket) return bracket class EmptyCommand(CommandBit): "An empty command (without parameters)" commandmap = FormulaConfig.commands def parsebit(self, pos): "Parse a command without parameters" self.contents = [FormulaConstant(self.translated)] class SpacedCommand(CommandBit): "An empty command which should have math spacing in formulas." commandmap = FormulaConfig.spacedcommands def parsebit(self, pos): "Place as contents the command translated and spaced." self.contents = [FormulaConstant(u' ' + self.translated + u' ')] class AlphaCommand(EmptyCommand): "A command without paramters whose result is alphabetical" commandmap = FormulaConfig.alphacommands def parsebit(self, pos): "Parse the command and set type to alpha" EmptyCommand.parsebit(self, pos) self.type = 'alpha' class OneParamFunction(CommandBit): "A function of one parameter" commandmap = FormulaConfig.onefunctions simplified = False def parsebit(self, pos): "Parse a function with one parameter" self.output = TaggedOutput().settag(self.translated) self.parseparameter(pos) self.simplifyifpossible() def simplifyifpossible(self): "Try to simplify to a single character." if self.original in self.commandmap: self.output = FixedOutput() self.html = [self.commandmap[self.original]] self.simplified = True class SymbolFunction(CommandBit): "Find a function which is represented by a symbol (like _ or ^)" commandmap = FormulaConfig.symbolfunctions def detect(self, pos): "Find the symbol" return pos.current() in SymbolFunction.commandmap def parsebit(self, pos): "Parse the symbol" self.setcommand(pos.current()) pos.skip(self.command) self.output = TaggedOutput().settag(self.translated) self.parseparameter(pos) class TextFunction(CommandBit): "A function where parameters are read as text." commandmap = FormulaConfig.textfunctions def parsebit(self, pos): "Parse a text parameter" self.output = TaggedOutput().settag(self.translated) self.parsetext(pos) def process(self): "Set the type to font" self.type = 'font' class LabelFunction(CommandBit): "A function that acts as a label" commandmap = FormulaConfig.labelfunctions def parsebit(self, pos): "Parse a literal parameter" self.key = self.parseliteral(pos) def process(self): "Add an anchor with the label contents." self.type = 'font' self.label = Label().create(' ', self.key, type = 'eqnumber') self.contents = [self.label] # store as a Label so we know it's been seen Label.names[self.key] = self.label class FontFunction(OneParamFunction): "A function of one parameter that changes the font" commandmap = FormulaConfig.fontfunctions def process(self): "Simplify if possible using a single character." self.type = 'font' self.simplifyifpossible() FormulaFactory.types += [FormulaCommand, SymbolFunction] FormulaCommand.types = [ AlphaCommand, EmptyCommand, OneParamFunction, FontFunction, LabelFunction, TextFunction, SpacedCommand, ] class BigSymbol(object): "A big symbol generator." symbols = FormulaConfig.bigsymbols def __init__(self, symbol): "Create the big symbol." self.symbol = symbol def getpieces(self): "Get an array with all pieces." if not self.symbol in self.symbols: return [self.symbol] if self.smalllimit(): return [self.symbol] return self.symbols[self.symbol] def smalllimit(self): "Decide if the limit should be a small, one-line symbol." if not DocumentParameters.displaymode: return True if len(self.symbols[self.symbol]) == 1: return True return Options.simplemath class BigBracket(BigSymbol): "A big bracket generator." def __init__(self, size, bracket, alignment='l'): "Set the size and symbol for the bracket." self.size = size self.original = bracket self.alignment = alignment self.pieces = None if bracket in FormulaConfig.bigbrackets: self.pieces = FormulaConfig.bigbrackets[bracket] def getpiece(self, index): "Return the nth piece for the bracket." function = getattr(self, 'getpiece' + unicode(len(self.pieces))) return function(index) def getpiece1(self, index): "Return the only piece for a single-piece bracket." return self.pieces[0] def getpiece3(self, index): "Get the nth piece for a 3-piece bracket: parenthesis or square bracket." if index == 0: return self.pieces[0] if index == self.size - 1: return self.pieces[-1] return self.pieces[1] def getpiece4(self, index): "Get the nth piece for a 4-piece bracket: curly bracket." if index == 0: return self.pieces[0] if index == self.size - 1: return self.pieces[3] if index == (self.size - 1)/2: return self.pieces[2] return self.pieces[1] def getcell(self, index): "Get the bracket piece as an array cell." piece = self.getpiece(index) span = 'span class="bracket align-' + self.alignment + '"' return TaggedBit().constant(piece, span) def getcontents(self): "Get the bracket as an array or as a single bracket." if self.size == 1 or not self.pieces: return self.getsinglebracket() rows = [] for index in range(self.size): cell = self.getcell(index) rows.append(TaggedBit().complete([cell], 'span class="arrayrow"')) return [TaggedBit().complete(rows, 'span class="array"')] def getsinglebracket(self): "Return the bracket as a single sign." if self.original == '.': return [TaggedBit().constant('', 'span class="emptydot"')] return [TaggedBit().constant(self.original, 'span class="symbol"')] class FormulaEquation(CommandBit): "A simple numbered equation." piece = 'equation' def parsebit(self, pos): "Parse the array" self.output = ContentsOutput() self.add(self.factory.parsetype(WholeFormula, pos)) class FormulaCell(FormulaCommand): "An array cell inside a row" def setalignment(self, alignment): self.alignment = alignment self.output = TaggedOutput().settag('span class="arraycell align-' + alignment +'"', True) return self def parsebit(self, pos): self.factory.clearskipped(pos) if pos.finished(): return self.add(self.factory.parsetype(WholeFormula, pos)) class FormulaRow(FormulaCommand): "An array row inside an array" cellseparator = FormulaConfig.array['cellseparator'] def setalignments(self, alignments): self.alignments = alignments self.output = TaggedOutput().settag('span class="arrayrow"', True) return self def parsebit(self, pos): "Parse a whole row" index = 0 pos.pushending(self.cellseparator, optional=True) while not pos.finished(): cell = self.createcell(index) cell.parsebit(pos) self.add(cell) index += 1 pos.checkskip(self.cellseparator) if len(self.contents) == 0: self.output = EmptyOutput() def createcell(self, index): "Create the cell that corresponds to the given index." alignment = self.alignments[index % len(self.alignments)] return self.factory.create(FormulaCell).setalignment(alignment) class MultiRowFormula(CommandBit): "A formula with multiple rows." def parserows(self, pos): "Parse all rows, finish when no more row ends" self.rows = [] first = True for row in self.iteraterows(pos): if first: first = False else: # intersparse empty rows self.addempty() row.parsebit(pos) self.addrow(row) self.size = len(self.rows) def iteraterows(self, pos): "Iterate over all rows, end when no more row ends" rowseparator = FormulaConfig.array['rowseparator'] while True: pos.pushending(rowseparator, True) row = self.factory.create(FormulaRow) yield row.setalignments(self.alignments) if pos.checkfor(rowseparator): self.original += pos.popending(rowseparator) else: return def addempty(self): "Add an empty row." row = self.factory.create(FormulaRow).setalignments(self.alignments) for index, originalcell in enumerate(self.rows[-1].contents): cell = row.createcell(index) cell.add(FormulaConstant(u' ')) row.add(cell) self.addrow(row) def addrow(self, row): "Add a row to the contents and to the list of rows." self.rows.append(row) self.add(row) class FormulaArray(MultiRowFormula): "An array within a formula" piece = 'array' def parsebit(self, pos): "Parse the array" self.output = TaggedOutput().settag('span class="array"', False) self.parsealignments(pos) self.parserows(pos) def parsealignments(self, pos): "Parse the different alignments" # vertical self.valign = 'c' literal = self.parsesquareliteral(pos) if literal: self.valign = literal # horizontal literal = self.parseliteral(pos) self.alignments = [] for l in literal: self.alignments.append(l) class FormulaMatrix(MultiRowFormula): "A matrix (array with center alignment)." piece = 'matrix' def parsebit(self, pos): "Parse the matrix, set alignments to 'c'." self.output = TaggedOutput().settag('span class="array"', False) self.valign = 'c' self.alignments = ['c'] self.parserows(pos) class FormulaCases(MultiRowFormula): "A cases statement" piece = 'cases' def parsebit(self, pos): "Parse the cases" self.output = ContentsOutput() self.alignments = ['l', 'l'] self.parserows(pos) for row in self.contents: for cell in row.contents: cell.output.settag('span class="case align-l"', True) cell.contents.append(FormulaConstant(u' ')) array = TaggedBit().complete(self.contents, 'span class="bracketcases"', True) brace = BigBracket(len(self.contents), '{', 'l') self.contents = brace.getcontents() + [array] class EquationEnvironment(MultiRowFormula): "A \\begin{}...\\end equation environment with rows and cells." def parsebit(self, pos): "Parse the whole environment." self.output = TaggedOutput().settag('span class="environment"', False) environment = self.piece.replace('*', '') if environment in FormulaConfig.environments: self.alignments = FormulaConfig.environments[environment] else: Trace.error('Unknown equation environment ' + self.piece) self.alignments = ['l'] self.parserows(pos) class BeginCommand(CommandBit): "A \\begin{}...\end command and what it entails (array, cases, aligned)" commandmap = {FormulaConfig.array['begin']:''} types = [FormulaEquation, FormulaArray, FormulaCases, FormulaMatrix] def parsebit(self, pos): "Parse the begin command" command = self.parseliteral(pos) bit = self.findbit(command) ending = FormulaConfig.array['end'] + '{' + command + '}' pos.pushending(ending) bit.parsebit(pos) self.add(bit) self.original += pos.popending(ending) self.size = bit.size def findbit(self, piece): "Find the command bit corresponding to the \\begin{piece}" for type in BeginCommand.types: if piece.replace('*', '') == type.piece: return self.factory.create(type) bit = self.factory.create(EquationEnvironment) bit.piece = piece return bit FormulaCommand.types += [BeginCommand] import datetime class CombiningFunction(OneParamFunction): commandmap = FormulaConfig.combiningfunctions def parsebit(self, pos): "Parse a combining function." self.type = 'alpha' combining = self.translated parameter = self.parsesingleparameter(pos) if not parameter: Trace.error('Empty parameter for combining function ' + self.command) elif len(parameter.extracttext()) != 1: Trace.error('Applying combining function ' + self.command + ' to invalid string "' + parameter.extracttext() + '"') self.contents.append(Constant(combining)) def parsesingleparameter(self, pos): "Parse a parameter, or a single letter." self.factory.clearskipped(pos) if pos.finished(): Trace.error('Error while parsing single parameter at ' + pos.identifier()) return None if self.factory.detecttype(Bracket, pos) \ or self.factory.detecttype(FormulaCommand, pos): return self.parseparameter(pos) letter = FormulaConstant(pos.skipcurrent()) self.add(letter) return letter class DecoratingFunction(OneParamFunction): "A function that decorates some bit of text" commandmap = FormulaConfig.decoratingfunctions def parsebit(self, pos): "Parse a decorating function" self.type = 'alpha' symbol = self.translated self.symbol = TaggedBit().constant(symbol, 'span class="symbolover"') self.parameter = self.parseparameter(pos) self.output = TaggedOutput().settag('span class="withsymbol"') self.contents.insert(0, self.symbol) self.parameter.output = TaggedOutput().settag('span class="undersymbol"') self.simplifyifpossible() class LimitCommand(EmptyCommand): "A command which accepts limits above and below, in display mode." commandmap = FormulaConfig.limitcommands def parsebit(self, pos): "Parse a limit command." pieces = BigSymbol(self.translated).getpieces() self.output = TaggedOutput().settag('span class="limits"') for piece in pieces: self.contents.append(TaggedBit().constant(piece, 'span class="limit"')) class LimitPreviousCommand(LimitCommand): "A command to limit the previous command." commandmap = None def parsebit(self, pos): "Do nothing." self.output = TaggedOutput().settag('span class="limits"') self.factory.clearskipped(pos) def __unicode__(self): "Return a printable representation." return 'Limit previous command' class LimitsProcessor(MathsProcessor): "A processor for limits inside an element." def process(self, contents, index): "Process the limits for an element." if Options.simplemath: return if self.checklimits(contents, index): self.modifylimits(contents, index) if self.checkscript(contents, index) and self.checkscript(contents, index + 1): self.modifyscripts(contents, index) def checklimits(self, contents, index): "Check if the current position has a limits command." if not DocumentParameters.displaymode: return False if self.checkcommand(contents, index + 1, LimitPreviousCommand): self.limitsahead(contents, index) return False if not isinstance(contents[index], LimitCommand): return False return self.checkscript(contents, index + 1) def limitsahead(self, contents, index): "Limit the current element based on the next." contents[index + 1].add(contents[index].clone()) contents[index].output = EmptyOutput() def modifylimits(self, contents, index): "Modify a limits commands so that the limits appear above and below." limited = contents[index] subscript = self.getlimit(contents, index + 1) limited.contents.append(subscript) if self.checkscript(contents, index + 1): superscript = self.getlimit(contents, index + 1) else: superscript = TaggedBit().constant(u' ', 'sup class="limit"') limited.contents.insert(0, superscript) def getlimit(self, contents, index): "Get the limit for a limits command." limit = self.getscript(contents, index) limit.output.tag = limit.output.tag.replace('script', 'limit') return limit def modifyscripts(self, contents, index): "Modify the super- and subscript to appear vertically aligned." subscript = self.getscript(contents, index) # subscript removed so instead of index + 1 we get index again superscript = self.getscript(contents, index) scripts = TaggedBit().complete([superscript, subscript], 'span class="scripts"') contents.insert(index, scripts) def checkscript(self, contents, index): "Check if the current element is a sub- or superscript." return self.checkcommand(contents, index, SymbolFunction) def checkcommand(self, contents, index, type): "Check for the given type as the current element." if len(contents) <= index: return False return isinstance(contents[index], type) def getscript(self, contents, index): "Get the sub- or superscript." bit = contents[index] bit.output.tag += ' class="script"' del contents[index] return bit class BracketCommand(OneParamFunction): "A command which defines a bracket." commandmap = FormulaConfig.bracketcommands def parsebit(self, pos): "Parse the bracket." OneParamFunction.parsebit(self, pos) def create(self, direction, character): "Create the bracket for the given character." self.original = character self.command = '\\' + direction self.contents = [FormulaConstant(character)] return self class BracketProcessor(MathsProcessor): "A processor for bracket commands." def process(self, contents, index): "Convert the bracket using Unicode pieces, if possible." if Options.simplemath: return if self.checkleft(contents, index): return self.processleft(contents, index) def processleft(self, contents, index): "Process a left bracket." rightindex = self.findright(contents, index + 1) if not rightindex: return size = self.findmax(contents, index, rightindex) self.resize(contents[index], size) self.resize(contents[rightindex], size) def checkleft(self, contents, index): "Check if the command at the given index is left." return self.checkdirection(contents[index], '\\left') def checkright(self, contents, index): "Check if the command at the given index is right." return self.checkdirection(contents[index], '\\right') def checkdirection(self, bit, command): "Check if the given bit is the desired bracket command." if not isinstance(bit, BracketCommand): return False return bit.command == command def findright(self, contents, index): "Find the right bracket starting at the given index, or 0." depth = 1 while index < len(contents): if self.checkleft(contents, index): depth += 1 if self.checkright(contents, index): depth -= 1 if depth == 0: return index index += 1 return None def findmax(self, contents, leftindex, rightindex): "Find the max size of the contents between the two given indices." sliced = contents[leftindex:rightindex] return max([element.size for element in sliced]) def resize(self, command, size): "Resize a bracket command to the given size." character = command.extracttext() alignment = command.command.replace('\\', '') bracket = BigBracket(size, character, alignment) command.output = ContentsOutput() command.contents = bracket.getcontents() class TodayCommand(EmptyCommand): "Shows today's date." commandmap = None def parsebit(self, pos): "Parse a command without parameters" self.output = FixedOutput() self.html = [datetime.date.today().strftime('%b %d, %Y')] FormulaCommand.types += [ DecoratingFunction, CombiningFunction, LimitCommand, BracketCommand, ] FormulaProcessor.processors += [ LimitsProcessor(), BracketProcessor(), ] class ParameterDefinition(object): "The definition of a parameter in a hybrid function." "[] parameters are optional, {} parameters are mandatory." "Each parameter has a one-character name, like {$1} or {$p}." "A parameter that ends in ! like {$p!} is a literal." "Example: [$1]{$p!} reads an optional parameter $1 and a literal mandatory parameter p." parambrackets = [('[', ']'), ('{', '}')] def __init__(self): self.name = None self.literal = False self.optional = False self.value = None self.literalvalue = None def parse(self, pos): "Parse a parameter definition: [$0], {$x}, {$1!}..." for (opening, closing) in ParameterDefinition.parambrackets: if pos.checkskip(opening): if opening == '[': self.optional = True if not pos.checkskip('$'): Trace.error('Wrong parameter name, did you mean $' + pos.current() + '?') return None self.name = pos.skipcurrent() if pos.checkskip('!'): self.literal = True if not pos.checkskip(closing): Trace.error('Wrong parameter closing ' + pos.skipcurrent()) return None return self Trace.error('Wrong character in parameter template: ' + pos.skipcurrent()) return None def read(self, pos, function): "Read the parameter itself using the definition." if self.literal: if self.optional: self.literalvalue = function.parsesquareliteral(pos) else: self.literalvalue = function.parseliteral(pos) if self.literalvalue: self.value = FormulaConstant(self.literalvalue) elif self.optional: self.value = function.parsesquare(pos) else: self.value = function.parseparameter(pos) def __unicode__(self): "Return a printable representation." result = 'param ' + self.name if self.value: result += ': ' + unicode(self.value) else: result += ' (empty)' return result class ParameterFunction(CommandBit): "A function with a variable number of parameters defined in a template." "The parameters are defined as a parameter definition." def readparams(self, readtemplate, pos): "Read the params according to the template." self.params = dict() for paramdef in self.paramdefs(readtemplate): paramdef.read(pos, self) self.params['$' + paramdef.name] = paramdef def paramdefs(self, readtemplate): "Read each param definition in the template" pos = TextPosition(readtemplate) while not pos.finished(): paramdef = ParameterDefinition().parse(pos) if paramdef: yield paramdef def getparam(self, name): "Get a parameter as parsed." if not name in self.params: return None return self.params[name] def getvalue(self, name): "Get the value of a parameter." return self.getparam(name).value def getliteralvalue(self, name): "Get the literal value of a parameter." param = self.getparam(name) if not param or not param.literalvalue: return None return param.literalvalue class HybridFunction(ParameterFunction): """ A parameter function where the output is also defined using a template. The template can use a number of functions; each function has an associated tag. Example: [f0{$1},span class="fbox"] defines a function f0 which corresponds to a span of class fbox, yielding $1. Literal parameters can be used in tags definitions: [f0{$1},span style="color: $p;"] yields $1, where $p is a literal parameter. Sizes can be specified in hybridsizes, e.g. adding parameter sizes. By default the resulting size is the max of all arguments. Sizes are used to generate the right parameters. A function followed by a single / is output as a self-closing XHTML tag: [f0/,hr] will generate
. """ commandmap = FormulaConfig.hybridfunctions def parsebit(self, pos): "Parse a function with [] and {} parameters" readtemplate = self.translated[0] writetemplate = self.translated[1] self.readparams(readtemplate, pos) self.contents = self.writeparams(writetemplate) self.computehybridsize() def writeparams(self, writetemplate): "Write all params according to the template" return self.writepos(TextPosition(writetemplate)) def writepos(self, pos): "Write all params as read in the parse position." result = [] while not pos.finished(): if pos.checkskip('$'): param = self.writeparam(pos) if param: result.append(param) elif pos.checkskip('f'): function = self.writefunction(pos) if function: function.type = None result.append(function) elif pos.checkskip('('): result.append(self.writebracket('left', '(')) elif pos.checkskip(')'): result.append(self.writebracket('right', ')')) else: result.append(FormulaConstant(pos.skipcurrent())) return result def writeparam(self, pos): "Write a single param of the form $0, $x..." name = '$' + pos.skipcurrent() if not name in self.params: Trace.error('Unknown parameter ' + name) return None if not self.params[name]: return None if pos.checkskip('.'): self.params[name].value.type = pos.globalpha() return self.params[name].value def writefunction(self, pos): "Write a single function f0,...,fn." tag = self.readtag(pos) if not tag: return None if pos.checkskip('/'): # self-closing XHTML tag, such as
return TaggedBit().selfcomplete(tag) if not pos.checkskip('{'): Trace.error('Function should be defined in {}') return None pos.pushending('}') contents = self.writepos(pos) pos.popending() if len(contents) == 0: return None return TaggedBit().complete(contents, tag) def readtag(self, pos): "Get the tag corresponding to the given index. Does parameter substitution." if not pos.current().isdigit(): Trace.error('Function should be f0,...,f9: f' + pos.current()) return None index = int(pos.skipcurrent()) if 2 + index > len(self.translated): Trace.error('Function f' + unicode(index) + ' is not defined') return None tag = self.translated[2 + index] if not '$' in tag: return tag for variable in self.params: if variable in tag: param = self.params[variable] if not param.literal: Trace.error('Parameters in tag ' + tag + ' should be literal: {' + variable + '!}') continue if param.literalvalue: value = param.literalvalue else: value = '' tag = tag.replace(variable, value) return tag def writebracket(self, direction, character): "Return a new bracket looking at the given direction." return self.factory.create(BracketCommand).create(direction, character) def computehybridsize(self): "Compute the size of the hybrid function." if not self.command in HybridSize.configsizes: self.computesize() return self.size = HybridSize().getsize(self) # set the size in all elements at first level for element in self.contents: element.size = self.size class HybridSize(object): "The size associated with a hybrid function." configsizes = FormulaConfig.hybridsizes def getsize(self, function): "Read the size for a function and parse it." sizestring = self.configsizes[function.command] for name in function.params: if name in sizestring: size = function.params[name].value.computesize() sizestring = sizestring.replace(name, unicode(size)) if '$' in sizestring: Trace.error('Unconverted variable in hybrid size: ' + sizestring) return 1 return eval(sizestring) FormulaCommand.types += [HybridFunction] class HeaderParser(Parser): "Parses the LyX header" def parse(self, reader): "Parse header parameters into a dictionary, return the preamble." contents = [] self.parseending(reader, lambda: self.parseline(reader, contents)) # skip last line reader.nextline() return contents def parseline(self, reader, contents): "Parse a single line as a parameter or as a start" line = reader.currentline() if line.startswith(HeaderConfig.parameters['branch']): self.parsebranch(reader) return elif line.startswith(HeaderConfig.parameters['lstset']): LstParser().parselstset(reader) return elif line.startswith(HeaderConfig.parameters['beginpreamble']): contents.append(self.factory.createcontainer(reader)) return # no match self.parseparameter(reader) def parsebranch(self, reader): "Parse all branch definitions." branch = reader.currentline().split()[1] reader.nextline() subparser = HeaderParser().complete(HeaderConfig.parameters['endbranch']) subparser.parse(reader) options = BranchOptions(branch) for key in subparser.parameters: options.set(key, subparser.parameters[key]) Options.branches[branch] = options def complete(self, ending): "Complete the parser with the given ending." self.ending = ending return self class PreambleParser(Parser): "A parser for the LyX preamble." preamble = [] def parse(self, reader): "Parse the full preamble with all statements." self.ending = HeaderConfig.parameters['endpreamble'] self.parseending(reader, lambda: self.parsepreambleline(reader)) return [] def parsepreambleline(self, reader): "Parse a single preamble line." PreambleParser.preamble.append(reader.currentline()) reader.nextline() class LstParser(object): "Parse global and local lstparams." globalparams = dict() def parselstset(self, reader): "Parse a declaration of lstparams in lstset." paramtext = self.extractlstset(reader) if not '{' in paramtext: Trace.error('Missing opening bracket in lstset: ' + paramtext) return lefttext = paramtext.split('{')[1] croppedtext = lefttext[:-1] LstParser.globalparams = self.parselstparams(croppedtext) def extractlstset(self, reader): "Extract the global lstset parameters." paramtext = '' while not reader.finished(): paramtext += reader.currentline() reader.nextline() if paramtext.endswith('}'): return paramtext Trace.error('Could not find end of \\lstset settings; aborting') def parsecontainer(self, container): "Parse some lstparams from elyxer.a container." container.lstparams = LstParser.globalparams.copy() paramlist = container.getparameterlist('lstparams') container.lstparams.update(self.parselstparams(paramlist)) def parselstparams(self, paramlist): "Process a number of lstparams from elyxer.a list." paramdict = dict() for param in paramlist: if not '=' in param: if len(param.strip()) > 0: Trace.error('Invalid listing parameter ' + param) else: key, value = param.split('=', 1) paramdict[key] = value return paramdict class MacroDefinition(CommandBit): "A function that defines a new command (a macro)." macros = dict() def parsebit(self, pos): "Parse the function that defines the macro." self.output = EmptyOutput() self.parameternumber = 0 self.defaults = [] self.factory.defining = True self.parseparameters(pos) self.factory.defining = False Trace.debug('New command ' + self.newcommand + ' (' + \ unicode(self.parameternumber) + ' parameters)') self.macros[self.newcommand] = self def parseparameters(self, pos): "Parse all optional parameters (number of parameters, default values)" "and the mandatory definition." self.newcommand = self.parsenewcommand(pos) # parse number of parameters literal = self.parsesquareliteral(pos) if literal: self.parameternumber = int(literal) # parse all default values bracket = self.parsesquare(pos) while bracket: self.defaults.append(bracket) bracket = self.parsesquare(pos) # parse mandatory definition self.definition = self.parseparameter(pos) def parsenewcommand(self, pos): "Parse the name of the new command." self.factory.clearskipped(pos) if self.factory.detecttype(Bracket, pos): return self.parseliteral(pos) if self.factory.detecttype(FormulaCommand, pos): return self.factory.create(FormulaCommand).extractcommand(pos) Trace.error('Unknown formula bit in defining function at ' + pos.identifier()) return 'unknown' def instantiate(self): "Return an instance of the macro." return self.definition.clone() class MacroParameter(FormulaBit): "A parameter from elyxer.a macro." def detect(self, pos): "Find a macro parameter: #n." return pos.checkfor('#') def parsebit(self, pos): "Parse the parameter: #n." if not pos.checkskip('#'): Trace.error('Missing parameter start #.') return self.number = int(pos.skipcurrent()) self.original = '#' + unicode(self.number) self.contents = [TaggedBit().constant('#' + unicode(self.number), 'span class="unknown"')] class MacroFunction(CommandBit): "A function that was defined using a macro." commandmap = MacroDefinition.macros def parsebit(self, pos): "Parse a number of input parameters." self.output = FilteredOutput() self.values = [] macro = self.translated self.parseparameters(pos, macro) self.completemacro(macro) def parseparameters(self, pos, macro): "Parse as many parameters as are needed." self.parseoptional(pos, list(macro.defaults)) self.parsemandatory(pos, macro.parameternumber - len(macro.defaults)) if len(self.values) < macro.parameternumber: Trace.error('Missing parameters in macro ' + unicode(self)) def parseoptional(self, pos, defaults): "Parse optional parameters." optional = [] while self.factory.detecttype(SquareBracket, pos): optional.append(self.parsesquare(pos)) if len(optional) > len(defaults): break for value in optional: default = defaults.pop() if len(value.contents) > 0: self.values.append(value) else: self.values.append(default) self.values += defaults def parsemandatory(self, pos, number): "Parse a number of mandatory parameters." for index in range(number): parameter = self.parsemacroparameter(pos, number - index) if not parameter: return self.values.append(parameter) def parsemacroparameter(self, pos, remaining): "Parse a macro parameter. Could be a bracket or a single letter." "If there are just two values remaining and there is a running number," "parse as two separater numbers." self.factory.clearskipped(pos) if pos.finished(): return None if self.factory.detecttype(FormulaNumber, pos): return self.parsenumbers(pos, remaining) return self.parseparameter(pos) def parsenumbers(self, pos, remaining): "Parse the remaining parameters as a running number." "For example, 12 would be {1}{2}." number = self.factory.parsetype(FormulaNumber, pos) if not len(number.original) == remaining: return number for digit in number.original: value = self.factory.create(FormulaNumber) value.add(FormulaConstant(digit)) value.type = number self.values.append(value) return None def completemacro(self, macro): "Complete the macro with the parameters read." self.contents = [macro.instantiate()] replaced = [False] * len(self.values) for parameter in self.searchall(MacroParameter): index = parameter.number - 1 if index >= len(self.values): Trace.error('Macro parameter index out of bounds: ' + unicode(index)) return replaced[index] = True parameter.contents = [self.values[index].clone()] for index in range(len(self.values)): if not replaced[index]: self.addfilter(index, self.values[index]) def addfilter(self, index, value): "Add a filter for the given parameter number and parameter value." original = '#' + unicode(index + 1) value = ''.join(self.values[0].gethtml()) self.output.addfilter(original, value) class FormulaMacro(Formula): "A math macro defined in an inset." def __init__(self): self.parser = MacroParser() self.output = EmptyOutput() def __unicode__(self): "Return a printable representation." return 'Math macro' FormulaFactory.types += [ MacroParameter ] FormulaCommand.types += [ MacroFunction, ] def math2html(formula): "Convert some TeX math to HTML." factory = FormulaFactory() whole = factory.parseformula(formula) FormulaProcessor().process(whole) whole.process() return ''.join(whole.gethtml()) def main(): "Main function, called if invoked from elyxer.the command line" args = sys.argv Options().parseoptions(args) if len(args) != 1: Trace.error('Usage: math2html.py escaped_string') exit() result = math2html(args[0]) Trace.message(result) if __name__ == '__main__': main() elyxer-1.2.5/forks/jras-elyxer/src/0000755000175000017500000000000012117061342016512 5ustar chennochennoelyxer-1.2.5/forks/jras-elyxer/src/freebsd-license0000644000175000017500000000116412117061342021471 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # math2html: convert LaTeX equations to HTML output. # # Copyright (C) 2009-2011 Alex Fernández # # Released under the terms of the `2-Clause BSD license'_, in short: # Copying and distribution of this file, with or without modification, # are permitted in any medium without royalty provided the copyright # notice and this notice are preserved. # This file is offered as-is, without any warranty. # # .. _2-Clause BSD license: http://www.spdx.org/licenses/BSD-2-Clause # Based on eLyXer: convert LyX source files to HTML output. # http://elyxer.nongnu.org/ elyxer-1.2.5/forks/jras-elyxer/src/jtp/0000755000175000017500000000000012117061342017307 5ustar chennochennoelyxer-1.2.5/forks/jras-elyxer/src/jtp/exportconfig.sh0000755000175000017500000000020512117061342022352 0ustar chennochenno#!/bin/bash # Alex 2010-03-14: export configuration for JavaToPy ./exportconfig.py --cfg conf/jtp.cfg --py conf/javatopyconf.py py elyxer-1.2.5/forks/jras-elyxer/src/jtp/porter.py0000644000175000017500000002163212117061342021200 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20091226 # Port a Java program to a Python equivalent. Used to port MathToWeb. from elyxer.jtp.parser import * from elyxer.jtp.grammar import * from elyxer.util.trace import Trace class JavaPorter(object): "Ports a Java file." def __init__(self): Grammar.instance.process() self.chooser = StatementChooser() def topy(self, filepos, writer): "Port the Java input file to Python." tok = Tokenizer(filepos) Grammar.instance.parse(tok) return while not tok.finished(): statement = self.nextstatement(tok) writer.writeline(statement) writer.close() def nextstatement(self, tok): "Return the next statement." statement = None while not statement and not tok.finished(): indent = self.chooser.getindent(tok) statement = self.parsestatement(tok) if not statement: return '' Trace.debug('Statement: ' + statement.strip()) if statement.startswith('\n'): # displace newline return '\n' + indent + statement[1:] return indent + statement def parsestatement(self, tok): "Parse a single statement." pending = self.chooser.pendingstatement(tok) if pending: return pending return self.chooser.choose(tok) class StatementChooser(object): "Chooses the next statement to parse, according to the first token." starttokens = { 'if':'conditionblock', 'catch':'parametersblock', 'import':'ignorestatement', 'public':'classormember', 'protected':'classormember', 'private':'classormember', 'class':'parseclass', 'else':'elseblock', 'try':'tryblock', 'return':'returnstatement', '{':'openblock', '}':'closeblock', 'for':'forparens0', 'throw':'throwstatement', 'throws':'throwsdeclaration', ';':'ignorestatement', 'while':'conditionblock' } javatokens = { 'new':'createstatement', 'this':'thisstatement' } def __init__(self): self.parser = StatementParser(self) def getindent(self, tok): "Get the indent for the next statement." return ' ' * tok.depth def choose(self, tok): "Parse a single statement." token = tok.next() if not token: return None if token in self.starttokens: function = getattr(self, self.starttokens[token]) elif token in self.javatokens: function = getattr(self, self.javatokens[token]) else: function = self.assigninvoke return function(tok) def pendingstatement(self, tok): "Return any pending statement from elyxer.before." if tok.infor != 0: tok.next() function = getattr(self, 'forparens' + unicode(tok.infor)) return function(tok) if len(tok.autoincreases) != 0: return self.autoincrease(tok) if len(tok.autodecreases) != 0: return self.autodecrease(tok) return None def autoincrease(self, tok): "Process a Java autoincrease (++)." variable = tok.autoincreases.pop() return variable + ' += 1' def autodecrease(self, tok): "Process a Java autodecrease (--)." variable = tok.autodecreases.pop() return variable + ' -= 1' def classormember(self, tok): "Parse a class or member (attribute or method)." if tok.inclass: return self.parser.translateinternal(tok) else: return self.parser.translateclass(tok) def conditionblock(self, tok): "Parse a condition in () and then a block {} (if or while statements)." token = tok.current() tok.checknext('(') parens = self.parser.parsecondition(tok, ')') self.parser.expectblock(tok) return token + ' ' + parens + ':' def parametersblock(self, tok): "Parse a parameters () and then a block {} (catch statement)." tok.checknext('(') parens = self.parser.listparameters(tok) self.parser.expectblock(tok) return 'except:' def forparens0(self, tok): "Parse the first statement of a for loop." "The remaining parts of the for(;;){} are parsed later." tok.checknext('(') first = self.assigninvoke(tok, tok.next()) tok.infor = 1 return first def forparens1(self, tok): "Read the condition in a for loop." condition = tok.current() + ' ' + self.parser.parseupto(';', tok) tok.depth += 1 tok.infor = 2 return 'while ' + condition + ':' def forparens2(self, tok): "Read the repeating statement in a for loop." statement = tok.current() + ' ' + self.parser.parseupto(')', tok) tok.depth -= 1 tok.infor = 0 self.parser.expectblock(tok) return statement def tryblock(self, tok): "Parse a block after a try." self.parser.expectblock(tok) return tok.current() + ':' def elseblock(self, tok): "Parse a block after an else." self.parser.expectblock(tok) if tok.peek() == 'if': tok.next() self.closeblock(tok) return 'el' + self.conditionblock(tok) return 'else:' def openblock(self, tok): "Open a block of code." if tok.waitingforblock: tok.waitingforblock = False else: tok.depth += 1 if tok.peek() == '}': return 'pass' return None def closeblock(self, tok): "Close a block of code." tok.depth -= 1 return None def returnstatement(self, tok): "A statement that contains a value (a return statement)." self.onelineblock(tok) return 'return ' + self.parser.parsevalue(tok) def throwstatement(self, tok): "A statement to throw (raise) an exception." exception = tok.next() if exception == 'new': return 'raise ' + self.createstatement(tok) token = tok.next() if token == ';': return 'raise ' + exception Trace.error('Invalid throw statement: "throw ' + exception + ' ' + token + '"') return 'raise ' + exception def throwsdeclaration(self, tok): "A throws clause, should be ignored." name = tok.next() return '' def assigninvoke(self, tok, token = None): "An assignment or a method invocation." self.onelineblock(tok) if not token: token = tok.current() token2 = tok.next() if token2 == '=': # assignment return token + ' = ' + self.parser.parsevalue(tok) if token2 == '.': member = tok.next() return self.assigninvoke(tok, token + '.' + member) if token2 == '(': parameters = self.parser.parseparameters(tok) Trace.debug('Parameters: ' + parameters) return self.assigninvoke(tok, token + parameters) if token2 == '[': square = self.parser.parseinsquare(tok) return self.assigninvoke(tok, token + square) if token2 == '{': # ignore anonymous class self.parser.parseupto('}', tok) return token if token2 == '++': Trace.debug('Increasing invoked ' + token) tok.autoincreases.append(token) return self.assigninvoke(tok, token + ' + 1') if token2 == '--': Trace.debug('Decreasing invoked ' + token) tok.autodecreases.append(token) return self.assigninvoke(tok, token + ' - 1') if token2 in [';', ',', ')']: # finished invocation return token if token2 in tok.javasymbols: Trace.error('Unknown symbol ' + token2 + ' for ' + token) return '*error ' + token + ' ' + token2 + ' error*' token3 = tok.next() if token3 == ';': # a declaration; ignore return '' if token3 == '=': # declaration + assignment tok.variables.append(token2) return token2 + ' = ' + self.parser.parsevalue(tok) if token3 == '[': # array declaration self.parser.parseupto(']', tok) return self.assigninvoke(tok, token2) Trace.error('Unknown combination ' + token + '+' + token2 + '+' + token3) return '*error ' + token + ' ' + token2 + ' ' + token + ' error*' def onelineblock(self, tok): "Check if a block was expected." if tok.waitingforblock: tok.waitingforblock = False tok.depth -= 1 def ignorestatement(self, tok): "Ignore a whole statement." while tok.current() != ';': tok.next() return None def createstatement(self, tok): "A statement to create an object and use it: new Class().do()." tok.next() return self.parser.parseinvocation(tok) def thisstatement(self, tok): "A statement starting with this, which translates to self." return self.assigninvoke(tok, 'self') elyxer-1.2.5/forks/jras-elyxer/src/jtp/grammar.py0000644000175000017500000002476412117061342021324 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20100311 # Read a generic grammar. from elyxer.util.trace import Trace from elyxer.util.clone import * from elyxer.conf.javatopyconf import * from elyxer.parse.position import * class Piece(object): "Represents a piece (word, bracket... of any type) in a grammar." def __init__(self): "Initialize common variables." self.closed = False self.valid = True def match(self, tok): "Match the piece against the current token and return the match." Trace.error('Unmatchable piece ' + unicode(self) + ' in ' + unicode(tok)) return None def fitnext(self, token): "Try to fit the next token and return the corresponding declaration." Trace.error('Unimplemented method: fit()') class ConstantWord(Piece): "Represents a constant word in a grammar." def __init__(self, constant): "Initialize the word with the constant." self.constant = constant def match(self, tok): "Just match the current token against the constant." if tok.current() == self.constant: tok.next() return self return None def fitnext(self, token): "Try to fit the next token." self.closed = True if token != self.constant: self.valid = False return None return self def __unicode__(self): "Printable representation." return '\'' + self.constant + '\'' class IdentifierWord(Piece): "A word made of alphanumeric and _ characters." def __init__(self): "Just create an empty word." self.word = None def set(self, word): self.word = word return self def match(self, tok): "Match the current token and store in the template." if tok.iscurrentidentifier(): identifier = IdentifierWord().set(tok.current()) tok.next() return identifier return None def fitnext(self, token): "Try to fit the next token." self.closed = True if token.iscurrentidentifier(): return IdentifierWord().set(tok.current()) return None class Bracket(Piece): "A bracket consisting of other words (repeated, conditional)." quantified = dict() def __init__(self): "Create an empty bracket." self.declaration = None self.quantifier = None def create(self, declaration, quantifier): "Create the bracket for a given declaration." self.declaration = declaration self.quantifier = quantifier return self def parse(self, pos): "Parse the bracket." pos.pushending(']') declaration = Declaration('bracket').parse(pos) pos.popending(']') quantifier = pos.skipcurrent() if not quantifier in self.quantified: Trace.error('Unknown quantifier ' + quantifier) return self bracket = Cloner.clone(self.quantified[quantifier]).create(declaration, quantifier) Trace.debug('Bracket: ' + unicode(bracket)) return bracket def __unicode__(self): "Printable representation." return '[' + unicode(self.declaration) + ']' + self.quantifier class MultipleBracket(Bracket): "A bracket present zero or more times (quantifier *)." def match(self, tok): "Match the bracket zero or more times." decl = Declaration('*') result = self.declaration.match(tok) while result != None: decl.pieces.append(result) result = self.declaration.match(tok) return decl class RepeatedBracket(Bracket): "A bracket present one or more times (quantifier +)." def match(self, tok): "Match the bracket at least one time." decl = Declaration('*') result = self.declaration.match(tok) if not result: return None while result != None: decl.pieces.append(result) result = self.declaration.match(tok) return decl class ConditionalBracket(Bracket): "A bracket which may or may not be present (quantifier ?)." def match(self, tok): "Match the bracket, or not." decl = Declaration('?') result = self.declaration.match(tok) if result: decl.pieces.append(result) return decl def fitnext(self, token): "Try to fit the next token." result = self.declaration.fitnext(token) decl = None if not self.declaration.valid: self.closed = True elif self.declaration.closed: self.closed = True if result: return result if token != self.constant: self.valid = False return None return self Bracket.quantified = { '*': MultipleBracket(), '+': RepeatedBracket(), '?': ConditionalBracket() } class Alternatives(Piece): "A group of alternatives to parse." def __init__(self): "Create an empty set of alternatives." self.alternatives = [] def add(self, pieces): "Add a new set of alternative pieces." alternative = Declaration('#' + unicode(len(self.alternatives))) alternative.pieces = pieces self.alternatives.append(alternative) Trace.debug('Alternatives: ' + unicode(self)) return self def match(self, tok): "Match any of the alternatives." for alternative in self.alternatives: result = alternative.match(tok) if result: return result return None def __unicode__(self): "Printable representation." if len(self.alternatives) == 0: return 'Empty alternatives' result = '' for alternative in self.alternatives: result += ' | ' + unicode(alternative) return result[3:] class Declaration(Piece): "A grammar declaration consisting of several pieces." notsymbol = '[]_ |$' pieces = [] def __init__(self, key): self.key = key self.pieces = [] def parse(self, pos): "Parse the given position." while not pos.finished(): if pos.checkskip('$'): self.parsevariable(pos) elif pos.checkskip('['): self.parsebracket(pos) elif pos.checkidentifier(): self.parseidentifier(pos) elif pos.checkskip(' '): # ignore blank characters pass elif pos.checkskip('|'): self.parsealternative(pos) else: self.parsesymbol(pos) self.checkalternatives() return self def parsevariable(self, pos): "Parse a variable." if pos.checkskip('$'): self.pieces.append(IdentifierWord()) return name = '$' + pos.globidentifier() if not name in Grammar.instance.declarations: Trace.error('Unknown variable ' + name) return Trace.debug('New variable ' + name) self.pieces.append(Grammar.instance.declarations[name]) def parsebracket(self, pos): "Parse a bracket and the quantifier (*+?)." self.pieces.append(Bracket().parse(pos)) def parseidentifier(self, pos): "Parse a constant identifier value." self.addconstant(pos.globidentifier()) def parsealternative(self, pos): "Parse an alternative in a group." if len(self.pieces) == 0: Trace.error('Empty beginning alternative at ' + pos.identifier()) return if self.checkalternatives(): return alt = Alternatives().add(self.pieces) self.pieces = [alt] def checkalternatives(self): "Check if there is a set of alternatives active, and add everything there." if len(self.pieces) == 0 or not isinstance(self.pieces[0], Alternatives): return False if len(self.pieces) == 1: Trace.error('Empty alternative') return self.pieces[0].add(self.pieces[1:]) self.pieces = [self.pieces[0]] return True def parsesymbol(self, pos): "Parse a symbol." symbol = '' while self.issymbol(pos): symbol += pos.skipcurrent() if symbol == '': symbol += pos.skipcurrent() Trace.error('Empty symbol; acquiring ' + symbol) self.addconstant(symbol) def issymbol(self, pos): "Find out if the current character belongs to a larger symbol." if pos.finished(): return False if pos.current() in self.notsymbol: return False if pos.checkidentifier(): return False return True def addconstant(self, constant): "Add a constant value." if constant in Grammar.instance.constants: Trace.error('Repeated constant ' + constant) return Trace.debug('New constant: ' + constant) self.pieces.append(ConstantWord(constant)) def match(self, tok): "Match the declaration against a tokenizer." decl = Declaration(self.key) state = tok.mark() for piece in self.pieces: Trace.debug('Matching ' + tok.current() + ' against ' + unicode(piece)) result = piece.match(tok) if not result: Trace.error('Mismatch of ' + tok.current() + ' against ' + unicode(piece)) tok.revert(state) return None decl.pieces.append(result) return decl def __unicode__(self): "Printable representation." if len(self.pieces) == 0: return u'❲empty❳' result = '' for piece in self.pieces: if isinstance(piece, Declaration): pieceresult = piece.key else: pieceresult = unicode(piece) result += ', ' + pieceresult return u'❲' + result[2:] + u'❳' class Grammar(object): "Read a complete grammar into memory." instance = None def __init__(self): "Read all declarations into variables." self.variables = dict() self.declarations = dict() self.constants = dict() def process(self): "Process the grammar and create all necessary structures." for key in JavaToPyConfig.declarations: self.variables[key] = JavaToPyConfig.declarations[key] for key in self.variables: self.declarations[key] = Declaration(key) for key in self.variables: Trace.debug('Interpreting ' + self.variables[key]) pos = TextPosition(self.variables[key]) self.declarations[key].parse(pos) def parse(self, tok): "Parse a whole file using a tokenizer." tok.next() filedecl = self.declarations['$file'] result = filedecl.match(tok) if not result: Trace.error('Actual file does not match $file.') return Grammar.instance = Grammar() elyxer-1.2.5/forks/jras-elyxer/src/jtp/parser.py0000644000175000017500000002546212117061342021166 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20091226 # Port a Java program to a Python equivalent. Used to port MathToWeb. from elyxer.util.trace import Trace class StatementParser(object): "A parser for a statement." def __init__(self, chooser): self.chooser = chooser def checkvariable(self, token): "Check if the token is a valid variable name." for char in token: if not Tokenizer.isalphanumeric(char): return False return True def autoincrease(self, tok): "Process a Java autoincrease (++)." variable = tok.autoincreases.pop() return variable + ' += 1' def autodecrease(self, tok): "Process a Java autodecrease (--)." variable = tok.autodecreases.pop() return variable + ' -= 1' def translateclass(self, tok): "Translate a class definition." tok.checknext('class') name = tok.next() tok.inclass = name inheritance = '' while tok.peek() != '{': inheritance += ' ' + tok.next() Trace.error('Unused inheritance ' + inheritance) return 'class ' + name + '(object):' def translateinternal(self, tok): "Translate an internal element (attribute or method)." token = self.membertoken(tok) name = self.membertoken(tok) if token == tok.inclass and name == '(': # constructor return self.translatemethod(token, tok) after = tok.next() while after == '[': tok.checknext(']') after = tok.next() if after == ';': return self.translateemptyattribute(name) if after == '(': return self.translatemethod(name, tok) if after != '=': Trace.error('Weird token after member: ' + token + ' ' + name + ' ' + after) return self.translateattribute(name, tok) def membertoken(self, tok): "Get the next member token, excluding static, []..." token = tok.next() if token in ['static', 'synchronized', 'final']: return self.membertoken(tok) if token == '[': tok.checknext(']') return self.membertoken(tok) return token def translatemethod(self, name, tok): "Translate a class method." tok.inmethod = name pars = self.listparameters(tok) self.expectblock(tok) parlist = ', ' for par in pars: if not ' ' in par: Trace.error('Invalid parameter declaration: ' + par) else: newpar = par.strip().split(' ', 1)[1] parlist += newpar + ', ' parlist = parlist[:-2] return '\ndef ' + name + '(self' + parlist + '):' def translateemptyattribute(self, name): "Translate an empty attribute definition." return name + ' = None' def translateattribute(self, name, tok): "Translate a class attribute." return name + ' = ' + self.parseupto(';', tok) def listparameters(self, tok): "Parse the parameters of a method definition, return them as a list." params = self.parseinparens(tok)[1:-1] pars = params.split(',') if pars[0] == '': return [] return pars def processtoken(self, tok): "Process a single token." token = tok.current() if token in self.chooser.javatokens: function = getattr(self.chooser, self.chooser.javatokens[token]) return function(tok) if token in tok.javasymbols: return self.processsymbol(tok) return token def processsymbol(self, tok): "Process a single java symbol." if tok.current() == '"' or tok.current() == '\'': return self.parsequoted(tok.current(), tok) if tok.current() == '{': return '{' + self.parseupto('}', tok) + '}' if tok.current() == '}': Trace.error('Erroneously closing }') return '' if tok.current() == '(': result = self.parseinparens(tok) return result if tok.current() == '[': result = self.parseinsquare(tok) return result if tok.current() == ')': Trace.error('Erroneously closing )') return ')' if tok.current() in tok.modified: return tok.modified[tok.current()] return tok.current() def parsequoted(self, quote, tok): "Parse a quoted sentence, with variable quotes." result = tok.current() + tok.pos.globincluding(quote) while result.endswith('\\' + quote) and not result.endswith('\\\\' + quote): result += tok.pos.globincluding(quote) return result def parseparameters(self, tok): "Parse the parameters to a method invocation." result = '(' while tok.current() != ')': param = self.parsevalue(tok, [',',')']) result += param + ', ' if len(result) == 1: return '()' return result[:-2] + ')' def parseparens(self, tok): "Parse a couple of () and the contents inside." tok.checknext('(') return self.parseinparens(tok) def parseinparens(self, tok): "Parse the contents inside ()." contents = self.parseupto(')', tok) if '{' in contents: # anonymous function; ignore return '()' if Tokenizer.isalphanumeric(contents): if Tokenizer.isalphanumeric(tok.peek()): # type cast; ignore return '' result = '(' + contents + ')' return result result = self.parseinbrackets('(', ')', tok) def parseinsquare(self, tok): "Parse the contents inside []." return self.parseinbrackets('[', ']', tok) def parseinbrackets(self, opening, closing, tok): "Parse the contents in any kind of brackets." result = self.parseupto(closing, tok) return opening + result + closing def parsecondition(self, tok, ending): "Parse a condition given the ending token." return self.parseupto(ending, tok) def parsevalue(self, tok, endings = [';']): "Parse a value (to be assigned or returned)." return self.parsetoendings(tok, endings) def parseinvocation(self, tok, previous = None): "Parse a class or method invocation." result = previous or '' name = tok.current() tok.checknext('(') params = self.parseparameters(tok) result += name + params if tok.peek() != '.': return result tok.checknext('.') return self.parseinvocation(tok, result + '.') def parseupto(self, ending, tok): "Parse the tokenizer up to the supplied ending." return self.parsetoendings(tok, [ending]) def parsetoendings(self, tok, endings): "Parse the tokenizer up to a number of endings." result = '' tok.next() while not tok.current() in endings: processed = self.processtoken(tok) if processed == '++': processed = '+ 1' Trace.debug('Increasing ' + result + ' for endings: ' + unicode(endings)) tok.autoincreases.append(result) if processed == '--': Trace.debug('Decreasing ' + result) processed = '- 1' tok.autodecreases.append(result) if processed != '.' and not result.endswith('.'): processed = ' ' + processed result += processed if not tok.current in endings: tok.next() if len(result) > 0: result = result[1:] Trace.debug('Left after ' + tok.current() + ', endings ' + unicode(endings) + ', result: ' + result) return result def expectblock(self, tok): "Mark that a block is to be expected." tok.depth += 1 tok.waitingforblock = True class Tokenizer(object): "Tokenizes a parse position." unmodified = [ '&', '|', '=', '(', ')', '{', '}', '.', '+', '-', '"', ',', '/', '*', '<', '>', '\'', '[', ']', '%', ';', '!=','<=','>=', '==', '++', '--' ] modified = { '&&':'and', '||':'or', '!':'not' } comments = ['//', '/*'] javasymbols = comments + unmodified + modified.keys() def __init__(self, pos): self.pos = pos self.currenttoken = None self.peeked = None self.autoincreases = [] self.autodecreases = [] self.depth = 0 self.waitingforblock = False self.inclass = None self.inmethod = None self.variables = ['this'] self.infor = 0 def next(self): "Get the next single token, and store it for current()." if self.peeked: self.currenttoken = self.peeked self.peeked = None else: self.currenttoken = self.extractwithoutcomments() return self.currenttoken def checknext(self, token): "Check that the next token is the parameter." self.next() if self.currenttoken != token: Trace.error('Expected token ' + token + ', found ' + self.currenttoken) return False return True def extractwithoutcomments(self): "Get the next single token without comments." token = self.extracttoken() while token in self.comments: self.skipcomment(token) token = self.extracttoken() self.pos.skipspace() return token def extracttoken(self): "Extract the next token." if self.finished(): return None if self.pos.checkidentifier(): return self.pos.globidentifier() if self.pos.current() in self.javasymbols: result = self.pos.skipcurrent() while result + self.pos.current() in self.javasymbols: result += self.pos.skipcurrent() return result current = self.pos.skipcurrent() raise Exception('Unrecognized character: ' + current) def current(self): "Get the current token." return self.currenttoken def finished(self): "Find out if the tokenizer has finished tokenizing." self.pos.skipspace() return self.pos.finished() def iscurrentidentifier(self): "Return if the current token is an identifier (alphanumeric or _ characters)." if self.currenttoken.replace('_', '').isalnum(): return True return False def skipcomment(self, token): "Skip over a comment." if token == '//': comment = self.pos.globexcluding('\n') return if token == '/*': while not self.pos.checkskip('/'): comment = self.pos.globincluding('*') return Trace.error('Unknown comment type ' + token) def peek(self): "Look ahead at the next token, without advancing the parse position." token = self.extractwithoutcomments() self.peeked = token return token def mark(self): "Mark the current state and return a handle." Trace.error('Unimplemented mark()') return None def revert(self, state): "Revert to a previous state as returned by mark()." Trace.error('Unimplemented revert()') elyxer-1.2.5/forks/jras-elyxer/src/jtp/__init__.py0000644000175000017500000000000012117061342021406 0ustar chennochennoelyxer-1.2.5/forks/jras-elyxer/src/setup.py0000644000175000017500000000400112117061342020217 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20090908 # eLyXer distutils management from distutils.core import setup packages = [ 'elyxer', 'elyxer.bib', 'elyxer.conf', 'elyxer.gen', 'elyxer.io', 'elyxer.main', 'elyxer.maths', 'elyxer.out', 'elyxer.parse', 'elyxer.proc', 'elyxer.ref', 'elyxer.util', 'elyxer.xtra' ] packages = [] setup(name = 'eLyXer', version = 'unknown', description = 'LyX to HTML converter', long_description = 'eLyXer is a LyX to HTML converter, with a focus on flexibility and elegant output.', author = 'Alex Fernandez', author_email = 'elyxer@gmail.com', url = 'http://elyxer.nongnu.org/', packages = packages, scripts = ['elyxer.py', 'math2html.py', 'loremipsumize.py'], classifiers = [ 'License :: OSI Approved :: GNU General Public License (GPL)', 'Development Status :: 5 - Production/Stable', 'Environment :: Console', 'Operating System :: OS Independent', 'Programming Language :: Python :: 2.4', 'Topic :: Printing', 'Topic :: Text Processing :: Markup :: HTML', 'Topic :: Utilities', 'Topic :: Internet :: WWW/HTTP :: Dynamic Content' ], license = 'GPL version 3 or later', platforms = ['Windows NT/2000/XP', 'Mac OS X', 'GNU/Linux'], ) elyxer-1.2.5/forks/jras-elyxer/src/elyxer/0000755000175000017500000000000012117175142020026 5ustar chennochennoelyxer-1.2.5/forks/jras-elyxer/src/elyxer/parse/0000755000175000017500000000000012117061342021134 5ustar chennochennoelyxer-1.2.5/forks/jras-elyxer/src/elyxer/parse/tableparse.py0000644000175000017500000000365312117061342023637 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20090503 # eLyXer table parsing from elyxer.parse.parser import * from elyxer.conf.config import * class TableParser(BoundedParser): "Parse the whole table" headers = ContainerConfig.table['headers'] def __init__(self): BoundedParser.__init__(self) self.columns = list() def parseheader(self, reader): "Parse table headers" reader.nextline() while self.startswithheader(reader): self.parseparameter(reader) return [] def startswithheader(self, reader): "Check if the current line starts with a header line" for start in TableParser.headers: if reader.currentline().strip().startswith(start): return True return False class TablePartParser(BoundedParser): "Parse a table part (row or cell)" def parseheader(self, reader): "Parse the header" tablekey, parameters = self.parsexml(reader) self.parameters = parameters return list() class ColumnParser(LoneCommand): "Parse column properties" def parseheader(self, reader): "Parse the column definition" key, parameters = self.parsexml(reader) self.parameters = parameters return [] elyxer-1.2.5/forks/jras-elyxer/src/elyxer/parse/formulaparse.py0000644000175000017500000001246012117061342024211 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20090503 # eLyXer formula parsing from elyxer.util.trace import Trace from elyxer.conf.config import * from elyxer.parse.parser import * from elyxer.parse.position import * class FormulaParser(Parser): "Parses a formula" def parseheader(self, reader): "See if the formula is inlined" self.begin = reader.linenumber + 1 type = self.parsetype(reader) if not type: reader.nextline() type = self.parsetype(reader) if not type: Trace.error('Unknown formula type in ' + reader.currentline().strip()) return ['unknown'] return [type] def parsetype(self, reader): "Get the formula type from the first line." if reader.currentline().find(FormulaConfig.starts['simple']) >= 0: return 'inline' if reader.currentline().find(FormulaConfig.starts['complex']) >= 0: return 'block' if reader.currentline().find(FormulaConfig.starts['unnumbered']) >= 0: return 'block' if reader.currentline().find(FormulaConfig.starts['beginbefore']) >= 0: return 'numbered' return None def parse(self, reader): "Parse the formula until the end" formula = self.parseformula(reader) while not reader.currentline().startswith(self.ending): stripped = reader.currentline().strip() if len(stripped) > 0: Trace.error('Unparsed formula line ' + stripped) reader.nextline() reader.nextline() return formula def parseformula(self, reader): "Parse the formula contents" simple = FormulaConfig.starts['simple'] if simple in reader.currentline(): rest = reader.currentline().split(simple, 1)[1] if simple in rest: # formula is $...$ return self.parsesingleliner(reader, simple, simple) # formula is multiline $...$ return self.parsemultiliner(reader, simple, simple) if FormulaConfig.starts['complex'] in reader.currentline(): # formula of the form \[...\] return self.parsemultiliner(reader, FormulaConfig.starts['complex'], FormulaConfig.endings['complex']) beginbefore = FormulaConfig.starts['beginbefore'] beginafter = FormulaConfig.starts['beginafter'] if beginbefore in reader.currentline(): if reader.currentline().strip().endswith(beginafter): current = reader.currentline().strip() endsplit = current.split(beginbefore)[1].split(beginafter) startpiece = beginbefore + endsplit[0] + beginafter endbefore = FormulaConfig.endings['endbefore'] endafter = FormulaConfig.endings['endafter'] endpiece = endbefore + endsplit[0] + endafter return startpiece + self.parsemultiliner(reader, startpiece, endpiece) + endpiece Trace.error('Missing ' + beginafter + ' in ' + reader.currentline()) return '' begincommand = FormulaConfig.starts['command'] beginbracket = FormulaConfig.starts['bracket'] if begincommand in reader.currentline() and beginbracket in reader.currentline(): endbracket = FormulaConfig.endings['bracket'] return self.parsemultiliner(reader, beginbracket, endbracket) Trace.error('Formula beginning ' + reader.currentline() + ' is unknown') return '' def parsesingleliner(self, reader, start, ending): "Parse a formula in one line" line = reader.currentline().strip() if not start in line: Trace.error('Line ' + line + ' does not contain formula start ' + start) return '' if not line.endswith(ending): Trace.error('Formula ' + line + ' does not end with ' + ending) return '' index = line.index(start) rest = line[index + len(start):-len(ending)] reader.nextline() return rest def parsemultiliner(self, reader, start, ending): "Parse a formula in multiple lines" formula = '' line = reader.currentline() if not start in line: Trace.error('Line ' + line.strip() + ' does not contain formula start ' + start) return '' index = line.index(start) line = line[index + len(start):].strip() while not line.endswith(ending): formula += line + '\n' reader.nextline() line = reader.currentline() formula += line[:-len(ending)] reader.nextline() return formula class MacroParser(FormulaParser): "A parser for a formula macro." def parseheader(self, reader): "See if the formula is inlined" self.begin = reader.linenumber + 1 return ['inline'] def parse(self, reader): "Parse the formula until the end" formula = self.parsemultiliner(reader, self.parent.start, self.ending) reader.nextline() return formula elyxer-1.2.5/forks/jras-elyxer/src/elyxer/parse/headerparse.py0000644000175000017500000001022312117061342023767 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20100509 # eLyXer: LyX header parsing. from elyxer.util.trace import Trace from elyxer.util.options import * from elyxer.conf.config import * from elyxer.parse.parser import * class HeaderParser(Parser): "Parses the LyX header" def parse(self, reader): "Parse header parameters into a dictionary, return the preamble." contents = [] self.parseending(reader, lambda: self.parseline(reader, contents)) # skip last line reader.nextline() return contents def parseline(self, reader, contents): "Parse a single line as a parameter or as a start" line = reader.currentline() if line.startswith(HeaderConfig.parameters['branch']): self.parsebranch(reader) return elif line.startswith(HeaderConfig.parameters['lstset']): LstParser().parselstset(reader) return elif line.startswith(HeaderConfig.parameters['beginpreamble']): contents.append(self.factory.createcontainer(reader)) return # no match self.parseparameter(reader) def parsebranch(self, reader): "Parse all branch definitions." branch = reader.currentline().split()[1] reader.nextline() subparser = HeaderParser().complete(HeaderConfig.parameters['endbranch']) subparser.parse(reader) options = BranchOptions(branch) for key in subparser.parameters: options.set(key, subparser.parameters[key]) Options.branches[branch] = options def complete(self, ending): "Complete the parser with the given ending." self.ending = ending return self class PreambleParser(Parser): "A parser for the LyX preamble." preamble = [] def parse(self, reader): "Parse the full preamble with all statements." self.ending = HeaderConfig.parameters['endpreamble'] self.parseending(reader, lambda: self.parsepreambleline(reader)) return [] def parsepreambleline(self, reader): "Parse a single preamble line." PreambleParser.preamble.append(reader.currentline()) reader.nextline() class LstParser(object): "Parse global and local lstparams." globalparams = dict() def parselstset(self, reader): "Parse a declaration of lstparams in lstset." paramtext = self.extractlstset(reader) if not '{' in paramtext: Trace.error('Missing opening bracket in lstset: ' + paramtext) return lefttext = paramtext.split('{')[1] croppedtext = lefttext[:-1] LstParser.globalparams = self.parselstparams(croppedtext) def extractlstset(self, reader): "Extract the global lstset parameters." paramtext = '' while not reader.finished(): paramtext += reader.currentline() reader.nextline() if paramtext.endswith('}'): return paramtext Trace.error('Could not find end of \\lstset settings; aborting') def parsecontainer(self, container): "Parse some lstparams from elyxer.a container." container.lstparams = LstParser.globalparams.copy() paramlist = container.getparameterlist('lstparams') container.lstparams.update(self.parselstparams(paramlist)) def parselstparams(self, paramlist): "Process a number of lstparams from elyxer.a list." paramdict = dict() for param in paramlist: if not '=' in param: if len(param.strip()) > 0: Trace.error('Invalid listing parameter ' + param) else: key, value = param.split('=', 1) paramdict[key] = value return paramdict elyxer-1.2.5/forks/jras-elyxer/src/elyxer/parse/position.py0000644000175000017500000001303512117061342023354 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20090503 # eLyXer formula parsing from elyxer.io.fileline import * from elyxer.util.trace import Trace from elyxer.conf.config import * from elyxer.parse.glob import * class Position(Globable): """A position in a text to parse. Including those in Globable, functions to implement by subclasses are: skip(), identifier(), extract(), isout() and current().""" def __init__(self): Globable.__init__(self) def skip(self, string): "Skip a string" Trace.error('Unimplemented skip()') def identifier(self): "Return an identifier for the current position." Trace.error('Unimplemented identifier()') return 'Error' def extract(self, length): "Extract the next string of the given length, or None if not enough text," "without advancing the parse position." Trace.error('Unimplemented extract()') return None def checkfor(self, string): "Check for a string at the given position." return string == self.extract(len(string)) def checkforlower(self, string): "Check for a string in lower case." extracted = self.extract(len(string)) if not extracted: return False return string.lower() == self.extract(len(string)).lower() def skipcurrent(self): "Return the current character and skip it." current = self.current() self.skip(current) return current def next(self): "Advance the position and return the next character." self.skipcurrent() return self.current() def checkskip(self, string): "Check for a string at the given position; if there, skip it" if not self.checkfor(string): return False self.skip(string) return True def error(self, message): "Show an error message and the position identifier." Trace.error(message + ': ' + self.identifier()) class TextPosition(Position): "A parse position based on a raw text." def __init__(self, text): "Create the position from elyxer.some text." Position.__init__(self) self.pos = 0 self.text = text self.checkbytemark() def skip(self, string): "Skip a string of characters." self.pos += len(string) def identifier(self): "Return a sample of the remaining text." length = 30 if self.pos + length > len(self.text): length = len(self.text) - self.pos return '*' + self.text[self.pos:self.pos + length] + '*' def isout(self): "Find out if we are out of the text yet." return self.pos >= len(self.text) def current(self): "Return the current character, assuming we are not out." return self.text[self.pos] def extract(self, length): "Extract the next string of the given length, or None if not enough text." if self.pos + length > len(self.text): return None return self.text[self.pos : self.pos + length] class FilePosition(Position): "A parse position based on an underlying file." def __init__(self, filename): "Create the position from a file." Position.__init__(self) self.reader = LineReader(filename) self.pos = 0 self.checkbytemark() def skip(self, string): "Skip a string of characters." length = len(string) while self.pos + length > len(self.reader.currentline()): length -= len(self.reader.currentline()) - self.pos + 1 self.nextline() self.pos += length def currentline(self): "Get the current line of the underlying file." return self.reader.currentline() def nextline(self): "Go to the next line." self.reader.nextline() self.pos = 0 def linenumber(self): "Return the line number of the file." return self.reader.linenumber + 1 def identifier(self): "Return the current line and line number in the file." before = self.reader.currentline()[:self.pos - 1] after = self.reader.currentline()[self.pos:] return 'line ' + unicode(self.getlinenumber()) + ': ' + before + '*' + after def isout(self): "Find out if we are out of the text yet." if self.pos > len(self.reader.currentline()): if self.pos > len(self.reader.currentline()) + 1: Trace.error('Out of the line ' + self.reader.currentline() + ': ' + unicode(self.pos)) self.nextline() return self.reader.finished() def current(self): "Return the current character, assuming we are not out." if self.pos == len(self.reader.currentline()): return '\n' if self.pos > len(self.reader.currentline()): Trace.error('Out of the line ' + self.reader.currentline() + ': ' + unicode(self.pos)) return '*' return self.reader.currentline()[self.pos] def extract(self, length): "Extract the next string of the given length, or None if not enough text." if self.pos + length > len(self.reader.currentline()): return None return self.reader.currentline()[self.pos : self.pos + length] elyxer-1.2.5/forks/jras-elyxer/src/elyxer/parse/parser.py0000644000175000017500000001320612117061342023004 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20090203 # eLyXer parsers from elyxer.util.trace import Trace from elyxer.util.options import * from elyxer.conf.config import * class Parser(object): "A generic parser" def __init__(self): self.begin = 0 self.parameters = dict() def parseheader(self, reader): "Parse the header" header = reader.currentline().split() reader.nextline() self.begin = reader.linenumber return header def parseparameter(self, reader): "Parse a parameter" if reader.currentline().strip().startswith('<'): key, value = self.parsexml(reader) self.parameters[key] = value return split = reader.currentline().strip().split(' ', 1) reader.nextline() if len(split) == 0: return key = split[0] if len(split) == 1: self.parameters[key] = True return if not '"' in split[1]: self.parameters[key] = split[1].strip() return doublesplit = split[1].split('"') self.parameters[key] = doublesplit[1] def parsexml(self, reader): "Parse a parameter in xml form: " strip = reader.currentline().strip() reader.nextline() if not strip.endswith('>'): Trace.error('XML parameter ' + strip + ' should be <...>') split = strip[1:-1].split() if len(split) == 0: Trace.error('Empty XML parameter <>') return None, None key = split[0] del split[0] if len(split) == 0: return key, dict() attrs = dict() for attr in split: if not '=' in attr: Trace.error('Erroneous attribute for ' + key + ': ' + attr) attr += '="0"' parts = attr.split('=') attrkey = parts[0] value = parts[1].split('"')[1] attrs[attrkey] = value return key, attrs def parseending(self, reader, process): "Parse until the current ending is found" if not self.ending: Trace.error('No ending for ' + unicode(self)) return while not reader.currentline().startswith(self.ending): process() def parsecontainer(self, reader, contents): container = self.factory.createcontainer(reader) if container: container.parent = self.parent contents.append(container) def __unicode__(self): "Return a description" return self.__class__.__name__ + ' (' + unicode(self.begin) + ')' class LoneCommand(Parser): "A parser for just one command line" def parse(self,reader): "Read nothing" return [] class TextParser(Parser): "A parser for a command and a bit of text" stack = [] def __init__(self, container): Parser.__init__(self) self.ending = None if container.__class__.__name__ in ContainerConfig.endings: self.ending = ContainerConfig.endings[container.__class__.__name__] self.endings = [] def parse(self, reader): "Parse lines as long as they are text" TextParser.stack.append(self.ending) self.endings = TextParser.stack + [ContainerConfig.endings['Layout'], ContainerConfig.endings['Inset'], self.ending] contents = [] while not self.isending(reader): self.parsecontainer(reader, contents) return contents def isending(self, reader): "Check if text is ending" current = reader.currentline().split() if len(current) == 0: return False if current[0] in self.endings: if current[0] in TextParser.stack: TextParser.stack.remove(current[0]) else: TextParser.stack = [] return True return False class ExcludingParser(Parser): "A parser that excludes the final line" def parse(self, reader): "Parse everything up to (and excluding) the final line" contents = [] self.parseending(reader, lambda: self.parsecontainer(reader, contents)) return contents class BoundedParser(ExcludingParser): "A parser bound by a final line" def parse(self, reader): "Parse everything, including the final line" contents = ExcludingParser.parse(self, reader) # skip last line reader.nextline() return contents class BoundedDummy(Parser): "A bound parser that ignores everything" def parse(self, reader): "Parse the contents of the container" self.parseending(reader, lambda: reader.nextline()) # skip last line reader.nextline() return [] class StringParser(Parser): "Parses just a string" def parseheader(self, reader): "Do nothing, just take note" self.begin = reader.linenumber + 1 return [] def parse(self, reader): "Parse a single line" contents = reader.currentline() reader.nextline() return contents class InsetParser(BoundedParser): "Parses a LyX inset" def parse(self, reader): "Parse inset parameters into a dictionary" startcommand = ContainerConfig.string['startcommand'] while reader.currentline() != '' and not reader.currentline().startswith(startcommand): self.parseparameter(reader) return BoundedParser.parse(self, reader) elyxer-1.2.5/forks/jras-elyxer/src/elyxer/parse/glob.py0000644000175000017500000001451612117061342022440 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20110111 # eLyXer globbing of an underlying string. from elyxer.util.trace import Trace class Globable(object): """A bit of text which can be globbed (lumped together in bits). Methods current(), skipcurrent(), checkfor() and isout() have to be implemented by subclasses.""" leavepending = False def __init__(self): self.endinglist = EndingList() def checkbytemark(self): "Check for a Unicode byte mark and skip it." if self.finished(): return if ord(self.current()) == 0xfeff: self.skipcurrent() def isout(self): "Find out if we are out of the position yet." Trace.error('Unimplemented isout()') return True def current(self): "Return the current character." Trace.error('Unimplemented current()') return '' def checkfor(self, string): "Check for the given string in the current position." Trace.error('Unimplemented checkfor()') return False def finished(self): "Find out if the current text has finished." if self.isout(): if not self.leavepending: self.endinglist.checkpending() return True return self.endinglist.checkin(self) def skipcurrent(self): "Return the current character and skip it." Trace.error('Unimplemented skipcurrent()') return '' def glob(self, currentcheck): "Glob a bit of text that satisfies a check on the current char." glob = '' while not self.finished() and currentcheck(): glob += self.skipcurrent() return glob def globalpha(self): "Glob a bit of alpha text" return self.glob(lambda: self.current().isalpha()) def globnumber(self): "Glob a row of digits." return self.glob(lambda: self.current().isdigit()) def isidentifier(self): "Return if the current character is alphanumeric or _." if self.current().isalnum() or self.current() == '_': return True return False def globidentifier(self): "Glob alphanumeric and _ symbols." return self.glob(self.isidentifier) def isvalue(self): "Return if the current character is a value character:" "not a bracket or a space." if self.current().isspace(): return False if self.current() in '{}()': return False return True def globvalue(self): "Glob a value: any symbols but brackets." return self.glob(self.isvalue) def skipspace(self): "Skip all whitespace at current position." return self.glob(lambda: self.current().isspace()) def globincluding(self, magicchar): "Glob a bit of text up to (including) the magic char." glob = self.glob(lambda: self.current() != magicchar) + magicchar self.skip(magicchar) return glob def globexcluding(self, excluded): "Glob a bit of text up until (excluding) any excluded character." return self.glob(lambda: self.current() not in excluded) def pushending(self, ending, optional = False): "Push a new ending to the bottom" self.endinglist.add(ending, optional) def popending(self, expected = None): "Pop the ending found at the current position" if self.isout() and self.leavepending: return expected ending = self.endinglist.pop(self) if expected and expected != ending: Trace.error('Expected ending ' + expected + ', got ' + ending) self.skip(ending) return ending def nextending(self): "Return the next ending in the queue." nextending = self.endinglist.findending(self) if not nextending: return None return nextending.ending class EndingList(object): "A list of position endings" def __init__(self): self.endings = [] def add(self, ending, optional = False): "Add a new ending to the list" self.endings.append(PositionEnding(ending, optional)) def pickpending(self, pos): "Pick any pending endings from a parse position." self.endings += pos.endinglist.endings def checkin(self, pos): "Search for an ending" if self.findending(pos): return True return False def pop(self, pos): "Remove the ending at the current position" if pos.isout(): Trace.error('No ending out of bounds') return '' ending = self.findending(pos) if not ending: Trace.error('No ending at ' + pos.current()) return '' for each in reversed(self.endings): self.endings.remove(each) if each == ending: return each.ending elif not each.optional: Trace.error('Removed non-optional ending ' + each) Trace.error('No endings left') return '' def findending(self, pos): "Find the ending at the current position" if len(self.endings) == 0: return None for index, ending in enumerate(reversed(self.endings)): if ending.checkin(pos): return ending if not ending.optional: return None return None def checkpending(self): "Check if there are any pending endings" if len(self.endings) != 0: Trace.error('Pending ' + unicode(self) + ' left open') def __unicode__(self): "Printable representation" string = 'endings [' for ending in self.endings: string += unicode(ending) + ',' if len(self.endings) > 0: string = string[:-1] return string + ']' class PositionEnding(object): "An ending for a parsing position" def __init__(self, ending, optional): self.ending = ending self.optional = optional def checkin(self, pos): "Check for the ending" return pos.checkfor(self.ending) def __unicode__(self): "Printable representation" string = 'Ending ' + self.ending if self.optional: string += ' (optional)' return string elyxer-1.2.5/forks/jras-elyxer/src/elyxer/parse/__init__.py0000644000175000017500000000000012117061342023233 0ustar chennochennoelyxer-1.2.5/forks/jras-elyxer/src/elyxer/ref/0000755000175000017500000000000012117061342020576 5ustar chennochennoelyxer-1.2.5/forks/jras-elyxer/src/elyxer/ref/partkey.py0000644000175000017500000001506412117061342022635 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20100705 # eLyXer: key that identifies a given document part (chapter, section...). from elyxer.util.trace import Trace from elyxer.util.options import * from elyxer.util.translate import * from elyxer.util.numbering import * from elyxer.util.docparams import * from elyxer.ref.label import * from elyxer.gen.inset import * from elyxer.out.template import * class PartKey(object): "A key to identify a given document part (chapter, section...)." partkey = None tocentry = None anchortext = None number = None filename = None titlecontents = None header = False def __init__(self): self.level = 0 def createindex(self, partkey): "Create a part key for an index page." self.partkey = partkey self.tocentry = partkey self.filename = partkey return self def createfloat(self, float): "Create a part key for a float." self.number = NumberGenerator.chaptered.generate(float.type) self.partkey = Translator.translate('float-' + float.type) + self.number if Options.notoclabels: self.tocentry = self.number else: self.tocentry = self.partkey self.readtitle(float) return self def createsubfloat(self, number): "Create the part key for a subfloat." self.partkey = '(' + number + ')' self.number = number return self def createformula(self, number): "Create the part key for a formula." self.number = number self.partkey = 'formula-' + number self.tocentry = '(' + number + ')' return self def createheader(self, headorfooter): "Create the part key for a header or footer." self.partkey = headorfooter self.tocentry = None self.header = True return self def createanchor(self, partkey): "Create an anchor for the page." self.partkey = partkey self.tocentry = partkey self.header = True return self def createmain(self): "Create the part key for the main page." self.partkey = '' self.tocentry = DocumentTitle().getvalue() return self def addtoclabel(self, container): "Create the label for the TOC, and add it to the container." labeltext = '' if self.anchortext: labeltext = self.anchortext container.contents.insert(0, Separator(u' ')) label = Label().create(labeltext, self.partkey, type='toc') container.contents.insert(0, label) def readtitle(self, container): "Read the title of the TOC entry." shorttitles = container.searchall(ShortTitle) if len(shorttitles) > 0: self.titlecontents = [] for shorttitle in shorttitles: self.titlecontents += shorttitle.contents return extractor = ContainerExtractor(TOCConfig.extracttitle) captions = container.searchall(Caption) if len(captions) == 1: self.titlecontents = extractor.extract(captions[0]) return self.titlecontents = extractor.extract(container) def __unicode__(self): "Return a printable representation." return 'Part key for ' + self.partkey class LayoutPartKey(PartKey): "The part key for a layout." generator = NumberGenerator() def create(self, layout): "Set the layout for which we are creating the part key." self.processtype(layout.type) self.readtitle(layout) return self def processtype(self, type): "Process the layout type." self.level = self.generator.getlevel(type) self.number = self.generator.generate(type) anchortype = self.getanchortype(type) self.partkey = 'toc-' + anchortype + '-' + self.number self.tocentry = self.gettocentry(type) self.filename = self.getfilename(type) if self.generator.isnumbered(type): if not self.tocentry: self.tocentry = '' else: self.tocentry += ' ' self.tocentry += self.number self.anchortext = self.getanchortext(type) def getanchortype(self, type): "Get the type for the anchor." parttype = self.generator.getparttype(type) if self.generator.isunordered(type): parttype += '-' return parttype def gettocentry(self, type): "Get the entry for the TOC: Chapter, Section..." if Options.notoclabels: return '' return Translator.translate(self.generator.getparttype(type)) def addtotocentry(self, text): "Add some text to the tocentry; create if None." if not self.tocentry: self.tocentry = '' self.tocentry += text def getanchortext(self, type): "Get the text for the anchor given to a layout type." if self.generator.isunique(type): return self.tocentry + '.' return self.number def getfilename(self, type): "Get the filename to be used if splitpart is active." if self.level == Options.splitpart and self.generator.isnumbered(type): return self.number if self.level <= Options.splitpart: return self.partkey.replace('toc-', '') return None def needspartkey(self, layout): "Find out if a layout needs a part key." if self.generator.isunique(layout.type): return True return self.generator.isinordered(layout.type) def __unicode__(self): "Get a printable representation." return 'Part key for layout ' + self.tocentry class PartKeyGenerator(object): "Number a layout with the relevant attributes." partkeyed = [] layoutpartkey = LayoutPartKey() def forlayout(cls, layout): "Get the part key for a layout." if layout.hasemptyoutput(): return None if not cls.layoutpartkey.needspartkey(layout): return None Label.lastlayout = layout cls.partkeyed.append(layout) return LayoutPartKey().create(layout) def forindex(cls, index): "Get the part key for an index or nomenclature." if index.hasemptyoutput(): return None cls.partkeyed.append(index) return PartKey().createindex(index.name) forlayout = classmethod(forlayout) forindex = classmethod(forindex) elyxer-1.2.5/forks/jras-elyxer/src/elyxer/ref/link.py0000644000175000017500000000705412117061342022113 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20090218 # eLyXer links from elyxer.util.trace import Trace from elyxer.util.translate import * from elyxer.parse.parser import * from elyxer.out.output import * from elyxer.gen.container import * from elyxer.gen.styles import * class Link(Container): "A link to another part of the document" anchor = None url = None type = None page = None target = None destination = None title = None def __init__(self): "Initialize the link, add target if configured." self.contents = [] self.parser = InsetParser() self.output = LinkOutput() if Options.target: self.target = Options.target def complete(self, text, anchor = None, url = None, type = None, title = None): "Complete the link." self.contents = [Constant(text)] if anchor: self.anchor = anchor if url: self.url = url if type: self.type = type if title: self.title = title return self def computedestination(self): "Use the destination link to fill in the destination URL." if not self.destination: return self.url = '' if self.destination.anchor: self.url = '#' + self.destination.anchor if self.destination.page: self.url = self.destination.page + self.url def setmutualdestination(self, destination): "Set another link as destination, and set its destination to this one." self.destination = destination destination.destination = self def __unicode__(self): "Return a printable representation." result = 'Link' if self.anchor: result += ' #' + self.anchor if self.url: result += ' to ' + self.url return result class URL(Link): "A clickable URL" def process(self): "Read URL from elyxer.parameters" target = self.escape(self.getparameter('target')) self.url = target type = self.getparameter('type') if type: self.url = self.escape(type) + target name = self.getparameter('name') if not name: name = target self.contents = [Constant(name)] class FlexURL(URL): "A flexible URL" def process(self): "Read URL from elyxer.contents" self.url = self.extracttext() class LinkOutput(ContainerOutput): "A link pointing to some destination" "Or an anchor (destination)" def gethtml(self, link): "Get the HTML code for the link" type = link.__class__.__name__ if link.type: type = link.type tag = 'a class="' + type + '"' if link.anchor: tag += ' name="' + link.anchor + '"' if link.destination: link.computedestination() if link.url: tag += ' href="' + link.url + '"' if link.target: tag += ' target="' + link.target + '"' if link.title: tag += ' title="' + link.title + '"' return TaggedOutput().settag(tag).gethtml(link) elyxer-1.2.5/forks/jras-elyxer/src/elyxer/ref/label.py0000644000175000017500000001051012117061342022224 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20090218 # eLyXer labels from elyxer.util.trace import Trace from elyxer.parse.parser import * from elyxer.out.output import * from elyxer.gen.container import * from elyxer.gen.styles import * from elyxer.ref.link import * from elyxer.proc.postprocess import * class Label(Link): "A label to be referenced" names = dict() lastlayout = None def __init__(self): Link.__init__(self) self.lastnumbered = None def process(self): "Process a label container." key = self.getparameter('name') self.create(' ', key) self.lastnumbered = Label.lastlayout def create(self, text, key, type = 'Label'): "Create the label for a given key." self.key = key self.complete(text, anchor = key, type = type) Label.names[key] = self if key in Reference.references: for reference in Reference.references[key]: reference.destination = self return self def findpartkey(self): "Get the part key for the latest numbered container seen." numbered = self.numbered(self) if numbered and numbered.partkey: return numbered.partkey return '' def numbered(self, container): "Get the numbered container for the label." if container.partkey: return container if not container.parent: if self.lastnumbered: return self.lastnumbered return None return self.numbered(container.parent) def __unicode__(self): "Return a printable representation." if not hasattr(self, 'key'): return 'Unnamed label' return 'Label ' + self.key class Reference(Link): "A reference to a label." references = dict() key = 'none' def process(self): "Read the reference and set the arrow." self.key = self.getparameter('reference') if self.key in Label.names: self.direction = u'↑' label = Label.names[self.key] else: self.direction = u'↓' label = Label().complete(' ', self.key, 'preref') self.destination = label self.formatcontents() if not self.key in Reference.references: Reference.references[self.key] = [] Reference.references[self.key].append(self) def formatcontents(self): "Format the reference contents." formatkey = self.getparameter('LatexCommand') if not formatkey: formatkey = 'ref' self.formatted = u'↕' if formatkey in StyleConfig.referenceformats: self.formatted = StyleConfig.referenceformats[formatkey] else: Trace.error('Unknown reference format ' + formatkey) self.replace(u'↕', self.direction) self.replace('#', '1') self.replace('on-page', Translator.translate('on-page')) partkey = self.destination.findpartkey() # only if partkey and partkey.number are not null, send partkey.number self.replace('@', partkey and partkey.number) self.replace(u'¶', partkey and partkey.tocentry) if not '$' in self.formatted or not partkey or not partkey.titlecontents: # there is a $ left, but it should go away on preprocessing self.contents = [Constant(self.formatted)] return pieces = self.formatted.split('$') self.contents = [Constant(pieces[0])] for piece in pieces[1:]: self.contents += partkey.titlecontents self.contents.append(Constant(piece)) def replace(self, key, value): "Replace a key in the format template with a value." if not key in self.formatted: return if not value: value = '' self.formatted = self.formatted.replace(key, value) def __unicode__(self): "Return a printable representation." return 'Reference ' + self.key elyxer-1.2.5/forks/jras-elyxer/src/elyxer/ref/index.py0000644000175000017500000002016612117061342022264 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20100713 # eLyXer: indexing entries from elyxer.util.trace import Trace from elyxer.util.translate import * from elyxer.parse.parser import * from elyxer.out.output import * from elyxer.gen.container import * from elyxer.gen.styles import * from elyxer.ref.link import * from elyxer.ref.partkey import * from elyxer.proc.process import * class ListInset(Container): "An inset with a list, normally made of links." def __init__(self): self.parser = InsetParser() self.output = ContentsOutput() def sortdictionary(self, dictionary): "Sort all entries in the dictionary" keys = dictionary.keys() # sort by name keys.sort() return keys sortdictionary = classmethod(sortdictionary) class ListOf(ListInset): "A list of entities (figures, tables, algorithms)" def process(self): "Parse the header and get the type" self.type = self.header[2] text = Translator.translate('list-' + self.type) self.contents = [TaggedText().constant(text, 'div class="tocheader"', True)] class TableOfContents(ListInset): "Table of contents" def process(self): "Parse the header and get the type" self.create(Translator.translate('toc')) def create(self, heading): "Create a table of contents with the given heading text." self.output = TaggedOutput().settag('div class="fulltoc"', True) self.contents = [TaggedText().constant(heading, 'div class="tocheader"', True)] return self def add(self, entry): "Add a new entry to the TOC." if entry: self.contents.append(entry) class IndexReference(Link): "A reference to an entry in the alphabetical index." name = 'none' def process(self): "Put entry in index" name = self.getparameter('name') if name: self.name = name.strip() else: self.name = self.extracttext() IndexEntry.get(self.name).addref(self) def __unicode__(self): "Return a printable representation." return 'Reference to ' + self.name class IndexHeader(Link): "The header line for an index entry. Keeps all arrows." keyescapes = {'!':'', '|':'-', ' ':'-', '--':'-', ',':'', '\\':'', '@':'_', u'°':''} def create(self, names): "Create the header for the given index entry." self.output = TaggedOutput().settag('p class="printindex"', True) self.name = names[-1] keys = [self.escape(part, self.keyescapes) for part in names] self.key = '-'.join(keys) self.anchor = Link().complete('', 'index-' + self.key, None, 'printindex') self.contents = [self.anchor, Constant(self.name + ': ')] self.arrows = [] return self def addref(self, reference): "Create an arrow pointing to a reference." reference.index = unicode(len(self.arrows)) reference.destination = self.anchor reference.complete(u'↓', 'entry-' + self.key + '-' + reference.index) arrow = Link().complete(u'↑', type = 'IndexArrow') arrow.destination = reference if len(self.arrows) > 0: self.contents.append(Constant(u', ')) self.arrows.append(arrow) self.contents.append(arrow) def __unicode__(self): "Return a printable representation." return 'Index header for ' + self.name class IndexGroup(Container): "A group of entries in the alphabetical index, for an entry." root = None def create(self): "Create an index group." self.entries = dict() self.output = EmptyOutput() return self def findentry(self, names): "Find the entry with the given names." if self == IndexGroup.root: self.output = ContentsOutput() else: self.output = TaggedOutput().settag('div class="indexgroup"', True) lastname = names[-1] if not lastname in self.entries: self.entries[lastname] = IndexEntry().create(names) return self.entries[lastname] def sort(self): "Sort all entries in the group." for key in ListInset.sortdictionary(self.entries): entry = self.entries[key] entry.group.sort() self.contents.append(entry) def __unicode__(self): "Return a printable representation." return 'Index group' IndexGroup.root = IndexGroup().create() class IndexEntry(Container): "An entry in the alphabetical index." "When an index entry is of the form 'part1 ! part2 ...', " "a hierarchical structure in the form of an IndexGroup is constructed." "An index entry contains a mandatory header, and an optional group." def create(self, names): "Create an index entry with the given name." self.output = ContentsOutput() self.header = IndexHeader().create(names) self.group = IndexGroup().create() self.contents = [self.header, self.group] return self def addref(self, reference): "Add a reference to the entry." self.header.addref(reference) def get(cls, name): "Get the index entry for the given name." group = IndexGroup.root parts = IndexEntry.splitname(name) readparts = [] for part in parts: readparts.append(part) entry = group.findentry(readparts) group = entry.group return entry def splitname(cls, name): "Split a name in parts divided by !." return [part.strip() for part in name.split('!')] def __unicode__(self): "Return a printable representation." return 'Index entry for ' + self.header.name get = classmethod(get) splitname = classmethod(splitname) class PrintIndex(ListInset): "Command to print an index" def process(self): "Create the alphabetic index" self.name = Translator.translate('index') self.partkey = PartKeyGenerator.forindex(self) if not self.partkey: return self.contents = [TaggedText().constant(self.name, 'h1 class="index"')] self.partkey.addtoclabel(self) IndexGroup.root.sort() self.contents.append(IndexGroup.root) class NomenclatureEntry(Link): "An entry of LyX nomenclature" entries = dict() def process(self): "Put entry in index" symbol = self.getparameter('symbol') description = self.getparameter('description') key = symbol.replace(' ', '-').lower() if key in NomenclatureEntry.entries: Trace.error('Duplicated nomenclature entry ' + key) self.complete(u'↓', 'noment-' + key) entry = Link().complete(u'↑', 'nom-' + key) entry.symbol = symbol entry.description = description self.setmutualdestination(entry) NomenclatureEntry.entries[key] = entry class PrintNomenclature(ListInset): "Print all nomenclature entries" def process(self): "Create the nomenclature." self.name = Translator.translate('nomenclature') self.partkey = PartKeyGenerator.forindex(self) if not self.partkey: return self.contents = [TaggedText().constant(self.name, 'h1 class="nomenclature"')] self.partkey.addtoclabel(self) for key in self.sortdictionary(NomenclatureEntry.entries): entry = NomenclatureEntry.entries[key] contents = [entry, Constant(entry.symbol + u' ' + entry.description)] text = TaggedText().complete(contents, 'div class="Nomenclated"', True) self.contents.append(text) class PreListInset(object): "Preprocess any container that contains a list inset." def preprocess(self, container): "Preprocess a container, extract any list inset and return it." listinsets = container.searchall(ListInset) if len(listinsets) == 0: return container if len(container.contents) > 1: return container return listinsets[0] Processor.prestages += [PreListInset()] elyxer-1.2.5/forks/jras-elyxer/src/elyxer/ref/__init__.py0000644000175000017500000000000012117061342022675 0ustar chennochennoelyxer-1.2.5/forks/jras-elyxer/src/elyxer/tex/0000755000175000017500000000000012117061342020622 5ustar chennochennoelyxer-1.2.5/forks/jras-elyxer/src/elyxer/tex/texcode.py0000644000175000017500000001303712117061342022633 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20110105 # eLyXer TeX (LyX ERT) parser. from elyxer.util.trace import Trace from elyxer.util.clone import * from elyxer.conf.config import * from elyxer.parse.position import * from elyxer.gen.layout import * from elyxer.maths.formula import * from elyxer.maths.command import * class ERT(FirstWord): "Evil Red Text: embedded TeX code." "Considered as a first word for descriptions." def __init__(self): self.parser = InsetParser() self.output = ContentsOutput() def process(self): "Process all TeX code, formulas, commands." text = '' separator = '' for container in self.contents: text += separator + container.extracttext() separator = '\n' pos = TextPosition(text) pos.leavepending = True code = TeXCode() code.parse(pos) self.contents = [code] def isempty(self): "Find out if the ERT is empty or not." if len(self.contents) == 0: return True if len(self.contents) > 1: Trace.error('Unknown ERT length 2') return False texcode = self.contents[0] return len(texcode.contents) == 0 class TeXCode(Container): "A parser and processor for TeX code." texseparators = ['{', '\\', '}', '$', '%'] replaced = BibTeXConfig.replaced factory = FormulaFactory() endinglist = EndingList() def __init__(self): self.contents = [] self.output = ContentsOutput() def parse(self, pos): "Parse some TeX code." self.parserecursive(pos) if pos.leavepending: self.endinglist.pickpending(pos) def findlaststring(self): "Find the last string in the contents." if len(self.contents) == 0: return None string = self.contents[-1] if not isinstance(string, StringContainer): return None return string def add(self, piece): "Add a new piece to the tag." if isinstance(piece, basestring): self.addtext(piece) else: self.contents.append(piece) def addtext(self, piece): "Add a text string to the tag." last = self.findlaststring() if last: last.string += piece return self.contents.append(Constant(piece)) def parserecursive(self, pos): "Parse brackets or quotes recursively." while not pos.finished(): self.parsetext(pos) if pos.finished(): return elif pos.checkfor('{'): self.parseopenbracket(pos) elif pos.checkfor('}'): self.parseclosebracket(pos) elif pos.checkfor('\\'): self.parseescaped(pos) elif pos.checkfor('$'): self.parseformula(pos) elif pos.checkfor('%'): self.parsecomment(pos) else: pos.error('Unexpected character ' + pos.current()) pos.skipcurrent() def parsetext(self, pos): "Parse a bit of text, excluding separators and compressing spaces." text = self.parsecompressingspace(pos) if text == '': return for key in self.replaced: if key in text: text = text.replace(key, self.replaced[key]) self.add(text) def parsecompressingspace(self, pos): "Parse some text excluding value separators and compressing spaces." parsed = '' while not pos.finished(): parsed += pos.glob(lambda: self.excludespaces(pos)) if not pos.finished() and pos.current().isspace(): parsed += ' ' pos.skipspace() else: return parsed return parsed def excludespaces(self, pos): "Exclude value separators and spaces." current = pos.current() if current in self.texseparators: return False if current.isspace(): return False return True def parseescaped(self, pos): "Parse an escaped string \\*." if pos.checkfor('\\(') or pos.checkfor('\\['): # start of formula commands self.parseformula(pos) return if not self.factory.detecttype(FormulaCommand, pos): pos.error('Not an escape sequence') return self.add(self.factory.parsetype(FormulaCommand, pos)) def parseopenbracket(self, pos): "Parse a { bracket." if not pos.checkskip('{'): pos.error('Missing opening { bracket') return pos.pushending('}') self.parserecursive(pos) pos.popending('}') def parseclosebracket(self, pos): "Parse a } bracket." ending = self.endinglist.findending(pos) if not ending: Trace.error('Unexpected closing } bracket') else: self.endinglist.pop(pos) if not pos.checkskip('}'): pos.error('Missing closing } bracket') return def parseformula(self, pos): "Parse a whole formula." formula = Formula().parse(pos) self.add(formula) def parsecomment(self, pos): "Parse a TeX comment: % to the end of the line." pos.globexcluding('\n') def __unicode__(self): "Return a printable representation." return 'TeX code: ' + self.extracttext() elyxer-1.2.5/forks/jras-elyxer/src/elyxer/tex/__init__.py0000644000175000017500000000000012117061342022721 0ustar chennochennoelyxer-1.2.5/forks/jras-elyxer/src/elyxer/xtra/0000755000175000017500000000000012117061342021000 5ustar chennochennoelyxer-1.2.5/forks/jras-elyxer/src/elyxer/xtra/newfangle.py0000644000175000017500000001714412117061342023327 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20100201 # LyX literate programming with the newfangle module. from elyxer.util.trace import Trace from elyxer.util.numbering import * from elyxer.gen.container import * from elyxer.gen.layout import * from elyxer.gen.inset import * from elyxer.gen.float import * from elyxer.ref.label import * class NewfangledChunk(Layout): "A chunk of literate programming." names = dict() firsttime = True def process(self): "Process the literate chunk." self.output.tag = 'div class="chunk"' self.type = 'chunk' text = self.extracttext() parts = text.split(',') if len(parts) < 1: Trace.error('Not enough parameters in ' + text) return self.name = parts[0] self.number = self.order() self.createlinks() self.contents = [self.left, self.declaration(), self.right] ChunkProcessor.lastchunk = self def order(self): "Create the order number for the chunk." return NumberGenerator.generator.generate('chunk') def createlinks(self): "Create back and forward links." self.leftlink = Link().complete(self.number, 'chunk:' + self.number, type='chunk') self.left = TaggedText().complete([self.leftlink], 'span class="chunkleft"', False) self.right = TaggedText().constant('', 'span class="chunkright"', False) if not self.name in NewfangledChunk.names: NewfangledChunk.names[self.name] = [] else: last = NewfangledChunk.names[self.name][-1] forwardlink = Link().complete(self.number + u'→', 'chunkback:' + last.number, type='chunk') backlink = Link().complete(u'←' + last.number + u' ', 'chunkforward:' + self.number, type='chunk') forwardlink.setmutualdestination(backlink) last.right.contents.append(forwardlink) self.right.contents.append(backlink) NewfangledChunk.names[self.name].append(self) self.origin = self.createorigin() if self.name in NewfangledChunkRef.references: for ref in NewfangledChunkRef.references[self.name]: self.linkorigin(ref.origin) def createorigin(self): "Create a link that points to the chunks' origin." link = Link() self.linkorigin(link) return link def linkorigin(self, link): "Create a link to the origin." start = NewfangledChunk.names[self.name][0] link.complete(start.number, type='chunk') link.destination = start.leftlink link.computedestination() def declaration(self): "Get the chunk declaration." contents = [] text = u'⟨' + self.name + '[' + unicode(len(NewfangledChunk.names[self.name])) + '] ' contents.append(Constant(text)) contents.append(self.origin) text = '' if NewfangledChunk.firsttime: Listing.processor = ChunkProcessor() NewfangledChunk.firsttime = False text += u'⟩' if len(NewfangledChunk.names[self.name]) > 1: text += '+' text += u'≡' contents.append(Constant(text)) return TaggedText().complete(contents, 'span class="chunkdecl"', True) class ChunkProcessor(object): "A processor for listings that belong to chunks." lastchunk = None counters = dict() endcommand = '}' chunkref = 'chunkref' def preprocess(self, listing): "Preprocess a listing: set the starting counter." if not ChunkProcessor.lastchunk: return name = ChunkProcessor.lastchunk.name if not name in ChunkProcessor.counters: ChunkProcessor.counters[name] = 0 listing.counter = ChunkProcessor.counters[name] for command, container, index in self.commandsinlisting(listing): chunkref = self.getchunkref(command) if chunkref: self.insertchunkref(chunkref, container, index) def commandsinlisting(self, listing): "Find all newfangle commands in a listing." for container in listing.contents: for index in range(len(container.contents) - 2): if self.findinelement(container, index): third = container.contents[index + 2].string end = third.index(NewfangleConfig.constants['endmark']) command = third[:end] lenstart = len(NewfangleConfig.constants['startmark']) container.contents[index].string = container.contents[index].string[:-lenstart] del container.contents[index + 1] container.contents[index + 1].string = third[end + len(NewfangleConfig.constants['endmark']):] yield command, container, index def findinelement(self, container, index): "Find a newfangle command in an element." for i in range(2): if not isinstance(container.contents[index + i], StringContainer): return False first = container.contents[index].string second = container.contents[index + 1].string third = container.contents[index + 2].string if not first.endswith(NewfangleConfig.constants['startmark']): return False if second != NewfangleConfig.constants['startcommand']: return False if not NewfangleConfig.constants['endmark'] in third: return False return True def getchunkref(self, command): "Get the contents of a chunkref command, if present." if not command.startswith(NewfangleConfig.constants['chunkref']): return None if not NewfangleConfig.constants['endcommand'] in command: return None start = len(NewfangleConfig.constants['chunkref']) end = command.index(NewfangleConfig.constants['endcommand']) return command[start:end] def insertchunkref(self, ref, container, index): "Insert a chunkref after the given index at the given container." chunkref = NewfangledChunkRef().complete(ref) container.contents.insert(index + 1, chunkref) def postprocess(self, listing): "Postprocess a listing: store the ending counter for next chunk." if not ChunkProcessor.lastchunk: return ChunkProcessor.counters[ChunkProcessor.lastchunk.name] = listing.counter class NewfangledChunkRef(Inset): "A reference to a chunk." references = dict() def process(self): "Show the reference." self.output.tag = 'span class="chunkref"' self.ref = self.extracttext() self.addbits() def complete(self, ref): "Complete the reference to the given string." self.output = ContentsOutput() self.ref = ref self.contents = [Constant(self.ref)] self.addbits() return self def addbits(self): "Add the bits to the reference." if not self.ref in NewfangledChunkRef.references: NewfangledChunkRef.references[self.ref] = [] NewfangledChunkRef.references[self.ref].append(self) if self.ref in NewfangledChunk.names: start = NewfangledChunk.names[self.ref][0] self.origin = start.createorigin() else: self.origin = Link() self.contents.insert(0, Constant(u'⟨')) self.contents.append(Constant(' ')) self.contents.append(self.origin) self.contents.append(Constant(u'⟩')) def __unicode__(self): "Return a printable representation." return 'Reference to chunk ' + self.ref elyxer-1.2.5/forks/jras-elyxer/src/elyxer/xtra/__init__.py0000644000175000017500000000000012117061342023077 0ustar chennochennoelyxer-1.2.5/forks/jras-elyxer/src/elyxer/io/0000755000175000017500000000000012117175142020435 5ustar chennochennoelyxer-1.2.5/forks/jras-elyxer/src/elyxer/io/path.py0000644000175000017500000000636412117061342021750 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20090905 # Path manipulations import os import os.path import codecs from elyxer.util.options import Options from elyxer.util.trace import Trace class Path(object): "Represents a generic path" def exists(self): "Check if the file exists" return os.path.exists(self.path) def open(self): "Open the file as readonly binary" return codecs.open(self.path, 'rb') def getmtime(self): "Return last modification time" return os.path.getmtime(self.path) def hasexts(self, exts): "Check if the file has one of the given extensions." for ext in exts: if self.hasext(ext): return True return False def hasext(self, ext): "Check if the file has the given extension" return self.getext() == ext def getext(self): "Get the current extension of the file." base, ext = os.path.splitext(self.path) return ext def __unicode__(self): "Return a unicode string representation" return self.path def __eq__(self, path): "Compare to another path" if not hasattr(path, 'path'): return False return self.path == path.path class InputPath(Path): "Represents an input file" def __init__(self, url): "Create the input path based on url" self.url = url self.path = url if not os.path.isabs(url): self.path = os.path.join(Options.directory, url) class OutputPath(Path): "Represents an output file" def __init__(self, inputpath): "Create the output path based on an input path" self.url = inputpath.url if os.path.isabs(self.url): self.url = os.path.basename(self.url) self.path = os.path.join(Options.destdirectory, self.url) def changeext(self, ext): "Change extension to the given one" base, oldext = os.path.splitext(self.path) self.path = base + ext base, oldext = os.path.splitext(self.url) self.url = base + ext def exists(self): "Check if the file exists" return os.path.exists(self.path) def createdirs(self): "Create any intermediate directories that don't exist" dir = os.path.dirname(self.path) if len(dir) > 0 and not os.path.exists(dir): os.makedirs(dir) def removebackdirs(self): "Remove any occurrences of ../ (or ..\ on Windows)" self.path = os.path.normpath(self.path) backdir = '..' + os.path.sep while self.path.startswith(backdir): self.path = self.path[len(backdir):] while self.url.startswith('../'): self.url = self.url[len('../'):] elyxer-1.2.5/forks/jras-elyxer/src/elyxer/io/fileline.py0000644000175000017500000000700712117061342022576 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20090308 # File line management for eLyXer import sys import codecs from elyxer.util.trace import Trace class LineReader(object): "Reads a file line by line" def __init__(self, filename): if isinstance(filename, file): self.file = filename else: self.file = codecs.open(filename, 'rU', 'utf-8') self.linenumber = 1 self.lastline = None self.current = None self.mustread = True self.depleted = False try: self.readline() except UnicodeDecodeError: # try compressed file import gzip self.file = gzip.open(filename, 'rb') self.readline() def setstart(self, firstline): "Set the first line to read." for i in range(firstline): self.file.readline() self.linenumber = firstline def setend(self, lastline): "Set the last line to read." self.lastline = lastline def currentline(self): "Get the current line" if self.mustread: self.readline() return self.current def nextline(self): "Go to next line" if self.depleted: Trace.fatal('Read beyond file end') self.mustread = True def readline(self): "Read a line from elyxer.file" self.current = self.file.readline() if not isinstance(self.file, codecs.StreamReaderWriter): self.current = self.current.decode('utf-8') if len(self.current) == 0: self.depleted = True self.current = self.current.rstrip('\n\r') self.linenumber += 1 self.mustread = False Trace.prefix = 'Line ' + unicode(self.linenumber) + ': ' if self.linenumber % 1000 == 0: Trace.message('Parsing') def finished(self): "Find out if the file is finished" if self.lastline and self.linenumber == self.lastline: return True if self.mustread: self.readline() return self.depleted def close(self): self.file.close() class LineWriter(object): "Writes a file as a series of lists" file = False def __init__(self, filename): if isinstance(filename, file): self.file = filename self.filename = None else: self.filename = filename def write(self, strings): "Write a list of strings" for string in strings: if not isinstance(string, basestring): Trace.error('Not a string: ' + unicode(string) + ' in ' + unicode(strings)) return self.writestring(string) def writestring(self, string): "Write a string" if not self.file: self.file = codecs.open(self.filename, 'w', "utf-8") if self.file == sys.stdout and sys.version_info < (3,0): string = string.encode('utf-8') self.file.write(string) def writeline(self, line): "Write a line to file" self.writestring(line + '\n') def close(self): self.file.close() elyxer-1.2.5/forks/jras-elyxer/src/elyxer/io/bulk.py0000644000175000017500000000410312117061342021736 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20090416 # Bulk file processing import os import codecs from elyxer.io.fileline import * from elyxer.util.trace import Trace class BulkFile(object): "A file to treat in bulk" encodings = ['utf-8','Cp1252'] def __init__(self, filename): self.filename = filename self.temp = self.filename + '.temp' def readall(self): "Read the whole file" for encoding in BulkFile.encodings: try: return self.readcodec(encoding) except UnicodeDecodeError: pass Trace.error('No suitable encoding for ' + self.filename) return [] def readcodec(self, encoding): "Read the whole file with the given encoding" filein = codecs.open(self.filename, 'rU', encoding) lines = filein.readlines() result = [] for line in lines: result.append(line.strip('\r\n') + '\n') filein.close() return result def getfiles(self): "Get reader and writer for a file name" reader = LineReader(self.filename) writer = LineWriter(self.temp) return reader, writer def swaptemp(self): "Swap the temp file for the original" os.chmod(self.temp, os.stat(self.filename).st_mode) os.rename(self.temp, self.filename) def __unicode__(self): "Get the unicode representation" return 'file ' + self.filename elyxer-1.2.5/forks/jras-elyxer/src/elyxer/io/__init__.py0000644000175000017500000000000012117061342022530 0ustar chennochennoelyxer-1.2.5/forks/jras-elyxer/src/elyxer/util/0000755000175000017500000000000012117175142021003 5ustar chennochennoelyxer-1.2.5/forks/jras-elyxer/src/elyxer/util/options.py0000644000175000017500000002430212117061342023045 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20090313 # eLyXer runtime options import os.path import sys from elyxer.conf.config import * from elyxer.util.trace import * from elyxer.util.clparse import * class Options(object): "A set of runtime options" instance = None location = None nocopy = False copyright = False debug = False quiet = False version = False hardversion = False versiondate = False html = False help = False showlines = True unicode = False iso885915 = False css = [] title = None directory = None destdirectory = None toc = False toctarget = '' tocfor = None forceformat = None lyxformat = False target = None splitpart = None memory = True lowmem = False nobib = False converter = 'imagemagick' raw = False jsmath = None mathjax = None nofooter = False simplemath = False template = None noconvert = False notoclabels = False letterfoot = True numberfoot = False symbolfoot = False hoverfoot = True marginfoot = False endfoot = False supfoot = True alignfoot = False footnotes = None imageformat = None copyimages = False googlecharts = False embedcss = [] branches = dict() def parseoptions(self, args): "Parse command line options" Options.location = args[0] del args[0] parser = CommandLineParser(Options) result = parser.parseoptions(args) if result: Trace.error(result) self.usage() self.processoptions() def processoptions(self): "Process all options parsed." if Options.help: self.usage() if Options.version: self.showversion() if Options.hardversion: self.showhardversion() if Options.versiondate: self.showversiondate() if Options.lyxformat: self.showlyxformat() if Options.splitpart: try: Options.splitpart = int(Options.splitpart) if Options.splitpart <= 0: Trace.error('--splitpart requires a number bigger than zero') self.usage() except: Trace.error('--splitpart needs a numeric argument, not ' + Options.splitpart) self.usage() if Options.lowmem or Options.toc or Options.tocfor: Options.memory = False self.parsefootnotes() if Options.forceformat and not Options.imageformat: Options.imageformat = Options.forceformat if Options.imageformat == 'copy': Options.copyimages = True if Options.css == []: Options.css = ['http://elyxer.nongnu.org/lyx.css'] if Options.html: Options.simplemath = True if Options.toc and not Options.tocfor: Trace.error('Option --toc is deprecated; use --tocfor "page" instead') Options.tocfor = Options.toctarget if Options.nocopy: Trace.error('Option --nocopy is deprecated; it is no longer needed') if Options.jsmath: Trace.error('Option --jsmath is deprecated; use --mathjax instead') # set in Trace if necessary for param in dir(Trace): if param.endswith('mode'): setattr(Trace, param, getattr(self, param[:-4])) def usage(self): "Show correct usage" Trace.error('Usage: ' + os.path.basename(Options.location) + ' [options] [filein] [fileout]') Trace.error('Convert LyX input file "filein" to HTML file "fileout".') Trace.error('If filein (or fileout) is not given use standard input (or output).') Trace.error('Main program of the eLyXer package (http://elyxer.nongnu.org/).') self.showoptions() def parsefootnotes(self): "Parse footnotes options." if not Options.footnotes: return Options.marginfoot = False Options.letterfoot = False Options.hoverfoot = False options = Options.footnotes.split(',') for option in options: footoption = option + 'foot' if hasattr(Options, footoption): setattr(Options, footoption, True) else: Trace.error('Unknown footnotes option: ' + option) if not Options.endfoot and not Options.marginfoot and not Options.hoverfoot: Options.hoverfoot = True if not Options.numberfoot and not Options.symbolfoot: Options.letterfoot = True def showoptions(self): "Show all possible options" Trace.error(' Common options:') Trace.error(' --help: show this online help') Trace.error(' --quiet: disables all runtime messages') Trace.error('') Trace.error(' Advanced options:') Trace.error(' --debug: enable debugging messages (for developers)') Trace.error(' --version: show version number and release date') Trace.error(' --lyxformat: return the highest LyX version supported') Trace.error(' Options for HTML output:') Trace.error(' --title "title": set the generated page title') Trace.error(' --css "file.css": use a custom CSS file') Trace.error(' --embedcss "file.css": embed styles from a CSS file into the output') Trace.error(' --html: output HTML 4.0 instead of the default XHTML') Trace.error(' --unicode: full Unicode output') Trace.error(' --iso885915: output a document with ISO-8859-15 encoding') Trace.error(' --nofooter: remove the footer "generated by eLyXer"') Trace.error(' --simplemath: do not generate fancy math constructions') Trace.error(' Options for image output:') Trace.error(' --directory "img_dir": look for images in the specified directory') Trace.error(' --destdirectory "dest": put converted images into this directory') Trace.error(' --imageformat ".ext": image output format, or "copy" to copy images') Trace.error(' --noconvert: do not convert images, use in original locations') Trace.error(' --converter "inkscape": use an alternative program to convert images') Trace.error(' Options for footnote display:') Trace.error(' --numberfoot: mark footnotes with numbers instead of letters') Trace.error(' --symbolfoot: mark footnotes with symbols (*, **...)') Trace.error(' --hoverfoot: show footnotes as hovering text (default)') Trace.error(' --marginfoot: show footnotes on the page margin') Trace.error(' --endfoot: show footnotes at the end of the page') Trace.error(' --supfoot: use superscript for footnote markers (default)') Trace.error(' --alignfoot: use aligned text for footnote markers') Trace.error(' --footnotes "options": specify several comma-separated footnotes options') Trace.error(' Available options are: "number", "symbol", "hover", "margin", "end",') Trace.error(' "sup", "align"') Trace.error(' Advanced output options:') Trace.error(' --splitpart "depth": split the resulting webpage at the given depth') Trace.error(' --tocfor "page": generate a TOC that points to the given page') Trace.error(' --target "frame": make all links point to the given frame') Trace.error(' --notoclabels: omit the part labels in the TOC, such as Chapter') Trace.error(' --lowmem: do the conversion on the fly (conserve memory)') Trace.error(' --raw: generate HTML without header or footer.') Trace.error(' --mathjax remote: use MathJax remotely to display equations') Trace.error(' --mathjax "URL": use MathJax from the given URL to display equations') Trace.error(' --googlecharts: use Google Charts to generate formula images') Trace.error(' --template "file": use a template, put everything in ') Trace.error(' --copyright: add a copyright notice at the bottom') Trace.error(' Deprecated options:') Trace.error(' --toc: (deprecated) create a table of contents') Trace.error(' --toctarget "page": (deprecated) generate a TOC for the given page') Trace.error(' --nocopy: (deprecated) maintained for backwards compatibility') Trace.error(' --jsmath "URL": use jsMath from the given URL to display equations') sys.exit() def showversion(self): "Return the current eLyXer version string" string = 'eLyXer version ' + GeneralConfig.version['number'] string += ' (' + GeneralConfig.version['date'] + ')' Trace.error(string) sys.exit() def showhardversion(self): "Return just the version string" Trace.message(GeneralConfig.version['number']) sys.exit() def showversiondate(self): "Return just the version dte" Trace.message(GeneralConfig.version['date']) sys.exit() def showlyxformat(self): "Return just the lyxformat parameter" Trace.message(GeneralConfig.version['lyxformat']) sys.exit() class BranchOptions(object): "A set of options for a branch" def __init__(self, name): self.name = name self.options = {'color':'#ffffff'} def set(self, key, value): "Set a branch option" if not key.startswith(ContainerConfig.string['startcommand']): Trace.error('Invalid branch option ' + key) return key = key.replace(ContainerConfig.string['startcommand'], '') self.options[key] = value def isselected(self): "Return if the branch is selected" if not 'selected' in self.options: return False return self.options['selected'] == '1' def __unicode__(self): "String representation" return 'options for ' + self.name + ': ' + unicode(self.options) elyxer-1.2.5/forks/jras-elyxer/src/elyxer/util/clone.py0000644000175000017500000000551012117061342022452 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20091101 # eLyXer object cloning from elyxer.util.trace import Trace class Cloner(object): "An object used to clone other objects." def clone(cls, original): "Return an exact copy of an object." "The original object must have an empty constructor." return cls.create(original.__class__) def create(cls, type): "Create an object of a given class." clone = type.__new__(type) clone.__init__() return clone clone = classmethod(clone) create = classmethod(create) class ContainerExtractor(object): "A class to extract certain containers." def __init__(self, config): "The config parameter is a map containing three lists: allowed, copied and extracted." "Each of the three is a list of class names for containers." "Allowed containers are included as is into the result." "Cloned containers are cloned and placed into the result." "Extracted containers are looked into." "All other containers are silently ignored." self.allowed = config['allowed'] self.cloned = config['cloned'] self.extracted = config['extracted'] def extract(self, container): "Extract a group of selected containers from elyxer.a container." list = [] locate = lambda c: c.__class__.__name__ in self.allowed + self.cloned recursive = lambda c: c.__class__.__name__ in self.extracted process = lambda c: self.process(c, list) container.recursivesearch(locate, recursive, process) return list def process(self, container, list): "Add allowed containers, clone cloned containers and add the clone." name = container.__class__.__name__ if name in self.allowed: list.append(container) elif name in self.cloned: list.append(self.safeclone(container)) else: Trace.error('Unknown container class ' + name) def safeclone(self, container): "Return a new container with contents only in a safe list, recursively." clone = Cloner.clone(container) clone.output = container.output clone.contents = self.extract(container) return clone elyxer-1.2.5/forks/jras-elyxer/src/elyxer/util/numbering.py0000644000175000017500000002050312117061342023337 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20090418 # eLyXer number generator from elyxer.util.trace import Trace from elyxer.util.translate import * from elyxer.util.docparams import * from elyxer.conf.config import * class NumberCounter(object): "A counter for numbers (by default)." "The type can be changed to return letters, roman numbers..." name = None value = None mode = None master = None letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' symbols = NumberingConfig.sequence['symbols'] romannumerals = [ ('M', 1000), ('CM', 900), ('D', 500), ('CD', 400), ('C', 100), ('XC', 90), ('L', 50), ('XL', 40), ('X', 10), ('IX', 9), ('V', 5), ('IV', 4), ('I', 1) ] def __init__(self, name): "Give a name to the counter." self.name = name def setmode(self, mode): "Set the counter mode. Can be changed at runtime." self.mode = mode return self def init(self, value): "Set an initial value." self.value = value def gettext(self): "Get the next value as a text string." return unicode(self.value) def getletter(self): "Get the next value as a letter." return self.getsequence(self.letters) def getsymbol(self): "Get the next value as a symbol." return self.getsequence(self.symbols) def getsequence(self, sequence): "Get the next value from elyxer.a sequence." return sequence[(self.value - 1) % len(sequence)] def getroman(self): "Get the next value as a roman number." result = '' number = self.value for numeral, value in self.romannumerals: if number >= value: result += numeral * (number / value) number = number % value return result def getvalue(self): "Get the current value as configured in the current mode." if not self.mode or self.mode in ['text', '1']: return self.gettext() if self.mode == 'A': return self.getletter() if self.mode == 'a': return self.getletter().lower() if self.mode == 'I': return self.getroman() if self.mode == '*': return self.getsymbol() Trace.error('Unknown counter mode ' + self.mode) return self.gettext() def getnext(self): "Increase the current value and get the next value as configured." if not self.value: self.value = 0 self.value += 1 return self.getvalue() def reset(self): "Reset the counter." self.value = 0 def __unicode__(self): "Return a printable representation." result = 'Counter ' + self.name if self.mode: result += ' in mode ' + self.mode return result class DependentCounter(NumberCounter): "A counter which depends on another one (the master)." def setmaster(self, master): "Set the master counter." self.master = master self.last = self.master.getvalue() return self def getnext(self): "Increase or, if the master counter has changed, restart." if self.last != self.master.getvalue(): self.reset() value = NumberCounter.getnext(self) self.last = self.master.getvalue() return value def getvalue(self): "Get the value of the combined counter: master.dependent." return self.master.getvalue() + '.' + NumberCounter.getvalue(self) class NumberGenerator(object): "A number generator for unique sequences and hierarchical structures. Used in:" " * ordered part numbers: Chapter 3, Section 5.3." " * unique part numbers: Footnote 15, Bibliography cite [15]." " * chaptered part numbers: Figure 3.15, Equation (8.3)." " * unique roman part numbers: Part I, Book IV." chaptered = None generator = None romanlayouts = [x.lower() for x in NumberingConfig.layouts['roman']] orderedlayouts = [x.lower() for x in NumberingConfig.layouts['ordered']] counters = dict() appendix = None def deasterisk(self, type): "Remove the possible asterisk in a layout type." return type.replace('*', '') def isunique(self, type): "Find out if the layout type corresponds to a unique part." return self.isroman(type) def isroman(self, type): "Find out if the layout type should have roman numeration." return self.deasterisk(type).lower() in self.romanlayouts def isinordered(self, type): "Find out if the layout type corresponds to an (un)ordered part." return self.deasterisk(type).lower() in self.orderedlayouts def isnumbered(self, type): "Find out if the type for a layout corresponds to a numbered layout." if '*' in type: return False if self.isroman(type): return True if not self.isinordered(type): return False if self.getlevel(type) > DocumentParameters.maxdepth: return False return True def isunordered(self, type): "Find out if the type contains an asterisk, basically." return '*' in type def getlevel(self, type): "Get the level that corresponds to a layout type." if self.isunique(type): return 0 if not self.isinordered(type): Trace.error('Unknown layout type ' + type) return 0 type = self.deasterisk(type).lower() level = self.orderedlayouts.index(type) + 1 return level - DocumentParameters.startinglevel def getparttype(self, type): "Obtain the type for the part: without the asterisk, " "and switched to Appendix if necessary." if NumberGenerator.appendix and self.getlevel(type) == 1: return 'Appendix' return self.deasterisk(type) def generate(self, type): "Generate a number for a layout type." "Unique part types such as Part or Book generate roman numbers: Part I." "Ordered part types return dot-separated tuples: Chapter 5, Subsection 2.3.5." "Everything else generates unique numbers: Bibliography [1]." "Each invocation results in a new number." return self.getcounter(type).getnext() def getcounter(self, type): "Get the counter for the given type." type = type.lower() if not type in self.counters: self.counters[type] = self.create(type) return self.counters[type] def create(self, type): "Create a counter for the given type." if self.isnumbered(type) and self.getlevel(type) > 1: index = self.orderedlayouts.index(type) above = self.orderedlayouts[index - 1] master = self.getcounter(above) return self.createdependent(type, master) counter = NumberCounter(type) if self.isroman(type): counter.setmode('I') return counter def getdependentcounter(self, type, master): "Get (or create) a counter of the given type that depends on another." if not type in self.counters or not self.counters[type].master: self.counters[type] = self.createdependent(type, master) return self.counters[type] def createdependent(self, type, master): "Create a dependent counter given the master." return DependentCounter(type).setmaster(master) def startappendix(self): "Start appendices here." firsttype = self.orderedlayouts[DocumentParameters.startinglevel] counter = self.getcounter(firsttype) counter.setmode('A').reset() NumberGenerator.appendix = True class ChapteredGenerator(NumberGenerator): "Generate chaptered numbers, as in Chapter.Number." "Used in equations, figures: Equation (5.3), figure 8.15." def generate(self, type): "Generate a number which goes with first-level numbers (chapters). " "For the article classes a unique number is generated." if DocumentParameters.startinglevel > 0: return NumberGenerator.generator.generate(type) chapter = self.getcounter('Chapter') return self.getdependentcounter(type, chapter).getnext() NumberGenerator.chaptered = ChapteredGenerator() NumberGenerator.generator = NumberGenerator() elyxer-1.2.5/forks/jras-elyxer/src/elyxer/util/clparse.py0000644000175000017500000000525712117061342023013 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20090416 # Command line option parser from elyxer.util.trace import * class CommandLineParser(object): "A parser for runtime options" def __init__(self, options): self.options = options def parseoptions(self, args): "Parse command line options" if len(args) == 0: return None while len(args) > 0 and args[0].startswith('--'): key, value = self.readoption(args) if not key: return 'Option ' + value + ' not recognized' if not value: return 'Option ' + key + ' needs a value' setattr(self.options, key, value) return None def readoption(self, args): "Read the key and value for an option" arg = args[0][2:] del args[0] if '=' in arg: key = self.readequalskey(arg, args) else: key = arg.replace('-', '') if not hasattr(self.options, key): return None, key current = getattr(self.options, key) if isinstance(current, bool): return key, True # read value if len(args) == 0: return key, None if args[0].startswith('"'): initial = args[0] del args[0] return key, self.readquoted(args, initial) value = args[0].decode('utf-8') del args[0] if isinstance(current, list): current.append(value) return key, current return key, value def readquoted(self, args, initial): "Read a value between quotes" Trace.error('Oops') value = initial[1:] while len(args) > 0 and not args[0].endswith('"') and not args[0].startswith('--'): Trace.error('Appending ' + args[0]) value += ' ' + args[0] del args[0] if len(args) == 0 or args[0].startswith('--'): return None value += ' ' + args[0:-1] return value def readequalskey(self, arg, args): "Read a key using equals" split = arg.split('=', 1) key = split[0] value = split[1] args.insert(0, value) return key elyxer-1.2.5/forks/jras-elyxer/src/elyxer/util/trace.py0000644000175000017500000000372612117061342022457 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20090131 # eLyXer trace library import sys class Trace(object): "A tracing class" debugmode = False quietmode = False showlinesmode = False prefix = None def debug(cls, message): "Show a debug message" if not Trace.debugmode or Trace.quietmode: return Trace.show(message, sys.stdout) def message(cls, message): "Show a trace message" if Trace.quietmode: return if Trace.prefix and Trace.showlinesmode: message = Trace.prefix + message Trace.show(message, sys.stdout) def error(cls, message): "Show an error message" message = '* ' + message if Trace.prefix and Trace.showlinesmode: message = Trace.prefix + message Trace.show(message, sys.stderr) def fatal(cls, message): "Show an error message and terminate" Trace.error('FATAL: ' + message) exit(-1) def show(cls, message, channel): "Show a message out of a channel" if sys.version_info < (3,0): message = message.encode('utf-8') channel.write(message + '\n') debug = classmethod(debug) message = classmethod(message) error = classmethod(error) fatal = classmethod(fatal) show = classmethod(show) elyxer-1.2.5/forks/jras-elyxer/src/elyxer/util/docparams.py0000644000175000017500000000220512117061342023321 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20100713 # eLyXer: LyX document parameters from elyxer.util.trace import Trace class DocumentParameters(object): "Global parameters for the document." pdftitle = None indentstandard = False tocdepth = 10 startinglevel = 0 maxdepth = 10 language = None bibliography = None outputchanges = False displaymode = False elyxer-1.2.5/forks/jras-elyxer/src/elyxer/util/translate.py0000644000175000017500000000520712117061342023352 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20100112 # eLyXer translations and translation generation import gettext from elyxer.util.trace import Trace from elyxer.util.docparams import * from elyxer.conf.config import * class Translator(object): "Reads the configuration file and tries to find a translation." "Otherwise falls back to the messages in the config file." instance = None def translate(cls, key): "Get the translated message for a key." return cls.instance.getmessage(key) translate = classmethod(translate) def __init__(self): self.translation = None self.first = True def findtranslation(self): "Find the translation for the document language." self.langcodes = None if not DocumentParameters.language: Trace.error('No language in document') return if not DocumentParameters.language in TranslationConfig.languages: Trace.error('Unknown language ' + DocumentParameters.language) return if TranslationConfig.languages[DocumentParameters.language] == 'en': return langcodes = [TranslationConfig.languages[DocumentParameters.language]] try: self.translation = gettext.translation('elyxer', None, langcodes) except IOError: Trace.error('No translation for ' + unicode(langcodes)) def getmessage(self, key): "Get the translated message for the given key." if self.first: self.findtranslation() self.first = False message = self.getuntranslated(key) if not self.translation: return message try: message = self.translation.ugettext(message) except IOError: pass return message def getuntranslated(self, key): "Get the untranslated message." if not key in TranslationConfig.constants: Trace.error('Cannot translate ' + key) return key return TranslationConfig.constants[key] Translator.instance = Translator() elyxer-1.2.5/forks/jras-elyxer/src/elyxer/util/__init__.py0000644000175000017500000000000012117061342023076 0ustar chennochennoelyxer-1.2.5/forks/jras-elyxer/src/elyxer/bib/0000755000175000017500000000000012117061342020556 5ustar chennochennoelyxer-1.2.5/forks/jras-elyxer/src/elyxer/bib/tag.py0000644000175000017500000002014212117061342021702 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20101027 # eLyXer BibTeX tag parsing from elyxer.util.trace import Trace from elyxer.util.clone import * from elyxer.conf.config import * from elyxer.parse.position import * from elyxer.gen.container import * from elyxer.maths.formula import * from elyxer.maths.command import * from elyxer.tex.texcode import * class BibTagParser(object): "A parser for BibTeX tags." nameseparators = ['{', '=', '"', '#'] def __init__(self): self.key = None tags = BibStylesConfig.defaulttags self.tags = dict((x, BibTag().constant(tags[x])) for x in tags) def parse(self, pos): "Parse the entry between {}." self.type = pos.globexcluding(self.nameseparators).strip() if not pos.checkskip('{'): pos.error('Entry should start with {') return pos.pushending('}') self.parsetags(pos) pos.popending('}') pos.skipspace() def parsetags(self, pos): "Parse all tags in the entry." pos.skipspace() while not pos.finished(): if pos.checkskip('{'): pos.error('Unmatched {') return pos.pushending(',', True) self.parsetag(pos) if pos.checkfor(','): pos.popending(',') def parsetag(self, pos): "Parse a single tag." (key, value) = self.getkeyvalue(pos) if not key: return if not value: self.key = key return name = key.lower() self.tags[name] = value if hasattr(self, 'dissect' + name): dissector = getattr(self, 'dissect' + name) dissector(value.extracttext()) if not pos.finished(): remainder = pos.globexcluding(',') pos.error('Ignored ' + remainder + ' before comma') def getkeyvalue(self, pos): "Parse a string of the form key=value." piece = pos.globexcluding(self.nameseparators).strip() if pos.finished(): return (piece, None) if not pos.checkskip('='): pos.error('Undesired character in tag name ' + piece) pos.skipcurrent() return (piece, None) key = piece.lower() pos.skipspace() value = self.parsevalue(pos) return (key, value) def parsevalue(self, pos): "Parse the value for a tag." tag = BibTag() pos.skipspace() if pos.checkfor(','): pos.error('Unexpected ,') return tag.error() tag.parse(pos) return tag def dissectauthor(self, authortag): "Dissect the author tag into pieces." authorsplit = authortag.split(' and ') if len(authorsplit) == 0: return authorlist = [] for authorname in authorsplit: author = BibAuthor().parse(authorname) authorlist.append(author) initials = '' authors = '' if len(authorlist) == 1: initials = authorlist[0].surname[0:3] authors = unicode(authorlist[0]) else: for author in authorlist: initials += author.surname[0:1] authors += unicode(author) + ', ' authors = authors[:-2] self.tags['surname'] = BibTag().constant(authorlist[0].surname) self.tags['Sur'] = BibTag().constant(initials) self.tags['authors'] = BibTag().constant(authors) def dissectyear(self, yeartag): "Dissect the year tag into pieces, looking for 4 digits in a row." pos = TextPosition(yeartag) while not pos.finished(): if pos.current().isdigit(): number = pos.globnumber() if len(number) == 4: self.tags['YY'] = BibTag().constant(number[2:]) return else: pos.skipcurrent() def dissectfile(self, filetag): "Extract the filename from elyxer.the file tag as ':filename:FORMAT'." if not filetag.startswith(':'): return bits = filetag.split(':') if len(bits) != 3: return self.tags['filename'] = BibTag().constant(bits[1]) self.tags['format'] = BibTag().constant(bits[2]) def gettag(self, key): "Get the tag for a given key." if not key in self.tags: return None return self.tags[key] def gettagtext(self, key): "Get the tag for a key as raw text." return self.gettag(key).extracttext() class BibTag(Container): "A tag in a BibTeX file." valueseparators = ['{', '"', '#', '}'] stringdefs = dict() def __init__(self): self.contents = [] self.output = ContentsOutput() def constant(self, text): "Initialize for a single constant." self.contents = [Constant(text)] return self def error(self): "To use when parsing resulted in an error." return self.constant('') def parse(self, pos): "Parse brackets or quotes at the first level." while not pos.finished(): self.parsetext(pos) if pos.finished(): return elif pos.checkfor('{'): self.parsebracket(pos) elif pos.checkfor('"'): self.parsequoted(pos) elif pos.checkfor('#'): self.parsehash(pos) else: pos.error('Unexpected character ' + pos.current()) pos.skipcurrent() def parsetext(self, pos): "Parse a bit of text, try to substitute strings with string defs." text = pos.globexcluding(self.valueseparators) key = text.strip() if key == '': return if key in self.stringdefs: self.add(self.stringdefs[key]) return self.add(Constant(key)) def add(self, piece): "Add a new piece to the tag." self.contents.append(piece) def parsetex(self, pos): "Parse some TeX code." tex = TeXCode() tex.parse(pos) self.add(tex) def parsebracket(self, pos): "Parse a {} bracket" if not pos.checkskip('{'): pos.error('Missing opening { in bracket') return pos.pushending('}') self.parsetex(pos) pos.popending('}') def parsequoted(self, pos): "Parse a piece of quoted text" if not pos.checkskip('"'): pos.error('Missing opening " in quote') return pos.pushending('"') self.parsetex(pos) pos.popending('"') pos.skipspace() def parsehash(self, pos): "Parse a hash mark #." if not pos.checkskip('#'): pos.error('Missing # in hash') return def __unicode__(self): "Return a printable representation." return 'BibTag: ' + self.extracttext() class BibAuthor(object): "A BibTeX individual author." def __init__(self): self.surname = '' self.firstnames = [] def parse(self, tag): "Parse an individual author tag." if ',' in tag: self.parsecomma(tag) else: self.parsewithoutcomma(tag) return self def parsecomma(self, tag): "Parse an author with a comma: Python, M." bits = tag.split(',') if len(bits) > 2: Trace.error('Too many commas in ' + tag) self.surname = bits[0].strip() self.parsefirstnames(bits[1].strip()) def parsewithoutcomma(self, tag): "Parse an author without a comma: M. Python." bits = tag.rsplit(None, 1) if len(bits) == 0: Trace.error('Empty author') ppp() return self.surname = bits[-1].strip() if len(bits) == 1: return self.parsefirstnames(bits[0].strip()) def parsefirstnames(self, firstnames): "Parse the first name." for firstname in firstnames.split(): self.firstnames.append(firstname) def getinitial(self): "Get the main initial for the author." if len(self.surname) == 0: return '' return self.surname[0].toupper() def __unicode__(self): "Return a printable representation." result = '' for firstname in self.firstnames: result += firstname + ' ' return result + self.surname elyxer-1.2.5/forks/jras-elyxer/src/elyxer/bib/pub.py0000644000175000017500000001440512117061342021722 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20100606 # eLyXer BibTeX publication entries. from elyxer.util.trace import Trace from elyxer.out.output import * from elyxer.conf.config import * from elyxer.parse.position import * from elyxer.ref.link import * from elyxer.bib.tex import * from elyxer.bib.tag import * class PubEntry(BibEntry): "A publication entry" def __init__(self): self.output = TaggedOutput().settag('p class="biblio"', True) def detect(self, pos): "Detect a publication entry." return pos.checkfor('@') def parse(self, pos): "Parse the publication entry." self.parser = BibTagParser() self.parser.parse(pos) self.type = self.parser.type def isvisible(self): "A publication entry is always visible." return True def isreferenced(self): "Check if the entry is referenced." if not self.parser.key: return False return self.parser.key in BiblioReference.references def process(self): "Process the entry." self.index = NumberGenerator.generator.generate('pubentry') self.parser.tags['index'] = Constant(self.index) biblio = BiblioEntry() biblio.citeref = self.createref() biblio.processcites(self.parser.key) self.contents = [biblio, Constant(' ')] self.contents += self.entrycontents() def entrycontents(self): "Get the contents of the entry." return self.translatetemplate(self.template) def createref(self): "Create the reference to cite." return self.translatetemplate(self.citetemplate) def translatetemplate(self, template): "Translate a complete template into a list of contents." pos = TextPosition(template) part = BibPart(self.parser.tags).parse(pos) for variable in part.searchall(BibVariable): if variable.empty(): Trace.error('Error parsing BibTeX template for ' + unicode(self) + ': ' + unicode(variable) + ' is empty') return [part] def __unicode__(self): "Return a string representation" string = '' if 'author' in self.parser.tags: string += self.parser.gettagtext('author') + ': ' if 'title' in self.parser.tags: string += '"' + self.parser.gettagtext('title') + '"' return string class BibPart(Container): "A part of a BibTeX template." def __init__(self, tags): self.output = ContentsOutput() self.contents = [] self.tags = tags self.quotes = 0 def parse(self, pos): "Parse a part of a template, return a list of contents." while not pos.finished(): self.add(self.parsepiece(pos)) return self def parsepiece(self, pos): "Get the next piece of the template, return if it was empty." if pos.checkfor('{'): return self.parsebraces(pos) elif pos.checkfor('$'): return self.parsevariable(pos) result = '' while not pos.finished() and not pos.current() in '{$': if pos.current() == '"': self.quotes += 1 result += pos.skipcurrent() return Constant(result) def parsebraces(self, pos): "Parse a pair of curly braces {}." if not pos.checkskip('{'): Trace.error('Missing { in braces.') return None pos.pushending('}') part = BibPart(self.tags).parse(pos) pos.popending('}') empty = part.emptyvariables() if empty: return None return part def parsevariable(self, pos): "Parse a variable $name." var = BibVariable(self.tags).parse(pos) if self.quotes % 2 == 1: # odd number of quotes; don't add spans in an attribute var.removetag() return var def emptyvariables(self): "Find out if there are only empty variables in the part." for variable in self.searchall(BibVariable): if not variable.empty(): return False return True def add(self, piece): "Add a new piece to the current part." if not piece: return if self.redundantdot(piece): # remove extra dot piece.string = piece.string[1:] self.contents.append(piece) piece.parent = self def redundantdot(self, piece): "Find out if there is a redundant dot in the next piece." if not isinstance(piece, Constant): return False if not piece.string.startswith('.'): return False if len(self.contents) == 0: return False if not isinstance(self.contents[-1], BibVariable): return False if not self.contents[-1].extracttext().endswith('.'): return False return True class BibVariable(Container): "A variable in a BibTeX template." def __init__(self, tags): self.output = TaggedOutput() self.contents = [] self.tags = tags def parse(self, pos): "Parse the variable name." if not pos.checkskip('$'): Trace.error('Missing $ in variable name.') return self self.key = pos.globalpha() self.output.tag = 'span class="bib-' + self.key + '"' self.processtags() return self def processtags(self): "Find the tag with the appropriate key in the list of tags." if not self.key in self.tags: return result = self.tags[self.key] self.contents = [result] def empty(self): "Find out if the variable is empty." if not self.contents: return True if self.extracttext() == '': return True return False def removetag(self): "Remove the output tag and leave just the contents." self.output = ContentsOutput() def __unicode__(self): "Return a printable representation." result = 'variable ' + self.key if not self.empty(): result += ':' + self.extracttext() return result BibEntry.instances += [PubEntry()] elyxer-1.2.5/forks/jras-elyxer/src/elyxer/bib/biblio.py0000644000175000017500000001130012117061342022363 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20090415 # eLyXer bibliography from elyxer.util.numbering import * from elyxer.util.docparams import * from elyxer.parse.parser import * from elyxer.out.output import * from elyxer.ref.link import * from elyxer.gen.layout import * from elyxer.proc.postprocess import * class BiblioCitation(Container): "A complete bibliography citation (possibly with many cites)." citations = dict() def __init__(self): self.parser = InsetParser() self.output = TaggedOutput().settag('span class="bibcites"') self.contents = [] def process(self): "Process the complete citation and all cites within." self.contents = [Constant('[')] keys = self.getparameterlist('key') for key in keys: self.contents += [BiblioCite().create(key), Constant(', ')] if len(keys) > 0: # remove trailing , self.contents.pop() self.contents.append(Constant(']')) class BiblioCite(Link): "Cite of a bibliography entry" cites = dict() def create(self, key): "Create the cite to the given key." self.key = key number = NumberGenerator.generator.generate('bibliocite') ref = BiblioReference().create(key, number) self.complete(number, 'cite-' + number, type='bibliocite') self.setmutualdestination(ref) if not key in BiblioCite.cites: BiblioCite.cites[key] = [] BiblioCite.cites[key].append(self) return self class Bibliography(Container): "A bibliography layout containing an entry" def __init__(self): self.parser = BoundedParser() self.output = TaggedOutput().settag('p class="biblio"', True) class BiblioHeader(Container): "The header of the bibliography." def __init__(self): "Create the header for the bibliography section." self.type = 'biblio' self.output = ContentsOutput() self.name = Translator.translate(DocumentParameters.bibliography) self.contents = [TaggedText().constant(self.name, 'h1 class="biblio"', True)] def addtotoc(self, parent): "Add the bibliography header to the TOC." self.parent = parent self.partkey = PartKeyGenerator.forindex(self) if not self.partkey: return self.partkey.addtoclabel(self) while parent: parent.partkey = self.partkey parent = parent.parent class PostBiblio(object): "Insert a Bibliography legend before the first item" processedclass = Bibliography def postprocess(self, last, element, next): "If we have the first bibliography insert a tag" if isinstance(last, Bibliography) or Options.nobib: return element layout = StandardLayout() header = BiblioHeader() header.addtotoc(layout) layout.complete([header, element]) return layout Postprocessor.stages += [PostBiblio] class BiblioReference(Link): "A reference to a bibliographical entry." references = dict() def create(self, key, number): "Create the reference with the given key and number." self.key = key self.complete(number, 'biblio-' + number, type='biblioentry') if not key in BiblioReference.references: BiblioReference.references[key] = [] BiblioReference.references[key].append(self) return self class BiblioEntry(Container): "A bibliography entry" entries = dict() def __init__(self): self.parser = InsetParser() self.output = TaggedOutput().settag('span class="entry"') self.contents = [] def process(self): "Process the cites for the entry's key" self.citeref = [Constant(NumberGenerator.generator.generate('biblioentry'))] self.processcites(self.getparameter('key')) def processcites(self, key): "Get all the cites of the entry" self.key = key if not key in BiblioReference.references: self.contents.append(Constant('[-] ')) return self.contents = [Constant('[')] for ref in BiblioReference.references[key]: self.contents.append(ref) self.contents.append(Constant(',')) self.contents.pop(-1) self.contents.append(Constant('] ')) elyxer-1.2.5/forks/jras-elyxer/src/elyxer/bib/tex.py0000644000175000017500000001707312117061342021740 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20090905 # eLyXer BibTeX processing from elyxer.util.trace import Trace from elyxer.util.clone import * from elyxer.out.output import * from elyxer.io.path import * from elyxer.io.bulk import * from elyxer.conf.config import * from elyxer.parse.position import * from elyxer.ref.link import * from elyxer.bib.biblio import * from elyxer.bib.tag import * class BibTeX(Container): "Show a BibTeX bibliography and all referenced entries" def __init__(self): self.parser = InsetParser() self.output = ContentsOutput() def process(self): "Read all bibtex files and process them." self.entries = [] self.contents = [self.createheader()] bibliography = Translator.translate('bibliography') files = self.getparameterlist('bibfiles') showall = False if self.getparameter('btprint') == 'btPrintAll': showall = True for file in files: bibfile = BibFile(file, showall) bibfile.parse() self.entries += bibfile.entries Trace.message('Parsed ' + unicode(bibfile)) self.entries.sort(key = unicode) self.applystyle() def createheader(self): "Create the header for the bibliography." header = BiblioHeader() if 'bibtotoc' in self.getparameterlist('options'): header.addtotoc(self) return header def applystyle(self): "Read the style and apply it to all entries" style = self.readstyle() for entry in self.entries: entry.template = style['default'] entry.citetemplate = style['cite'] type = entry.type.lower() if type in style: entry.template = style[type] entry.process() self.contents.append(entry) def readstyle(self): "Read the style from elyxer.the bibliography options" for option in self.getparameterlist('options'): if hasattr(BibStylesConfig, option): return getattr(BibStylesConfig, option) return BibStylesConfig.default class BibFile(object): "A BibTeX file" def __init__(self, filename, showall): "Create the BibTeX file" self.filename = filename + '.bib' self.showall = showall self.added = 0 self.ignored = 0 self.entries = [] def parse(self): "Parse the BibTeX file and extract all entries." try: self.parsefile() except IOError: Trace.error('Error reading ' + self.filename + '; make sure the file exists and can be read.') def parsefile(self): "Parse the whole file." bibpath = InputPath(self.filename) if Options.lowmem: pos = FilePosition(bibpath.path) else: bulkfile = BulkFile(bibpath.path) text = ''.join(bulkfile.readall()) pos = TextPosition(text) while not pos.finished(): pos.skipspace() if pos.checkskip(','): pos.skipspace() self.parseentry(pos) def parseentry(self, pos): "Parse a single entry" for entry in BibEntry.instances: if entry.detect(pos): newentry = Cloner.clone(entry) newentry.parse(pos) if not newentry.isvisible(): return if self.showall or newentry.isreferenced(): self.entries.append(newentry) self.added += 1 else: Trace.debug('Ignored entry ' + unicode(newentry)) self.ignored += 1 return # Skip the whole line since it's a comment outside an entry pos.globincluding('\n').strip() def __unicode__(self): "String representation" string = self.filename + ': ' + unicode(self.added) + ' entries added, ' string += unicode(self.ignored) + ' entries ignored' return string class BibEntry(Container): "An entry in a BibTeX file" instances = [] def detect(self, pos): "Throw an error." Trace.error('Tried to detect() in ' + unicode(self)) def parse(self, pos): "Throw an error." Trace.error('Tried to parse() in ' + unicode(self)) def isvisible(self): "Return if the entry should be visible. Throws an error." Trace.error('Function isvisible() not implemented for ' + unicode(self)) def isreferenced(self): "Return if the entry is referenced. Throws an error." Trace.error('Function isreferenced() not implemented for ' + unicode(self)) def __unicode__(self): "Return a string representation" return 'BibTeX entry ' + self.__class__.__name__ class CommentEntry(BibEntry): "A simple comment." def detect(self, pos): "Detect the special entry" return pos.checkfor('%') def parse(self, pos): "Parse all consecutive comment lines." while pos.checkfor('%'): pos.globincluding('\n') def isvisible(self): "A comment entry is never visible." return False def __unicode__(self): "Return a string representation" return 'Comment' class SpecialEntry(BibEntry): "A special entry" types = ['@preamble', '@comment'] def __init__(self): self.contents = [] self.output = EmptyOutput() def detect(self, pos): "Detect the special entry" for type in self.types: if pos.checkforlower(type): return True return False def parse(self, pos): "Parse and ignore." self.type = 'special' pos.globincluding('{') pos.pushending('}') while not pos.finished(): if pos.checkfor('{'): self.parse(pos) else: pos.skipcurrent() pos.popending() def isvisible(self): "A special entry is never visible." return False def __unicode__(self): "Return a string representation" return self.type class StringEntry(SpecialEntry): "A string definition. The definition can later be used in other entries." parser = BibTagParser() start = '@string' key = None def detect(self, pos): "Detect the string definition." return pos.checkforlower(self.start) def parse(self, pos): "Parse a single tag, which will define a string." self.type = self.start if not self.checkstart(pos): return pos.skipspace() if not pos.checkskip('{'): Trace.error('Missing opening { in ' + unicode(self)) pos.globincluding('\n') return pos.pushending('}') (self.key, value) = self.parser.getkeyvalue(pos) BibTag.stringdefs[self.key] = value pos.popending('}') def checkstart(self, pos): "Check that the entry starts with @string." if not pos.checkskip('@'): Trace.error('Missing @ from elyxer.string definition') return False name = '@' + pos.globalpha() if not name.lower() == self.start.lower(): Trace.error('Invalid start @' + name +', missing ' + self.start + ' from elyxer.' + unicode(self)) pos.globincluding('\n') return False return True def __unicode__(self): "Return a printable representation." result = 'string definition' if self.key: result += ' for ' + self.key return result # More instances will be added later BibEntry.instances += [CommentEntry(), SpecialEntry(), StringEntry()] elyxer-1.2.5/forks/jras-elyxer/src/elyxer/bib/__init__.py0000644000175000017500000000000012117061342022655 0ustar chennochennoelyxer-1.2.5/forks/jras-elyxer/src/elyxer/proc/0000755000175000017500000000000012117061342020765 5ustar chennochennoelyxer-1.2.5/forks/jras-elyxer/src/elyxer/proc/postprocess.py0000644000175000017500000000571412117061342023732 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20090324 # eLyXer postprocessor code class Postprocessor(object): "Postprocess a container keeping some context" stages = [] def __init__(self): self.stages = StageDict(Postprocessor.stages, self) self.current = None self.last = None def postprocess(self, next): "Postprocess a container and its contents." self.postrecursive(self.current) result = self.postcurrent(next) self.last = self.current self.current = next return result def postrecursive(self, container): "Postprocess the container contents recursively" if not hasattr(container, 'contents'): return if len(container.contents) == 0: return if hasattr(container, 'postprocess'): if not container.postprocess: return postprocessor = Postprocessor() contents = [] for element in container.contents: post = postprocessor.postprocess(element) if post: contents.append(post) # two rounds to empty the pipeline for i in range(2): post = postprocessor.postprocess(None) if post: contents.append(post) container.contents = contents def postcurrent(self, next): "Postprocess the current element taking into account next and last." stage = self.stages.getstage(self.current) if not stage: return self.current return stage.postprocess(self.last, self.current, next) class StageDict(object): "A dictionary of stages corresponding to classes" def __init__(self, classes, postprocessor): "Instantiate an element from elyxer.each class and store as a dictionary" instances = self.instantiate(classes, postprocessor) self.stagedict = dict([(x.processedclass, x) for x in instances]) def instantiate(self, classes, postprocessor): "Instantiate an element from elyxer.each class" stages = [x.__new__(x) for x in classes] for element in stages: element.__init__() element.postprocessor = postprocessor return stages def getstage(self, element): "Get the stage for a given element, if the type is in the dict" if not element.__class__ in self.stagedict: return None return self.stagedict[element.__class__] elyxer-1.2.5/forks/jras-elyxer/src/elyxer/proc/process.py0000644000175000017500000000470712117061342023025 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20100714 # eLyXer: internal processing code from elyxer.util.trace import * from elyxer.gen.header import * from elyxer.ref.index import * from elyxer.gen.layout import * from elyxer.proc.postprocess import * class Processor(object): "Process a container and its contents." prestages = [] skipfiltered = ['LyXHeader', 'LyXFooter', 'Title', 'Author', 'TableOfContents'] def __init__(self, filtering): "Set filtering mode (to skip postprocessing)." "With filtering on, the classes in skipfiltered are not processed at all." self.filtering = filtering self.postprocessor = Postprocessor() def process(self, container): "Do the whole processing on a container." if self.filtering and container.__class__.__name__ in self.skipfiltered: return None container = self.preprocess(container) self.processcontainer(container) if not container: # do not postprocess empty containers from elyxer.here return container return self.postprocess(container) def preprocess(self, root): "Preprocess a root container with all prestages." if not root: return None for stage in self.prestages: root = stage.preprocess(root) if not root: return None return root def processcontainer(self, container): "Process a container and its contents, recursively." if not container: return for element in container.contents: self.processcontainer(element) container.process() def postprocess(self, container): "Postprocess a container, unless filtering is on." if self.filtering: return container return self.postprocessor.postprocess(container) elyxer-1.2.5/forks/jras-elyxer/src/elyxer/proc/formulaproc.py0000644000175000017500000000576712117061342023707 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20101111 # eLyXer formulae processing. from elyxer.util.trace import * from elyxer.conf.config import * from elyxer.maths.bits import * class MathsProcessor(object): "A processor for a maths construction inside the FormulaProcessor." def process(self, contents, index): "Process an element inside a formula." Trace.error('Unimplemented process() in ' + unicode(self)) def __unicode__(self): "Return a printable description." return 'Maths processor ' + self.__class__.__name__ class FormulaProcessor(object): "A processor specifically for formulas." processors = [] def process(self, bit): "Process the contents of every formula bit, recursively." self.processcontents(bit) self.processinsides(bit) self.traversewhole(bit) def processcontents(self, bit): "Process the contents of a formula bit." if not isinstance(bit, FormulaBit): return bit.process() for element in bit.contents: self.processcontents(element) def processinsides(self, bit): "Process the insides (limits, brackets) in a formula bit." if not isinstance(bit, FormulaBit): return for index, element in enumerate(bit.contents): for processor in self.processors: processor.process(bit.contents, index) # continue with recursive processing self.processinsides(element) def traversewhole(self, formula): "Traverse over the contents to alter variables and space units." last = None for bit, contents in self.traverse(formula): if bit.type == 'alpha': self.italicize(bit, contents) elif bit.type == 'font' and last and last.type == 'number': bit.contents.insert(0, FormulaConstant(u' ')) last = bit def traverse(self, bit): "Traverse a formula and yield a flattened structure of (bit, list) pairs." for element in bit.contents: if hasattr(element, 'type') and element.type: yield (element, bit.contents) elif isinstance(element, FormulaBit): for pair in self.traverse(element): yield pair def italicize(self, bit, contents): "Italicize the given bit of text." index = contents.index(bit) contents[index] = TaggedBit().complete([bit], 'i') elyxer-1.2.5/forks/jras-elyxer/src/elyxer/proc/__init__.py0000644000175000017500000000000012117061342023064 0ustar chennochennoelyxer-1.2.5/forks/jras-elyxer/src/elyxer/main/0000755000175000017500000000000012117061342020746 5ustar chennochennoelyxer-1.2.5/forks/jras-elyxer/src/elyxer/main/convert.py0000644000175000017500000001355412117061342023010 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20090919 # eLyXer converter # http://www.nongnu.org/elyxer/ import os.path from elyxer.io.fileline import * from elyxer.util.options import * from elyxer.gen.factory import * from elyxer.gen.toc import * from elyxer.gen.inset import * from elyxer.gen.basket import * from elyxer.gen.integral import * from elyxer.gen.splitpart import * from elyxer.proc.process import * from elyxer.maths.postformula import * class eLyXerConverter(object): "Converter for a document in a lyx file. Places all output in a given basket." def __init__(self): self.filtering = False def setio(self, ioparser): "Set the InOutParser" self.reader = ioparser.getreader() self.basket = self.getbasket() self.basket.setwriter(ioparser.getwriter()) return self def getbasket(self): "Get the appropriate basket for the current options." if Options.tocfor: if Options.splitpart: return SplitTOCBasket() return TOCBasket() if Options.splitpart: return SplitPartBasket() if Options.memory: return MemoryBasket() return WriterBasket() def embed(self, reader): "Embed the results from elyxer.a reader into a memory basket." "Header and footer are ignored. Useful for embedding one document inside another." self.filtering = True self.reader = reader self.basket = MemoryBasket() return self def convert(self): "Perform the conversion for the document" try: self.processcontents() except (Exception): version = '[eLyXer version ' + GeneralConfig.version['number'] version += ' (' + GeneralConfig.version['date'] + ') in ' version += Options.location + '] ' Trace.error(version) Trace.error('Conversion failed at ' + self.reader.currentline()) raise def processcontents(self): "Parse the contents and write it by containers" factory = ContainerFactory() processor = Processor(self.filtering) while not self.reader.finished(): container = factory.createcontainer(self.reader) result = processor.process(container) self.writecontainer(result) result = processor.postprocess(None) self.writecontainer(result) if not self.filtering: self.basket.finish() def writecontainer(self, container): "Write each container to the correct basket." if not container: return includes = container.searchremove(IncludeInset) self.basket.write(container) # recursive processing for IncludeInset for include in includes: for element in include.contents: self.basket.write(element) def getcontents(self): "Return the contents of the basket." return self.basket.contents def __unicode__(self): "Printable representation." string = 'Converter with filtering ' + unicode(self.filtering) string += ' and basket ' + unicode(self.basket) return string class InOutParser(object): "Parse in and out arguments" def __init__(self): self.filein = sys.stdin self.fileout = sys.stdout def parse(self, args): "Parse command line arguments" self.filein = sys.stdin self.fileout = sys.stdout if len(args) < 2: Trace.quietmode = True if len(args) > 0: self.filein = args[0] del args[0] self.readdir(self.filein, 'directory') else: Options.directory = '.' if len(args) > 0: self.fileout = args[0] del args[0] self.readdir(self.fileout, 'destdirectory') else: Options.destdirectory = '.' if len(args) > 0: raise Exception('Unused arguments: ' + unicode(args)) return self def getreader(self): "Get the resulting reader." return LineReader(self.filein) def getwriter(self): "Get the resulting writer." return LineWriter(self.fileout) def readdir(self, filename, diroption): "Read the current directory if needed" if getattr(Options, diroption) != None: return setattr(Options, diroption, os.path.dirname(filename)) if getattr(Options, diroption) == '': setattr(Options, diroption, '.') class NullWriter(object): "A writer that goes nowhere." def write(self, list): "Do nothing." pass class ConverterFactory(object): "Create a converter fit for converting a filename and embedding the result." def create(self, container): "Create a converter for a given container, with filename" " and possibly other parameters." fullname = os.path.join(Options.directory, container.filename) reader = LineReader(container.filename) if 'firstline' in container.lstparams: reader.setstart(int(container.lstparams['firstline'])) if 'lastline' in container.lstparams: reader.setend(int(container.lstparams['lastline'])) return eLyXerConverter().embed(reader) IncludeInset.converterfactory = ConverterFactory() def convertdoc(args): "Read a whole document from the command line and write it." Options().parseoptions(args) ioparser = InOutParser().parse(args) converter = eLyXerConverter().setio(ioparser) converter.convert() def main(): "Main function, called if invoked from the command line" convertdoc(list(sys.argv)) elyxer-1.2.5/forks/jras-elyxer/src/elyxer/main/__init__.py0000644000175000017500000000000012117061342023045 0ustar chennochennoelyxer-1.2.5/forks/jras-elyxer/src/elyxer/conf/0000755000175000017500000000000012117175142020753 5ustar chennochennoelyxer-1.2.5/forks/jras-elyxer/src/elyxer/conf/fileconfig.py0000644000175000017500000001714212117061342023433 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20090203 # eLyXer parsers import datetime from elyxer.util.trace import Trace from elyxer.io.fileline import * class ConfigReader(object): "Read a configuration file" escapes = [ ('\n', ' '), (':', ':'), ('#', '#'), ('[', '['), (']', ']'), ('&', '&'), ] def __init__(self, filename): self.reader = LineReader(filename) self.objects = dict() self.section = None self.serializer = ConfigSerializer(ConfigReader.escapes) def parse(self): "Parse the whole file" while not self.reader.finished(): self.parseline(self.reader.currentline()) self.reader.nextline() return self def parseline(self, line): "Parse a single line" if line == '': return if line.startswith('#'): return if line.startswith('['): self.parsesection(line) else: self.parseparam(line) def parsesection(self, line): "Parse a section header" if not line.endswith(']'): Trace.error('Incorrect section header ' + line) return name = line[1:-1] self.section = name self.objects[name] = dict() def parseparam(self, line): "Parse a parameter line" if len(line.strip()) == 0: return if not ':' in line: Trace.error('Invalid configuration parameter ' + line) return pieces = line.split(':', 1) key = self.serializer.unescape(pieces[0]) value = self.serializer.deserialize(pieces[1]) object = self.objects[self.section] if key in object: Trace.error('Repeated key ' + key + ' for ' + value) object[key] = value class ConfigWriter(object): "Write a configuration file" def __init__(self, writer): self.writer = writer self.serializer = ConfigSerializer(ConfigReader.escapes) def writeall(self, types): "Write a list of configuration objects given their class names" for type in types: object = type.__new__(type) self.write(object) def write(self, object): "Write a configuration object" for attr in dir(object): self.writeattr(object, attr) def writeattr(self, object, attr): "Write an attribute" if attr.startswith('__'): return self.writesection(object, attr) valuedict = getattr(object, attr) if not isinstance(valuedict, dict): Trace.error('Unknown config type ' + valuedict.__class__.__name__ + ' in ' + attr) return names = valuedict.keys() names.sort() for name in names: value = self.serializer.serialize(valuedict[name]) self.writer.writeline(self.serializer.escape(name) + ':' + value) def writesection(self, object, attr): "Write a new section" self.writer.writeline('') header = '[' + object.__class__.__name__ + '.' + attr + ']' self.writer.writeline(header) class ConfigToPython(ConfigWriter): "Exports a number of dictionaries from elyxer.a config file to a Python class" escapes = [ ('\\', '\\\\'), ('\n', '\\n'), ('\'', '\\\'') ] def __init__(self, writer): self.writer = writer self.serializer = ConfigSerializer(ConfigToPython.escapes) def write(self, objects): "Write the whole set of objects" self.writer.writeline('#! /usr/bin/env python') self.writer.writeline('# -*- coding: utf-8 -*-') self.writer.writeline('') self.writer.writeline('# eLyXer configuration') self.writer.writeline('# autogenerated from elyxer.config file on ' + datetime.date.today().isoformat()) self.writer.writeline('') classes = self.sort(objects) names = classes.keys() names.sort() for classname in names: self.writeclass(classname, classes[classname]) def writeclass(self, name, current): "Write an object class" self.writer.writeline('class ' + name + '(object):') self.writer.writeline(' "Configuration class from elyxer.config file"') self.writer.writeline('') names = current.keys() names.sort() for attrname in names: self.writeattr(attrname, current[attrname]) def writeattr(self, name, contents): "Write a dictionary attribute" if not isinstance(contents, dict): Trace.error('Unknown config type ' + contents.__class__.__name__) return self.writer.writestring(' ' + name + ' = ') self.writer.writeline('{') string = ' ' names = contents.keys() names.sort() for name in names: value = self.serializer.pyserialize(contents[name]) piece = 'u\'' + self.serializer.escape(name) + '\':' + value + ', ' string = self.append(string, piece) self.writer.writeline(string) self.writer.writeline(' }') self.writer.writeline('') def append(self, string, piece): "Write a piece to the string or to disk" if len(string + piece) > 80: self.writer.writeline(string) string = ' ' return string + piece def sort(self, objects): "Sort the objects into classes" classes = dict() for name, object in objects.iteritems(): pieces = name.split('.') if len(pieces) != 2: Trace.error('Wrong method name ' + name) return classname = pieces[0] methodname = pieces[1] if not classname in classes: classes[classname] = dict() currentclass = classes[classname] currentclass[methodname] = object return classes class ConfigSerializer(object): "Serialize and deserialize config object" def __init__(self, escapes): self.escapes = escapes def serialize(self, object): "Convert an object to a string" if not isinstance(object, list): return self.escape(object) result = '' for value in object: result += self.escape(value) + ',' if len(object) > 0: result = result[:-1] return '[' + result + ']' def pyserialize(self, object): "Convert an object to a Python definition" if not isinstance(object, list): return 'u\'' + self.escape(object) + '\'' result = '[u\'' for value in object: result += self.escape(value) + '\',u\'' if len(object) > 0: result = result[:-2] return result + ']' def escape(self, string): "Escape a string or a list" for escape, value in self.escapes: if escape in string: string = string.replace(escape, value) return string def deserialize(self, string): "Parse a string into an object (string or list)" if not string.startswith('[') or not string.endswith(']'): return self.unescape(string) result = [] contents = string[1:-1].split(',') for piece in contents: result.append(self.unescape(piece)) return result def unescape(self, string): "Remove the escaping from elyxer.a string." if string.startswith('&#x') and string.endswith(';'): # single unicode character return unichr(int('0x' + string[3:-1], 16)) for escape, value in self.escapes: string = string.replace(value, escape) return string elyxer-1.2.5/forks/jras-elyxer/src/elyxer/conf/config.py0000644000175000017500000014251512117061347022603 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer configuration # autogenerated from elyxer.config file on 2013-03-10 class BibStylesConfig(object): "Configuration class from elyxer.config file" abbrvnat = { u'@article':u'$authors. $title. $journal,{ {$volume:}$pages,} $month $year.{ doi: $doi.}{ URL $url.}{ $note.}', u'cite':u'$surname($year)', u'default':u'$authors. $title. $publisher, $year.{ URL $url.}{ $note.}', } alpha = { u'@article':u'$authors. $title.{ $journal{, {$volume}{($number)}}{: $pages}{, $year}.}{ $url.}{ $filename.}{ $note.}', u'cite':u'$Sur$YY', u'default':u'$authors. $title.{ $journal,} $year.{ $url.}{ $filename.}{ $note.}', } authordate2 = { u'@article':u'$authors. $year. $title. $journal, $volume($number), $pages.{ URL $url.}{ $note.}', u'@book':u'$authors. $year. $title. $publisher.{ URL $url.}{ $note.}', u'cite':u'$surname, $year', u'default':u'$authors. $year. $title. $publisher.{ URL $url.}{ $note.}', } default = { u'@article':u'$authors: “$title”, $journal,{ pp. $pages,} $year.{ URL $url.}{ $note.}', u'@book':u'{$authors: }$title{ ($editor, ed.)}.{{ $publisher,} $year.}{ URL $url.}{ $note.}', u'@booklet':u'$authors: $title.{{ $publisher,} $year.}{ URL $url.}{ $note.}', u'@conference':u'$authors: “$title”, $journal,{ pp. $pages,} $year.{ URL $url.}{ $note.}', u'@inbook':u'$authors: $title.{{ $publisher,} $year.}{ URL $url.}{ $note.}', u'@incollection':u'$authors: $title{ in $booktitle{ ($editor, ed.)}}.{{ $publisher,} $year.}{ URL $url.}{ $note.}', u'@inproceedings':u'$authors: “$title”, $booktitle,{ pp. $pages,} $year.{ URL $url.}{ $note.}', u'@manual':u'$authors: $title.{{ $publisher,} $year.}{ URL $url.}{ $note.}', u'@mastersthesis':u'$authors: $title.{{ $publisher,} $year.}{ URL $url.}{ $note.}', u'@misc':u'$authors: $title.{{ $publisher,}{ $howpublished,} $year.}{ URL $url.}{ $note.}', u'@phdthesis':u'$authors: $title.{{ $publisher,} $year.}{ URL $url.}{ $note.}', u'@proceedings':u'$authors: “$title”, $journal,{ pp. $pages,} $year.{ URL $url.}{ $note.}', u'@techreport':u'$authors: $title, $year.{ URL $url.}{ $note.}', u'@unpublished':u'$authors: “$title”, $journal, $year.{ URL $url.}{ $note.}', u'cite':u'$index', u'default':u'$authors: $title.{{ $publisher,} $year.}{ URL $url.}{ $note.}', } defaulttags = { u'YY':u'??', u'authors':u'', u'surname':u'', } ieeetr = { u'@article':u'$authors, “$title”, $journal, vol. $volume, no. $number, pp. $pages, $year.{ URL $url.}{ $note.}', u'@book':u'$authors, $title. $publisher, $year.{ URL $url.}{ $note.}', u'cite':u'$index', u'default':u'$authors, “$title”. $year.{ URL $url.}{ $note.}', } plain = { u'@article':u'$authors. $title.{ $journal{, {$volume}{($number)}}{:$pages}{, $year}.}{ URL $url.}{ $note.}', u'@book':u'$authors. $title. $publisher,{ $month} $year.{ URL $url.}{ $note.}', u'@incollection':u'$authors. $title.{ In $booktitle {($editor, ed.)}.} $publisher,{ $month} $year.{ URL $url.}{ $note.}', u'@inproceedings':u'$authors. $title. { $booktitle{, {$volume}{($number)}}{:$pages}{, $year}.}{ URL $url.}{ $note.}', u'cite':u'$index', u'default':u'{$authors. }$title.{{ $publisher,} $year.}{ URL $url.}{ $note.}', } vancouver = { u'@article':u'$authors. $title. $journal, $year{;{$volume}{($number)}{:$pages}}.{ URL: $url.}{ $note.}', u'@book':u'$authors. $title. {$publisher, }$year.{ URL: $url.}{ $note.}', u'cite':u'$index', u'default':u'$authors. $title; {$publisher, }$year.{ $howpublished.}{ URL: $url.}{ $note.}', } class BibTeXConfig(object): "Configuration class from elyxer.config file" replaced = { u'--':u'—', u'..':u'.', } class ContainerConfig(object): "Configuration class from elyxer.config file" endings = { u'Align':u'\\end_layout', u'BarredText':u'\\bar', u'BoldText':u'\\series', u'Cell':u'':u'>', } html = { u'/>':u'>', } iso885915 = { u' ':u' ', u' ':u' ', u' ':u' ', } nonunicode = { u' ':u' ', } class FormulaConfig(object): "Configuration class from elyxer.config file" alphacommands = { u'\\AA':u'Å', u'\\AE':u'Æ', u'\\AmS':u'AmS', u'\\Angstroem':u'Å', u'\\DH':u'Ð', u'\\Koppa':u'Ϟ', u'\\L':u'Ł', u'\\Micro':u'µ', u'\\O':u'Ø', u'\\OE':u'Œ', u'\\Sampi':u'Ϡ', u'\\Stigma':u'Ϛ', u'\\TH':u'Þ', u'\\aa':u'å', u'\\ae':u'æ', u'\\alpha':u'α', u'\\beta':u'β', u'\\delta':u'δ', u'\\dh':u'ð', u'\\digamma':u'ϝ', u'\\epsilon':u'ϵ', u'\\eta':u'η', u'\\eth':u'ð', u'\\gamma':u'γ', u'\\i':u'ı', u'\\imath':u'ı', u'\\iota':u'ι', u'\\j':u'ȷ', u'\\jmath':u'ȷ', u'\\kappa':u'κ', u'\\koppa':u'ϟ', u'\\l':u'ł', u'\\lambda':u'λ', u'\\mu':u'μ', u'\\nu':u'ν', u'\\o':u'ø', u'\\oe':u'œ', u'\\omega':u'ω', u'\\phi':u'φ', u'\\pi':u'π', u'\\psi':u'ψ', u'\\rho':u'ρ', u'\\sampi':u'ϡ', u'\\sigma':u'σ', u'\\ss':u'ß', u'\\stigma':u'ϛ', u'\\tau':u'τ', u'\\tcohm':u'Ω', u'\\textcrh':u'ħ', u'\\th':u'þ', u'\\theta':u'θ', u'\\upsilon':u'υ', u'\\varDelta':u'∆', u'\\varGamma':u'Γ', u'\\varLambda':u'Λ', u'\\varOmega':u'Ω', u'\\varPhi':u'Φ', u'\\varPi':u'Π', u'\\varPsi':u'Ψ', u'\\varSigma':u'Σ', u'\\varTheta':u'Θ', u'\\varUpsilon':u'Υ', u'\\varXi':u'Ξ', u'\\varbeta':u'ϐ', u'\\varepsilon':u'ε', u'\\varkappa':u'ϰ', u'\\varphi':u'φ', u'\\varpi':u'ϖ', u'\\varrho':u'ϱ', u'\\varsigma':u'ς', u'\\vartheta':u'ϑ', u'\\xi':u'ξ', u'\\zeta':u'ζ', } array = { u'begin':u'\\begin', u'cellseparator':u'&', u'end':u'\\end', u'rowseparator':u'\\\\', } bigbrackets = { u'(':[u'⎛',u'⎜',u'⎝',], u')':[u'⎞',u'⎟',u'⎠',], u'[':[u'⎡',u'⎢',u'⎣',], u']':[u'⎤',u'⎥',u'⎦',], u'{':[u'⎧',u'⎪',u'⎨',u'⎩',], u'|':[u'|',], u'}':[u'⎫',u'⎪',u'⎬',u'⎭',], u'∥':[u'∥',], } bigsymbols = { u'∑':[u'⎲',u'⎳',], u'∫':[u'⌠',u'⌡',], } bracketcommands = { u'\\left':u'span class="symbol"', u'\\left.':u'', u'\\middle':u'span class="symbol"', u'\\right':u'span class="symbol"', u'\\right.':u'', } combiningfunctions = { u'\\"':u'̈', u'\\\'':u'́', u'\\^':u'̂', u'\\`':u'̀', u'\\acute':u'́', u'\\bar':u'̄', u'\\breve':u'̆', u'\\c':u'̧', u'\\check':u'̌', u'\\dddot':u'⃛', u'\\ddot':u'̈', u'\\dot':u'̇', u'\\grave':u'̀', u'\\hat':u'̂', u'\\mathring':u'̊', u'\\overleftarrow':u'⃖', u'\\overrightarrow':u'⃗', u'\\r':u'̊', u'\\s':u'̩', u'\\textcircled':u'⃝', u'\\textsubring':u'̥', u'\\tilde':u'̃', u'\\v':u'̌', u'\\vec':u'⃗', u'\\~':u'̃', } commands = { u'\\ ':u' ', u'\\!':u'', u'\\#':u'#', u'\\$':u'$', u'\\%':u'%', u'\\&':u'&', u'\\,':u' ', u'\\:':u' ', u'\\;':u' ', u'\\AC':u'∿', u'\\APLcomment':u'⍝', u'\\APLdownarrowbox':u'⍗', u'\\APLinput':u'⍞', u'\\APLinv':u'⌹', u'\\APLleftarrowbox':u'⍇', u'\\APLlog':u'⍟', u'\\APLrightarrowbox':u'⍈', u'\\APLuparrowbox':u'⍐', u'\\Box':u'□', u'\\Bumpeq':u'≎', u'\\CIRCLE':u'●', u'\\Cap':u'⋒', u'\\CapitalDifferentialD':u'ⅅ', u'\\CheckedBox':u'☑', u'\\Circle':u'○', u'\\Coloneqq':u'⩴', u'\\ComplexI':u'ⅈ', u'\\ComplexJ':u'ⅉ', u'\\Corresponds':u'≙', u'\\Cup':u'⋓', u'\\Delta':u'Δ', u'\\Diamond':u'◇', u'\\Diamondblack':u'◆', u'\\Diamonddot':u'⟐', u'\\DifferentialD':u'ⅆ', u'\\Downarrow':u'⇓', u'\\EUR':u'€', u'\\Euler':u'ℇ', u'\\ExponetialE':u'ⅇ', u'\\Finv':u'Ⅎ', u'\\Game':u'⅁', u'\\Gamma':u'Γ', u'\\Im':u'ℑ', u'\\Join':u'⨝', u'\\LEFTCIRCLE':u'◖', u'\\LEFTcircle':u'◐', u'\\LHD':u'◀', u'\\Lambda':u'Λ', u'\\Lbag':u'⟅', u'\\Leftarrow':u'⇐', u'\\Lleftarrow':u'⇚', u'\\Longleftarrow':u'⟸', u'\\Longleftrightarrow':u'⟺', u'\\Longrightarrow':u'⟹', u'\\Lparen':u'⦅', u'\\Lsh':u'↰', u'\\Mapsfrom':u'⇐|', u'\\Mapsto':u'|⇒', u'\\Omega':u'Ω', u'\\P':u'¶', u'\\Phi':u'Φ', u'\\Pi':u'Π', u'\\Pr':u'Pr', u'\\Psi':u'Ψ', u'\\Qoppa':u'Ϙ', u'\\RHD':u'▶', u'\\RIGHTCIRCLE':u'◗', u'\\RIGHTcircle':u'◑', u'\\Rbag':u'⟆', u'\\Re':u'ℜ', u'\\Rparen':u'⦆', u'\\Rrightarrow':u'⇛', u'\\Rsh':u'↱', u'\\S':u'§', u'\\Sigma':u'Σ', u'\\Square':u'☐', u'\\Subset':u'⋐', u'\\Sun':u'☉', u'\\Supset':u'⋑', u'\\Theta':u'Θ', u'\\Uparrow':u'⇑', u'\\Updownarrow':u'⇕', u'\\Upsilon':u'Υ', u'\\Vdash':u'⊩', u'\\Vert':u'∥', u'\\Vvdash':u'⊪', u'\\XBox':u'☒', u'\\Xi':u'Ξ', u'\\Yup':u'⅄', u'\\\\':u'
', u'\\_':u'_', u'\\aleph':u'ℵ', u'\\amalg':u'∐', u'\\anchor':u'⚓', u'\\angle':u'∠', u'\\aquarius':u'♒', u'\\arccos':u'arccos', u'\\arcsin':u'arcsin', u'\\arctan':u'arctan', u'\\arg':u'arg', u'\\aries':u'♈', u'\\arrowbullet':u'➢', u'\\ast':u'∗', u'\\asymp':u'≍', u'\\backepsilon':u'∍', u'\\backprime':u'‵', u'\\backsimeq':u'⋍', u'\\backslash':u'\\', u'\\ballotx':u'✗', u'\\barwedge':u'⊼', u'\\because':u'∵', u'\\beth':u'ℶ', u'\\between':u'≬', u'\\bigcap':u'∩', u'\\bigcirc':u'○', u'\\bigcup':u'∪', u'\\bigodot':u'⊙', u'\\bigoplus':u'⊕', u'\\bigotimes':u'⊗', u'\\bigsqcup':u'⊔', u'\\bigstar':u'★', u'\\bigtriangledown':u'▽', u'\\bigtriangleup':u'△', u'\\biguplus':u'⊎', u'\\bigvee':u'∨', u'\\bigwedge':u'∧', u'\\biohazard':u'☣', u'\\blacklozenge':u'⧫', u'\\blacksmiley':u'☻', u'\\blacksquare':u'■', u'\\blacktriangle':u'▲', u'\\blacktriangledown':u'▼', u'\\blacktriangleleft':u'◂', u'\\blacktriangleright':u'▶', u'\\blacktriangleup':u'▴', u'\\bot':u'⊥', u'\\bowtie':u'⋈', u'\\box':u'▫', u'\\boxast':u'⧆', u'\\boxbar':u'◫', u'\\boxbox':u'⧈', u'\\boxbslash':u'⧅', u'\\boxcircle':u'⧇', u'\\boxdot':u'⊡', u'\\boxminus':u'⊟', u'\\boxplus':u'⊞', u'\\boxslash':u'⧄', u'\\boxtimes':u'⊠', u'\\bullet':u'•', u'\\bumpeq':u'≏', u'\\cancer':u'♋', u'\\cap':u'∩', u'\\capricornus':u'♑', u'\\cat':u'⁀', u'\\cdot':u'⋅', u'\\cdots':u'⋯', u'\\cent':u'¢', u'\\centerdot':u'∙', u'\\checkmark':u'✓', u'\\chi':u'χ', u'\\circ':u'○', u'\\circeq':u'≗', u'\\circlearrowleft':u'↺', u'\\circlearrowright':u'↻', u'\\circledR':u'®', u'\\circledast':u'⊛', u'\\circledbslash':u'⦸', u'\\circledcirc':u'⊚', u'\\circleddash':u'⊝', u'\\circledgtr':u'⧁', u'\\circledless':u'⧀', u'\\clubsuit':u'♣', u'\\coloneqq':u'≔', u'\\complement':u'∁', u'\\cong':u'≅', u'\\coprod':u'∐', u'\\copyright':u'©', u'\\cos':u'cos', u'\\cosh':u'cosh', u'\\cot':u'cot', u'\\coth':u'coth', u'\\csc':u'csc', u'\\cup':u'∪', u'\\curlyvee':u'⋎', u'\\curlywedge':u'⋏', u'\\curvearrowleft':u'↶', u'\\curvearrowright':u'↷', u'\\dag':u'†', u'\\dagger':u'†', u'\\daleth':u'ℸ', u'\\dashleftarrow':u'⇠', u'\\dashv':u'⊣', u'\\ddag':u'‡', u'\\ddagger':u'‡', u'\\ddots':u'⋱', u'\\deg':u'deg', u'\\det':u'det', u'\\diagdown':u'╲', u'\\diagup':u'╱', u'\\diameter':u'⌀', u'\\diamond':u'◇', u'\\diamondsuit':u'♦', u'\\dim':u'dim', u'\\div':u'÷', u'\\divideontimes':u'⋇', u'\\dotdiv':u'∸', u'\\doteq':u'≐', u'\\doteqdot':u'≑', u'\\dotplus':u'∔', u'\\dots':u'…', u'\\doublebarwedge':u'⌆', u'\\downarrow':u'↓', u'\\downdownarrows':u'⇊', u'\\downharpoonleft':u'⇃', u'\\downharpoonright':u'⇂', u'\\dsub':u'⩤', u'\\earth':u'♁', u'\\eighthnote':u'♪', u'\\ell':u'ℓ', u'\\emptyset':u'∅', u'\\eqcirc':u'≖', u'\\eqcolon':u'≕', u'\\eqsim':u'≂', u'\\euro':u'€', u'\\exists':u'∃', u'\\exp':u'exp', u'\\fallingdotseq':u'≒', u'\\fcmp':u'⨾', u'\\female':u'♀', u'\\flat':u'♭', u'\\forall':u'∀', u'\\fourth':u'⁗', u'\\frown':u'⌢', u'\\frownie':u'☹', u'\\gcd':u'gcd', u'\\gemini':u'♊', u'\\geq)':u'≥', u'\\geqq':u'≧', u'\\geqslant':u'≥', u'\\gets':u'←', u'\\gg':u'≫', u'\\ggg':u'⋙', u'\\gimel':u'ℷ', u'\\gneqq':u'≩', u'\\gnsim':u'⋧', u'\\gtrdot':u'⋗', u'\\gtreqless':u'⋚', u'\\gtreqqless':u'⪌', u'\\gtrless':u'≷', u'\\gtrsim':u'≳', u'\\guillemotleft':u'«', u'\\guillemotright':u'»', u'\\hbar':u'ℏ', u'\\heartsuit':u'♥', u'\\hfill':u' ', u'\\hom':u'hom', u'\\hookleftarrow':u'↩', u'\\hookrightarrow':u'↪', u'\\hslash':u'ℏ', u'\\idotsint':u'∫⋯∫', u'\\iiint':u'', u'\\iint':u'', u'\\imath':u'ı', u'\\inf':u'inf', u'\\infty':u'∞', u'\\intercal':u'⊺', u'\\interleave':u'⫴', u'\\invamp':u'⅋', u'\\invneg':u'⌐', u'\\jmath':u'ȷ', u'\\jupiter':u'♃', u'\\ker':u'ker', u'\\land':u'∧', u'\\landupint':u'', u'\\lang':u'⟪', u'\\langle':u'⟨', u'\\lblot':u'⦉', u'\\lbrace':u'{', u'\\lbrace)':u'{', u'\\lbrack':u'[', u'\\lceil':u'⌈', u'\\ldots':u'…', u'\\leadsto':u'⇝', u'\\leftarrow)':u'←', u'\\leftarrowtail':u'↢', u'\\leftarrowtobar':u'⇤', u'\\leftharpoondown':u'↽', u'\\leftharpoonup':u'↼', u'\\leftleftarrows':u'⇇', u'\\leftleftharpoons':u'⥢', u'\\leftmoon':u'☾', u'\\leftrightarrow':u'↔', u'\\leftrightarrows':u'⇆', u'\\leftrightharpoons':u'⇋', u'\\leftthreetimes':u'⋋', u'\\leo':u'♌', u'\\leq)':u'≤', u'\\leqq':u'≦', u'\\leqslant':u'≤', u'\\lessdot':u'⋖', u'\\lesseqgtr':u'⋛', u'\\lesseqqgtr':u'⪋', u'\\lessgtr':u'≶', u'\\lesssim':u'≲', u'\\lfloor':u'⌊', u'\\lg':u'lg', u'\\lgroup':u'⟮', u'\\lhd':u'⊲', u'\\libra':u'♎', u'\\lightning':u'↯', u'\\limg':u'⦇', u'\\liminf':u'liminf', u'\\limsup':u'limsup', u'\\ll':u'≪', u'\\llbracket':u'⟦', u'\\llcorner':u'⌞', u'\\lll':u'⋘', u'\\ln':u'ln', u'\\lneqq':u'≨', u'\\lnot':u'¬', u'\\lnsim':u'⋦', u'\\log':u'log', u'\\longleftarrow':u'⟵', u'\\longleftrightarrow':u'⟷', u'\\longmapsto':u'⟼', u'\\longrightarrow':u'⟶', u'\\looparrowleft':u'↫', u'\\looparrowright':u'↬', u'\\lor':u'∨', u'\\lozenge':u'◊', u'\\lrcorner':u'⌟', u'\\ltimes':u'⋉', u'\\lyxlock':u'', u'\\male':u'♂', u'\\maltese':u'✠', u'\\mapsfrom':u'↤', u'\\mapsto':u'↦', u'\\mathcircumflex':u'^', u'\\max':u'max', u'\\measuredangle':u'∡', u'\\medbullet':u'⚫', u'\\medcirc':u'⚪', u'\\mercury':u'☿', u'\\mho':u'℧', u'\\mid':u'∣', u'\\min':u'min', u'\\models':u'⊨', u'\\mp':u'∓', u'\\multimap':u'⊸', u'\\nLeftarrow':u'⇍', u'\\nLeftrightarrow':u'⇎', u'\\nRightarrow':u'⇏', u'\\nVDash':u'⊯', u'\\nabla':u'∇', u'\\napprox':u'≉', u'\\natural':u'♮', u'\\ncong':u'≇', u'\\nearrow':u'↗', u'\\neg':u'¬', u'\\neg)':u'¬', u'\\neptune':u'♆', u'\\nequiv':u'≢', u'\\newline':u'
', u'\\nexists':u'∄', u'\\ngeqslant':u'≱', u'\\ngtr':u'≯', u'\\ngtrless':u'≹', u'\\ni':u'∋', u'\\ni)':u'∋', u'\\nleftarrow':u'↚', u'\\nleftrightarrow':u'↮', u'\\nleqslant':u'≰', u'\\nless':u'≮', u'\\nlessgtr':u'≸', u'\\nmid':u'∤', u'\\nolimits':u'', u'\\nonumber':u'', u'\\not':u'¬', u'\\not<':u'≮', u'\\not=':u'≠', u'\\not>':u'≯', u'\\notbackslash':u'⍀', u'\\notin':u'∉', u'\\notni':u'∌', u'\\notslash':u'⌿', u'\\nparallel':u'∦', u'\\nprec':u'⊀', u'\\nrightarrow':u'↛', u'\\nsim':u'≁', u'\\nsimeq':u'≄', u'\\nsqsubset':u'⊏̸', u'\\nsubseteq':u'⊈', u'\\nsucc':u'⊁', u'\\nsucccurlyeq':u'⋡', u'\\nsupset':u'⊅', u'\\nsupseteq':u'⊉', u'\\ntriangleleft':u'⋪', u'\\ntrianglelefteq':u'⋬', u'\\ntriangleright':u'⋫', u'\\ntrianglerighteq':u'⋭', u'\\nvDash':u'⊭', u'\\nvdash':u'⊬', u'\\nwarrow':u'↖', u'\\odot':u'⊙', u'\\officialeuro':u'€', u'\\oiiint':u'', u'\\oiint':u'', u'\\oint':u'', u'\\ointclockwise':u'', u'\\ointctrclockwise':u'', u'\\ominus':u'⊖', u'\\oplus':u'⊕', u'\\oslash':u'⊘', u'\\otimes':u'⊗', u'\\owns':u'∋', u'\\parallel':u'∥', u'\\partial':u'∂', u'\\pencil':u'✎', u'\\perp':u'⊥', u'\\pisces':u'♓', u'\\pitchfork':u'⋔', u'\\pluto':u'♇', u'\\pm':u'±', u'\\pointer':u'➪', u'\\pointright':u'☞', u'\\pounds':u'£', u'\\prec':u'≺', u'\\preccurlyeq':u'≼', u'\\preceq':u'≼', u'\\precsim':u'≾', u'\\prime':u'′', u'\\prompto':u'∝', u'\\qoppa':u'ϙ', u'\\qquad':u' ', u'\\quad':u' ', u'\\quarternote':u'♩', u'\\radiation':u'☢', u'\\rang':u'⟫', u'\\rangle':u'⟩', u'\\rblot':u'⦊', u'\\rbrace':u'}', u'\\rbrace)':u'}', u'\\rbrack':u']', u'\\rceil':u'⌉', u'\\recycle':u'♻', u'\\rfloor':u'⌋', u'\\rgroup':u'⟯', u'\\rhd':u'⊳', u'\\rightangle':u'∟', u'\\rightarrow)':u'→', u'\\rightarrowtail':u'↣', u'\\rightarrowtobar':u'⇥', u'\\rightharpoondown':u'⇁', u'\\rightharpoonup':u'⇀', u'\\rightharpooondown':u'⇁', u'\\rightharpooonup':u'⇀', u'\\rightleftarrows':u'⇄', u'\\rightleftharpoons':u'⇌', u'\\rightmoon':u'☽', u'\\rightrightarrows':u'⇉', u'\\rightrightharpoons':u'⥤', u'\\rightthreetimes':u'⋌', u'\\rimg':u'⦈', u'\\risingdotseq':u'≓', u'\\rrbracket':u'⟧', u'\\rsub':u'⩥', u'\\rtimes':u'⋊', u'\\sagittarius':u'♐', u'\\saturn':u'♄', u'\\scorpio':u'♏', u'\\searrow':u'↘', u'\\sec':u'sec', u'\\second':u'″', u'\\setminus':u'∖', u'\\sharp':u'♯', u'\\simeq':u'≃', u'\\sin':u'sin', u'\\sinh':u'sinh', u'\\sixteenthnote':u'♬', u'\\skull':u'☠', u'\\slash':u'∕', u'\\smallsetminus':u'∖', u'\\smalltriangledown':u'▿', u'\\smalltriangleleft':u'◃', u'\\smalltriangleright':u'▹', u'\\smalltriangleup':u'▵', u'\\smile':u'⌣', u'\\smiley':u'☺', u'\\spadesuit':u'♠', u'\\spddot':u'¨', u'\\sphat':u'', u'\\sphericalangle':u'∢', u'\\spot':u'⦁', u'\\sptilde':u'~', u'\\sqcap':u'⊓', u'\\sqcup':u'⊔', u'\\sqsubset':u'⊏', u'\\sqsubseteq':u'⊑', u'\\sqsupset':u'⊐', u'\\sqsupseteq':u'⊒', u'\\square':u'□', u'\\sslash':u'⫽', u'\\star':u'⋆', u'\\steaming':u'☕', u'\\subseteqq':u'⫅', u'\\subsetneqq':u'⫋', u'\\succ':u'≻', u'\\succcurlyeq':u'≽', u'\\succeq':u'≽', u'\\succnsim':u'⋩', u'\\succsim':u'≿', u'\\sun':u'☼', u'\\sup':u'sup', u'\\supseteqq':u'⫆', u'\\supsetneqq':u'⫌', u'\\surd':u'√', u'\\swarrow':u'↙', u'\\swords':u'⚔', u'\\talloblong':u'⫾', u'\\tan':u'tan', u'\\tanh':u'tanh', u'\\taurus':u'♉', u'\\textasciicircum':u'^', u'\\textasciitilde':u'~', u'\\textbackslash':u'\\', u'\\textcopyright':u'©\'', u'\\textdegree':u'°', u'\\textellipsis':u'…', u'\\textemdash':u'—', u'\\textendash':u'—', u'\\texteuro':u'€', u'\\textgreater':u'>', u'\\textless':u'<', u'\\textordfeminine':u'ª', u'\\textordmasculine':u'º', u'\\textquotedblleft':u'“', u'\\textquotedblright':u'”', u'\\textquoteright':u'’', u'\\textregistered':u'®', u'\\textrightarrow':u'→', u'\\textsection':u'§', u'\\texttrademark':u'™', u'\\texttwosuperior':u'²', u'\\textvisiblespace':u' ', u'\\therefore':u'∴', u'\\third':u'‴', u'\\top':u'⊤', u'\\triangle':u'△', u'\\triangleleft':u'⊲', u'\\trianglelefteq':u'⊴', u'\\triangleq':u'≜', u'\\triangleright':u'▷', u'\\trianglerighteq':u'⊵', u'\\twoheadleftarrow':u'↞', u'\\twoheadrightarrow':u'↠', u'\\twonotes':u'♫', u'\\udot':u'⊍', u'\\ulcorner':u'⌜', u'\\unlhd':u'⊴', u'\\unrhd':u'⊵', u'\\unrhl':u'⊵', u'\\uparrow':u'↑', u'\\updownarrow':u'↕', u'\\upharpoonleft':u'↿', u'\\upharpoonright':u'↾', u'\\uplus':u'⊎', u'\\upuparrows':u'⇈', u'\\uranus':u'♅', u'\\urcorner':u'⌝', u'\\vDash':u'⊨', u'\\varclubsuit':u'♧', u'\\vardiamondsuit':u'♦', u'\\varheartsuit':u'♥', u'\\varnothing':u'∅', u'\\varspadesuit':u'♤', u'\\vdash':u'⊢', u'\\vdots':u'⋮', u'\\vee':u'∨', u'\\vee)':u'∨', u'\\veebar':u'⊻', u'\\vert':u'∣', u'\\virgo':u'♍', u'\\warning':u'⚠', u'\\wasylozenge':u'⌑', u'\\wedge':u'∧', u'\\wedge)':u'∧', u'\\wp':u'℘', u'\\wr':u'≀', u'\\yen':u'¥', u'\\yinyang':u'☯', u'\\{':u'{', u'\\|':u'∥', u'\\}':u'}', } decoratedcommand = { } decoratingfunctions = { u'\\overleftarrow':u'⟵', u'\\overrightarrow':u'⟶', u'\\widehat':u'^', } endings = { u'bracket':u'}', u'complex':u'\\]', u'endafter':u'}', u'endbefore':u'\\end{', u'squarebracket':u']', } environments = { u'align':[u'r',u'l',], u'eqnarray':[u'r',u'c',u'l',], u'gathered':[u'l',u'l',], } fontfunctions = { u'\\boldsymbol':u'b', u'\\mathbb':u'span class="blackboard"', u'\\mathbb{A}':u'𝔸', u'\\mathbb{B}':u'𝔹', u'\\mathbb{C}':u'ℂ', u'\\mathbb{D}':u'𝔻', u'\\mathbb{E}':u'𝔼', u'\\mathbb{F}':u'𝔽', u'\\mathbb{G}':u'𝔾', u'\\mathbb{H}':u'ℍ', u'\\mathbb{J}':u'𝕁', u'\\mathbb{K}':u'𝕂', u'\\mathbb{L}':u'𝕃', u'\\mathbb{N}':u'ℕ', u'\\mathbb{O}':u'𝕆', u'\\mathbb{P}':u'ℙ', u'\\mathbb{Q}':u'ℚ', u'\\mathbb{R}':u'ℝ', u'\\mathbb{S}':u'𝕊', u'\\mathbb{T}':u'𝕋', u'\\mathbb{W}':u'𝕎', u'\\mathbb{Z}':u'ℤ', u'\\mathbf':u'b', u'\\mathcal':u'span class="scriptfont"', u'\\mathcal{B}':u'ℬ', u'\\mathcal{E}':u'ℰ', u'\\mathcal{F}':u'ℱ', u'\\mathcal{H}':u'ℋ', u'\\mathcal{I}':u'ℐ', u'\\mathcal{L}':u'ℒ', u'\\mathcal{M}':u'ℳ', u'\\mathcal{R}':u'ℛ', u'\\mathfrak':u'span class="fraktur"', u'\\mathfrak{C}':u'ℭ', u'\\mathfrak{F}':u'𝔉', u'\\mathfrak{H}':u'ℌ', u'\\mathfrak{I}':u'ℑ', u'\\mathfrak{R}':u'ℜ', u'\\mathfrak{Z}':u'ℨ', u'\\mathit':u'i', u'\\mathring{A}':u'Å', u'\\mathring{U}':u'Ů', u'\\mathring{a}':u'å', u'\\mathring{u}':u'ů', u'\\mathring{w}':u'ẘ', u'\\mathring{y}':u'ẙ', u'\\mathrm':u'span class="mathrm"', u'\\mathscr':u'span class="scriptfont"', u'\\mathscr{B}':u'ℬ', u'\\mathscr{E}':u'ℰ', u'\\mathscr{F}':u'ℱ', u'\\mathscr{H}':u'ℋ', u'\\mathscr{I}':u'ℐ', u'\\mathscr{L}':u'ℒ', u'\\mathscr{M}':u'ℳ', u'\\mathscr{R}':u'ℛ', u'\\mathsf':u'span class="mathsf"', u'\\mathtt':u'tt', } hybridfunctions = { u'\\addcontentsline':[u'{$p!}{$q!}{$r!}',u'f0{}',u'ignored',], u'\\addtocontents':[u'{$p!}{$q!}',u'f0{}',u'ignored',], u'\\backmatter':[u'',u'f0{}',u'ignored',], u'\\binom':[u'{$1}{$2}',u'f2{(}f0{f1{$1}f1{$2}}f2{)}',u'span class="binom"',u'span class="binomstack"',u'span class="bigsymbol"',], u'\\boxed':[u'{$1}',u'f0{$1}',u'span class="boxed"',], u'\\cfrac':[u'[$p!]{$1}{$2}',u'f0{f3{(}f1{$1}f3{)/(}f2{$2}f3{)}}',u'span class="fullfraction"',u'span class="numerator align-$p"',u'span class="denominator"',u'span class="ignored"',], u'\\color':[u'{$p!}{$1}',u'f0{$1}',u'span style="color: $p;"',], u'\\colorbox':[u'{$p!}{$1}',u'f0{$1}',u'span class="colorbox" style="background: $p;"',], u'\\dbinom':[u'{$1}{$2}',u'(f0{f1{f2{$1}}f1{f2{ }}f1{f2{$2}}})',u'span class="binomial"',u'span class="binomrow"',u'span class="binomcell"',], u'\\dfrac':[u'{$1}{$2}',u'f0{f3{(}f1{$1}f3{)/(}f2{$2}f3{)}}',u'span class="fullfraction"',u'span class="numerator"',u'span class="denominator"',u'span class="ignored"',], u'\\displaystyle':[u'{$1}',u'f0{$1}',u'span class="displaystyle"',], u'\\fancyfoot':[u'[$p!]{$q!}',u'f0{}',u'ignored',], u'\\fancyhead':[u'[$p!]{$q!}',u'f0{}',u'ignored',], u'\\fbox':[u'{$1}',u'f0{$1}',u'span class="fbox"',], u'\\fboxrule':[u'{$p!}',u'f0{}',u'ignored',], u'\\fboxsep':[u'{$p!}',u'f0{}',u'ignored',], u'\\fcolorbox':[u'{$p!}{$q!}{$1}',u'f0{$1}',u'span class="boxed" style="border-color: $p; background: $q;"',], u'\\frac':[u'{$1}{$2}',u'f0{f3{(}f1{$1}f3{)/(}f2{$2}f3{)}}',u'span class="fraction"',u'span class="numerator"',u'span class="denominator"',u'span class="ignored"',], u'\\framebox':[u'[$p!][$q!]{$1}',u'f0{$1}',u'span class="framebox align-$q" style="width: $p;"',], u'\\frontmatter':[u'',u'f0{}',u'ignored',], u'\\href':[u'[$o]{$u!}{$t!}',u'f0{$t}',u'a href="$u"',], u'\\hspace':[u'{$p!}',u'f0{ }',u'span class="hspace" style="width: $p;"',], u'\\leftroot':[u'{$p!}',u'f0{ }',u'span class="leftroot" style="width: $p;px"',], u'\\mainmatter':[u'',u'f0{}',u'ignored',], u'\\markboth':[u'{$p!}{$q!}',u'f0{}',u'ignored',], u'\\markright':[u'{$p!}',u'f0{}',u'ignored',], u'\\nicefrac':[u'{$1}{$2}',u'f0{f1{$1}⁄f2{$2}}',u'span class="fraction"',u'sup class="numerator"',u'sub class="denominator"',u'span class="ignored"',], u'\\parbox':[u'[$p!]{$w!}{$1}',u'f0{1}',u'div class="Boxed" style="width: $w;"',], u'\\raisebox':[u'{$p!}{$1}',u'f0{$1.font}',u'span class="raisebox" style="vertical-align: $p;"',], u'\\renewenvironment':[u'{$1!}{$2!}{$3!}',u'',], u'\\rule':[u'[$v!]{$w!}{$h!}',u'f0/',u'hr class="line" style="width: $w; height: $h;"',], u'\\scriptscriptstyle':[u'{$1}',u'f0{$1}',u'span class="scriptscriptstyle"',], u'\\scriptstyle':[u'{$1}',u'f0{$1}',u'span class="scriptstyle"',], u'\\sqrt':[u'[$0]{$1}',u'f0{f1{$0}f2{√}f4{(}f3{$1}f4{)}}',u'span class="sqrt"',u'sup class="root"',u'span class="radical"',u'span class="root"',u'span class="ignored"',], u'\\stackrel':[u'{$1}{$2}',u'f0{f1{$1}f2{$2}}',u'span class="stackrel"',u'span class="upstackrel"',u'span class="downstackrel"',], u'\\tbinom':[u'{$1}{$2}',u'(f0{f1{f2{$1}}f1{f2{ }}f1{f2{$2}}})',u'span class="binomial"',u'span class="binomrow"',u'span class="binomcell"',], u'\\textcolor':[u'{$p!}{$1}',u'f0{$1}',u'span style="color: $p;"',], u'\\textstyle':[u'{$1}',u'f0{$1}',u'span class="textstyle"',], u'\\thispagestyle':[u'{$p!}',u'f0{}',u'ignored',], u'\\unit':[u'[$0]{$1}',u'$0f0{$1.font}',u'span class="unit"',], u'\\unitfrac':[u'[$0]{$1}{$2}',u'$0f0{f1{$1.font}⁄f2{$2.font}}',u'span class="fraction"',u'sup class="unit"',u'sub class="unit"',], u'\\uproot':[u'{$p!}',u'f0{ }',u'span class="uproot" style="width: $p;px"',], u'\\url':[u'{$u!}',u'f0{$u}',u'a href="$u"',], u'\\vspace':[u'{$p!}',u'f0{ }',u'span class="vspace" style="height: $p;"',], } hybridsizes = { u'\\binom':u'$1+$2', u'\\cfrac':u'$1+$2', u'\\dbinom':u'$1+$2+1', u'\\dfrac':u'$1+$2', u'\\frac':u'$1+$2', u'\\tbinom':u'$1+$2+1', } labelfunctions = { u'\\label':u'a name="#"', } limitcommands = { u'\\biginterleave':u'⫼', u'\\bigsqcap':u'⨅', u'\\fint':u'⨏', u'\\iiiint':u'⨌', u'\\int':u'∫', u'\\intop':u'∫', u'\\lim':u'lim', u'\\prod':u'∏', u'\\smallint':u'∫', u'\\sqint':u'⨖', u'\\sum':u'∑', u'\\varointclockwise':u'∲', u'\\varprod':u'⨉', u'\\zcmp':u'⨟', u'\\zhide':u'⧹', u'\\zpipe':u'⨠', u'\\zproject':u'⨡', } misccommands = { u'\\limits':u'LimitPreviousCommand', u'\\newcommand':u'MacroDefinition', u'\\renewcommand':u'MacroDefinition', u'\\setcounter':u'SetCounterFunction', u'\\tag':u'FormulaTag', u'\\tag*':u'FormulaTag', u'\\today':u'TodayCommand', } modified = { u'\n':u'', u' ':u'', u'$':u'', u'&':u' ', u'\'':u'’', u'+':u' + ', u',':u', ', u'-':u' − ', u'/':u' ⁄ ', u'<':u' < ', u'=':u' = ', u'>':u' > ', u'@':u'', u'~':u'', } onefunctions = { u'\\Big':u'span class="bigsymbol"', u'\\Bigg':u'span class="hugesymbol"', u'\\bar':u'span class="bar"', u'\\begin{array}':u'span class="arraydef"', u'\\big':u'span class="symbol"', u'\\bigg':u'span class="largesymbol"', u'\\bigl':u'span class="bigsymbol"', u'\\bigr':u'span class="bigsymbol"', u'\\centering':u'span class="align-center"', u'\\ensuremath':u'span class="ensuremath"', u'\\hphantom':u'span class="phantom"', u'\\noindent':u'span class="noindent"', u'\\overbrace':u'span class="overbrace"', u'\\overline':u'span class="overline"', u'\\phantom':u'span class="phantom"', u'\\underbrace':u'span class="underbrace"', u'\\underline':u'u', u'\\vphantom':u'span class="phantom"', } spacedcommands = { u'\\Bot':u'⫫', u'\\Doteq':u'≑', u'\\DownArrowBar':u'⤓', u'\\DownLeftTeeVector':u'⥞', u'\\DownLeftVectorBar':u'⥖', u'\\DownRightTeeVector':u'⥟', u'\\DownRightVectorBar':u'⥗', u'\\Equal':u'⩵', u'\\LeftArrowBar':u'⇤', u'\\LeftDownTeeVector':u'⥡', u'\\LeftDownVectorBar':u'⥙', u'\\LeftTeeVector':u'⥚', u'\\LeftTriangleBar':u'⧏', u'\\LeftUpTeeVector':u'⥠', u'\\LeftUpVectorBar':u'⥘', u'\\LeftVectorBar':u'⥒', u'\\Leftrightarrow':u'⇔', u'\\Longmapsfrom':u'⟽', u'\\Longmapsto':u'⟾', u'\\MapsDown':u'↧', u'\\MapsUp':u'↥', u'\\Nearrow':u'⇗', u'\\NestedGreaterGreater':u'⪢', u'\\NestedLessLess':u'⪡', u'\\NotGreaterLess':u'≹', u'\\NotGreaterTilde':u'≵', u'\\NotLessTilde':u'≴', u'\\Nwarrow':u'⇖', u'\\Proportion':u'∷', u'\\RightArrowBar':u'⇥', u'\\RightDownTeeVector':u'⥝', u'\\RightDownVectorBar':u'⥕', u'\\RightTeeVector':u'⥛', u'\\RightTriangleBar':u'⧐', u'\\RightUpTeeVector':u'⥜', u'\\RightUpVectorBar':u'⥔', u'\\RightVectorBar':u'⥓', u'\\Rightarrow':u'⇒', u'\\Same':u'⩶', u'\\Searrow':u'⇘', u'\\Swarrow':u'⇙', u'\\Top':u'⫪', u'\\UpArrowBar':u'⤒', u'\\VDash':u'⊫', u'\\approx':u'≈', u'\\approxeq':u'≊', u'\\backsim':u'∽', u'\\barin':u'⋶', u'\\barleftharpoon':u'⥫', u'\\barrightharpoon':u'⥭', u'\\bij':u'⤖', u'\\coloneq':u'≔', u'\\corresponds':u'≙', u'\\curlyeqprec':u'⋞', u'\\curlyeqsucc':u'⋟', u'\\dashrightarrow':u'⇢', u'\\dlsh':u'↲', u'\\downdownharpoons':u'⥥', u'\\downuparrows':u'⇵', u'\\downupharpoons':u'⥯', u'\\drsh':u'↳', u'\\eqslantgtr':u'⪖', u'\\eqslantless':u'⪕', u'\\equiv':u'≡', u'\\ffun':u'⇻', u'\\finj':u'⤕', u'\\ge':u'≥', u'\\geq':u'≥', u'\\ggcurly':u'⪼', u'\\gnapprox':u'⪊', u'\\gneq':u'⪈', u'\\gtrapprox':u'⪆', u'\\hash':u'⋕', u'\\iddots':u'⋰', u'\\implies':u' ⇒ ', u'\\in':u'∈', u'\\le':u'≤', u'\\leftarrow':u'←', u'\\leftarrowtriangle':u'⇽', u'\\leftbarharpoon':u'⥪', u'\\leftrightarrowtriangle':u'⇿', u'\\leftrightharpoon':u'⥊', u'\\leftrightharpoondown':u'⥐', u'\\leftrightharpoonup':u'⥎', u'\\leftrightsquigarrow':u'↭', u'\\leftslice':u'⪦', u'\\leftsquigarrow':u'⇜', u'\\leftupdownharpoon':u'⥑', u'\\leq':u'≤', u'\\lessapprox':u'⪅', u'\\llcurly':u'⪻', u'\\lnapprox':u'⪉', u'\\lneq':u'⪇', u'\\longmapsfrom':u'⟻', u'\\multimapboth':u'⧟', u'\\multimapdotbothA':u'⊶', u'\\multimapdotbothB':u'⊷', u'\\multimapinv':u'⟜', u'\\nVdash':u'⊮', u'\\ne':u'≠', u'\\neq':u'≠', u'\\ngeq':u'≱', u'\\nleq':u'≰', u'\\nni':u'∌', u'\\not\\in':u'∉', u'\\notasymp':u'≭', u'\\npreceq':u'⋠', u'\\nsqsubseteq':u'⋢', u'\\nsqsupseteq':u'⋣', u'\\nsubset':u'⊄', u'\\nsucceq':u'⋡', u'\\pfun':u'⇸', u'\\pinj':u'⤔', u'\\precapprox':u'⪷', u'\\preceqq':u'⪳', u'\\precnapprox':u'⪹', u'\\precnsim':u'⋨', u'\\propto':u'∝', u'\\psur':u'⤀', u'\\rightarrow':u'→', u'\\rightarrowtriangle':u'⇾', u'\\rightbarharpoon':u'⥬', u'\\rightleftharpoon':u'⥋', u'\\rightslice':u'⪧', u'\\rightsquigarrow':u'⇝', u'\\rightupdownharpoon':u'⥏', u'\\sim':u'~', u'\\strictfi':u'⥼', u'\\strictif':u'⥽', u'\\subset':u'⊂', u'\\subseteq':u'⊆', u'\\subsetneq':u'⊊', u'\\succapprox':u'⪸', u'\\succeqq':u'⪴', u'\\succnapprox':u'⪺', u'\\supset':u'⊃', u'\\supseteq':u'⊇', u'\\supsetneq':u'⊋', u'\\times':u'×', u'\\to':u'→', u'\\updownarrows':u'⇅', u'\\updownharpoons':u'⥮', u'\\upupharpoons':u'⥣', u'\\vartriangleleft':u'⊲', u'\\vartriangleright':u'⊳', } starts = { u'beginafter':u'}', u'beginbefore':u'\\begin{', u'bracket':u'{', u'command':u'\\', u'comment':u'%', u'complex':u'\\[', u'simple':u'$', u'squarebracket':u'[', u'unnumbered':u'*', } symbolfunctions = { u'^':u'sup', u'_':u'sub', } textfunctions = { u'\\mbox':u'span class="mbox"', u'\\text':u'span class="text"', u'\\textbf':u'b', u'\\textipa':u'span class="textipa"', u'\\textit':u'i', u'\\textnormal':u'span class="textnormal"', u'\\textrm':u'span class="textrm"', u'\\textsc':u'span class="versalitas"', u'\\textsf':u'span class="textsf"', u'\\textsl':u'i', u'\\texttt':u'tt', u'\\textup':u'span class="normal"', } unmodified = { u'characters':[u'.',u'*',u'€',u'(',u')',u'[',u']',u':',u'·',u'!',u';',u'|',u'§',u'"',], } urls = { u'googlecharts':u'http://chart.googleapis.com/chart?cht=tx&chl=', } class GeneralConfig(object): "Configuration class from elyxer.config file" version = { u'date':u'2013-03-10', u'lyxformat':u'413', u'number':u'1.2.4', } class HeaderConfig(object): "Configuration class from elyxer.config file" parameters = { u'beginpreamble':u'\\begin_preamble', u'branch':u'\\branch', u'documentclass':u'\\textclass', u'endbranch':u'\\end_branch', u'endpreamble':u'\\end_preamble', u'language':u'\\language', u'lstset':u'\\lstset', u'outputchanges':u'\\output_changes', u'paragraphseparation':u'\\paragraph_separation', u'pdftitle':u'\\pdf_title', u'secnumdepth':u'\\secnumdepth', u'tocdepth':u'\\tocdepth', } styles = { u'article':[u'article',u'aastex',u'aapaper',u'acmsiggraph',u'sigplanconf',u'achemso',u'amsart',u'apa',u'arab-article',u'armenian-article',u'article-beamer',u'chess',u'dtk',u'elsarticle',u'heb-article',u'IEEEtran',u'iopart',u'kluwer',u'scrarticle-beamer',u'scrartcl',u'extarticle',u'paper',u'mwart',u'revtex4',u'spie',u'svglobal3',u'ltugboat',u'agu-dtd',u'jgrga',u'agums',u'entcs',u'egs',u'ijmpc',u'ijmpd',u'singlecol-new',u'doublecol-new',u'isprs',u'tarticle',u'jsarticle',u'jarticle',u'jss',u'literate-article',u'siamltex',u'cl2emult',u'llncs',u'svglobal',u'svjog',u'svprobth',], u'book':[u'book',u'amsbook',u'scrbook',u'extbook',u'tufte-book',u'report',u'extreport',u'scrreprt',u'memoir',u'tbook',u'jsbook',u'jbook',u'mwbk',u'svmono',u'svmult',u'treport',u'jreport',u'mwrep',], } class ImageConfig(object): "Configuration class from elyxer.config file" converters = { u'imagemagick':u'convert[ -density $scale][ -define $format:use-cropbox=true] "$input" "$output"', u'inkscape':u'inkscape "$input" --export-png="$output"', u'lyx':u'lyx -C "$input" "$output"', } cropboxformats = { u'.eps':u'ps', u'.pdf':u'pdf', u'.ps':u'ps', } formats = { u'default':u'.png', u'vector':[u'.svg',u'.eps',], } class LayoutConfig(object): "Configuration class from elyxer.config file" groupable = { u'allowed':[u'StringContainer',u'Constant',u'TaggedText',u'Align',u'TextFamily',u'EmphaticText',u'VersalitasText',u'BarredText',u'SizeText',u'ColorText',u'LangLine',u'Formula',], } class NewfangleConfig(object): "Configuration class from elyxer.config file" constants = { u'chunkref':u'chunkref{', u'endcommand':u'}', u'endmark':u'>', u'startcommand':u'\\', u'startmark':u'=<', } class NumberingConfig(object): "Configuration class from elyxer.config file" layouts = { u'ordered':[u'Chapter',u'Section',u'Subsection',u'Subsubsection',u'Paragraph',], u'roman':[u'Part',u'Book',], } sequence = { u'symbols':[u'*',u'**',u'†',u'‡',u'§',u'§§',u'¶',u'¶¶',u'#',u'##',], } class StyleConfig(object): "Configuration class from elyxer.config file" hspaces = { u'\\enskip{}':u' ', u'\\hfill{}':u' ', u'\\hspace*{\\fill}':u' ', u'\\hspace*{}':u'', u'\\hspace{}':u' ', u'\\negthinspace{}':u'', u'\\qquad{}':u'  ', u'\\quad{}':u' ', u'\\space{}':u' ', u'\\thinspace{}':u' ', u'~':u' ', } quotes = { u'ald':u'»', u'als':u'›', u'ard':u'«', u'ars':u'‹', u'eld':u'“', u'els':u'‘', u'erd':u'”', u'ers':u'’', u'fld':u'«', u'fls':u'‹', u'frd':u'»', u'frs':u'›', u'gld':u'„', u'gls':u'‚', u'grd':u'“', u'grs':u'‘', u'pld':u'„', u'pls':u'‚', u'prd':u'”', u'prs':u'’', u'sld':u'”', u'srd':u'”', } referenceformats = { u'eqref':u'(@↕)', u'formatted':u'¶↕', u'nameref':u'$↕', u'pageref':u'#↕', u'ref':u'@↕', u'vpageref':u'on-page#↕', u'vref':u'@on-page#↕', } size = { u'ignoredtexts':[u'col',u'text',u'line',u'page',u'theight',u'pheight',], } vspaces = { u'bigskip':u'
', u'defskip':u'
', u'medskip':u'
', u'smallskip':u'
', u'vfill':u'
', } class TOCConfig(object): "Configuration class from elyxer.config file" extractplain = { u'allowed':[u'StringContainer',u'Constant',u'TaggedText',u'Align',u'TextFamily',u'EmphaticText',u'VersalitasText',u'BarredText',u'SizeText',u'ColorText',u'LangLine',u'Formula',], u'cloned':[u'',], u'extracted':[u'',], } extracttitle = { u'allowed':[u'StringContainer',u'Constant',u'Space',], u'cloned':[u'TextFamily',u'EmphaticText',u'VersalitasText',u'BarredText',u'SizeText',u'ColorText',u'LangLine',u'Formula',], u'extracted':[u'PlainLayout',u'TaggedText',u'Align',u'Caption',u'StandardLayout',u'FlexInset',], } class TagConfig(object): "Configuration class from elyxer.config file" barred = { u'under':u'u', } family = { u'sans':u'span class="sans"', u'typewriter':u'tt', } flex = { u'CharStyle:Code':u'span class="code"', u'CharStyle:MenuItem':u'span class="menuitem"', u'Code':u'span class="code"', u'MenuItem':u'span class="menuitem"', u'Noun':u'span class="noun"', u'Strong':u'span class="strong"', } group = { u'layouts':[u'Quotation',u'Quote',], } layouts = { u'Center':u'div', u'Chapter':u'h?', u'Date':u'h2', u'Paragraph':u'div', u'Part':u'h1', u'Quotation':u'blockquote', u'Quote':u'blockquote', u'Section':u'h?', u'Subsection':u'h?', u'Subsubsection':u'h?', } listitems = { u'Enumerate':u'ol', u'Itemize':u'ul', } notes = { u'Comment':u'', u'Greyedout':u'span class="greyedout"', u'Note':u'', } script = { u'subscript':u'sub', u'superscript':u'sup', } shaped = { u'italic':u'i', u'slanted':u'i', u'smallcaps':u'span class="versalitas"', } class TranslationConfig(object): "Configuration class from elyxer.config file" constants = { u'Appendix':u'Appendix', u'Book':u'Book', u'Chapter':u'Chapter', u'Paragraph':u'Paragraph', u'Part':u'Part', u'Section':u'Section', u'Subsection':u'Subsection', u'Subsubsection':u'Subsubsection', u'abstract':u'Abstract', u'bibliography':u'Bibliography', u'figure':u'figure', u'float-algorithm':u'Algorithm ', u'float-figure':u'Figure ', u'float-listing':u'Listing ', u'float-table':u'Table ', u'float-tableau':u'Tableau ', u'footnotes':u'Footnotes', u'generated-by':u'Document generated by ', u'generated-on':u' on ', u'index':u'Index', u'jsmath-enable':u'Please enable JavaScript on your browser.', u'jsmath-requires':u' requires JavaScript to correctly process the mathematics on this page. ', u'jsmath-warning':u'Warning: ', u'list-algorithm':u'List of Algorithms', u'list-figure':u'List of Figures', u'list-table':u'List of Tables', u'list-tableau':u'List of Tableaux', u'main-page':u'Main page', u'next':u'Next', u'nomenclature':u'Nomenclature', u'on-page':u' on page ', u'prev':u'Prev', u'references':u'References', u'toc':u'Table of Contents', u'toc-for':u'Contents for ', u'up':u'Up', } languages = { u'american':u'en', u'british':u'en', u'deutsch':u'de', u'dutch':u'nl', u'english':u'en', u'french':u'fr', u'ngerman':u'de', u'russian':u'ru', u'spanish':u'es', } elyxer-1.2.5/forks/jras-elyxer/src/elyxer/conf/importconfig.py0000644000175000017500000001227712117061342024032 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20090617 # eLyXer import configuration file from elyxer.util.trace import Trace from elyxer.io.fileline import * from elyxer.conf.fileconfig import * class ImportFile(object): "Generic import file." def __init__(self, filename): self.reader = LineReader(filename) self.objects = dict() self.section = 'FormulaConfig.commands' self.objects[self.section] = dict() self.sectionobject = self.objects[self.section] self.serializer = ConfigSerializer(ImportCommands.escapes) self.existing = dict() self.existing.update(FormulaConfig.commands) self.existing.update(FormulaConfig.alphacommands) self.existing.update(FormulaConfig.spacedcommands) def parsewhole(self, parseline): "Parse the whole file line by line." while not self.reader.finished(): line = self.convertline(self.reader.currentline()) if line: parseline(line) self.reader.nextline() def convertline(self, line): "Convert a single line removing comments." if line == '': return None if line.startswith('#'): return None if '#' in line: line = line.split('#')[0] return line def setsymbol(self, command, unicodesymbol): "Set the unicode symbol for a command." if not command.startswith('\\'): Trace.error('Invalid command ' + command) return if command.count('\\') > 1: Trace.error('Too many commands ' + command) return if command in self.existing: return self.sectionobject[command] = unicodesymbol class ImportCommands(ImportFile): "Import a LyX unicodesymbols file" escapes = [ ('\\', '\\\\') ] def parse(self): "Parse the whole LyX commands file." self.parsewhole(self.parseparam) return self def parseparam(self, line): "Parse a parameter line" line = line.strip() if len(line) == 0: return pieces = line.split() if len(pieces) < 5: return unicode = pieces[0] if not unicode.startswith('0x'): Trace.error('Invalid unicode ' + unicode) return unicode = unicode.replace('0x', '') unicodechar = unichr(int(unicode, 16)) command = pieces[4].replace('"', '') command = self.serializer.unescape(command) self.setsymbol(command, unicodechar) class ImportCsv(ImportFile): "Import a file with comma-separated values of the form: \command,unicode." def parse(self): "Parse the whole CSV file." self.parsewhole(self.parsecsv) return self def parsecsv(self, line): "Parse a line \command,unicode." line = line.strip() if len(line) == 0: return pieces = line.split(',') if len(pieces) != 2: return self.setsymbol(pieces[0],pieces[1]) class ImportUnimath(ImportFile): "Import a file in unimath format." "See http://milde.users.sourceforge.net/LUCR/Math/" def parse(self): "Parse the whole unimath file." self.parsewhole(self.parseunimath) return self def parseunimath(self, line): "Parse a line \command,unicode." line = line.strip() if len(line) == 0: return pieces = line.split('^') if len(pieces) != 8: Trace.error('Weird line: ' + line) return symbol = pieces[1] command = pieces[2] if command == '' or not command.startswith('\\'): return mathclass = pieces[4] mathcategory = pieces[5] if mathcategory in ['mathord', 'mathbin', 'mathopen', 'mathclose']: # plain old command self.add(symbol, command, 'FormulaConfig.commands') elif mathcategory in ['mathalpha']: # alpha command self.add(symbol, command, 'FormulaConfig.alphacommands') elif mathcategory in ['mathaccent', 'mathfence', 'mathradical', 'mathover', 'mathunder', '']: # ignore Trace.error('Ignoring ' + symbol + ' with category ' + mathcategory) elif mathcategory in ['mathop']: self.add(symbol, command, 'FormulaConfig.limitcommands') elif mathcategory in ['mathrel']: self.add(symbol, command, 'FormulaConfig.spacedcommands') else: Trace.error('Unknown math category ' + mathcategory + ' for ' + symbol) def add(self, symbol, command, category): "Add a symbol to a category." if not category in self.objects: self.objects[category] = dict() self.sectionobject = self.objects[category] if command == '': return if '{' in command or '}' in command or '[' in command or ']' in command: return self.setsymbol(command, symbol) elyxer-1.2.5/forks/jras-elyxer/src/elyxer/conf/jtp.cfg0000644000175000017500000000413712117061342022232 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009-2010 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- [GeneralConfig.version] date:2010-03-11 number:0.1 [JavaToPyConfig.declarations] $file:[$class]+ $class:$scope class $classname $inheritance { [$method]* } $scope:public|private|protected $classname:$$ $inheritance:[extends $classlist]? [implements $classlist]? $classlist:[$classname]?[, $classname]* $method:$scope [$qualifier]* $type $methodname ( $paramsdeclaration ) { $block } $methodname:$$ $paramsdeclaration:[$paramdeclaration]?[,$paramdeclaration]* $paramdeclaration:$type $variablename $variablename:$$ $qualifier:static|final $type:int|String|$classname $conditional:if ($condition) $block $condition:$value|$logicalvalue $logicalvalue:$orvalue|$andvalue $orvalue:$value || $value $andvalue:$value && $value $block:[$statement]* $statement:$conditional|$declaration|$assignment|$methodcall $methodcall:$variablename[.$methodname($params)]+ $params:[$value]?[,$value]+ $value:$variablename|$methodcall|$arithmeticexpression $arithmeticexpression:$value + $value $declaration:$simpledeclaration|$declarationassignment $simpledeclaration:$type $variablename; $declarationassignment:$type $variablename = $value; $assignment:$variablename = $value; [JavaToPyConfig.output] $class:class $classname(object):\n\t[$method]* $classname:$classname $method:def $methodname:\n\t$block $conditional:if $condition:\n\t$block elyxer-1.2.5/forks/jras-elyxer/src/elyxer/conf/javatopyconf.py0000644000175000017500000000400012117061342024016 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer configuration # autogenerated from elyxer.config file on 2010-03-15 class GeneralConfig(object): "Configuration class from elyxer.config file" version = { u'date':u'2010-03-15', u'number':u'0.1', } class JavaToPyConfig(object): "Configuration class from elyxer.config file" declarations = { u'$andvalue':u'$value && $value', u'$arithmeticexpression':u'$value + $value', u'$assignment':u'$variablename = $value;', u'$block':u'[$statement]*', u'$class':u'$scope class $classname $inheritance { [$method]* }', u'$classlist':u'[$classname]?[, $classname]*', u'$classname':u'$$', u'$condition':u'$value|$logicalvalue', u'$conditional':u'if ($condition) $block', u'$declaration':u'$simpledeclaration|$declarationassignment', u'$declarationassignment':u'$type $variablename = $value;', u'$file':u'[$class]+', u'$inheritance':u'[extends $classlist]? [implements $classlist]?', u'$logicalvalue':u'$orvalue|$andvalue', u'$method':u'$scope [$qualifier]* $type $methodname ( $paramsdeclaration ) { $block }', u'$methodcall':u'$variablename[.$methodname($params)]+', u'$methodname':u'$$', u'$orvalue':u'$value || $value', u'$paramdeclaration':u'$type $variablename', u'$params':u'[$value]?[,$value]+', u'$paramsdeclaration':u'[$paramdeclaration]?[,$paramdeclaration]*', u'$qualifier':u'static|final', u'$scope':u'public|private|protected', u'$simpledeclaration':u'$type $variablename;', u'$statement':u'$conditional|$declaration|$assignment|$methodcall', u'$type':u'int|String|$classname', u'$value':u'$variablename|$methodcall|$arithmeticexpression', u'$variablename':u'$$', } output = { u'$class':u'class $classname(object):\\n\\t[$method]*', u'$classname':u'$classname', u'$conditional':u'if $condition:\\n\\t$block', u'$method':u'def $methodname:\\n\\t$block', } elyxer-1.2.5/forks/jras-elyxer/src/elyxer/conf/__init__.py0000644000175000017500000000000012117061342023046 0ustar chennochennoelyxer-1.2.5/forks/jras-elyxer/src/elyxer/maths/0000755000175000017500000000000012117061342021136 5ustar chennochennoelyxer-1.2.5/forks/jras-elyxer/src/elyxer/maths/symbol.py0000644000175000017500000000707412117061342023025 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20101218 # eLyXer big symbol generation. from elyxer.util.trace import Trace from elyxer.util.docparams import * from elyxer.conf.config import * from elyxer.maths.bits import * class BigSymbol(object): "A big symbol generator." symbols = FormulaConfig.bigsymbols def __init__(self, symbol): "Create the big symbol." self.symbol = symbol def getpieces(self): "Get an array with all pieces." if not self.symbol in self.symbols: return [self.symbol] if self.smalllimit(): return [self.symbol] return self.symbols[self.symbol] def smalllimit(self): "Decide if the limit should be a small, one-line symbol." if not DocumentParameters.displaymode: return True if len(self.symbols[self.symbol]) == 1: return True return Options.simplemath class BigBracket(BigSymbol): "A big bracket generator." def __init__(self, size, bracket, alignment='l'): "Set the size and symbol for the bracket." self.size = size self.original = bracket self.alignment = alignment self.pieces = None if bracket in FormulaConfig.bigbrackets: self.pieces = FormulaConfig.bigbrackets[bracket] def getpiece(self, index): "Return the nth piece for the bracket." function = getattr(self, 'getpiece' + unicode(len(self.pieces))) return function(index) def getpiece1(self, index): "Return the only piece for a single-piece bracket." return self.pieces[0] def getpiece3(self, index): "Get the nth piece for a 3-piece bracket: parenthesis or square bracket." if index == 0: return self.pieces[0] if index == self.size - 1: return self.pieces[-1] return self.pieces[1] def getpiece4(self, index): "Get the nth piece for a 4-piece bracket: curly bracket." if index == 0: return self.pieces[0] if index == self.size - 1: return self.pieces[3] if index == (self.size - 1)/2: return self.pieces[2] return self.pieces[1] def getcell(self, index): "Get the bracket piece as an array cell." piece = self.getpiece(index) span = 'span class="bracket align-' + self.alignment + '"' return TaggedBit().constant(piece, span) def getcontents(self): "Get the bracket as an array or as a single bracket." if self.size == 1 or not self.pieces: return self.getsinglebracket() rows = [] for index in range(self.size): cell = self.getcell(index) rows.append(TaggedBit().complete([cell], 'span class="arrayrow"')) return [TaggedBit().complete(rows, 'span class="array"')] def getsinglebracket(self): "Return the bracket as a single sign." if self.original == '.': return [TaggedBit().constant('', 'span class="emptydot"')] return [TaggedBit().constant(self.original, 'span class="symbol"')] elyxer-1.2.5/forks/jras-elyxer/src/elyxer/maths/hybrid.py0000644000175000017500000002137312117061342022777 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20091214 # eLyXer functions with a variable number of parameters. from elyxer.util.trace import Trace from elyxer.conf.config import * from elyxer.maths.command import * from elyxer.maths.extracommand import * class ParameterDefinition(object): "The definition of a parameter in a hybrid function." "[] parameters are optional, {} parameters are mandatory." "Each parameter has a one-character name, like {$1} or {$p}." "A parameter that ends in ! like {$p!} is a literal." "Example: [$1]{$p!} reads an optional parameter $1 and a literal mandatory parameter p." parambrackets = [('[', ']'), ('{', '}')] def __init__(self): self.name = None self.literal = False self.optional = False self.value = None self.literalvalue = None def parse(self, pos): "Parse a parameter definition: [$0], {$x}, {$1!}..." for (opening, closing) in ParameterDefinition.parambrackets: if pos.checkskip(opening): if opening == '[': self.optional = True if not pos.checkskip('$'): Trace.error('Wrong parameter name, did you mean $' + pos.current() + '?') return None self.name = pos.skipcurrent() if pos.checkskip('!'): self.literal = True if not pos.checkskip(closing): Trace.error('Wrong parameter closing ' + pos.skipcurrent()) return None return self Trace.error('Wrong character in parameter template: ' + pos.skipcurrent()) return None def read(self, pos, function): "Read the parameter itself using the definition." if self.literal: if self.optional: self.literalvalue = function.parsesquareliteral(pos) else: self.literalvalue = function.parseliteral(pos) if self.literalvalue: self.value = FormulaConstant(self.literalvalue) elif self.optional: self.value = function.parsesquare(pos) else: self.value = function.parseparameter(pos) def __unicode__(self): "Return a printable representation." result = 'param ' + self.name if self.value: result += ': ' + unicode(self.value) else: result += ' (empty)' return result class ParameterFunction(CommandBit): "A function with a variable number of parameters defined in a template." "The parameters are defined as a parameter definition." def readparams(self, readtemplate, pos): "Read the params according to the template." self.params = dict() for paramdef in self.paramdefs(readtemplate): paramdef.read(pos, self) self.params['$' + paramdef.name] = paramdef def paramdefs(self, readtemplate): "Read each param definition in the template" pos = TextPosition(readtemplate) while not pos.finished(): paramdef = ParameterDefinition().parse(pos) if paramdef: yield paramdef def getparam(self, name): "Get a parameter as parsed." if not name in self.params: return None return self.params[name] def getvalue(self, name): "Get the value of a parameter." return self.getparam(name).value def getliteralvalue(self, name): "Get the literal value of a parameter." param = self.getparam(name) if not param or not param.literalvalue: return None return param.literalvalue class HybridFunction(ParameterFunction): """ A parameter function where the output is also defined using a template. The template can use a number of functions; each function has an associated tag. Example: [f0{$1},span class="fbox"] defines a function f0 which corresponds to a span of class fbox, yielding $1. Literal parameters can be used in tags definitions: [f0{$1},span style="color: $p;"] yields $1, where $p is a literal parameter. Sizes can be specified in hybridsizes, e.g. adding parameter sizes. By default the resulting size is the max of all arguments. Sizes are used to generate the right parameters. A function followed by a single / is output as a self-closing XHTML tag: [f0/,hr] will generate
. """ commandmap = FormulaConfig.hybridfunctions def parsebit(self, pos): "Parse a function with [] and {} parameters" readtemplate = self.translated[0] writetemplate = self.translated[1] self.readparams(readtemplate, pos) self.contents = self.writeparams(writetemplate) self.computehybridsize() def writeparams(self, writetemplate): "Write all params according to the template" return self.writepos(TextPosition(writetemplate)) def writepos(self, pos): "Write all params as read in the parse position." result = [] while not pos.finished(): if pos.checkskip('$'): param = self.writeparam(pos) if param: result.append(param) elif pos.checkskip('f'): function = self.writefunction(pos) if function: function.type = None result.append(function) elif pos.checkskip('('): result.append(self.writebracket('left', '(')) elif pos.checkskip(')'): result.append(self.writebracket('right', ')')) else: result.append(FormulaConstant(pos.skipcurrent())) return result def writeparam(self, pos): "Write a single param of the form $0, $x..." name = '$' + pos.skipcurrent() if not name in self.params: Trace.error('Unknown parameter ' + name) return None if not self.params[name]: return None if pos.checkskip('.'): self.params[name].value.type = pos.globalpha() return self.params[name].value def writefunction(self, pos): "Write a single function f0,...,fn." tag = self.readtag(pos) if not tag: return None if pos.checkskip('/'): # self-closing XHTML tag, such as
return TaggedBit().selfcomplete(tag) if not pos.checkskip('{'): Trace.error('Function should be defined in {}') return None pos.pushending('}') contents = self.writepos(pos) pos.popending() if len(contents) == 0: return None return TaggedBit().complete(contents, tag) def readtag(self, pos): "Get the tag corresponding to the given index. Does parameter substitution." if not pos.current().isdigit(): Trace.error('Function should be f0,...,f9: f' + pos.current()) return None index = int(pos.skipcurrent()) if 2 + index > len(self.translated): Trace.error('Function f' + unicode(index) + ' is not defined') return None tag = self.translated[2 + index] if not '$' in tag: return tag for variable in self.params: if variable in tag: param = self.params[variable] if not param.literal: Trace.error('Parameters in tag ' + tag + ' should be literal: {' + variable + '!}') continue if param.literalvalue: value = param.literalvalue else: value = '' tag = tag.replace(variable, value) return tag def writebracket(self, direction, character): "Return a new bracket looking at the given direction." return self.factory.create(BracketCommand).create(direction, character) def computehybridsize(self): "Compute the size of the hybrid function." if not self.command in HybridSize.configsizes: self.computesize() return self.size = HybridSize().getsize(self) # set the size in all elements at first level for element in self.contents: element.size = self.size class HybridSize(object): "The size associated with a hybrid function." configsizes = FormulaConfig.hybridsizes def getsize(self, function): "Read the size for a function and parse it." sizestring = self.configsizes[function.command] for name in function.params: if name in sizestring: size = function.params[name].value.computesize() sizestring = sizestring.replace(name, unicode(size)) if '$' in sizestring: Trace.error('Unconverted variable in hybrid size: ' + sizestring) return 1 return eval(sizestring) FormulaCommand.types += [HybridFunction] elyxer-1.2.5/forks/jras-elyxer/src/elyxer/maths/postformula.py0000644000175000017500000000606012117061342024065 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20090422 # eLyXer postprocessor for formulae from elyxer.util.numbering import * from elyxer.maths.command import * from elyxer.maths.array import * from elyxer.maths.misc import * from elyxer.proc.postprocess import * from elyxer.ref.link import * from elyxer.ref.label import * from elyxer.ref.partkey import * class PostFormula(object): "Postprocess a formula" processedclass = Formula def postprocess(self, last, formula, next): "Postprocess any formulae" if Options.jsmath or Options.mathjax: return formula self.postnumbering(formula) return formula def postnumbering(self, formula): "Check if it's a numbered equation, insert number." if formula.header[0] != 'numbered': return functions = formula.searchremove(LabelFunction) if len(functions) == 0: label = self.createlabel(formula) elif len(functions) == 1: label = self.createlabel(formula, functions[0]) if len(functions) <= 1: label.parent = formula formula.contents.insert(0, label) return for function in functions: label = self.createlabel(formula, function) row = self.searchrow(function) label.parent = row row.contents.insert(0, label) def createlabel(self, formula, function = None): "Create a new label for a formula." "Add a label to a formula." tag = self.createtag(formula) partkey = PartKey().createformula(tag) if not formula.partkey: formula.partkey = partkey if not function: label = Label() label.create(partkey.tocentry + ' ', 'eq-' + tag, type="eqnumber") else: label = function.label label.complete(partkey.tocentry + ' ') return label def createtag(self, formula): "Create the label tag." tags = formula.searchall(FormulaTag) if len(tags) == 0: return NumberGenerator.chaptered.generate('formula') if len(tags) > 1: Trace.error('More than one tag in formula: ' + unicode(formula)) return tags[0].tag def searchrow(self, function): "Search for the row that contains the label function." if isinstance(function.parent, Formula) or isinstance(function.parent, FormulaRow): return function.parent return self.searchrow(function.parent) Postprocessor.stages.append(PostFormula) elyxer-1.2.5/forks/jras-elyxer/src/elyxer/maths/misc.py0000644000175000017500000000422012117061342022441 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20110109 # eLyXer misc commands, invoked by class name from the configuration file. from elyxer.util.numbering import * from elyxer.maths.command import * from elyxer.maths.extracommand import * from elyxer.maths.macro import * class SetCounterFunction(CommandBit): "A function which is used in the preamble to set a counter." def parsebit(self, pos): "Parse a function with [] and {} parameters." counter = self.parseliteral(pos) value = self.parseliteral(pos) try: self.setcounter(counter, int(value)) except: Trace.error('Counter ' + counter + ' cannot be set to ' + value) def setcounter(self, counter, value): "Set a global counter." Trace.debug('Setting counter ' + unicode(counter) + ' to ' + unicode(value)) NumberGenerator.generator.getcounter(counter).init(value) class FormulaTag(CommandBit): "A \\tag command." def parsebit(self, pos): "Parse the tag and apply it." self.output = EmptyOutput() self.tag = self.parseliteral(pos) class MiscCommand(CommandBit): "A generic command which maps to a command class." commandmap = FormulaConfig.misccommands def parsebit(self, pos): "Find the right command to parse and parse it." commandtype = globals()[self.translated] return self.parsecommandtype(self.translated, commandtype, pos) FormulaCommand.types += [MiscCommand] elyxer-1.2.5/forks/jras-elyxer/src/elyxer/maths/formula.py0000644000175000017500000001525112117061342023161 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20090207 # eLyXer formula processing import urllib from elyxer.gen.container import * from elyxer.util.trace import Trace from elyxer.util.clone import * from elyxer.util.docparams import * from elyxer.conf.config import * from elyxer.parse.formulaparse import * from elyxer.proc.formulaproc import * class Formula(Container): "A LaTeX formula" def __init__(self): self.parser = FormulaParser() self.output = TaggedOutput().settag('span class="formula"') def process(self): "Convert the formula to tags" if self.header[0] == 'inline': DocumentParameters.displaymode = False else: DocumentParameters.displaymode = True self.output.settag('div class="formula"', True) if Options.jsmath: self.jsmath() elif Options.mathjax: self.mathjax() elif Options.googlecharts: self.googlecharts() else: self.classic() def jsmath(self): "Make the contents for jsMath." if self.header[0] != 'inline': self.output = TaggedOutput().settag('div class="math"') else: self.output = TaggedOutput().settag('span class="math"') self.contents = [Constant(self.parsed)] def mathjax(self): "Make the contents for MathJax." self.output.tag = 'span class="MathJax_Preview"' tag = 'script type="math/tex' if self.header[0] != 'inline': tag += ';mode=display' self.contents = [TaggedText().constant(self.parsed, tag + '"', True)] def googlecharts(self): "Make the contents using Google Charts http://code.google.com/apis/chart/." url = FormulaConfig.urls['googlecharts'] + urllib.quote_plus(self.parsed) img = '' + self.parsed + '' self.contents = [Constant(img)] def classic(self): "Make the contents using classic output generation with XHTML and CSS." whole = FormulaFactory().parseformula(self.parsed) FormulaProcessor().process(whole) whole.parent = self self.contents = [whole] def parse(self, pos): "Parse using a parse position instead of self.parser." if pos.checkskip('$$'): self.parsedollarblock(pos) elif pos.checkskip('$'): self.parsedollarinline(pos) elif pos.checkskip('\\('): self.parseinlineto(pos, '\\)') elif pos.checkskip('\\['): self.parseblockto(pos, '\\]') else: pos.error('Unparseable formula') self.process() return self def parsedollarinline(self, pos): "Parse a $...$ formula." self.header = ['inline'] self.parsedollar(pos) def parsedollarblock(self, pos): "Parse a $$...$$ formula." self.header = ['block'] self.parsedollar(pos) if not pos.checkskip('$'): pos.error('Formula should be $$...$$, but last $ is missing.') def parsedollar(self, pos): "Parse to the next $." pos.pushending('$') self.parsed = pos.globexcluding('$') pos.popending('$') def parseinlineto(self, pos, limit): "Parse a \\(...\\) formula." self.header = ['inline'] self.parseupto(pos, limit) def parseblockto(self, pos, limit): "Parse a \\[...\\] formula." self.header = ['block'] self.parseupto(pos, limit) def parseupto(self, pos, limit): "Parse a formula that ends with the given command." pos.pushending(limit) self.parsed = pos.glob(lambda: True) pos.popending(limit) def __unicode__(self): "Return a printable representation." if self.partkey and self.partkey.number: return 'Formula (' + self.partkey.number + ')' return 'Unnumbered formula' class WholeFormula(FormulaBit): "Parse a whole formula" def detect(self, pos): "Not outside the formula is enough." return not pos.finished() def parsebit(self, pos): "Parse with any formula bit" while not pos.finished(): self.add(self.factory.parseany(pos)) class FormulaFactory(object): "Construct bits of formula" # bit types will be appended later types = [FormulaSymbol, RawText, FormulaNumber, Bracket, Comment, WhiteSpace] skippedtypes = [Comment, WhiteSpace] defining = False def __init__(self): "Initialize the map of instances." self.instances = dict() def detecttype(self, type, pos): "Detect a bit of a given type." if pos.finished(): return False return self.instance(type).detect(pos) def instance(self, type): "Get an instance of the given type." if not type in self.instances or not self.instances[type]: self.instances[type] = self.create(type) return self.instances[type] def create(self, type): "Create a new formula bit of the given type." return Cloner.create(type).setfactory(self) def clearskipped(self, pos): "Clear any skipped types." while not pos.finished(): if not self.skipany(pos): return return def skipany(self, pos): "Skip any skipped types." for type in self.skippedtypes: if self.instance(type).detect(pos): return self.parsetype(type, pos) return None def parseany(self, pos): "Parse any formula bit at the current location." for type in self.types + self.skippedtypes: if self.detecttype(type, pos): return self.parsetype(type, pos) Trace.error('Unrecognized formula at ' + pos.identifier()) return FormulaConstant(pos.skipcurrent()) def parsetype(self, type, pos): "Parse the given type and return it." bit = self.instance(type) self.instances[type] = None returnedbit = bit.parsebit(pos) if returnedbit: return returnedbit.setfactory(self) return bit def parseformula(self, formula): "Parse a string of text that contains a whole formula." pos = TextPosition(formula) whole = self.create(WholeFormula) if whole.detect(pos): whole.parsebit(pos) return whole # no formula found if not pos.finished(): Trace.error('Unknown formula at: ' + pos.identifier()) whole.add(TaggedBit().constant(formula, 'span class="unknown"')) return whole elyxer-1.2.5/forks/jras-elyxer/src/elyxer/maths/command.py0000644000175000017500000002077412117061342023140 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20090330 # eLyXer commands in formula processing import unicodedata from elyxer.gen.container import * from elyxer.ref.label import * from elyxer.util.trace import Trace from elyxer.util.clone import * from elyxer.conf.config import * from elyxer.maths.formula import * from elyxer.maths.bits import * class FormulaCommand(FormulaBit): "A LaTeX command inside a formula" types = [] start = FormulaConfig.starts['command'] commandmap = None def detect(self, pos): "Find the current command." return pos.checkfor(FormulaCommand.start) def parsebit(self, pos): "Parse the command." command = self.extractcommand(pos) bit = self.parsewithcommand(command, pos) if bit: return bit if command.startswith('\\up') or command.startswith('\\Up'): upgreek = self.parseupgreek(command, pos) if upgreek: return upgreek if not self.factory.defining: Trace.error('Unknown command ' + command) self.output = TaggedOutput().settag('span class="unknown"') self.add(FormulaConstant(command)) return None def parsewithcommand(self, command, pos): "Parse the command type once we have the command." for type in FormulaCommand.types: if command in type.commandmap: return self.parsecommandtype(command, type, pos) return None def parsecommandtype(self, command, type, pos): "Parse a given command type." bit = self.factory.create(type) bit.setcommand(command) returned = bit.parsebit(pos) if returned: return returned return bit def extractcommand(self, pos): "Extract the command from elyxer.the current position." if not pos.checkskip(FormulaCommand.start): pos.error('Missing command start ' + FormulaCommand.start) return if pos.finished(): return self.emptycommand(pos) if pos.current().isalpha(): # alpha command command = FormulaCommand.start + pos.globalpha() # skip mark of short command pos.checkskip('*') return command # symbol command return FormulaCommand.start + pos.skipcurrent() def emptycommand(self, pos): """Check for an empty command: look for command disguised as ending. Special case against '{ \{ \} }' situation.""" command = '' if not pos.isout(): ending = pos.nextending() if ending and pos.checkskip(ending): command = ending return FormulaCommand.start + command def parseupgreek(self, command, pos): "Parse the Greek \\up command.." if len(command) < 4: return None if command.startswith('\\up'): upcommand = '\\' + command[3:] elif pos.checkskip('\\Up'): upcommand = '\\' + command[3:4].upper() + command[4:] else: Trace.error('Impossible upgreek command: ' + command) return upgreek = self.parsewithcommand(upcommand, pos) if upgreek: upgreek.type = 'font' return upgreek class CommandBit(FormulaCommand): "A formula bit that includes a command" def setcommand(self, command): "Set the command in the bit" self.command = command if self.commandmap: self.original += command self.translated = self.commandmap[self.command] def parseparameter(self, pos): "Parse a parameter at the current position" self.factory.clearskipped(pos) if pos.finished(): return None parameter = self.factory.parseany(pos) self.add(parameter) return parameter def parsesquare(self, pos): "Parse a square bracket" self.factory.clearskipped(pos) if not self.factory.detecttype(SquareBracket, pos): return None bracket = self.factory.parsetype(SquareBracket, pos) self.add(bracket) return bracket def parseliteral(self, pos): "Parse a literal bracket." self.factory.clearskipped(pos) if not self.factory.detecttype(Bracket, pos): if not pos.isvalue(): Trace.error('No literal parameter found at: ' + pos.identifier()) return None return pos.globvalue() bracket = Bracket().setfactory(self.factory) self.add(bracket.parseliteral(pos)) return bracket.literal def parsesquareliteral(self, pos): "Parse a square bracket literally." self.factory.clearskipped(pos) if not self.factory.detecttype(SquareBracket, pos): return None bracket = SquareBracket().setfactory(self.factory) self.add(bracket.parseliteral(pos)) return bracket.literal def parsetext(self, pos): "Parse a text parameter." self.factory.clearskipped(pos) if not self.factory.detecttype(Bracket, pos): Trace.error('No text parameter for ' + self.command) return None bracket = Bracket().setfactory(self.factory).parsetext(pos) self.add(bracket) return bracket class EmptyCommand(CommandBit): "An empty command (without parameters)" commandmap = FormulaConfig.commands def parsebit(self, pos): "Parse a command without parameters" self.contents = [FormulaConstant(self.translated)] class SpacedCommand(CommandBit): "An empty command which should have math spacing in formulas." commandmap = FormulaConfig.spacedcommands def parsebit(self, pos): "Place as contents the command translated and spaced." self.contents = [FormulaConstant(u' ' + self.translated + u' ')] class AlphaCommand(EmptyCommand): "A command without paramters whose result is alphabetical" commandmap = FormulaConfig.alphacommands def parsebit(self, pos): "Parse the command and set type to alpha" EmptyCommand.parsebit(self, pos) self.type = 'alpha' class OneParamFunction(CommandBit): "A function of one parameter" commandmap = FormulaConfig.onefunctions simplified = False def parsebit(self, pos): "Parse a function with one parameter" self.output = TaggedOutput().settag(self.translated) self.parseparameter(pos) self.simplifyifpossible() def simplifyifpossible(self): "Try to simplify to a single character." if self.original in self.commandmap: self.output = FixedOutput() self.html = [self.commandmap[self.original]] self.simplified = True class SymbolFunction(CommandBit): "Find a function which is represented by a symbol (like _ or ^)" commandmap = FormulaConfig.symbolfunctions def detect(self, pos): "Find the symbol" return pos.current() in SymbolFunction.commandmap def parsebit(self, pos): "Parse the symbol" self.setcommand(pos.current()) pos.skip(self.command) self.output = TaggedOutput().settag(self.translated) self.parseparameter(pos) class TextFunction(CommandBit): "A function where parameters are read as text." commandmap = FormulaConfig.textfunctions def parsebit(self, pos): "Parse a text parameter" self.output = TaggedOutput().settag(self.translated) self.parsetext(pos) def process(self): "Set the type to font" self.type = 'font' class LabelFunction(CommandBit): "A function that acts as a label" commandmap = FormulaConfig.labelfunctions def parsebit(self, pos): "Parse a literal parameter" self.key = self.parseliteral(pos) def process(self): "Add an anchor with the label contents." self.type = 'font' self.label = Label().create(' ', self.key, type = 'eqnumber') self.contents = [self.label] # store as a Label so we know it's been seen Label.names[self.key] = self.label class FontFunction(OneParamFunction): "A function of one parameter that changes the font" commandmap = FormulaConfig.fontfunctions def process(self): "Simplify if possible using a single character." self.type = 'font' self.simplifyifpossible() FormulaFactory.types += [FormulaCommand, SymbolFunction] FormulaCommand.types = [ AlphaCommand, EmptyCommand, OneParamFunction, FontFunction, LabelFunction, TextFunction, SpacedCommand, ] elyxer-1.2.5/forks/jras-elyxer/src/elyxer/maths/macro.py0000644000175000017500000001475012117061342022620 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20100615 # eLyXer macro processing from elyxer.util.trace import Trace from elyxer.conf.config import * from elyxer.parse.formulaparse import * from elyxer.parse.headerparse import * from elyxer.maths.formula import * from elyxer.maths.hybrid import * class MacroDefinition(CommandBit): "A function that defines a new command (a macro)." macros = dict() def parsebit(self, pos): "Parse the function that defines the macro." self.output = EmptyOutput() self.parameternumber = 0 self.defaults = [] self.factory.defining = True self.parseparameters(pos) self.factory.defining = False Trace.debug('New command ' + self.newcommand + ' (' + \ unicode(self.parameternumber) + ' parameters)') self.macros[self.newcommand] = self def parseparameters(self, pos): "Parse all optional parameters (number of parameters, default values)" "and the mandatory definition." self.newcommand = self.parsenewcommand(pos) # parse number of parameters literal = self.parsesquareliteral(pos) if literal: self.parameternumber = int(literal) # parse all default values bracket = self.parsesquare(pos) while bracket: self.defaults.append(bracket) bracket = self.parsesquare(pos) # parse mandatory definition self.definition = self.parseparameter(pos) def parsenewcommand(self, pos): "Parse the name of the new command." self.factory.clearskipped(pos) if self.factory.detecttype(Bracket, pos): return self.parseliteral(pos) if self.factory.detecttype(FormulaCommand, pos): return self.factory.create(FormulaCommand).extractcommand(pos) Trace.error('Unknown formula bit in defining function at ' + pos.identifier()) return 'unknown' def instantiate(self): "Return an instance of the macro." return self.definition.clone() class MacroParameter(FormulaBit): "A parameter from elyxer.a macro." def detect(self, pos): "Find a macro parameter: #n." return pos.checkfor('#') def parsebit(self, pos): "Parse the parameter: #n." if not pos.checkskip('#'): Trace.error('Missing parameter start #.') return self.number = int(pos.skipcurrent()) self.original = '#' + unicode(self.number) self.contents = [TaggedBit().constant('#' + unicode(self.number), 'span class="unknown"')] class MacroFunction(CommandBit): "A function that was defined using a macro." commandmap = MacroDefinition.macros def parsebit(self, pos): "Parse a number of input parameters." self.output = FilteredOutput() self.values = [] macro = self.translated self.parseparameters(pos, macro) self.completemacro(macro) def parseparameters(self, pos, macro): "Parse as many parameters as are needed." self.parseoptional(pos, list(macro.defaults)) self.parsemandatory(pos, macro.parameternumber - len(macro.defaults)) if len(self.values) < macro.parameternumber: Trace.error('Missing parameters in macro ' + unicode(self)) def parseoptional(self, pos, defaults): "Parse optional parameters." optional = [] while self.factory.detecttype(SquareBracket, pos): optional.append(self.parsesquare(pos)) if len(optional) > len(defaults): break for value in optional: default = defaults.pop() if len(value.contents) > 0: self.values.append(value) else: self.values.append(default) self.values += defaults def parsemandatory(self, pos, number): "Parse a number of mandatory parameters." for index in range(number): parameter = self.parsemacroparameter(pos, number - index) if not parameter: return self.values.append(parameter) def parsemacroparameter(self, pos, remaining): "Parse a macro parameter. Could be a bracket or a single letter." "If there are just two values remaining and there is a running number," "parse as two separater numbers." self.factory.clearskipped(pos) if pos.finished(): return None if self.factory.detecttype(FormulaNumber, pos): return self.parsenumbers(pos, remaining) return self.parseparameter(pos) def parsenumbers(self, pos, remaining): "Parse the remaining parameters as a running number." "For example, 12 would be {1}{2}." number = self.factory.parsetype(FormulaNumber, pos) if not len(number.original) == remaining: return number for digit in number.original: value = self.factory.create(FormulaNumber) value.add(FormulaConstant(digit)) value.type = number self.values.append(value) return None def completemacro(self, macro): "Complete the macro with the parameters read." self.contents = [macro.instantiate()] replaced = [False] * len(self.values) for parameter in self.searchall(MacroParameter): index = parameter.number - 1 if index >= len(self.values): Trace.error('Macro parameter index out of bounds: ' + unicode(index)) return replaced[index] = True parameter.contents = [self.values[index].clone()] for index in range(len(self.values)): if not replaced[index]: self.addfilter(index, self.values[index]) def addfilter(self, index, value): "Add a filter for the given parameter number and parameter value." original = '#' + unicode(index + 1) value = ''.join(self.values[0].gethtml()) self.output.addfilter(original, value) class FormulaMacro(Formula): "A math macro defined in an inset." def __init__(self): self.parser = MacroParser() self.output = EmptyOutput() def __unicode__(self): "Return a printable representation." return 'Math macro' FormulaFactory.types += [ MacroParameter ] FormulaCommand.types += [ MacroFunction, ] elyxer-1.2.5/forks/jras-elyxer/src/elyxer/maths/bits.py0000644000175000017500000001737612117061342022467 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20090614 # eLyXer formula bits from elyxer.util.trace import Trace from elyxer.conf.config import * from elyxer.maths.formula import * class FormulaBit(Container): "A bit of a formula" type = None size = 1 original = '' def __init__(self): "The formula bit type can be 'alpha', 'number', 'font'." self.contents = [] self.output = ContentsOutput() def setfactory(self, factory): "Set the internal formula factory." self.factory = factory return self def add(self, bit): "Add any kind of formula bit already processed" self.contents.append(bit) self.original += bit.original bit.parent = self def skiporiginal(self, string, pos): "Skip a string and add it to the original formula" self.original += string if not pos.checkskip(string): Trace.error('String ' + string + ' not at ' + pos.identifier()) def computesize(self): "Compute the size of the bit as the max of the sizes of all contents." if len(self.contents) == 0: return 1 self.size = max([element.size for element in self.contents]) return self.size def clone(self): "Return a copy of itself." return self.factory.parseformula(self.original) def __unicode__(self): "Get a string representation" return self.__class__.__name__ + ' read in ' + self.original class TaggedBit(FormulaBit): "A tagged string in a formula" def constant(self, constant, tag): "Set the constant and the tag" self.output = TaggedOutput().settag(tag) self.add(FormulaConstant(constant)) return self def complete(self, contents, tag, breaklines = False): "Set the constant and the tag" self.contents = contents self.output = TaggedOutput().settag(tag, breaklines) return self def selfcomplete(self, tag): "Set the self-closing tag, no contents (as in
)." self.output = TaggedOutput().settag(tag, empty = True) return self class FormulaConstant(Constant): "A constant string in a formula" def __init__(self, string): "Set the constant string" Constant.__init__(self, string) self.original = string self.size = 1 self.type = None def computesize(self): "Compute the size of the constant: always 1." return self.size def clone(self): "Return a copy of itself." return FormulaConstant(self.original) def __unicode__(self): "Return a printable representation." return 'Formula constant: ' + self.string class RawText(FormulaBit): "A bit of text inside a formula" def detect(self, pos): "Detect a bit of raw text" return pos.current().isalpha() def parsebit(self, pos): "Parse alphabetic text" alpha = pos.globalpha() self.add(FormulaConstant(alpha)) self.type = 'alpha' class FormulaSymbol(FormulaBit): "A symbol inside a formula" modified = FormulaConfig.modified unmodified = FormulaConfig.unmodified['characters'] def detect(self, pos): "Detect a symbol" if pos.current() in FormulaSymbol.unmodified: return True if pos.current() in FormulaSymbol.modified: return True return False def parsebit(self, pos): "Parse the symbol" if pos.current() in FormulaSymbol.unmodified: self.addsymbol(pos.current(), pos) return if pos.current() in FormulaSymbol.modified: self.addsymbol(FormulaSymbol.modified[pos.current()], pos) return Trace.error('Symbol ' + pos.current() + ' not found') def addsymbol(self, symbol, pos): "Add a symbol" self.skiporiginal(pos.current(), pos) self.contents.append(FormulaConstant(symbol)) class FormulaNumber(FormulaBit): "A string of digits in a formula" def detect(self, pos): "Detect a digit" return pos.current().isdigit() def parsebit(self, pos): "Parse a bunch of digits" digits = pos.glob(lambda: pos.current().isdigit()) self.add(FormulaConstant(digits)) self.type = 'number' class Comment(FormulaBit): "A LaTeX comment: % to the end of the line." start = FormulaConfig.starts['comment'] def detect(self, pos): "Detect the %." return pos.current() == self.start def parsebit(self, pos): "Parse to the end of the line." self.original += pos.globincluding('\n') class WhiteSpace(FormulaBit): "Some white space inside a formula." def detect(self, pos): "Detect the white space." return pos.current().isspace() def parsebit(self, pos): "Parse all whitespace." self.original += pos.skipspace() def __unicode__(self): "Return a printable representation." return 'Whitespace: *' + self.original + '*' class Bracket(FormulaBit): "A {} bracket inside a formula" start = FormulaConfig.starts['bracket'] ending = FormulaConfig.endings['bracket'] def __init__(self): "Create a (possibly literal) new bracket" FormulaBit.__init__(self) self.inner = None def detect(self, pos): "Detect the start of a bracket" return pos.checkfor(self.start) def parsebit(self, pos): "Parse the bracket" self.parsecomplete(pos, self.innerformula) return self def parsetext(self, pos): "Parse a text bracket" self.parsecomplete(pos, self.innertext) return self def parseliteral(self, pos): "Parse a literal bracket" self.parsecomplete(pos, self.innerliteral) return self def parsecomplete(self, pos, innerparser): "Parse the start and end marks" if not pos.checkfor(self.start): Trace.error('Bracket should start with ' + self.start + ' at ' + pos.identifier()) return None self.skiporiginal(self.start, pos) pos.pushending(self.ending) innerparser(pos) self.original += pos.popending(self.ending) self.computesize() def innerformula(self, pos): "Parse a whole formula inside the bracket" while not pos.finished(): self.add(self.factory.parseany(pos)) def innertext(self, pos): "Parse some text inside the bracket, following textual rules." specialchars = FormulaConfig.symbolfunctions.keys() specialchars.append(FormulaConfig.starts['command']) specialchars.append(FormulaConfig.starts['bracket']) specialchars.append(Comment.start) while not pos.finished(): if pos.current() in specialchars: self.add(self.factory.parseany(pos)) if pos.checkskip(' '): self.original += ' ' else: self.add(FormulaConstant(pos.skipcurrent())) def innerliteral(self, pos): "Parse a literal inside the bracket, which does not generate HTML." self.literal = '' while not pos.finished() and not pos.current() == self.ending: if pos.current() == self.start: self.parseliteral(pos) else: self.literal += pos.skipcurrent() self.original += self.literal class SquareBracket(Bracket): "A [] bracket inside a formula" start = FormulaConfig.starts['squarebracket'] ending = FormulaConfig.endings['squarebracket'] def clone(self): "Return a new square bracket with the same contents." bracket = SquareBracket() bracket.contents = self.contents return bracket elyxer-1.2.5/forks/jras-elyxer/src/elyxer/maths/extracommand.py0000644000175000017500000002147512117061342024203 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20101218 # eLyXer extra commands for unusual things. from elyxer.util.trace import Trace from elyxer.util.clone import * from elyxer.conf.config import * from elyxer.maths.command import * from elyxer.maths.symbol import * from elyxer.maths.array import * import datetime class CombiningFunction(OneParamFunction): commandmap = FormulaConfig.combiningfunctions def parsebit(self, pos): "Parse a combining function." self.type = 'alpha' combining = self.translated parameter = self.parsesingleparameter(pos) if not parameter: Trace.error('Empty parameter for combining function ' + self.command) elif len(parameter.extracttext()) != 1: Trace.error('Applying combining function ' + self.command + ' to invalid string "' + parameter.extracttext() + '"') self.contents.append(Constant(combining)) def parsesingleparameter(self, pos): "Parse a parameter, or a single letter." self.factory.clearskipped(pos) if pos.finished(): Trace.error('Error while parsing single parameter at ' + pos.identifier()) return None if self.factory.detecttype(Bracket, pos) \ or self.factory.detecttype(FormulaCommand, pos): return self.parseparameter(pos) letter = FormulaConstant(pos.skipcurrent()) self.add(letter) return letter class DecoratingFunction(OneParamFunction): "A function that decorates some bit of text" commandmap = FormulaConfig.decoratingfunctions def parsebit(self, pos): "Parse a decorating function" self.type = 'alpha' symbol = self.translated self.symbol = TaggedBit().constant(symbol, 'span class="symbolover"') self.parameter = self.parseparameter(pos) self.output = TaggedOutput().settag('span class="withsymbol"') self.contents.insert(0, self.symbol) self.parameter.output = TaggedOutput().settag('span class="undersymbol"') self.simplifyifpossible() class LimitCommand(EmptyCommand): "A command which accepts limits above and below, in display mode." commandmap = FormulaConfig.limitcommands def parsebit(self, pos): "Parse a limit command." pieces = BigSymbol(self.translated).getpieces() self.output = TaggedOutput().settag('span class="limits"') for piece in pieces: self.contents.append(TaggedBit().constant(piece, 'span class="limit"')) class LimitPreviousCommand(LimitCommand): "A command to limit the previous command." commandmap = None def parsebit(self, pos): "Do nothing." self.output = TaggedOutput().settag('span class="limits"') self.factory.clearskipped(pos) def __unicode__(self): "Return a printable representation." return 'Limit previous command' class LimitsProcessor(MathsProcessor): "A processor for limits inside an element." def process(self, contents, index): "Process the limits for an element." if Options.simplemath: return if self.checklimits(contents, index): self.modifylimits(contents, index) if self.checkscript(contents, index) and self.checkscript(contents, index + 1): self.modifyscripts(contents, index) def checklimits(self, contents, index): "Check if the current position has a limits command." if not DocumentParameters.displaymode: return False if self.checkcommand(contents, index + 1, LimitPreviousCommand): self.limitsahead(contents, index) return False if not isinstance(contents[index], LimitCommand): return False return self.checkscript(contents, index + 1) def limitsahead(self, contents, index): "Limit the current element based on the next." contents[index + 1].add(contents[index].clone()) contents[index].output = EmptyOutput() def modifylimits(self, contents, index): "Modify a limits commands so that the limits appear above and below." limited = contents[index] subscript = self.getlimit(contents, index + 1) limited.contents.append(subscript) if self.checkscript(contents, index + 1): superscript = self.getlimit(contents, index + 1) else: superscript = TaggedBit().constant(u' ', 'sup class="limit"') limited.contents.insert(0, superscript) def getlimit(self, contents, index): "Get the limit for a limits command." limit = self.getscript(contents, index) limit.output.tag = limit.output.tag.replace('script', 'limit') return limit def modifyscripts(self, contents, index): "Modify the super- and subscript to appear vertically aligned." subscript = self.getscript(contents, index) # subscript removed so instead of index + 1 we get index again superscript = self.getscript(contents, index) scripts = TaggedBit().complete([superscript, subscript], 'span class="scripts"') contents.insert(index, scripts) def checkscript(self, contents, index): "Check if the current element is a sub- or superscript." return self.checkcommand(contents, index, SymbolFunction) def checkcommand(self, contents, index, type): "Check for the given type as the current element." if len(contents) <= index: return False return isinstance(contents[index], type) def getscript(self, contents, index): "Get the sub- or superscript." bit = contents[index] bit.output.tag += ' class="script"' del contents[index] return bit class BracketCommand(OneParamFunction): "A command which defines a bracket." commandmap = FormulaConfig.bracketcommands def parsebit(self, pos): "Parse the bracket." OneParamFunction.parsebit(self, pos) def create(self, direction, character): "Create the bracket for the given character." self.original = character self.command = '\\' + direction self.contents = [FormulaConstant(character)] return self class BracketProcessor(MathsProcessor): "A processor for bracket commands." def process(self, contents, index): "Convert the bracket using Unicode pieces, if possible." if Options.simplemath: return if self.checkleft(contents, index): return self.processleft(contents, index) def processleft(self, contents, index): "Process a left bracket." rightindex = self.findright(contents, index + 1) if not rightindex: return size = self.findmax(contents, index, rightindex) self.resize(contents[index], size) self.resize(contents[rightindex], size) def checkleft(self, contents, index): "Check if the command at the given index is left." return self.checkdirection(contents[index], '\\left') def checkright(self, contents, index): "Check if the command at the given index is right." return self.checkdirection(contents[index], '\\right') def checkdirection(self, bit, command): "Check if the given bit is the desired bracket command." if not isinstance(bit, BracketCommand): return False return bit.command == command def findright(self, contents, index): "Find the right bracket starting at the given index, or 0." depth = 1 while index < len(contents): if self.checkleft(contents, index): depth += 1 if self.checkright(contents, index): depth -= 1 if depth == 0: return index index += 1 return None def findmax(self, contents, leftindex, rightindex): "Find the max size of the contents between the two given indices." sliced = contents[leftindex:rightindex] return max([element.size for element in sliced]) def resize(self, command, size): "Resize a bracket command to the given size." character = command.extracttext() alignment = command.command.replace('\\', '') bracket = BigBracket(size, character, alignment) command.output = ContentsOutput() command.contents = bracket.getcontents() class TodayCommand(EmptyCommand): "Shows today's date." commandmap = None def parsebit(self, pos): "Parse a command without parameters" self.output = FixedOutput() self.html = [datetime.date.today().strftime('%b %d, %Y')] FormulaCommand.types += [ DecoratingFunction, CombiningFunction, LimitCommand, BracketCommand, ] FormulaProcessor.processors += [ LimitsProcessor(), BracketProcessor(), ] elyxer-1.2.5/forks/jras-elyxer/src/elyxer/maths/array.py0000644000175000017500000001515512117061342022635 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20090427 # eLyXer arrays in formulae from elyxer.gen.container import * from elyxer.util.trace import Trace from elyxer.util.clone import * from elyxer.conf.config import * from elyxer.maths.formula import * from elyxer.maths.command import * from elyxer.maths.symbol import * class FormulaEquation(CommandBit): "A simple numbered equation." piece = 'equation' def parsebit(self, pos): "Parse the array" self.output = ContentsOutput() self.add(self.factory.parsetype(WholeFormula, pos)) class FormulaCell(FormulaCommand): "An array cell inside a row" def setalignment(self, alignment): self.alignment = alignment self.output = TaggedOutput().settag('span class="arraycell align-' + alignment +'"', True) return self def parsebit(self, pos): self.factory.clearskipped(pos) if pos.finished(): return self.add(self.factory.parsetype(WholeFormula, pos)) class FormulaRow(FormulaCommand): "An array row inside an array" cellseparator = FormulaConfig.array['cellseparator'] def setalignments(self, alignments): self.alignments = alignments self.output = TaggedOutput().settag('span class="arrayrow"', True) return self def parsebit(self, pos): "Parse a whole row" index = 0 pos.pushending(self.cellseparator, optional=True) while not pos.finished(): cell = self.createcell(index) cell.parsebit(pos) self.add(cell) index += 1 pos.checkskip(self.cellseparator) if len(self.contents) == 0: self.output = EmptyOutput() def createcell(self, index): "Create the cell that corresponds to the given index." alignment = self.alignments[index % len(self.alignments)] return self.factory.create(FormulaCell).setalignment(alignment) class MultiRowFormula(CommandBit): "A formula with multiple rows." def parserows(self, pos): "Parse all rows, finish when no more row ends" self.rows = [] first = True for row in self.iteraterows(pos): if first: first = False else: # intersparse empty rows self.addempty() row.parsebit(pos) self.addrow(row) self.size = len(self.rows) def iteraterows(self, pos): "Iterate over all rows, end when no more row ends" rowseparator = FormulaConfig.array['rowseparator'] while True: pos.pushending(rowseparator, True) row = self.factory.create(FormulaRow) yield row.setalignments(self.alignments) if pos.checkfor(rowseparator): self.original += pos.popending(rowseparator) else: return def addempty(self): "Add an empty row." row = self.factory.create(FormulaRow).setalignments(self.alignments) for index, originalcell in enumerate(self.rows[-1].contents): cell = row.createcell(index) cell.add(FormulaConstant(u' ')) row.add(cell) self.addrow(row) def addrow(self, row): "Add a row to the contents and to the list of rows." self.rows.append(row) self.add(row) class FormulaArray(MultiRowFormula): "An array within a formula" piece = 'array' def parsebit(self, pos): "Parse the array" self.output = TaggedOutput().settag('span class="array"', False) self.parsealignments(pos) self.parserows(pos) def parsealignments(self, pos): "Parse the different alignments" # vertical self.valign = 'c' literal = self.parsesquareliteral(pos) if literal: self.valign = literal # horizontal literal = self.parseliteral(pos) self.alignments = [] for l in literal: self.alignments.append(l) class FormulaMatrix(MultiRowFormula): "A matrix (array with center alignment)." piece = 'matrix' def parsebit(self, pos): "Parse the matrix, set alignments to 'c'." self.output = TaggedOutput().settag('span class="array"', False) self.valign = 'c' self.alignments = ['c'] self.parserows(pos) class FormulaCases(MultiRowFormula): "A cases statement" piece = 'cases' def parsebit(self, pos): "Parse the cases" self.output = ContentsOutput() self.alignments = ['l', 'l'] self.parserows(pos) for row in self.contents: for cell in row.contents: cell.output.settag('span class="case align-l"', True) cell.contents.append(FormulaConstant(u' ')) array = TaggedBit().complete(self.contents, 'span class="bracketcases"', True) brace = BigBracket(len(self.contents), '{', 'l') self.contents = brace.getcontents() + [array] class EquationEnvironment(MultiRowFormula): "A \\begin{}...\\end equation environment with rows and cells." def parsebit(self, pos): "Parse the whole environment." self.output = TaggedOutput().settag('span class="environment"', False) environment = self.piece.replace('*', '') if environment in FormulaConfig.environments: self.alignments = FormulaConfig.environments[environment] else: Trace.error('Unknown equation environment ' + self.piece) self.alignments = ['l'] self.parserows(pos) class BeginCommand(CommandBit): "A \\begin{}...\end command and what it entails (array, cases, aligned)" commandmap = {FormulaConfig.array['begin']:''} types = [FormulaEquation, FormulaArray, FormulaCases, FormulaMatrix] def parsebit(self, pos): "Parse the begin command" command = self.parseliteral(pos) bit = self.findbit(command) ending = FormulaConfig.array['end'] + '{' + command + '}' pos.pushending(ending) bit.parsebit(pos) self.add(bit) self.original += pos.popending(ending) self.size = bit.size def findbit(self, piece): "Find the command bit corresponding to the \\begin{piece}" for type in BeginCommand.types: if piece.replace('*', '') == type.piece: return self.factory.create(type) bit = self.factory.create(EquationEnvironment) bit.piece = piece return bit FormulaCommand.types += [BeginCommand] elyxer-1.2.5/forks/jras-elyxer/src/elyxer/maths/__init__.py0000644000175000017500000000000012117061342023235 0ustar chennochennoelyxer-1.2.5/forks/jras-elyxer/src/elyxer/out/0000755000175000017500000000000012117061342020631 5ustar chennochennoelyxer-1.2.5/forks/jras-elyxer/src/elyxer/out/template.py0000644000175000017500000002434612117061342023027 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20100620 # eLyXer HTML templates import datetime from elyxer.io.bulk import * from elyxer.parse.position import * from elyxer.util.trace import Trace from elyxer.util.options import * from elyxer.util.translate import * from elyxer.util.docparams import * from elyxer.out.output import * class HTMLTemplate(object): "A template for HTML generation." current = None def getheader(self): "Get the header (before content) of the template." return [] def convertheader(self): "Convert the header and all variables." return self.convert(self.getheader()) def convertfooter(self): "Convert the footer and all variables." return self.convert(self.getfooter()) def convert(self, html): "Convert a bit of HTML replacing all variables." varmap = VariableMap() for index, line in enumerate(html): if '\n'] def getfooter(self): "Get the raw footer." return ['\n\n'] class FileTemplate(HTMLTemplate): "A template read from elyxer.a file." divider = '' def read(self): "Read the file, separate header and footer." self.header = [] lines = [] for line in self.templatelines(): if FileTemplate.divider == line: self.header = lines lines = [] else: lines.append(line) if self.header == []: Trace.error('No ' + FileTemplate.divider + ' in template') self.header = lines lines = [] self.footer = lines return self def templatelines(self): "Read all lines in the template, separate content into its own line." template = BulkFile(Options.template).readall() for line in template: if not FileTemplate.divider in line: yield line else: split = line.split(FileTemplate.divider) for part in split[:-1]: yield part yield FileTemplate.divider yield split[-1] def getheader(self): "Return the header (before content)." return self.header def getfooter(self): "Return the footer (after the content)." return self.footer class DefaultTemplate(HTMLTemplate): "The default HTML template when not configured." def getheader(self): "Get the default header (before content)." html = [] if not Options.html: html.append(u'"?>\n') html.append(u'\n') html.append(u'\n') else: html.append(u'\n') html.append(u'\n') html.append(u'\n') html.append(u'\n') html.append(u'\n') html.append(u'\n') html += self.getcss() html.append(u'<!--$title-->\n') if Options.jsmath: html.append(u'\n') html.append(u'\n') if Options.mathjax: if Options.mathjax == 'remote': html.append(u'\n') else: html.append(u'\n') html.append('\n') html.append('\n') html.append('
\n') if Options.jsmath or Options.mathjax: if Options.mathjax: html.append(u'\n') html.append(u'\n') return html def getcss(self): "Get the CSS headers, both linked and embedded." html = [] for cssdoc in Options.css: if cssdoc != '': html.append(u'\n') for cssfile in Options.embedcss: html.append(u'\n') return html def getfooter(self): "Get the default footer (after content)." html = [] html.append('\n') footer = self.createfooter() if len(footer) > 0: html.append('\n') html += footer html.append('
\n') html.append('\n') html.append('\n') return html def createfooter(self): "Create the footer proper." html = [] if Options.copyright: html.append('\n') if Options.nofooter: return html html.append('\n') return html class VariableMap(object): "A map with all replacement variables." def __init__(self): self.variables = dict() self.variables['title'] = DocumentTitle().getvalue() self.variables['author'] = DocumentAuthor().getvalue() self.variables['version'] = GeneralConfig.version['number'] + ' (' \ + GeneralConfig.version['date'] + ')' self.variables['year'] = unicode(datetime.date.today().year) self.variables['date'] = datetime.date.today().isoformat() self.variables['datetime'] = datetime.datetime.now().isoformat() self.variables['css'] = Options.css[0] if Options.iso885915: self.variables['encoding'] = 'ISO-8859-1' else: self.variables['encoding'] = 'UTF-8' if Options.jsmath: self.variables['jsmath'] = Options.jsmath if Options.mathjax: self.variables['mathjax'] = Options.mathjax def replace(self, line): "Replace all variables in a line." result = '' pos = TextPosition(line) while not pos.finished(): if pos.checkskip(''): Trace.error('Weird template format in ' + line) return value class DocumentTitle(object): "The title of the whole document." title = None def getvalue(self): "Return the correct title from elyxer.the option or the PDF title." if Options.title: return Options.title if DocumentTitle.title: return DocumentTitle.title if DocumentParameters.pdftitle: return DocumentParameters.pdftitle return 'Converted document' class DocumentAuthor(object): "The author of the document." author = '' def appendauthor(cls, authorline): "Append a line with author information." cls.author += authorline appendauthor = classmethod(appendauthor) def getvalue(self): "Get the document author." return DocumentAuthor.author class HeaderOutput(ContainerOutput): "Returns the HTML headers" def gethtml(self, container): "Return a constant header" return HTMLTemplate.get().convertheader() class FooterOutput(ContentsOutput): "Return the HTML code for the footer" def gethtml(self, container): "Footer HTML" contents = ContentsOutput.gethtml(self, container) return contents + HTMLTemplate.get().convertfooter() elyxer-1.2.5/forks/jras-elyxer/src/elyxer/out/output.py0000644000175000017500000001071212117061342022544 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20090203 # eLyXer html outputters from elyxer.util.trace import Trace class ContainerOutput(object): "The generic HTML output for a container." def gethtml(self, container): "Show an error." Trace.error('gethtml() not implemented for ' + unicode(self)) def isempty(self): "Decide if the output is empty: by default, not empty." return False class EmptyOutput(ContainerOutput): def gethtml(self, container): "Return empty HTML code." return [] def isempty(self): "This output is particularly empty." return True class FixedOutput(ContainerOutput): "Fixed output" def gethtml(self, container): "Return constant HTML code" return container.html class ContentsOutput(ContainerOutput): "Outputs the contents converted to HTML" def gethtml(self, container): "Return the HTML code" html = [] if container.contents == None: return html for element in container.contents: if not hasattr(element, 'gethtml'): Trace.error('No html in ' + element.__class__.__name__ + ': ' + unicode(element)) return html html += element.gethtml() return html class TaggedOutput(ContentsOutput): "Outputs an HTML tag surrounding the contents." tag = None breaklines = False empty = False def settag(self, tag, breaklines=False, empty=False): "Set the value for the tag and other attributes." self.tag = tag if breaklines: self.breaklines = breaklines if empty: self.empty = empty return self def setbreaklines(self, breaklines): "Set the value for breaklines." self.breaklines = breaklines return self def gethtml(self, container): "Return the HTML code." if self.empty: return [self.selfclosing(container)] html = [self.open(container)] html += ContentsOutput.gethtml(self, container) html.append(self.close(container)) return html def open(self, container): "Get opening line." if not self.checktag(): return '' open = '<' + self.tag + '>' if self.breaklines: return open + '\n' return open def close(self, container): "Get closing line." if not self.checktag(): return '' close = '' if self.breaklines: return '\n' + close + '\n' return close def selfclosing(self, container): "Get self-closing line." if not self.checktag(): return '' selfclosing = '<' + self.tag + '/>' if self.breaklines: return selfclosing + '\n' return selfclosing def checktag(self): "Check that the tag is valid." if not self.tag: Trace.error('No tag in ' + unicode(container)) return False if self.tag == '': return False return True class FilteredOutput(ContentsOutput): "Returns the output in the contents, but filtered:" "some strings are replaced by others." def __init__(self): "Initialize the filters." self.filters = [] def addfilter(self, original, replacement): "Add a new filter: replace the original by the replacement." self.filters.append((original, replacement)) def gethtml(self, container): "Return the HTML code" result = [] html = ContentsOutput.gethtml(self, container) for line in html: result.append(self.filter(line)) return result def filter(self, line): "Filter a single line with all available filters." for original, replacement in self.filters: if original in line: line = line.replace(original, replacement) return line class StringOutput(ContainerOutput): "Returns a bare string as output" def gethtml(self, container): "Return a bare string" return [container.string] elyxer-1.2.5/forks/jras-elyxer/src/elyxer/out/__init__.py0000644000175000017500000000000012117061342022730 0ustar chennochennoelyxer-1.2.5/forks/jras-elyxer/src/elyxer/gen/0000755000175000017500000000000012117061342020573 5ustar chennochennoelyxer-1.2.5/forks/jras-elyxer/src/elyxer/gen/container.py0000644000175000017500000002122512117061342023131 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20090131 # eLyXer containers for Lyx data that output HTML from elyxer.util.trace import Trace from elyxer.util.clone import * from elyxer.parse.parser import * from elyxer.out.output import * from elyxer.conf.config import * from elyxer.parse.position import * class Container(object): "A container for text and objects in a lyx file" partkey = None parent = None begin = None def __init__(self): self.contents = list() def process(self): "Process contents" pass def gethtml(self): "Get the resulting HTML" html = self.output.gethtml(self) if isinstance(html, basestring): Trace.error('Raw string ' + html) html = [html] return self.escapeall(html) def escapeall(self, lines): "Escape all lines in an array according to the output options." result = [] for line in lines: if Options.html: line = self.escape(line, EscapeConfig.html) if Options.iso885915: line = self.escape(line, EscapeConfig.iso885915) line = self.escapeentities(line) elif not Options.unicode: line = self.escape(line, EscapeConfig.nonunicode) result.append(line) return result def escape(self, line, replacements = EscapeConfig.entities): "Escape a line with replacements from elyxer.a map" pieces = replacements.keys() # do them in order pieces.sort() for piece in pieces: if piece in line: line = line.replace(piece, replacements[piece]) return line def escapeentities(self, line): "Escape all Unicode characters to HTML entities." result = '' pos = TextPosition(line) while not pos.finished(): if ord(pos.current()) > 128: codepoint = hex(ord(pos.current())) if codepoint == '0xd835': codepoint = hex(ord(pos.next()) + 0xf800) result += '&#' + codepoint[1:] + ';' else: result += pos.current() pos.skipcurrent() return result def searchall(self, type): "Search for all embedded containers of a given type" list = [] self.searchprocess(type, lambda container: list.append(container)) return list def searchremove(self, type): "Search for all containers of a type and remove them" list = self.searchall(type) for container in list: container.parent.contents.remove(container) return list def searchprocess(self, type, process): "Search for elements of a given type and process them" self.locateprocess(lambda container: isinstance(container, type), process) def locateprocess(self, locate, process): "Search for all embedded containers and process them" for container in self.contents: container.locateprocess(locate, process) if locate(container): process(container) def recursivesearch(self, locate, recursive, process): "Perform a recursive search in the container." for container in self.contents: if recursive(container): container.recursivesearch(locate, recursive, process) if locate(container): process(container) def extracttext(self): "Extract all text from elyxer.allowed containers." result = '' constants = ContainerExtractor(ContainerConfig.extracttext).extract(self) for constant in constants: result += constant.string return result def group(self, index, group, isingroup): "Group some adjoining elements into a group" if index >= len(self.contents): return if hasattr(self.contents[index], 'grouped'): return while index < len(self.contents) and isingroup(self.contents[index]): self.contents[index].grouped = True group.contents.append(self.contents[index]) self.contents.pop(index) self.contents.insert(index, group) def remove(self, index): "Remove a container but leave its contents" container = self.contents[index] self.contents.pop(index) while len(container.contents) > 0: self.contents.insert(index, container.contents.pop()) def tree(self, level = 0): "Show in a tree" Trace.debug(" " * level + unicode(self)) for container in self.contents: container.tree(level + 1) def getparameter(self, name): "Get the value of a parameter, if present." if not name in self.parameters: return None return self.parameters[name] def getparameterlist(self, name): "Get the value of a comma-separated parameter as a list." paramtext = self.getparameter(name) if not paramtext: return [] return paramtext.split(',') def hasemptyoutput(self): "Check if the parent's output is empty." current = self.parent while current: if current.output.isempty(): return True current = current.parent return False def __unicode__(self): "Get a description" if not self.begin: return self.__class__.__name__ return self.__class__.__name__ + '@' + unicode(self.begin) class BlackBox(Container): "A container that does not output anything" def __init__(self): self.parser = LoneCommand() self.output = EmptyOutput() self.contents = [] class LyXFormat(BlackBox): "Read the lyxformat command" def process(self): "Show warning if version < 276" version = int(self.header[1]) if version < 276: Trace.error('Warning: unsupported old format version ' + str(version)) if version > int(GeneralConfig.version['lyxformat']): Trace.error('Warning: unsupported new format version ' + str(version)) class StringContainer(Container): "A container for a single string" parsed = None def __init__(self): self.parser = StringParser() self.output = StringOutput() self.string = '' def process(self): "Replace special chars from elyxer.the contents." if self.parsed: self.string = self.replacespecial(self.parsed) self.parsed = None def replacespecial(self, line): "Replace all special chars from elyxer.a line" replaced = self.escape(line, EscapeConfig.entities) replaced = self.changeline(replaced) if ContainerConfig.string['startcommand'] in replaced and len(replaced) > 1: # unprocessed commands if self.begin: message = 'Unknown command at ' + unicode(self.begin) + ': ' else: message = 'Unknown command: ' Trace.error(message + replaced.strip()) return replaced def changeline(self, line): line = self.escape(line, EscapeConfig.chars) if not ContainerConfig.string['startcommand'] in line: return line line = self.escape(line, EscapeConfig.commands) return line def extracttext(self): "Return all text." return self.string def __unicode__(self): "Return a printable representation." result = 'StringContainer' if self.begin: result += '@' + unicode(self.begin) ellipsis = '...' if len(self.string.strip()) <= 15: ellipsis = '' return result + ' (' + self.string.strip()[:15] + ellipsis + ')' class Constant(StringContainer): "A constant string" def __init__(self, text): self.contents = [] self.string = text self.output = StringOutput() def __unicode__(self): return 'Constant: ' + self.string class TaggedText(Container): "Text inside a tag" output = None def __init__(self): self.parser = TextParser(self) self.output = TaggedOutput() def complete(self, contents, tag, breaklines=False): "Complete the tagged text and return it" self.contents = contents self.output.tag = tag self.output.breaklines = breaklines return self def constant(self, text, tag, breaklines=False): "Complete the tagged text with a constant" constant = Constant(text) return self.complete([constant], tag, breaklines) def __unicode__(self): "Return a printable representation." if not hasattr(self.output, 'tag'): return 'Emtpy tagged text' if not self.output.tag: return 'Tagged ' return 'Tagged <' + self.output.tag + '>' elyxer-1.2.5/forks/jras-elyxer/src/elyxer/gen/toc.py0000644000175000017500000001300712117061342021733 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20091006 # eLyXer TOC generation # http://www.nongnu.org/elyxer/ from elyxer.gen.header import * from elyxer.ref.label import * from elyxer.util.docparams import * class TOCEntry(Container): "A container for a TOC entry." def __init__(self): Container.__init__(self) self.branches = [] def create(self, container): "Create the TOC entry for a container, consisting of a single link." if container.partkey.header: return self.header(container) self.contents = [self.createlink(container)] self.output = TaggedOutput().settag('div class="toc"', True) self.partkey = container.partkey return self def header(self, container): "Create a TOC entry for header and footer (0 depth)." self.partkey = container.partkey self.output = EmptyOutput() return self def createlink(self, container): "Create the link that will make the whole TOC entry." labels = container.searchall(Label) link = Link() if self.isanchor(labels): link.url = '#' + container.partkey.partkey if Options.tocfor: link.url = Options.tocfor + link.url else: label = labels[0] link.destination = label if container.partkey.tocentry: link.complete(container.partkey.tocentry) if container.partkey.titlecontents: if Options.notoclabels: separator = u' ' else: separator = u': ' if container.partkey.tocentry: link.contents.append(Constant(separator)) link.contents += container.partkey.titlecontents return link def isanchor(self, labels): "Decide if the link is an anchor based on a set of labels." if len(labels) == 0: return True if not Options.tocfor: return False if Options.splitpart: return False return True def __unicode__(self): "Return a printable representation." if not self.partkey.tocentry: return 'Unnamed TOC entry' return 'TOC entry: ' + self.partkey.tocentry class Indenter(object): "Manages and writes indentation for the TOC." def __init__(self): self.depth = 0 def getindent(self, depth): indent = '' if depth > self.depth: indent = self.openindent(depth - self.depth) elif depth < self.depth: indent = self.closeindent(self.depth - depth) self.depth = depth return Constant(indent) def openindent(self, times): "Open the indenting div a few times." indent = '' for i in range(times): indent += '
\n' return indent def closeindent(self, times): "Close the indenting div a few times." indent = '' for i in range(times): indent += '
\n' return indent class IndentedEntry(Container): "An entry with an indentation." def __init__(self): self.output = ContentsOutput() def create(self, indent, entry): "Create the indented entry." self.entry = entry self.contents = [indent, entry] return self def __unicode__(self): "Return a printable documentation." return 'Indented ' + unicode(self.entry) class TOCTree(object): "A tree that contains the full TOC." def __init__(self): self.tree = [] self.branches = [] def store(self, entry): "Place the entry in a tree of entries." while len(self.tree) < entry.partkey.level: self.tree.append(None) if len(self.tree) > entry.partkey.level: self.tree = self.tree[:entry.partkey.level] stem = self.findstem() if len(self.tree) == 0: self.branches.append(entry) self.tree.append(entry) if stem: entry.stem = stem stem.branches.append(entry) def findstem(self): "Find the stem where our next element will be inserted." for element in reversed(self.tree): if element: return element return None class TOCConverter(object): "A converter from elyxer.containers to TOC entries." cache = dict() tree = TOCTree() def __init__(self): self.indenter = Indenter() def convertindented(self, container): "Convert a container into an indented TOC entry." entry = self.convert(container) if not entry: return None return self.indent(entry) def indent(self, entry): "Indent a TOC entry." indent = self.indenter.getindent(entry.partkey.level) return IndentedEntry().create(indent, entry) def convert(self, container): "Convert a container to a TOC entry." if not container.partkey: return None if container.partkey.partkey in self.cache: return TOCConverter.cache[container.partkey.partkey] if container.partkey.level > DocumentParameters.tocdepth: return None entry = TOCEntry().create(container) TOCConverter.cache[container.partkey.partkey] = entry TOCConverter.tree.store(entry) return entry elyxer-1.2.5/forks/jras-elyxer/src/elyxer/gen/inset.py0000644000175000017500000001155012117061342022271 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20090506 # LyX insets from elyxer.util.trace import Trace from elyxer.parse.parser import * from elyxer.parse.headerparse import * from elyxer.out.output import * from elyxer.io.bulk import * from elyxer.gen.container import * from elyxer.gen.styles import * from elyxer.gen.layout import * class InsetText(Container): "An inset of text in a lyx file" def __init__(self): self.parser = BoundedParser() self.output = ContentsOutput() class Inset(Container): "A generic inset in a LyX document" def __init__(self): self.contents = list() self.parser = InsetParser() self.output = TaggedOutput().setbreaklines(True) def process(self): self.type = self.header[1] self.output.tag = 'span class="' + self.type + '"' def __unicode__(self): return 'Inset of type ' + self.type class NewlineInset(Newline): "A newline or line break in an inset" def __init__(self): self.parser = InsetParser() self.output = FixedOutput() class NewPageInset(NewPage): "A new page command." def __init__(self): self.parser = InsetParser() self.output = FixedOutput() class Branch(Container): "A branch within a LyX document" def __init__(self): self.parser = InsetParser() self.output = TaggedOutput().settag('span class="branch"', True) def process(self): "Disable inactive branches" self.branch = self.header[2] if not self.isactive(): Trace.debug('Branch ' + self.branch + ' not active') self.output = EmptyOutput() def isactive(self): "Check if the branch is active" if not self.branch in Options.branches: Trace.error('Invalid branch ' + self.branch) return True branch = Options.branches[self.branch] return branch.isselected() class ShortTitle(Container): "A short title to display (always hidden)" def __init__(self): self.parser = InsetParser() self.output = EmptyOutput() class FlexInset(Container): "A flexible inset, generic version." def __init__(self): self.parser = InsetParser() self.output = TaggedOutput().settag('span', False) def process(self): "Set the correct flex tag." self.type = self.header[2] if self.type in TagConfig.flex: self.output.settag(TagConfig.flex[self.type], False) else: self.output.settag('span class="' + self.type + '"', False) class InfoInset(Container): "A LyX Info inset" def __init__(self): self.parser = InsetParser() self.output = TaggedOutput().settag('span class="Info"', False) def process(self): "Set the shortcut as text" self.type = self.getparameter('type') self.contents = [Constant(self.getparameter('arg'))] class BoxInset(Container): "A box inset" def __init__(self): self.parser = InsetParser() self.output = TaggedOutput().settag('div', True) def process(self): "Set the correct tag" self.type = self.header[2] self.output.settag('div class="' + self.type + '"', True) ContainerSize().readparameters(self).addstyle(self) class PhantomText(Container): "A line of invisible text (white over white)." def __init__(self): self.parser = InsetParser() self.output = TaggedOutput().settag('span class="phantom"', False) class LineInset(LyXLine): "A LaTeX ruler, but parsed as an inset." def __init__(self): self.parser = InsetParser() self.output = FixedOutput() class Caption(Container): "A caption for a figure or a table" def __init__(self): self.parser = InsetParser() self.output = TaggedOutput().settag('div class="caption"', True) def create(self, message): "Create a caption with a given message." self.contents = [Constant(message)] return self class ScriptInset(Container): "Sub- or super-script in an inset." def __init__(self): self.parser = InsetParser() self.output = TaggedOutput().settag('span', False) def process(self): "Set the correct script tag." self.type = self.header[2] if not self.type in TagConfig.script: Trace.error('Unknown script type ' + self.type) return self.output.settag(TagConfig.script[self.type], False) elyxer-1.2.5/forks/jras-elyxer/src/elyxer/gen/list.py0000644000175000017500000001105412117061342022121 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20100427 # eLyXer lists and list post-processing from elyxer.util.trace import Trace from elyxer.parse.parser import * from elyxer.out.output import * from elyxer.gen.container import * from elyxer.proc.postprocess import * class ListItem(Container): "An element in a list" type = 'none' def __init__(self): "Create a list item." self.parser = BoundedParser() self.output = ContentsOutput() def process(self): "Set the correct type and contents." self.type = self.header[1] tag = TaggedText().complete(self.contents, 'li', True) self.contents = [tag] def __unicode__(self): return self.type + ' item @ ' + unicode(self.begin) class DeeperList(Container): "A nested list" def __init__(self): "Create a nested list element." self.parser = BoundedParser() self.output = ContentsOutput() self.contents = [] def process(self): "Create the deeper list" if len(self.contents) == 0: Trace.error('Empty deeper list') return def __unicode__(self): result = 'deeper list @ ' + unicode(self.begin) + ': [' for element in self.contents: result += unicode(element) + ', ' return result[:-2] + ']' class PendingList(object): "A pending list" def __init__(self): self.contents = [] self.type = None def additem(self, item): "Add a list item" self.contents += item.contents if not self.type: self.type = item.type def adddeeper(self, deeper): "Add a deeper list item" if self.empty(): self.insertfake() self.contents[-1].contents += deeper.contents def generate(self): "Get the resulting list" if not self.type: tag = 'ul' else: tag = TagConfig.listitems[self.type] text = TaggedText().complete(self.contents, tag, True) self.__init__() return text def isduewithitem(self, item): "Decide whether the pending list must be generated before the given item" if not self.type: return False if self.type != item.type: return True return False def isduewithnext(self, next): "Applies only if the list is finished with next item." if not next: return True if not isinstance(next, ListItem) and not isinstance(next, DeeperList): return True return False def empty(self): return len(self.contents) == 0 def insertfake(self): "Insert a fake item" item = TaggedText().constant('', 'li class="nested"', True) self.contents = [item] self.type = 'Itemize' def __unicode__(self): result = 'pending ' + unicode(self.type) + ': [' for element in self.contents: result += unicode(element) + ', ' if len(self.contents) > 0: result = result[:-2] return result + ']' class PostListItem(object): "Postprocess a list item" processedclass = ListItem def postprocess(self, last, item, next): "Add the item to pending and return an empty item" if not hasattr(self.postprocessor, 'list'): self.postprocessor.list = PendingList() self.postprocessor.list.additem(item) if self.postprocessor.list.isduewithnext(next): return self.postprocessor.list.generate() if isinstance(next, ListItem) and self.postprocessor.list.isduewithitem(next): return self.postprocessor.list.generate() return BlackBox() class PostDeeperList(object): "Postprocess a deeper list" processedclass = DeeperList def postprocess(self, last, deeper, next): "Append to the list in the postprocessor" if not hasattr(self.postprocessor, 'list'): self.postprocessor.list = PendingList() self.postprocessor.list.adddeeper(deeper) if self.postprocessor.list.isduewithnext(next): return self.postprocessor.list.generate() return BlackBox() Postprocessor.stages += [PostListItem, PostDeeperList] elyxer-1.2.5/forks/jras-elyxer/src/elyxer/gen/styles.py0000644000175000017500000001434212117061342022474 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20090311 # LyX styles in containers from elyxer.util.trace import Trace from elyxer.util.numbering import * from elyxer.parse.parser import * from elyxer.out.output import * from elyxer.gen.container import * from elyxer.gen.size import * class QuoteContainer(Container): "A container for a pretty quote" def __init__(self): self.parser = BoundedParser() self.output = FixedOutput() def process(self): "Process contents" self.type = self.header[2] if not self.type in StyleConfig.quotes: Trace.error('Quote type ' + self.type + ' not found') self.html = ['"'] return self.html = [StyleConfig.quotes[self.type]] class LyXLine(Container): "A Lyx line" def __init__(self): self.parser = LoneCommand() self.output = FixedOutput() def process(self): self.html = ['
'] class EmphaticText(TaggedText): "Text with emphatic mode" def process(self): self.output.tag = 'i' class ShapedText(TaggedText): "Text shaped (italic, slanted)" def process(self): self.type = self.header[1] if not self.type in TagConfig.shaped: Trace.error('Unrecognized shape ' + self.header[1]) self.output.tag = 'span' return self.output.tag = TagConfig.shaped[self.type] class VersalitasText(TaggedText): "Text in versalitas" def process(self): self.output.tag = 'span class="versalitas"' class ColorText(TaggedText): "Colored text" def process(self): self.color = self.header[1] self.output.tag = 'span class="' + self.color + '"' class SizeText(TaggedText): "Sized text" def process(self): self.size = self.header[1] self.output.tag = 'span class="' + self.size + '"' class BoldText(TaggedText): "Bold text" def process(self): self.output.tag = 'b' class TextFamily(TaggedText): "A bit of text from elyxer.a different family" def process(self): "Parse the type of family" self.type = self.header[1] if not self.type in TagConfig.family: Trace.error('Unrecognized family ' + type) self.output.tag = 'span' return self.output.tag = TagConfig.family[self.type] class Hfill(TaggedText): "Horizontall fill" def process(self): self.output.tag = 'span class="hfill"' class BarredText(TaggedText): "Text with a bar somewhere" def process(self): "Parse the type of bar" self.type = self.header[1] if not self.type in TagConfig.barred: Trace.error('Unknown bar type ' + self.type) self.output.tag = 'span' return self.output.tag = TagConfig.barred[self.type] class LangLine(TaggedText): "A line with language information" def process(self): "Only generate a span with lang info when the language is recognized." lang = self.header[1] if not lang in TranslationConfig.languages: self.output = ContentsOutput() return isolang = TranslationConfig.languages[lang] self.output = TaggedOutput().settag('span lang="' + isolang + '"', False) class InsetLength(BlackBox): "A length measure inside an inset." def process(self): self.length = self.header[1] class Space(Container): "A space of several types" def __init__(self): self.parser = InsetParser() self.output = FixedOutput() def process(self): self.type = self.header[2] if self.type not in StyleConfig.hspaces: Trace.error('Unknown space type ' + self.type) self.html = [' '] return self.html = [StyleConfig.hspaces[self.type]] length = self.getlength() if not length: return self.output = TaggedOutput().settag('span class="hspace"', False) ContainerSize().set(length).addstyle(self) def getlength(self): "Get the space length from elyxer.the contents or parameters." if len(self.contents) == 0 or not isinstance(self.contents[0], InsetLength): return None return self.contents[0].length class VerticalSpace(Container): "An inset that contains a vertical space." def __init__(self): self.parser = InsetParser() self.output = FixedOutput() def process(self): "Set the correct tag" self.type = self.header[2] if self.type not in StyleConfig.vspaces: self.output = TaggedOutput().settag('div class="vspace" style="height: ' + self.type + ';"', True) return self.html = [StyleConfig.vspaces[self.type]] class Align(Container): "Bit of aligned text" def __init__(self): self.parser = ExcludingParser() self.output = TaggedOutput().setbreaklines(True) def process(self): self.output.tag = 'div class="' + self.header[1] + '"' class Newline(Container): "A newline" def __init__(self): self.parser = LoneCommand() self.output = FixedOutput() def process(self): "Process contents" self.html = ['
\n'] class NewPage(Newline): "A new page" def process(self): "Process contents" self.html = ['


\n

\n'] class Separator(Container): "A separator string which is not extracted by extracttext()." def __init__(self, constant): self.output = FixedOutput() self.contents = [] self.html = [constant] class StrikeOut(TaggedText): "Striken out text." def process(self): "Set the output tag to strike." self.output.tag = 'strike' class StartAppendix(BlackBox): "Mark to start an appendix here." "From this point on, all chapters become appendices." def process(self): "Activate the special numbering scheme for appendices, using letters." NumberGenerator.generator.startappendix() elyxer-1.2.5/forks/jras-elyxer/src/elyxer/gen/integral.py0000644000175000017500000001232712117061342022757 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20091109 # eLyXer integral processing # http://www.nongnu.org/elyxer/ from elyxer.gen.layout import * from elyxer.gen.float import * from elyxer.ref.index import * from elyxer.bib.biblio import * from elyxer.gen.basket import * class IntegralProcessor(object): "A processor for an integral document." def __init__(self): "Create the processor for the integral contents." self.storage = [] def locate(self, container): "Locate only containers of the processed type." return isinstance(container, self.processedtype) def store(self, container): "Store a new container." self.storage.append(container) def process(self): "Process the whole storage." for container in self.storage: self.processeach(container) class IntegralTOC(IntegralProcessor): "A processor for an integral TOC." processedtype = TableOfContents tocentries = [] def processeach(self, toc): "Fill in a Table of Contents." converter = TOCConverter() for container in PartKeyGenerator.partkeyed: toc.add(converter.convertindented(container)) # finish off with the footer to align indents toc.add(converter.convertindented(LyXFooter())) def writetotoc(self, entries, toc): "Write some entries to the TOC." for entry in entries: toc.contents.append(entry) class IntegralBiblioEntry(IntegralProcessor): "A processor for an integral bibliography entry." processedtype = BiblioEntry def processeach(self, entry): "Process each entry." number = NumberGenerator.generator.generate('integralbib') link = Link().complete('cite', 'biblio-' + number, type='biblioentry') link.contents = entry.citeref entry.contents = [Constant('['), link, Constant('] ')] if entry.key in BiblioCite.cites: for cite in BiblioCite.cites[entry.key]: cite.contents = entry.citeref cite.anchor = 'cite-' + number cite.destination = link class IntegralFloat(IntegralProcessor): "Store all floats in the document by type." processedtype = Float bytype = dict() def processeach(self, float): "Store each float by type." if not float.type in IntegralFloat.bytype: IntegralFloat.bytype[float.type] = [] IntegralFloat.bytype[float.type].append(float) class IntegralListOf(IntegralProcessor): "A processor for an integral list of floats." processedtype = ListOf def processeach(self, listof): "Fill in a list of floats." listof.output = TaggedOutput().settag('div class="fulltoc"', True) if not listof.type in IntegralFloat.bytype: Trace.message('No floats of type ' + listof.type) return for float in IntegralFloat.bytype[listof.type]: entry = self.processfloat(float) if entry: listof.contents.append(entry) def processfloat(self, float): "Get an entry for the list of floats." if not float.isparent(): return None return TOCEntry().create(float) class IntegralReference(IntegralProcessor): "A processor for a reference to a label." processedtype = Reference def processeach(self, reference): "Extract the text of the original label." reference.formatcontents() class MemoryBasket(KeeperBasket): "A basket which stores everything in memory, processes it and writes it." def __init__(self): "Create all processors in one go." KeeperBasket.__init__(self) self.processors = [ IntegralTOC(), IntegralBiblioEntry(), IntegralFloat(), IntegralListOf(), IntegralReference(), ] def finish(self): "Process everything which cannot be done in one pass and write to disk." self.process() self.flush() def process(self): "Process everything with the integral processors." self.searchintegral() for processor in self.processors: processor.process() def searchintegral(self): "Search for all containers for all integral processors." for container in self.contents: # container.tree() if self.integrallocate(container): self.integralstore(container) container.locateprocess(self.integrallocate, self.integralstore) def integrallocate(self, container): "Locate all integrals." for processor in self.processors: if processor.locate(container): return True return False def integralstore(self, container): "Store a container in one or more processors." for processor in self.processors: if processor.locate(container): processor.store(container) elyxer-1.2.5/forks/jras-elyxer/src/elyxer/gen/include.py0000644000175000017500000000657612117061342022606 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20110201 # LyX child documents (included insets). from elyxer.util.trace import Trace from elyxer.parse.parser import * from elyxer.parse.headerparse import * from elyxer.out.output import * from elyxer.io.bulk import * from elyxer.gen.container import * from elyxer.gen.styles import * from elyxer.gen.layout import * from elyxer.gen.float import * class IncludeInset(Container): "A child document included within another." # the converter factory will be set in converter.py converterfactory = None filename = None def __init__(self): self.parser = InsetParser() self.output = ContentsOutput() def process(self): "Include the provided child document" self.filename = os.path.join(Options.directory, self.getparameter('filename')) Trace.debug('Child document: ' + self.filename) LstParser().parsecontainer(self) command = self.getparameter('LatexCommand') if command == 'verbatiminput': self.readverbatim() return elif command == 'lstinputlisting': self.readlisting() return self.processinclude() def processinclude(self): "Process a regular include: standard child document." self.contents = [] olddir = Options.directory newdir = os.path.dirname(self.getparameter('filename')) if newdir != '': Trace.debug('Child dir: ' + newdir) Options.directory = os.path.join(Options.directory, newdir) try: self.convertinclude() finally: Options.directory = olddir def convertinclude(self): "Convert an included document." try: converter = IncludeInset.converterfactory.create(self) except: Trace.error('Could not read ' + self.filename + ', please check that the file exists and has read permissions.') return if self.hasemptyoutput(): return converter.convert() self.contents = converter.getcontents() def readverbatim(self): "Read a verbatim document." self.contents = [TaggedText().complete(self.readcontents(), 'pre', True)] def readlisting(self): "Read a document as a listing." listing = Listing() listing.contents = self.readcontents() listing.parameters = self.parameters listing.process() self.contents = [listing] def readcontents(self): "Read the contents of a complete file." contents = list() lines = BulkFile(self.filename).readall() for line in lines: contents.append(Constant(line)) return contents def __unicode__(self): "Return a printable description." if not self.filename: return 'Included unnamed file' return 'Included "' + self.filename + '"' elyxer-1.2.5/forks/jras-elyxer/src/elyxer/gen/image.py0000644000175000017500000002140512117061342022231 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20090308 # eLyXer image treatment import struct import sys import os import shutil from elyxer.util.trace import Trace from elyxer.util.translate import * from elyxer.gen.container import * from elyxer.gen.size import * from elyxer.io.path import * class Image(Container): "An embedded image" defaultformat = ImageConfig.formats['default'] size = None copy = None def __init__(self): self.parser = InsetParser() self.output = TaggedOutput() self.type = 'embedded' def process(self): "Place the url, convert the image if necessary." self.origin = InputPath(self.getparameter('filename')) self.destination = self.getdestination(self.origin) self.size = ContainerSize().readparameters(self) if self.origin.exists(): ImageConverter.instance.convert(self) else: Trace.error('Image ' + unicode(self.origin) + ' not found') self.setsize() self.settag() def getdestination(self, origin): "Convert origin path to destination path." "Changes extension of destination to output image format." destination = OutputPath(origin) if Options.noconvert: return destination self.convertformat(destination) destination.removebackdirs() return destination def convertformat(self, destination): "Convert the format of the destination image." if Options.copyimages: return imageformat = '.jpg' forcedest = Image.defaultformat if Options.imageformat: imageformat = Options.imageformat forcedest = Options.imageformat if not destination.hasext(imageformat): destination.changeext(forcedest) def setsize(self): "Set the size attributes width and height." width, height = ImageFile(self.destination).getdimensions() self.size.checkimage(width, height) def scalevalue(self, value): "Scale the value according to the image scale and return it as unicode." scaled = value * int(self.size.scale) / 100 return unicode(int(scaled)) + 'px' def settag(self): "Set the output tag for the image." tag = 'img class="' + self.type + '"' if self.origin.exists(): url = self.destination.url else: url = self.origin.url alt = Translator.translate('figure') + ' ' + url tag += ' src="' + url + '" alt="' + alt + '"' emptytag = True if self.destination.hasext('.svg'): self.contents = [Constant(alt)] tag = 'object class="' + self.type + '" data="' + url + '"' emptytag = False self.output.settag(tag, True, empty=emptytag) self.size.addstyle(self) class ImageConverter(object): "A converter from elyxer.one image file to another." vectorformats = ImageConfig.formats['vector'] cropboxformats = ImageConfig.cropboxformats active = True instance = None def convert(self, image): "Convert an image to PNG" if not ImageConverter.active or Options.noconvert: return if image.origin.path == image.destination.path: return if image.destination.exists(): if image.origin.getmtime() <= image.destination.getmtime(): # file has not changed; do not convert return image.destination.createdirs() if Options.copyimages: Trace.debug('Copying ' + image.origin.path + ' to ' + image.destination.path) shutil.copy2(image.origin.path, image.destination.path) return converter, command = self.buildcommand(image) try: Trace.debug(converter + ' command: "' + command + '"') result = os.system(command.encode(sys.getfilesystemencoding())) if result != 0: Trace.error(converter + ' not installed; images will not be processed') ImageConverter.active = False return Trace.message('Converted ' + unicode(image.origin) + ' to ' + unicode(image.destination)) except OSError, exception: Trace.error('Error while converting image ' + unicode(image.origin) + ': ' + unicode(exception)) def buildcommand(self, image): "Build the command to convert the image." if Options.converter in ImageConfig.converters: command = ImageConfig.converters[Options.converter] else: command = Options.converter; params = self.getparams(image) for param in params: command = command.replace('$' + param, unicode(params[param])) # remove unwanted options while '[' in command and ']' in command: command = self.removeparam(command) return Options.converter, command def removeparam(self, command): "Remove an unwanted param." if command.index('[') > command.index(']'): Trace.error('Converter command should be [...$...]: ' + command) exit() before = command[:command.index('[')] after = command[command.index(']') + 1:] between = command[command.index('[') + 1:command.index(']')] if '$' in between: return before + after return before + between + after def getparams(self, image): "Get the parameters for ImageMagick conversion" params = dict() params['input'] = image.origin params['output'] = image.destination if image.origin.hasexts(self.vectorformats): scale = 100 if image.size.scale: scale = image.size.scale # descale image.size.scale = None params['scale'] = scale if image.origin.getext() in self.cropboxformats: params['format'] = self.cropboxformats[image.origin.getext()] return params ImageConverter.instance = ImageConverter() class ImageFile(object): "A file corresponding to an image (JPG or PNG)" dimensions = dict() def __init__(self, path): "Create the file based on its path" self.path = path def getdimensions(self): "Get the dimensions of a JPG or PNG image" if not self.path.exists(): return None, None if unicode(self.path) in ImageFile.dimensions: return ImageFile.dimensions[unicode(self.path)] dimensions = (None, None) if self.path.hasext('.png'): dimensions = self.getpngdimensions() elif self.path.hasext('.jpg'): dimensions = self.getjpgdimensions() elif self.path.hasext('.svg'): dimensions = self.getsvgdimensions() ImageFile.dimensions[unicode(self.path)] = dimensions return dimensions def getpngdimensions(self): "Get the dimensions of a PNG image" pngfile = self.path.open() pngfile.seek(16) width = self.readlong(pngfile) height = self.readlong(pngfile) pngfile.close() return (width, height) def getjpgdimensions(self): "Get the dimensions of a JPEG image" jpgfile = self.path.open() start = self.readword(jpgfile) if start != int('ffd8', 16): Trace.error(unicode(self.path) + ' not a JPEG file') return (None, None) self.skipheaders(jpgfile, ['ffc0', 'ffc2']) self.seek(jpgfile, 3) height = self.readword(jpgfile) width = self.readword(jpgfile) jpgfile.close() return (width, height) def getsvgdimensions(self): "Get the dimensions of a SVG image." return (None, None) def skipheaders(self, file, hexvalues): "Skip JPEG headers until one of the parameter headers is found" headervalues = [int(value, 16) for value in hexvalues] header = self.readword(file) safetycounter = 0 while header not in headervalues and safetycounter < 30: length = self.readword(file) if length == 0: Trace.error('End of file ' + file.name) return self.seek(file, length - 2) header = self.readword(file) safetycounter += 1 def readlong(self, file): "Read a long (32-bit) value from elyxer.file" return self.readformat(file, '>L', 4) def readword(self, file): "Read a 16-bit value from elyxer.file" return self.readformat(file, '>H', 2) def readformat(self, file, format, bytes): "Read any format from elyxer.file" read = file.read(bytes) if read == '' or len(read) < bytes: Trace.error('EOF reached') return 0 tuple = struct.unpack(format, read) return tuple[0] def seek(self, file, bytes): "Seek forward, just by reading the given number of bytes" file.read(bytes) elyxer-1.2.5/forks/jras-elyxer/src/elyxer/gen/change.py0000644000175000017500000000277512117061342022405 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20100829 # Change tracking from elyxer.util.trace import Trace from elyxer.util.docparams import * from elyxer.gen.container import * class ChangeInserted(Container): "A change which consists of an insertion." def __init__(self): self.parser = TextParser(self) if DocumentParameters.outputchanges: self.output = TaggedOutput().settag('span class="inserted"') else: self.output = ContentsOutput() class ChangeDeleted(TaggedText): "A change which consists of a deletion." def __init__(self): self.parser = TextParser(self) if DocumentParameters.outputchanges: self.output = TaggedOutput().settag('span class="deleted"') else: self.output = EmptyOutput() elyxer-1.2.5/forks/jras-elyxer/src/elyxer/gen/header.py0000644000175000017500000001011012117061342022366 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20090312 # LyX structure in containers from elyxer.util.docparams import * from elyxer.parse.parser import * from elyxer.parse.headerparse import * from elyxer.out.output import * from elyxer.out.template import * from elyxer.gen.container import * from elyxer.ref.partkey import * from elyxer.maths.command import * from elyxer.maths.macro import * from elyxer.gen.notes import * class LyXHeader(Container): "Reads the header, outputs the HTML header" def __init__(self): self.contents = [] self.parser = HeaderParser() self.output = HeaderOutput() self.parameters = dict() self.partkey = PartKey().createheader('header') def process(self): "Find pdf title" DocumentParameters.pdftitle = self.getheaderparameter('pdftitle') documentclass = self.getheaderparameter('documentclass') if documentclass in HeaderConfig.styles['article']: DocumentParameters.startinglevel = 1 if documentclass in HeaderConfig.styles['book']: DocumentParameters.bibliography = 'bibliography' else: DocumentParameters.bibliography = 'references' if self.getheaderparameter('paragraphseparation') == 'indent': DocumentParameters.indentstandard = True DocumentParameters.tocdepth = self.getlevel('tocdepth') DocumentParameters.maxdepth = self.getlevel('secnumdepth') DocumentParameters.language = self.getheaderparameter('language') if self.getheaderparameter('outputchanges') == 'true': DocumentParameters.outputchanges = True return self def getheaderparameter(self, configparam): "Get a parameter configured in HeaderConfig." key = HeaderConfig.parameters[configparam] if not key in self.parameters: return None return self.parameters[key] def getlevel(self, configparam): "Get a level read as a parameter from elyxer.HeaderConfig." paramvalue = self.getheaderparameter(configparam) if not paramvalue: return 0 value = int(paramvalue) if DocumentParameters.startinglevel == 1: return value return value + 1 class LyXPreamble(Container): "The preamble at the beginning of a LyX file. Parsed for macros." def __init__(self): self.parser = PreambleParser() self.output = EmptyOutput() self.factory = FormulaFactory() def process(self): "Parse the LyX preamble, if needed." if len(PreambleParser.preamble) == 0: return pos = TextPosition('\n'.join(PreambleParser.preamble)) while not pos.finished(): if self.detectfunction(pos): self.parsefunction(pos) else: pos.globincluding('\n') PreambleParser.preamble = [] def detectfunction(self, pos): "Detect a macro definition or a preamble function." for function in FormulaConfig.misccommands: if pos.checkfor(function): return True return False def parsefunction(self, pos): "Parse a single command." self.factory.parsetype(FormulaCommand, pos) class LyXFooter(Container): "Reads the footer, outputs the HTML footer" def __init__(self): self.contents = [] self.parser = BoundedDummy() self.output = FooterOutput() self.partkey = PartKey().createheader('footer') def process(self): "Include any footnotes at the end." if EndFootnotes.footnotes: endnotes = EndFootnotes() self.contents = [endnotes] elyxer-1.2.5/forks/jras-elyxer/src/elyxer/gen/basket.py0000644000175000017500000000464312117061342022425 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20091101 # eLyXer output baskets # http://www.nongnu.org/elyxer/ from elyxer.util.options import * from elyxer.util.clone import * from elyxer.gen.toc import * class Basket(object): "A basket to place a set of containers. Can write them, store them..." def setwriter(self, writer): self.writer = writer return self class WriterBasket(Basket): "A writer of containers. Just writes them out to a writer." def write(self, container): "Write a container to the line writer." self.writer.write(container.gethtml()) def finish(self): "Mark as finished." self.writer.close() class KeeperBasket(Basket): "Keeps all containers stored." def __init__(self): self.contents = [] def write(self, container): "Keep the container." self.contents.append(container) def finish(self): "Finish the basket by flushing to disk." self.flush() def flush(self): "Flush the contents to the writer." for container in self.contents: self.writer.write(container.gethtml()) self.writer.close() class TOCBasket(Basket): "A basket to place the TOC of a document." def __init__(self): self.converter = TOCConverter() def setwriter(self, writer): Basket.setwriter(self, writer) Options.nocopy = True self.writer.write(LyXHeader().gethtml()) return self def write(self, container): "Write the table of contents for a container." entry = self.converter.convertindented(container) if entry: self.writer.write(entry.gethtml()) def finish(self): "Mark as finished." self.writer.write(LyXFooter().gethtml()) self.writer.close() elyxer-1.2.5/forks/jras-elyxer/src/elyxer/gen/size.py0000644000175000017500000001141312117061342022117 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20100828 # Container size parsing and output from elyxer.util.trace import Trace from elyxer.gen.container import * class ContainerSize(object): "The size of a container." width = None height = None maxwidth = None maxheight = None scale = None def set(self, width = None, height = None): "Set the proper size with width and height." self.setvalue('width', width) self.setvalue('height', height) return self def setmax(self, maxwidth = None, maxheight = None): "Set max width and/or height." self.setvalue('maxwidth', maxwidth) self.setvalue('maxheight', maxheight) return self def readparameters(self, container): "Read some size parameters off a container." self.setparameter(container, 'width') self.setparameter(container, 'height') self.setparameter(container, 'scale') self.checkvalidheight(container) return self def setparameter(self, container, name): "Read a size parameter off a container, and set it if present." value = container.getparameter(name) self.setvalue(name, value) def setvalue(self, name, value): "Set the value of a parameter name, only if it's valid." value = self.processparameter(value) if value: setattr(self, name, value) def checkvalidheight(self, container): "Check if the height parameter is valid; otherwise erase it." heightspecial = container.getparameter('height_special') if self.height and self.extractnumber(self.height) == '1' and heightspecial == 'totalheight': self.height = None def processparameter(self, value): "Do the full processing on a parameter." if not value: return None if self.extractnumber(value) == '0': return None for ignored in StyleConfig.size['ignoredtexts']: if ignored in value: value = value.replace(ignored, '') return value def extractnumber(self, text): "Extract the first number in the given text." result = '' decimal = False for char in text: if char.isdigit(): result += char elif char == '.' and not decimal: result += char decimal = True else: return result return result def checkimage(self, width, height): "Check image dimensions, set them if possible." if width: self.maxwidth = unicode(width) + 'px' if self.scale and not self.width: self.width = self.scalevalue(width) if height: self.maxheight = unicode(height) + 'px' if self.scale and not self.height: self.height = self.scalevalue(height) if self.width and not self.height: self.height = 'auto' if self.height and not self.width: self.width = 'auto' def scalevalue(self, value): "Scale the value according to the image scale and return it as unicode." scaled = value * int(self.scale) / 100 return unicode(int(scaled)) + 'px' def removepercentwidth(self): "Remove percent width if present, to set it at the figure level." if not self.width: return None if not '%' in self.width: return None width = self.width self.width = None if self.height == 'auto': self.height = None return width def addstyle(self, container): "Add the proper style attribute to the output tag." if not isinstance(container.output, TaggedOutput): Trace.error('No tag to add style, in ' + unicode(container)) if not self.width and not self.height and not self.maxwidth and not self.maxheight: # nothing to see here; move along return tag = ' style="' tag += self.styleparameter('width') tag += self.styleparameter('maxwidth') tag += self.styleparameter('height') tag += self.styleparameter('maxheight') if tag[-1] == ' ': tag = tag[:-1] tag += '"' container.output.tag += tag def styleparameter(self, name): "Get the style for a single parameter." value = getattr(self, name) if value: return name.replace('max', 'max-') + ': ' + value + '; ' return '' elyxer-1.2.5/forks/jras-elyxer/src/elyxer/gen/layout.py0000644000175000017500000002356712117061342022477 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20090411 # LyX layout and derived classes from elyxer.util.trace import Trace from elyxer.parse.parser import * from elyxer.out.output import * from elyxer.gen.container import * from elyxer.gen.styles import * from elyxer.gen.header import * from elyxer.proc.postprocess import * from elyxer.ref.label import * from elyxer.ref.partkey import * from elyxer.ref.link import * class Layout(Container): "A layout (block of text) inside a lyx file" type = 'none' def __init__(self): "Initialize the layout." self.contents = [] self.parser = BoundedParser() self.output = TaggedOutput().setbreaklines(True) def process(self): "Get the type and numerate if necessary." self.type = self.header[1] if self.type in TagConfig.layouts: self.output.tag = TagConfig.layouts[self.type] + ' class="' + self.type + '"' elif self.type.replace('*', '') in TagConfig.layouts: self.output.tag = TagConfig.layouts[self.type.replace('*', '')] self.output.tag += ' class="' + self.type.replace('*', '-') + '"' else: self.output.tag = 'div class="' + self.type + '"' self.numerate() def numerate(self): "Numerate if necessary." partkey = PartKeyGenerator.forlayout(self) if partkey: self.partkey = partkey self.output.tag = self.output.tag.replace('?', unicode(partkey.level)) def __unicode__(self): "Return a printable representation." if self.partkey: return 'Layout ' + self.type + ' #' + unicode(self.partkey.partkey) return 'Layout of type ' + self.type class StandardLayout(Layout): "A standard layout -- can be a true div or nothing at all" indentation = False def process(self): self.type = 'standard' self.output = ContentsOutput() def complete(self, contents): "Set the contents and return it." self.process() self.contents = contents return self class Title(Layout): "The title of the whole document" def process(self): self.type = 'title' self.output.tag = 'h1 class="title"' title = self.extracttext() DocumentTitle.title = title Trace.message('Title: ' + title) class Author(Layout): "The document author" def process(self): self.type = 'author' self.output.tag = 'h2 class="author"' author = self.extracttext() Trace.debug('Author: ' + author) DocumentAuthor.appendauthor(author) class Abstract(Layout): "A paper abstract" done = False def process(self): self.type = 'abstract' self.output.tag = 'div class="abstract"' if Abstract.done: return message = Translator.translate('abstract') tagged = TaggedText().constant(message, 'p class="abstract-message"', True) self.contents.insert(0, tagged) Abstract.done = True class FirstWorder(Layout): "A layout where the first word is extracted" def extractfirstword(self): "Extract the first word as a list" return self.extractfromcontents(self.contents) def extractfromcontents(self, contents): "Extract the first word in contents." firstcontents = [] while len(contents) > 0: if self.isfirstword(contents[0]): firstcontents.append(contents[0]) del contents[0] return firstcontents if self.spaceincontainer(contents[0]): extracted = self.extractfromcontainer(contents[0]) firstcontents.append(extracted) return firstcontents firstcontents.append(contents[0]) del contents[0] return firstcontents def extractfromcontainer(self, container): "Extract the first word from a container cloning it including its output." if isinstance(container, StringContainer): return self.extractfromstring(container) result = Cloner.clone(container) result.output = container.output result.contents = self.extractfromcontents(container.contents) return result def extractfromstring(self, container): "Extract the first word from elyxer.a string container." if not ' ' in container.string: Trace.error('No space in string ' + container.string) return container split = container.string.split(' ', 1) container.string = split[1] return Constant(split[0]) def spaceincontainer(self, container): "Find out if the container contains a space somewhere." return ' ' in container.extracttext() def isfirstword(self, container): "Find out if the container is valid as a first word." if not isinstance(container, FirstWord): return False return not container.isempty() class FirstWord(Container): "A container which is in itself a first word, unless it's empty." "Should be inherited by other containers, e.g. ERT." def isempty(self): "Find out if the first word is empty." Trace.error('Unimplemented isempty()') return True class Description(FirstWorder): "A description layout" def process(self): "Set the first word to bold" self.type = 'Description' self.output.tag = 'div class="Description"' firstword = self.extractfirstword() if not firstword: return tag = 'span class="Description-entry"' self.contents.insert(0, TaggedText().complete(firstword, tag)) self.contents.insert(1, Constant(u' ')) class List(FirstWorder): "A list layout" def process(self): "Set the first word to bold" self.type = 'List' self.output.tag = 'div class="List"' firstword = self.extractfirstword() if not firstword: return first = TaggedText().complete(firstword, 'span class="List-entry"') second = TaggedText().complete(self.contents, 'span class="List-contents"') self.contents = [first, second] class PlainLayout(Layout): "A plain layout" def process(self): "Output just as contents." self.output = ContentsOutput() self.type = 'Plain' def makevisible(self): "Make the layout visible, output as tagged text." self.output = TaggedOutput().settag('div class="PlainVisible"', True) class LyXCode(Layout): "A bit of LyX-Code." def process(self): "Output as pre." self.output.tag = 'pre class="LyX-Code"' for newline in self.searchall(Newline): index = newline.parent.contents.index(newline) newline.parent.contents[index] = Constant('\n') class PostLayout(object): "Numerate an indexed layout" processedclass = Layout def postprocess(self, last, layout, next): "Group layouts and/or number them." if layout.type in TagConfig.group['layouts']: return self.group(last, layout) if layout.partkey: self.number(layout) return layout def group(self, last, layout): "Group two layouts if they are the same type." if not self.isgroupable(layout) or not self.isgroupable(last) or last.type != layout.type: return layout layout.contents = last.contents + [Constant('
\n')] + layout.contents last.contents = [] last.output = EmptyOutput() return layout def isgroupable(self, container): "Check that the container can be grouped." if not isinstance(container, Layout): return False for element in container.contents: if not element.__class__.__name__ in LayoutConfig.groupable['allowed']: return False return True def number(self, layout): "Generate a number and place it before the text" layout.partkey.addtoclabel(layout) class PostStandard(object): "Convert any standard spans in root to divs" processedclass = StandardLayout def postprocess(self, last, standard, next): "Switch to div, and clear if empty." type = 'Standard' if self.isempty(standard): standard.output = EmptyOutput() return standard if DocumentParameters.indentstandard: if isinstance(last, StandardLayout): type = 'Indented' else: type = 'Unindented' standard.output = TaggedOutput().settag('div class="' + type + '"', True) return standard def isempty(self, standard): "Find out if the standard layout is empty." for element in standard.contents: if not element.output.isempty(): return False return True class PostPlainLayout(PostLayout): "Numerate a plain layout" processedclass = PlainLayout def postprocess(self, last, plain, next): "Group plain layouts." if not self.istext(last) or not self.istext(plain): return plain plain.makevisible() return self.group(last, plain) def istext(self, container): "Find out if the container is only text." if not isinstance(container, PlainLayout): return False extractor = ContainerExtractor(TOCConfig.extractplain) text = extractor.extract(container) return (len(text) > 0) class PostLyXCode(object): "Coalesce contiguous LyX-Code layouts." processedclass = LyXCode def postprocess(self, last, lyxcode, next): "Coalesce if last was also LyXCode" if not isinstance(last, LyXCode): return lyxcode if hasattr(last, 'first'): lyxcode.first = last.first else: lyxcode.first = last toappend = lyxcode.first.contents toappend.append(Constant('\n')) toappend += lyxcode.contents lyxcode.output = EmptyOutput() return lyxcode Postprocessor.stages += [ PostLayout, PostStandard, PostLyXCode, PostPlainLayout ] elyxer-1.2.5/forks/jras-elyxer/src/elyxer/gen/table.py0000644000175000017500000001301212117061342022231 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20090207 # eLyXer tables from elyxer.util.trace import Trace from elyxer.gen.container import * from elyxer.gen.layout import * from elyxer.parse.parser import * from elyxer.out.output import * from elyxer.parse.tableparse import * from elyxer.proc.postprocess import * class Table(Container): "A lyx table" def __init__(self): self.parser = TableParser() self.output = TaggedOutput().settag('table', True) self.columns = [] def process(self): "Set the columns on every row" index = 0 while index < len(self.contents): element = self.contents[index] if isinstance(element, Column): self.columns.append(element) del self.contents[index] elif isinstance(element, BlackBox): del self.contents[index] elif isinstance(element, Row): element.setcolumns(self.columns) index += 1 else: Trace.error('Unknown element type ' + element.__class__.__name__ + ' in table: ' + unicode(element.contents[0])) index += 1 class Row(Container): "A row in a table" def __init__(self): self.parser = TablePartParser() self.output = TaggedOutput().settag('tr', True) self.columns = list() def setcolumns(self, columns): "Process alignments for every column" if len(columns) != len(self.contents): Trace.error('Columns: ' + unicode(len(columns)) + ', cells: ' + unicode(len(self.contents))) return for index, cell in enumerate(self.contents): columns[index].set(cell) class Column(Container): "A column definition in a table" def __init__(self): self.parser = ColumnParser() self.output = EmptyOutput() def process(self): "Read size parameters if present." self.size = ContainerSize().readparameters(self) def set(self, cell): "Set alignments in the corresponding cell" alignment = self.getparameter('alignment') if alignment == 'block': alignment = 'justify' cell.setattribute('align', alignment) valignment = self.getparameter('valignment') cell.setattribute('valign', valignment) self.size.addstyle(cell) class Cell(Container): "A cell in a table" def __init__(self): self.parser = TablePartParser() self.output = TaggedOutput().settag('td', True) def setmulticolumn(self, span): "Set the cell as multicolumn" self.setattribute('colspan', span) def setattribute(self, attribute, value): "Set a cell attribute in the tag" self.output.tag += ' ' + attribute + '="' + unicode(value) + '"' class PostTable(object): "Postprocess a table" processedclass = Table def postprocess(self, last, table, next): "Postprocess a table: long table, multicolumn rows" self.longtable(table) for row in table.contents: index = 0 while index < len(row.contents): self.checkforplain(row, index) self.checkmulticolumn(row, index) index += 1 return table def longtable(self, table): "Postprocess a long table, removing unwanted rows" features = table.getparameter('features') if not features: return if not 'islongtable' in features: return if features['islongtable'] != 'true': return if self.hasrow(table, 'endfirsthead'): self.removerows(table, 'endhead') if self.hasrow(table, 'endlastfoot'): self.removerows(table, 'endfoot') def hasrow(self, table, attrname): "Find out if the table has a row of first heads" for row in table.contents: if row.getparameter(attrname): return True return False def removerows(self, table, attrname): "Remove the head rows, since the table has first head rows." for row in table.contents: if row.getparameter(attrname): row.output = EmptyOutput() def checkforplain(self, row, index): "Make plain layouts visible if necessary." cell = row.contents[index] plainlayouts = cell.searchall(PlainLayout) if len(plainlayouts) <= 1: return for plain in plainlayouts: plain.makevisible() def checkmulticolumn(self, row, index): "Process a multicolumn attribute" cell = row.contents[index] mc = cell.getparameter('multicolumn') if not mc: return if mc != '1': Trace.error('Unprocessed multicolumn=' + unicode(multicolumn) + ' cell ' + unicode(cell)) return total = 1 index += 1 while self.checkbounds(row, index): del row.contents[index] total += 1 cell.setmulticolumn(total) def checkbounds(self, row, index): "Check if the index is within bounds for the row" if index >= len(row.contents): return False mc = row.contents[index].getparameter('multicolumn') if mc != '2': return False return True Postprocessor.stages.append(PostTable) elyxer-1.2.5/forks/jras-elyxer/src/elyxer/gen/float.py0000644000175000017500000002004112117061342022247 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20090518 # LyX floats from elyxer.util.trace import Trace from elyxer.util.numbering import * from elyxer.parse.parser import * from elyxer.out.output import * from elyxer.gen.layout import * from elyxer.gen.image import * from elyxer.ref.label import * from elyxer.ref.partkey import * from elyxer.proc.postprocess import * class Float(Container): "A floating inset" type = 'none' def __init__(self): self.parser = InsetParser() self.output = TaggedOutput().settag('div class="float"', True) def process(self): "Get the float type." self.type = self.header[2] self.processnumber() self.processfloats() self.processtags() def isparent(self): "Find out whether the float is the parent float or is contained in another float." current = self.parent while current: if isinstance(current, Float): return False current = current.parent return True def processnumber(self): "Number a float if it isn't numbered." if not self.isparent(): # do nothing; parent will take care of numbering return self.partkey = PartKey().createfloat(self) def processtags(self): "Process the HTML tags." tagged = self.embed() self.applywideningtag(tagged) def embed(self): "Embed the whole contents in a div." embeddedtag = self.getembeddedtag() tagged = TaggedText().complete(self.contents, embeddedtag, True) self.contents = [tagged] return tagged def processfloats(self): "Process all floats contained inside." floats = self.searchall(Float) counter = NumberCounter('subfloat').setmode('a') for subfloat in floats: subfloat.output.tag = subfloat.output.tag.replace('div', 'span') subfloat.partkey = PartKey().createsubfloat(counter.getnext()) def getembeddedtag(self): "Get the tag for the embedded object." floats = self.searchall(Float) if len(floats) > 0: return 'div class="multi' + self.type + '"' return 'div class="' + self.type + '"' def applywideningtag(self, container): "Apply the tag to set float width, if present." images = self.searchall(Image) if len(images) != 1: return '' image = images[0] if not image.size: return width = image.size.removepercentwidth() if not width: return image.type = 'figure' ContainerSize().setmax(width).addstyle(container) image.settag() def searchinside(self, type): "Search for a given type in the contents" return self.searchincontents(self.contents, type) def searchincontents(self, contents, type): "Search in the given contents for the required type." list = [] for element in contents: list += self.searchinelement(element, type) return list def searchinelement(self, element, type): "Search for a given type outside floats" if isinstance(element, Float): return [] if isinstance(element, type): return [element] return self.searchincontents(element.contents, type) def __unicode__(self): "Return a printable representation" return 'Floating inset of type ' + self.type class Wrap(Float): "A wrapped (floating) float" def processtags(self): "Add the widening tag to the parent tag." self.embed() placement = self.getparameter('placement') if not placement: placement = 'o' self.output.tag = 'div class="wrap-' + placement + '"' self.applywideningtag(self) class Listing(Container): "A code listing" processor = None def __init__(self): self.parser = InsetParser() self.output = TaggedOutput().settag('div class="listing"', True) self.numbered = None def process(self): "Remove all layouts" self.counter = 0 self.type = 'listing' self.processparams() if Listing.processor: Listing.processor.preprocess(self) for container in self.extractcontents(): if container: self.contents.append(container) if 'caption' in self.lstparams: text = self.lstparams['caption'][1:-1] self.contents.insert(0, Caption().create(text)) if Listing.processor: Listing.processor.postprocess(self) def extractcontents(self): "Extract all contents one container at a time." oldcontents = self.contents self.contents = [] inpre = [] for container in oldcontents: if self.iscaption(container): yield self.completepre(inpre) inpre = [] yield container else: inpre += self.extract(container) yield self.completepre(inpre) def processparams(self): "Process listing parameteres." LstParser().parsecontainer(self) if 'numbers' in self.lstparams: self.numbered = self.lstparams['numbers'] def iscaption(self, container): "Find out if the container has a caption (which should not be in
)."
    return (len(container.searchall(Caption)) > 0)

  def completepre(self, listinpre):
    "Complete the 
 tag with whatever has already been added."
    if len(listinpre) == 0:
      return None
    return TaggedText().complete(listinpre, 'pre class="listing"', False)

  def extract(self, container):
    "Extract the container's contents and return them"
    if isinstance(container, StringContainer):
      return self.modifystring(container)
    if isinstance(container, StandardLayout):
      return self.modifylayout(container)
    if isinstance(container, PlainLayout):
      return self.modifylayout(container)
    Trace.error('Unexpected container ' + container.__class__.__name__ +
        ' in listing')
    container.tree()
    return []

  def modifystring(self, string):
    "Modify a listing string"
    if string.string == '':
      string.string = u'​'
    return self.modifycontainer(string)

  def modifylayout(self, layout):
    "Modify a standard layout"
    if len(layout.contents) == 0:
      layout.contents = [Constant(u'​')]
    return self.modifycontainer(layout)

  def modifycontainer(self, container):
    "Modify a listing container"
    contents = [container, Constant('\n')]
    if self.numbered:
      self.counter += 1
      tag = 'span class="number-' + self.numbered + '"'
      contents.insert(0, TaggedText().constant(unicode(self.counter), tag))
    return contents

class FloatNumber(Container):
  "Holds the number for a float in the caption."

  def __init__(self):
    self.output = ContentsOutput()

  def create(self, float):
    "Create the float number."
    self.contents = [Constant(float.partkey.partkey)]
    return self

class PostFloat(object):
  "Postprocess a float: number it and move the label"

  processedclass = Float

  def postprocess(self, last, float, next):
    "Move the label to the top and number the caption"
    number = FloatNumber().create(float)
    for caption in float.searchinside(Caption):
      self.postlabels(float, caption)
      caption.contents = [number, Separator(u' ')] + caption.contents
    return float

  def postlabels(self, float, caption):
    "Search for labels and move them to the top"
    labels = caption.searchremove(Label)
    if len(labels) == 0 and float.partkey.tocentry:
      labels = [Label().create(' ', float.partkey.partkey.replace(' ', '-'))]
    float.contents = labels + float.contents

class PostWrap(PostFloat):
  "For a wrap: exactly like a float"

  processedclass = Wrap

Postprocessor.stages += [PostFloat, PostWrap]

elyxer-1.2.5/forks/jras-elyxer/src/elyxer/gen/factory.py0000644000175000017500000001145012117061342022615 0ustar  chennochenno#! /usr/bin/env python
# -*- coding: utf-8 -*-

#   eLyXer -- convert LyX source files to HTML output.
#
#   Copyright (C) 2009 Alex Fernández
#
#   This program is free software: 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 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
#   GNU General Public License for more details.
#
#   You should have received a copy of the GNU General Public License
#   along with this program.  If not, see .

# --end--
# Alex 20090509
# eLyXer factory to create and parse containers

from elyxer.util.trace import Trace
from elyxer.conf.config import *
from elyxer.gen.styles import *
from elyxer.ref.link import *
from elyxer.ref.label import *
from elyxer.bib.biblio import *
from elyxer.ref.index import *
from elyxer.maths.formula import *
from elyxer.maths.command import *
from elyxer.maths.hybrid import *
from elyxer.gen.table import *
from elyxer.gen.image import *
from elyxer.gen.layout import *
from elyxer.gen.list import *
from elyxer.gen.inset import *
from elyxer.gen.include import *
from elyxer.gen.notes import *
from elyxer.gen.float import *
from elyxer.gen.header import *
from elyxer.gen.change import *
from elyxer.maths.array import *
from elyxer.bib.tex import *
from elyxer.bib.pub import *
from elyxer.xtra.newfangle import *
from elyxer.maths.macro import *
from elyxer.maths.extracommand import *
from elyxer.tex.texcode import *
from elyxer.maths.misc import *


class ContainerFactory(object):
  "Creates containers depending on the first line"

  def __init__(self):
    "Read table that convert start lines to containers"
    types = dict()
    for start, typename in ContainerConfig.starts.iteritems():
      types[start] = globals()[typename]
    self.tree = ParseTree(types)

  def createcontainer(self, reader):
    "Parse a single container."
    #Trace.debug('processing "' + reader.currentline().strip() + '"')
    if reader.currentline() == '':
      reader.nextline()
      return None
    container = Cloner.create(self.tree.find(reader))
    container.start = reader.currentline().strip()
    self.parse(container, reader)
    return container

  def parse(self, container, reader):
    "Parse a container"
    parser = container.parser
    parser.parent = container
    parser.ending = self.getending(container)
    parser.factory = self
    container.header = parser.parseheader(reader)
    container.begin = parser.begin
    self.parsecontents(container, reader)
    container.parameters = parser.parameters
    container.parser = None

  def parsecontents(self, container, reader):
    "Parse the contents of a container."
    contents = container.parser.parse(reader)
    if isinstance(contents, basestring):
      # read a string, set as parsed
      container.parsed = contents
      container.contents = []
    else:
      container.contents = contents

  def getending(self, container):
    "Get the ending for a container"
    split = container.start.split()
    if len(split) == 0:
      return None
    start = split[0]
    if start in ContainerConfig.startendings:
      return ContainerConfig.startendings[start]
    classname = container.__class__.__name__
    if classname in ContainerConfig.endings:
      return ContainerConfig.endings[classname]
    if hasattr(container, 'ending'):
      Trace.error('Pending ending in ' + container.__class__.__name__)
      return container.ending
    return None

class ParseTree(object):
  "A parsing tree"

  default = '~~default~~'

  def __init__(self, types):
    "Create the parse tree"
    self.root = dict()
    for start, type in types.iteritems():
      self.addstart(type, start)

  def addstart(self, type, start):
    "Add a start piece to the tree"
    tree = self.root
    for piece in start.split():
      if not piece in tree:
        tree[piece] = dict()
      tree = tree[piece]
    if ParseTree.default in tree:
      Trace.error('Start ' + start + ' duplicated')
    tree[ParseTree.default] = type

  def find(self, reader):
    "Find the current sentence in the tree"
    branches = self.matchline(reader.currentline())
    while not ParseTree.default in branches[-1]:
      branches.pop()
    last = branches[-1]
    return last[ParseTree.default]

  def matchline(self, line):
    "Match a given line against the tree, as deep as possible."
    branches = [self.root]
    for piece in line.split(' '):
      current = branches[-1]
      piece = piece.rstrip('>')
      if piece in current:
        branches.append(current[piece])
      else:
        return branches
    return branches

elyxer-1.2.5/forks/jras-elyxer/src/elyxer/gen/splitpart.py0000644000175000017500000002436512117061342023201 0ustar  chennochenno#! /usr/bin/env python
# -*- coding: utf-8 -*-

#   eLyXer -- convert LyX source files to HTML output.
#
#   Copyright (C) 2009 Alex Fernández
#
#   This program is free software: 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 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
#   GNU General Public License for more details.
#
#   You should have received a copy of the GNU General Public License
#   along with this program.  If not, see .

# --end--
# Alex 20100418
# eLyXer split part processing
# http://www.nongnu.org/elyxer/


from elyxer.util.translate import *
from elyxer.gen.basket import *
from elyxer.gen.integral import *


class SplitPartLink(IntegralProcessor):
  "A link processor for multi-page output."

  processedtype = Link

  def processeach(self, link):
    "Process each link and add the current page."
    link.page = self.page

class NavigationLink(Container):
  "A link in the navigation header."

  def __init__(self, name):
    "Create the link for a given name (prev, next...)."
    self.name = name
    self.link = Link().complete(u' ', name, type=name)
    self.output = TaggedOutput().settag('span class="' + name + '"')
    self.contents = [self.link]

  def complete(self, container, after = False):
    "Complete the navigation link with destination container."
    "The 'after' parameter decides if the link goes after the part title."
    if not container.partkey:
      Trace.error('No part key for link name ' + unicode(container))
      return
    self.link.contents = [Constant(Translator.translate(self.name))]
    partname = self.getpartname(container)
    separator = Constant(u' ')
    if after:
      self.contents = partname + [separator, self.link]
    else:
      self.contents = [self.link, separator] + partname

  def getpartname(self, container):
    "Get the part name for a container, title optional."
    partname = [Constant(container.partkey.tocentry)]
    if not container.partkey.titlecontents:
      return partname
    if Options.notoclabels:
      return container.partkey.titlecontents
    return partname + [Constant(': ')] + container.partkey.titlecontents

  def setdestination(self, destination):
    "Set the destination for this link."
    self.link.destination = destination

  def setmutualdestination(self, destination):
    "Set the destination for this link, and vice versa."
    self.link.setmutualdestination(destination.link)

class UpAnchor(Link):
  "An anchor to the top of the page for the up links."

  def create(self, container):
    "Create the up anchor based on the first container."
    if not container.partkey:
      Trace.error('No part key for ' + unicode(container))
      return None
    self.createliteral(container.partkey.tocentry)
    self.partkey.titlecontents = container.partkey.titlecontents
    return self

  def createmain(self):
    "Create the up anchor for the main page."
    return self.createliteral(Translator.translate('main-page'))

  def createliteral(self, literal):
    "Create the up anchor based on a literal string."
    self.complete('', '')
    self.output = EmptyOutput()
    self.partkey = PartKey().createanchor(literal)
    return self

class SplitPartNavigation(object):
  "Used to create the navigation links for a new split page."

  def __init__(self):
    self.upanchors = []
    self.lastcontainer = None
    self.nextlink = None
    self.lastnavigation = None

  def writefirstheader(self, basket):
    "Write the first header to the basket."
    anchor = self.createmainanchor()
    basket.write(anchor)
    basket.write(self.createnavigation(anchor))

  def writeheader(self, basket, container):
    "Write the header to the basket."
    basket.write(LyXHeader())
    basket.write(self.currentupanchor(container))
    basket.write(self.createnavigation(container))

  def writefooter(self, basket):
    "Write the footer to the basket."
    if self.lastnavigation:
      basket.write(self.lastnavigation)
    basket.write(LyXFooter())

  def createnavigation(self, container):
    "Create the navigation bar with all links."
    prevlink = NavigationLink('prev')
    uplink = NavigationLink('up')
    if self.nextlink:
      prevlink.complete(self.lastcontainer)
      self.nextlink.complete(container, after=True)
      prevlink.setmutualdestination(self.nextlink)
      uplink.complete(self.getupdestination(container))
      uplink.setdestination(self.getupdestination(container))
    self.nextlink = NavigationLink('next')
    contents = [prevlink, Constant('\n'), uplink, Constant('\n'), self.nextlink]
    header = TaggedText().complete(contents, 'div class="splitheader"', True)
    self.lastcontainer = container
    self.lastnavigation = header
    return header
  
  def currentupanchor(self, container):
    "Update the internal list of up anchors, and return the current one."
    level = self.getlevel(container)
    while len(self.upanchors) > level:
      del self.upanchors[-1]
    while len(self.upanchors) < level:
      self.upanchors.append(self.upanchors[-1])
    upanchor = UpAnchor().create(container)
    self.upanchors.append(upanchor)
    return upanchor

  def createmainanchor(self):
    "Create the up anchor to the main page."
    mainanchor = UpAnchor().createmain()
    self.upanchors.append(mainanchor)
    return mainanchor

  def getupdestination(self, container):
    "Get the name of the up page."
    level = self.getlevel(container)
    if len(self.upanchors) < level:
      uppage = self.upanchors[-1]
    else:
      uppage = self.upanchors[level - 1]
    return uppage

  def getlevel(self, container):
    "Get the level of the container."
    if not container.partkey:
      return 1
    else:
      return container.partkey.level + 1

class SplitFileBasket(MemoryBasket):
  "A memory basket which contains a part split into a file, possibly with a TOC."

  def __init__(self):
    MemoryBasket.__init__(self)
    self.entrycount = 0
    self.root = None
    self.converter = TOCConverter()

  def write(self, container):
    "Keep track of numbered layouts."
    MemoryBasket.write(self, container)
    if not container.partkey:
      return
    if container.partkey.header:
      return
    entry = self.converter.convert(container)
    if not entry:
      return
    self.entrycount += 1
    self.root = entry

  def addtoc(self):
    "Add the table of contents if necessary."
    if self.entrycount != 1:
      return
    if self.root.branches == []:
      return
    text = Translator.translate('toc-for') + self.root.partkey.tocentry
    toc = TableOfContents().create(text)
    self.addbranches(self.root, toc)
    toc.add(self.converter.convertindented(LyXFooter()))
    self.write(toc)

  def addbranches(self, entry, toc):
    "Add an entry and all of its branches to the table of contents."
    for branch in entry.branches:
      toc.add(self.converter.indent(branch))
      self.addbranches(branch, toc)
  
class SplitPartBasket(Basket):
  "A basket used to split the output in different files."

  baskets = []

  def setwriter(self, writer):
    if not hasattr(writer, 'filename') or not writer.filename:
      Trace.error('Cannot use standard output for split output; ' +
          'please supply an output filename.')
      exit()
    self.writer = writer
    self.filename = writer.filename
    self.converter = TOCConverter()
    self.basket = MemoryBasket()
    self.basket.page = writer.filename
    return self

  def write(self, container):
    "Write a container, possibly splitting the file."
    self.basket.write(container)

  def splitbaskets(self):
    "Process the whole basket and create all baskets for split part pages."
    self.basket.process()
    basket = self.firstbasket()
    navigation = SplitPartNavigation()
    for container in self.basket.contents:
      if self.mustsplit(container):
        filename = self.getfilename(container)
        Trace.debug('New page ' + filename)
        basket.addtoc()
        navigation.writefooter(basket)
        basket = self.addbasket(filename)
        navigation.writeheader(basket, container)
      basket.write(container)
      if self.afterheader(container):
        navigation.writefirstheader(basket)
        self.mainanchor = navigation.upanchors[0]
    for basket in self.baskets:
      basket.process()

  def finish(self):
    "Process the whole basket, split into page baskets and flush all of them."
    self.splitbaskets()
    for basket in self.baskets:
      basket.flush()

  def afterheader(self, container):
    "Find out if this is the header on the file."
    return isinstance(container, LyXHeader)

  def firstbasket(self):
    "Create the first basket."
    return self.addbasket(self.filename, self.writer)

  def addbasket(self, filename, writer = None):
    "Add a new basket."
    if not writer:
      writer = LineWriter(filename)
    basket = SplitFileBasket()
    basket.setwriter(writer)
    self.baskets.append(basket)
    # set the page name everywhere
    basket.page = filename
    splitpartlink = SplitPartLink()
    splitpartlink.page = os.path.basename(basket.page)
    basket.processors = [splitpartlink]
    return basket

  def mustsplit(self, container):
    "Find out if the oputput file has to be split at this entry."
    if not container.partkey:
      return False
    if not container.partkey.filename:
      return False
    return True

  def getfilename(self, container):
    "Get the new file name for a given container."
    partname = container.partkey.filename
    basename = self.filename
    if Options.tocfor:
      basename = Options.tocfor
    base, extension = os.path.splitext(basename)
    return base + '-' + partname + extension

class SplitTOCBasket(SplitPartBasket):
  "A basket which contains the TOC for a split part document."

  def finish(self):
    "Process the whole basket, split into page baskets and flush all of them."
    self.splitbaskets()
    tocbasket = TOCBasket().setwriter(self.writer)
    self.mainanchor.partkey = PartKey().createmain()
    tocbasket.write(self.mainanchor)
    for container in self.basket.contents:
      tocbasket.write(container)
    tocbasket.finish()

elyxer-1.2.5/forks/jras-elyxer/src/elyxer/gen/notes.py0000644000175000017500000001151612117061342022301 0ustar  chennochenno#! /usr/bin/env python
# -*- coding: utf-8 -*-

#   eLyXer -- convert LyX source files to HTML output.
#
#   Copyright (C) 2009 Alex Fernández
#
#   This program is free software: 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 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
#   GNU General Public License for more details.
#
#   You should have received a copy of the GNU General Public License
#   along with this program.  If not, see .

# --end--
# Alex 20101119
# LyX notes: notes, footnotes and margin notes.

from elyxer.util.trace import Trace
from elyxer.util.numbering import *
from elyxer.parse.parser import *
from elyxer.out.output import *
from elyxer.gen.container import *
from elyxer.ref.link import *


class SideNote(Container):
  "A side note that appears at the right."

  def __init__(self):
    self.parser = InsetParser()
    self.output = TaggedOutput()

  def process(self):
    "Enclose everything in a marginal span."
    self.output.settag('span class="Marginal"', True)

class FootnoteMarker(Container):
  "A marker for a footnote."

  def __init__(self):
    "Set the correct span class."
    self.contents = []
    span = 'span class="SupFootMarker"'
    if Options.alignfoot:
      span = 'span class="AlignFootMarker"'
    self.output = TaggedOutput().settag(span, False)
    mode = 'A'
    if Options.numberfoot:
      mode = '1'
    if Options.symbolfoot:
      mode = '*'
    NumberGenerator.generator.getcounter('Footnote').setmode(mode)

  def create(self):
    "Create the marker for a footnote."
    self.order = NumberGenerator.generator.generate('Footnote')
    if Options.endfoot:
      self.link = Link().complete(self.getmark(), 'footmarker-' + self.order)
    self.createcontents()
    return self

  def createanchor(self, marker):
    "Create the anchor for a footnote. Adds a link for end footnotes."
    self.order = marker.order
    if Options.endfoot:
      self.link = Link().complete(self.getmark(), 'footnote-' + self.order)
      self.link.setmutualdestination(marker.link)
    self.createcontents()
    return self

  def createlabel(self, marker):
    "Create the label for a footnote. Used in hoverfoot and marginfoot."
    self.order = marker.order
    self.contents = [Constant(self.getmark())]
    space = Constant(u' ')
    self.contents = [space] + self.contents + [space]
    return self

  def createcontents(self):
    "Create the contents of the marker."
    if Options.endfoot:
      self.contents = [self.link]
    else:
      self.contents = [Constant(self.getmark())]
    space = Constant(u' ')
    self.contents = [space] + self.contents + [space]

  def getmark(self):
    "Get the mark to be displayed in the marker based on the order."
    if Options.symbolfoot:
      return self.order
    else:
      return '[' + self.order + ']'

class Footnote(Container):
  "A footnote to the main text."

  def __init__(self):
    self.parser = InsetParser()
    self.output = TaggedOutput().settag('span class="FootOuter"', False)

  def process(self):
    "Add a counter for the footnote."
    "Can be numeric or a letter depending on runtime options."
    marker = FootnoteMarker().create()
    anchor = FootnoteMarker().createanchor(marker)
    label = FootnoteMarker().createlabel(marker)
    notecontents = list(self.contents)
    self.contents = [marker]
    if Options.hoverfoot:
      self.contents.append(self.createnote([label] + notecontents, 'span class="HoverFoot"'))
    if Options.marginfoot:
      self.contents.append(self.createnote([label] + notecontents, 'span class="MarginFoot"'))
    if Options.endfoot:
      EndFootnotes.footnotes.append(self.createnote([anchor] + notecontents, 'div class="EndFoot"'))

  def createnote(self, contents, tag):
    "Create a note with the given contents and HTML tag."
    return TaggedText().complete(contents, tag, False)

class EndFootnotes(Container):
  "The collection of footnotes at the document end."

  footnotes = []

  def __init__(self):
    "Generate all footnotes and a proper header for them all."
    self.output = ContentsOutput()
    header = TaggedText().constant(Translator.translate('footnotes'), 'h1 class="index"')
    self.contents = [header] + self.footnotes

class Note(Container):
  "A LyX note of several types"

  def __init__(self):
    self.parser = InsetParser()
    self.output = EmptyOutput()

  def process(self):
    "Hide note and comment, dim greyed out"
    self.type = self.header[2]
    if TagConfig.notes[self.type] == '':
      return
    self.output = TaggedOutput().settag(TagConfig.notes[self.type], True)

elyxer-1.2.5/forks/jras-elyxer/src/elyxer/gen/__init__.py0000644000175000017500000000000012117061342022672 0ustar  chennochennoelyxer-1.2.5/forks/jras-elyxer/src/elyxer/__init__.py0000644000175000017500000000000012117061342022121 0ustar  chennochennoelyxer-1.2.5/forks/jras-elyxer/src/gpl-license0000644000175000017500000000144612117061342020644 0ustar  chennochenno#! /usr/bin/env python
# -*- coding: utf-8 -*-

#   eLyXer -- convert LyX source files to HTML output.
#
#   Copyright (C) 2009-2010 Alex Fernández
#
#   This program is free software: 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 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
#   GNU General Public License for more details.
#
#   You should have received a copy of the GNU General Public License
#   along with this program.  If not, see .

elyxer-1.2.5/forks/jras-elyxer/src/math2html.py0000755000175000017500000000325612117061342020775 0ustar  chennochenno#! /usr/bin/env python
# -*- coding: utf-8 -*-

#   eLyXer -- convert LyX source files to HTML output.
#
#   Copyright (C) 2009 Alex Fernández
#
#   This program is free software: 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 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
#   GNU General Public License for more details.
#
#   You should have received a copy of the GNU General Public License
#   along with this program.  If not, see .

# --end--
# Alex 20101110
# eLyXer standalone formula conversion to HTML.

from elyxer.util.trace import Trace
from elyxer.util.options import *
from elyxer.maths.formula import *
from elyxer.maths.bits import *
from elyxer.maths.command import *
from elyxer.maths.hybrid import *
from elyxer.maths.array import *
from elyxer.maths.macro import *
from elyxer.proc.formulaproc import *


def math2html(formula):
  "Convert some TeX math to HTML."
  factory = FormulaFactory()
  whole = factory.parseformula(formula)
  FormulaProcessor().process(whole)
  whole.process()
  return ''.join(whole.gethtml())

def main():
  "Main function, called if invoked from elyxer.the command line"
  args = sys.argv
  Options().parseoptions(args)
  if len(args) != 1:
    Trace.error('Usage: math2html.py escaped_string')
    exit()
  result = math2html(args[0])
  Trace.message(result)

if __name__ == '__main__':
  main()

elyxer-1.2.5/forks/jras-elyxer/src/licensify.py0000755000175000017500000000337012117061342021057 0ustar  chennochenno#! /usr/bin/env python
# -*- coding: utf-8 -*-

#   eLyXer -- convert LyX source files to HTML output.
#
#   Copyright (C) 2009 Alex Fernández
#
#   This program is free software: 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 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
#   GNU General Public License for more details.
#
#   You should have received a copy of the GNU General Public License
#   along with this program.  If not, see .

# --end--
# Alex 20090314
# Modifies the license of a Python source file

import sys
from elyxer.io.fileline import *
from elyxer.io.bulk import *
from elyxer.util.trace import Trace


mark = '--end--'

def process(reader, writer, license):
  "Conflate all Python files used in filein to fileout"
  for line in license:
    writer.writestring(line)
  while not mark in reader.currentline():
    reader.nextline()
  while not reader.finished():
    line = reader.currentline()
    writer.writeline(line)
    reader.nextline()
  reader.close()

def processall(args):
  "Process all arguments"
  del args[0]
  if len(args) == 0:
    Trace.error('Usage: licensify.py licensefile [file...]')
    return
  licensefile = BulkFile(args[0])
  license = licensefile.readall()
  del args[0]
  while len(args) > 0:
    pythonfile = BulkFile(args[0])
    reader, writer = pythonfile.getfiles()
    del args[0]
    process(reader, writer, license)
    pythonfile.swaptemp()

processall(sys.argv)

elyxer-1.2.5/forks/jras-elyxer/src/css/0000755000175000017500000000000012117061342017302 5ustar  chennochennoelyxer-1.2.5/forks/jras-elyxer/src/css/print.css0000644000175000017500000000151312117061342021150 0ustar  chennochenno/*
* CSS section for print.
*/
@media print {
body {
	font: 90% serif;
	background: #ffffff;
	color: black;
	margin: 0;
	padding: 0;
}
#globalWrapper {
	width: 100%;
	margin: 0px;
	padding: 0px;
	background: #ffffff;
	line-height: 1.5em;
}
span.FootOuter .Foot {
	display: block;
	position: relative;
	float: right;
	clear: right;
	margin: 0.2ex;
	border: thin solid #c0c0c0;
	background: #ffffff;
	width: 30%;
	padding: 0.5ex;
	font-size: small;
	font-weight: normal;
	line-height: 1.5em;
	text-align: left;
}
span.FootOuter .HoverFoot {
	display: block;
	position: relative;
	float: right;
	clear: right;
	margin: 0.2ex;
	border: thin solid #c0c0c0;
	background: #ffffff;
	width: 30%;
	padding: 0.5ex;
	font-size: small;
	font-weight: normal;
	line-height: 1.5em;
	text-align: left;
}
a:visited {
	color: #0030c0;
}
/* end of print CSS */
}
elyxer-1.2.5/forks/jras-elyxer/src/css/master.css0000644000175000017500000001315512117061342021314 0ustar  chennochenno/*
*   eLyXer -- convert LyX source files to HTML output.
*
*   Copyright (C) 2009-2010 Alex Fernández
*
*   This program is free software: 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 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
*   GNU General Public License for more details.
*
*   You should have received a copy of the GNU General Public License
*   along with this program.  If not, see http://www.gnu.org/licenses/.
*/
/* --end--
* Global CSS file for LyX documents.
*/

body {
	font: 90% sans-serif;
	background: #f9f9f9;
	color: black;
	margin: 0;
	padding: 0;
}

#globalWrapper {
	margin: 10px 5%;
	padding: 20px;
	background: #ffffff;
	line-height: 1.5em;
}

/* Basic styles */
a {
	text-decoration: none;
	background: none;
}
a:link {
	color: #0030c0;
}
a:visited {
	color: #603090;
}
a:active {
	color: #ffa000;
}
a:hover {
	text-decoration: underline;
}
h1 {
	margin-top: 1em;
	line-height: 1.5em;
}
h1.Part {
	text-align: center;
}
h1.Part- {
	text-align: center;
}
sup {
	font-size: 0.75em;
	line-height: 0.5em;
	vertical-align: text-top;
}
sub {
	font-size: 0.75em;
	line-height: 0.5em;
	vertical-align: text-bottom;
}
div.Standard {
	margin: 1em 0;
}
div.Unindented {
	margin: 0;
}
div.Indented {
	text-indent: 30pt;
	margin: 0;
}
div.Indented * {
	text-indent: 0pt;
}
p.dir {
	float: right;
}
p.printindex {
	font-size: 0.90em;
}
a.printindex {
	color: black;
}
table {
	display: inline-table;
	text-align: center;
	border-collapse: collapse;
	margin-top: 1em;
	margin-bottom: 1em;
}
tr.header {
	border-bottom: thin solid #c0c0c0;
	background: #ffffff;
	font-weight: bold;
}
td {
	padding: 1ex;
	border: thin solid #f0f0f0;
}
td div.Standard {
	margin: 0ex;
	padding: 0ex;
}
div.caption div.Standard, div.table div.Standard {
	margin: 0ex;
	padding: 0ex;
}
td.numeric {
	text-align: right;
}
td.empty {
	text-align: center;
}
div.right {
	text-align: right;
}
div.center {
	text-align: center;
	margin-left: auto;
	margin-right: auto;
}
p.biblio {
}
div.Paragraph, div.Paragraph- {
	font-weight: bold;
	font-size: 103%;
}
span.versalitas, span.noun {
	font-variant: small-caps;
}
span.sans {
	font-family: sans-serif;
}
span.code {
	font-family: monospace;
}
div.Plain {
	display: inline;
	width: auto;
}
h2 {
	line-height: 1.4em;
}
span.Description-entry {
	font-weight: bold;
}
span.List-entry {
	display: inline-block;
	width: 25%;
	vertical-align: text-top;
}
span.List-contents {
	display: inline-block;
	width: 75%;
	vertical-align: text-top;
}
div.Space {
	display: none;
}
span.appendix {
	display: none;
}
h1.biblio {
}
span.greyedout {
	color: #808080;
}
div.Description, div.List, li {
	margin: 1em 0;
}
li.nested {
	list-style-type: none;
}
span.Info {
	background: #f0f0f0;
	border: thin solid #c0c0c0;
}
pre {
	padding: 0em;
	margin: 0em;
	width: auto;
	font-family: monospace;
	line-height: 1.5em;
}
pre.LyX-Code {
	margin: 0.5em 3em;
}
a.Label {
	text-decoration: none;
	color: #000000;
}
span.phantom {
	color: #ffffff;
}
a.biblioentry {
	color: black;
}
span.menuitem {
	font-size: 105%;
}
span.normal {
	font-style: normal;
}
div.PlainVisible {
	width: auto;
}
div.indexgroup {
	margin-left: 2em;
}
span.strong {
	font-weight: bold;
}

/* Figures and Tables */
img.embedded {
	width: 100%;
	_width: auto;
}
div.float {
	margin-top: 1ex;
	margin-bottom: 1ex;
	text-align: center;
}
span.float {
	margin-top: 1ex;
	margin-bottom: 1ex;
	text-align: center;
}
div.figure {
	display: inline-block;
	text-align: left;
	padding: 1ex;
	margin-left: auto;
	margin-right: auto;
	border: thin solid #c0c0c0;
}
div.table {
	display: inline-block;
	text-align: left;
	padding: 1ex;
	margin-left: auto;
	margin-right: auto;
	border: thin solid #c0c0c0;
}
div.algorithm {
	display: inline-block;
	text-align: left;
	padding: 1ex;
	margin-left: auto;
	margin-right: auto;
	border: thin solid #c0c0c0;
}
div.caption {
	text-align: center;
	font-family: sans-serif;
	margin-left: auto;
	margin-right: auto;
	padding: 0.5ex;
}
img.figure {
	width: 100%;
	_width: auto;
}
div.multifigure {
	padding: 1ex;
	width: 100%;
}
div.multitable {
	display: inline-block;
	padding: 1ex;
	margin-left: auto;
	margin-right: auto;
	border: thin solid #c0c0c0;
}
div.multialgorithm {
	display: inline-block;
	padding: 1ex;
	margin-left: auto;
	margin-right: auto;
	border: thin solid #c0c0c0;
}
div.wrap-l, div.wrap-o, div.wrap-i {
	margin: 2ex;
	float: left;
}
div.wrap-r {
	margin: 2ex;
	float: right;
}
div.listing {
	display: inline-block;
	text-align: left;
	margin-left: auto;
	margin-right: auto;
	padding: 0.5ex;
	border: thin solid #c0c0c0;
}
span.number-left {
	float: left;
	background: #f0f0f0;
	width: 3em;
	text-align: right;
	margin-right: 1em;
}
span.number-right {
	float: right;
	background: #f0f0f0;
	width: 3em;
	text-align: right;
	margin-left: 1em;
}

/* Header */
h1.title {
	text-align: center;
}
h2.author {
	text-align: center;
}
h2.Date {
	text-align: center;
}
div.abstract {
	margin: 1em 3em;
	text-align: left;
	font-size: 0.95em;
}
p.abstract-message {
	text-align: center;
	font-weight: bold;
}
div.tocheader {
	margin: 1em 0;
	font-size: large;
}
a.toc {
	color: black;
}
div.tocindent {
	padding: 0 0 0 2em;
}
div.toc {
	margin: 0.5em 0;
	font-size: 0.95em;
}
div.fulltoc {
	padding: 1em;
}
div.warning {
	font-size: 120%;
	color:#cc0000;
}
div.Institute {
	text-align: center;
}
@import "extras.css";
@import "math.css";
@import "obsolete.css";
@import "print.css";
elyxer-1.2.5/forks/jras-elyxer/src/css/math.css0000644000175000017500000000524612117061342020754 0ustar  chennochenno/* --end--
* CSS file for LaTeX formulas.
*/

/* Formulas */
.formula {
	text-align: center;
	font-family: "DejaVu Serif", serif;
	margin: 1.2em 0;
}
span.formula {
	white-space: nowrap;
}
div.formula {
	padding: 0.5ex;
	margin-left: auto;
	margin-right: auto;
}

/* Basic features */
a.eqnumber {
	display: inline-block;
	float: right;
	clear: right;
	font-weight: bold;
}
span.unknown {
	color: #800000;
}
span.ignored, span.arraydef {
	display: none;
}
.formula i {
	letter-spacing: 0.1ex;
}

/* Alignment */
.align-left, .align-l {
	text-align: left;
}
.align-right, .align-r {
	text-align: right;
}
.align-center, .align-c {
	text-align: center;
}

/* Structures */
span.overline, span.bar {
	text-decoration: overline;
}
.fraction, .fullfraction {
	display: inline-block;
	vertical-align: middle;
	text-align: center;
}
.fraction .fraction {
	font-size: 80%;
	line-height: 100%;
}
span.numerator {
	display: block;
}
span.denominator {
	display: block;
	padding: 0ex;
	border-top: thin solid;
}
sup.numerator, sup.unit {
	font-size: 70%;
	vertical-align: 80%;
}
sub.denominator, sub.unit {
	font-size: 70%;
	vertical-align: -20%;
}
span.sqrt {
	display: inline-block;
	vertical-align: middle;
	padding: 0.1ex;
}
sup.root {
	font-size: 70%;
	position: relative;
	left: 1.4ex;
}
span.radical {
	display: inline-block;
	padding: 0ex;
	font-size: 150%;
	vertical-align: top;
}
span.root {
	display: inline-block;
	border-top: thin solid;
	padding: 0ex;
	vertical-align: middle;
}
span.symbol {
	font-size: 125%;
}
span.bigsymbol {
	font-size: 150%;
}
span.largesymbol {
	font-size: 175%;
}
span.hugesymbol {
	font-size: 200%;
}
span.scripts {
	display: inline-table;
	vertical-align: middle;
}
.script {
	display: table-row;
	text-align: left;
	line-height: 150%;
}
span.limits {
	display: inline-table;
	vertical-align: middle;
}
.limit {
	display: table-row;
	line-height: 95%;
}
sup.limit, sub.limit {
	line-height: 150%;
}
span.symbolover {
	display: inline-block;
	text-align: center;
	position: relative;
	float: right;
	right: 100%;
	bottom: 0.5em;
	width: 0px;
}
span.withsymbol {
	display: inline-block;
}
span.symbolunder {
	display: inline-block;
	text-align: center;
	position: relative;
	float: right;
	right: 80%;
	top: 0.3em;
	width: 0px;
}

/* Environments */
span.array, span.bracketcases, span.binomial, span.environment {
	display: inline-table;
	text-align: center;
	border-collapse: collapse;
	margin: 0em;
	vertical-align: middle;
}
span.arrayrow, span.binomrow {
	display: table-row;
	padding: 0ex;
	border: 0ex;
}
span.arraycell, span.bracket, span.case, span.binomcell, span.environmentcell {
	display: table-cell;
	padding: 0ex 0.2ex;
	line-height: 99%;
	border: 0ex;
}
@import "math-extras.css";

elyxer-1.2.5/forks/jras-elyxer/src/css/math-extras.css0000644000175000017500000000263312117061342022255 0ustar  chennochenno/*
* CSS file for LaTeX formulas, extra stuff:
* binomials, vertical braces, stackrel, fonts and colors.
*/

/* Inline binomials */
span.binom {
	display: inline-block;
	vertical-align: middle;
	text-align: center;
	font-size: 80%;
}
span.binomstack {
	display: block;
	padding: 0em;
}

/* Over- and underbraces */
span.overbrace {
	border-top: 2pt solid;
}
span.underbrace {
	border-bottom: 2pt solid;
}

/* Stackrel */
span.stackrel {
	display: inline-block;
	text-align: center;
}
span.upstackrel {
	display: block;
	padding: 0em;
	font-size: 80%;
	line-height: 64%;
	position: relative;
	top: 0.15em;

}
span.downstackrel {
	display: block;
	vertical-align: bottom;
	padding: 0em;
}

/* Fonts */
span.mathsf, span.textsf {
	font-style: normal;
	font-family: sans-serif;
}
span.mathrm, span.textrm {
	font-style: normal;
	font-family: serif;
}
span.text, span.textnormal {
	font-style: normal;
}
span.textipa {
	color: #008080;
}
span.fraktur {
	font-family: "Lucida Blackletter", eufm10, blackletter;
}
span.blackboard {
	font-family: Blackboard, msbm10, serif;
}
span.scriptfont {
	font-family: "Monotype Corsiva", "Apple Chancery", "URW Chancery L", cursive;
	font-style: italic;
}

/* Colors */
span.colorbox {
	display: inline-block;
	padding: 5px;
}
span.fbox {
	display: inline-block;
	border: thin solid black;
	padding: 2px;
}
span.boxed, span.framebox {
	display: inline-block;
	border: thin solid black;
	padding: 5px;
}
elyxer-1.2.5/forks/jras-elyxer/src/css/freebsd-license.css0000644000175000017500000000111212117061342023041 0ustar  chennochenno/*
*   math2html: convert LaTeX equations to HTML output.
*
*   Copyright (C) 2009,2010 Alex Fernández
*
*   Released under the terms of the `2-Clause BSD license'_, in short:
*   Copying and distribution of this file, with or without modification,
*   are permitted in any medium without royalty provided the copyright
*   notice and this notice are preserved.
*   This file is offered as-is, without any warranty.
*
* .. _2-Clause BSD license: http://www.spdx.org/licenses/BSD-2-Clause
*
*   Based on eLyXer: convert LyX source files to HTML output.
*   http://elyxer.nongnu.org/
*/
elyxer-1.2.5/forks/jras-elyxer/src/css/extras.css0000644000175000017500000000626512117061342021333 0ustar  chennochenno/*
* Extras: colors, footnotes, boxes, spaces...
*/

/* Raw colors */
span.red {
	color: #c00000;
}
span.blue {
	color: #0000c0;
}
span.green {
	color: #00c000;
}
span.magenta {
	color: #c000c0;
}
span.cyan {
	color: #00c0c0;
}
span.yellow {
	color: #c0c000;
}
span.white {
	color: #ffffff;
}

/* Footnotes */
span.SupFootMarker {
	color: #0030c0;
	font-size: 0.75em;
	line-height: 0.5em;
	vertical-align: text-top;
}
span.AlignFootMarker {
	color: #0030c0;
}
div.EndFoot {
	margin: 0.2ex;
	background: #ffffff;
	padding: 0.5ex;
	font-size: small;
	font-weight: normal;
	line-height: 1.5em;
	text-align: left;
}
span.MarginFoot {
	float: right;
	clear: right;
	margin: 0.2ex;
	border: thin solid #c0c0c0;
	background: #ffffff;
	width: 30%;
	padding: 0.5ex;
	font-size: small;
	font-weight: normal;
	line-height: 1.5em;
	text-align: left;
}
span.HoverFoot {
	margin: 0.2ex;
	border: thin solid #c0c0c0;
	background: #ffffff;
	padding: 0.5ex;
	font-size: small;
	font-weight: normal;
	line-height: 1.5em;
	text-align: left;
}
span.FootOuter .HoverFoot {
	display: none;
	position: absolute;
}
span.FootOuter:hover .HoverFoot {
	display: inline;
	float: none;
}
span.Marginal {
	float: right;
	clear: right;
	margin: 0.2ex;
	border: thin solid #c0c0c0;
	background: #ffffff;
	width: 30%;
	padding: 0.5ex;
	font-size: small;
	font-weight: normal;
	line-height: 1.5em;
	text-align: left;
}
span.Note {
	display: none;
}

/* Boxes */
div.framed {
	outline-style: solid;
}
div.frameless {
}
div.Frameless {
}
div.Boxed {
	outline-width: thin;
	outline-style: solid;
}
div.Framed {
	outline-width: thin;
	outline-style: solid;
	line-height: 200%;
}
div.Doublebox {
	outline-style: double;
}
div.Shadowbox {
	outline-style: outset;
}
div.Shaded {
	outline-style: inset;
}
div.ovalbox {
	outline-style: groove;
}
div.Ovalbox {
	outline-style: ridge;
}
hr.line {
	display: inline-block;
}

/* Spaces */
span.hspace {
	display: inline-block;
}
span.vspace {
	display: inline-block;
	vertical-align: text-top;
}
span.hfill {
	display: inline-block;
	margin-left: auto;
	margin-right: auto;
	min-width: 20mm;
	background: #fff0f0;
}
div.defskip {
	display: block;
	height: 1em;
}
div.smallskip {
	display: block;
	height: 0.5em;
}
div.medskip {
	display: block;
	height: 1em;
}
div.bigskip {
	display: block;
	height: 2em;
}
div.vfill {
	display: block;
	height: 30em;
}

/* Sizes */
span.scriptstyle {
	font-size: 0.75em;
}
span.scriptscriptstyle {
	font-size: 0.60em;
}

/* Chunks */
div.chunk {
	width: auto;
}
span.chunkleft span.chunkright {
	font-style: normal;
}
span.chunkdecl {
	font-style: italic;
	padding: 0em 2em;
}
span.chunkref {
	font-style: italic;
}

/* Split Part Navigation */
div.splitheader {
	margin: 0em;
	padding: 0.1em;
	text-align: center;
	background: #f9f9f9;
	overflow: auto;
}
span.next {
	float: right;
	width: 30%;
	text-align: right;
}
span.up {
	display: inline-block;
	width: 30%;
	text-align: center;
}
span.prev {
	float: left;
	width: 30%;
	text-align: left;
}
hr.footer {
	margin-top: 2em;
}
div.footer {
	font-size: 0.90em;
	margin: 1em 0;
}

/* Change Tracking */
span.inserted {
	color: #0000ff;
}
span.deleted {
	color: #ff0000;
	text-decoration: line-through;
}

/* Google Charts */
img.chart {
	vertical-align: middle;
}
elyxer-1.2.5/forks/jras-elyxer/src/css/gpl-license.css0000644000175000017500000000137112117061342022220 0ustar  chennochenno/*
*   eLyXer -- convert LyX source files to HTML output.
*
*   Copyright (C) 2009-2010 Alex Fernández
*
*   This program is free software: 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 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
*   GNU General Public License for more details.
*
*   You should have received a copy of the GNU General Public License
*   along with this program.  If not, see http://www.gnu.org/licenses/.
*/
elyxer-1.2.5/forks/jras-elyxer/src/css/obsolete.css0000644000175000017500000000442212117061342021632 0ustar  chennochenno/*
* Obsolete definitions, kept for backwards compatibility.
*/

/* Footnotes */
span.FootMarker {
	color: #0030c0;
	font-size: 0.75em;
	line-height: 0.5em;
	vertical-align: text-top;
}
span.Foot {
	margin: 0.2ex;
	border: thin solid #c0c0c0;
	background: #ffffff;
	padding: 0.5ex;
	font-size: small;
	font-weight: normal;
	line-height: 1.5em;
	text-align: left;
}
span.FootOuter .Foot {
	display: none;
	position: absolute;
}
span.FootOuter:hover .Foot {
	display: inline;
	float: none;
}

/* Dotted box */
span.dotted {
	border-top: thin dotted;
}

/* Obsolete aligned structures */
span.numerator-l {
	display: block;
	text-align: left;
}
span.numerator-r {
	display: block;
	text-align: right;
}
span.numeratorl {
	display: block;
	text-align: left;
}
span.numeratorr {
	display: block;
	text-align: right;
}
span.framebox- {
	display: inline-block;
	border: thin solid black;
	text-align: center;
	padding: 5px;
}
span.framebox-l {
	display: inline-block;
	border: thin solid black;
	text-align: left;
	padding: 5px;
}
span.framebox-r {
	display: inline-block;
	border: thin solid black;
	text-align: right;
	padding: 5px;
}
td.formula-l {
	text-align: left;
	padding: 0.2ex;
	border: 0ex;
}
td.formula-c {
	text-align: center;
	padding: 0.2ex;
	border: 0ex;
}
td.formula-r {
	text-align: right;
	padding: 0.2ex;
	border: 0ex;
}

/* Obsolete limits */
sub.bigsymbol {
	display: table-row;
	text-align: left;
	line-height: 150%;
}
sup.bigsymbol {
	display: table-row;
	text-align: left;
	line-height: 150%;
}

/* Obsolete cases */
table.cases {
	display: inline-block;
	text-align: center;
	border-collapse: collapse;
	margin: 0.2em;
	border-left: thin solid;
	vertical-align: middle;
}
table.cases tr td {
	padding-left: 1ex;
	padding-right: 1em;
}

/* Obsolete binomials */
span.fullbinom {
	display: inline-block;
	vertical-align: middle;
	text-align: center;
}
span.upbinom {
	display: block;
	padding: 0em;
}
span.downbinom {
	display: block;
	padding: 0em;
}

/* Obsolete environments */
table.formula {
	display: inline-block;
	text-align: center;
	border-collapse: collapse;
	margin: 0em;
	vertical-align: middle;
}
td.formula {
	padding: 0.2ex;
	border: 0ex;
}
table.environment {
	display: inline-block;
	text-align: right;
	margin: 0;
	vertical-align: middle;
}
table.environment tr td {
	padding: 0 1em;
}
elyxer-1.2.5/forks/jras-elyxer/src/loremipsumize.py0000755000175000017500000000622112117061342021774 0ustar  chennochenno#! /usr/bin/env python
# -*- coding: utf-8 -*-

#   eLyXer -- convert LyX source files to HTML output.
#
#   Copyright (C) 2009 Alex Fernández
#
#   This program is free software: 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 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
#   GNU General Public License for more details.
#
#   You should have received a copy of the GNU General Public License
#   along with this program.  If not, see .

# --end--
# Alex 20091210
# Lorem-ipsumize a document: replace all alphanumeric texts longer than two words with "Lorem ipsum" and leave the symbols.

import sys
from elyxer.io.fileline import *
from elyxer.parse.position import *
from elyxer.util.trace import Trace


files = list()

def getreader(filename):
  "Get a reader for lines"
  if filename in files:
    # already parsed; skip
    return None
  files.append(filename)
  return LineReader(filename)

def readargs(args):
  "Read arguments from the command line"
  del args[0]
  if len(args) == 0:
    usage()
    return None, None
  if args[0] == '-h' or args[0] == '--help':
    usage()
    return None, None
  reader = getreader(args[0])
  del args[0]
  fileout = sys.stdout
  if len(args) > 0:
    fileout = args[0]
    del args[0]
  if len(args) > 0:
    usage()
    return
  writer = LineWriter(fileout)
  return reader, writer

def usage():
  "Show command line help."
  Trace.error('Usage: loremipsumize.py filein [fileout]')
  Trace.error('Mask your document using nonsensical words (Lorem Ipsum).')
  Trace.error('Part of the eLyXer package (http://elyxer.nongnu.org/).')
  Trace.error('  Options:')
  Trace.error('    --help: show this message and quit.')
  return

class LoremIpsumizer(object):

  starts = '@\\'

  def loremipsumize(self, reader, writer):
    "Convert all texts longer than two words to 'lorem ipsum'."
    if not reader:
      return
    while not reader.finished():
      line = self.processline(reader.currentline())
      writer.writeline(line)
      reader.nextline()
    reader.close()

  def processline(self, line):
    "Process a single line and return the result."
    if len(line) == 0:
      return ''
    if line[0] in LoremIpsumizer.starts:
      return line
    pos = TextPosition(line)
    result = ''
    while not pos.finished():
      result += self.parsepos(pos)
    return result

  def parsepos(self, pos):
    "Parse the current position, return the result."
    if pos.current().isalpha() or pos.current().isdigit():
      alpha = pos.glob(lambda current: current.isalpha() or current.isspace() or current.isdigit())
      if len(alpha.split()) > 2:
        return "lorem ipsum"
      return alpha
    if pos.current().isspace():
      return pos.skipspace()
    return pos.skipcurrent()

reader, writer = readargs(sys.argv)
if reader:
  LoremIpsumizer().loremipsumize(reader, writer)
  writer.close()


elyxer-1.2.5/forks/jras-elyxer/src/javatopy.py0000755000175000017500000000334412117061342020730 0ustar  chennochenno#! /usr/bin/env python
# -*- coding: utf-8 -*-

#   eLyXer -- convert LyX source files to HTML output.
#
#   Copyright (C) 2009 Alex Fernández
#
#   This program is free software: 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 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
#   GNU General Public License for more details.
#
#   You should have received a copy of the GNU General Public License
#   along with this program.  If not, see .

# --end--
# Alex 20091226
# Port a Java program to a Python equivalent. Used to port MathToWeb.

import sys
import os.path
from elyxer.io.fileline import *
from elyxer.parse.position import *
from elyxer.util.trace import Trace
from jtp.porter import *


def readargs(args):
  "Read arguments from the command line"
  del args[0]
  if len(args) == 0:
    usage()
    return
  inputfile = args[0]
  del args[0]
  outputfile = os.path.splitext(inputfile)[0].lower() + '.py'
  if len(args) > 0:
    outputfile = args[0]
    del args[0]
  if len(args) > 0:
    usage()
    return
  return inputfile, outputfile

def usage():
  Trace.error('Usage: javatopy.py filein.java [fileout.py]')
  return

inputfile, outputfile = readargs(sys.argv)
Trace.debugmode = True
Trace.showlinesmode = True
if inputfile:
  JavaPorter().topy(FilePosition(inputfile), LineWriter(outputfile))
  Trace.message('Conversion done, running ' + outputfile)
  os.system('python ' + outputfile)

elyxer-1.2.5/forks/jras-elyxer/src/exportconfig.py0000755000175000017500000001315112117061342021577 0ustar  chennochenno#! /usr/bin/env python
# -*- coding: utf-8 -*-

#   eLyXer -- convert LyX source files to HTML output.
#
#   Copyright (C) 2009 Alex Fernández
#
#   This program is free software: 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 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
#   GNU General Public License for more details.
#
#   You should have received a copy of the GNU General Public License
#   along with this program.  If not, see .

# --end--
# Alex 20090504
# eLyXer configuration manipulation

import sys
import datetime
from elyxer.util.trace import Trace
from elyxer.util.clparse import *
from elyxer.conf.fileconfig import *
from elyxer.conf.importconfig import *


class Config(object):
  "A configuration file"

  cfg = 'conf/base.cfg'
  py = 'elyxer/conf/config.py'
  po = 'conf/elyxer.pot'
  addcfg = None
  importcfg = None
  importcsv = None
  importunimath = None
  help = False

  def run(self, args):
    "Parse command line options and run export to cfg or to py"
    parser = CommandLineParser(Config)
    error = parser.parseoptions(args)
    if error:
      Trace.error(error)
      self.usage()
    elif Config.help:
      self.usage()
    option = self.parseoption(args)
    if not option:
      Trace.error('Choose cfg, py or po')
      self.usage()
    if option == 'cfg':
      self.exportcfg()
      return
    elif option == 'py':
      self.exportpy()
      return
    elif option == 'po':
      self.exportpo()
    else:
      Trace.error('Unknown option ' + option)
      self.usage()

  def usage(self):
    "Show tool usage"
    Trace.error('Usage: exportconfig.py [options] [cfg|py|po]')
    Trace.error('  cfg: export to text configuration file')
    Trace.error('  py: export to python file')
    Trace.error('  po: export elyxer.pot internationalization file')
    Trace.error('  options:')
    Trace.error('    --cfg base.cfg: choose base config file')
    Trace.error('    --addcfg add.cfg: load additional config file')
    Trace.error('    --py config.py: choose Python config file')
    Trace.error('    --importcfg unicodesymbols: import LyX unicode symbols file')
    Trace.error('    --importcsv unicodecsv: import a file of "\command,unicode" pairs')
    Trace.error('    --importunimath unimath.txt: import a file in unimath format')
    Trace.error('      (See http://milde.users.sourceforge.net/LUCR/Math/)')
    exit()

  def read(self):
    "Read from configuration file"
    reader = ConfigReader(Config.cfg).parse()
    if Config.addcfg:
      addreader = ConfigReader(Config.addcfg).parse()
      self.mix(reader, addreader)
    if Config.importcfg:
      addreader = ImportCommands(Config.importcfg).parse()
      self.mix(reader, addreader)
    if Config.importcsv:
      addreader = ImportCsv(Config.importcsv).parse()
      self.mix(reader, addreader)
    if Config.importunimath:
      addreader = ImportUnimath(Config.importunimath).parse()
      self.mix(reader, addreader)
    reader.objects['GeneralConfig.version']['date'] = datetime.date.today().isoformat()
    return reader

  def exportcfg(self):
    "Export configuration to a cfg file"
    linewriter = LineWriter(Config.cfg)
    writer = ConfigWriter(linewriter)
    configs = [globals()[x] for x in dir(elyxer.conf.config) if x.endswith('Config')]
    writer.writeall(configs)

  def exportpy(self):
    "Export configuration as a Python file"
    reader = self.read()
    linewriter = LineWriter(Config.py)
    translator = ConfigToPython(linewriter)
    translator.write(reader.objects)

  def exportpo(self):
    "Export configuration as a gettext .po file."
    reader = self.read()
    writer = LineWriter(Config.po)
    export = TranslationExport(writer)
    export.export(reader.objects['TranslationConfig.constants'])

  def parseoption(self, args):
    "Parse the next option"
    if len(args) == 0:
      return None
    option = args[0]
    del args[0]
    return option

  def mix(self, reader, addreader):
    "Mix two configuration files"
    Trace.message('--- new content follows ---')
    for name, object in addreader.objects.iteritems():
      Trace.message('')
      Trace.message('[' + name + ']')
      equiv = reader.objects[name]
      for key, value in object.iteritems():
        if not key in equiv:
          equiv[key] = value
          Trace.message(key + ':' + unicode(value))

class TranslationExport(object):
  "Export the translation to a file."

  def __init__(self, writer):
    self.writer = writer

  def export(self, constants):
    "Export the translation constants as a .po file."
    self.writer.writeline('# eLyXer internationalization file.')
    self.writer.writeline('# Created on ' + datetime.date.today().isoformat())
    self.writer.writeline(u'# Contact: Alex Fernandez ')
    self.writer.writeline(u'# http://elyxer.nongnu.org/')
    self.writer.writeline('# This file is distributed under the same license as the eLyXer package.')
    self.writer.writeline('# (C) 2010 Alex Fernandez .')
    self.writer.writeline('#')
    self.writer.writeline('')
    for key, message in constants.iteritems():
      self.writer.writeline('')
      self.writer.writeline('#: ' + key)
      self.writer.writeline('msgid  "' + message + '"')
      self.writer.writeline('msgstr "' + message + '"')
    self.writer.close()

config = Config()
del sys.argv[0]
config.run(sys.argv)

elyxer-1.2.5/forks/jras-elyxer/src/textchange.py0000755000175000017500000000454612117061342021232 0ustar  chennochenno#! /usr/bin/env python
# -*- coding: utf-8 -*-

#   eLyXer -- convert LyX source files to HTML output.
#
#   Copyright (C) 2009 Alex Fernández
#
#   This program is free software: 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 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
#   GNU General Public License for more details.
#
#   You should have received a copy of the GNU General Public License
#   along with this program.  If not, see .

# --end--
# Alex 20090416
# Change text in some files at once

import sys
from elyxer.io.fileline import *
from elyxer.io.bulk import *
from elyxer.util.trace import Trace
from elyxer.util.clparse import *


class TextChange(object):
  "A change in some text"

  def __init__(self, key, value):
    self.key = key
    self.value = value

  def affects(self, line):
    "Decide if the change affects the line"
    if self.key in line:
      return True
    return False

  def do(self, line):
    "Change the text in the line"
    return line.replace(self.key, self.value)

def process(reader, writer, change):
  "Change all lines in the file"
  counter = 0
  while not reader.finished():
    line = reader.currentline()
    if change.affects(line):
      line = change.do(line)
      counter += 1
    writer.writeline(line)
    reader.nextline()
  reader.close()
  return counter

def processall(args):
  "Process all arguments"
  del args[0]
  if len(args) < 3:
    Trace.error('Usage: textchange.py original changed [file...]')
    return
  original = args[0]
  del args[0]
  changed = args[0]
  del args[0]
  Trace.message('Replacing ' + original + '->' + changed)
  change = TextChange(original, changed)
  total = 0
  while len(args) > 0:
    pythonfile = BulkFile(args[0])
    reader, writer = pythonfile.getfiles()
    del args[0]
    counter = process(reader, writer, change)
    total += counter
    Trace.message('  ' + unicode(counter) + ' occurrences in ' +
        unicode(pythonfile))
    pythonfile.swaptemp()
  Trace.message('Total replacements: ' + unicode(total))

processall(sys.argv)

elyxer-1.2.5/forks/jras-elyxer/src/conf/0000755000175000017500000000000012117061350017436 5ustar  chennochennoelyxer-1.2.5/forks/jras-elyxer/src/conf/elyxer.pot0000644000175000017500000000446412117061350021502 0ustar  chennochenno# eLyXer internationalization file.
# Created on 2013-03-10
# Contact: Alex Fernandez 
# http://elyxer.nongnu.org/
# This file is distributed under the same license as the eLyXer package.
# (C) 2010 Alex Fernandez .
#


#: Subsubsection
msgid  "Subsubsection"
msgstr "Subsubsection"

#: figure
msgid  "figure"
msgstr "figure"

#: abstract
msgid  "Abstract"
msgstr "Abstract"

#: jsmath-warning
msgid  "Warning: "
msgstr "Warning: "

#: up
msgid  "Up"
msgstr "Up"

#: Book
msgid  "Book"
msgstr "Book"

#: references
msgid  "References"
msgstr "References"

#: Subsection
msgid  "Subsection"
msgstr "Subsection"

#: list-algorithm
msgid  "List of Algorithms"
msgstr "List of Algorithms"

#: Appendix
msgid  "Appendix"
msgstr "Appendix"

#: index
msgid  "Index"
msgstr "Index"

#: bibliography
msgid  "Bibliography"
msgstr "Bibliography"

#: list-table
msgid  "List of Tables"
msgstr "List of Tables"

#: next
msgid  "Next"
msgstr "Next"

#: float-algorithm
msgid  "Algorithm "
msgstr "Algorithm "

#: Part
msgid  "Part"
msgstr "Part"

#: generated-by
msgid  "Document generated by "
msgstr "Document generated by "

#: toc
msgid  "Table of Contents"
msgstr "Table of Contents"

#: prev
msgid  "Prev"
msgstr "Prev"

#: Section
msgid  "Section"
msgstr "Section"

#: Chapter
msgid  "Chapter"
msgstr "Chapter"

#: list-tableau
msgid  "List of Tableaux"
msgstr "List of Tableaux"

#: generated-on
msgid  " on "
msgstr " on "

#: float-tableau
msgid  "Tableau "
msgstr "Tableau "

#: Paragraph
msgid  "Paragraph"
msgstr "Paragraph"

#: list-figure
msgid  "List of Figures"
msgstr "List of Figures"

#: main-page
msgid  "Main page"
msgstr "Main page"

#: float-listing
msgid  "Listing "
msgstr "Listing "

#: on-page
msgid  " on page "
msgstr " on page "

#: nomenclature
msgid  "Nomenclature"
msgstr "Nomenclature"

#: float-table
msgid  "Table "
msgstr "Table "

#: float-figure
msgid  "Figure "
msgstr "Figure "

#: toc-for
msgid  "Contents for "
msgstr "Contents for "

#: jsmath-enable
msgid  "Please enable JavaScript on your browser."
msgstr "Please enable JavaScript on your browser."

#: footnotes
msgid  "Footnotes"
msgstr "Footnotes"

#: jsmath-requires
msgid  " requires JavaScript to correctly process the mathematics on this page. "
msgstr " requires JavaScript to correctly process the mathematics on this page. "
elyxer-1.2.5/forks/jras-elyxer/src/conf/unimathsymbols.txt0000644000175000017500000064551612117061342023277 0ustar  chennochenno# Unicode characters and corresponding LaTeX math mode commands
# *************************************************************
#
# :Copyright: © 2011 Günter Milde
# :Date:      Last revised 2011-03-14
# :Licence:   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.
#
# .. _LaTeX Project Public License: http://www.latex-project.org/lppl.txt
#
# This is a mapping of mathematical Unicode characters to corresponding
# (La)TeX commands.
#
# While the contents of this file represent the best information
# available to the author as of the date referenced above, it
# contains omissions and maybe errors. It is likely that the
# information in this file will change from time to time.
#
# The character encoding of the file is UTF-8.
#
# Each data record consists of 8 fields. Fields are delimited by “^”.
# Spaces adjacent to the delimiter are not significant. The number and
# type of fields in this file may change in future versions.
#
# 1. code point (Unicode character number)
#
#    The code point field is unique.
#
# 2. literal character (UTF-8 encoded)
#
# 3. (La)TeX _`command`
#
#    Preferred representation of the character in TeX.
#    Alternative commands are listed in the comments_ field.
#
# 4. command used by the `unicode-math`_ package
#
#    .. _unicode-math:
#       http://mirror.ctan.org/help/Catalogue/entries/unicode-math.html
#
# 5. Unicode math character class (after MathClassEx_).
#
#    .. _MathClassEx:
#       http://www.unicode.org/Public/math/revision-11/MathClassEx-11.txt
#
#    The class can be one of:
#
#    :N: Normal- includes all digits and symbols requiring only one form
#    :A: Alphabetic
#    :B: Binary
#    :C: Closing – usually paired with opening delimiter
#    :D: Diacritic
#    :F: Fence - unpaired delimiter (often used as opening or closing)
#    :G: Glyph_Part- piece of large operator
#    :L: Large -n-ary or Large operator, often takes limits
#    :O: Opening – usually paired with closing delimiter
#    :P: Punctuation
#    :R: Relation- includes arrows
#    :S: Space
#    :U: Unary – operators that are only unary
#    :V: Vary – operators that can be unary or binary depending on context
#    :X: Special –characters not covered by other classes
#
#    C, O, and F operators are stretchy. In addition some binary
#    operators, such as 002F are stretchy as noted in the descriptive
#    comments. The classes are also useful in determining extra spacing
#    around the operators as discussed in UTR#25.
#
# 6. TeX math category (after unimath-symbols_)
#
#    .. _unimath-symbols:
#       http://mirror.ctan.org/macros/latex/contrib/unicode-math/unimath-symbols.pdf
#
# 7. requirements and conflicts
#
#    Space delimited list of LaTeX packages or features [1]_ providing
#    the LaTeX command_ or conflicting with it.
#
#    Packages/features preceded by a HYPHEN-MINUS (-) use the command
#    for a different symbol.
#
#    To save space, packages providing/modifying (almost) all commands
#    of a feature or another package are not listed here but in the
#    ``packages.txt`` file.
#
#    .. [1] A feature can be a set of commands common to several packages,
#    	    (e.g. ``mathbb`` or ``slantedGreek``) or a constraint (e.g.
#	    ``literal`` mapping plain characters to upright face).
#
# 8. descriptive _`comments`
#
#    The descriptive comments provide more information about the
#    character, or its specific appearance or use.
#
#    Some descriptions contain references to related commands,
#    marked by a character describing the relation
#
#    :=:  equals  (alias commands),
#    :#:  approx  (similar, different character with same glyph),
#    :x:  not     (false friends and name clashes),
#    :t:  text    (text mode command),
#
#    followed by requirements in parantheses, and
#    delimited by commas.
#
#    Comments in UPPERCASE are Unicode character names
#
# no.^chr^LaTeX^unicode-math^cls^category^requirements^comments
00021^!^!^\exclam^N^mathpunct^^EXCLAMATION MARK
00023^#^\#^\octothorpe^N^mathord^^NUMBER SIGN
00024^$^\$^\mathdollar^N^mathord^^= \mathdollar, DOLLAR SIGN
00025^%^\%^\percent^N^mathord^^PERCENT SIGN
00026^&^\&^\ampersand^N^mathord^^# \binampersand (stmaryrd)
00028^(^(^\lparen^O^mathopen^^LEFT PARENTHESIS
00029^)^)^\rparen^C^mathclose^^RIGHT PARENTHESIS
0002A^*^*^^N^mathord^^# \ast, (high) ASTERISK, star
0002B^+^+^\plus^V^mathbin^^PLUS SIGN
0002C^,^,^\comma^P^mathpunct^^COMMA
0002D^-^^^N^mathbin^^t -, HYPHEN-MINUS (deprecated for math)
0002E^.^.^\period^P^mathalpha^^FULL STOP, period
0002F^/^/^\mathslash^B^mathord^^# \slash, SOLIDUS
00030^0^0^^N^mathord^^DIGIT ZERO
00031^1^1^^N^mathord^^DIGIT ONE
00032^2^2^^N^mathord^^DIGIT TWO
00033^3^3^^N^mathord^^DIGIT THREE
00034^4^4^^N^mathord^^DIGIT FOUR
00035^5^5^^N^mathord^^DIGIT FIVE
00036^6^6^^N^mathord^^DIGIT SIX
00037^7^7^^N^mathord^^DIGIT SEVEN
00038^8^8^^N^mathord^^DIGIT EIGHT
00039^9^9^^N^mathord^^DIGIT NINE
0003A^:^:^\mathcolon^P^mathpunct^-literal^= \colon (literal), COLON (not ratio)
0003B^;^;^\semicolon^P^mathpunct^^SEMICOLON p:
0003C^<^<^\less^R^mathrel^^LESS-THAN SIGN r:
0003D^=^=^\equal^R^mathrel^^EQUALS SIGN r:
0003E^>^>^\greater^R^mathrel^^GREATER-THAN SIGN r:
0003F^?^?^\question^P^mathord^^QUESTION MARK
00040^@^@^\atsign^N^mathord^^at
00041^A^A^^A^mathalpha^-literal^= \mathrm{A}, LATIN CAPITAL LETTER A
00042^B^B^^A^mathalpha^-literal^= \mathrm{B}, LATIN CAPITAL LETTER B
00043^C^C^^A^mathalpha^-literal^= \mathrm{C}, LATIN CAPITAL LETTER C
00044^D^D^^A^mathalpha^-literal^= \mathrm{D}, LATIN CAPITAL LETTER D
00045^E^E^^A^mathalpha^-literal^= \mathrm{E}, LATIN CAPITAL LETTER E
00046^F^F^^A^mathalpha^-literal^= \mathrm{F}, LATIN CAPITAL LETTER F
00047^G^G^^A^mathalpha^-literal^= \mathrm{G}, LATIN CAPITAL LETTER G
00048^H^H^^A^mathalpha^-literal^= \mathrm{H}, LATIN CAPITAL LETTER H
00049^I^I^^A^mathalpha^-literal^= \mathrm{I}, LATIN CAPITAL LETTER I
0004A^J^J^^A^mathalpha^-literal^= \mathrm{J}, LATIN CAPITAL LETTER J
0004B^K^K^^A^mathalpha^-literal^= \mathrm{K}, LATIN CAPITAL LETTER K
0004C^L^L^^A^mathalpha^-literal^= \mathrm{L}, LATIN CAPITAL LETTER L
0004D^M^M^^A^mathalpha^-literal^= \mathrm{M}, LATIN CAPITAL LETTER M
0004E^N^N^^A^mathalpha^-literal^= \mathrm{N}, LATIN CAPITAL LETTER N
0004F^O^O^^A^mathalpha^-literal^= \mathrm{O}, LATIN CAPITAL LETTER O
00050^P^P^^A^mathalpha^-literal^= \mathrm{P}, LATIN CAPITAL LETTER P
00051^Q^Q^^A^mathalpha^-literal^= \mathrm{Q}, LATIN CAPITAL LETTER Q
00052^R^R^^A^mathalpha^-literal^= \mathrm{R}, LATIN CAPITAL LETTER R
00053^S^S^^A^mathalpha^-literal^= \mathrm{S}, LATIN CAPITAL LETTER S
00054^T^T^^A^mathalpha^-literal^= \mathrm{T}, LATIN CAPITAL LETTER T
00055^U^U^^A^mathalpha^-literal^= \mathrm{U}, LATIN CAPITAL LETTER U
00056^V^V^^A^mathalpha^-literal^= \mathrm{V}, LATIN CAPITAL LETTER V
00057^W^W^^A^mathalpha^-literal^= \mathrm{W}, LATIN CAPITAL LETTER W
00058^X^X^^A^mathalpha^-literal^= \mathrm{X}, LATIN CAPITAL LETTER X
00059^Y^Y^^A^mathalpha^-literal^= \mathrm{Y}, LATIN CAPITAL LETTER Y
0005A^Z^Z^^A^mathalpha^-literal^= \mathrm{Z}, LATIN CAPITAL LETTER Z
0005B^[^\lbrack^\lbrack^O^mathopen^^LEFT SQUARE BRACKET
0005C^\^\backslash^\backslash^B^mathord^^REVERSE SOLIDUS
0005D^]^\rbrack^\rbrack^C^mathclose^^RIGHT SQUARE BRACKET
0005E^^\sphat^^N^mathord^amsxtra^CIRCUMFLEX ACCENT, TeX superscript operator
0005F^_^\_^^N^mathord^^LOW LINE, TeX subscript operator
00060^`^^^D^mathord^^grave, alias for 0300
00061^a^a^^A^mathalpha^-literal^= \mathrm{a}, LATIN SMALL LETTER A
00062^b^b^^A^mathalpha^-literal^= \mathrm{b}, LATIN SMALL LETTER B
00063^c^c^^A^mathalpha^-literal^= \mathrm{c}, LATIN SMALL LETTER C
00064^d^d^^A^mathalpha^-literal^= \mathrm{d}, LATIN SMALL LETTER D
00065^e^e^^A^mathalpha^-literal^= \mathrm{e}, LATIN SMALL LETTER E
00066^f^f^^A^mathalpha^-literal^= \mathrm{f}, LATIN SMALL LETTER F
00067^g^g^^A^mathalpha^-literal^= \mathrm{g}, LATIN SMALL LETTER G
00068^h^h^^A^mathalpha^-literal^= \mathrm{h}, LATIN SMALL LETTER H
00069^i^i^^A^mathalpha^-literal^= \mathrm{i}, LATIN SMALL LETTER I
0006A^j^j^^A^mathalpha^-literal^= \mathrm{j}, LATIN SMALL LETTER J
0006B^k^k^^A^mathalpha^-literal^= \mathrm{k}, LATIN SMALL LETTER K
0006C^l^l^^A^mathalpha^-literal^= \mathrm{l}, LATIN SMALL LETTER L
0006D^m^m^^A^mathalpha^-literal^= \mathrm{m}, LATIN SMALL LETTER M
0006E^n^n^^A^mathalpha^-literal^= \mathrm{n}, LATIN SMALL LETTER N
0006F^o^o^^A^mathalpha^-literal^= \mathrm{o}, LATIN SMALL LETTER O
00070^p^p^^A^mathalpha^-literal^= \mathrm{p}, LATIN SMALL LETTER P
00071^q^q^^A^mathalpha^-literal^= \mathrm{q}, LATIN SMALL LETTER Q
00072^r^r^^A^mathalpha^-literal^= \mathrm{r}, LATIN SMALL LETTER R
00073^s^s^^A^mathalpha^-literal^= \mathrm{s}, LATIN SMALL LETTER S
00074^t^t^^A^mathalpha^-literal^= \mathrm{t}, LATIN SMALL LETTER T
00075^u^u^^A^mathalpha^-literal^= \mathrm{u}, LATIN SMALL LETTER U
00076^v^v^^A^mathalpha^-literal^= \mathrm{v}, LATIN SMALL LETTER V
00077^w^w^^A^mathalpha^-literal^= \mathrm{w}, LATIN SMALL LETTER W
00078^x^x^^A^mathalpha^-literal^= \mathrm{x}, LATIN SMALL LETTER X
00079^y^y^^A^mathalpha^-literal^= \mathrm{y}, LATIN SMALL LETTER Y
0007A^z^z^^A^mathalpha^-literal^= \mathrm{z}, LATIN SMALL LETTER Z
0007B^{^\{^\lbrace^O^mathopen^^= \lbrace, LEFT CURLY BRACKET
0007C^|^|^\vert^F^mathfence^^= \vert, vertical bar
0007D^}^\}^\rbrace^C^mathclose^^= \rbrace, RIGHT CURLY BRACKET
0007E^~^\sptilde^^N^mathord^amsxtra^# \sim, TILDE
000A0^ ^~^^S^^^nbsp
000A1^¡^^^P^^^iexcl
000A2^¢^\cent^^N^mathord^wasysym^= \mathcent (txfonts), cent
000A3^£^\pounds^\sterling^N^mathord^-fourier -omlmathit^= \mathsterling (txfonts), POUND SIGN, fourier prints a dollar sign
000A4^¤^^^N^mathord^^t \currency (wasysym), curren
000A5^¥^\yen^\yen^N^mathord^amsfonts^YEN SIGN
000A6^¦^^^N^mathord^^brvbar (vertical)
000A7^§^^^N^mathord^^sect
000A8^¨^\spddot^^D^mathord^amsxtra^Dot /die, alias for 0308
000AC^¬^\neg^\neg^U^mathord^^= \lnot, NOT SIGN
000AE^®^\circledR^^X^mathord^amsfonts^REGISTERED SIGN
000AF^¯^^^D^mathord^^macr, alias for 0304
000B0^°^^^N^mathord^^deg
000B1^±^\pm^\pm^V^mathbin^^plus-or-minus sign
000B2^²^^^N^mathord^^sup2
000B3^³^^^N^mathord^^sup3
000B4^´^^^N^mathord^^acute, alias for 0301
000B5^µ^\Micro^^N^mathalpha^wrisym^= \tcmu (mathcomp), t \textmu (textcomp), # \mathrm{\mu} (omlmathrm), # \muup (kpfonts mathdesign), MICRO SIGN
000B6^¶^^^N^mathord^^para (paragraph sign, pilcrow)
000B7^·^^\cdotp^B^mathbin^^# \cdot, x \centerdot, b: MIDDLE DOT
000B9^¹^^^N^mathord^^sup1
000BC^¼^^^N^mathord^^frac14
000BD^½^^^N^mathord^^frac12
000BE^¾^^^N^mathord^^frac34
000BF^¿^^^P^^^iquest
000D7^×^\times^\times^B^mathbin^^MULTIPLICATION SIGN, z notation Cartesian product
000F0^ð^\eth^\matheth^^mathalpha^amssymb arevmath^eth
000F7^÷^\div^\div^B^mathbin^^divide sign
00131^ı^\imath^^A^mathalpha^-literal^imath
001B5^Ƶ^^\Zbar^^mathord^^impedance
00237^ȷ^\jmath^^A^mathalpha^-literal^jmath
002C6^ˆ^^^D^mathalpha^^circ, alias for 0302
002C7^ˇ^^^D^mathalpha^^CARON, alias for 030C
002D8^˘^^^D^mathord^^BREVE, alias for 0306
002D9^˙^^^D^mathord^^dot, alias for 0307
002DA^˚^^^D^mathord^^ring, alias for 030A
002DC^˜^^^D^mathord^^tilde, alias for 0303
00300^x̀^\grave^\grave^D^mathaccent^^grave accent
00301^x́^\acute^\acute^D^mathaccent^^acute accent
00302^x̂^\hat^\hat^D^mathaccent^^# \widehat (amssymb), circumflex accent
00303^x̃^\tilde^\tilde^D^mathaccent^^# \widetilde (yhmath, fourier), tilde
00304^x̄^\bar^\bar^D^mathaccent^^macron
00305^x̅^\overline^\overbar^D^mathaccent^^overbar embellishment
00306^x̆^\breve^\breve^D^mathaccent^^breve
00307^ẋ^\dot^\dot^D^mathaccent^-oz^= \Dot (wrisym), dot above
00308^ẍ^\ddot^\ddot^D^mathaccent^^= \DDot (wrisym), dieresis
00309^x̉^^\ovhook^^mathaccent^^COMBINING HOOK ABOVE
0030A^x̊^\mathring^\ocirc^D^mathaccent^amssymb^= \ring (yhmath), ring
0030C^x̌^\check^\check^D^mathaccent^^caron
00310^x̐^^\candra^^mathaccent^^candrabindu (non-spacing)
00311^x̑^^^D^mathaccent^^COMBINING INVERTED BREVE
00312^x̒^^\oturnedcomma^^mathaccent^^COMBINING TURNED COMMA ABOVE
00315^x̕^^\ocommatopright^^mathaccent^^COMBINING COMMA ABOVE RIGHT
0031A^x̚^^\droang^^mathaccent^^left angle above (non-spacing)
00323^x̣^^^D^mathaccent^^COMBINING DOT BELOW
0032C^x̬^^^D^mathaccent^^COMBINING CARON BELOW
0032D^x̭^^^D^mathaccent^^COMBINING CIRCUMFLEX ACCENT BELOW
0032E^x̮^^^D^mathaccent^^COMBINING BREVE BELOW
0032F^x̯^^^D^mathaccent^^COMBINING INVERTED BREVE BELOW
00330^x̰^\utilde^\wideutilde^D^mathaccent^undertilde^under tilde accent (multiple characters and non-spacing)
00331^x̱^\underbar^\underbar^D^mathaccent^^COMBINING MACRON BELOW
00332^x̲^\underline^^D^mathaccent^^COMBINING LOW LINE
00333^x̳^^^D^mathaccent^^2lowbar
00338^x̸^\not^\not^D^mathaccent^^COMBINING LONG SOLIDUS OVERLAY
0033A^x̺^^^D^mathaccent^^COMBINING INVERTED BRIDGE BELOW
0033F^x̿^^^D^mathaccent^^COMBINING DOUBLE OVERLINE
00346^x͆^^^D^mathaccent^^COMBINING BRIDGE ABOVE
00391^Α^^\upAlpha^A^mathalpha^^capital alpha, greek
00392^Β^^\upBeta^A^mathalpha^^capital beta, greek
00393^Γ^\Gamma^\upGamma^A^mathalpha^-literal^= \Gamma (-slantedGreek), = \mathrm{\Gamma}, capital gamma, greek
00394^Δ^\Delta^\upDelta^A^mathalpha^-literal^= \Delta (-slantedGreek), = \mathrm{\Delta}, capital delta, greek
00395^Ε^^\upEpsilon^A^mathalpha^^capital epsilon, greek
00396^Ζ^^\upZeta^A^mathalpha^^capital zeta, greek
00397^Η^^\upEta^A^mathalpha^^capital eta, greek
00398^Θ^\Theta^\upTheta^A^mathalpha^-literal^= \Theta (-slantedGreek), = \mathrm{\Theta}, capital theta, greek
00399^Ι^^\upIota^A^mathalpha^^capital iota, greek
0039A^Κ^^\upKappa^A^mathalpha^^capital kappa, greek
0039B^Λ^\Lambda^\upLambda^A^mathalpha^-literal^= \Lambda (-slantedGreek), = \mathrm{\Lambda}, capital lambda, greek
0039C^Μ^^\upMu^A^mathalpha^^capital mu, greek
0039D^Ν^^\upNu^A^mathalpha^^capital nu, greek
0039E^Ξ^\Xi^\upXi^A^mathalpha^-literal^= \Xi (-slantedGreek), = \mathrm{\Xi}, capital xi, greek
0039F^Ο^^\upOmicron^A^mathalpha^^capital omicron, greek
003A0^Π^\Pi^\upPi^A^mathalpha^-literal^= \Pi (-slantedGreek), = \mathrm{\Pi}, capital pi, greek
003A1^Ρ^^\upRho^A^mathalpha^^capital rho, greek
003A3^Σ^\Sigma^\upSigma^A^mathalpha^-literal^= \Sigma (-slantedGreek), = \mathrm{\Sigma}, capital sigma, greek
003A4^Τ^^\upTau^A^mathalpha^^capital tau, greek
003A5^Υ^\Upsilon^\upUpsilon^A^mathalpha^-literal^= \Upsilon (-slantedGreek), = \mathrm{\Upsilon}, capital upsilon, greek
003A6^Φ^\Phi^\upPhi^A^mathalpha^-literal^= \Phi (-slantedGreek), = \mathrm{\Phi}, capital phi, greek
003A7^Χ^^\upChi^A^mathalpha^^capital chi, greek
003A8^Ψ^\Psi^\upPsi^A^mathalpha^-literal^= \Psi (-slantedGreek), = \mathrm{\Psi}, capital psi, greek
003A9^Ω^\Omega^\upOmega^A^mathalpha^-literal^= \Omega (-slantedGreek), = \mathrm{\Omega}, capital omega, greek
003B1^α^\alpha^\upalpha^A^mathalpha^-literal^= \mathrm{\alpha} (omlmathrm), = \alphaup (kpfonts mathdesign), = \upalpha (upgreek), alpha, greek
003B2^β^\beta^\upbeta^A^mathalpha^-literal^= \mathrm{\beta} (omlmathrm), = \betaup (kpfonts mathdesign), = \upbeta (upgreek), beta, greek
003B3^γ^\gamma^\upgamma^A^mathalpha^-literal^= \mathrm{\gamma} (omlmathrm), = \gammaup (kpfonts mathdesign), = \upgamma (upgreek), gamma, greek
003B4^δ^\delta^\updelta^A^mathalpha^-literal^= \mathrm{\delta} (omlmathrm), = \deltaup (kpfonts mathdesign), = \updelta (upgreek), delta, greek
003B5^ε^\varepsilon^\upepsilon^A^mathalpha^-literal^= \mathrm{\varepsilon} (omlmathrm), = \varepsilonup (kpfonts mathdesign), = \upepsilon (upgreek), rounded epsilon, greek
003B6^ζ^\zeta^\upzeta^A^mathalpha^-literal^= \mathrm{\zeta} (omlmathrm), = \zetaup (kpfonts mathdesign), = \upzeta (upgreek), zeta, greek
003B7^η^\eta^\upeta^A^mathalpha^-literal^= \mathrm{\eta} (omlmathrm), = \etaup (kpfonts mathdesign), = \upeta (upgreek), eta, greek
003B8^θ^\theta^\uptheta^A^mathalpha^-literal^= \mathrm{\theta} (omlmathrm), = \thetaup (kpfonts mathdesign), straight theta, = \uptheta (upgreek), theta, greek
003B9^ι^\iota^\upiota^A^mathalpha^-literal^= \mathrm{\iota} (omlmathrm), = \iotaup (kpfonts mathdesign), = \upiota (upgreek), iota, greek
003BA^κ^\kappa^\upkappa^A^mathalpha^-literal^= \mathrm{\kappa} (omlmathrm), = \kappaup (kpfonts mathdesign), = \upkappa (upgreek), kappa, greek
003BB^λ^\lambda^\uplambda^A^mathalpha^-literal^= \mathrm{\lambda} (omlmathrm), = \lambdaup (kpfonts mathdesign), = \uplambda (upgreek), lambda, greek
003BC^μ^\mu^\upmu^A^mathalpha^-literal^= \mathrm{\mu} (omlmathrm), = \muup (kpfonts mathdesign), = \upmu (upgreek), mu, greek
003BD^ν^\nu^\upnu^A^mathalpha^-literal^= \mathrm{\nu} (omlmathrm), = \nuup (kpfonts mathdesign), = \upnu (upgreek), nu, greek
003BE^ξ^\xi^\upxi^A^mathalpha^-literal^= \mathrm{\xi} (omlmathrm), = \xiup (kpfonts mathdesign), = \upxi (upgreek), xi, greek
003BF^ο^^\upomicron^A^mathalpha^^small omicron, greek
003C0^π^\pi^\uppi^A^mathalpha^-literal^= \mathrm{\pi} (omlmathrm), = \piup (kpfonts mathdesign), = \uppi (upgreek), pi, greek
003C1^ρ^\rho^\uprho^A^mathalpha^-literal^= \mathrm{\rho} (omlmathrm), = \rhoup (kpfonts mathdesign), = \uprho (upgreek), rho, greek
003C2^ς^\varsigma^\upvarsigma^^mathalpha^-literal^= \mathrm{\varsigma} (omlmathrm), = \varsigmaup (kpfonts mathdesign), = \upvarsigma (upgreek), terminal sigma, greek
003C3^σ^\sigma^\upsigma^A^mathalpha^-literal^= \mathrm{\sigma} (omlmathrm), = \sigmaup (kpfonts mathdesign), = \upsigma (upgreek), sigma, greek
003C4^τ^\tau^\uptau^A^mathalpha^-literal^= \mathrm{\tau} (omlmathrm), = \tauup (kpfonts mathdesign), = \uptau (upgreek), tau, greek
003C5^υ^\upsilon^\upupsilon^A^mathalpha^-literal^= \mathrm{\upsilon} (omlmathrm), = \upsilonup (kpfonts mathdesign), = \upupsilon (upgreek), upsilon, greek
003C6^φ^\varphi^\upvarphi^A^mathalpha^-literal^= \mathrm{\varphi} (omlmathrm), = \varphiup (kpfonts mathdesign), = \upvarphi (upgreek), curly or open phi, greek
003C7^χ^\chi^\upchi^A^mathalpha^-literal^= \mathrm{\chi} (omlmathrm), = \chiup (kpfonts mathdesign), = \upchi (upgreek), chi, greek
003C8^ψ^\psi^\uppsi^A^mathalpha^-literal^= \mathrm{\psi} (omlmathrm), = \psiup (kpfonts mathdesign), = \uppsi (upgreek), psi, greek
003C9^ω^\omega^\upomega^A^mathalpha^-literal^= \mathrm{\omega} (omlmathrm), = \omegaup (kpfonts mathdesign), = \upomega (upgreek), omega, greek
003D0^ϐ^\varbeta^\upvarbeta^A^mathalpha^arevmath^rounded beta, greek
003D1^ϑ^\vartheta^\upvartheta^A^mathalpha^-literal^= \mathrm{\vartheta} (omlmathrm), = \varthetaup (kpfonts mathdesign), curly or open theta
003D2^ϒ^^\upUpsilon^A^mathalpha^^# \mathrm{\Upsilon}, GREEK UPSILON WITH HOOK SYMBOL
003D5^ϕ^\phi^\upphi^A^mathalpha^-literal^= \mathrm{\phi} (omlmathrm), = \phiup (kpfonts mathdesign), GREEK PHI SYMBOL (straight)
003D6^ϖ^\varpi^\upvarpi^A^mathalpha^-literal^= \mathrm{\varpi} (omlmathrm), = \varpiup (kpfonts mathdesign), GREEK PI SYMBOL (pomega)
003D8^Ϙ^\Qoppa^\upoldKoppa^N^mathord^arevmath^= \Koppa (wrisym), t \Qoppa (LGR), GREEK LETTER ARCHAIC KOPPA
003D9^ϙ^\qoppa^\upoldkoppa^N^mathord^arevmath^= \koppa (wrisym), t \qoppa (LGR), GREEK SMALL LETTER ARCHAIC KOPPA
003DA^Ϛ^\Stigma^\upStigma^A^mathalpha^arevmath wrisym^capital stigma
003DB^ϛ^\stigma^\upstigma^A^mathalpha^arevmath wrisym^GREEK SMALL LETTER STIGMA
003DC^Ϝ^\digamma^\upDigamma^A^mathalpha^amssymb -wrisym^= \Digamma (wrisym), capital digamma
003DD^ϝ^\digamma^\updigamma^A^mathalpha^arevmath wrisym -amssymb^GREEK SMALL LETTER DIGAMMA
003DE^Ϟ^\Koppa^\upKoppa^^mathalpha^arevmath^capital koppa
003DF^ϟ^\koppa^\upkoppa^^mathalpha^arevmath^GREEK SMALL LETTER KOPPA
003E0^Ϡ^\Sampi^\upSampi^A^mathalpha^arevmath wrisym^capital sampi
003E1^ϡ^\sampi^\upsampi^A^mathalpha^arevmath^# \sampi (wrisym), GREEK SMALL LETTER SAMPI
003F0^ϰ^^\upvarkappa^A^mathalpha^^GREEK KAPPA SYMBOL (round)
003F1^ϱ^\varrho^\upvarrho^A^mathalpha^omlmathrm -literal^= \mathrm{\varrho} (omlmathrm), = \varrhoup (kpfonts mathdesign), GREEK RHO SYMBOL (round)
003F4^ϴ^^\upvarTheta^A^mathalpha^^x \varTheta (amssymb), GREEK CAPITAL THETA SYMBOL
003F5^ϵ^\epsilon^\upvarepsilon^A^mathalpha^omlmathrm -literal^= \mathrm{\epsilon} (omlmathrm), = \epsilonup (kpfonts mathdesign), GREEK LUNATE EPSILON SYMBOL
003F6^϶^\backepsilon^\upbackepsilon^N^mathord^amssymb wrisym^GREEK REVERSED LUNATE EPSILON SYMBOL
00428^Ш^^^A^mathalpha^^t \CYRSHHA (T2A), Shcy, CYRILLIC CAPITAL LETTER SHA
02000^ ^^^S^^^enquad
02001^ ^\quad^^S^^^emquad
02002^ ^^^S^^^ensp (half an em)
02003^ ^^^S^^^emsp
02004^ ^^^S^^^THREE-PER-EM SPACE
02005^ ^^^S^^^FOUR-PER-EM SPACE, mid space
02006^ ^^^S^^^SIX-PER-EM SPACE
02007^ ^^^S^^^FIGURE SPACE
02009^ ^^^S^^^THIN SPACE
0200A^ ^^^S^^^HAIR SPACE
0200B^​^^^S^^^# \hspace{0pt}, zwsp
02010^‐^^^P^mathord^^HYPHEN (true graphic)
02012^‒^^^P^mathord^^dash
02013^–^^^P^mathord^^ndash
02014^—^^^P^mathord^^mdash
02015^―^^\horizbar^^mathord^^HORIZONTAL BAR
02016^‖^\|^\Vert^F^mathfence^^= \Vert, double vertical bar
02017^‗^^\twolowline^^mathord^^DOUBLE LOW LINE (spacing)
02020^†^\dagger^\dagger^N^mathbin^^DAGGER relation
02021^‡^\ddagger^\ddagger^N^mathbin^^DOUBLE DAGGER relation
02022^•^^\smblkcircle^B^mathbin^^# \bullet, b: round BULLET, filled
02025^‥^^\enleadertwodots^^mathord^^double baseline dot (en leader)
02026^…^\ldots^\unicodeellipsis^N^mathord^^ellipsis (horizontal)
02032^′^\prime^\prime^N^mathord^^PRIME or minute, not superscripted
02033^″^\second^\dprime^N^mathord^mathabx^DOUBLE PRIME or second, not superscripted
02034^‴^\third^\trprime^N^mathord^mathabx^TRIPLE PRIME (not superscripted)
02035^‵^\backprime^\backprime^N^mathord^amssymb^reverse prime, not superscripted
02036^‶^^\backdprime^N^mathord^^double reverse prime, not superscripted
02037^‷^^\backtrprime^N^mathord^^triple reverse prime, not superscripted
02038^‸^^\caretinsert^^mathord^^CARET (insertion mark)
0203B^※^^^N^^^REFERENCE MARK, Japanese kome jirushi
0203C^‼^^\Exclam^N^mathord^^# !!, DOUBLE EXCLAMATION MARK
02040^⁀^\cat^\tieconcat^B^mathbin^oz^CHARACTER TIE, z notation sequence concatenation
02043^⁃^^\hyphenbullet^^mathord^^rectangle, filled (HYPHEN BULLET)
02044^⁄^^\fracslash^B^mathbin^^# /, FRACTION SLASH
02047^⁇^^\Question^^mathord^^# ??, DOUBLE QUESTION MARK
0204E^⁎^^^B^mathbin^^# \ast, lowast, LOW ASTERISK
0204F^⁏^^^R^^^bsemi, REVERSED SEMICOLON
02050^⁐^^\closure^R^mathrel^^CLOSE UP (editing mark)
02051^⁑^^^N^^^Ast
02052^⁒^^^N^mathord^^# ./., COMMERCIAL MINUS SIGN
02057^⁗^\fourth^\qprime^N^mathord^mathabx^QUADRUPLE PRIME, not superscripted
0205F^ ^\:^^S^^^= \medspace (amsmath), MEDIUM MATHEMATICAL SPACE, four-eighteenths of an em
02061^⁡^^^B^^^FUNCTION APPLICATION
02062^⁢^^^B^^^INVISIBLE TIMES
02063^⁣^^^P^^^INVISIBLE SEPARATOR
02064^⁤^^^X^^^INVISIBLE PLUS
0207A^⁺^^^N^mathord^^SUPERSCRIPT PLUS SIGN subscript operators
0207B^⁻^^^N^mathord^^SUPERSCRIPT MINUS subscript operators
0207C^⁼^^^N^mathord^^SUPERSCRIPT EQUALS SIGN subscript operators
0207D^⁽^^^N^mathopen^^SUPERSCRIPT LEFT PARENTHESIS subscript operators
0207E^⁾^^^N^mathclose^^SUPERSCRIPT RIGHT PARENTHESIS subscript operators
0208A^₊^^^N^mathord^^SUBSCRIPT PLUS SIGN superscript operators
0208B^₋^^^N^mathord^^SUBSCRIPT MINUS superscript operators
0208C^₌^^^N^mathord^^SUBSCRIPT EQUALS SIGN superscript operators
0208D^₍^^^N^mathopen^^SUBSCRIPT LEFT PARENTHESIS superscript operators
0208E^₎^^^N^mathclose^^SUBSCRIPT RIGHT PARENTHESIS superscript operators
020AC^€^^\euro^^mathord^^EURO SIGN
020D0^x⃐^\lvec^\leftharpoonaccent^D^mathaccent^wrisym^COMBINING LEFT HARPOON ABOVE
020D1^x⃑^\vec^\rightharpoonaccent^D^mathaccent^wrisym^COMBINING RIGHT HARPOON ABOVE
020D2^x⃒^^\vertoverlay^D^mathaccent^^COMBINING LONG VERTICAL LINE OVERLAY
020D3^x⃓^^^X^mathaccent^^COMBINING SHORT VERTICAL LINE OVERLAY
020D4^x⃔^^^D^mathaccent^^COMBINING ANTICLOCKWISE ARROW ABOVE
020D6^x⃖^\LVec^\overleftarrow^D^mathaccent^wrisym^# \overleftarrow, COMBINING LEFT ARROW ABOVE
020D7^x⃗^\vec^\vec^D^mathaccent^-wrisym^= \Vec (wrisym), # \overrightarrow, COMBINING RIGHT ARROW ABOVE
020D8^x⃘^^^D^mathaccent^^COMBINING RING OVERLAY
020D9^x⃙^^^D^mathaccent^^COMBINING CLOCKWISE RING OVERLAY
020DA^x⃚^^^D^mathaccent^^COMBINING ANTICLOCKWISE RING OVERLAY
020DB^x⃛^\dddot^\dddot^D^mathaccent^amsmath^= \DDDot (wrisym), COMBINING THREE DOTS ABOVE
020DC^x⃜^\ddddot^\ddddot^D^mathaccent^amsmath^COMBINING FOUR DOTS ABOVE
020DD^x⃝^^\enclosecircle^D^mathaccent^^COMBINING ENCLOSING CIRCLE
020DE^x⃞^^\enclosesquare^D^mathaccent^^COMBINING ENCLOSING SQUARE
020DF^x⃟^^\enclosediamond^D^mathaccent^^COMBINING ENCLOSING DIAMOND
020E1^x⃡^\overleftrightarrow^\overleftrightarrow^D^mathaccent^amsmath^COMBINING LEFT RIGHT ARROW ABOVE
020E4^x⃤^^\enclosetriangle^D^mathaccent^^COMBINING ENCLOSING UPWARD POINTING TRIANGLE
020E5^x⃥^^^D^mathaccent^^COMBINING REVERSE SOLIDUS OVERLAY
020E6^x⃦^^^D^mathaccent^^COMBINING DOUBLE VERTICAL STROKE OVERLAY, z notation finite function diacritic
020E7^x⃧^^\annuity^D^mathaccent^^COMBINING ANNUITY SYMBOL
020E8^x⃨^^\threeunderdot^D^mathaccent^^COMBINING TRIPLE UNDERDOT
020E9^x⃩^^\widebridgeabove^D^mathaccent^^COMBINING WIDE BRIDGE ABOVE
020EA^x⃪^^^D^mathaccent^^COMBINING LEFTWARDS ARROW OVERLAY
020EB^x⃫^^^D^mathaccent^^COMBINING LONG DOUBLE SOLIDUS OVERLAY
020EC^x⃬^^\underrightharpoondown^D^mathaccent^^COMBINING RIGHTWARDS HARPOON WITH BARB DOWNWARDS
020ED^x⃭^^\underleftharpoondown^D^mathaccent^^COMBINING LEFTWARDS HARPOON WITH BARB DOWNWARDS
020EE^x⃮^\underleftarrow^\underleftarrow^D^mathaccent^amsmath^COMBINING LEFT ARROW BELOW
020EF^x⃯^\underrightarrow^\underrightarrow^D^mathaccent^amsmath^COMBINING RIGHT ARROW BELOW
020F0^x⃰^^\asteraccent^^mathaccent^^COMBINING ASTERISK ABOVE
02102^ℂ^\mathbb{C}^\BbbC^A^mathalpha^mathbb^= \mathds{C} (dsfont), open face C
02107^ℇ^\Euler^\Eulerconst^N^mathord^wrisym^EULER CONSTANT
0210A^ℊ^\mathcal{g}^\mscrg^A^mathalpha^urwchancal^/scr g, script small letter g
0210B^ℋ^\mathcal{H}^\mscrH^A^mathalpha^^hamiltonian (script capital H)
0210C^ℌ^\mathfrak{H}^\mfrakH^A^mathalpha^eufrak^/frak H, black-letter capital H
0210D^ℍ^\mathbb{H}^\BbbH^A^mathalpha^mathbb^= \mathds{H} (dsfont), open face capital H
0210E^ℎ^^\Planckconst^N^mathord^^# h, Planck constant
0210F^ℏ^\hslash^\hslash^N^mathalpha^amssymb fourier arevmath^=\HBar (wrisym), Planck's h over 2pi
02110^ℐ^\mathcal{I}^\mscrI^A^mathalpha^^/scr I, script capital I
02111^ℑ^\Im^\Im^A^mathalpha^^= \mathfrak{I} (eufrak), imaginary part
02112^ℒ^\mathcal{L}^\mscrL^A^mathalpha^^lagrangian (script capital L)
02113^ℓ^\ell^\ell^A^mathalpha^^cursive small l
02115^ℕ^\mathbb{N}^\BbbN^A^mathalpha^mathbb^= \mathds{N} (dsfont), open face N
02118^℘^\wp^\wp^A^mathalpha^amssymb^weierstrass p
02119^ℙ^\mathbb{P}^\BbbP^A^mathalpha^mathbb^= \mathds{P} (dsfont), open face P
0211A^ℚ^\mathbb{Q}^\BbbQ^A^mathalpha^mathbb^= \mathds{Q} (dsfont), open face Q
0211B^ℛ^\mathcal{R}^\mscrR^A^mathalpha^^/scr R, script capital R
0211C^ℜ^\Re^\Re^A^mathalpha^^= \mathfrak{R} (eufrak), real part
0211D^ℝ^\mathbb{R}^\BbbR^A^mathalpha^mathbb^= \mathds{R} (dsfont), open face R
02124^ℤ^\mathbb{Z}^\BbbZ^A^mathalpha^mathbb^= \mathds{Z} (dsfont), open face Z
02126^Ω^\tcohm^^N^mathalpha^mathcomp^# \mathrm{\Omega}, ohm (deprecated in math, use greek letter)
02127^℧^\mho^\mho^N^mathord^amsfonts arevmath^= \Mho (wrisym), t \agemO (wasysym), conductance
02128^ℨ^\mathfrak{Z}^\mfrakZ^A^mathalpha^eufrak^/frak Z, black-letter capital Z
02129^℩^^\turnediota^N^mathalpha^^turned iota
0212B^Å^\Angstroem^\Angstrom^A^mathalpha^wrisym^# \mathring{\mathrm{A}}, Ångström capital A with ring
0212C^ℬ^\mathcal{B}^\mscrB^A^mathalpha^^bernoulli function (script capital B)
0212D^ℭ^\mathfrak{C}^\mfrakC^A^mathalpha^eufrak^black-letter capital C
0212F^ℯ^\mathcal{e}^\mscre^A^mathalpha^urwchancal^/scr e, script small letter e
02130^ℰ^\mathcal{E}^\mscrE^A^mathalpha^^/scr E, script capital E
02131^ℱ^\mathcal{F}^\mscrF^A^mathalpha^^/scr F, script capital F
02132^Ⅎ^\Finv^\Finv^N^mathord^amssymb^TURNED CAPITAL F
02133^ℳ^\mathcal{M}^\mscrM^A^mathalpha^^physics m-matrix (SCRIPT CAPITAL M)
02134^ℴ^\mathcal{o}^\mscro^A^mathalpha^urwchancal^order of (SCRIPT SMALL O)
02135^ℵ^\aleph^\aleph^A^mathalpha^^aleph, hebrew
02136^ℶ^\beth^\beth^A^mathalpha^amssymb wrisym^beth, hebrew
02137^ℷ^\gimel^\gimel^A^mathalpha^amssymb wrisym^gimel, hebrew
02138^ℸ^\daleth^\daleth^A^mathalpha^amssymb wrisym^daleth, hebrew
0213C^ℼ^\mathbb{\pi}^\Bbbpi^A^mathord^bbold^\DoublePi (wrisym), DOUBLE-STRUCK SMALL PI
0213D^ℽ^\mathbb{\gamma}^\Bbbgamma^A^mathalpha^bbold^\EulerGamma (wrisym), DOUBLE-STRUCK SMALL GAMMA
0213E^ℾ^\mathbb{\Gamma}^\BbbGamma^N^mathalpha^bbold^DOUBLE-STRUCK CAPITAL GAMMA
0213F^ℿ^\mathbb{\Pi}^\BbbPi^A^mathalpha^bbold^DOUBLE-STRUCK CAPITAL PI
02140^⅀^\mathbb{\Sigma}^\Bbbsum^L^mathop^bbold^DOUBLE-STRUCK N-ARY SUMMATION
02141^⅁^^\Game^N^mathord^^# \Game (amssymb), TURNED SANS-SERIF CAPITAL G (amssymb has mirrored G)
02142^⅂^^\sansLturned^N^mathord^^TURNED SANS-SERIF CAPITAL L
02143^⅃^^\sansLmirrored^N^mathord^^REVERSED SANS-SERIF CAPITAL L
02144^⅄^\Yup^\Yup^N^mathord^stmaryrd^TURNED SANS-SERIF CAPITAL Y
02145^ⅅ^\CapitalDifferentialD^\mitBbbD^N^mathord^wrisym^= \DD (wrisym), DOUBLE-STRUCK ITALIC CAPITAL D
02146^ⅆ^\DifferentialD^\mitBbbd^N^mathord^wrisym^= \dd (wrisym), DOUBLE-STRUCK ITALIC SMALL D
02147^ⅇ^\ExponetialE^\mitBbbe^N^mathord^wrisym^= \ee (wrisym), DOUBLE-STRUCK ITALIC SMALL E
02148^ⅈ^\ComplexI^\mitBbbi^N^mathord^wrisym^= \ii (wrisym), DOUBLE-STRUCK ITALIC SMALL I
02149^ⅉ^\ComplexJ^\mitBbbj^N^mathord^wrisym^= \jj (wrisym), DOUBLE-STRUCK ITALIC SMALL J
0214A^⅊^^\PropertyLine^^mathord^^PROPERTY LINE
0214B^⅋^\invamp^\upand^N^mathbin^txfonts^# \bindnasrepma (stmaryrd), TURNED AMPERSAND
02190^←^\leftarrow^\leftarrow^R^mathrel^^= \gets, a: leftward arrow
02191^↑^\uparrow^\uparrow^R^mathrel^^upward arrow
02192^→^\rightarrow^\rightarrow^R^mathrel^^= \to, = \tfun (oz), = \fun (oz), rightward arrow, z notation total function
02193^↓^\downarrow^\downarrow^R^mathrel^^downward arrow
02194^↔^\leftrightarrow^\leftrightarrow^R^mathrel^-wrisym^= \rel (oz), LEFT RIGHT ARROW, z notation relation
02195^↕^\updownarrow^\updownarrow^R^mathrel^^up and down arrow
02196^↖^\nwarrow^\nwarrow^R^mathrel^amssymb^nw pointing arrow
02197^↗^\nearrow^\nearrow^R^mathrel^^ne pointing arrow
02198^↘^\searrow^\searrow^R^mathrel^^se pointing arrow
02199^↙^\swarrow^\swarrow^R^mathrel^^sw pointing arrow
0219A^↚^\nleftarrow^\nleftarrow^R^mathrel^amssymb^not left arrow
0219B^↛^\nrightarrow^\nrightarrow^R^mathrel^amssymb^not right arrow
0219C^↜^^\leftwavearrow^R^mathrel^^left arrow-wavy
0219D^↝^^\rightwavearrow^R^mathrel^^right arrow-wavy
0219E^↞^\twoheadleftarrow^\twoheadleftarrow^R^mathrel^amssymb^left two-headed arrow
0219F^↟^^\twoheaduparrow^R^mathrel^^up two-headed arrow
021A0^↠^\twoheadrightarrow^\twoheadrightarrow^R^mathrel^amssymb^= \tsur (oz), = \surj (oz), right two-headed arrow, z notation total surjection
021A1^↡^^\twoheaddownarrow^R^mathrel^^down two-headed arrow
021A2^↢^\leftarrowtail^\leftarrowtail^R^mathrel^amssymb^left arrow-tailed
021A3^↣^\rightarrowtail^\rightarrowtail^R^mathrel^amssymb^= \tinj (oz), = \inj (oz), right arrow-tailed, z notation total injection
021A4^↤^\mapsfrom^\mapsfrom^R^mathrel^stmaryrd^= \mappedfrom (kpfonts), maps to, leftward
021A5^↥^\MapsUp^\mapsup^R^mathrel^wrisym^maps to, upward
021A6^↦^\mapsto^\mapsto^R^mathrel^^maps to, rightward, z notation maplet
021A7^↧^\MapsDown^\mapsdown^R^mathrel^wrisym^maps to, downward
021A8^↨^^\updownarrowbar^R^mathord^^UP DOWN ARROW WITH BASE (perpendicular)
021A9^↩^\hookleftarrow^\hookleftarrow^R^mathrel^^left arrow-hooked
021AA^↪^\hookrightarrow^\hookrightarrow^R^mathrel^^right arrow-hooked
021AB^↫^\looparrowleft^\looparrowleft^R^mathrel^amssymb^left arrow-looped
021AC^↬^\looparrowright^\looparrowright^R^mathrel^amssymb^right arrow-looped
021AD^↭^\leftrightsquigarrow^\leftrightsquigarrow^R^mathrel^amssymb^left and right arr-wavy
021AE^↮^\nleftrightarrow^\nleftrightarrow^R^mathrel^amssymb^not left and right arrow
021AF^↯^\lightning^\downzigzagarrow^R^mathrel^stmaryrd^t \Lightning (marvosym), DOWNWARDS ZIGZAG ARROW
021B0^↰^\Lsh^\Lsh^R^mathrel^amssymb^a: UPWARDS ARROW WITH TIP LEFTWARDS
021B1^↱^\Rsh^\Rsh^R^mathrel^amssymb^a: UPWARDS ARROW WITH TIP RIGHTWARDS
021B2^↲^\dlsh^\Ldsh^R^mathrel^mathabx^left down angled arrow
021B3^↳^\drsh^\Rdsh^R^mathrel^mathabx^right down angled arrow
021B4^↴^^\linefeed^^mathord^^RIGHTWARDS ARROW WITH CORNER DOWNWARDS
021B5^↵^^\carriagereturn^^mathord^^downwards arrow with corner leftward = carriage return
021B6^↶^\curvearrowleft^\curvearrowleft^R^mathrel^amssymb fourier^left curved arrow
021B7^↷^\curvearrowright^\curvearrowright^R^mathrel^amssymb fourier^right curved arrow
021B8^↸^^\barovernorthwestarrow^^mathord^^NORTH WEST ARROW TO LONG BAR
021B9^↹^^\barleftarrowrightarrowba^^mathord^^LEFTWARDS ARROW TO BAR OVER RIGHTWARDS ARROW TO BAR
021BA^↺^\circlearrowleft^\acwopencirclearrow^R^mathord^amssymb^= \leftturn (wasysym), ANTICLOCKWISE OPEN CIRCLE ARROW
021BB^↻^\circlearrowright^\cwopencirclearrow^R^mathord^amssymb^= \rightturn (wasysym), CLOCKWISE OPEN CIRCLE ARROW
021BC^↼^\leftharpoonup^\leftharpoonup^R^mathrel^^left harpoon-up
021BD^↽^\leftharpoondown^\leftharpoondown^R^mathrel^^left harpoon-down
021BE^↾^\upharpoonright^\upharpoonright^R^mathrel^amssymb^= \restriction (amssymb), = \upharpoonrightup (wrisym), a: up harpoon-right
021BF^↿^\upharpoonleft^\upharpoonleft^R^mathrel^amssymb^= \upharpoonleftup (wrisym), up harpoon-left
021C0^⇀^\rightharpoonup^\rightharpoonup^R^mathrel^^right harpoon-up
021C1^⇁^\rightharpoondown^\rightharpoondown^R^mathrel^^right harpoon-down
021C2^⇂^\downharpoonright^\downharpoonright^R^mathrel^amssymb^= \upharpoonrightdown (wrisym), down harpoon-right
021C3^⇃^\downharpoonleft^\downharpoonleft^R^mathrel^amssymb^= \upharpoonleftdown (wrisym), down harpoon-left
021C4^⇄^\rightleftarrows^\rightleftarrows^R^mathrel^amssymb^= \rightleftarrow (wrisym), right arrow over left arrow
021C5^⇅^\updownarrows^\updownarrows^R^mathrel^mathabx^= \uparrowdownarrow (wrisym), up arrow, down arrow
021C6^⇆^\leftrightarrows^\leftrightarrows^R^mathrel^amssymb^= \leftrightarrow (wrisym), left arrow over right arrow
021C7^⇇^\leftleftarrows^\leftleftarrows^R^mathrel^amssymb fourier^two left arrows
021C8^⇈^\upuparrows^\upuparrows^R^mathrel^amssymb^two up arrows
021C9^⇉^\rightrightarrows^\rightrightarrows^R^mathrel^amssymb fourier^two right arrows
021CA^⇊^\downdownarrows^\downdownarrows^R^mathrel^amssymb^two down arrows
021CB^⇋^\leftrightharpoons^\leftrightharpoons^R^mathrel^amssymb^= \revequilibrium (wrisym), left harpoon over right
021CC^⇌^\rightleftharpoons^\rightleftharpoons^R^mathrel^^= \equilibrium (wrisym), right harpoon over left
021CD^⇍^\nLeftarrow^\nLeftarrow^R^mathrel^amssymb^not implied by
021CE^⇎^\nLeftrightarrow^\nLeftrightarrow^R^mathrel^amssymb^not left and right double arrows
021CF^⇏^\nRightarrow^\nRightarrow^R^mathrel^amssymb^not implies
021D0^⇐^\Leftarrow^\Leftarrow^R^mathrel^^left double arrow
021D1^⇑^\Uparrow^\Uparrow^R^mathrel^^up double arrow
021D2^⇒^\Rightarrow^\Rightarrow^R^mathrel^-marvosym^right double arrow
021D3^⇓^\Downarrow^\Downarrow^R^mathrel^^down double arrow
021D4^⇔^\Leftrightarrow^\Leftrightarrow^R^mathrel^^left and right double arrow
021D5^⇕^\Updownarrow^\Updownarrow^R^mathrel^^up and down double arrow
021D6^⇖^\Nwarrow^\Nwarrow^R^mathrel^txfonts^nw pointing double arrow
021D7^⇗^\Nearrow^\Nearrow^R^mathrel^txfonts^ne pointing double arrow
021D8^⇘^\Searrow^\Searrow^R^mathrel^txfonts^se pointing double arrow
021D9^⇙^\Swarrow^\Swarrow^R^mathrel^txfonts^sw pointing double arrow
021DA^⇚^\Lleftarrow^\Lleftarrow^R^mathrel^amssymb^left triple arrow
021DB^⇛^\Rrightarrow^\Rrightarrow^R^mathrel^amssymb^right triple arrow
021DC^⇜^\leftsquigarrow^\leftsquigarrow^R^mathrel^mathabx txfonts^LEFTWARDS SQUIGGLE ARROW
021DD^⇝^\rightsquigarrow^\rightsquigarrow^R^mathrel^amssymb^RIGHTWARDS SQUIGGLE ARROW
021DE^⇞^^\nHuparrow^R^mathord^^UPWARDS ARROW WITH DOUBLE STROKE
021DF^⇟^^\nHdownarrow^R^mathord^^DOWNWARDS ARROW WITH DOUBLE STROKE
021E0^⇠^\dashleftarrow^\leftdasharrow^R^mathord^amsfonts^LEFTWARDS DASHED ARROW
021E1^⇡^^\updasharrow^R^mathord^^UPWARDS DASHED ARROW
021E2^⇢^\dashrightarrow^\rightdasharrow^R^mathord^amsfonts^= \dasharrow (amsfonts), RIGHTWARDS DASHED ARROW
021E3^⇣^^\downdasharrow^R^mathord^^DOWNWARDS DASHED ARROW
021E4^⇤^\LeftArrowBar^\barleftarrow^R^mathrel^wrisym^LEFTWARDS ARROW TO BAR
021E5^⇥^\RightArrowBar^\rightarrowbar^R^mathrel^wrisym^RIGHTWARDS ARROW TO BAR
021E6^⇦^^\leftwhitearrow^R^mathord^^LEFTWARDS WHITE ARROW
021E7^⇧^^\upwhitearrow^R^mathord^^UPWARDS WHITE ARROW
021E8^⇨^^\rightwhitearrow^R^mathord^^RIGHTWARDS WHITE ARROW
021E9^⇩^^\downwhitearrow^R^mathord^^DOWNWARDS WHITE ARROW
021EA^⇪^^\whitearrowupfrombar^^mathord^^UPWARDS WHITE ARROW FROM BAR
021EB^⇫^^^^mathord^^UPWARDS WHITE ARROW ON PEDESTAL
021EC^⇬^^^^mathord^^UPWARDS WHITE ARROW ON PEDESTAL WITH HORIZONTAL BAR
021ED^⇭^^^^mathord^^UPWARDS WHITE ARROW ON PEDESTAL WITH VERTICAL BAR
021EE^⇮^^^^mathord^^UPWARDS WHITE DOUBLE ARROW
021EF^⇯^^^^mathord^^UPWARDS WHITE DOUBLE ARROW ON PEDESTAL
021F0^⇰^^^^mathord^^RIGHTWARDS WHITE ARROW FROM WALL
021F1^⇱^^^^mathord^^NORTH WEST ARROW TO CORNER
021F2^⇲^^^^mathord^^SOUTH EAST ARROW TO CORNER
021F3^⇳^^^^mathord^^UP DOWN WHITE ARROW
021F4^⇴^^\circleonrightarrow^R^mathrel^^RIGHT ARROW WITH SMALL CIRCLE
021F5^⇵^\downuparrows^\downuparrows^R^mathrel^mathabx^= \downarrowuparrow (wrisym), DOWNWARDS ARROW LEFTWARDS OF UPWARDS ARROW
021F6^⇶^^\rightthreearrows^R^mathrel^^THREE RIGHTWARDS ARROWS
021F7^⇷^^\nvleftarrow^R^mathrel^^LEFTWARDS ARROW WITH VERTICAL STROKE
021F8^⇸^\pfun^\nvrightarrow^R^mathrel^oz^RIGHTWARDS ARROW WITH VERTICAL STROKE, z notation partial function
021F9^⇹^^\nvleftrightarrow^R^mathrel^^LEFT RIGHT ARROW WITH VERTICAL STROKE, z notation partial relation
021FA^⇺^^\nVleftarrow^R^mathrel^^LEFTWARDS ARROW WITH DOUBLE VERTICAL STROKE
021FB^⇻^\ffun^\nVrightarrow^R^mathrel^oz^RIGHTWARDS ARROW WITH DOUBLE VERTICAL STROKE, z notation finite function
021FC^⇼^^\nVleftrightarrow^R^mathrel^^LEFT RIGHT ARROW WITH DOUBLE VERTICAL STROKE, z notation finite relation
021FD^⇽^\leftarrowtriangle^\leftarrowtriangle^R^mathrel^stmaryrd^LEFTWARDS OPEN-HEADED ARROW
021FE^⇾^\rightarrowtriangle^\rightarrowtriangle^R^mathrel^stmaryrd^RIGHTWARDS OPEN-HEADED ARROW
021FF^⇿^\leftrightarrowtriangle^\leftrightarrowtriangle^R^mathrel^stmaryrd^LEFT RIGHT OPEN-HEADED ARROW
02200^∀^\forall^\forall^U^mathord^^FOR ALL
02201^∁^\complement^\complement^U^mathord^amssymb fourier^COMPLEMENT sign
02202^∂^\partial^\partial^N^mathord^-literal^= \partialup (kpfonts), PARTIAL DIFFERENTIAL
02203^∃^\exists^\exists^U^mathord^^= \exi (oz), at least one exists
02204^∄^\nexists^\nexists^U^mathord^amssymb fourier^= \nexi (oz), negated exists
02205^∅^\varnothing^\varnothing^N^mathord^amssymb^circle, slash
02206^∆^^\increment^U^mathord^^# \mathrm{\Delta}, laplacian (Delta; nabla square)
02207^∇^\nabla^\nabla^U^mathord^^NABLA, del, hamilton operator
02208^∈^\in^\in^R^mathrel^^set membership, variant
02209^∉^\notin^\notin^R^mathrel^^= \nin (wrisym), negated set membership
0220A^∊^^\smallin^R^mathrel^^set membership (small set membership)
0220B^∋^\ni^\ni^R^mathrel^^= \owns, contains, variant
0220C^∌^\nni^\nni^R^mathrel^wrisym^= \notni (txfonts), = \notowner (mathabx), = \notowns (fourier), negated contains, variant
0220D^∍^^\smallni^R^mathrel^^r: contains (SMALL CONTAINS AS MEMBER)
0220E^∎^^\QED^N^mathord^^# \blacksquare (amssymb), END OF PROOF
0220F^∏^\prod^\prod^L^mathop^^product operator
02210^∐^\coprod^\coprod^L^mathop^^coproduct operator
02211^∑^\sum^\sum^L^mathop^^summation operator
02212^−^-^\minus^V^mathbin^^MINUS SIGN
02213^∓^\mp^\mp^V^mathbin^^MINUS-OR-PLUS SIGN
02214^∔^\dotplus^\dotplus^B^mathbin^amssymb^plus sign, dot above
02215^∕^\slash^\divslash^B^mathbin^^DIVISION SLASH
02216^∖^\smallsetminus^\smallsetminus^B^mathbin^amssymb fourier^small SET MINUS (cf. reverse solidus)
02217^∗^\ast^\ast^B^mathbin^^ASTERISK OPERATOR (Hodge star operator)
02218^∘^\circ^\vysmwhtcircle^B^mathbin^^composite function (small circle)
02219^∙^\bullet^\vysmblkcircle^B^mathbin^^BULLET OPERATOR
0221A^√^\sqrt^\sqrt^L^mathradical^^radical
0221B^∛^\sqrt[3]^\cuberoot^L^mathradical^^CUBE ROOT
0221C^∜^\sqrt[4]^\fourthroot^L^mathradical^^FOURTH ROOT
0221D^∝^\propto^\propto^R^mathrel^^# \varpropto (amssymb), is PROPORTIONAL TO
0221E^∞^\infty^\infty^N^mathord^^INFINITY
0221F^∟^\rightangle^\rightangle^N^mathord^wrisym^right (90 degree) angle
02220^∠^\angle^\angle^N^mathord^^ANGLE
02221^∡^\measuredangle^\measuredangle^N^mathord^amssymb wrisym^MEASURED ANGLE
02222^∢^\sphericalangle^\sphericalangle^N^mathord^amssymb wrisym^SPHERICAL ANGLE
02223^∣^\mid^\mid^R^mathrel^^r: DIVIDES
02224^∤^\nmid^\nmid^R^mathrel^amssymb^negated mid, DOES NOT DIVIDE
02225^∥^\parallel^\parallel^R^mathrel^^parallel
02226^∦^\nparallel^\nparallel^R^mathrel^amssymb fourier^not parallel
02227^∧^\wedge^\wedge^B^mathbin^amssymb^= \land, b: LOGICAL AND
02228^∨^\vee^\vee^B^mathbin^^= \lor, b: LOGICAL OR
02229^∩^\cap^\cap^B^mathbin^^INTERSECTION
0222A^∪^\cup^\cup^B^mathbin^^UNION or logical sum
0222B^∫^\int^\int^L^mathop^^INTEGRAL operator
0222C^∬^\iint^\iint^L^mathop^amsmath fourier esint wasysym^DOUBLE INTEGRAL operator
0222D^∭^\iiint^\iiint^L^mathop^amsmath fourier esint wasysym^TRIPLE INTEGRAL operator
0222E^∮^\oint^\oint^L^mathop^^CONTOUR INTEGRAL operator
0222F^∯^\oiint^\oiint^L^mathop^esint wasysym fourier^= \dbloint (wrisym), double contour integral operator
02230^∰^\oiiint^\oiiint^L^mathop^txfonts fourier^triple contour integral operator
02231^∱^^\intclockwise^L^mathop^^CLOCKWISE INTEGRAL
02232^∲^\varointclockwise^\varointclockwise^L^mathop^esint^= \clockoint (wrisym), contour integral, clockwise
02233^∳^\ointctrclockwise^\ointctrclockwise^L^mathop^esint^= \cntclockoint (wrisym), contour integral, anticlockwise
02234^∴^\therefore^\therefore^R^mathord^amssymb wrisym^= \wasytherefore (wasysym), THEREFORE
02235^∵^\because^\because^R^mathord^amssymb wrisym^BECAUSE
02236^∶^:^\mathratio^R^mathrel^^x \colon, RATIO
02237^∷^\Proportion^\Colon^R^mathrel^wrisym^# ::, two colons
02238^∸^^\dotminus^B^mathbin^^minus sign, dot above
02239^∹^\eqcolon^\dashcolon^R^mathrel^txfonts -mathabx^# -: ,EXCESS
0223A^∺^^\dotsminusdots^R^mathrel^^minus with four dots, GEOMETRIC PROPORTION
0223B^∻^^\kernelcontraction^R^mathrel^^HOMOTHETIC
0223C^∼^\sim^\sim^R^mathrel^^similar to, TILDE OPERATOR
0223D^∽^\backsim^\backsim^R^mathrel^amssymb^reverse similar
0223E^∾^^\invlazys^B^mathbin^^most positive, INVERTED LAZY S
0223F^∿^\AC^\sinewave^N^mathord^wasysym^SINE WAVE, alternating current
02240^≀^\wr^\wr^B^mathbin^amssymb^WREATH PRODUCT
02241^≁^\nsim^\nsim^R^mathrel^amssymb wrisym^not similar
02242^≂^\eqsim^\eqsim^R^mathrel^amssymb^equals, similar
02243^≃^\simeq^\simeq^R^mathrel^^similar, equals
02244^≄^\nsimeq^\nsime^R^mathrel^txfonts^not similar, equals
02245^≅^\cong^\cong^R^mathrel^^congruent with
02246^≆^^\simneqq^R^mathrel^^similar, not equals [vert only for 9573 entity]
02247^≇^\ncong^\ncong^R^mathrel^amssymb wrisym^not congruent with
02248^≈^\approx^\approx^R^mathrel^^approximate
02249^≉^\napprox^\napprox^R^mathrel^wrisym^not approximate
0224A^≊^\approxeq^\approxeq^R^mathrel^amssymb^approximate, equals
0224B^≋^^\approxident^R^mathrel^^approximately identical to
0224C^≌^^\backcong^R^mathrel^^ALL EQUAL TO
0224D^≍^\asymp^\asymp^R^mathrel^^asymptotically equal to
0224E^≎^\Bumpeq^\Bumpeq^R^mathrel^amssymb wrisym^bumpy equals
0224F^≏^\bumpeq^\bumpeq^R^mathrel^amssymb wrisym^bumpy equals, equals
02250^≐^\doteq^\doteq^R^mathrel^^= \dotequal (wrisym), equals, single dot above
02251^≑^\Doteq^\Doteq^R^mathrel^amssymb^= \doteqdot (amssymb), /doteq r: equals, even dots
02252^≒^\fallingdotseq^\fallingdotseq^R^mathrel^amssymb^equals, falling dots
02253^≓^\risingdotseq^\risingdotseq^R^mathrel^amssymb^equals, rising dots
02254^≔^\coloneq^\coloneq^R^mathrel^mathabx -txfonts^= \coloneqq (txfonts), = \SetDelayed (wrisym), # := colon, equals
02255^≕^\eqcolon^\eqcolon^R^mathrel^mathabx -txfonts^= \eqqcolon (txfonts), # =:, equals, colon
02256^≖^\eqcirc^\eqcirc^R^mathrel^amssymb^circle on equals sign
02257^≗^\circeq^\circeq^R^mathrel^amssymb^circle, equals
02258^≘^^\arceq^R^mathrel^^arc, equals; CORRESPONDS TO
02259^≙^\corresponds^\wedgeq^R^mathrel^mathabx^= \sdef (oz), t \Corresponds (marvosym), corresponds to (wedge over equals)
0225A^≚^^\veeeq^R^mathrel^^logical or, equals
0225B^≛^^\stareq^R^mathrel^^STAR EQUALS
0225C^≜^\triangleq^\triangleq^R^mathrel^amssymb^= \varsdef (oz), triangle, equals
0225D^≝^^\eqdef^R^mathrel^^equals by definition
0225E^≞^^\measeq^R^mathrel^^MEASURED BY (m over equals)
0225F^≟^^\questeq^R^mathrel^^equal with questionmark
02260^≠^\neq^\ne^R^mathrel^^= \ne, r: not equal
02261^≡^\equiv^\equiv^R^mathrel^^identical with
02262^≢^\nequiv^\nequiv^R^mathrel^wrisym^not identical with
02263^≣^^\Equiv^R^mathrel^^strict equivalence (4 lines)
02264^≤^\leq^\leq^R^mathrel^^= \le, r: less-than-or-equal
02265^≥^\geq^\geq^R^mathrel^^= \ge, r: greater-than-or-equal
02266^≦^\leqq^\leqq^R^mathrel^amssymb^less, double equals
02267^≧^\geqq^\geqq^R^mathrel^amssymb^greater, double equals
02268^≨^\lneqq^\lneqq^R^mathrel^amssymb^less, not double equals
02269^≩^\gneqq^\gneqq^R^mathrel^amssymb^greater, not double equals
0226A^≪^\ll^\ll^R^mathrel^^much less than, type 2
0226B^≫^\gg^\gg^R^mathrel^^much greater than, type 2
0226C^≬^\between^\between^R^mathrel^amssymb^BETWEEN
0226D^≭^\notasymp^\nasymp^R^mathrel^mathabx^= \nasymp (wrisym), not asymptotically equal to
0226E^≮^\nless^\nless^R^mathrel^amssymb^NOT LESS-THAN
0226F^≯^\ngtr^\ngtr^R^mathrel^amssymb^NOT GREATER-THAN
02270^≰^\nleq^\nleq^R^mathrel^amssymb wrisym^= \nleqslant (fourier), not less-than-or-equal
02271^≱^\ngeq^\ngeq^R^mathrel^amssymb wrisym^= \ngeqslant (fourier), not greater-than-or-equal
02272^≲^\lesssim^\lesssim^R^mathrel^amssymb^= \apprle (wasysym), = \LessTilde (wrisym), less, similar
02273^≳^\gtrsim^\gtrsim^R^mathrel^amssymb^= \apprge (wasysym), = \GreaterTilde (wrisym), greater, similar
02274^≴^\NotLessTilde^\nlesssim^R^mathrel^wrisym^not less, similar
02275^≵^\NotGreaterTilde^\ngtrsim^R^mathrel^wrisym^not greater, similar
02276^≶^\lessgtr^\lessgtr^R^mathrel^amssymb^less, greater
02277^≷^\gtrless^\gtrless^R^mathrel^amssymb^= \GreaterLess (wrisym), greater, less
02278^≸^^\nlessgtr^R^mathrel^wrisym^not less, greater
02279^≹^\NotGreaterLess^\ngtrless^R^mathrel^wrisym^not greater, less
0227A^≺^\prec^\prec^R^mathrel^^PRECEDES
0227B^≻^\succ^\succ^R^mathrel^^SUCCEEDS
0227C^≼^\preccurlyeq^\preccurlyeq^R^mathrel^amssymb^= \PrecedesSlantEqual (wrisym), precedes, curly equals
0227D^≽^\succcurlyeq^\succcurlyeq^R^mathrel^amssymb^= \SucceedsSlantEqual (wrisym), succeeds, curly equals
0227E^≾^\precsim^\precsim^R^mathrel^amssymb^= \PrecedesTilde (wrisym), precedes, similar
0227F^≿^\succsim^\succsim^R^mathrel^amssymb^= \SucceedsTilde (wrisym), succeeds, similar
02280^⊀^\nprec^\nprec^R^mathrel^amssymb wrisym^not precedes
02281^⊁^\nsucc^\nsucc^R^mathrel^amssymb wrisym^not succeeds
02282^⊂^\subset^\subset^R^mathrel^^subset or is implied by
02283^⊃^\supset^\supset^R^mathrel^^superset or implies
02284^⊄^\nsubset^\nsubset^R^mathrel^wrisym^not subset, variant [slash negation]
02285^⊅^\nsupset^\nsupset^R^mathrel^wrisym^not superset, variant [slash negation]
02286^⊆^\subseteq^\subseteq^R^mathrel^^subset, equals
02287^⊇^\supseteq^\supseteq^R^mathrel^^superset, equals
02288^⊈^\nsubseteq^\nsubseteq^R^mathrel^amssymb wrisym^not subset, equals
02289^⊉^\nsupseteq^\nsupseteq^R^mathrel^amssymb wrisym^not superset, equals
0228A^⊊^\subsetneq^\subsetneq^R^mathrel^amssymb^= \varsubsetneq (fourier), subset, not equals
0228B^⊋^\supsetneq^\supsetneq^R^mathrel^amssymb^superset, not equals
0228C^⊌^^\cupleftarrow^B^mathbin^^MULTISET
0228D^⊍^^\cupdot^B^mathbin^^union, with dot
0228E^⊎^\uplus^\uplus^B^mathbin^^= \buni (oz), plus sign in union
0228F^⊏^\sqsubset^\sqsubset^R^mathrel^amsfonts^square subset
02290^⊐^\sqsupset^\sqsupset^R^mathrel^amsfonts^square superset
02291^⊑^\sqsubseteq^\sqsubseteq^R^mathrel^^square subset, equals
02292^⊒^\sqsupseteq^\sqsupseteq^R^mathrel^^square superset, equals
02293^⊓^\sqcap^\sqcap^B^mathbin^^square intersection
02294^⊔^\sqcup^\sqcup^B^mathbin^^square union
02295^⊕^\oplus^\oplus^B^mathbin^^plus sign in circle
02296^⊖^\ominus^\ominus^B^mathbin^^minus sign in circle
02297^⊗^\otimes^\otimes^B^mathbin^^multiply sign in circle
02298^⊘^\oslash^\oslash^B^mathbin^^solidus in circle
02299^⊙^\odot^\odot^B^mathbin^^middle dot in circle
0229A^⊚^\circledcirc^\circledcirc^B^mathbin^amssymb^small circle in circle
0229B^⊛^\circledast^\circledast^B^mathbin^amssymb^asterisk in circle
0229C^⊜^^\circledequal^B^mathbin^^equal in circle
0229D^⊝^\circleddash^\circleddash^B^mathbin^amssymb^hyphen in circle
0229E^⊞^\boxplus^\boxplus^B^mathbin^amssymb^plus sign in box
0229F^⊟^\boxminus^\boxminus^B^mathbin^amssymb^minus sign in box
022A0^⊠^\boxtimes^\boxtimes^B^mathbin^amssymb^multiply sign in box
022A1^⊡^\boxdot^\boxdot^B^mathbin^amssymb stmaryrd^/dotsquare /boxdot b: small dot in box
022A2^⊢^\vdash^\vdash^R^mathrel^^RIGHT TACK, proves, implies, yields, (vertical, dash)
022A3^⊣^\dashv^\dashv^R^mathrel^amssymb^LEFT TACK, non-theorem, does not yield, (dash, vertical)
022A4^⊤^\top^\top^N^mathord^^DOWN TACK, top
022A5^⊥^\bot^\bot^R^mathord^^UP TACK, bottom
022A6^⊦^^\assert^R^mathrel^^# \vdash, ASSERTION (vertical, short dash)
022A7^⊧^\models^\models^R^mathrel^^MODELS (vertical, short double dash)
022A8^⊨^\vDash^\vDash^R^mathrel^amssymb fourier^TRUE (vertical, double dash)
022A9^⊩^\Vdash^\Vdash^R^mathrel^amssymb^double vertical, dash
022AA^⊪^\Vvdash^\Vvdash^R^mathrel^amssymb^triple vertical, dash
022AB^⊫^\VDash^\VDash^R^mathrel^mathabx txfonts^double vert, double dash
022AC^⊬^\nvdash^\nvdash^R^mathrel^amssymb^not vertical, dash
022AD^⊭^\nvDash^\nvDash^R^mathrel^amssymb fourier^not vertical, double dash
022AE^⊮^\nVdash^\nVdash^R^mathrel^amssymb^not double vertical, dash
022AF^⊯^\nVDash^\nVDash^R^mathrel^amssymb^not double vert, double dash
022B0^⊰^^\prurel^R^mathrel^^element PRECEDES UNDER RELATION
022B1^⊱^^\scurel^R^mathrel^^SUCCEEDS UNDER RELATION
022B2^⊲^\vartriangleleft^\vartriangleleft^R^mathrel^amssymb^left triangle, open, variant
022B3^⊳^\vartriangleright^\vartriangleright^R^mathrel^amssymb^right triangle, open, variant
022B4^⊴^\trianglelefteq^\trianglelefteq^R^mathrel^amssymb^= \unlhd (wrisym), left triangle, equals
022B5^⊵^\trianglerighteq^\trianglerighteq^R^mathrel^amssymb^= \unrhd (wrisym), right triangle, equals
022B6^⊶^\multimapdotbothA^\origof^R^mathrel^txfonts^ORIGINAL OF
022B7^⊷^\multimapdotbothB^\imageof^R^mathrel^txfonts^IMAGE OF
022B8^⊸^\multimap^\multimap^R^mathrel^amssymb^/MULTIMAP a:
022B9^⊹^^\hermitmatrix^B^mathord^^HERMITIAN CONJUGATE MATRIX
022BA^⊺^\intercal^\intercal^B^mathbin^amssymb fourier^intercal
022BB^⊻^\veebar^\veebar^B^mathbin^amssymb^logical or, bar below (large vee); exclusive disjunction
022BC^⊼^\barwedge^\barwedge^B^mathbin^amssymb^logical NAND (bar over wedge)
022BD^⊽^^\barvee^B^mathbin^^bar, vee (large vee)
022BE^⊾^^\measuredrightangle^N^mathord^^right angle-measured [with arc]
022BF^⊿^^\varlrtriangle^N^mathord^^RIGHT TRIANGLE
022C0^⋀^\bigwedge^\bigwedge^L^mathop^^logical or operator
022C1^⋁^\bigvee^\bigvee^L^mathop^^logical and operator
022C2^⋂^\bigcap^\bigcap^L^mathop^^= \dint (oz), \dinter (oz), intersection operator
022C3^⋃^\bigcup^\bigcup^L^mathop^^= \duni (oz), \dunion (oz), union operator
022C4^⋄^\diamond^\smwhtdiamond^B^mathbin^^DIAMOND OPERATOR (white diamond)
022C5^⋅^\cdot^\cdot^B^mathbin^^DOT OPERATOR (small middle dot)
022C6^⋆^\star^\star^B^mathbin^^small star, filled, low
022C7^⋇^\divideontimes^\divideontimes^B^mathbin^amssymb^division on times
022C8^⋈^\bowtie^\bowtie^R^mathrel^^= \lrtimes (txfonts), BOWTIE
022C9^⋉^\ltimes^\ltimes^B^mathbin^amssymb^times sign, left closed
022CA^⋊^\rtimes^\rtimes^B^mathbin^amssymb^times sign, right closed
022CB^⋋^\leftthreetimes^\leftthreetimes^B^mathbin^amssymb^LEFT SEMIDIRECT PRODUCT
022CC^⋌^\rightthreetimes^\rightthreetimes^B^mathbin^amssymb^RIGHT SEMIDIRECT PRODUCT
022CD^⋍^\backsimeq^\backsimeq^R^mathrel^amssymb^reverse similar, equals
022CE^⋎^\curlyvee^\curlyvee^B^mathbin^amssymb^CURLY LOGICAL OR
022CF^⋏^\curlywedge^\curlywedge^B^mathbin^amssymb^CURLY LOGICAL AND
022D0^⋐^\Subset^\Subset^R^mathrel^amssymb^DOUBLE SUBSET
022D1^⋑^\Supset^\Supset^R^mathrel^amssymb^DOUBLE SUPERSET
022D2^⋒^\Cap^\Cap^B^mathbin^amssymb^/cap /doublecap b: DOUBLE INTERSECTION
022D3^⋓^\Cup^\Cup^B^mathbin^amssymb^/cup /doublecup b: DOUBLE UNION
022D4^⋔^\pitchfork^\pitchfork^R^mathrel^amssymb^PITCHFORK
022D5^⋕^\hash^\equalparallel^R^mathrel^mathabx^parallel, equal; equal or parallel
022D6^⋖^\lessdot^\lessdot^R^mathrel^amssymb^less than, with dot
022D7^⋗^\gtrdot^\gtrdot^R^mathrel^amssymb^greater than, with dot
022D8^⋘^\lll^\lll^R^mathrel^amssymb -mathabx^triple less-than
022D9^⋙^\ggg^\ggg^R^mathrel^amssymb -mathabx^triple greater-than
022DA^⋚^\lesseqgtr^\lesseqgtr^R^mathrel^amssymb^less, equals, greater
022DB^⋛^\gtreqless^\gtreqless^R^mathrel^amssymb^greater, equals, less
022DC^⋜^^\eqless^R^mathrel^^equal-or-less
022DD^⋝^^\eqgtr^R^mathrel^^equal-or-greater
022DE^⋞^\curlyeqprec^\curlyeqprec^R^mathrel^amssymb^curly equals, precedes
022DF^⋟^\curlyeqsucc^\curlyeqsucc^R^mathrel^amssymb^curly equals, succeeds
022E0^⋠^\npreceq^\npreccurlyeq^R^mathrel^amssymb wrisym^DOES NOT PRECEDE OR EQUAL
022E1^⋡^\nsucceq^\nsucccurlyeq^R^mathrel^amssymb wrisym^not succeeds, curly equals
022E2^⋢^\nsqsubseteq^\nsqsubseteq^R^mathrel^wrisym^not, square subset, equals
022E3^⋣^\nsqsupseteq^\nsqsupseteq^R^mathrel^wrisym^not, square superset, equals
022E4^⋤^^\sqsubsetneq^R^mathrel^^square subset, not equals
022E5^⋥^^\sqsupsetneq^R^mathrel^^square superset, not equals
022E6^⋦^\lnsim^\lnsim^R^mathrel^amssymb^less, not similar
022E7^⋧^\gnsim^\gnsim^R^mathrel^amssymb^greater, not similar
022E8^⋨^\precnsim^\precnsim^R^mathrel^amssymb^precedes, not similar
022E9^⋩^\succnsim^\succnsim^R^mathrel^amssymb^succeeds, not similar
022EA^⋪^\ntriangleleft^\ntriangleleft^R^mathrel^amssymb^= \NotLeftTriangle (wrisym), not left triangle
022EB^⋫^\ntriangleright^\ntriangleright^R^mathrel^amssymb^= \NotRightTriangle (wrisym), not right triangle
022EC^⋬^\ntrianglelefteq^\ntrianglelefteq^R^mathrel^amssymb^= \nunlhd (wrisym), not left triangle, equals
022ED^⋭^\ntrianglerighteq^\ntrianglerighteq^R^mathrel^amssymb^= \nunrhd (wrisym), not right triangle, equals
022EE^⋮^\vdots^\vdots^R^mathrel^^VERTICAL ELLIPSIS
022EF^⋯^\cdots^\unicodecdots^R^mathord^^three dots, centered
022F0^⋰^\iddots^\adots^R^mathrel^mathdots^= \adots (yhmath), three dots, ascending
022F1^⋱^\ddots^\ddots^R^mathrel^^three dots, descending
022F2^⋲^^\disin^R^mathrel^^ELEMENT OF WITH LONG HORIZONTAL STROKE
022F3^⋳^^\varisins^R^mathrel^^ELEMENT OF WITH VERTICAL BAR AT END OF HORIZONTAL STROKE
022F4^⋴^^\isins^R^mathrel^^SMALL ELEMENT OF WITH VERTICAL BAR AT END OF HORIZONTAL STROKE
022F5^⋵^^\isindot^R^mathrel^^ELEMENT OF WITH DOT ABOVE
022F6^⋶^\barin^\varisinobar^R^mathrel^mathabx^ELEMENT OF WITH OVERBAR
022F7^⋷^^\isinobar^R^mathrel^^SMALL ELEMENT OF WITH OVERBAR
022F8^⋸^^\isinvb^R^mathrel^^ELEMENT OF WITH UNDERBAR
022F9^⋹^^\isinE^R^mathrel^^ELEMENT OF WITH TWO HORIZONTAL STROKES
022FA^⋺^^\nisd^R^mathrel^^CONTAINS WITH LONG HORIZONTAL STROKE
022FB^⋻^^\varnis^R^mathrel^^CONTAINS WITH VERTICAL BAR AT END OF HORIZONTAL STROKE
022FC^⋼^^\nis^R^mathrel^^SMALL CONTAINS WITH VERTICAL BAR AT END OF HORIZONTAL STROKE
022FD^⋽^^\varniobar^R^mathrel^^CONTAINS WITH OVERBAR
022FE^⋾^^\niobar^R^mathrel^^SMALL CONTAINS WITH OVERBAR
022FF^⋿^^\bagmember^R^mathrel^^# \mathsf{E}, Z NOTATION BAG MEMBERSHIP
02300^⌀^\diameter^\diameter^N^mathord^mathabx^# \varnothing (amssymb), DIAMETER SIGN
02302^⌂^^\house^N^mathord^^HOUSE
02305^⌅^^\varbarwedge^B^mathbin^^# \barwedge (amssymb), PROJECTIVE (bar over small wedge) not nand
02306^⌆^^\vardoublebarwedge^B^mathbin^^# \doublebarwedge (amssymb), PERSPECTIVE (double bar over small wedge)
02308^⌈^\lceil^\lceil^O^mathopen^^LEFT CEILING
02309^⌉^\rceil^\rceil^C^mathclose^^RIGHT CEILING
0230A^⌊^\lfloor^\lfloor^O^mathopen^^LEFT FLOOR
0230B^⌋^\rfloor^\rfloor^C^mathclose^^RIGHT FLOOR
02310^⌐^\invneg^\invnot^N^mathord^wasysym^reverse not
02311^⌑^\wasylozenge^\sqlozenge^N^mathord^wasysym^SQUARE LOZENGE
02312^⌒^^\profline^^mathord^^profile of a line
02313^⌓^^\profsurf^^mathord^^profile of a surface
02317^⌗^^\viewdata^^mathord^^VIEWDATA SQUARE
02319^⌙^^\turnednot^N^mathord^^TURNED NOT SIGN
0231C^⌜^\ulcorner^\ulcorner^O^mathopen^amsfonts^upper left corner
0231D^⌝^\urcorner^\urcorner^C^mathclose^amsfonts^upper right corner
0231E^⌞^\llcorner^\llcorner^O^mathopen^amsfonts^lower left corner
0231F^⌟^\lrcorner^\lrcorner^C^mathclose^amsfonts^lower right corner
02320^⌠^^\inttop^G^mathord^^TOP HALF INTEGRAL
02321^⌡^^\intbottom^G^mathord^^BOTTOM HALF INTEGRAL
02322^⌢^\frown^\frown^R^mathrel^^# \smallFROWN, down curve
02323^⌣^\smile^\smile^R^mathrel^^# \smallSMILE, up curve
0232C^⌬^^\varhexagonlrbonds^^mathord^^six carbon ring, corner down, double bonds lower right etc
02332^⌲^^\conictaper^^mathord^^CONICAL TAPER
02336^⌶^^\topbot^N^mathord^^APL FUNCTIONAL SYMBOL I-BEAM, top and bottom
02337^⌷^^^^mathord^^APL FUNCTIONAL SYMBOL SQUISH QUAD
02338^⌸^^^^mathord^^APL FUNCTIONAL SYMBOL QUAD EQUAL
02339^⌹^\APLinv^^^mathord^wasysym^APL FUNCTIONAL SYMBOL QUAD DIVIDE
0233A^⌺^^^^mathord^^APL FUNCTIONAL SYMBOL QUAD DIAMOND
0233B^⌻^^^^mathord^^APL FUNCTIONAL SYMBOL QUAD JOT
0233C^⌼^^^^mathord^^# \APLcirc{\APLbox} (wasysym), APL FUNCTIONAL SYMBOL QUAD CIRCLE
0233D^⌽^^\obar^B^mathbin^^# \APLvert{\Circle} (wasysym), x \obar (stmaryrd), APL FUNCTIONAL SYMBOL CIRCLE STILE, circle with vertical bar
0233E^⌾^^^^mathord^^# \APLcirc{\Circle} (wasysym), APL FUNCTIONAL SYMBOL CIRCLE JOT
0233F^⌿^\notslash^\APLnotslash^R^mathrel^wasysym^APL FUNCTIONAL SYMBOL SLASH BAR, solidus, bar through
02340^⍀^\notbackslash^\APLnotbackslash^^mathord^wasysym^APL FUNCTIONAL SYMBOL BACKSLASH BAR
02341^⍁^^^^mathord^^APL FUNCTIONAL SYMBOL QUAD SLASH
02342^⍂^^^^mathord^^APL FUNCTIONAL SYMBOL QUAD BACKSLASH
02343^⍃^^^^mathord^^APL FUNCTIONAL SYMBOL QUAD LESS-THAN
02344^⍄^^^^mathord^^APL FUNCTIONAL SYMBOL QUAD GREATER-THAN
02345^⍅^^^^mathord^^APL FUNCTIONAL SYMBOL LEFTWARDS VANE
02346^⍆^^^^mathord^^APL FUNCTIONAL SYMBOL RIGHTWARDS VANE
02347^⍇^\APLleftarrowbox^^^mathord^wasysym^APL FUNCTIONAL SYMBOL QUAD LEFTWARDS ARROW
02348^⍈^\APLrightarrowbox^^^mathord^wasysym^APL FUNCTIONAL SYMBOL QUAD RIGHTWARDS ARROW
02349^⍉^^^^mathord^^APL FUNCTIONAL SYMBOL CIRCLE BACKSLASH
0234A^⍊^^^^mathord^^APL FUNCTIONAL SYMBOL DOWN TACK UNDERBAR
0234B^⍋^^^^mathord^^# \APLvert{\APLup} (wasysym), APL FUNCTIONAL SYMBOL DELTA STILE
0234C^⍌^^^^mathord^^APL FUNCTIONAL SYMBOL QUAD DOWN CARET
0234D^⍍^^^^mathord^^APL FUNCTIONAL SYMBOL QUAD DELTA
0234E^⍎^^^^mathord^^APL FUNCTIONAL SYMBOL DOWN TACK JOT
0234F^⍏^^^^mathord^^APL FUNCTIONAL SYMBOL UPWARDS VANE
02350^⍐^\APLuparrowbox^^^mathord^wasysym^APL FUNCTIONAL SYMBOL QUAD UPWARDS ARROW
02351^⍑^^^^mathord^^APL FUNCTIONAL SYMBOL UP TACK OVERBAR
02352^⍒^^^^mathord^wasysym^# \APLvert{\APLdown} (wasysym), APL FUNCTIONAL SYMBOL DEL STILE
02353^⍓^^\APLboxupcaret^^mathord^^APL FUNCTIONAL SYMBOL QUAD UP CARET
02354^⍔^^^^mathord^^APL FUNCTIONAL SYMBOL QUAD DEL
02355^⍕^^^^mathord^^APL FUNCTIONAL SYMBOL UP TACK JOT
02356^⍖^^^^mathord^^APL FUNCTIONAL SYMBOL DOWNWARDS VANE
02357^⍗^\APLdownarrowbox^^^mathord^wasysym^APL FUNCTIONAL SYMBOL QUAD DOWNWARDS ARROW
02358^⍘^^^^mathord^^APL FUNCTIONAL SYMBOL QUOTE UNDERBAR
02359^⍙^^^^mathord^^APL FUNCTIONAL SYMBOL DELTA UNDERBAR
0235A^⍚^^^^mathord^^APL FUNCTIONAL SYMBOL DIAMOND UNDERBAR
0235B^⍛^^^^mathord^^APL FUNCTIONAL SYMBOL JOT UNDERBAR
0235C^⍜^^^^mathord^^APL FUNCTIONAL SYMBOL CIRCLE UNDERBAR
0235D^⍝^\APLcomment^^^mathord^wasysym^APL FUNCTIONAL SYMBOL UP SHOE JOT
0235E^⍞^\APLinput^^^mathord^wasysym^APL FUNCTIONAL SYMBOL QUOTE QUAD
0235F^⍟^\APLlog^^^mathord^wasysym^APL FUNCTIONAL SYMBOL CIRCLE STAR
02360^⍠^^^^mathord^^APL FUNCTIONAL SYMBOL QUAD COLON
02361^⍡^^^^mathord^^APL FUNCTIONAL SYMBOL UP TACK DIAERESIS
02362^⍢^^^^mathord^^APL FUNCTIONAL SYMBOL DEL DIAERESIS
02363^⍣^^^^mathord^^APL FUNCTIONAL SYMBOL STAR DIAERESIS
02364^⍤^^^^mathord^^APL FUNCTIONAL SYMBOL JOT DIAERESIS
02365^⍥^^^^mathord^^APL FUNCTIONAL SYMBOL CIRCLE DIAERESIS
02366^⍦^^^^mathord^^APL FUNCTIONAL SYMBOL DOWN SHOE STILE
02367^⍧^^^^mathord^^APL FUNCTIONAL SYMBOL LEFT SHOE STILE
02368^⍨^^^^mathord^^APL FUNCTIONAL SYMBOL TILDE DIAERESIS
02369^⍩^^^^mathord^^APL FUNCTIONAL SYMBOL GREATER-THAN DIAERESIS
0236A^⍪^^^^mathord^^APL FUNCTIONAL SYMBOL COMMA BAR
0236B^⍫^^^^mathord^^# \APLnot{\APLdown} (wasysym), APL FUNCTIONAL SYMBOL DEL TILDE
0236C^⍬^^^^mathord^^APL FUNCTIONAL SYMBOL ZILDE
0236D^⍭^^^^mathord^^APL FUNCTIONAL SYMBOL STILE TILDE
0236E^⍮^^^^mathord^^APL FUNCTIONAL SYMBOL SEMICOLON UNDERBAR
0236F^⍯^^^^mathord^^APL FUNCTIONAL SYMBOL QUAD NOT EQUAL
02370^⍰^^\APLboxquestion^^mathord^^APL FUNCTIONAL SYMBOL QUAD QUESTION
02371^⍱^^^^mathord^^APL FUNCTIONAL SYMBOL DOWN CARET TILDE
02372^⍲^^^^mathord^^APL FUNCTIONAL SYMBOL UP CARET TILDE
02373^⍳^^^^mathord^^APL FUNCTIONAL SYMBOL IOTA
02374^⍴^^^^mathord^^APL FUNCTIONAL SYMBOL RHO
02375^⍵^^^^mathord^^APL FUNCTIONAL SYMBOL OMEGA
02376^⍶^^^^mathord^^APL FUNCTIONAL SYMBOL ALPHA UNDERBAR
02377^⍷^^^^mathord^^APL FUNCTIONAL SYMBOL EPSILON UNDERBAR
02378^⍸^^^^mathord^^APL FUNCTIONAL SYMBOL IOTA UNDERBAR
02379^⍹^^^^mathord^^APL FUNCTIONAL SYMBOL OMEGA UNDERBAR
0237C^⍼^^\rangledownzigzagarrow^^mathord^^RIGHT ANGLE WITH DOWNWARDS ZIGZAG ARROW
02394^⎔^^\hexagon^N^mathord^^horizontal benzene ring [hexagon flat open]
0239B^⎛^^\lparenuend^G^mathord^^LEFT PARENTHESIS UPPER HOOK
0239C^⎜^^\lparenextender^G^mathord^^LEFT PARENTHESIS EXTENSION
0239D^⎝^^\lparenlend^G^mathord^^LEFT PARENTHESIS LOWER HOOK
0239E^⎞^^\rparenuend^G^mathord^^RIGHT PARENTHESIS UPPER HOOK
0239F^⎟^^\rparenextender^G^mathord^^RIGHT PARENTHESIS EXTENSION
023A0^⎠^^\rparenlend^G^mathord^^RIGHT PARENTHESIS LOWER HOOK
023A1^⎡^^\lbrackuend^G^mathord^^LEFT SQUARE BRACKET UPPER CORNER
023A2^⎢^^\lbrackextender^G^mathord^^LEFT SQUARE BRACKET EXTENSION
023A3^⎣^^\lbracklend^G^mathord^^LEFT SQUARE BRACKET LOWER CORNER
023A4^⎤^^\rbrackuend^G^mathord^^RIGHT SQUARE BRACKET UPPER CORNER
023A5^⎥^^\rbrackextender^G^mathord^^RIGHT SQUARE BRACKET EXTENSION
023A6^⎦^^\rbracklend^G^mathord^^RIGHT SQUARE BRACKET LOWER CORNER
023A7^⎧^^\lbraceuend^G^mathord^^LEFT CURLY BRACKET UPPER HOOK
023A8^⎨^^\lbracemid^G^mathord^^LEFT CURLY BRACKET MIDDLE PIECE
023A9^⎩^^\lbracelend^G^mathord^^LEFT CURLY BRACKET LOWER HOOK
023AA^⎪^^\vbraceextender^G^mathord^^CURLY BRACKET EXTENSION
023AB^⎫^^\rbraceuend^G^mathord^^RIGHT CURLY BRACKET UPPER HOOK
023AC^⎬^^\rbracemid^G^mathord^^RIGHT CURLY BRACKET MIDDLE PIECE
023AD^⎭^^\rbracelend^G^mathord^^RIGHT CURLY BRACKET LOWER HOOK
023AE^⎮^^\intextender^G^mathord^^INTEGRAL EXTENSION
023AF^⎯^^\harrowextender^G^mathord^^HORIZONTAL LINE EXTENSION (used to extend arrows)
023B0^⎰^^\lmoustache^R^mathord^^? \lmoustache, UPPER LEFT OR LOWER RIGHT CURLY BRACKET SECTION
023B1^⎱^^\rmoustache^R^mathord^^? \rmoustache, UPPER RIGHT OR LOWER LEFT CURLY BRACKET SECTION
023B2^⎲^^\sumtop^G^mathord^^SUMMATION TOP
023B3^⎳^^\sumbottom^G^mathord^^SUMMATION BOTTOM
023B4^⎴^^\overbracket^N^mathover^^TOP SQUARE BRACKET
023B5^⎵^^\underbracket^N^mathunder^^BOTTOM SQUARE BRACKET
023B6^⎶^^\bbrktbrk^N^mathord^^BOTTOM SQUARE BRACKET OVER TOP SQUARE BRACKET
023B7^⎷^^\sqrtbottom^G^mathord^^RADICAL SYMBOL BOTTOM
023B8^⎸^^\lvboxline^^mathord^^LEFT VERTICAL BOX LINE
023B9^⎹^^\rvboxline^^mathord^^RIGHT VERTICAL BOX LINE
023CE^⏎^^\varcarriagereturn^^mathord^^RETURN SYMBOL
023D0^⏐^^^G^mathord^^VERTICAL LINE EXTENSION (VERTICAL LINE EXTENSION)
023DC^⏜^\overparen^\overparen^N^mathover^wrisym^= \wideparen (yhmath mathabx fourier), TOP PARENTHESIS (mathematical use)
023DD^⏝^\underparen^\underparen^N^mathunder^wrisym^BOTTOM PARENTHESIS (mathematical use)
023DE^⏞^\overbrace^\overbrace^N^mathover^^TOP CURLY BRACKET (mathematical use)
023DF^⏟^\underbrace^\underbrace^N^mathunder^^BOTTOM CURLY BRACKET (mathematical use)
023E0^⏠^^\obrbrak^N^mathord^^TOP TORTOISE SHELL BRACKET (mathematical use)
023E1^⏡^^\ubrbrak^N^mathord^^BOTTOM TORTOISE SHELL BRACKET (mathematical use)
023E2^⏢^^\trapezium^N^mathord^^WHITE TRAPEZIUM
023E3^⏣^^\benzenr^N^mathord^^BENZENE RING WITH CIRCLE
023E4^⏤^^\strns^N^mathord^^STRAIGHTNESS
023E5^⏥^^\fltns^N^mathord^^FLATNESS
023E6^⏦^^\accurrent^N^mathord^^# \AC (wasysym), AC CURRENT
023E7^⏧^^\elinters^N^mathord^^ELECTRICAL INTERSECTION
024C8^Ⓢ^^^N^mathord^^oS capital S in circle
02506^┆^^\bdtriplevdash^^mathord^^doubly broken vert
02580^▀^^\blockuphalf^^mathord^^UPPER HALF BLOCK
02584^▄^^\blocklowhalf^^mathord^^LOWER HALF BLOCK
02588^█^^\blockfull^^mathord^^FULL BLOCK
0258C^▌^^\blocklefthalf^^mathord^^LEFT HALF BLOCK
02590^▐^^\blockrighthalf^^mathord^^RIGHT HALF BLOCK
02591^░^^\blockqtrshaded^^mathord^^25\% shaded block
02592^▒^^\blockhalfshaded^^mathord^^50\% shaded block
02593^▓^^\blockthreeqtrshaded^^mathord^^75\% shaded block
025A0^■^^\mdlgblksquare^N^mathord^^square, filled
025A1^□^^\mdlgwhtsquare^N^mathord^^square, open
025A2^▢^^\squoval^^mathord^^WHITE SQUARE WITH ROUNDED CORNERS
025A3^▣^^\blackinwhitesquare^^mathord^^WHITE SQUARE CONTAINING BLACK SMALL SQUARE
025A4^▤^^\squarehfill^^mathord^^square, horizontal rule filled
025A5^▥^^\squarevfill^^mathord^^square, vertical rule filled
025A6^▦^^\squarehvfill^^mathord^^SQUARE WITH ORTHOGONAL CROSSHATCH FILL
025A7^▧^^\squarenwsefill^^mathord^^square, nw-to-se rule filled
025A8^▨^^\squareneswfill^^mathord^^square, ne-to-sw rule filled
025A9^▩^^\squarecrossfill^^mathord^^SQUARE WITH DIAGONAL CROSSHATCH FILL
025AA^▪^^\smblksquare^N^mathord^^sq bullet, filled
025AB^▫^^\smwhtsquare^N^mathord^^WHITE SMALL SQUARE
025AC^▬^^\hrectangleblack^^mathord^^BLACK RECTANGLE
025AD^▭^^\hrectangle^N^mathord^^horizontal rectangle, open
025AE^▮^^\vrectangleblack^N^mathord^^BLACK VERTICAL RECTANGLE
025AF^▯^^\vrectangle^N^mathord^^rectangle, white (vertical)
025B0^▰^^\parallelogramblack^^mathord^^BLACK PARALLELOGRAM
025B1^▱^^\parallelogram^N^mathord^^parallelogram, open
025B2^▲^^\bigblacktriangleup^B^mathord^^BLACK UP-POINTING TRIANGLE
025B3^△^\bigtriangleup^\bigtriangleup^B^mathbin^-stmaryrd^= \triangle (amsfonts), # \vartriangle (amssymb), big up triangle, open
025B4^▴^\blacktriangleup^\blacktriangle^B^mathbin^mathabx^up triangle, filled
025B5^▵^\smalltriangleup^\vartriangle^B^mathbin^mathabx^# \vartriangle (amssymb), small up triangle, open
025B6^▶^\RHD^\blacktriangleright^B^mathbin^wasysym^= \blacktriangleright (fourier -mathabx), (large) right triangle, filled
025B7^▷^\rhd^\triangleright^B^mathbin^amssymb wasysym^= \rres (oz), = \RightTriangle (wrisym), (large) right triangle, open; z notation range restriction
025B8^▸^\blacktriangleright^\smallblacktriangleright^B^mathbin^mathabx -fourier^right triangle, filled
025B9^▹^\smalltriangleright^\smalltriangleright^B^mathbin^mathabx^# \triangleright, x \triangleright (mathabx), right triangle, open
025BA^►^^\blackpointerright^^mathord^^BLACK RIGHT-POINTING POINTER
025BB^▻^^\whitepointerright^^mathord^^# \triangleright (mathabx), WHITE RIGHT-POINTING POINTER
025BC^▼^^\bigblacktriangledown^B^mathord^^big down triangle, filled
025BD^▽^\bigtriangledown^\bigtriangledown^B^mathbin^-stmaryrd^big down triangle, open
025BE^▾^\blacktriangledown^\blacktriangledown^B^mathbin^mathabx^BLACK DOWN-POINTING SMALL TRIANGLE
025BF^▿^\smalltriangledown^\triangledown^B^mathbin^mathabx^# \triangledown (amssymb), WHITE DOWN-POINTING SMALL TRIANGLE
025C0^◀^\LHD^\blacktriangleleft^B^mathbin^wasysym^= \blacktriangleleft (fourier -mathabx), (large) left triangle, filled
025C1^◁^\lhd^\triangleleft^B^mathbin^amssymb wasysym^= \dres (oz), = \LeftTriangle (wrisym), (large) left triangle, open; z notation domain restriction
025C2^◂^\blacktriangleleft^\smallblacktriangleleft^B^mathbin^mathabx -fourier^left triangle, filled
025C3^◃^\smalltriangleleft^\smalltriangleleft^B^mathbin^mathabx^# \triangleleft, x \triangleleft (mathabx), left triangle, open
025C4^◄^^\blackpointerleft^B^mathord^^BLACK LEFT-POINTING POINTER
025C5^◅^^\whitepointerleft^B^mathord^^# \triangleleft (mathabx), WHITE LEFT-POINTING POINTER
025C6^◆^\Diamondblack^\mdlgblkdiamond^N^mathord^txfonts^BLACK DIAMOND
025C7^◇^\Diamond^\mdlgwhtdiamond^N^mathord^amssymb^WHITE DIAMOND; diamond, open
025C8^◈^^\blackinwhitediamond^N^mathord^^WHITE DIAMOND CONTAINING BLACK SMALL DIAMOND
025C9^◉^^\fisheye^N^mathord^^FISHEYE
025CA^◊^\lozenge^\mdlgwhtlozenge^B^mathord^amssymb^LOZENGE or total mark
025CB^○^\Circle^\mdlgwhtcircle^B^mathbin^wasysym^medium large circle
025CC^◌^^\dottedcircle^^mathord^^DOTTED CIRCLE
025CD^◍^^\circlevertfill^^mathord^^CIRCLE WITH VERTICAL FILL
025CE^◎^^\bullseye^N^mathord^^# \circledcirc (amssymb), BULLSEYE
025CF^●^\CIRCLE^\mdlgblkcircle^N^mathord^wasysym^circle, filled
025D0^◐^\LEFTcircle^\circlelefthalfblack^^mathord^wasysym^circle, filled left half [harvey ball]
025D1^◑^\RIGHTcircle^\circlerighthalfblack^^mathord^wasysym^circle, filled right half
025D2^◒^^\circlebottomhalfblack^^mathord^^circle, filled bottom half
025D3^◓^^\circletophalfblack^^mathord^^circle, filled top half
025D4^◔^^\circleurquadblack^^mathord^^CIRCLE WITH UPPER RIGHT QUADRANT BLACK
025D5^◕^^\blackcircleulquadwhite^^mathord^^CIRCLE WITH ALL BUT UPPER LEFT QUADRANT BLACK
025D6^◖^\LEFTCIRCLE^\blacklefthalfcircle^N^mathord^wasysym^LEFT HALF BLACK CIRCLE
025D7^◗^\RIGHTCIRCLE^\blackrighthalfcircle^N^mathord^wasysym^RIGHT HALF BLACK CIRCLE
025D8^◘^^\inversebullet^^mathord^^INVERSE BULLET
025D9^◙^^\inversewhitecircle^^mathord^^INVERSE WHITE CIRCLE
025DA^◚^^\invwhiteupperhalfcircle^^mathord^^UPPER HALF INVERSE WHITE CIRCLE
025DB^◛^^\invwhitelowerhalfcircle^^mathord^^LOWER HALF INVERSE WHITE CIRCLE
025DC^◜^^\ularc^^mathord^^UPPER LEFT QUADRANT CIRCULAR ARC
025DD^◝^^\urarc^^mathord^^UPPER RIGHT QUADRANT CIRCULAR ARC
025DE^◞^^\lrarc^^mathord^^LOWER RIGHT QUADRANT CIRCULAR ARC
025DF^◟^^\llarc^^mathord^^LOWER LEFT QUADRANT CIRCULAR ARC
025E0^◠^^\topsemicircle^^mathord^^UPPER HALF CIRCLE
025E1^◡^^\botsemicircle^^mathord^^LOWER HALF CIRCLE
025E2^◢^^\lrblacktriangle^N^mathord^^lower right triangle, filled
025E3^◣^^\llblacktriangle^N^mathord^^lower left triangle, filled
025E4^◤^^\ulblacktriangle^N^mathord^^upper left triangle, filled
025E5^◥^^\urblacktriangle^N^mathord^^upper right triangle, filled
025E6^◦^^\smwhtcircle^B^mathord^^WHITE BULLET
025E7^◧^^\squareleftblack^^mathord^^square, filled left half
025E8^◨^^\squarerightblack^^mathord^^square, filled right half
025E9^◩^^\squareulblack^^mathord^^square, filled top left corner
025EA^◪^^\squarelrblack^^mathord^^square, filled bottom right corner
025EB^◫^\boxbar^\boxbar^B^mathbin^stmaryrd txfonts^vertical bar in box
025EC^◬^^\trianglecdot^B^mathord^^triangle with centered dot
025ED^◭^^\triangleleftblack^^mathord^^UP-POINTING TRIANGLE WITH LEFT HALF BLACK
025EE^◮^^\trianglerightblack^^mathord^^UP-POINTING TRIANGLE WITH RIGHT HALF BLACK
025EF^◯^^\lgwhtcircle^N^mathord^^LARGE CIRCLE
025F0^◰^^\squareulquad^^mathord^^WHITE SQUARE WITH UPPER LEFT QUADRANT
025F1^◱^^\squarellquad^^mathord^^WHITE SQUARE WITH LOWER LEFT QUADRANT
025F2^◲^^\squarelrquad^^mathord^^WHITE SQUARE WITH LOWER RIGHT QUADRANT
025F3^◳^^\squareurquad^^mathord^^WHITE SQUARE WITH UPPER RIGHT QUADRANT
025F4^◴^^\circleulquad^^mathord^^WHITE CIRCLE WITH UPPER LEFT QUADRANT
025F5^◵^^\circlellquad^^mathord^^WHITE CIRCLE WITH LOWER LEFT QUADRANT
025F6^◶^^\circlelrquad^^mathord^^WHITE CIRCLE WITH LOWER RIGHT QUADRANT
025F7^◷^^\circleurquad^^mathord^^WHITE CIRCLE WITH UPPER RIGHT QUADRANT
025F8^◸^^\ultriangle^B^mathord^^UPPER LEFT TRIANGLE
025F9^◹^^\urtriangle^B^mathord^^UPPER RIGHT TRIANGLE
025FA^◺^^\lltriangle^B^mathord^^LOWER LEFT TRIANGLE
025FB^◻^\square^\mdwhtsquare^B^mathord^amssymb -fourier^WHITE MEDIUM SQUARE
025FC^◼^\blacksquare^\mdblksquare^B^mathord^amssymb -fourier^BLACK MEDIUM SQUARE
025FD^◽^^\mdsmwhtsquare^B^mathord^^WHITE MEDIUM SMALL SQUARE
025FE^◾^^\mdsmblksquare^B^mathord^^BLACK MEDIUM SMALL SQUARE
025FF^◿^^\lrtriangle^B^mathord^^LOWER RIGHT TRIANGLE
02605^★^\bigstar^\bigstar^B^mathord^amssymb^star, filled
02606^☆^^\bigwhitestar^B^mathord^^star, open
02609^☉^\Sun^\astrosun^N^mathord^mathabx^SUN
0260C^☌^^^N^mathord^wasysym^text \CONJUNCTION (wasysym), CONJUNCTION
02610^☐^\Square^^^mathord^wasysym^BALLOT BOX
02611^☑^\CheckedBox^^^mathord^wasysym^t \Checkedbox (marvosym), BALLOT BOX WITH CHECK
02612^☒^\XBox^^N^mathord^wasysym^t \Crossedbox (marvosym), BALLOT BOX WITH X
02615^☕^\steaming^^^mathord^arevmath^HOT BEVERAGE
0261E^☞^\pointright^^^mathord^arevmath^WHITE RIGHT POINTING INDEX
02620^☠^\skull^^^mathord^arevmath^SKULL AND CROSSBONES
02621^☡^^\danger^^mathord^^CAUTION SIGN, dangerous bend
02622^☢^\radiation^^^mathord^arevmath^RADIOACTIVE SIGN
02623^☣^\biohazard^^^mathord^arevmath^BIOHAZARD SIGN
0262F^☯^\yinyang^^^mathord^arevmath^YIN YANG
02639^☹^\frownie^^^mathord^wasysym^= \sadface (arevmath), WHITE FROWNING FACE
0263A^☺^\smiley^^^mathord^wasysym^= \smileface (arevmath), WHITE SMILING FACE
0263B^☻^\blacksmiley^\blacksmiley^^mathord^wasysym^= \invsmileface (arevmath), BLACK SMILING FACE
0263C^☼^\sun^\sun^^mathord^wasysym^WHITE SUN WITH RAYS
0263D^☽^\rightmoon^\rightmoon^N^mathord^wasysym mathabx^FIRST QUARTER MOON
0263E^☾^\leftmoon^\leftmoon^N^mathord^wasysym mathabx^LAST QUARTER MOON
0263F^☿^\mercury^^N^mathord^wasysym^= \Mercury (mathabx), MERCURY
02640^♀^\female^\female^N^mathord^wasysym^= \Venus (mathabx), = \girl (mathabx), venus, female
02641^♁^\earth^^N^mathord^wasysym^= \varEarth (mathabx), EARTH
02642^♂^\male^\male^N^mathord^wasysym^= \Mars (mathabx), = \boy (mathabx), mars, male
02643^♃^\jupiter^^N^mathord^wasysym^= \Jupiter (mathabx), JUPITER
02644^♄^\saturn^^N^mathord^wasysym^= \Saturn (mathabx), SATURN
02645^♅^\uranus^^^mathord^wasysym^= \Uranus (mathabx), URANUS
02646^♆^\neptune^^N^mathord^wasysym^= \Neptune (mathabx), NEPTUNE
02647^♇^\pluto^^N^mathord^wasysym^= \Pluto (mathabx), PLUTO
02648^♈^\aries^^N^mathord^wasysym^= \Aries (mathabx), ARIES
02649^♉^\taurus^^N^mathord^wasysym^= \Taurus (mathabx), TAURUS
0264A^♊^\gemini^^^mathord^wasysym^= \Gemini (mathabx), GEMINI
0264B^♋^\cancer^^^mathord^wasysym^CANCER
0264C^♌^\leo^^^mathord^wasysym^= \Leo (mathabx), LEO
0264D^♍^\virgo^^^mathord^wasysym^VIRGO
0264E^♎^\libra^^^mathord^wasysym^= \Libra (mathabx), LIBRA
0264F^♏^\scorpio^^^mathord^wasysym^= \Scorpio (mathabx), SCORPIUS
02650^♐^\sagittarius^^^mathord^wasysym^SAGITTARIUS
02651^♑^\capricornus^^^mathord^wasysym^CAPRICORN
02652^♒^\aquarius^^^mathord^wasysym^AQUARIUS
02653^♓^\pisces^^^mathord^wasysym^PISCES
02660^♠^\spadesuit^\spadesuit^N^mathord^^spades suit symbol
02661^♡^\heartsuit^\heartsuit^N^mathord^^heart suit symbol
02662^♢^\diamondsuit^\diamondsuit^N^mathord^^diamond suit symbol
02663^♣^\clubsuit^\clubsuit^N^mathord^^club suit symbol
02664^♤^\varspadesuit^\varspadesuit^N^mathord^txfonts^= \varspade (arevmath), spade, white (card suit)
02665^♥^\varheartsuit^\varheartsuit^N^mathord^txfonts^= \varheart (arevmath), filled heart (card suit)
02666^♦^\vardiamondsuit^\vardiamondsuit^N^mathord^txfonts^= \vardiamond (arevmath), filled diamond (card suit)
02667^♧^\varclubsuit^\varclubsuit^N^mathord^txfonts^= \varclub (arevmath), club, white (card suit)
02669^♩^\quarternote^\quarternote^N^mathord^arevmath wasysym^music note (sung text sign)
0266A^♪^\eighthnote^\eighthnote^^mathord^arevmath^EIGHTH NOTE
0266B^♫^\twonotes^\twonotes^^mathord^wasysym^BEAMED EIGHTH NOTES
0266C^♬^\sixteenthnote^^^mathord^arevmath^BEAMED SIXTEENTH NOTES
0266D^♭^\flat^\flat^N^mathord^^musical flat
0266E^♮^\natural^\natural^N^mathord^^music natural
0266F^♯^\sharp^\sharp^N^mathord^^# \# (oz), musical sharp, z notation infix bag count
0267B^♻^\recycle^^^mathord^arevmath^BLACK UNIVERSAL RECYCLING SYMBOL
0267E^♾^^\acidfree^^mathord^^PERMANENT PAPER SIGN
02680^⚀^^\dicei^N^mathord^^DIE FACE-1
02681^⚁^^\diceii^N^mathord^^DIE FACE-2
02682^⚂^^\diceiii^N^mathord^^DIE FACE-3
02683^⚃^^\diceiv^N^mathord^^DIE FACE-4
02684^⚄^^\dicev^N^mathord^^DIE FACE-5
02685^⚅^^\dicevi^N^mathord^^DIE FACE-6
02686^⚆^^\circledrightdot^N^mathord^^WHITE CIRCLE WITH DOT RIGHT
02687^⚇^^\circledtwodots^N^mathord^^WHITE CIRCLE WITH TWO DOTS
02688^⚈^^\blackcircledrightdot^N^mathord^^BLACK CIRCLE WITH WHITE DOT RIGHT
02689^⚉^^\blackcircledtwodots^N^mathord^^BLACK CIRCLE WITH TWO WHITE DOTS
02693^⚓^\anchor^^^mathord^arevmath^ANCHOR
02694^⚔^\swords^^^mathord^arevmath^CROSSED SWORDS
026A0^⚠^\warning^^^mathord^arevmath^WARNING SIGN
026A5^⚥^^\Hermaphrodite^^mathord^^MALE AND FEMALE SIGN
026AA^⚪^\medcirc^\mdwhtcircle^N^mathord^txfonts^MEDIUM WHITE CIRCLE
026AB^⚫^\medbullet^\mdblkcircle^N^mathord^txfonts^MEDIUM BLACK CIRCLE
026AC^⚬^^\mdsmwhtcircle^N^mathord^^MEDIUM SMALL WHITE CIRCLE
026B2^⚲^^\neuter^N^mathord^^NEUTER
0270E^✎^\pencil^^^mathord^arevmath^LOWER RIGHT PENCIL
02713^✓^\checkmark^\checkmark^N^mathord^amsfonts^= \ballotcheck (arevmath), tick, CHECK MARK
02717^✗^\ballotx^^^mathord^arevmath^BALLOT X
02720^✠^\maltese^\maltese^N^mathord^amsfonts^MALTESE CROSS
0272A^✪^^\circledstar^N^mathord^^CIRCLED WHITE STAR
02736^✶^^\varstar^N^mathord^^SIX POINTED BLACK STAR
0273D^✽^^\dingasterisk^^mathord^^HEAVY TEARDROP-SPOKED ASTERISK
02772^❲^^\lbrbrak^O^mathopen^^LIGHT LEFT TORTOISE SHELL BRACKET ORNAMENT
02773^❳^^\rbrbrak^C^mathclose^^LIGHT RIGHT TORTOISE SHELL BRACKET ORNAMENT
0279B^➛^^\draftingarrow^^mathord^^right arrow with bold head (drafting)
027A2^➢^\arrowbullet^^^mathord^arevmath^THREE-D TOP-LIGHTED RIGHTWARDS ARROWHEAD
027C0^⟀^^\threedangle^N^mathord^^THREE DIMENSIONAL ANGLE
027C1^⟁^^\whiteinwhitetriangle^N^mathord^^WHITE TRIANGLE CONTAINING SMALL WHITE TRIANGLE
027C2^⟂^\perp^\perp^R^mathrel^^PERPENDICULAR
027C3^⟃^^\subsetcirc^R^mathord^^OPEN SUBSET
027C4^⟄^^\supsetcirc^R^mathord^^OPEN SUPERSET
027C5^⟅^\Lbag^\lbag^R^mathopen^stmaryrd txfonts^= \lbag (stmaryrd -oz), LEFT S-SHAPED BAG DELIMITER
027C6^⟆^\Rbag^\rbag^R^mathclose^stmaryrd txfonts^= \rbag (stmaryrd -oz), RIGHT S-SHAPED BAG DELIMITER
027C7^⟇^^\veedot^R^mathbin^^OR WITH DOT INSIDE
027C8^⟈^^\bsolhsub^R^mathrel^^REVERSE SOLIDUS PRECEDING SUBSET
027C9^⟉^^\suphsol^R^mathrel^^SUPERSET PRECEDING SOLIDUS
027CC^⟌^^\longdivision^^mathopen^^LONG DIVISION
027D0^⟐^\Diamonddot^\diamondcdot^N^mathord^txfonts^WHITE DIAMOND WITH CENTRED DOT
027D1^⟑^^\wedgedot^B^mathbin^^AND WITH DOT
027D2^⟒^^\upin^R^mathrel^^ELEMENT OF OPENING UPWARDS
027D3^⟓^^\pullback^R^mathrel^^LOWER RIGHT CORNER WITH DOT
027D4^⟔^^\pushout^R^mathrel^^UPPER LEFT CORNER WITH DOT
027D5^⟕^^\leftouterjoin^L^mathop^^LEFT OUTER JOIN
027D6^⟖^^\rightouterjoin^L^mathop^^RIGHT OUTER JOIN
027D7^⟗^^\fullouterjoin^L^mathop^^FULL OUTER JOIN
027D8^⟘^^\bigbot^L^mathop^^LARGE UP TACK
027D9^⟙^^\bigtop^L^mathop^^LARGE DOWN TACK
027DA^⟚^^\DashVDash^R^mathrel^^LEFT AND RIGHT DOUBLE TURNSTILE
027DB^⟛^^\dashVdash^R^mathrel^^LEFT AND RIGHT TACK
027DC^⟜^\multimapinv^\multimapinv^R^mathrel^txfonts^LEFT MULTIMAP
027DD^⟝^^\vlongdash^R^mathrel^^long left tack
027DE^⟞^^\longdashv^R^mathrel^^long right tack
027DF^⟟^^\cirbot^R^mathrel^^UP TACK WITH CIRCLE ABOVE
027E0^⟠^^\lozengeminus^B^mathbin^^LOZENGE DIVIDED BY HORIZONTAL RULE
027E1^⟡^^\concavediamond^B^mathbin^^WHITE CONCAVE-SIDED DIAMOND
027E2^⟢^^\concavediamondtickleft^B^mathbin^^WHITE CONCAVE-SIDED DIAMOND WITH LEFTWARDS TICK
027E3^⟣^^\concavediamondtickright^B^mathbin^^WHITE CONCAVE-SIDED DIAMOND WITH RIGHTWARDS TICK
027E4^⟤^^\whitesquaretickleft^B^mathbin^^WHITE SQUARE WITH LEFTWARDS TICK
027E5^⟥^^\whitesquaretickright^B^mathbin^^WHITE SQUARE WITH RIGHTWARDS TICK
027E6^⟦^\llbracket^\lBrack^O^mathopen^stmaryrd wrisym kpfonts fourier^= \Lbrack (mathbbol), = \lbag (oz -stmaryrd), MATHEMATICAL LEFT WHITE SQUARE BRACKET
027E7^⟧^\rrbracket^\rBrack^C^mathclose^stmaryrd wrisym kpfonts fourier^= \Rbrack (mathbbol), = \rbag (oz -stmaryrd), MATHEMATICAL RIGHT WHITE SQUARE BRACKET
027E8^⟨^\langle^\langle^O^mathopen^^MATHEMATICAL LEFT ANGLE BRACKET
027E9^⟩^\rangle^\rangle^C^mathclose^^MATHEMATICAL RIGHT ANGLE BRACKET
027EA^⟪^\lang^\lAngle^O^mathopen^oz^MATHEMATICAL LEFT DOUBLE ANGLE BRACKET, z notation left chevron bracket
027EB^⟫^\rang^\rAngle^C^mathclose^oz^MATHEMATICAL RIGHT DOUBLE ANGLE BRACKET, z notation right chevron bracket
027EC^⟬^^\Lbrbrak^O^mathopen^^MATHEMATICAL LEFT WHITE TORTOISE SHELL BRACKET
027ED^⟭^^\Rbrbrak^C^mathclose^^MATHEMATICAL RIGHT WHITE TORTOISE SHELL BRACKET
027EE^⟮^\lgroup^^O^mathopen^^MATHEMATICAL LEFT FLATTENED PARENTHESIS
027EF^⟯^\rgroup^^C^mathclose^^MATHEMATICAL RIGHT FLATTENED PARENTHESIS
027F0^⟰^^\UUparrow^R^mathrel^^UPWARDS QUADRUPLE ARROW
027F1^⟱^^\DDownarrow^R^mathrel^^DOWNWARDS QUADRUPLE ARROW
027F2^⟲^^\acwgapcirclearrow^R^mathrel^^ANTICLOCKWISE GAPPED CIRCLE ARROW
027F3^⟳^^\cwgapcirclearrow^R^mathrel^^CLOCKWISE GAPPED CIRCLE ARROW
027F4^⟴^^\rightarrowonoplus^R^mathrel^^RIGHT ARROW WITH CIRCLED PLUS
027F5^⟵^\longleftarrow^\longleftarrow^R^mathrel^^LONG LEFTWARDS ARROW
027F6^⟶^\longrightarrow^\longrightarrow^R^mathrel^^LONG RIGHTWARDS ARROW
027F7^⟷^\longleftrightarrow^\longleftrightarrow^R^mathrel^^LONG LEFT RIGHT ARROW
027F8^⟸^\Longleftarrow^\Longleftarrow^R^mathrel^^= \impliedby (amsmath), LONG LEFTWARDS DOUBLE ARROW
027F9^⟹^\Longrightarrow^\Longrightarrow^R^mathrel^^= \implies (amsmath), LONG RIGHTWARDS DOUBLE ARROW
027FA^⟺^\Longleftrightarrow^\Longleftrightarrow^R^mathrel^^= \iff (oz), LONG LEFT RIGHT DOUBLE ARROW
027FB^⟻^\longmapsfrom^\longmapsfrom^R^mathrel^stmaryrd^= \longmappedfrom (kpfonts), LONG LEFTWARDS ARROW FROM BAR
027FC^⟼^\longmapsto^\longmapsto^R^mathrel^^LONG RIGHTWARDS ARROW FROM BAR
027FD^⟽^\Longmapsfrom^\Longmapsfrom^R^mathrel^stmaryrd^= \Longmappedfrom (kpfonts), LONG LEFTWARDS DOUBLE ARROW FROM BAR
027FE^⟾^\Longmapsto^\Longmapsto^R^mathrel^stmaryrd^LONG RIGHTWARDS DOUBLE ARROW FROM BAR
027FF^⟿^^\longrightsquigarrow^R^mathrel^^LONG RIGHTWARDS SQUIGGLE ARROW
02900^⤀^\psur^\nvtwoheadrightarrow^R^mathrel^oz^= \psurj (oz), RIGHTWARDS TWO-HEADED ARROW WITH VERTICAL STROKE, z notation partial surjection
02901^⤁^^\nVtwoheadrightarrow^R^mathrel^^RIGHTWARDS TWO-HEADED ARROW WITH DOUBLE VERTICAL STROKE, z notation finite surjection
02902^⤂^^\nvLeftarrow^R^mathrel^^LEFTWARDS DOUBLE ARROW WITH VERTICAL STROKE
02903^⤃^^\nvRightarrow^R^mathrel^^RIGHTWARDS DOUBLE ARROW WITH VERTICAL STROKE
02904^⤄^^\nvLeftrightarrow^R^mathrel^^LEFT RIGHT DOUBLE ARROW WITH VERTICAL STROKE
02905^⤅^^\twoheadmapsto^R^mathrel^^RIGHTWARDS TWO-HEADED ARROW FROM BAR
02906^⤆^\Mapsfrom^\Mapsfrom^R^mathrel^stmaryrd^= \Mappedfrom (kpfonts), LEFTWARDS DOUBLE ARROW FROM BAR
02907^⤇^\Mapsto^\Mapsto^R^mathrel^stmaryrd^RIGHTWARDS DOUBLE ARROW FROM BAR
02908^⤈^^\downarrowbarred^R^mathrel^^DOWNWARDS ARROW WITH HORIZONTAL STROKE
02909^⤉^^\uparrowbarred^R^mathrel^^UPWARDS ARROW WITH HORIZONTAL STROKE
0290A^⤊^^\Uuparrow^R^mathrel^^UPWARDS TRIPLE ARROW
0290B^⤋^^\Ddownarrow^R^mathrel^^DOWNWARDS TRIPLE ARROW
0290C^⤌^^\leftbkarrow^R^mathrel^^LEFTWARDS DOUBLE DASH ARROW
0290D^⤍^^\rightbkarrow^R^mathrel^^RIGHTWARDS DOUBLE DASH ARROW
0290E^⤎^^\leftdbkarrow^R^mathrel^^LEFTWARDS TRIPLE DASH ARROW
0290F^⤏^^\dbkarow^R^mathrel^^RIGHTWARDS TRIPLE DASH ARROW
02910^⤐^^\drbkarow^R^mathrel^^RIGHTWARDS TWO-HEADED TRIPLE DASH ARROW
02911^⤑^^\rightdotarrow^R^mathrel^^RIGHTWARDS ARROW WITH DOTTED STEM
02912^⤒^\UpArrowBar^\baruparrow^R^mathrel^wrisym^UPWARDS ARROW TO BAR
02913^⤓^\DownArrowBar^\downarrowbar^R^mathrel^wrisym^DOWNWARDS ARROW TO BAR
02914^⤔^\pinj^\nvrightarrowtail^R^mathrel^oz^RIGHTWARDS ARROW WITH TAIL WITH VERTICAL STROKE, z notation partial injection
02915^⤕^\finj^\nVrightarrowtail^R^mathrel^oz^RIGHTWARDS ARROW WITH TAIL WITH DOUBLE VERTICAL STROKE, z notation finite injection
02916^⤖^\bij^\twoheadrightarrowtail^R^mathrel^oz^RIGHTWARDS TWO-HEADED ARROW WITH TAIL, z notation bijection
02917^⤗^^\nvtwoheadrightarrowtail^R^mathrel^^RIGHTWARDS TWO-HEADED ARROW WITH TAIL WITH VERTICAL STROKE, z notation surjective injection
02918^⤘^^\nVtwoheadrightarrowtail^R^mathrel^^RIGHTWARDS TWO-HEADED ARROW WITH TAIL WITH DOUBLE VERTICAL STROKE, z notation finite surjective injection
02919^⤙^^\lefttail^R^mathrel^^LEFTWARDS ARROW-TAIL
0291A^⤚^^\righttail^R^mathrel^^RIGHTWARDS ARROW-TAIL
0291B^⤛^^\leftdbltail^R^mathrel^^LEFTWARDS DOUBLE ARROW-TAIL
0291C^⤜^^\rightdbltail^R^mathrel^^RIGHTWARDS DOUBLE ARROW-TAIL
0291D^⤝^^\diamondleftarrow^R^mathrel^^LEFTWARDS ARROW TO BLACK DIAMOND
0291E^⤞^^\rightarrowdiamond^R^mathrel^^RIGHTWARDS ARROW TO BLACK DIAMOND
0291F^⤟^^\diamondleftarrowbar^R^mathrel^^LEFTWARDS ARROW FROM BAR TO BLACK DIAMOND
02920^⤠^^\barrightarrowdiamond^R^mathrel^^RIGHTWARDS ARROW FROM BAR TO BLACK DIAMOND
02921^⤡^^\nwsearrow^R^mathrel^^NORTH WEST AND SOUTH EAST ARROW
02922^⤢^^\neswarrow^R^mathrel^^NORTH EAST AND SOUTH WEST ARROW
02923^⤣^^\hknwarrow^R^mathrel^^NORTH WEST ARROW WITH HOOK
02924^⤤^^\hknearrow^R^mathrel^^NORTH EAST ARROW WITH HOOK
02925^⤥^^\hksearow^R^mathrel^^SOUTH EAST ARROW WITH HOOK
02926^⤦^^\hkswarow^R^mathrel^^SOUTH WEST ARROW WITH HOOK
02927^⤧^^\tona^R^mathrel^^NORTH WEST ARROW AND NORTH EAST ARROW
02928^⤨^^\toea^R^mathrel^^NORTH EAST ARROW AND SOUTH EAST ARROW
02929^⤩^^\tosa^R^mathrel^^SOUTH EAST ARROW AND SOUTH WEST ARROW
0292A^⤪^^\towa^R^mathrel^^SOUTH WEST ARROW AND NORTH WEST ARROW
0292B^⤫^^\rdiagovfdiag^R^mathord^^RISING DIAGONAL CROSSING FALLING DIAGONAL
0292C^⤬^^\fdiagovrdiag^R^mathord^^FALLING DIAGONAL CROSSING RISING DIAGONAL
0292D^⤭^^\seovnearrow^R^mathord^^SOUTH EAST ARROW CROSSING NORTH EAST ARROW
0292E^⤮^^\neovsearrow^R^mathord^^NORTH EAST ARROW CROSSING SOUTH EAST ARROW
0292F^⤯^^\fdiagovnearrow^R^mathord^^FALLING DIAGONAL CROSSING NORTH EAST ARROW
02930^⤰^^\rdiagovsearrow^R^mathord^^RISING DIAGONAL CROSSING SOUTH EAST ARROW
02931^⤱^^\neovnwarrow^R^mathord^^NORTH EAST ARROW CROSSING NORTH WEST ARROW
02932^⤲^^\nwovnearrow^R^mathord^^NORTH WEST ARROW CROSSING NORTH EAST ARROW
02933^⤳^\leadsto^\rightcurvedarrow^R^mathrel^txfonts^WAVE ARROW POINTING DIRECTLY RIGHT
02934^⤴^^\uprightcurvearrow^R^mathord^^ARROW POINTING RIGHTWARDS THEN CURVING UPWARDS
02935^⤵^^\downrightcurvedarrow^R^mathord^^ARROW POINTING RIGHTWARDS THEN CURVING DOWNWARDS
02936^⤶^^\leftdowncurvedarrow^R^mathrel^^ARROW POINTING DOWNWARDS THEN CURVING LEFTWARDS
02937^⤷^^\rightdowncurvedarrow^R^mathrel^^ARROW POINTING DOWNWARDS THEN CURVING RIGHTWARDS
02938^⤸^^\cwrightarcarrow^R^mathrel^^RIGHT-SIDE ARC CLOCKWISE ARROW
02939^⤹^^\acwleftarcarrow^R^mathrel^^LEFT-SIDE ARC ANTICLOCKWISE ARROW
0293A^⤺^^\acwoverarcarrow^R^mathrel^^TOP ARC ANTICLOCKWISE ARROW
0293B^⤻^^\acwunderarcarrow^R^mathrel^^BOTTOM ARC ANTICLOCKWISE ARROW
0293C^⤼^^\curvearrowrightminus^R^mathrel^^TOP ARC CLOCKWISE ARROW WITH MINUS
0293D^⤽^^\curvearrowleftplus^R^mathrel^^TOP ARC ANTICLOCKWISE ARROW WITH PLUS
0293E^⤾^^\cwundercurvearrow^R^mathrel^^LOWER RIGHT SEMICIRCULAR CLOCKWISE ARROW
0293F^⤿^^\ccwundercurvearrow^R^mathrel^^LOWER LEFT SEMICIRCULAR ANTICLOCKWISE ARROW
02940^⥀^^\acwcirclearrow^R^mathrel^^ANTICLOCKWISE CLOSED CIRCLE ARROW
02941^⥁^^\cwcirclearrow^R^mathrel^^CLOCKWISE CLOSED CIRCLE ARROW
02942^⥂^^\rightarrowshortleftarrow^R^mathrel^^RIGHTWARDS ARROW ABOVE SHORT LEFTWARDS ARROW
02943^⥃^^\leftarrowshortrightarrow^R^mathrel^^LEFTWARDS ARROW ABOVE SHORT RIGHTWARDS ARROW
02944^⥄^^\shortrightarrowleftarrow^R^mathrel^^SHORT RIGHTWARDS ARROW ABOVE LEFTWARDS ARROW
02945^⥅^^\rightarrowplus^R^mathrel^^RIGHTWARDS ARROW WITH PLUS BELOW
02946^⥆^^\leftarrowplus^R^mathrel^^LEFTWARDS ARROW WITH PLUS BELOW
02947^⥇^^\rightarrowx^R^mathrel^^RIGHTWARDS ARROW THROUGH X
02948^⥈^^\leftrightarrowcircle^R^mathrel^^LEFT RIGHT ARROW THROUGH SMALL CIRCLE
02949^⥉^^\twoheaduparrowcircle^R^mathrel^^UPWARDS TWO-HEADED ARROW FROM SMALL CIRCLE
0294A^⥊^\leftrightharpoon^\leftrightharpoonupdown^R^mathrel^mathabx^LEFT BARB UP RIGHT BARB DOWN HARPOON
0294B^⥋^\rightleftharpoon^\leftrightharpoondownup^R^mathrel^mathabx^LEFT BARB DOWN RIGHT BARB UP HARPOON
0294C^⥌^^\updownharpoonrightleft^R^mathrel^^UP BARB RIGHT DOWN BARB LEFT HARPOON
0294D^⥍^^\updownharpoonleftright^R^mathrel^^UP BARB LEFT DOWN BARB RIGHT HARPOON
0294E^⥎^\leftrightharpoonup^\leftrightharpoonupup^R^mathrel^wrisym^LEFT BARB UP RIGHT BARB UP HARPOON
0294F^⥏^\rightupdownharpoon^\updownharpoonrightright^R^mathrel^wrisym^UP BARB RIGHT DOWN BARB RIGHT HARPOON
02950^⥐^\leftrightharpoondown^\leftrightharpoondowndown^R^mathrel^wrisym^LEFT BARB DOWN RIGHT BARB DOWN HARPOON
02951^⥑^\leftupdownharpoon^\updownharpoonleftleft^R^mathrel^wrisym^UP BARB LEFT DOWN BARB LEFT HARPOON
02952^⥒^\LeftVectorBar^\barleftharpoonup^R^mathrel^wrisym^LEFTWARDS HARPOON WITH BARB UP TO BAR
02953^⥓^\RightVectorBar^\rightharpoonupbar^R^mathrel^wrisym^RIGHTWARDS HARPOON WITH BARB UP TO BAR
02954^⥔^\RightUpVectorBar^\barupharpoonright^R^mathrel^wrisym^UPWARDS HARPOON WITH BARB RIGHT TO BAR
02955^⥕^\RightDownVectorBar^\downharpoonrightbar^R^mathrel^wrisym^DOWNWARDS HARPOON WITH BARB RIGHT TO BAR
02956^⥖^\DownLeftVectorBar^\barleftharpoondown^R^mathrel^wrisym^LEFTWARDS HARPOON WITH BARB DOWN TO BAR
02957^⥗^\DownRightVectorBar^\rightharpoondownbar^R^mathrel^wrisym^RIGHTWARDS HARPOON WITH BARB DOWN TO BAR
02958^⥘^\LeftUpVectorBar^\barupharpoonleft^R^mathrel^wrisym^UPWARDS HARPOON WITH BARB LEFT TO BAR
02959^⥙^\LeftDownVectorBar^\downharpoonleftbar^R^mathrel^wrisym^DOWNWARDS HARPOON WITH BARB LEFT TO BAR
0295A^⥚^\LeftTeeVector^\leftharpoonupbar^R^mathrel^wrisym^LEFTWARDS HARPOON WITH BARB UP FROM BAR
0295B^⥛^\RightTeeVector^\barrightharpoonup^R^mathrel^wrisym^RIGHTWARDS HARPOON WITH BARB UP FROM BAR
0295C^⥜^\RightUpTeeVector^\upharpoonrightbar^R^mathrel^wrisym^UPWARDS HARPOON WITH BARB RIGHT FROM BAR
0295D^⥝^\RightDownTeeVector^\bardownharpoonright^R^mathrel^wrisym^DOWNWARDS HARPOON WITH BARB RIGHT FROM BAR
0295E^⥞^\DownLeftTeeVector^\leftharpoondownbar^R^mathrel^wrisym^LEFTWARDS HARPOON WITH BARB DOWN FROM BAR
0295F^⥟^\DownRightTeeVector^\barrightharpoondown^R^mathrel^wrisym^RIGHTWARDS HARPOON WITH BARB DOWN FROM BAR
02960^⥠^\LeftUpTeeVector^\upharpoonleftbar^R^mathrel^wrisym^UPWARDS HARPOON WITH BARB LEFT FROM BAR
02961^⥡^\LeftDownTeeVector^\bardownharpoonleft^R^mathrel^wrisym^DOWNWARDS HARPOON WITH BARB LEFT FROM BAR
02962^⥢^\leftleftharpoons^\leftharpoonsupdown^R^mathrel^mathabx^LEFTWARDS HARPOON WITH BARB UP ABOVE LEFTWARDS HARPOON WITH BARB DOWN
02963^⥣^\upupharpoons^\upharpoonsleftright^R^mathrel^mathabx^UPWARDS HARPOON WITH BARB LEFT BESIDE UPWARDS HARPOON WITH BARB RIGHT
02964^⥤^\rightrightharpoons^\rightharpoonsupdown^R^mathrel^mathabx^RIGHTWARDS HARPOON WITH BARB UP ABOVE RIGHTWARDS HARPOON WITH BARB DOWN
02965^⥥^\downdownharpoons^\downharpoonsleftright^R^mathrel^mathabx^DOWNWARDS HARPOON WITH BARB LEFT BESIDE DOWNWARDS HARPOON WITH BARB RIGHT
02966^⥦^^\leftrightharpoonsup^R^mathrel^^LEFTWARDS HARPOON WITH BARB UP ABOVE RIGHTWARDS HARPOON WITH BARB UP
02967^⥧^^\leftrightharpoonsdown^R^mathrel^^LEFTWARDS HARPOON WITH BARB DOWN ABOVE RIGHTWARDS HARPOON WITH BARB DOWN
02968^⥨^^\rightleftharpoonsup^R^mathrel^^RIGHTWARDS HARPOON WITH BARB UP ABOVE LEFTWARDS HARPOON WITH BARB UP
02969^⥩^^\rightleftharpoonsdown^R^mathrel^^RIGHTWARDS HARPOON WITH BARB DOWN ABOVE LEFTWARDS HARPOON WITH BARB DOWN
0296A^⥪^\leftbarharpoon^\leftharpoonupdash^R^mathrel^mathabx^LEFTWARDS HARPOON WITH BARB UP ABOVE LONG DASH
0296B^⥫^\barleftharpoon^\dashleftharpoondown^R^mathrel^mathabx^LEFTWARDS HARPOON WITH BARB DOWN BELOW LONG DASH
0296C^⥬^\rightbarharpoon^\rightharpoonupdash^R^mathrel^mathabx^RIGHTWARDS HARPOON WITH BARB UP ABOVE LONG DASH
0296D^⥭^\barrightharpoon^\dashrightharpoondown^R^mathrel^mathabx^RIGHTWARDS HARPOON WITH BARB DOWN BELOW LONG DASH
0296E^⥮^\updownharpoons^\updownharpoonsleftright^R^mathrel^mathabx^= \upequilibrium (wrisym), UPWARDS HARPOON WITH BARB LEFT BESIDE DOWNWARDS HARPOON WITH BARB RIGHT
0296F^⥯^\downupharpoons^\downupharpoonsleftright^R^mathrel^mathabx^= \uprevequilibrium (wrisym), DOWNWARDS HARPOON WITH BARB LEFT BESIDE UPWARDS HARPOON WITH BARB RIGHT
02970^⥰^^\rightimply^R^mathrel^^RIGHT DOUBLE ARROW WITH ROUNDED HEAD
02971^⥱^^\equalrightarrow^R^mathrel^^EQUALS SIGN ABOVE RIGHTWARDS ARROW
02972^⥲^^\similarrightarrow^R^mathrel^^TILDE OPERATOR ABOVE RIGHTWARDS ARROW
02973^⥳^^\leftarrowsimilar^R^mathrel^^LEFTWARDS ARROW ABOVE TILDE OPERATOR
02974^⥴^^\rightarrowsimilar^R^mathrel^^RIGHTWARDS ARROW ABOVE TILDE OPERATOR
02975^⥵^^\rightarrowapprox^R^mathrel^^RIGHTWARDS ARROW ABOVE ALMOST EQUAL TO
02976^⥶^^\ltlarr^R^mathrel^^LESS-THAN ABOVE LEFTWARDS ARROW
02977^⥷^^\leftarrowless^R^mathrel^^LEFTWARDS ARROW THROUGH LESS-THAN
02978^⥸^^\gtrarr^R^mathrel^^GREATER-THAN ABOVE RIGHTWARDS ARROW
02979^⥹^^\subrarr^R^mathrel^^SUBSET ABOVE RIGHTWARDS ARROW
0297A^⥺^^\leftarrowsubset^R^mathrel^^LEFTWARDS ARROW THROUGH SUBSET
0297B^⥻^^\suplarr^R^mathrel^^SUPERSET ABOVE LEFTWARDS ARROW
0297C^⥼^\strictfi^\leftfishtail^R^mathrel^txfonts^LEFT FISH TAIL
0297D^⥽^\strictif^\rightfishtail^R^mathrel^txfonts^RIGHT FISH TAIL
0297E^⥾^^\upfishtail^R^mathrel^^UP FISH TAIL
0297F^⥿^^\downfishtail^R^mathrel^^DOWN FISH TAIL
02980^⦀^\VERT^\Vvert^F^mathfence^fourier^TRIPLE VERTICAL BAR DELIMITER
02981^⦁^\spot^\mdsmblkcircle^N^mathord^oz^= \dot (oz), Z NOTATION SPOT
02982^⦂^^\typecolon^F^mathbin^^Z NOTATION TYPE COLON, (present in bbold font but no command)
02983^⦃^^\lBrace^O^mathopen^^LEFT WHITE CURLY BRACKET
02984^⦄^^\rBrace^C^mathclose^^RIGHT WHITE CURLY BRACKET
02985^⦅^\Lparen^\lParen^O^mathopen^mathbbol^LEFT WHITE PARENTHESIS
02986^⦆^\Rparen^\rParen^C^mathclose^mathbbol^RIGHT WHITE PARENTHESIS
02987^⦇^\limg^\llparenthesis^O^mathopen^oz^= \llparenthesis (stmaryrd), Z NOTATION LEFT IMAGE BRACKET
02988^⦈^\rimg^\rrparenthesis^C^mathclose^oz^= \rrparenthesis (stmaryrd), Z NOTATION RIGHT IMAGE BRACKET
02989^⦉^\lblot^\llangle^O^mathopen^oz^Z NOTATION LEFT BINDING BRACKET
0298A^⦊^\rblot^\rrangle^C^mathclose^oz^Z NOTATION RIGHT BINDING BRACKET
0298B^⦋^^\lbrackubar^O^mathopen^^LEFT SQUARE BRACKET WITH UNDERBAR
0298C^⦌^^\rbrackubar^C^mathclose^^RIGHT SQUARE BRACKET WITH UNDERBAR
0298D^⦍^^\lbrackultick^O^mathopen^^LEFT SQUARE BRACKET WITH TICK IN TOP CORNER
0298E^⦎^^\rbracklrtick^C^mathclose^^RIGHT SQUARE BRACKET WITH TICK IN BOTTOM CORNER
0298F^⦏^^\lbracklltick^O^mathopen^^LEFT SQUARE BRACKET WITH TICK IN BOTTOM CORNER
02990^⦐^^\rbrackurtick^C^mathclose^^RIGHT SQUARE BRACKET WITH TICK IN TOP CORNER
02991^⦑^^\langledot^O^mathopen^^LEFT ANGLE BRACKET WITH DOT
02992^⦒^^\rangledot^C^mathclose^^RIGHT ANGLE BRACKET WITH DOT
02993^⦓^^\lparenless^O^mathopen^^LEFT ARC LESS-THAN BRACKET
02994^⦔^^\rparengtr^C^mathclose^^RIGHT ARC GREATER-THAN BRACKET
02995^⦕^^\Lparengtr^O^mathopen^^DOUBLE LEFT ARC GREATER-THAN BRACKET
02996^⦖^^\Rparenless^C^mathclose^^DOUBLE RIGHT ARC LESS-THAN BRACKET
02997^⦗^^\lblkbrbrak^O^mathopen^^LEFT BLACK TORTOISE SHELL BRACKET
02998^⦘^^\rblkbrbrak^C^mathclose^^RIGHT BLACK TORTOISE SHELL BRACKET
02999^⦙^^\fourvdots^F^mathord^^DOTTED FENCE
0299A^⦚^^\vzigzag^F^mathord^^VERTICAL ZIGZAG LINE
0299B^⦛^^\measuredangleleft^N^mathord^^MEASURED ANGLE OPENING LEFT
0299C^⦜^^\rightanglesqr^N^mathord^^RIGHT ANGLE VARIANT WITH SQUARE
0299D^⦝^^\rightanglemdot^N^mathord^^MEASURED RIGHT ANGLE WITH DOT
0299E^⦞^^\angles^N^mathord^^ANGLE WITH S INSIDE
0299F^⦟^^\angdnr^N^mathord^^ACUTE ANGLE
029A0^⦠^^\gtlpar^N^mathord^^SPHERICAL ANGLE OPENING LEFT
029A1^⦡^^\sphericalangleup^N^mathord^^SPHERICAL ANGLE OPENING UP
029A2^⦢^^\turnangle^N^mathord^^TURNED ANGLE
029A3^⦣^^\revangle^N^mathord^^REVERSED ANGLE
029A4^⦤^^\angleubar^N^mathord^^ANGLE WITH UNDERBAR
029A5^⦥^^\revangleubar^N^mathord^^REVERSED ANGLE WITH UNDERBAR
029A6^⦦^^\wideangledown^N^mathord^^OBLIQUE ANGLE OPENING UP
029A7^⦧^^\wideangleup^N^mathord^^OBLIQUE ANGLE OPENING DOWN
029A8^⦨^^\measanglerutone^N^mathord^^MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING UP AND RIGHT
029A9^⦩^^\measanglelutonw^N^mathord^^MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING UP AND LEFT
029AA^⦪^^\measanglerdtose^N^mathord^^MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING DOWN AND RIGHT
029AB^⦫^^\measangleldtosw^N^mathord^^MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING DOWN AND LEFT
029AC^⦬^^\measangleurtone^N^mathord^^MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING RIGHT AND UP
029AD^⦭^^\measangleultonw^N^mathord^^MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING LEFT AND UP
029AE^⦮^^\measangledrtose^N^mathord^^MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING RIGHT AND DOWN
029AF^⦯^^\measangledltosw^N^mathord^^MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING LEFT AND DOWN
029B0^⦰^^\revemptyset^N^mathord^^REVERSED EMPTY SET
029B1^⦱^^\emptysetobar^N^mathord^^EMPTY SET WITH OVERBAR
029B2^⦲^^\emptysetocirc^N^mathord^^EMPTY SET WITH SMALL CIRCLE ABOVE
029B3^⦳^^\emptysetoarr^N^mathord^^EMPTY SET WITH RIGHT ARROW ABOVE
029B4^⦴^^\emptysetoarrl^N^mathord^^EMPTY SET WITH LEFT ARROW ABOVE
029B5^⦵^^\circlehbar^N^mathbin^^CIRCLE WITH HORIZONTAL BAR
029B6^⦶^^\circledvert^B^mathbin^^CIRCLED VERTICAL BAR
029B7^⦷^^\circledparallel^B^mathbin^^CIRCLED PARALLEL
029B8^⦸^\circledbslash^\obslash^B^mathbin^txfonts^CIRCLED REVERSE SOLIDUS
029B9^⦹^^\operp^B^mathbin^^CIRCLED PERPENDICULAR
029BA^⦺^^\obot^N^mathord^^CIRCLE DIVIDED BY HORIZONTAL BAR AND TOP HALF DIVIDED BY VERTICAL BAR
029BB^⦻^^\olcross^N^mathord^^CIRCLE WITH SUPERIMPOSED X
029BC^⦼^^\odotslashdot^N^mathord^^CIRCLED ANTICLOCKWISE-ROTATED DIVISION SIGN
029BD^⦽^^\uparrowoncircle^N^mathord^^UP ARROW THROUGH CIRCLE
029BE^⦾^^\circledwhitebullet^N^mathord^^CIRCLED WHITE BULLET
029BF^⦿^^\circledbullet^N^mathord^^CIRCLED BULLET
029C0^⧀^\circledless^\olessthan^B^mathbin^txfonts^CIRCLED LESS-THAN
029C1^⧁^\circledgtr^\ogreaterthan^B^mathbin^txfonts^CIRCLED GREATER-THAN
029C2^⧂^^\cirscir^N^mathord^^CIRCLE WITH SMALL CIRCLE TO THE RIGHT
029C3^⧃^^\cirE^N^mathord^^CIRCLE WITH TWO HORIZONTAL STROKES TO THE RIGHT
029C4^⧄^\boxslash^\boxdiag^B^mathbin^stmaryrd txfonts^SQUARED RISING DIAGONAL SLASH
029C5^⧅^\boxbslash^\boxbslash^B^mathbin^stmaryrd txfonts^SQUARED FALLING DIAGONAL SLASH
029C6^⧆^\boxast^\boxast^B^mathbin^stmaryrd txfonts^SQUARED ASTERISK
029C7^⧇^\boxcircle^\boxcircle^B^mathbin^stmaryrd^SQUARED SMALL CIRCLE
029C8^⧈^\boxbox^\boxbox^B^mathbin^stmaryrd^SQUARED SQUARE
029C9^⧉^^\boxonbox^N^mathord^^TWO JOINED SQUARES
029CA^⧊^^\triangleodot^N^mathord^^TRIANGLE WITH DOT ABOVE
029CB^⧋^^\triangleubar^N^mathord^^TRIANGLE WITH UNDERBAR
029CC^⧌^^\triangles^N^mathord^^S IN TRIANGLE
029CD^⧍^^\triangleserifs^N^mathbin^^TRIANGLE WITH SERIFS AT BOTTOM
029CE^⧎^^\rtriltri^R^mathrel^^RIGHT TRIANGLE ABOVE LEFT TRIANGLE
029CF^⧏^\LeftTriangleBar^\ltrivb^R^mathrel^wrisym^LEFT TRIANGLE BESIDE VERTICAL BAR
029D0^⧐^\RightTriangleBar^\vbrtri^R^mathrel^wrisym^VERTICAL BAR BESIDE RIGHT TRIANGLE
029D1^⧑^^\lfbowtie^R^mathrel^^left black bowtie
029D2^⧒^^\rfbowtie^R^mathrel^^right black bowtie
029D3^⧓^^\fbowtie^R^mathrel^^BLACK BOWTIE
029D4^⧔^^\lftimes^R^mathrel^^left black times
029D5^⧕^^\rftimes^R^mathrel^^right black times
029D6^⧖^^\hourglass^B^mathbin^^WHITE HOURGLASS
029D7^⧗^^\blackhourglass^B^mathbin^^BLACK HOURGLASS
029D8^⧘^^\lvzigzag^O^mathopen^^LEFT WIGGLY FENCE
029D9^⧙^^\rvzigzag^C^mathclose^^RIGHT WIGGLY FENCE
029DA^⧚^^\Lvzigzag^O^mathopen^^LEFT DOUBLE WIGGLY FENCE
029DB^⧛^^\Rvzigzag^C^mathclose^^RIGHT DOUBLE WIGGLY FENCE
029DC^⧜^^\iinfin^N^mathord^^INCOMPLETE INFINITY
029DD^⧝^^\tieinfty^N^mathord^^TIE OVER INFINITY
029DE^⧞^^\nvinfty^N^mathord^^INFINITY NEGATED WITH VERTICAL BAR
029DF^⧟^\multimapboth^\dualmap^R^mathrel^txfonts^DOUBLE-ENDED MULTIMAP
029E0^⧠^^\laplac^N^mathord^^SQUARE WITH CONTOURED OUTLINE
029E1^⧡^^\lrtriangleeq^R^mathrel^^INCREASES AS
029E2^⧢^^\shuffle^B^mathbin^^SHUFFLE PRODUCT
029E3^⧣^^\eparsl^R^mathrel^^EQUALS SIGN AND SLANTED PARALLEL
029E4^⧤^^\smeparsl^R^mathrel^^EQUALS SIGN AND SLANTED PARALLEL WITH TILDE ABOVE
029E5^⧥^^\eqvparsl^R^mathrel^^IDENTICAL TO AND SLANTED PARALLEL
029E6^⧦^^\gleichstark^R^mathrel^^GLEICH STARK
029E7^⧧^^\thermod^N^mathord^^THERMODYNAMIC
029E8^⧨^^\downtriangleleftblack^N^mathord^^DOWN-POINTING TRIANGLE WITH LEFT HALF BLACK
029E9^⧩^^\downtrianglerightblack^N^mathord^^DOWN-POINTING TRIANGLE WITH RIGHT HALF BLACK
029EA^⧪^^\blackdiamonddownarrow^N^mathord^^BLACK DIAMOND WITH DOWN ARROW
029EB^⧫^\blacklozenge^\mdlgblklozenge^B^mathbin^amssymb^BLACK LOZENGE
029EC^⧬^^\circledownarrow^N^mathord^^WHITE CIRCLE WITH DOWN ARROW
029ED^⧭^^\blackcircledownarrow^N^mathord^^BLACK CIRCLE WITH DOWN ARROW
029EE^⧮^^\errbarsquare^N^mathord^^ERROR-BARRED WHITE SQUARE
029EF^⧯^^\errbarblacksquare^N^mathord^^ERROR-BARRED BLACK SQUARE
029F0^⧰^^\errbardiamond^N^mathord^^ERROR-BARRED WHITE DIAMOND
029F1^⧱^^\errbarblackdiamond^N^mathord^^ERROR-BARRED BLACK DIAMOND
029F2^⧲^^\errbarcircle^N^mathord^^ERROR-BARRED WHITE CIRCLE
029F3^⧳^^\errbarblackcircle^N^mathord^^ERROR-BARRED BLACK CIRCLE
029F4^⧴^^\ruledelayed^R^mathrel^^RULE-DELAYED
029F5^⧵^\setminus^\setminus^B^mathbin^^REVERSE SOLIDUS OPERATOR
029F6^⧶^^\dsol^B^mathbin^^SOLIDUS WITH OVERBAR
029F7^⧷^^\rsolbar^B^mathbin^^REVERSE SOLIDUS WITH HORIZONTAL STROKE
029F8^⧸^^\xsol^L^mathop^^BIG SOLIDUS
029F9^⧹^\zhide^\xbsol^L^mathop^oz^= \hide (oz), BIG REVERSE SOLIDUS, z notation schema hiding
029FA^⧺^^\doubleplus^B^mathbin^^DOUBLE PLUS
029FB^⧻^^\tripleplus^B^mathbin^^TRIPLE PLUS
029FC^⧼^^\lcurvyangle^O^mathopen^^left pointing curved angle bracket
029FD^⧽^^\rcurvyangle^C^mathclose^^right pointing curved angle bracket
029FE^⧾^^\tplus^B^mathbin^^TINY
029FF^⧿^^\tminus^B^mathbin^^MINY
02A00^⨀^\bigodot^\bigodot^L^mathop^^N-ARY CIRCLED DOT OPERATOR
02A01^⨁^\bigoplus^\bigoplus^L^mathop^^N-ARY CIRCLED PLUS OPERATOR
02A02^⨂^\bigotimes^\bigotimes^L^mathop^^N-ARY CIRCLED TIMES OPERATOR
02A03^⨃^^\bigcupdot^L^mathop^^N-ARY UNION OPERATOR WITH DOT
02A04^⨄^\biguplus^\biguplus^L^mathop^^N-ARY UNION OPERATOR WITH PLUS
02A05^⨅^\bigsqcap^\bigsqcap^L^mathop^txfonts^N-ARY SQUARE INTERSECTION OPERATOR
02A06^⨆^\bigsqcup^\bigsqcup^L^mathop^^N-ARY SQUARE UNION OPERATOR
02A07^⨇^^\conjquant^L^mathop^^TWO LOGICAL AND OPERATOR
02A08^⨈^^\disjquant^L^mathop^^TWO LOGICAL OR OPERATOR
02A09^⨉^\varprod^\bigtimes^L^mathop^txfonts^N-ARY TIMES OPERATOR
02A0A^⨊^^\modtwosum^L^mathord^^MODULO TWO SUM
02A0B^⨋^^\sumint^L^mathop^^SUMMATION WITH INTEGRAL
02A0C^⨌^\iiiint^\iiiint^L^mathop^amsmath esint^QUADRUPLE INTEGRAL OPERATOR
02A0D^⨍^^\intbar^L^mathop^^FINITE PART INTEGRAL
02A0E^⨎^^\intBar^L^mathop^^INTEGRAL WITH DOUBLE STROKE
02A0F^⨏^\fint^\fint^L^mathop^esint wrisym^INTEGRAL AVERAGE WITH SLASH
02A10^⨐^^\cirfnint^L^mathop^^CIRCULATION FUNCTION
02A11^⨑^^\awint^L^mathop^^ANTICLOCKWISE INTEGRATION
02A12^⨒^^\rppolint^L^mathop^^LINE INTEGRATION WITH RECTANGULAR PATH AROUND POLE
02A13^⨓^^\scpolint^L^mathop^^LINE INTEGRATION WITH SEMICIRCULAR PATH AROUND POLE
02A14^⨔^^\npolint^L^mathop^^LINE INTEGRATION NOT INCLUDING THE POLE
02A15^⨕^^\pointint^L^mathop^^INTEGRAL AROUND A POINT OPERATOR
02A16^⨖^\sqint^\sqint^L^mathop^esint^= \sqrint (wrisym), QUATERNION INTEGRAL OPERATOR
02A17^⨗^^\intlarhk^L^mathop^^INTEGRAL WITH LEFTWARDS ARROW WITH HOOK
02A18^⨘^^\intx^L^mathop^^INTEGRAL WITH TIMES SIGN
02A19^⨙^^\intcap^L^mathop^^INTEGRAL WITH INTERSECTION
02A1A^⨚^^\intcup^L^mathop^^INTEGRAL WITH UNION
02A1B^⨛^^\upint^L^mathop^^INTEGRAL WITH OVERBAR
02A1C^⨜^^\lowint^L^mathop^^INTEGRAL WITH UNDERBAR
02A1D^⨝^\Join^\Join^L^mathop^amssymb^JOIN
02A1E^⨞^^\bigtriangleleft^L^mathop^^LARGE LEFT TRIANGLE OPERATOR
02A1F^⨟^\zcmp^\zcmp^L^mathop^oz^= \semi (oz), = \fatsemi (stmaryrd), Z NOTATION SCHEMA COMPOSITION
02A20^⨠^\zpipe^\zpipe^L^mathop^oz^Z NOTATION SCHEMA PIPING
02A21^⨡^\zproject^\zproject^L^mathop^oz^= \project (oz), Z NOTATION SCHEMA PROJECTION
02A22^⨢^^\ringplus^B^mathbin^^PLUS SIGN WITH SMALL CIRCLE ABOVE
02A23^⨣^^\plushat^B^mathbin^^PLUS SIGN WITH CIRCUMFLEX ACCENT ABOVE
02A24^⨤^^\simplus^B^mathbin^^PLUS SIGN WITH TILDE ABOVE
02A25^⨥^^\plusdot^B^mathbin^^PLUS SIGN WITH DOT BELOW
02A26^⨦^^\plussim^B^mathbin^^PLUS SIGN WITH TILDE BELOW
02A27^⨧^^\plussubtwo^B^mathbin^^PLUS SIGN WITH SUBSCRIPT TWO
02A28^⨨^^\plustrif^B^mathbin^^PLUS SIGN WITH BLACK TRIANGLE
02A29^⨩^^\commaminus^B^mathbin^^MINUS SIGN WITH COMMA ABOVE
02A2A^⨪^^\minusdot^B^mathbin^^MINUS SIGN WITH DOT BELOW
02A2B^⨫^^\minusfdots^B^mathbin^^MINUS SIGN WITH FALLING DOTS
02A2C^⨬^^\minusrdots^B^mathbin^^MINUS SIGN WITH RISING DOTS
02A2D^⨭^^\opluslhrim^B^mathbin^^PLUS SIGN IN LEFT HALF CIRCLE
02A2E^⨮^^\oplusrhrim^B^mathbin^^PLUS SIGN IN RIGHT HALF CIRCLE
02A2F^⨯^^\vectimes^B^mathbin^^# \times, VECTOR OR CROSS PRODUCT
02A30^⨰^^\dottimes^B^mathbin^^MULTIPLICATION SIGN WITH DOT ABOVE
02A31^⨱^^\timesbar^B^mathbin^^MULTIPLICATION SIGN WITH UNDERBAR
02A32^⨲^^\btimes^B^mathbin^^SEMIDIRECT PRODUCT WITH BOTTOM CLOSED
02A33^⨳^^\smashtimes^B^mathbin^^SMASH PRODUCT
02A34^⨴^^\otimeslhrim^B^mathbin^^MULTIPLICATION SIGN IN LEFT HALF CIRCLE
02A35^⨵^^\otimesrhrim^B^mathbin^^MULTIPLICATION SIGN IN RIGHT HALF CIRCLE
02A36^⨶^^\otimeshat^B^mathbin^^CIRCLED MULTIPLICATION SIGN WITH CIRCUMFLEX ACCENT
02A37^⨷^^\Otimes^B^mathbin^^MULTIPLICATION SIGN IN DOUBLE CIRCLE
02A38^⨸^^\odiv^B^mathbin^^CIRCLED DIVISION SIGN
02A39^⨹^^\triangleplus^B^mathbin^^PLUS SIGN IN TRIANGLE
02A3A^⨺^^\triangleminus^B^mathbin^^MINUS SIGN IN TRIANGLE
02A3B^⨻^^\triangletimes^B^mathbin^^MULTIPLICATION SIGN IN TRIANGLE
02A3C^⨼^^\intprod^B^mathbin^^INTERIOR PRODUCT
02A3D^⨽^^\intprodr^B^mathbin^^RIGHTHAND INTERIOR PRODUCT
02A3E^⨾^\fcmp^\fcmp^B^mathbin^oz^= \comp (oz), Z NOTATION RELATIONAL COMPOSITION
02A3F^⨿^\amalg^\amalg^B^mathbin^^AMALGAMATION OR COPRODUCT
02A40^⩀^^\capdot^B^mathbin^^INTERSECTION WITH DOT
02A41^⩁^^\uminus^B^mathbin^^UNION WITH MINUS SIGN, z notation bag subtraction
02A42^⩂^^\barcup^B^mathbin^^UNION WITH OVERBAR
02A43^⩃^^\barcap^B^mathbin^^INTERSECTION WITH OVERBAR
02A44^⩄^^\capwedge^B^mathbin^^INTERSECTION WITH LOGICAL AND
02A45^⩅^^\cupvee^B^mathbin^^UNION WITH LOGICAL OR
02A46^⩆^^\cupovercap^B^mathbin^^UNION ABOVE INTERSECTION
02A47^⩇^^\capovercup^B^mathbin^^INTERSECTION ABOVE UNION
02A48^⩈^^\cupbarcap^B^mathbin^^UNION ABOVE BAR ABOVE INTERSECTION
02A49^⩉^^\capbarcup^B^mathbin^^INTERSECTION ABOVE BAR ABOVE UNION
02A4A^⩊^^\twocups^B^mathbin^^UNION BESIDE AND JOINED WITH UNION
02A4B^⩋^^\twocaps^B^mathbin^^INTERSECTION BESIDE AND JOINED WITH INTERSECTION
02A4C^⩌^^\closedvarcup^B^mathbin^^CLOSED UNION WITH SERIFS
02A4D^⩍^^\closedvarcap^B^mathbin^^CLOSED INTERSECTION WITH SERIFS
02A4E^⩎^^\Sqcap^B^mathbin^^DOUBLE SQUARE INTERSECTION
02A4F^⩏^^\Sqcup^B^mathbin^^DOUBLE SQUARE UNION
02A50^⩐^^\closedvarcupsmashprod^B^mathbin^^CLOSED UNION WITH SERIFS AND SMASH PRODUCT
02A51^⩑^^\wedgeodot^B^mathbin^^LOGICAL AND WITH DOT ABOVE
02A52^⩒^^\veeodot^B^mathbin^^LOGICAL OR WITH DOT ABOVE
02A53^⩓^^\Wedge^B^mathbin^^DOUBLE LOGICAL AND
02A54^⩔^^\Vee^B^mathbin^^DOUBLE LOGICAL OR
02A55^⩕^^\wedgeonwedge^B^mathbin^^TWO INTERSECTING LOGICAL AND
02A56^⩖^^\veeonvee^B^mathbin^^TWO INTERSECTING LOGICAL OR
02A57^⩗^^\bigslopedvee^B^mathbin^^SLOPING LARGE OR
02A58^⩘^^\bigslopedwedge^B^mathbin^^SLOPING LARGE AND
02A59^⩙^^\veeonwedge^R^mathrel^^LOGICAL OR OVERLAPPING LOGICAL AND
02A5A^⩚^^\wedgemidvert^B^mathbin^^LOGICAL AND WITH MIDDLE STEM
02A5B^⩛^^\veemidvert^B^mathbin^^LOGICAL OR WITH MIDDLE STEM
02A5C^⩜^^\midbarwedge^B^mathbin^^ogical and with horizontal dash
02A5D^⩝^^\midbarvee^B^mathbin^^LOGICAL OR WITH HORIZONTAL DASH
02A5E^⩞^\doublebarwedge^\doublebarwedge^B^mathbin^amssymb^LOGICAL AND WITH DOUBLE OVERBAR
02A5F^⩟^^\wedgebar^B^mathbin^^LOGICAL AND WITH UNDERBAR
02A60^⩠^^\wedgedoublebar^B^mathbin^^LOGICAL AND WITH DOUBLE UNDERBAR
02A61^⩡^^\varveebar^B^mathbin^^SMALL VEE WITH UNDERBAR
02A62^⩢^^\doublebarvee^B^mathbin^^LOGICAL OR WITH DOUBLE OVERBAR
02A63^⩣^^\veedoublebar^B^mathbin^^LOGICAL OR WITH DOUBLE UNDERBAR
02A64^⩤^\dsub^\dsub^B^mathbin^oz^= \ndres (oz), Z NOTATION DOMAIN ANTIRESTRICTION
02A65^⩥^\rsub^\rsub^B^mathbin^oz^= \nrres (oz), Z NOTATION RANGE ANTIRESTRICTION
02A66^⩦^^\eqdot^R^mathrel^^EQUALS SIGN WITH DOT BELOW
02A67^⩧^^\dotequiv^R^mathrel^^IDENTICAL WITH DOT ABOVE
02A68^⩨^^\equivVert^R^mathrel^^TRIPLE HORIZONTAL BAR WITH DOUBLE VERTICAL STROKE
02A69^⩩^^\equivVvert^R^mathrel^^TRIPLE HORIZONTAL BAR WITH TRIPLE VERTICAL STROKE
02A6A^⩪^^\dotsim^R^mathrel^^TILDE OPERATOR WITH DOT ABOVE
02A6B^⩫^^\simrdots^R^mathrel^^TILDE OPERATOR WITH RISING DOTS
02A6C^⩬^^\simminussim^R^mathrel^^SIMILAR MINUS SIMILAR
02A6D^⩭^^\congdot^R^mathrel^^CONGRUENT WITH DOT ABOVE
02A6E^⩮^^\asteq^R^mathrel^^EQUALS WITH ASTERISK
02A6F^⩯^^\hatapprox^R^mathrel^^ALMOST EQUAL TO WITH CIRCUMFLEX ACCENT
02A70^⩰^^\approxeqq^R^mathrel^^APPROXIMATELY EQUAL OR EQUAL TO
02A71^⩱^^\eqqplus^B^mathbin^^EQUALS SIGN ABOVE PLUS SIGN
02A72^⩲^^\pluseqq^B^mathbin^^PLUS SIGN ABOVE EQUALS SIGN
02A73^⩳^^\eqqsim^R^mathrel^^EQUALS SIGN ABOVE TILDE OPERATOR
02A74^⩴^\Coloneqq^\Coloneq^R^mathrel^txfonts^# ::=, x \Coloneq (txfonts), DOUBLE COLON EQUAL
02A75^⩵^\Equal^\eqeq^R^mathrel^wrisym^# ==, TWO CONSECUTIVE EQUALS SIGNS
02A76^⩶^\Same^\eqeqeq^R^mathrel^wrisym^# ===, THREE CONSECUTIVE EQUALS SIGNS
02A77^⩷^^\ddotseq^R^mathrel^^EQUALS SIGN WITH TWO DOTS ABOVE AND TWO DOTS BELOW
02A78^⩸^^\equivDD^R^mathrel^^EQUIVALENT WITH FOUR DOTS ABOVE
02A79^⩹^^\ltcir^R^mathrel^^LESS-THAN WITH CIRCLE INSIDE
02A7A^⩺^^\gtcir^R^mathrel^^GREATER-THAN WITH CIRCLE INSIDE
02A7B^⩻^^\ltquest^R^mathrel^^LESS-THAN WITH QUESTION MARK ABOVE
02A7C^⩼^^\gtquest^R^mathrel^^GREATER-THAN WITH QUESTION MARK ABOVE
02A7D^⩽^\leqslant^\leqslant^R^mathrel^amssymb fourier^LESS-THAN OR SLANTED EQUAL TO
02A7E^⩾^\geqslant^\geqslant^R^mathrel^amssymb fourier^GREATER-THAN OR SLANTED EQUAL TO
02A7F^⩿^^\lesdot^R^mathrel^^LESS-THAN OR SLANTED EQUAL TO WITH DOT INSIDE
02A80^⪀^^\gesdot^R^mathrel^^GREATER-THAN OR SLANTED EQUAL TO WITH DOT INSIDE
02A81^⪁^^\lesdoto^R^mathrel^^LESS-THAN OR SLANTED EQUAL TO WITH DOT ABOVE
02A82^⪂^^\gesdoto^R^mathrel^^GREATER-THAN OR SLANTED EQUAL TO WITH DOT ABOVE
02A83^⪃^^\lesdotor^R^mathrel^^LESS-THAN OR SLANTED EQUAL TO WITH DOT ABOVE RIGHT
02A84^⪄^^\gesdotol^R^mathrel^^GREATER-THAN OR SLANTED EQUAL TO WITH DOT ABOVE LEFT
02A85^⪅^\lessapprox^\lessapprox^R^mathrel^amssymb^LESS-THAN OR APPROXIMATE
02A86^⪆^\gtrapprox^\gtrapprox^R^mathrel^amssymb^GREATER-THAN OR APPROXIMATE
02A87^⪇^\lneq^\lneq^R^mathrel^amssymb^LESS-THAN AND SINGLE-LINE NOT EQUAL TO
02A88^⪈^\gneq^\gneq^R^mathrel^amssymb^GREATER-THAN AND SINGLE-LINE NOT EQUAL TO
02A89^⪉^\lnapprox^\lnapprox^R^mathrel^amssymb^LESS-THAN AND NOT APPROXIMATE
02A8A^⪊^\gnapprox^\gnapprox^R^mathrel^amssymb^GREATER-THAN AND NOT APPROXIMATE
02A8B^⪋^\lesseqqgtr^\lesseqqgtr^R^mathrel^amssymb^LESS-THAN ABOVE DOUBLE-LINE EQUAL ABOVE GREATER-THAN
02A8C^⪌^\gtreqqless^\gtreqqless^R^mathrel^amssymb^GREATER-THAN ABOVE DOUBLE-LINE EQUAL ABOVE LESS-THAN
02A8D^⪍^^\lsime^R^mathrel^^LESS-THAN ABOVE SIMILAR OR EQUAL
02A8E^⪎^^\gsime^R^mathrel^^GREATER-THAN ABOVE SIMILAR OR EQUAL
02A8F^⪏^^\lsimg^R^mathrel^^LESS-THAN ABOVE SIMILAR ABOVE GREATER-THAN
02A90^⪐^^\gsiml^R^mathrel^^GREATER-THAN ABOVE SIMILAR ABOVE LESS-THAN
02A91^⪑^^\lgE^R^mathrel^^LESS-THAN ABOVE GREATER-THAN ABOVE DOUBLE-LINE EQUAL
02A92^⪒^^\glE^R^mathrel^^GREATER-THAN ABOVE LESS-THAN ABOVE DOUBLE-LINE EQUAL
02A93^⪓^^\lesges^R^mathrel^^LESS-THAN ABOVE SLANTED EQUAL ABOVE GREATER-THAN ABOVE SLANTED EQUAL
02A94^⪔^^\gesles^R^mathrel^^GREATER-THAN ABOVE SLANTED EQUAL ABOVE LESS-THAN ABOVE SLANTED EQUAL
02A95^⪕^\eqslantless^\eqslantless^R^mathrel^amssymb^SLANTED EQUAL TO OR LESS-THAN
02A96^⪖^\eqslantgtr^\eqslantgtr^R^mathrel^amssymb^SLANTED EQUAL TO OR GREATER-THAN
02A97^⪗^^\elsdot^R^mathrel^^SLANTED EQUAL TO OR LESS-THAN WITH DOT INSIDE
02A98^⪘^^\egsdot^R^mathrel^^SLANTED EQUAL TO OR GREATER-THAN WITH DOT INSIDE
02A99^⪙^^\eqqless^R^mathrel^^DOUBLE-LINE EQUAL TO OR LESS-THAN
02A9A^⪚^^\eqqgtr^R^mathrel^^DOUBLE-LINE EQUAL TO OR GREATER-THAN
02A9B^⪛^^\eqqslantless^R^mathrel^^DOUBLE-LINE SLANTED EQUAL TO OR LESS-THAN
02A9C^⪜^^\eqqslantgtr^R^mathrel^^DOUBLE-LINE SLANTED EQUAL TO OR GREATER-THAN
02A9D^⪝^^\simless^R^mathrel^^SIMILAR OR LESS-THAN
02A9E^⪞^^\simgtr^R^mathrel^^SIMILAR OR GREATER-THAN
02A9F^⪟^^\simlE^R^mathrel^^SIMILAR ABOVE LESS-THAN ABOVE EQUALS SIGN
02AA0^⪠^^\simgE^R^mathrel^^SIMILAR ABOVE GREATER-THAN ABOVE EQUALS SIGN
02AA1^⪡^\NestedLessLess^\Lt^R^mathrel^wrisym^= \lll (mathabx -amssymb), DOUBLE NESTED LESS-THAN
02AA2^⪢^\NestedGreaterGreater^\Gt^R^mathrel^wrisym^= \ggg (mathabx -amssymb), DOUBLE NESTED GREATER-THAN
02AA3^⪣^^\partialmeetcontraction^R^mathrel^^double less-than with underbar
02AA4^⪤^^\glj^R^mathrel^^GREATER-THAN OVERLAPPING LESS-THAN
02AA5^⪥^^\gla^R^mathrel^^GREATER-THAN BESIDE LESS-THAN
02AA6^⪦^\leftslice^\ltcc^R^mathrel^stmaryrd^LESS-THAN CLOSED BY CURVE
02AA7^⪧^\rightslice^\gtcc^R^mathrel^stmaryrd^GREATER-THAN CLOSED BY CURVE
02AA8^⪨^^\lescc^R^mathrel^^LESS-THAN CLOSED BY CURVE ABOVE SLANTED EQUAL
02AA9^⪩^^\gescc^R^mathrel^^GREATER-THAN CLOSED BY CURVE ABOVE SLANTED EQUAL
02AAA^⪪^^\smt^R^mathrel^^SMALLER THAN
02AAB^⪫^^\lat^R^mathrel^^LARGER THAN
02AAC^⪬^^\smte^R^mathrel^^SMALLER THAN OR EQUAL TO
02AAD^⪭^^\late^R^mathrel^^LARGER THAN OR EQUAL TO
02AAE^⪮^^\bumpeqq^R^mathrel^^EQUALS SIGN WITH BUMPY ABOVE
02AAF^⪯^\preceq^\preceq^R^mathrel^^PRECEDES ABOVE SINGLE-LINE EQUALS SIGN
02AB0^⪰^\succeq^\succeq^R^mathrel^^SUCCEEDS ABOVE SINGLE-LINE EQUALS SIGN
02AB1^⪱^^\precneq^R^mathrel^^PRECEDES ABOVE SINGLE-LINE NOT EQUAL TO
02AB2^⪲^^\succneq^R^mathrel^^SUCCEEDS ABOVE SINGLE-LINE NOT EQUAL TO
02AB3^⪳^\preceqq^\preceqq^R^mathrel^txfonts^PRECEDES ABOVE EQUALS SIGN
02AB4^⪴^\succeqq^\succeqq^R^mathrel^txfonts^SUCCEEDS ABOVE EQUALS SIGN
02AB5^⪵^^\precneqq^R^mathrel^amssymb^PRECEDES ABOVE NOT EQUAL TO
02AB6^⪶^^\succneqq^R^mathrel^amssymb^SUCCEEDS ABOVE NOT EQUAL TO
02AB7^⪷^\precapprox^\precapprox^R^mathrel^amssymb^PRECEDES ABOVE ALMOST EQUAL TO
02AB8^⪸^\succapprox^\succapprox^R^mathrel^amssymb^SUCCEEDS ABOVE ALMOST EQUAL TO
02AB9^⪹^\precnapprox^\precnapprox^R^mathrel^amssymb^PRECEDES ABOVE NOT ALMOST EQUAL TO
02ABA^⪺^\succnapprox^\succnapprox^R^mathrel^amssymb^SUCCEEDS ABOVE NOT ALMOST EQUAL TO
02ABB^⪻^\llcurly^\Prec^R^mathrel^mathabx^DOUBLE PRECEDES
02ABC^⪼^\ggcurly^\Succ^R^mathrel^mathabx^DOUBLE SUCCEEDS
02ABD^⪽^^\subsetdot^R^mathrel^^SUBSET WITH DOT
02ABE^⪾^^\supsetdot^R^mathrel^^SUPERSET WITH DOT
02ABF^⪿^^\subsetplus^R^mathrel^^SUBSET WITH PLUS SIGN BELOW
02AC0^⫀^^\supsetplus^R^mathrel^^SUPERSET WITH PLUS SIGN BELOW
02AC1^⫁^^\submult^R^mathrel^^SUBSET WITH MULTIPLICATION SIGN BELOW
02AC2^⫂^^\supmult^R^mathrel^^SUPERSET WITH MULTIPLICATION SIGN BELOW
02AC3^⫃^^\subedot^R^mathrel^^SUBSET OF OR EQUAL TO WITH DOT ABOVE
02AC4^⫄^^\supedot^R^mathrel^^SUPERSET OF OR EQUAL TO WITH DOT ABOVE
02AC5^⫅^\subseteqq^\subseteqq^R^mathrel^amssymb^SUBSET OF ABOVE EQUALS SIGN
02AC6^⫆^\supseteqq^\supseteqq^R^mathrel^amssymb^SUPERSET OF ABOVE EQUALS SIGN
02AC7^⫇^^\subsim^R^mathrel^^SUBSET OF ABOVE TILDE OPERATOR
02AC8^⫈^^\supsim^R^mathrel^^SUPERSET OF ABOVE TILDE OPERATOR
02AC9^⫉^^\subsetapprox^R^mathrel^^SUBSET OF ABOVE ALMOST EQUAL TO
02ACA^⫊^^\supsetapprox^R^mathrel^^SUPERSET OF ABOVE ALMOST EQUAL TO
02ACB^⫋^\subsetneqq^\subsetneqq^R^mathrel^amssymb^SUBSET OF ABOVE NOT EQUAL TO
02ACC^⫌^\supsetneqq^\supsetneqq^R^mathrel^amssymb^SUPERSET OF ABOVE NOT EQUAL TO
02ACD^⫍^^\lsqhook^R^mathrel^^SQUARE LEFT OPEN BOX OPERATOR
02ACE^⫎^^\rsqhook^R^mathrel^^SQUARE RIGHT OPEN BOX OPERATOR
02ACF^⫏^^\csub^R^mathrel^^CLOSED SUBSET
02AD0^⫐^^\csup^R^mathrel^^CLOSED SUPERSET
02AD1^⫑^^\csube^R^mathrel^^CLOSED SUBSET OR EQUAL TO
02AD2^⫒^^\csupe^R^mathrel^^CLOSED SUPERSET OR EQUAL TO
02AD3^⫓^^\subsup^R^mathrel^^SUBSET ABOVE SUPERSET
02AD4^⫔^^\supsub^R^mathrel^^SUPERSET ABOVE SUBSET
02AD5^⫕^^\subsub^R^mathrel^^SUBSET ABOVE SUBSET
02AD6^⫖^^\supsup^R^mathrel^^SUPERSET ABOVE SUPERSET
02AD7^⫗^^\suphsub^R^mathrel^^SUPERSET BESIDE SUBSET
02AD8^⫘^^\supdsub^R^mathrel^^SUPERSET BESIDE AND JOINED BY DASH WITH SUBSET
02AD9^⫙^^\forkv^R^mathrel^^ELEMENT OF OPENING DOWNWARDS
02ADA^⫚^^\topfork^R^mathrel^^PITCHFORK WITH TEE TOP
02ADB^⫛^^\mlcp^R^mathrel^^TRANSVERSAL INTERSECTION
02ADC^⫝̸^^\forks^R^mathrel^^FORKING
02ADD^⫝^^\forksnot^R^mathrel^^NONFORKING
02ADE^⫞^^\shortlefttack^R^mathrel^^SHORT LEFT TACK
02ADF^⫟^^\shortdowntack^R^mathrel^^SHORT DOWN TACK
02AE0^⫠^^\shortuptack^R^mathrel^^SHORT UP TACK
02AE1^⫡^^\perps^N^mathord^^PERPENDICULAR WITH S
02AE2^⫢^^\vDdash^R^mathrel^^VERTICAL BAR TRIPLE RIGHT TURNSTILE
02AE3^⫣^^\dashV^R^mathrel^^DOUBLE VERTICAL BAR LEFT TURNSTILE
02AE4^⫤^^\Dashv^R^mathrel^^VERTICAL BAR DOUBLE LEFT TURNSTILE
02AE5^⫥^^\DashV^R^mathrel^^DOUBLE VERTICAL BAR DOUBLE LEFT TURNSTILE
02AE6^⫦^^\varVdash^R^mathrel^^LONG DASH FROM LEFT MEMBER OF DOUBLE VERTICAL
02AE7^⫧^^\Barv^R^mathrel^^SHORT DOWN TACK WITH OVERBAR
02AE8^⫨^^\vBar^R^mathrel^^SHORT UP TACK WITH UNDERBAR
02AE9^⫩^^\vBarv^R^mathrel^^SHORT UP TACK ABOVE SHORT DOWN TACK
02AEA^⫪^\Top^\barV^R^mathrel^txfonts^DOUBLE DOWN TACK
02AEB^⫫^\Bot^\Vbar^R^mathrel^txfonts^= \Perp (txfonts), DOUBLE UP TACK
02AEC^⫬^^\Not^R^mathrel^^DOUBLE STROKE NOT SIGN
02AED^⫭^^\bNot^R^mathrel^^REVERSED DOUBLE STROKE NOT SIGN
02AEE^⫮^^\revnmid^R^mathrel^^DOES NOT DIVIDE WITH REVERSED NEGATION SLASH
02AEF^⫯^^\cirmid^R^mathrel^^VERTICAL LINE WITH CIRCLE ABOVE
02AF0^⫰^^\midcir^R^mathrel^^VERTICAL LINE WITH CIRCLE BELOW
02AF1^⫱^^\topcir^N^mathord^^DOWN TACK WITH CIRCLE BELOW
02AF2^⫲^^\nhpar^R^mathrel^^PARALLEL WITH HORIZONTAL STROKE
02AF3^⫳^^\parsim^R^mathrel^^PARALLEL WITH TILDE OPERATOR
02AF4^⫴^\interleave^\interleave^B^mathbin^stmaryrd^TRIPLE VERTICAL BAR BINARY RELATION
02AF5^⫵^^\nhVvert^B^mathbin^^TRIPLE VERTICAL BAR WITH HORIZONTAL STROKE
02AF6^⫶^^\threedotcolon^B^mathbin^^TRIPLE COLON OPERATOR
02AF7^⫷^^\lllnest^R^mathrel^^TRIPLE NESTED LESS-THAN
02AF8^⫸^^\gggnest^R^mathrel^^TRIPLE NESTED GREATER-THAN
02AF9^⫹^^\leqqslant^R^mathrel^^DOUBLE-LINE SLANTED LESS-THAN OR EQUAL TO
02AFA^⫺^^\geqqslant^R^mathrel^^DOUBLE-LINE SLANTED GREATER-THAN OR EQUAL TO
02AFB^⫻^^\trslash^B^mathbin^^TRIPLE SOLIDUS BINARY RELATION
02AFC^⫼^\biginterleave^\biginterleave^L^mathop^stmaryrd^LARGE TRIPLE VERTICAL BAR OPERATOR
02AFD^⫽^\sslash^\sslash^B^mathbin^stmaryrd^# \varparallel (txfonts), DOUBLE SOLIDUS OPERATOR
02AFE^⫾^\talloblong^\talloblong^B^mathbin^stmaryrd^WHITE VERTICAL BAR
02AFF^⫿^^\bigtalloblong^L^mathop^^N-ARY WHITE VERTICAL BAR
02B00^⬀^^^R?^mathord^^NORTH EAST WHITE ARROW
02B01^⬁^^^R?^mathord^^NORTH WEST WHITE ARROW
02B02^⬂^^^R?^mathord^^SOUTH EAST WHITE ARROW
02B03^⬃^^^R?^mathord^^SOUTH WEST WHITE ARROW
02B04^⬄^^^R?^mathord^^LEFT RIGHT WHITE ARROW
02B05^⬅^^^R?^mathord^^LEFTWARDS BLACK ARROW
02B06^⬆^^^R?^mathord^^UPWARDS BLACK ARROW
02B07^⬇^^^R?^mathord^^DOWNWARDS BLACK ARROW
02B08^⬈^^^R?^mathord^^NORTH EAST BLACK ARROW
02B09^⬉^^^R?^mathord^^NORTH WEST BLACK ARROW
02B0A^⬊^^^R?^mathord^^SOUTH EAST BLACK ARROW
02B0B^⬋^^^R?^mathord^^SOUTH WEST BLACK ARROW
02B0C^⬌^^^R?^mathord^^LEFT RIGHT BLACK ARROW
02B0D^⬍^^^R?^mathord^^UP DOWN BLACK ARROW
02B0E^⬎^^^R?^mathord^^RIGHTWARDS ARROW WITH TIP DOWNWARDS
02B0F^⬏^^^R?^mathord^^RIGHTWARDS ARROW WITH TIP UPWARDS
02B10^⬐^^^R?^mathord^^LEFTWARDS ARROW WITH TIP DOWNWARDS
02B11^⬑^^^R?^mathord^^LEFTWARDS ARROW WITH TIP UPWARDS
02B12^⬒^^\squaretopblack^N^mathord^^SQUARE WITH TOP HALF BLACK
02B13^⬓^^\squarebotblack^N^mathord^^SQUARE WITH BOTTOM HALF BLACK
02B14^⬔^^\squareurblack^N^mathord^^SQUARE WITH UPPER RIGHT DIAGONAL HALF BLACK
02B15^⬕^^\squarellblack^N^mathord^^SQUARE WITH LOWER LEFT DIAGONAL HALF BLACK
02B16^⬖^^\diamondleftblack^N^mathord^^DIAMOND WITH LEFT HALF BLACK
02B17^⬗^^\diamondrightblack^N^mathord^^DIAMOND WITH RIGHT HALF BLACK
02B18^⬘^^\diamondtopblack^N^mathord^^DIAMOND WITH TOP HALF BLACK
02B19^⬙^^\diamondbotblack^N^mathord^^DIAMOND WITH BOTTOM HALF BLACK
02B1A^⬚^^\dottedsquare^^mathord^^DOTTED SQUARE
02B1B^⬛^\blacksquare^\lgblksquare^^mathord^fourier -amssymb^BLACK LARGE SQUARE
02B1C^⬜^\square^\lgwhtsquare^^mathord^fourier -amssymb^WHITE LARGE SQUARE
02B1D^⬝^^\vysmblksquare^^mathord^^# \centerdot (amssymb), t \Squaredot (marvosym), BLACK VERY SMALL SQUARE
02B1E^⬞^^\vysmwhtsquare^^mathord^^WHITE VERY SMALL SQUARE
02B1F^⬟^^\pentagonblack^^mathord^^BLACK PENTAGON
02B20^⬠^^\pentagon^N^mathord^^WHITE PENTAGON
02B21^⬡^^\varhexagon^N^mathord^^WHITE HEXAGON
02B22^⬢^^\varhexagonblack^N^mathord^^BLACK HEXAGON
02B23^⬣^^\hexagonblack^N^mathord^^HORIZONTAL BLACK HEXAGON
02B24^⬤^^\lgblkcircle^^mathord^^BLACK LARGE CIRCLE
02B25^⬥^^\mdblkdiamond^^mathord^^BLACK MEDIUM DIAMOND
02B26^⬦^^\mdwhtdiamond^^mathord^^WHITE MEDIUM DIAMOND
02B27^⬧^^\mdblklozenge^^mathord^^# \blacklozenge (amssymb), BLACK MEDIUM LOZENGE
02B28^⬨^^\mdwhtlozenge^^mathord^^# \lozenge (amssymb), WHITE MEDIUM LOZENGE
02B29^⬩^^\smblkdiamond^^mathord^^BLACK SMALL DIAMOND
02B2A^⬪^^\smblklozenge^^mathord^^BLACK SMALL LOZENGE
02B2B^⬫^^\smwhtlozenge^^mathord^^WHITE SMALL LOZENGE
02B2C^⬬^^\blkhorzoval^^mathord^^BLACK HORIZONTAL ELLIPSE
02B2D^⬭^^\whthorzoval^^mathord^^WHITE HORIZONTAL ELLIPSE
02B2E^⬮^^\blkvertoval^^mathord^^BLACK VERTICAL ELLIPSE
02B2F^⬯^^\whtvertoval^^mathord^^WHITE VERTICAL ELLIPSE
02B30^⬰^^\circleonleftarrow^^mathrel^^LEFT ARROW WITH SMALL CIRCLE
02B31^⬱^^\leftthreearrows^^mathrel^^THREE LEFTWARDS ARROWS
02B32^⬲^^\leftarrowonoplus^^mathrel^^LEFT ARROW WITH CIRCLED PLUS
02B33^⬳^^\longleftsquigarrow^^mathrel^^LONG LEFTWARDS SQUIGGLE ARROW
02B34^⬴^^\nvtwoheadleftarrow^^mathrel^^LEFTWARDS TWO-HEADED ARROW WITH VERTICAL STROKE
02B35^⬵^^\nVtwoheadleftarrow^^mathrel^^LEFTWARDS TWO-HEADED ARROW WITH DOUBLE VERTICAL STROKE
02B36^⬶^^\twoheadmapsfrom^^mathrel^^LEFTWARDS TWO-HEADED ARROW FROM BAR
02B37^⬷^^\twoheadleftdbkarrow^^mathrel^^leftwards two-headed triple-dash arrow
02B38^⬸^^\leftdotarrow^^mathrel^^LEFTWARDS ARROW WITH DOTTED STEM
02B39^⬹^^\nvleftarrowtail^^mathrel^^LEFTWARDS ARROW WITH TAIL WITH VERTICAL STROKE
02B3A^⬺^^\nVleftarrowtail^^mathrel^^LEFTWARDS ARROW WITH TAIL WITH DOUBLE VERTICAL STROKE
02B3B^⬻^^\twoheadleftarrowtail^^mathrel^^LEFTWARDS TWO-HEADED ARROW WITH TAIL
02B3C^⬼^^\nvtwoheadleftarrowtail^^mathrel^^LEFTWARDS TWO-HEADED ARROW WITH TAIL WITH VERTICAL STROKE
02B3D^⬽^^\nVtwoheadleftarrowtail^^mathrel^^LEFTWARDS TWO-HEADED ARROW WITH TAIL WITH DOUBLE VERTICAL STROKE
02B3E^⬾^^\leftarrowx^^mathrel^^LEFTWARDS ARROW THROUGH X
02B3F^⬿^^\leftcurvedarrow^^mathrel^^WAVE ARROW POINTING DIRECTLY LEFT
02B40^⭀^^\equalleftarrow^^mathrel^^EQUALS SIGN ABOVE LEFTWARDS ARROW
02B41^⭁^^\bsimilarleftarrow^^mathrel^^REVERSE TILDE OPERATOR ABOVE LEFTWARDS ARROW
02B42^⭂^^\leftarrowbackapprox^^mathrel^^LEFTWARDS ARROW ABOVE REVERSE ALMOST EQUAL TO
02B43^⭃^^\rightarrowgtr^^mathrel^^rightwards arrow through less-than
02B44^⭄^^\rightarrowsupset^^mathrel^^rightwards arrow through subset
02B45^⭅^^\LLeftarrow^^mathrel^^LEFTWARDS QUADRUPLE ARROW
02B46^⭆^^\RRightarrow^^mathrel^^RIGHTWARDS QUADRUPLE ARROW
02B47^⭇^^\bsimilarrightarrow^^mathrel^^REVERSE TILDE OPERATOR ABOVE RIGHTWARDS ARROW
02B48^⭈^^\rightarrowbackapprox^^mathrel^^RIGHTWARDS ARROW ABOVE REVERSE ALMOST EQUAL TO
02B49^⭉^^\similarleftarrow^^mathrel^^TILDE OPERATOR ABOVE LEFTWARDS ARROW
02B4A^⭊^^\leftarrowapprox^^mathrel^^LEFTWARDS ARROW ABOVE ALMOST EQUAL TO
02B4B^⭋^^\leftarrowbsimilar^^mathrel^^LEFTWARDS ARROW ABOVE REVERSE TILDE OPERATOR
02B4C^⭌^^\rightarrowbsimilar^^mathrel^^righttwards arrow above reverse tilde operator
02B50^⭐^^\medwhitestar^^mathord^^WHITE MEDIUM STAR
02B51^⭑^^\medblackstar^^mathord^^black medium star
02B52^⭒^^\smwhitestar^^mathord^^WHITE SMALL STAR
02B53^⭓^^\rightpentagonblack^^mathord^^BLACK RIGHT-POINTING PENTAGON
02B54^⭔^^\rightpentagon^^mathord^^WHITE RIGHT-POINTING PENTAGON
03008^〈^^^X^mathopen^^# \langle, LEFT ANGLE BRACKET (deprecated for math use)
03009^〉^^^X^mathclose^^# \rangle, RIGHT ANGLE BRACKET (deprecated for math use)
03012^〒^^\postalmark^^mathord^^POSTAL MARK
03014^〔^^\lbrbrak^^mathopen^^left broken bracket
03015^〕^^\rbrbrak^^mathclose^^right broken bracket
03018^〘^^\Lbrbrak^^mathopen^^LEFT WHITE TORTOISE SHELL BRACKET
03019^〙^^\Rbrbrak^^mathclose^^RIGHT WHITE TORTOISE SHELL BRACKET
0301A^〚^^^X^mathopen^^# \llbracket (stmaryrd), LEFT WHITE SQUARE BRACKET (deprecated for math use)
0301B^〛^^^X^mathclose^^# \rrbracket (stmaryrd), RIGHT WHITE SQUARE BRACKET (deprecated for math use)
03030^〰^^\hzigzag^^mathord^^zigzag
0306E^の^^^N^mathalpha^^HIRAGANA LETTER NO
0FB29^﬩^^^X^mathord^^HEBREW LETTER ALTERNATIVE PLUS SIGN (doesn't have cross shape)
0FE00^︀^^^D^mathaccent^^VARIATION SELECTOR-1
0FE61^﹡^^^X^^^SMALL ASTERISK
0FE62^﹢^^^X^mathord^^SMALL PLUS SIGN
0FE63^﹣^^^X^mathord^^SMALL HYPHEN-MINUS
0FE64^﹤^^^X^mathord^^SMALL LESS-THAN SIGN
0FE65^﹥^^^X^mathord^^SMALL GREATER-THAN SIGN
0FE66^﹦^^^X^mathord^^SMALL EQUALS SIGN
0FE68^﹨^^^X^^^SMALL REVERSE SOLIDUS
0FF0B^+^^^X^mathord^^FULLWIDTH PLUS SIGN
0FF1C^<^^^X^mathord^^FULLWIDTH LESS-THAN SIGN
0FF1D^=^^^X^mathord^^FULLWIDTH EQUALS SIGN
0FF1E^>^^^X^mathord^^FULLWIDTH GREATER-THAN SIGN
0FF3C^\^^^X^^^FULLWIDTH REVERSE SOLIDUS
0FF3E^^^^^X^mathord^^FULLWIDTH CIRCUMFLEX ACCENT
0FF5C^|^^^X^mathord^^FULLWIDTH VERTICAL LINE
0FF5E^~^^^X^mathord^^FULLWIDTH TILDE
0FFE2^¬^^^X^mathord^^FULLWIDTH NOT SIGN
0FFE9^←^^^X^mathord^^HALFWIDTH LEFTWARDS ARROW
0FFEA^↑^^^X^mathord^^HALFWIDTH UPWARDS ARROW
0FFEB^→^^^X^mathord^^HALFWIDTH RIGHTWARDS ARROW
0FFEC^↓^^^X^mathord^^HALFWIDTH DOWNWARDS ARROW
1D400^𝐀^\mathbf{A}^\mbfA^A^mathalpha^^MATHEMATICAL BOLD CAPITAL A
1D401^𝐁^\mathbf{B}^\mbfB^A^mathalpha^^MATHEMATICAL BOLD CAPITAL B
1D402^𝐂^\mathbf{C}^\mbfC^A^mathalpha^^MATHEMATICAL BOLD CAPITAL C
1D403^𝐃^\mathbf{D}^\mbfD^A^mathalpha^^MATHEMATICAL BOLD CAPITAL D
1D404^𝐄^\mathbf{E}^\mbfE^A^mathalpha^^MATHEMATICAL BOLD CAPITAL E
1D405^𝐅^\mathbf{F}^\mbfF^A^mathalpha^^MATHEMATICAL BOLD CAPITAL F
1D406^𝐆^\mathbf{G}^\mbfG^A^mathalpha^^MATHEMATICAL BOLD CAPITAL G
1D407^𝐇^\mathbf{H}^\mbfH^A^mathalpha^^MATHEMATICAL BOLD CAPITAL H
1D408^𝐈^\mathbf{I}^\mbfI^A^mathalpha^^MATHEMATICAL BOLD CAPITAL I
1D409^𝐉^\mathbf{J}^\mbfJ^A^mathalpha^^MATHEMATICAL BOLD CAPITAL J
1D40A^𝐊^\mathbf{K}^\mbfK^A^mathalpha^^MATHEMATICAL BOLD CAPITAL K
1D40B^𝐋^\mathbf{L}^\mbfL^A^mathalpha^^MATHEMATICAL BOLD CAPITAL L
1D40C^𝐌^\mathbf{M}^\mbfM^A^mathalpha^^MATHEMATICAL BOLD CAPITAL M
1D40D^𝐍^\mathbf{N}^\mbfN^A^mathalpha^^MATHEMATICAL BOLD CAPITAL N
1D40E^𝐎^\mathbf{O}^\mbfO^A^mathalpha^^MATHEMATICAL BOLD CAPITAL O
1D40F^𝐏^\mathbf{P}^\mbfP^A^mathalpha^^MATHEMATICAL BOLD CAPITAL P
1D410^𝐐^\mathbf{Q}^\mbfQ^A^mathalpha^^MATHEMATICAL BOLD CAPITAL Q
1D411^𝐑^\mathbf{R}^\mbfR^A^mathalpha^^MATHEMATICAL BOLD CAPITAL R
1D412^𝐒^\mathbf{S}^\mbfS^A^mathalpha^^MATHEMATICAL BOLD CAPITAL S
1D413^𝐓^\mathbf{T}^\mbfT^A^mathalpha^^MATHEMATICAL BOLD CAPITAL T
1D414^𝐔^\mathbf{U}^\mbfU^A^mathalpha^^MATHEMATICAL BOLD CAPITAL U
1D415^𝐕^\mathbf{V}^\mbfV^A^mathalpha^^MATHEMATICAL BOLD CAPITAL V
1D416^𝐖^\mathbf{W}^\mbfW^A^mathalpha^^MATHEMATICAL BOLD CAPITAL W
1D417^𝐗^\mathbf{X}^\mbfX^A^mathalpha^^MATHEMATICAL BOLD CAPITAL X
1D418^𝐘^\mathbf{Y}^\mbfY^A^mathalpha^^MATHEMATICAL BOLD CAPITAL Y
1D419^𝐙^\mathbf{Z}^\mbfZ^A^mathalpha^^MATHEMATICAL BOLD CAPITAL Z
1D41A^𝐚^\mathbf{a}^\mbfa^A^mathalpha^^MATHEMATICAL BOLD SMALL A
1D41B^𝐛^\mathbf{b}^\mbfb^A^mathalpha^^MATHEMATICAL BOLD SMALL B
1D41C^𝐜^\mathbf{c}^\mbfc^A^mathalpha^^MATHEMATICAL BOLD SMALL C
1D41D^𝐝^\mathbf{d}^\mbfd^A^mathalpha^^MATHEMATICAL BOLD SMALL D
1D41E^𝐞^\mathbf{e}^\mbfe^A^mathalpha^^MATHEMATICAL BOLD SMALL E
1D41F^𝐟^\mathbf{f}^\mbff^A^mathalpha^^MATHEMATICAL BOLD SMALL F
1D420^𝐠^\mathbf{g}^\mbfg^A^mathalpha^^MATHEMATICAL BOLD SMALL G
1D421^𝐡^\mathbf{h}^\mbfh^A^mathalpha^^MATHEMATICAL BOLD SMALL H
1D422^𝐢^\mathbf{i}^\mbfi^A^mathalpha^^MATHEMATICAL BOLD SMALL I
1D423^𝐣^\mathbf{j}^\mbfj^A^mathalpha^^MATHEMATICAL BOLD SMALL J
1D424^𝐤^\mathbf{k}^\mbfk^A^mathalpha^^MATHEMATICAL BOLD SMALL K
1D425^𝐥^\mathbf{l}^\mbfl^A^mathalpha^^MATHEMATICAL BOLD SMALL L
1D426^𝐦^\mathbf{m}^\mbfm^A^mathalpha^^MATHEMATICAL BOLD SMALL M
1D427^𝐧^\mathbf{n}^\mbfn^A^mathalpha^^MATHEMATICAL BOLD SMALL N
1D428^𝐨^\mathbf{o}^\mbfo^A^mathalpha^^MATHEMATICAL BOLD SMALL O
1D429^𝐩^\mathbf{p}^\mbfp^A^mathalpha^^MATHEMATICAL BOLD SMALL P
1D42A^𝐪^\mathbf{q}^\mbfq^A^mathalpha^^MATHEMATICAL BOLD SMALL Q
1D42B^𝐫^\mathbf{r}^\mbfr^A^mathalpha^^MATHEMATICAL BOLD SMALL R
1D42C^𝐬^\mathbf{s}^\mbfs^A^mathalpha^^MATHEMATICAL BOLD SMALL S
1D42D^𝐭^\mathbf{t}^\mbft^A^mathalpha^^MATHEMATICAL BOLD SMALL T
1D42E^𝐮^\mathbf{u}^\mbfu^A^mathalpha^^MATHEMATICAL BOLD SMALL U
1D42F^𝐯^\mathbf{v}^\mbfv^A^mathalpha^^MATHEMATICAL BOLD SMALL V
1D430^𝐰^\mathbf{w}^\mbfw^A^mathalpha^^MATHEMATICAL BOLD SMALL W
1D431^𝐱^\mathbf{x}^\mbfx^A^mathalpha^^MATHEMATICAL BOLD SMALL X
1D432^𝐲^\mathbf{y}^\mbfy^A^mathalpha^^MATHEMATICAL BOLD SMALL Y
1D433^𝐳^\mathbf{z}^\mbfz^A^mathalpha^^MATHEMATICAL BOLD SMALL Z
1D434^𝐴^A^\mitA^A^mathalpha^-frenchstyle^= \mathit{A}, MATHEMATICAL ITALIC CAPITAL A
1D435^𝐵^B^\mitB^A^mathalpha^-frenchstyle^= \mathit{B}, MATHEMATICAL ITALIC CAPITAL B
1D436^𝐶^C^\mitC^A^mathalpha^-frenchstyle^= \mathit{C}, MATHEMATICAL ITALIC CAPITAL C
1D437^𝐷^D^\mitD^A^mathalpha^-frenchstyle^= \mathit{D}, MATHEMATICAL ITALIC CAPITAL D
1D438^𝐸^E^\mitE^A^mathalpha^-frenchstyle^= \mathit{E}, MATHEMATICAL ITALIC CAPITAL E
1D439^𝐹^F^\mitF^A^mathalpha^-frenchstyle^= \mathit{F}, MATHEMATICAL ITALIC CAPITAL F
1D43A^𝐺^G^\mitG^A^mathalpha^-frenchstyle^= \mathit{G}, MATHEMATICAL ITALIC CAPITAL G
1D43B^𝐻^H^\mitH^A^mathalpha^-frenchstyle^= \mathit{H}, MATHEMATICAL ITALIC CAPITAL H
1D43C^𝐼^I^\mitI^A^mathalpha^-frenchstyle^= \mathit{I}, MATHEMATICAL ITALIC CAPITAL I
1D43D^𝐽^J^\mitJ^A^mathalpha^-frenchstyle^= \mathit{J}, MATHEMATICAL ITALIC CAPITAL J
1D43E^𝐾^K^\mitK^A^mathalpha^-frenchstyle^= \mathit{K}, MATHEMATICAL ITALIC CAPITAL K
1D43F^𝐿^L^\mitL^A^mathalpha^-frenchstyle^= \mathit{L}, MATHEMATICAL ITALIC CAPITAL L
1D440^𝑀^M^\mitM^A^mathalpha^-frenchstyle^= \mathit{M}, MATHEMATICAL ITALIC CAPITAL M
1D441^𝑁^N^\mitN^A^mathalpha^-frenchstyle^= \mathit{N}, MATHEMATICAL ITALIC CAPITAL N
1D442^𝑂^O^\mitO^A^mathalpha^-frenchstyle^= \mathit{O}, MATHEMATICAL ITALIC CAPITAL O
1D443^𝑃^P^\mitP^A^mathalpha^-frenchstyle^= \mathit{P}, MATHEMATICAL ITALIC CAPITAL P
1D444^𝑄^Q^\mitQ^A^mathalpha^-frenchstyle^= \mathit{Q}, MATHEMATICAL ITALIC CAPITAL Q
1D445^𝑅^R^\mitR^A^mathalpha^-frenchstyle^= \mathit{R}, MATHEMATICAL ITALIC CAPITAL R
1D446^𝑆^S^\mitS^A^mathalpha^-frenchstyle^= \mathit{S}, MATHEMATICAL ITALIC CAPITAL S
1D447^𝑇^T^\mitT^A^mathalpha^-frenchstyle^= \mathit{T}, MATHEMATICAL ITALIC CAPITAL T
1D448^𝑈^U^\mitU^A^mathalpha^-frenchstyle^= \mathit{U}, MATHEMATICAL ITALIC CAPITAL U
1D449^𝑉^V^\mitV^A^mathalpha^-frenchstyle^= \mathit{V}, MATHEMATICAL ITALIC CAPITAL V
1D44A^𝑊^W^\mitW^A^mathalpha^-frenchstyle^= \mathit{W}, MATHEMATICAL ITALIC CAPITAL W
1D44B^𝑋^X^\mitX^A^mathalpha^-frenchstyle^= \mathit{X}, MATHEMATICAL ITALIC CAPITAL X
1D44C^𝑌^Y^\mitY^A^mathalpha^-frenchstyle^= \mathit{Y}, MATHEMATICAL ITALIC CAPITAL Y
1D44D^𝑍^Z^\mitZ^A^mathalpha^-frenchstyle^= \mathit{Z}, MATHEMATICAL ITALIC CAPITAL Z
1D44E^𝑎^a^\mita^A^mathalpha^-uprightstyle^= \mathit{a}, MATHEMATICAL ITALIC SMALL A
1D44F^𝑏^b^\mitb^A^mathalpha^-uprightstyle^= \mathit{b}, MATHEMATICAL ITALIC SMALL B
1D450^𝑐^c^\mitc^A^mathalpha^-uprightstyle^= \mathit{c}, MATHEMATICAL ITALIC SMALL C
1D451^𝑑^d^\mitd^A^mathalpha^-uprightstyle^= \mathit{d}, MATHEMATICAL ITALIC SMALL D
1D452^𝑒^e^\mite^A^mathalpha^-uprightstyle^= \mathit{e}, MATHEMATICAL ITALIC SMALL E
1D453^𝑓^f^\mitf^A^mathalpha^-uprightstyle^= \mathit{f}, MATHEMATICAL ITALIC SMALL F
1D454^𝑔^g^\mitg^A^mathalpha^-uprightstyle^= \mathit{g}, MATHEMATICAL ITALIC SMALL G
1D456^𝑖^i^\miti^A^mathalpha^-uprightstyle^= \mathit{i}, MATHEMATICAL ITALIC SMALL I
1D457^𝑗^j^\mitj^A^mathalpha^-uprightstyle^= \mathit{j}, MATHEMATICAL ITALIC SMALL J
1D458^𝑘^k^\mitk^A^mathalpha^-uprightstyle^= \mathit{k}, MATHEMATICAL ITALIC SMALL K
1D459^𝑙^l^\mitl^A^mathalpha^-uprightstyle^= \mathit{l}, MATHEMATICAL ITALIC SMALL L
1D45A^𝑚^m^\mitm^A^mathalpha^-uprightstyle^= \mathit{m}, MATHEMATICAL ITALIC SMALL M
1D45B^𝑛^n^\mitn^A^mathalpha^-uprightstyle^= \mathit{n}, MATHEMATICAL ITALIC SMALL N
1D45C^𝑜^o^\mito^A^mathalpha^-uprightstyle^= \mathit{o}, MATHEMATICAL ITALIC SMALL O
1D45D^𝑝^p^\mitp^A^mathalpha^-uprightstyle^= \mathit{p}, MATHEMATICAL ITALIC SMALL P
1D45E^𝑞^q^\mitq^A^mathalpha^-uprightstyle^= \mathit{q}, MATHEMATICAL ITALIC SMALL Q
1D45F^𝑟^r^\mitr^A^mathalpha^-uprightstyle^= \mathit{r}, MATHEMATICAL ITALIC SMALL R
1D460^𝑠^s^\mits^A^mathalpha^-uprightstyle^= \mathit{s}, MATHEMATICAL ITALIC SMALL S
1D461^𝑡^t^\mitt^A^mathalpha^-uprightstyle^= \mathit{t}, MATHEMATICAL ITALIC SMALL T
1D462^𝑢^u^\mitu^A^mathalpha^-uprightstyle^= \mathit{u}, MATHEMATICAL ITALIC SMALL U
1D463^𝑣^v^\mitv^A^mathalpha^-uprightstyle^= \mathit{v}, MATHEMATICAL ITALIC SMALL V
1D464^𝑤^w^\mitw^A^mathalpha^-uprightstyle^= \mathit{w}, MATHEMATICAL ITALIC SMALL W
1D465^𝑥^x^\mitx^A^mathalpha^-uprightstyle^= \mathit{x}, MATHEMATICAL ITALIC SMALL X
1D466^𝑦^y^\mity^A^mathalpha^-uprightstyle^= \mathit{y}, MATHEMATICAL ITALIC SMALL Y
1D467^𝑧^z^\mitz^A^mathalpha^-uprightstyle^= \mathit{z}, MATHEMATICAL ITALIC SMALL Z
1D468^𝑨^\mathbfit{A}^\mbfitA^A^mathalpha^isomath^= \mathbold{A} (fixmath), MATHEMATICAL BOLD ITALIC CAPITAL A
1D469^𝑩^\mathbfit{B}^\mbfitB^A^mathalpha^isomath^= \mathbold{B} (fixmath), MATHEMATICAL BOLD ITALIC CAPITAL B
1D46A^𝑪^\mathbfit{C}^\mbfitC^A^mathalpha^isomath^= \mathbold{C} (fixmath), MATHEMATICAL BOLD ITALIC CAPITAL C
1D46B^𝑫^\mathbfit{D}^\mbfitD^A^mathalpha^isomath^= \mathbold{D} (fixmath), MATHEMATICAL BOLD ITALIC CAPITAL D
1D46C^𝑬^\mathbfit{E}^\mbfitE^A^mathalpha^isomath^= \mathbold{E} (fixmath), MATHEMATICAL BOLD ITALIC CAPITAL E
1D46D^𝑭^\mathbfit{F}^\mbfitF^A^mathalpha^isomath^= \mathbold{F} (fixmath), MATHEMATICAL BOLD ITALIC CAPITAL F
1D46E^𝑮^\mathbfit{G}^\mbfitG^A^mathalpha^isomath^= \mathbold{G} (fixmath), MATHEMATICAL BOLD ITALIC CAPITAL G
1D46F^𝑯^\mathbfit{H}^\mbfitH^A^mathalpha^isomath^= \mathbold{H} (fixmath), MATHEMATICAL BOLD ITALIC CAPITAL H
1D470^𝑰^\mathbfit{I}^\mbfitI^A^mathalpha^isomath^= \mathbold{I} (fixmath), MATHEMATICAL BOLD ITALIC CAPITAL I
1D471^𝑱^\mathbfit{J}^\mbfitJ^A^mathalpha^isomath^= \mathbold{J} (fixmath), MATHEMATICAL BOLD ITALIC CAPITAL J
1D472^𝑲^\mathbfit{K}^\mbfitK^A^mathalpha^isomath^= \mathbold{K} (fixmath), MATHEMATICAL BOLD ITALIC CAPITAL K
1D473^𝑳^\mathbfit{L}^\mbfitL^A^mathalpha^isomath^= \mathbold{L} (fixmath), MATHEMATICAL BOLD ITALIC CAPITAL L
1D474^𝑴^\mathbfit{M}^\mbfitM^A^mathalpha^isomath^= \mathbold{M} (fixmath), MATHEMATICAL BOLD ITALIC CAPITAL M
1D475^𝑵^\mathbfit{N}^\mbfitN^A^mathalpha^isomath^= \mathbold{N} (fixmath), MATHEMATICAL BOLD ITALIC CAPITAL N
1D476^𝑶^\mathbfit{O}^\mbfitO^A^mathalpha^isomath^= \mathbold{O} (fixmath), MATHEMATICAL BOLD ITALIC CAPITAL O
1D477^𝑷^\mathbfit{P}^\mbfitP^A^mathalpha^isomath^= \mathbold{P} (fixmath), MATHEMATICAL BOLD ITALIC CAPITAL P
1D478^𝑸^\mathbfit{Q}^\mbfitQ^A^mathalpha^isomath^= \mathbold{Q} (fixmath), MATHEMATICAL BOLD ITALIC CAPITAL Q
1D479^𝑹^\mathbfit{R}^\mbfitR^A^mathalpha^isomath^= \mathbold{R} (fixmath), MATHEMATICAL BOLD ITALIC CAPITAL R
1D47A^𝑺^\mathbfit{S}^\mbfitS^A^mathalpha^isomath^= \mathbold{S} (fixmath), MATHEMATICAL BOLD ITALIC CAPITAL S
1D47B^𝑻^\mathbfit{T}^\mbfitT^A^mathalpha^isomath^= \mathbold{T} (fixmath), MATHEMATICAL BOLD ITALIC CAPITAL T
1D47C^𝑼^\mathbfit{U}^\mbfitU^A^mathalpha^isomath^= \mathbold{U} (fixmath), MATHEMATICAL BOLD ITALIC CAPITAL U
1D47D^𝑽^\mathbfit{V}^\mbfitV^A^mathalpha^isomath^= \mathbold{V} (fixmath), MATHEMATICAL BOLD ITALIC CAPITAL V
1D47E^𝑾^\mathbfit{W}^\mbfitW^A^mathalpha^isomath^= \mathbold{W} (fixmath), MATHEMATICAL BOLD ITALIC CAPITAL W
1D47F^𝑿^\mathbfit{X}^\mbfitX^A^mathalpha^isomath^= \mathbold{X} (fixmath), MATHEMATICAL BOLD ITALIC CAPITAL X
1D480^𝒀^\mathbfit{Y}^\mbfitY^A^mathalpha^isomath^= \mathbold{Y} (fixmath), MATHEMATICAL BOLD ITALIC CAPITAL Y
1D481^𝒁^\mathbfit{Z}^\mbfitZ^A^mathalpha^isomath^= \mathbold{Z} (fixmath), MATHEMATICAL BOLD ITALIC CAPITAL Z
1D482^𝒂^\mathbfit{a}^\mbfita^A^mathalpha^isomath^= \mathbold{a} (fixmath), MATHEMATICAL BOLD ITALIC SMALL A
1D483^𝒃^\mathbfit{b}^\mbfitb^A^mathalpha^isomath^= \mathbold{b} (fixmath), MATHEMATICAL BOLD ITALIC SMALL B
1D484^𝒄^\mathbfit{c}^\mbfitc^A^mathalpha^isomath^= \mathbold{c} (fixmath), MATHEMATICAL BOLD ITALIC SMALL C
1D485^𝒅^\mathbfit{d}^\mbfitd^A^mathalpha^isomath^= \mathbold{d} (fixmath), MATHEMATICAL BOLD ITALIC SMALL D
1D486^𝒆^\mathbfit{e}^\mbfite^A^mathalpha^isomath^= \mathbold{e} (fixmath), MATHEMATICAL BOLD ITALIC SMALL E
1D487^𝒇^\mathbfit{f}^\mbfitf^A^mathalpha^isomath^= \mathbold{f} (fixmath), MATHEMATICAL BOLD ITALIC SMALL F
1D488^𝒈^\mathbfit{g}^\mbfitg^A^mathalpha^isomath^= \mathbold{g} (fixmath), MATHEMATICAL BOLD ITALIC SMALL G
1D489^𝒉^\mathbfit{h}^\mbfith^A^mathalpha^isomath^= \mathbold{h} (fixmath), MATHEMATICAL BOLD ITALIC SMALL H
1D48A^𝒊^\mathbfit{i}^\mbfiti^A^mathalpha^isomath^= \mathbold{i} (fixmath), MATHEMATICAL BOLD ITALIC SMALL I
1D48B^𝒋^\mathbfit{j}^\mbfitj^A^mathalpha^isomath^= \mathbold{j} (fixmath), MATHEMATICAL BOLD ITALIC SMALL J
1D48C^𝒌^\mathbfit{k}^\mbfitk^A^mathalpha^isomath^= \mathbold{k} (fixmath), MATHEMATICAL BOLD ITALIC SMALL K
1D48D^𝒍^\mathbfit{l}^\mbfitl^A^mathalpha^isomath^= \mathbold{l} (fixmath), MATHEMATICAL BOLD ITALIC SMALL L
1D48E^𝒎^\mathbfit{m}^\mbfitm^A^mathalpha^isomath^= \mathbold{m} (fixmath), MATHEMATICAL BOLD ITALIC SMALL M
1D48F^𝒏^\mathbfit{n}^\mbfitn^A^mathalpha^isomath^= \mathbold{n} (fixmath), MATHEMATICAL BOLD ITALIC SMALL N
1D490^𝒐^\mathbfit{o}^\mbfito^A^mathalpha^isomath^= \mathbold{o} (fixmath), MATHEMATICAL BOLD ITALIC SMALL O
1D491^𝒑^\mathbfit{p}^\mbfitp^A^mathalpha^isomath^= \mathbold{p} (fixmath), MATHEMATICAL BOLD ITALIC SMALL P
1D492^𝒒^\mathbfit{q}^\mbfitq^A^mathalpha^isomath^= \mathbold{q} (fixmath), MATHEMATICAL BOLD ITALIC SMALL Q
1D493^𝒓^\mathbfit{r}^\mbfitr^A^mathalpha^isomath^= \mathbold{r} (fixmath), MATHEMATICAL BOLD ITALIC SMALL R
1D494^𝒔^\mathbfit{s}^\mbfits^A^mathalpha^isomath^= \mathbold{s} (fixmath), MATHEMATICAL BOLD ITALIC SMALL S
1D495^𝒕^\mathbfit{t}^\mbfitt^A^mathalpha^isomath^= \mathbold{t} (fixmath), MATHEMATICAL BOLD ITALIC SMALL T
1D496^𝒖^\mathbfit{u}^\mbfitu^A^mathalpha^isomath^= \mathbold{u} (fixmath), MATHEMATICAL BOLD ITALIC SMALL U
1D497^𝒗^\mathbfit{v}^\mbfitv^A^mathalpha^isomath^= \mathbold{v} (fixmath), MATHEMATICAL BOLD ITALIC SMALL V
1D498^𝒘^\mathbfit{w}^\mbfitw^A^mathalpha^isomath^= \mathbold{w} (fixmath), MATHEMATICAL BOLD ITALIC SMALL W
1D499^𝒙^\mathbfit{x}^\mbfitx^A^mathalpha^isomath^= \mathbold{x} (fixmath), MATHEMATICAL BOLD ITALIC SMALL X
1D49A^𝒚^\mathbfit{y}^\mbfity^A^mathalpha^isomath^= \mathbold{y} (fixmath), MATHEMATICAL BOLD ITALIC SMALL Y
1D49B^𝒛^\mathbfit{z}^\mbfitz^A^mathalpha^isomath^= \mathbold{z} (fixmath), MATHEMATICAL BOLD ITALIC SMALL Z
1D49C^𝒜^\mathcal{A}^\mscrA^A^mathalpha^^MATHEMATICAL SCRIPT CAPITAL A
1D49E^𝒞^\mathcal{C}^\mscrC^A^mathalpha^^MATHEMATICAL SCRIPT CAPITAL C
1D49F^𝒟^\mathcal{D}^\mscrD^A^mathalpha^^MATHEMATICAL SCRIPT CAPITAL D
1D4A2^𝒢^\mathcal{G}^\mscrG^A^mathalpha^^MATHEMATICAL SCRIPT CAPITAL G
1D4A5^𝒥^\mathcal{J}^\mscrJ^A^mathalpha^^MATHEMATICAL SCRIPT CAPITAL J
1D4A6^𝒦^\mathcal{K}^\mscrK^A^mathalpha^^MATHEMATICAL SCRIPT CAPITAL K
1D4A9^𝒩^\mathcal{N}^\mscrN^A^mathalpha^^MATHEMATICAL SCRIPT CAPITAL N
1D4AA^𝒪^\mathcal{O}^\mscrO^A^mathalpha^^MATHEMATICAL SCRIPT CAPITAL O
1D4AB^𝒫^\mathcal{P}^\mscrP^A^mathalpha^^MATHEMATICAL SCRIPT CAPITAL P
1D4AC^𝒬^\mathcal{Q}^\mscrQ^A^mathalpha^^MATHEMATICAL SCRIPT CAPITAL Q
1D4AE^𝒮^\mathcal{S}^\mscrS^A^mathalpha^^MATHEMATICAL SCRIPT CAPITAL S
1D4AF^𝒯^\mathcal{T}^\mscrT^A^mathalpha^^MATHEMATICAL SCRIPT CAPITAL T
1D4B0^𝒰^\mathcal{U}^\mscrU^A^mathalpha^^MATHEMATICAL SCRIPT CAPITAL U
1D4B1^𝒱^\mathcal{V}^\mscrV^A^mathalpha^^MATHEMATICAL SCRIPT CAPITAL V
1D4B2^𝒲^\mathcal{W}^\mscrW^A^mathalpha^^MATHEMATICAL SCRIPT CAPITAL W
1D4B3^𝒳^\mathcal{X}^\mscrX^A^mathalpha^^MATHEMATICAL SCRIPT CAPITAL X
1D4B4^𝒴^\mathcal{Y}^\mscrY^A^mathalpha^^MATHEMATICAL SCRIPT CAPITAL Y
1D4B5^𝒵^\mathcal{Z}^\mscrZ^A^mathalpha^^MATHEMATICAL SCRIPT CAPITAL Z
1D4B6^𝒶^\mathcal{a}^\mscra^A^mathalpha^urwchancal^MATHEMATICAL SCRIPT SMALL A
1D4B7^𝒷^\mathcal{b}^\mscrb^A^mathalpha^urwchancal^MATHEMATICAL SCRIPT SMALL B
1D4B8^𝒸^\mathcal{c}^\mscrc^A^mathalpha^urwchancal^MATHEMATICAL SCRIPT SMALL C
1D4B9^𝒹^\mathcal{d}^\mscrd^A^mathalpha^urwchancal^MATHEMATICAL SCRIPT SMALL D
1D4BB^𝒻^\mathcal{f}^\mscrf^A^mathalpha^urwchancal^MATHEMATICAL SCRIPT SMALL F
1D4BD^𝒽^\mathcal{h}^\mscrh^A^mathalpha^urwchancal^MATHEMATICAL SCRIPT SMALL H
1D4BE^𝒾^\mathcal{i}^\mscri^A^mathalpha^urwchancal^MATHEMATICAL SCRIPT SMALL I
1D4BF^𝒿^\mathcal{j}^\mscrj^A^mathalpha^urwchancal^MATHEMATICAL SCRIPT SMALL J
1D4C0^𝓀^\mathcal{k}^\mscrk^A^mathalpha^urwchancal^MATHEMATICAL SCRIPT SMALL K
1D4C1^𝓁^\mathcal{l}^\mscrl^A^mathalpha^urwchancal^MATHEMATICAL SCRIPT SMALL L
1D4C2^𝓂^\mathcal{m}^\mscrm^A^mathalpha^urwchancal^MATHEMATICAL SCRIPT SMALL M
1D4C3^𝓃^\mathcal{n}^\mscrn^A^mathalpha^urwchancal^MATHEMATICAL SCRIPT SMALL N
1D4C5^𝓅^\mathcal{p}^\mscrp^A^mathalpha^urwchancal^MATHEMATICAL SCRIPT SMALL P
1D4C6^𝓆^\mathcal{q}^\mscrq^A^mathalpha^urwchancal^MATHEMATICAL SCRIPT SMALL Q
1D4C7^𝓇^\mathcal{r}^\mscrr^A^mathalpha^urwchancal^MATHEMATICAL SCRIPT SMALL R
1D4C8^𝓈^\mathcal{s}^\mscrs^A^mathalpha^urwchancal^MATHEMATICAL SCRIPT SMALL S
1D4C9^𝓉^\mathcal{t}^\mscrt^A^mathalpha^urwchancal^MATHEMATICAL SCRIPT SMALL T
1D4CA^𝓊^\mathcal{u}^\mscru^A^mathalpha^urwchancal^MATHEMATICAL SCRIPT SMALL U
1D4CB^𝓋^\mathcal{v}^\mscrv^A^mathalpha^urwchancal^MATHEMATICAL SCRIPT SMALL V
1D4CC^𝓌^\mathcal{w}^\mscrw^A^mathalpha^urwchancal^MATHEMATICAL SCRIPT SMALL W
1D4CD^𝓍^\mathcal{x}^\mscrx^A^mathalpha^urwchancal^MATHEMATICAL SCRIPT SMALL X
1D4CE^𝓎^\mathcal{y}^\mscry^A^mathalpha^urwchancal^MATHEMATICAL SCRIPT SMALL Y
1D4CF^𝓏^\mathcal{z}^\mscrz^A^mathalpha^urwchancal^MATHEMATICAL SCRIPT SMALL Z
1D4D0^𝓐^^\mbfscrA^A^mathalpha^^MATHEMATICAL BOLD SCRIPT CAPITAL A
1D4D1^𝓑^^\mbfscrB^A^mathalpha^^MATHEMATICAL BOLD SCRIPT CAPITAL B
1D4D2^𝓒^^\mbfscrC^A^mathalpha^^MATHEMATICAL BOLD SCRIPT CAPITAL C
1D4D3^𝓓^^\mbfscrD^A^mathalpha^^MATHEMATICAL BOLD SCRIPT CAPITAL D
1D4D4^𝓔^^\mbfscrE^A^mathalpha^^MATHEMATICAL BOLD SCRIPT CAPITAL E
1D4D5^𝓕^^\mbfscrF^A^mathalpha^^MATHEMATICAL BOLD SCRIPT CAPITAL F
1D4D6^𝓖^^\mbfscrG^A^mathalpha^^MATHEMATICAL BOLD SCRIPT CAPITAL G
1D4D7^𝓗^^\mbfscrH^A^mathalpha^^MATHEMATICAL BOLD SCRIPT CAPITAL H
1D4D8^𝓘^^\mbfscrI^A^mathalpha^^MATHEMATICAL BOLD SCRIPT CAPITAL I
1D4D9^𝓙^^\mbfscrJ^A^mathalpha^^MATHEMATICAL BOLD SCRIPT CAPITAL J
1D4DA^𝓚^^\mbfscrK^A^mathalpha^^MATHEMATICAL BOLD SCRIPT CAPITAL K
1D4DB^𝓛^^\mbfscrL^A^mathalpha^^MATHEMATICAL BOLD SCRIPT CAPITAL L
1D4DC^𝓜^^\mbfscrM^A^mathalpha^^MATHEMATICAL BOLD SCRIPT CAPITAL M
1D4DD^𝓝^^\mbfscrN^A^mathalpha^^MATHEMATICAL BOLD SCRIPT CAPITAL N
1D4DE^𝓞^^\mbfscrO^A^mathalpha^^MATHEMATICAL BOLD SCRIPT CAPITAL O
1D4DF^𝓟^^\mbfscrP^A^mathalpha^^MATHEMATICAL BOLD SCRIPT CAPITAL P
1D4E0^𝓠^^\mbfscrQ^A^mathalpha^^MATHEMATICAL BOLD SCRIPT CAPITAL Q
1D4E1^𝓡^^\mbfscrR^A^mathalpha^^MATHEMATICAL BOLD SCRIPT CAPITAL R
1D4E2^𝓢^^\mbfscrS^A^mathalpha^^MATHEMATICAL BOLD SCRIPT CAPITAL S
1D4E3^𝓣^^\mbfscrT^A^mathalpha^^MATHEMATICAL BOLD SCRIPT CAPITAL T
1D4E4^𝓤^^\mbfscrU^A^mathalpha^^MATHEMATICAL BOLD SCRIPT CAPITAL U
1D4E5^𝓥^^\mbfscrV^A^mathalpha^^MATHEMATICAL BOLD SCRIPT CAPITAL V
1D4E6^𝓦^^\mbfscrW^A^mathalpha^^MATHEMATICAL BOLD SCRIPT CAPITAL W
1D4E7^𝓧^^\mbfscrX^A^mathalpha^^MATHEMATICAL BOLD SCRIPT CAPITAL X
1D4E8^𝓨^^\mbfscrY^A^mathalpha^^MATHEMATICAL BOLD SCRIPT CAPITAL Y
1D4E9^𝓩^^\mbfscrZ^A^mathalpha^^MATHEMATICAL BOLD SCRIPT CAPITAL Z
1D4EA^𝓪^^\mbfscra^A^mathalpha^^MATHEMATICAL BOLD SCRIPT SMALL A
1D4EB^𝓫^^\mbfscrb^A^mathalpha^^MATHEMATICAL BOLD SCRIPT SMALL B
1D4EC^𝓬^^\mbfscrc^A^mathalpha^^MATHEMATICAL BOLD SCRIPT SMALL C
1D4ED^𝓭^^\mbfscrd^A^mathalpha^^MATHEMATICAL BOLD SCRIPT SMALL D
1D4EE^𝓮^^\mbfscre^A^mathalpha^^MATHEMATICAL BOLD SCRIPT SMALL E
1D4EF^𝓯^^\mbfscrf^A^mathalpha^^MATHEMATICAL BOLD SCRIPT SMALL F
1D4F0^𝓰^^\mbfscrg^A^mathalpha^^MATHEMATICAL BOLD SCRIPT SMALL G
1D4F1^𝓱^^\mbfscrh^A^mathalpha^^MATHEMATICAL BOLD SCRIPT SMALL H
1D4F2^𝓲^^\mbfscri^A^mathalpha^^MATHEMATICAL BOLD SCRIPT SMALL I
1D4F3^𝓳^^\mbfscrj^A^mathalpha^^MATHEMATICAL BOLD SCRIPT SMALL J
1D4F4^𝓴^^\mbfscrk^A^mathalpha^^MATHEMATICAL BOLD SCRIPT SMALL K
1D4F5^𝓵^^\mbfscrl^A^mathalpha^^MATHEMATICAL BOLD SCRIPT SMALL L
1D4F6^𝓶^^\mbfscrm^A^mathalpha^^MATHEMATICAL BOLD SCRIPT SMALL M
1D4F7^𝓷^^\mbfscrn^A^mathalpha^^MATHEMATICAL BOLD SCRIPT SMALL N
1D4F8^𝓸^^\mbfscro^A^mathalpha^^MATHEMATICAL BOLD SCRIPT SMALL O
1D4F9^𝓹^^\mbfscrp^A^mathalpha^^MATHEMATICAL BOLD SCRIPT SMALL P
1D4FA^𝓺^^\mbfscrq^A^mathalpha^^MATHEMATICAL BOLD SCRIPT SMALL Q
1D4FB^𝓻^^\mbfscrr^A^mathalpha^^MATHEMATICAL BOLD SCRIPT SMALL R
1D4FC^𝓼^^\mbfscrs^A^mathalpha^^MATHEMATICAL BOLD SCRIPT SMALL S
1D4FD^𝓽^^\mbfscrt^A^mathalpha^^MATHEMATICAL BOLD SCRIPT SMALL T
1D4FE^𝓾^^\mbfscru^A^mathalpha^^MATHEMATICAL BOLD SCRIPT SMALL U
1D4FF^𝓿^^\mbfscrv^A^mathalpha^^MATHEMATICAL BOLD SCRIPT SMALL V
1D500^𝔀^^\mbfscrw^A^mathalpha^^MATHEMATICAL BOLD SCRIPT SMALL W
1D501^𝔁^^\mbfscrx^A^mathalpha^^MATHEMATICAL BOLD SCRIPT SMALL X
1D502^𝔂^^\mbfscry^A^mathalpha^^MATHEMATICAL BOLD SCRIPT SMALL Y
1D503^𝔃^^\mbfscrz^A^mathalpha^^MATHEMATICAL BOLD SCRIPT SMALL Z
1D504^𝔄^\mathfrak{A}^\mfrakA^A^mathalpha^eufrak^MATHEMATICAL FRAKTUR CAPITAL A
1D505^𝔅^\mathfrak{B}^\mfrakB^A^mathalpha^eufrak^MATHEMATICAL FRAKTUR CAPITAL B
1D507^𝔇^\mathfrak{D}^\mfrakD^A^mathalpha^eufrak^MATHEMATICAL FRAKTUR CAPITAL D
1D508^𝔈^\mathfrak{E}^\mfrakE^A^mathalpha^eufrak^MATHEMATICAL FRAKTUR CAPITAL E
1D509^𝔉^\mathfrak{F}^\mfrakF^A^mathalpha^eufrak^MATHEMATICAL FRAKTUR CAPITAL F
1D50A^𝔊^\mathfrak{G}^\mfrakG^A^mathalpha^eufrak^MATHEMATICAL FRAKTUR CAPITAL G
1D50D^𝔍^\mathfrak{J}^\mfrakJ^A^mathalpha^eufrak^MATHEMATICAL FRAKTUR CAPITAL J
1D50E^𝔎^\mathfrak{K}^\mfrakK^A^mathalpha^eufrak^MATHEMATICAL FRAKTUR CAPITAL K
1D50F^𝔏^\mathfrak{L}^\mfrakL^A^mathalpha^eufrak^MATHEMATICAL FRAKTUR CAPITAL L
1D510^𝔐^\mathfrak{M}^\mfrakM^A^mathalpha^eufrak^MATHEMATICAL FRAKTUR CAPITAL M
1D511^𝔑^\mathfrak{N}^\mfrakN^A^mathalpha^eufrak^MATHEMATICAL FRAKTUR CAPITAL N
1D512^𝔒^\mathfrak{O}^\mfrakO^A^mathalpha^eufrak^MATHEMATICAL FRAKTUR CAPITAL O
1D513^𝔓^\mathfrak{P}^\mfrakP^A^mathalpha^eufrak^MATHEMATICAL FRAKTUR CAPITAL P
1D514^𝔔^\mathfrak{Q}^\mfrakQ^A^mathalpha^eufrak^MATHEMATICAL FRAKTUR CAPITAL Q
1D516^𝔖^\mathfrak{S}^\mfrakS^A^mathalpha^eufrak^MATHEMATICAL FRAKTUR CAPITAL S
1D517^𝔗^\mathfrak{T}^\mfrakT^A^mathalpha^eufrak^MATHEMATICAL FRAKTUR CAPITAL T
1D518^𝔘^\mathfrak{U}^\mfrakU^A^mathalpha^eufrak^MATHEMATICAL FRAKTUR CAPITAL U
1D519^𝔙^\mathfrak{V}^\mfrakV^A^mathalpha^eufrak^MATHEMATICAL FRAKTUR CAPITAL V
1D51A^𝔚^\mathfrak{W}^\mfrakW^A^mathalpha^eufrak^MATHEMATICAL FRAKTUR CAPITAL W
1D51B^𝔛^\mathfrak{X}^\mfrakX^A^mathalpha^eufrak^MATHEMATICAL FRAKTUR CAPITAL X
1D51C^𝔜^\mathfrak{Y}^\mfrakY^A^mathalpha^eufrak^MATHEMATICAL FRAKTUR CAPITAL Y
1D51E^𝔞^\mathfrak{a}^\mfraka^A^mathalpha^eufrak^MATHEMATICAL FRAKTUR SMALL A
1D51F^𝔟^\mathfrak{b}^\mfrakb^A^mathalpha^eufrak^MATHEMATICAL FRAKTUR SMALL B
1D520^𝔠^\mathfrak{c}^\mfrakc^A^mathalpha^eufrak^MATHEMATICAL FRAKTUR SMALL C
1D521^𝔡^\mathfrak{d}^\mfrakd^A^mathalpha^eufrak^MATHEMATICAL FRAKTUR SMALL D
1D522^𝔢^\mathfrak{e}^\mfrake^A^mathalpha^eufrak^MATHEMATICAL FRAKTUR SMALL E
1D523^𝔣^\mathfrak{f}^\mfrakf^A^mathalpha^eufrak^MATHEMATICAL FRAKTUR SMALL F
1D524^𝔤^\mathfrak{g}^\mfrakg^A^mathalpha^eufrak^MATHEMATICAL FRAKTUR SMALL G
1D525^𝔥^\mathfrak{h}^\mfrakh^A^mathalpha^eufrak^MATHEMATICAL FRAKTUR SMALL H
1D526^𝔦^\mathfrak{i}^\mfraki^A^mathalpha^eufrak^MATHEMATICAL FRAKTUR SMALL I
1D527^𝔧^\mathfrak{j}^\mfrakj^A^mathalpha^eufrak^MATHEMATICAL FRAKTUR SMALL J
1D528^𝔨^\mathfrak{k}^\mfrakk^A^mathalpha^eufrak^MATHEMATICAL FRAKTUR SMALL K
1D529^𝔩^\mathfrak{l}^\mfrakl^A^mathalpha^eufrak^MATHEMATICAL FRAKTUR SMALL L
1D52A^𝔪^\mathfrak{m}^\mfrakm^A^mathalpha^eufrak^MATHEMATICAL FRAKTUR SMALL M
1D52B^𝔫^\mathfrak{n}^\mfrakn^A^mathalpha^eufrak^MATHEMATICAL FRAKTUR SMALL N
1D52C^𝔬^\mathfrak{o}^\mfrako^A^mathalpha^eufrak^MATHEMATICAL FRAKTUR SMALL O
1D52D^𝔭^\mathfrak{p}^\mfrakp^A^mathalpha^eufrak^MATHEMATICAL FRAKTUR SMALL P
1D52E^𝔮^\mathfrak{q}^\mfrakq^A^mathalpha^eufrak^MATHEMATICAL FRAKTUR SMALL Q
1D52F^𝔯^\mathfrak{r}^\mfrakr^A^mathalpha^eufrak^MATHEMATICAL FRAKTUR SMALL R
1D530^𝔰^\mathfrak{s}^\mfraks^A^mathalpha^eufrak^MATHEMATICAL FRAKTUR SMALL S
1D531^𝔱^\mathfrak{t}^\mfrakt^A^mathalpha^eufrak^MATHEMATICAL FRAKTUR SMALL T
1D532^𝔲^\mathfrak{u}^\mfraku^A^mathalpha^eufrak^MATHEMATICAL FRAKTUR SMALL U
1D533^𝔳^\mathfrak{v}^\mfrakv^A^mathalpha^eufrak^MATHEMATICAL FRAKTUR SMALL V
1D534^𝔴^\mathfrak{w}^\mfrakw^A^mathalpha^eufrak^MATHEMATICAL FRAKTUR SMALL W
1D535^𝔵^\mathfrak{x}^\mfrakx^A^mathalpha^eufrak^MATHEMATICAL FRAKTUR SMALL X
1D536^𝔶^\mathfrak{y}^\mfraky^A^mathalpha^eufrak^MATHEMATICAL FRAKTUR SMALL Y
1D537^𝔷^\mathfrak{z}^\mfrakz^A^mathalpha^eufrak^MATHEMATICAL FRAKTUR SMALL Z
1D538^𝔸^\mathbb{A}^\BbbA^A^mathalpha^mathbb^= \mathds{A} (dsfont), MATHEMATICAL DOUBLE-STRUCK CAPITAL A
1D539^𝔹^\mathbb{B}^\BbbB^A^mathalpha^mathbb^= \mathds{B} (dsfont), matMATHEMATICAL DOUBLE-STRUCK CAPITAL B
1D53B^𝔻^\mathbb{D}^\BbbD^A^mathalpha^mathbb^= \mathds{D} (dsfont), matMATHEMATICAL DOUBLE-STRUCK CAPITAL D
1D53C^𝔼^\mathbb{E}^\BbbE^A^mathalpha^mathbb^= \mathds{E} (dsfont), matMATHEMATICAL DOUBLE-STRUCK CAPITAL E
1D53D^𝔽^\mathbb{F}^\BbbF^A^mathalpha^mathbb^= \mathds{F} (dsfont), matMATHEMATICAL DOUBLE-STRUCK CAPITAL F
1D53E^𝔾^\mathbb{G}^\BbbG^A^mathalpha^mathbb^= \mathds{G} (dsfont), matMATHEMATICAL DOUBLE-STRUCK CAPITAL G
1D540^𝕀^\mathbb{I}^\BbbI^A^mathalpha^mathbb^= \mathds{I} (dsfont), matMATHEMATICAL DOUBLE-STRUCK CAPITAL I
1D541^𝕁^\mathbb{J}^\BbbJ^A^mathalpha^mathbb^= \mathds{J} (dsfont), matMATHEMATICAL DOUBLE-STRUCK CAPITAL J
1D542^𝕂^\mathbb{K}^\BbbK^A^mathalpha^mathbb^= \mathds{K} (dsfont), matMATHEMATICAL DOUBLE-STRUCK CAPITAL K
1D543^𝕃^\mathbb{L}^\BbbL^A^mathalpha^mathbb^= \mathds{L} (dsfont), matMATHEMATICAL DOUBLE-STRUCK CAPITAL L
1D544^𝕄^\mathbb{M}^\BbbM^A^mathalpha^mathbb^= \mathds{M} (dsfont), matMATHEMATICAL DOUBLE-STRUCK CAPITAL M
1D546^𝕆^\mathbb{O}^\BbbO^A^mathalpha^mathbb^= \mathds{O} (dsfont), matMATHEMATICAL DOUBLE-STRUCK CAPITAL O
1D54A^𝕊^\mathbb{S}^\BbbS^A^mathalpha^mathbb^= \mathds{S} (dsfont), matMATHEMATICAL DOUBLE-STRUCK CAPITAL S
1D54B^𝕋^\mathbb{T}^\BbbT^A^mathalpha^mathbb^= \mathds{T} (dsfont), matMATHEMATICAL DOUBLE-STRUCK CAPITAL T
1D54C^𝕌^\mathbb{U}^\BbbU^A^mathalpha^mathbb^= \mathds{U} (dsfont), matMATHEMATICAL DOUBLE-STRUCK CAPITAL U
1D54D^𝕍^\mathbb{V}^\BbbV^A^mathalpha^mathbb^= \mathds{V} (dsfont), matMATHEMATICAL DOUBLE-STRUCK CAPITAL V
1D54E^𝕎^\mathbb{W}^\BbbW^A^mathalpha^mathbb^= \mathds{W} (dsfont), matMATHEMATICAL DOUBLE-STRUCK CAPITAL W
1D54F^𝕏^\mathbb{X}^\BbbX^A^mathalpha^mathbb^= \mathds{X} (dsfont), matMATHEMATICAL DOUBLE-STRUCK CAPITAL X
1D550^𝕐^\mathbb{Y}^\BbbY^A^mathalpha^mathbb^= \mathds{Y} (dsfont), matMATHEMATICAL DOUBLE-STRUCK CAPITAL Y
1D552^𝕒^\mathbb{a}^\Bbba^A^mathalpha^bbold^MATHEMATICAL DOUBLE-STRUCK SMALL A
1D553^𝕓^\mathbb{b}^\Bbbb^A^mathalpha^bbold^MATHEMATICAL DOUBLE-STRUCK SMALL B
1D554^𝕔^\mathbb{c}^\Bbbc^A^mathalpha^bbold^MATHEMATICAL DOUBLE-STRUCK SMALL C
1D555^𝕕^\mathbb{d}^\Bbbd^A^mathalpha^bbold^MATHEMATICAL DOUBLE-STRUCK SMALL D
1D556^𝕖^\mathbb{e}^\Bbbe^A^mathalpha^bbold^MATHEMATICAL DOUBLE-STRUCK SMALL E
1D557^𝕗^\mathbb{f}^\Bbbf^A^mathalpha^bbold^MATHEMATICAL DOUBLE-STRUCK SMALL F
1D558^𝕘^\mathbb{g}^\Bbbg^A^mathalpha^bbold^MATHEMATICAL DOUBLE-STRUCK SMALL G
1D559^𝕙^\mathbb{h}^\Bbbh^A^mathalpha^bbold^MATHEMATICAL DOUBLE-STRUCK SMALL H
1D55A^𝕚^\mathbb{i}^\Bbbi^A^mathalpha^bbold^MATHEMATICAL DOUBLE-STRUCK SMALL I
1D55B^𝕛^\mathbb{j}^\Bbbj^A^mathalpha^bbold^MATHEMATICAL DOUBLE-STRUCK SMALL J
1D55C^𝕜^\mathbb{k}^\Bbbk^A^mathalpha^bbold fourier^= \Bbbk (amssymb), MATHEMATICAL DOUBLE-STRUCK SMALL K
1D55D^𝕝^\mathbb{l}^\Bbbl^A^mathalpha^bbold^MATHEMATICAL DOUBLE-STRUCK SMALL L
1D55E^𝕞^\mathbb{m}^\Bbbm^A^mathalpha^bbold^MATHEMATICAL DOUBLE-STRUCK SMALL M
1D55F^𝕟^\mathbb{n}^\Bbbn^A^mathalpha^bbold^MATHEMATICAL DOUBLE-STRUCK SMALL N
1D560^𝕠^\mathbb{o}^\Bbbo^A^mathalpha^bbold^MATHEMATICAL DOUBLE-STRUCK SMALL O
1D561^𝕡^\mathbb{p}^\Bbbp^A^mathalpha^bbold^MATHEMATICAL DOUBLE-STRUCK SMALL P
1D562^𝕢^\mathbb{q}^\Bbbq^A^mathalpha^bbold^MATHEMATICAL DOUBLE-STRUCK SMALL Q
1D563^𝕣^\mathbb{r}^\Bbbr^A^mathalpha^bbold^MATHEMATICAL DOUBLE-STRUCK SMALL R
1D564^𝕤^\mathbb{s}^\Bbbs^A^mathalpha^bbold^MATHEMATICAL DOUBLE-STRUCK SMALL S
1D565^𝕥^\mathbb{t}^\Bbbt^A^mathalpha^bbold^MATHEMATICAL DOUBLE-STRUCK SMALL T
1D566^𝕦^\mathbb{u}^\Bbbu^A^mathalpha^bbold^MATHEMATICAL DOUBLE-STRUCK SMALL U
1D567^𝕧^\mathbb{v}^\Bbbv^A^mathalpha^bbold^MATHEMATICAL DOUBLE-STRUCK SMALL V
1D568^𝕨^\mathbb{w}^\Bbbw^A^mathalpha^bbold^MATHEMATICAL DOUBLE-STRUCK SMALL W
1D569^𝕩^\mathbb{x}^\Bbbx^A^mathalpha^bbold^MATHEMATICAL DOUBLE-STRUCK SMALL X
1D56A^𝕪^\mathbb{y}^\Bbby^A^mathalpha^bbold^MATHEMATICAL DOUBLE-STRUCK SMALL Y
1D56B^𝕫^\mathbb{z}^\Bbbz^A^mathalpha^bbold^MATHEMATICAL DOUBLE-STRUCK SMALL Z
1D56C^𝕬^^\mbffrakA^A^mathalpha^^MATHEMATICAL BOLD FRAKTUR CAPITAL A
1D56D^𝕭^^\mbffrakB^A^mathalpha^^MATHEMATICAL BOLD FRAKTUR CAPITAL B
1D56E^𝕮^^\mbffrakC^A^mathalpha^^MATHEMATICAL BOLD FRAKTUR CAPITAL C
1D56F^𝕯^^\mbffrakD^A^mathalpha^^MATHEMATICAL BOLD FRAKTUR CAPITAL D
1D570^𝕰^^\mbffrakE^A^mathalpha^^MATHEMATICAL BOLD FRAKTUR CAPITAL E
1D571^𝕱^^\mbffrakF^A^mathalpha^^MATHEMATICAL BOLD FRAKTUR CAPITAL F
1D572^𝕲^^\mbffrakG^A^mathalpha^^MATHEMATICAL BOLD FRAKTUR CAPITAL G
1D573^𝕳^^\mbffrakH^A^mathalpha^^MATHEMATICAL BOLD FRAKTUR CAPITAL H
1D574^𝕴^^\mbffrakI^A^mathalpha^^MATHEMATICAL BOLD FRAKTUR CAPITAL I
1D575^𝕵^^\mbffrakJ^A^mathalpha^^MATHEMATICAL BOLD FRAKTUR CAPITAL J
1D576^𝕶^^\mbffrakK^A^mathalpha^^MATHEMATICAL BOLD FRAKTUR CAPITAL K
1D577^𝕷^^\mbffrakL^A^mathalpha^^MATHEMATICAL BOLD FRAKTUR CAPITAL L
1D578^𝕸^^\mbffrakM^A^mathalpha^^MATHEMATICAL BOLD FRAKTUR CAPITAL M
1D579^𝕹^^\mbffrakN^A^mathalpha^^MATHEMATICAL BOLD FRAKTUR CAPITAL N
1D57A^𝕺^^\mbffrakO^A^mathalpha^^MATHEMATICAL BOLD FRAKTUR CAPITAL O
1D57B^𝕻^^\mbffrakP^A^mathalpha^^MATHEMATICAL BOLD FRAKTUR CAPITAL P
1D57C^𝕼^^\mbffrakQ^A^mathalpha^^MATHEMATICAL BOLD FRAKTUR CAPITAL Q
1D57D^𝕽^^\mbffrakR^A^mathalpha^^MATHEMATICAL BOLD FRAKTUR CAPITAL R
1D57E^𝕾^^\mbffrakS^A^mathalpha^^MATHEMATICAL BOLD FRAKTUR CAPITAL S
1D57F^𝕿^^\mbffrakT^A^mathalpha^^MATHEMATICAL BOLD FRAKTUR CAPITAL T
1D580^𝖀^^\mbffrakU^A^mathalpha^^MATHEMATICAL BOLD FRAKTUR CAPITAL U
1D581^𝖁^^\mbffrakV^A^mathalpha^^MATHEMATICAL BOLD FRAKTUR CAPITAL V
1D582^𝖂^^\mbffrakW^A^mathalpha^^MATHEMATICAL BOLD FRAKTUR CAPITAL W
1D583^𝖃^^\mbffrakX^A^mathalpha^^MATHEMATICAL BOLD FRAKTUR CAPITAL X
1D584^𝖄^^\mbffrakY^A^mathalpha^^MATHEMATICAL BOLD FRAKTUR CAPITAL Y
1D585^𝖅^^\mbffrakZ^A^mathalpha^^MATHEMATICAL BOLD FRAKTUR CAPITAL Z
1D586^𝖆^^\mbffraka^A^mathalpha^^MATHEMATICAL BOLD FRAKTUR SMALL A
1D587^𝖇^^\mbffrakb^A^mathalpha^^MATHEMATICAL BOLD FRAKTUR SMALL B
1D588^𝖈^^\mbffrakc^A^mathalpha^^MATHEMATICAL BOLD FRAKTUR SMALL C
1D589^𝖉^^\mbffrakd^A^mathalpha^^MATHEMATICAL BOLD FRAKTUR SMALL D
1D58A^𝖊^^\mbffrake^A^mathalpha^^MATHEMATICAL BOLD FRAKTUR SMALL E
1D58B^𝖋^^\mbffrakf^A^mathalpha^^MATHEMATICAL BOLD FRAKTUR SMALL F
1D58C^𝖌^^\mbffrakg^A^mathalpha^^MATHEMATICAL BOLD FRAKTUR SMALL G
1D58D^𝖍^^\mbffrakh^A^mathalpha^^MATHEMATICAL BOLD FRAKTUR SMALL H
1D58E^𝖎^^\mbffraki^A^mathalpha^^MATHEMATICAL BOLD FRAKTUR SMALL I
1D58F^𝖏^^\mbffrakj^A^mathalpha^^MATHEMATICAL BOLD FRAKTUR SMALL J
1D590^𝖐^^\mbffrakk^A^mathalpha^^MATHEMATICAL BOLD FRAKTUR SMALL K
1D591^𝖑^^\mbffrakl^A^mathalpha^^MATHEMATICAL BOLD FRAKTUR SMALL L
1D592^𝖒^^\mbffrakm^A^mathalpha^^MATHEMATICAL BOLD FRAKTUR SMALL M
1D593^𝖓^^\mbffrakn^A^mathalpha^^MATHEMATICAL BOLD FRAKTUR SMALL N
1D594^𝖔^^\mbffrako^A^mathalpha^^MATHEMATICAL BOLD FRAKTUR SMALL O
1D595^𝖕^^\mbffrakp^A^mathalpha^^MATHEMATICAL BOLD FRAKTUR SMALL P
1D596^𝖖^^\mbffrakq^A^mathalpha^^MATHEMATICAL BOLD FRAKTUR SMALL Q
1D597^𝖗^^\mbffrakr^A^mathalpha^^MATHEMATICAL BOLD FRAKTUR SMALL R
1D598^𝖘^^\mbffraks^A^mathalpha^^MATHEMATICAL BOLD FRAKTUR SMALL S
1D599^𝖙^^\mbffrakt^A^mathalpha^^MATHEMATICAL BOLD FRAKTUR SMALL T
1D59A^𝖚^^\mbffraku^A^mathalpha^^MATHEMATICAL BOLD FRAKTUR SMALL U
1D59B^𝖛^^\mbffrakv^A^mathalpha^^MATHEMATICAL BOLD FRAKTUR SMALL V
1D59C^𝖜^^\mbffrakw^A^mathalpha^^MATHEMATICAL BOLD FRAKTUR SMALL W
1D59D^𝖝^^\mbffrakx^A^mathalpha^^MATHEMATICAL BOLD FRAKTUR SMALL X
1D59E^𝖞^^\mbffraky^A^mathalpha^^MATHEMATICAL BOLD FRAKTUR SMALL Y
1D59F^𝖟^^\mbffrakz^A^mathalpha^^MATHEMATICAL BOLD FRAKTUR SMALL Z
1D5A0^𝖠^\mathsf{A}^\msansA^A^mathalpha^^MATHEMATICAL SANS-SERIF CAPITAL A
1D5A1^𝖡^\mathsf{B}^\msansB^A^mathalpha^^MATHEMATICAL SANS-SERIF CAPITAL B
1D5A2^𝖢^\mathsf{C}^\msansC^A^mathalpha^^MATHEMATICAL SANS-SERIF CAPITAL C
1D5A3^𝖣^\mathsf{D}^\msansD^A^mathalpha^^MATHEMATICAL SANS-SERIF CAPITAL D
1D5A4^𝖤^\mathsf{E}^\msansE^A^mathalpha^^MATHEMATICAL SANS-SERIF CAPITAL E
1D5A5^𝖥^\mathsf{F}^\msansF^A^mathalpha^^MATHEMATICAL SANS-SERIF CAPITAL F
1D5A6^𝖦^\mathsf{G}^\msansG^A^mathalpha^^MATHEMATICAL SANS-SERIF CAPITAL G
1D5A7^𝖧^\mathsf{H}^\msansH^A^mathalpha^^MATHEMATICAL SANS-SERIF CAPITAL H
1D5A8^𝖨^\mathsf{I}^\msansI^A^mathalpha^^MATHEMATICAL SANS-SERIF CAPITAL I
1D5A9^𝖩^\mathsf{J}^\msansJ^A^mathalpha^^MATHEMATICAL SANS-SERIF CAPITAL J
1D5AA^𝖪^\mathsf{K}^\msansK^A^mathalpha^^MATHEMATICAL SANS-SERIF CAPITAL K
1D5AB^𝖫^\mathsf{L}^\msansL^A^mathalpha^^MATHEMATICAL SANS-SERIF CAPITAL L
1D5AC^𝖬^\mathsf{M}^\msansM^A^mathalpha^^MATHEMATICAL SANS-SERIF CAPITAL M
1D5AD^𝖭^\mathsf{N}^\msansN^A^mathalpha^^MATHEMATICAL SANS-SERIF CAPITAL N
1D5AE^𝖮^\mathsf{O}^\msansO^A^mathalpha^^MATHEMATICAL SANS-SERIF CAPITAL O
1D5AF^𝖯^\mathsf{P}^\msansP^A^mathalpha^^MATHEMATICAL SANS-SERIF CAPITAL P
1D5B0^𝖰^\mathsf{Q}^\msansQ^A^mathalpha^^MATHEMATICAL SANS-SERIF CAPITAL Q
1D5B1^𝖱^\mathsf{R}^\msansR^A^mathalpha^^MATHEMATICAL SANS-SERIF CAPITAL R
1D5B2^𝖲^\mathsf{S}^\msansS^A^mathalpha^^MATHEMATICAL SANS-SERIF CAPITAL S
1D5B3^𝖳^\mathsf{T}^\msansT^A^mathalpha^^MATHEMATICAL SANS-SERIF CAPITAL T
1D5B4^𝖴^\mathsf{U}^\msansU^A^mathalpha^^MATHEMATICAL SANS-SERIF CAPITAL U
1D5B5^𝖵^\mathsf{V}^\msansV^A^mathalpha^^MATHEMATICAL SANS-SERIF CAPITAL V
1D5B6^𝖶^\mathsf{W}^\msansW^A^mathalpha^^MATHEMATICAL SANS-SERIF CAPITAL W
1D5B7^𝖷^\mathsf{X}^\msansX^A^mathalpha^^MATHEMATICAL SANS-SERIF CAPITAL X
1D5B8^𝖸^\mathsf{Y}^\msansY^A^mathalpha^^MATHEMATICAL SANS-SERIF CAPITAL Y
1D5B9^𝖹^\mathsf{Z}^\msansZ^A^mathalpha^^MATHEMATICAL SANS-SERIF CAPITAL Z
1D5BA^𝖺^\mathsf{a}^\msansa^A^mathalpha^^MATHEMATICAL SANS-SERIF SMALL A
1D5BB^𝖻^\mathsf{b}^\msansb^A^mathalpha^^MATHEMATICAL SANS-SERIF SMALL B
1D5BC^𝖼^\mathsf{c}^\msansc^A^mathalpha^^MATHEMATICAL SANS-SERIF SMALL C
1D5BD^𝖽^\mathsf{d}^\msansd^A^mathalpha^^MATHEMATICAL SANS-SERIF SMALL D
1D5BE^𝖾^\mathsf{e}^\msanse^A^mathalpha^^MATHEMATICAL SANS-SERIF SMALL E
1D5BF^𝖿^\mathsf{f}^\msansf^A^mathalpha^^MATHEMATICAL SANS-SERIF SMALL F
1D5C0^𝗀^\mathsf{g}^\msansg^A^mathalpha^^MATHEMATICAL SANS-SERIF SMALL G
1D5C1^𝗁^\mathsf{h}^\msansh^A^mathalpha^^MATHEMATICAL SANS-SERIF SMALL H
1D5C2^𝗂^\mathsf{i}^\msansi^A^mathalpha^^MATHEMATICAL SANS-SERIF SMALL I
1D5C3^𝗃^\mathsf{j}^\msansj^A^mathalpha^^MATHEMATICAL SANS-SERIF SMALL J
1D5C4^𝗄^\mathsf{k}^\msansk^A^mathalpha^^MATHEMATICAL SANS-SERIF SMALL K
1D5C5^𝗅^\mathsf{l}^\msansl^A^mathalpha^^MATHEMATICAL SANS-SERIF SMALL L
1D5C6^𝗆^\mathsf{m}^\msansm^A^mathalpha^^MATHEMATICAL SANS-SERIF SMALL M
1D5C7^𝗇^\mathsf{n}^\msansn^A^mathalpha^^MATHEMATICAL SANS-SERIF SMALL N
1D5C8^𝗈^\mathsf{o}^\msanso^A^mathalpha^^MATHEMATICAL SANS-SERIF SMALL O
1D5C9^𝗉^\mathsf{p}^\msansp^A^mathalpha^^MATHEMATICAL SANS-SERIF SMALL P
1D5CA^𝗊^\mathsf{q}^\msansq^A^mathalpha^^MATHEMATICAL SANS-SERIF SMALL Q
1D5CB^𝗋^\mathsf{r}^\msansr^A^mathalpha^^MATHEMATICAL SANS-SERIF SMALL R
1D5CC^𝗌^\mathsf{s}^\msanss^A^mathalpha^^MATHEMATICAL SANS-SERIF SMALL S
1D5CD^𝗍^\mathsf{t}^\msanst^A^mathalpha^^MATHEMATICAL SANS-SERIF SMALL T
1D5CE^𝗎^\mathsf{u}^\msansu^A^mathalpha^^MATHEMATICAL SANS-SERIF SMALL U
1D5CF^𝗏^\mathsf{v}^\msansv^A^mathalpha^^MATHEMATICAL SANS-SERIF SMALL V
1D5D0^𝗐^\mathsf{w}^\msansw^A^mathalpha^^MATHEMATICAL SANS-SERIF SMALL W
1D5D1^𝗑^\mathsf{x}^\msansx^A^mathalpha^^MATHEMATICAL SANS-SERIF SMALL X
1D5D2^𝗒^\mathsf{y}^\msansy^A^mathalpha^^MATHEMATICAL SANS-SERIF SMALL Y
1D5D3^𝗓^\mathsf{z}^\msansz^A^mathalpha^^MATHEMATICAL SANS-SERIF SMALL Z
1D5D4^𝗔^\mathsfbf{A}^\mbfsansA^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD CAPITAL A
1D5D5^𝗕^\mathsfbf{B}^\mbfsansB^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD CAPITAL B
1D5D6^𝗖^\mathsfbf{C}^\mbfsansC^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD CAPITAL C
1D5D7^𝗗^\mathsfbf{D}^\mbfsansD^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD CAPITAL D
1D5D8^𝗘^\mathsfbf{E}^\mbfsansE^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD CAPITAL E
1D5D9^𝗙^\mathsfbf{F}^\mbfsansF^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD CAPITAL F
1D5DA^𝗚^\mathsfbf{G}^\mbfsansG^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD CAPITAL G
1D5DB^𝗛^\mathsfbf{H}^\mbfsansH^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD CAPITAL H
1D5DC^𝗜^\mathsfbf{I}^\mbfsansI^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD CAPITAL I
1D5DD^𝗝^\mathsfbf{J}^\mbfsansJ^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD CAPITAL J
1D5DE^𝗞^\mathsfbf{K}^\mbfsansK^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD CAPITAL K
1D5DF^𝗟^\mathsfbf{L}^\mbfsansL^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD CAPITAL L
1D5E0^𝗠^\mathsfbf{M}^\mbfsansM^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD CAPITAL M
1D5E1^𝗡^\mathsfbf{N}^\mbfsansN^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD CAPITAL N
1D5E2^𝗢^\mathsfbf{O}^\mbfsansO^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD CAPITAL O
1D5E3^𝗣^\mathsfbf{P}^\mbfsansP^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD CAPITAL P
1D5E4^𝗤^\mathsfbf{Q}^\mbfsansQ^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD CAPITAL Q
1D5E5^𝗥^\mathsfbf{R}^\mbfsansR^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD CAPITAL R
1D5E6^𝗦^\mathsfbf{S}^\mbfsansS^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD CAPITAL S
1D5E7^𝗧^\mathsfbf{T}^\mbfsansT^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD CAPITAL T
1D5E8^𝗨^\mathsfbf{U}^\mbfsansU^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD CAPITAL U
1D5E9^𝗩^\mathsfbf{V}^\mbfsansV^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD CAPITAL V
1D5EA^𝗪^\mathsfbf{W}^\mbfsansW^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD CAPITAL W
1D5EB^𝗫^\mathsfbf{X}^\mbfsansX^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD CAPITAL X
1D5EC^𝗬^\mathsfbf{Y}^\mbfsansY^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD CAPITAL Y
1D5ED^𝗭^\mathsfbf{Z}^\mbfsansZ^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD CAPITAL Z
1D5EE^𝗮^\mathsfbf{a}^\mbfsansa^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD SMALL A
1D5EF^𝗯^\mathsfbf{b}^\mbfsansb^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD SMALL B
1D5F0^𝗰^\mathsfbf{c}^\mbfsansc^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD SMALL C
1D5F1^𝗱^\mathsfbf{d}^\mbfsansd^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD SMALL D
1D5F2^𝗲^\mathsfbf{e}^\mbfsanse^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD SMALL E
1D5F3^𝗳^\mathsfbf{f}^\mbfsansf^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD SMALL F
1D5F4^𝗴^\mathsfbf{g}^\mbfsansg^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD SMALL G
1D5F5^𝗵^\mathsfbf{h}^\mbfsansh^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD SMALL H
1D5F6^𝗶^\mathsfbf{i}^\mbfsansi^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD SMALL I
1D5F7^𝗷^\mathsfbf{j}^\mbfsansj^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD SMALL J
1D5F8^𝗸^\mathsfbf{k}^\mbfsansk^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD SMALL K
1D5F9^𝗹^\mathsfbf{l}^\mbfsansl^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD SMALL L
1D5FA^𝗺^\mathsfbf{m}^\mbfsansm^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD SMALL M
1D5FB^𝗻^\mathsfbf{n}^\mbfsansn^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD SMALL N
1D5FC^𝗼^\mathsfbf{o}^\mbfsanso^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD SMALL O
1D5FD^𝗽^\mathsfbf{p}^\mbfsansp^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD SMALL P
1D5FE^𝗾^\mathsfbf{q}^\mbfsansq^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD SMALL Q
1D5FF^𝗿^\mathsfbf{r}^\mbfsansr^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD SMALL R
1D600^𝘀^\mathsfbf{s}^\mbfsanss^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD SMALL S
1D601^𝘁^\mathsfbf{t}^\mbfsanst^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD SMALL T
1D602^𝘂^\mathsfbf{u}^\mbfsansu^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD SMALL U
1D603^𝘃^\mathsfbf{v}^\mbfsansv^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD SMALL V
1D604^𝘄^\mathsfbf{w}^\mbfsansw^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD SMALL W
1D605^𝘅^\mathsfbf{x}^\mbfsansx^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD SMALL X
1D606^𝘆^\mathsfbf{y}^\mbfsansy^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD SMALL Y
1D607^𝘇^\mathsfbf{z}^\mbfsansz^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD SMALL Z
1D608^𝘈^\mathsfit{A}^\mitsansA^A^mathalpha^omlmathsfit^MATHEMATICAL SANS-SERIF ITALIC CAPITAL A
1D609^𝘉^\mathsfit{B}^\mitsansB^A^mathalpha^omlmathsfit^MATHEMATICAL SANS-SERIF ITALIC CAPITAL B
1D60A^𝘊^\mathsfit{C}^\mitsansC^A^mathalpha^omlmathsfit^MATHEMATICAL SANS-SERIF ITALIC CAPITAL C
1D60B^𝘋^\mathsfit{D}^\mitsansD^A^mathalpha^omlmathsfit^MATHEMATICAL SANS-SERIF ITALIC CAPITAL D
1D60C^𝘌^\mathsfit{E}^\mitsansE^A^mathalpha^omlmathsfit^MATHEMATICAL SANS-SERIF ITALIC CAPITAL E
1D60D^𝘍^\mathsfit{F}^\mitsansF^A^mathalpha^omlmathsfit^MATHEMATICAL SANS-SERIF ITALIC CAPITAL F
1D60E^𝘎^\mathsfit{G}^\mitsansG^A^mathalpha^omlmathsfit^MATHEMATICAL SANS-SERIF ITALIC CAPITAL G
1D60F^𝘏^\mathsfit{H}^\mitsansH^A^mathalpha^omlmathsfit^MATHEMATICAL SANS-SERIF ITALIC CAPITAL H
1D610^𝘐^\mathsfit{I}^\mitsansI^A^mathalpha^omlmathsfit^MATHEMATICAL SANS-SERIF ITALIC CAPITAL I
1D611^𝘑^\mathsfit{J}^\mitsansJ^A^mathalpha^omlmathsfit^MATHEMATICAL SANS-SERIF ITALIC CAPITAL J
1D612^𝘒^\mathsfit{K}^\mitsansK^A^mathalpha^omlmathsfit^MATHEMATICAL SANS-SERIF ITALIC CAPITAL K
1D613^𝘓^\mathsfit{L}^\mitsansL^A^mathalpha^omlmathsfit^MATHEMATICAL SANS-SERIF ITALIC CAPITAL L
1D614^𝘔^\mathsfit{M}^\mitsansM^A^mathalpha^omlmathsfit^MATHEMATICAL SANS-SERIF ITALIC CAPITAL M
1D615^𝘕^\mathsfit{N}^\mitsansN^A^mathalpha^omlmathsfit^MATHEMATICAL SANS-SERIF ITALIC CAPITAL N
1D616^𝘖^\mathsfit{O}^\mitsansO^A^mathalpha^omlmathsfit^MATHEMATICAL SANS-SERIF ITALIC CAPITAL O
1D617^𝘗^\mathsfit{P}^\mitsansP^A^mathalpha^omlmathsfit^MATHEMATICAL SANS-SERIF ITALIC CAPITAL P
1D618^𝘘^\mathsfit{Q}^\mitsansQ^A^mathalpha^omlmathsfit^MATHEMATICAL SANS-SERIF ITALIC CAPITAL Q
1D619^𝘙^\mathsfit{R}^\mitsansR^A^mathalpha^omlmathsfit^MATHEMATICAL SANS-SERIF ITALIC CAPITAL R
1D61A^𝘚^\mathsfit{S}^\mitsansS^A^mathalpha^omlmathsfit^MATHEMATICAL SANS-SERIF ITALIC CAPITAL S
1D61B^𝘛^\mathsfit{T}^\mitsansT^A^mathalpha^omlmathsfit^MATHEMATICAL SANS-SERIF ITALIC CAPITAL T
1D61C^𝘜^\mathsfit{U}^\mitsansU^A^mathalpha^omlmathsfit^MATHEMATICAL SANS-SERIF ITALIC CAPITAL U
1D61D^𝘝^\mathsfit{V}^\mitsansV^A^mathalpha^omlmathsfit^MATHEMATICAL SANS-SERIF ITALIC CAPITAL V
1D61E^𝘞^\mathsfit{W}^\mitsansW^A^mathalpha^omlmathsfit^MATHEMATICAL SANS-SERIF ITALIC CAPITAL W
1D61F^𝘟^\mathsfit{X}^\mitsansX^A^mathalpha^omlmathsfit^MATHEMATICAL SANS-SERIF ITALIC CAPITAL X
1D620^𝘠^\mathsfit{Y}^\mitsansY^A^mathalpha^omlmathsfit^MATHEMATICAL SANS-SERIF ITALIC CAPITAL Y
1D621^𝘡^\mathsfit{Z}^\mitsansZ^A^mathalpha^omlmathsfit^MATHEMATICAL SANS-SERIF ITALIC CAPITAL Z
1D622^𝘢^\mathsfit{a}^\mitsansa^A^mathalpha^omlmathsfit^MATHEMATICAL SANS-SERIF ITALIC SMALL A
1D623^𝘣^\mathsfit{b}^\mitsansb^A^mathalpha^omlmathsfit^MATHEMATICAL SANS-SERIF ITALIC SMALL B
1D624^𝘤^\mathsfit{c}^\mitsansc^A^mathalpha^omlmathsfit^MATHEMATICAL SANS-SERIF ITALIC SMALL C
1D625^𝘥^\mathsfit{d}^\mitsansd^A^mathalpha^omlmathsfit^MATHEMATICAL SANS-SERIF ITALIC SMALL D
1D626^𝘦^\mathsfit{e}^\mitsanse^A^mathalpha^omlmathsfit^MATHEMATICAL SANS-SERIF ITALIC SMALL E
1D627^𝘧^\mathsfit{f}^\mitsansf^A^mathalpha^omlmathsfit^MATHEMATICAL SANS-SERIF ITALIC SMALL F
1D628^𝘨^\mathsfit{g}^\mitsansg^A^mathalpha^omlmathsfit^MATHEMATICAL SANS-SERIF ITALIC SMALL G
1D629^𝘩^\mathsfit{h}^\mitsansh^A^mathalpha^omlmathsfit^MATHEMATICAL SANS-SERIF ITALIC SMALL H
1D62A^𝘪^\mathsfit{i}^\mitsansi^A^mathalpha^omlmathsfit^MATHEMATICAL SANS-SERIF ITALIC SMALL I
1D62B^𝘫^\mathsfit{j}^\mitsansj^A^mathalpha^omlmathsfit^MATHEMATICAL SANS-SERIF ITALIC SMALL J
1D62C^𝘬^\mathsfit{k}^\mitsansk^A^mathalpha^omlmathsfit^MATHEMATICAL SANS-SERIF ITALIC SMALL K
1D62D^𝘭^\mathsfit{l}^\mitsansl^A^mathalpha^omlmathsfit^MATHEMATICAL SANS-SERIF ITALIC SMALL L
1D62E^𝘮^\mathsfit{m}^\mitsansm^A^mathalpha^omlmathsfit^MATHEMATICAL SANS-SERIF ITALIC SMALL M
1D62F^𝘯^\mathsfit{n}^\mitsansn^A^mathalpha^omlmathsfit^MATHEMATICAL SANS-SERIF ITALIC SMALL N
1D630^𝘰^\mathsfit{o}^\mitsanso^A^mathalpha^omlmathsfit^MATHEMATICAL SANS-SERIF ITALIC SMALL O
1D631^𝘱^\mathsfit{p}^\mitsansp^A^mathalpha^omlmathsfit^MATHEMATICAL SANS-SERIF ITALIC SMALL P
1D632^𝘲^\mathsfit{q}^\mitsansq^A^mathalpha^omlmathsfit^MATHEMATICAL SANS-SERIF ITALIC SMALL Q
1D633^𝘳^\mathsfit{r}^\mitsansr^A^mathalpha^omlmathsfit^MATHEMATICAL SANS-SERIF ITALIC SMALL R
1D634^𝘴^\mathsfit{s}^\mitsanss^A^mathalpha^omlmathsfit^MATHEMATICAL SANS-SERIF ITALIC SMALL S
1D635^𝘵^\mathsfit{t}^\mitsanst^A^mathalpha^omlmathsfit^MATHEMATICAL SANS-SERIF ITALIC SMALL T
1D636^𝘶^\mathsfit{u}^\mitsansu^A^mathalpha^omlmathsfit^MATHEMATICAL SANS-SERIF ITALIC SMALL U
1D637^𝘷^\mathsfit{v}^\mitsansv^A^mathalpha^omlmathsfit^MATHEMATICAL SANS-SERIF ITALIC SMALL V
1D638^𝘸^\mathsfit{w}^\mitsansw^A^mathalpha^omlmathsfit^MATHEMATICAL SANS-SERIF ITALIC SMALL W
1D639^𝘹^\mathsfit{x}^\mitsansx^A^mathalpha^omlmathsfit^MATHEMATICAL SANS-SERIF ITALIC SMALL X
1D63A^𝘺^\mathsfit{y}^\mitsansy^A^mathalpha^omlmathsfit^MATHEMATICAL SANS-SERIF ITALIC SMALL Y
1D63B^𝘻^\mathsfit{z}^\mitsansz^A^mathalpha^omlmathsfit^MATHEMATICAL SANS-SERIF ITALIC SMALL Z
1D63C^𝘼^\mathsfbfit{A}^\mbfitsansA^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL A
1D63D^𝘽^\mathsfbfit{B}^\mbfitsansB^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL B
1D63E^𝘾^\mathsfbfit{C}^\mbfitsansC^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL C
1D63F^𝘿^\mathsfbfit{D}^\mbfitsansD^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL D
1D640^𝙀^\mathsfbfit{E}^\mbfitsansE^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL E
1D641^𝙁^\mathsfbfit{F}^\mbfitsansF^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL F
1D642^𝙂^\mathsfbfit{G}^\mbfitsansG^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL G
1D643^𝙃^\mathsfbfit{H}^\mbfitsansH^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL H
1D644^𝙄^\mathsfbfit{I}^\mbfitsansI^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL I
1D645^𝙅^\mathsfbfit{J}^\mbfitsansJ^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL J
1D646^𝙆^\mathsfbfit{K}^\mbfitsansK^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL K
1D647^𝙇^\mathsfbfit{L}^\mbfitsansL^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL L
1D648^𝙈^\mathsfbfit{M}^\mbfitsansM^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL M
1D649^𝙉^\mathsfbfit{N}^\mbfitsansN^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL N
1D64A^𝙊^\mathsfbfit{O}^\mbfitsansO^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL O
1D64B^𝙋^\mathsfbfit{P}^\mbfitsansP^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL P
1D64C^𝙌^\mathsfbfit{Q}^\mbfitsansQ^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL Q
1D64D^𝙍^\mathsfbfit{R}^\mbfitsansR^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL R
1D64E^𝙎^\mathsfbfit{S}^\mbfitsansS^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL S
1D64F^𝙏^\mathsfbfit{T}^\mbfitsansT^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL T
1D650^𝙐^\mathsfbfit{U}^\mbfitsansU^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL U
1D651^𝙑^\mathsfbfit{V}^\mbfitsansV^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL V
1D652^𝙒^\mathsfbfit{W}^\mbfitsansW^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL W
1D653^𝙓^\mathsfbfit{X}^\mbfitsansX^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL X
1D654^𝙔^\mathsfbfit{Y}^\mbfitsansY^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL Y
1D655^𝙕^\mathsfbfit{Z}^\mbfitsansZ^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL Z
1D656^𝙖^\mathsfbfit{a}^\mbfitsansa^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL A
1D657^𝙗^\mathsfbfit{b}^\mbfitsansb^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL B
1D658^𝙘^\mathsfbfit{c}^\mbfitsansc^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL C
1D659^𝙙^\mathsfbfit{d}^\mbfitsansd^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL D
1D65A^𝙚^\mathsfbfit{e}^\mbfitsanse^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL E
1D65B^𝙛^\mathsfbfit{f}^\mbfitsansf^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL F
1D65C^𝙜^\mathsfbfit{g}^\mbfitsansg^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL G
1D65D^𝙝^\mathsfbfit{h}^\mbfitsansh^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL H
1D65E^𝙞^\mathsfbfit{i}^\mbfitsansi^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL I
1D65F^𝙟^\mathsfbfit{j}^\mbfitsansj^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL J
1D660^𝙠^\mathsfbfit{k}^\mbfitsansk^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL K
1D661^𝙡^\mathsfbfit{l}^\mbfitsansl^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL L
1D662^𝙢^\mathsfbfit{m}^\mbfitsansm^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL M
1D663^𝙣^\mathsfbfit{n}^\mbfitsansn^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL N
1D664^𝙤^\mathsfbfit{o}^\mbfitsanso^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL O
1D665^𝙥^\mathsfbfit{p}^\mbfitsansp^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL P
1D666^𝙦^\mathsfbfit{q}^\mbfitsansq^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL Q
1D667^𝙧^\mathsfbfit{r}^\mbfitsansr^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL R
1D668^𝙨^\mathsfbfit{s}^\mbfitsanss^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL S
1D669^𝙩^\mathsfbfit{t}^\mbfitsanst^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL T
1D66A^𝙪^\mathsfbfit{u}^\mbfitsansu^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL U
1D66B^𝙫^\mathsfbfit{v}^\mbfitsansv^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL V
1D66C^𝙬^\mathsfbfit{w}^\mbfitsansw^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL W
1D66D^𝙭^\mathsfbfit{x}^\mbfitsansx^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL X
1D66E^𝙮^\mathsfbfit{y}^\mbfitsansy^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL Y
1D66F^𝙯^\mathsfbfit{z}^\mbfitsansz^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL Z
1D670^𝙰^\mathtt{A}^\mttA^A^mathalpha^^MATHEMATICAL MONOSPACE CAPITAL A
1D671^𝙱^\mathtt{B}^\mttB^A^mathalpha^^MATHEMATICAL MONOSPACE CAPITAL B
1D672^𝙲^\mathtt{C}^\mttC^A^mathalpha^^MATHEMATICAL MONOSPACE CAPITAL C
1D673^𝙳^\mathtt{D}^\mttD^A^mathalpha^^MATHEMATICAL MONOSPACE CAPITAL D
1D674^𝙴^\mathtt{E}^\mttE^A^mathalpha^^MATHEMATICAL MONOSPACE CAPITAL E
1D675^𝙵^\mathtt{F}^\mttF^A^mathalpha^^MATHEMATICAL MONOSPACE CAPITAL F
1D676^𝙶^\mathtt{G}^\mttG^A^mathalpha^^MATHEMATICAL MONOSPACE CAPITAL G
1D677^𝙷^\mathtt{H}^\mttH^A^mathalpha^^MATHEMATICAL MONOSPACE CAPITAL H
1D678^𝙸^\mathtt{I}^\mttI^A^mathalpha^^MATHEMATICAL MONOSPACE CAPITAL I
1D679^𝙹^\mathtt{J}^\mttJ^A^mathalpha^^MATHEMATICAL MONOSPACE CAPITAL J
1D67A^𝙺^\mathtt{K}^\mttK^A^mathalpha^^MATHEMATICAL MONOSPACE CAPITAL K
1D67B^𝙻^\mathtt{L}^\mttL^A^mathalpha^^MATHEMATICAL MONOSPACE CAPITAL L
1D67C^𝙼^\mathtt{M}^\mttM^A^mathalpha^^MATHEMATICAL MONOSPACE CAPITAL M
1D67D^𝙽^\mathtt{N}^\mttN^A^mathalpha^^MATHEMATICAL MONOSPACE CAPITAL N
1D67E^𝙾^\mathtt{O}^\mttO^A^mathalpha^^MATHEMATICAL MONOSPACE CAPITAL O
1D67F^𝙿^\mathtt{P}^\mttP^A^mathalpha^^MATHEMATICAL MONOSPACE CAPITAL P
1D680^𝚀^\mathtt{Q}^\mttQ^A^mathalpha^^MATHEMATICAL MONOSPACE CAPITAL Q
1D681^𝚁^\mathtt{R}^\mttR^A^mathalpha^^MATHEMATICAL MONOSPACE CAPITAL R
1D682^𝚂^\mathtt{S}^\mttS^A^mathalpha^^MATHEMATICAL MONOSPACE CAPITAL S
1D683^𝚃^\mathtt{T}^\mttT^A^mathalpha^^MATHEMATICAL MONOSPACE CAPITAL T
1D684^𝚄^\mathtt{U}^\mttU^A^mathalpha^^MATHEMATICAL MONOSPACE CAPITAL U
1D685^𝚅^\mathtt{V}^\mttV^A^mathalpha^^MATHEMATICAL MONOSPACE CAPITAL V
1D686^𝚆^\mathtt{W}^\mttW^A^mathalpha^^MATHEMATICAL MONOSPACE CAPITAL W
1D687^𝚇^\mathtt{X}^\mttX^A^mathalpha^^MATHEMATICAL MONOSPACE CAPITAL X
1D688^𝚈^\mathtt{Y}^\mttY^A^mathalpha^^MATHEMATICAL MONOSPACE CAPITAL Y
1D689^𝚉^\mathtt{Z}^\mttZ^A^mathalpha^^MATHEMATICAL MONOSPACE CAPITAL Z
1D68A^𝚊^\mathtt{a}^\mtta^A^mathalpha^^MATHEMATICAL MONOSPACE SMALL A
1D68B^𝚋^\mathtt{b}^\mttb^A^mathalpha^^MATHEMATICAL MONOSPACE SMALL B
1D68C^𝚌^\mathtt{c}^\mttc^A^mathalpha^^MATHEMATICAL MONOSPACE SMALL C
1D68D^𝚍^\mathtt{d}^\mttd^A^mathalpha^^MATHEMATICAL MONOSPACE SMALL D
1D68E^𝚎^\mathtt{e}^\mtte^A^mathalpha^^MATHEMATICAL MONOSPACE SMALL E
1D68F^𝚏^\mathtt{f}^\mttf^A^mathalpha^^MATHEMATICAL MONOSPACE SMALL F
1D690^𝚐^\mathtt{g}^\mttg^A^mathalpha^^MATHEMATICAL MONOSPACE SMALL G
1D691^𝚑^\mathtt{h}^\mtth^A^mathalpha^^MATHEMATICAL MONOSPACE SMALL H
1D692^𝚒^\mathtt{i}^\mtti^A^mathalpha^^MATHEMATICAL MONOSPACE SMALL I
1D693^𝚓^\mathtt{j}^\mttj^A^mathalpha^^MATHEMATICAL MONOSPACE SMALL J
1D694^𝚔^\mathtt{k}^\mttk^A^mathalpha^^MATHEMATICAL MONOSPACE SMALL K
1D695^𝚕^\mathtt{l}^\mttl^A^mathalpha^^MATHEMATICAL MONOSPACE SMALL L
1D696^𝚖^\mathtt{m}^\mttm^A^mathalpha^^MATHEMATICAL MONOSPACE SMALL M
1D697^𝚗^\mathtt{n}^\mttn^A^mathalpha^^MATHEMATICAL MONOSPACE SMALL N
1D698^𝚘^\mathtt{o}^\mtto^A^mathalpha^^MATHEMATICAL MONOSPACE SMALL O
1D699^𝚙^\mathtt{p}^\mttp^A^mathalpha^^MATHEMATICAL MONOSPACE SMALL P
1D69A^𝚚^\mathtt{q}^\mttq^A^mathalpha^^MATHEMATICAL MONOSPACE SMALL Q
1D69B^𝚛^\mathtt{r}^\mttr^A^mathalpha^^MATHEMATICAL MONOSPACE SMALL R
1D69C^𝚜^\mathtt{s}^\mtts^A^mathalpha^^MATHEMATICAL MONOSPACE SMALL S
1D69D^𝚝^\mathtt{t}^\mttt^A^mathalpha^^MATHEMATICAL MONOSPACE SMALL T
1D69E^𝚞^\mathtt{u}^\mttu^A^mathalpha^^MATHEMATICAL MONOSPACE SMALL U
1D69F^𝚟^\mathtt{v}^\mttv^A^mathalpha^^MATHEMATICAL MONOSPACE SMALL V
1D6A0^𝚠^\mathtt{w}^\mttw^A^mathalpha^^MATHEMATICAL MONOSPACE SMALL W
1D6A1^𝚡^\mathtt{x}^\mttx^A^mathalpha^^MATHEMATICAL MONOSPACE SMALL X
1D6A2^𝚢^\mathtt{y}^\mtty^A^mathalpha^^MATHEMATICAL MONOSPACE SMALL Y
1D6A3^𝚣^\mathtt{z}^\mttz^A^mathalpha^^MATHEMATICAL MONOSPACE SMALL Z
1D6A4^𝚤^\imath^\imath^A^mathalpha^^MATHEMATICAL ITALIC SMALL DOTLESS I
1D6A5^𝚥^\jmath^\jmath^A^mathalpha^^MATHEMATICAL ITALIC SMALL DOTLESS J
1D6A8^𝚨^^\mbfAlpha^A^mathalpha^^MATHEMATICAL BOLD CAPITAL ALPHA
1D6A9^𝚩^^\mbfBeta^A^mathalpha^^MATHEMATICAL BOLD CAPITAL BETA
1D6AA^𝚪^\mathbf{\Gamma}^\mbfGamma^A^mathalpha^-fourier^MATHEMATICAL BOLD CAPITAL GAMMA
1D6AB^𝚫^\mathbf{\Delta}^\mbfDelta^A^mathalpha^-fourier^MATHEMATICAL BOLD CAPITAL DELTA
1D6AC^𝚬^^\mbfEpsilon^A^mathalpha^^MATHEMATICAL BOLD CAPITAL EPSILON
1D6AD^𝚭^^\mbfZeta^A^mathalpha^^MATHEMATICAL BOLD CAPITAL ZETA
1D6AE^𝚮^^\mbfEta^A^mathalpha^^MATHEMATICAL BOLD CAPITAL ETA
1D6AF^𝚯^\mathbf{\Theta}^\mbfTheta^A^mathalpha^-fourier^MATHEMATICAL BOLD CAPITAL THETA
1D6B0^𝚰^^\mbfIota^A^mathalpha^^MATHEMATICAL BOLD CAPITAL IOTA
1D6B1^𝚱^^\mbfKappa^A^mathalpha^^MATHEMATICAL BOLD CAPITAL KAPPA
1D6B2^𝚲^\mathbf{\Lambda}^\mbfLambda^A^mathalpha^-fourier^mathematical bold capital lambda
1D6B3^𝚳^^\mbfMu^A^mathalpha^^MATHEMATICAL BOLD CAPITAL MU
1D6B4^𝚴^^\mbfNu^A^mathalpha^^MATHEMATICAL BOLD CAPITAL NU
1D6B5^𝚵^\mathbf{\Xi}^\mbfXi^A^mathalpha^-fourier^MATHEMATICAL BOLD CAPITAL XI
1D6B6^𝚶^^\mbfOmicron^A^mathalpha^^MATHEMATICAL BOLD CAPITAL OMICRON
1D6B7^𝚷^\mathbf{\Pi}^\mbfPi^A^mathalpha^-fourier^MATHEMATICAL BOLD CAPITAL PI
1D6B8^𝚸^^\mbfRho^A^mathalpha^^MATHEMATICAL BOLD CAPITAL RHO
1D6B9^𝚹^^\mbfvarTheta^A^mathalpha^^MATHEMATICAL BOLD CAPITAL THETA SYMBOL
1D6BA^𝚺^\mathbf{\Sigma}^\mbfSigma^A^mathalpha^-fourier^MATHEMATICAL BOLD CAPITAL SIGMA
1D6BB^𝚻^^\mbfTau^A^mathalpha^^MATHEMATICAL BOLD CAPITAL TAU
1D6BC^𝚼^\mathbf{\Upsilon}^\mbfUpsilon^A^mathalpha^-fourier^MATHEMATICAL BOLD CAPITAL UPSILON
1D6BD^𝚽^\mathbf{\Phi}^\mbfPhi^A^mathalpha^-fourier^MATHEMATICAL BOLD CAPITAL PHI
1D6BE^𝚾^^\mbfChi^A^mathalpha^^MATHEMATICAL BOLD CAPITAL CHI
1D6BF^𝚿^\mathbf{\Psi}^\mbfPsi^A^mathalpha^-fourier^MATHEMATICAL BOLD CAPITAL PSI
1D6C0^𝛀^\mathbf{\Omega}^\mbfOmega^A^mathalpha^-fourier^MATHEMATICAL BOLD CAPITAL OMEGA
1D6C1^𝛁^^\mbfnabla^A^mathord^^MATHEMATICAL BOLD NABLA
1D6C2^𝛂^\mathbf{\alpha}^\mbfalpha^A^mathalpha^omlmathbf^MATHEMATICAL BOLD SMALL ALPHA
1D6C3^𝛃^\mathbf{\beta}^\mbfbeta^A^mathalpha^omlmathbf^MATHEMATICAL BOLD SMALL BETA
1D6C4^𝛄^\mathbf{\gamma}^\mbfgamma^A^mathalpha^omlmathbf^MATHEMATICAL BOLD SMALL GAMMA
1D6C5^𝛅^\mathbf{\delta}^\mbfdelta^A^mathalpha^omlmathbf^MATHEMATICAL BOLD SMALL DELTA
1D6C6^𝛆^\mathbf{\varepsilon}^\mbfepsilon^A^mathalpha^omlmathbf^MATHEMATICAL BOLD SMALL EPSILON
1D6C7^𝛇^\mathbf{\zeta}^\mbfzeta^A^mathalpha^omlmathbf^MATHEMATICAL BOLD SMALL ZETA
1D6C8^𝛈^\mathbf{\eta}^\mbfeta^A^mathalpha^omlmathbf^MATHEMATICAL BOLD SMALL ETA
1D6C9^𝛉^\mathbf{\theta}^\mbftheta^A^mathalpha^omlmathbf^MATHEMATICAL BOLD SMALL THETA
1D6CA^𝛊^\mathbf{\iota}^\mbfiota^A^mathalpha^omlmathbf^MATHEMATICAL BOLD SMALL IOTA
1D6CB^𝛋^\mathbf{\kappa}^\mbfkappa^A^mathalpha^omlmathbf^MATHEMATICAL BOLD SMALL KAPPA
1D6CC^𝛌^\mathbf{\lambda}^\mbflambda^A^mathalpha^omlmathbf^mathematical bold small lambda
1D6CD^𝛍^\mathbf{\mu}^\mbfmu^A^mathalpha^omlmathbf^MATHEMATICAL BOLD SMALL MU
1D6CE^𝛎^\mathbf{\nu}^\mbfnu^A^mathalpha^omlmathbf^MATHEMATICAL BOLD SMALL NU
1D6CF^𝛏^\mathbf{\xi}^\mbfxi^A^mathalpha^omlmathbf^MATHEMATICAL BOLD SMALL XI
1D6D0^𝛐^^\mbfomicron^A^mathalpha^^MATHEMATICAL BOLD SMALL OMICRON
1D6D1^𝛑^\mathbf{\pi}^\mbfpi^A^mathalpha^omlmathbf^MATHEMATICAL BOLD SMALL PI
1D6D2^𝛒^\mathbf{\rho}^\mbfrho^A^mathalpha^omlmathbf^MATHEMATICAL BOLD SMALL RHO
1D6D3^𝛓^\mathbf{\varsigma}^\mbfvarsigma^A^mathalpha^omlmathbf^MATHEMATICAL BOLD SMALL FINAL SIGMA
1D6D4^𝛔^\mathbf{\sigma}^\mbfsigma^A^mathalpha^omlmathbf^MATHEMATICAL BOLD SMALL SIGMA
1D6D5^𝛕^\mathbf{\tau}^\mbftau^A^mathalpha^omlmathbf^MATHEMATICAL BOLD SMALL TAU
1D6D6^𝛖^\mathbf{\upsilon}^\mbfupsilon^A^mathalpha^omlmathbf^MATHEMATICAL BOLD SMALL UPSILON
1D6D7^𝛗^\mathbf{\varphi}^\mbfvarphi^A^mathalpha^omlmathbf^MATHEMATICAL BOLD SMALL PHI
1D6D8^𝛘^\mathbf{\chi}^\mbfchi^A^mathalpha^omlmathbf^MATHEMATICAL BOLD SMALL CHI
1D6D9^𝛙^\mathbf{\psi}^\mbfpsi^A^mathalpha^omlmathbf^MATHEMATICAL BOLD SMALL PSI
1D6DA^𝛚^\mathbf{\omega}^\mbfomega^A^mathalpha^omlmathbf^MATHEMATICAL BOLD SMALL OMEGA
1D6DB^𝛛^^\mbfpartial^A^mathord^^MATHEMATICAL BOLD PARTIAL DIFFERENTIAL
1D6DC^𝛜^\mathbf{\epsilon}^\mbfvarepsilon^A^mathalpha^omlmathbf^MATHEMATICAL BOLD EPSILON SYMBOL
1D6DD^𝛝^\mathbf{\vartheta}^\mbfvartheta^A^mathalpha^omlmathbf^MATHEMATICAL BOLD THETA SYMBOL
1D6DE^𝛞^^\mbfvarkappa^A^mathalpha^^MATHEMATICAL BOLD KAPPA SYMBOL
1D6DF^𝛟^\mathbf{\phi}^\mbfphi^A^mathalpha^omlmathbf^MATHEMATICAL BOLD PHI SYMBOL
1D6E0^𝛠^\mathbf{\varrho}^\mbfvarrho^A^mathalpha^omlmathbf^MATHEMATICAL BOLD RHO SYMBOL
1D6E1^𝛡^\mathbf{\varpi}^\mbfvarpi^A^mathalpha^omlmathbf^MATHEMATICAL BOLD PI SYMBOL
1D6E2^𝛢^^\mitAlpha^A^mathalpha^^MATHEMATICAL ITALIC CAPITAL ALPHA
1D6E3^𝛣^^\mitBeta^A^mathalpha^^MATHEMATICAL ITALIC CAPITAL BETA
1D6E4^𝛤^\Gamma^\mitGamma^A^mathalpha^slantedGreek^= \mathit{\Gamma} (-fourier), = \varGamma (amsmath fourier), MATHEMATICAL ITALIC CAPITAL GAMMA
1D6E5^𝛥^\Delta^\mitDelta^A^mathalpha^slantedGreek^= \mathit{\Delta} (-fourier), = \varDelta (amsmath fourier), MATHEMATICAL ITALIC CAPITAL DELTA
1D6E6^𝛦^^\mitEpsilon^A^mathalpha^^MATHEMATICAL ITALIC CAPITAL EPSILON
1D6E7^𝛧^^\mitZeta^A^mathalpha^^MATHEMATICAL ITALIC CAPITAL ZETA
1D6E8^𝛨^^\mitEta^A^mathalpha^^MATHEMATICAL ITALIC CAPITAL ETA
1D6E9^𝛩^\Theta^\mitTheta^A^mathalpha^slantedGreek^= \mathit{\Theta} (-fourier), = \varTheta (amsmath fourier), MATHEMATICAL ITALIC CAPITAL THETA
1D6EA^𝛪^^\mitIota^A^mathalpha^^MATHEMATICAL ITALIC CAPITAL IOTA
1D6EB^𝛫^^\mitKappa^A^mathalpha^^MATHEMATICAL ITALIC CAPITAL KAPPA
1D6EC^𝛬^\Lambda^\mitLambda^A^mathalpha^slantedGreek^= \mathit{\Lambda} (-fourier), = \varLambda (amsmath fourier), mathematical italic capital lambda
1D6ED^𝛭^^\mitMu^A^mathalpha^^MATHEMATICAL ITALIC CAPITAL MU
1D6EE^𝛮^^\mitNu^A^mathalpha^^MATHEMATICAL ITALIC CAPITAL NU
1D6EF^𝛯^\Xi^\mitXi^A^mathalpha^slantedGreek^= \mathit{\Xi} (-fourier), = \varXi (amsmath fourier), MATHEMATICAL ITALIC CAPITAL XI
1D6F0^𝛰^^\mitOmicron^A^mathalpha^^MATHEMATICAL ITALIC CAPITAL OMICRON
1D6F1^𝛱^\Pi^\mitPi^A^mathalpha^slantedGreek^= \mathit{\Pi} (-fourier), = \varPi (amsmath fourier), MATHEMATICAL ITALIC CAPITAL PI
1D6F2^𝛲^^\mitRho^A^mathalpha^^MATHEMATICAL ITALIC CAPITAL RHO
1D6F3^𝛳^^\mitvarTheta^A^mathalpha^^MATHEMATICAL ITALIC CAPITAL THETA SYMBOL
1D6F4^𝛴^\Sigma^\mitSigma^A^mathalpha^slantedGreek^= \mathit{\Sigma} (-fourier), = \varSigma (amsmath fourier), MATHEMATICAL ITALIC CAPITAL SIGMA
1D6F5^𝛵^^\mitTau^A^mathalpha^^MATHEMATICAL ITALIC CAPITAL TAU
1D6F6^𝛶^\Upsilon^\mitUpsilon^A^mathalpha^slantedGreek^= \mathit{\Upsilon} (-fourier), = \varUpsilon (amsmath fourier), MATHEMATICAL ITALIC CAPITAL UPSILON
1D6F7^𝛷^\Phi^\mitPhi^A^mathalpha^slantedGreek^= \mathit{\Phi} (-fourier), = \varPhi (amsmath fourier), MATHEMATICAL ITALIC CAPITAL PHI
1D6F8^𝛸^^\mitChi^A^mathalpha^^MATHEMATICAL ITALIC CAPITAL CHI
1D6F9^𝛹^\Psi^\mitPsi^A^mathalpha^slantedGreek^= \mathit{\Psi} (-fourier), = \varPsi (amsmath fourier), MATHEMATICAL ITALIC CAPITAL PSI
1D6FA^𝛺^\Omega^\mitOmega^A^mathalpha^slantedGreek^= \mathit{\Omega} (-fourier), = \varOmega (amsmath fourier), MATHEMATICAL ITALIC CAPITAL OMEGA
1D6FB^𝛻^^\mitnabla^A^mathord^^MATHEMATICAL ITALIC NABLA
1D6FC^𝛼^\alpha^\mitalpha^A^mathalpha^^= \mathit{\alpha} (omlmathit), MATHEMATICAL ITALIC SMALL ALPHA
1D6FD^𝛽^\beta^\mitbeta^A^mathalpha^^= \mathit{\beta} (omlmathit), MATHEMATICAL ITALIC SMALL BETA
1D6FE^𝛾^\gamma^\mitgamma^A^mathalpha^^= \mathit{\gamma} (omlmathit), MATHEMATICAL ITALIC SMALL GAMMA
1D6FF^𝛿^\delta^\mitdelta^A^mathalpha^^= \mathit{\delta} (omlmathit), MATHEMATICAL ITALIC SMALL DELTA
1D700^𝜀^\varepsilon^\mitepsilon^A^mathalpha^^= \mathit{\varepsilon} (omlmathit), MATHEMATICAL ITALIC SMALL EPSILON
1D701^𝜁^\zeta^\mitzeta^A^mathalpha^^= \mathit{\zeta} (omlmathit), MATHEMATICAL ITALIC SMALL ZETA
1D702^𝜂^\eta^\miteta^A^mathalpha^^= \mathit{\eta} (omlmathit), MATHEMATICAL ITALIC SMALL ETA
1D703^𝜃^\theta^\mittheta^A^mathalpha^^= \mathit{\theta} (omlmathit), MATHEMATICAL ITALIC SMALL THETA
1D704^𝜄^\iota^\mitiota^A^mathalpha^^= \mathit{\iota} (omlmathit), MATHEMATICAL ITALIC SMALL IOTA
1D705^𝜅^\kappa^\mitkappa^A^mathalpha^^= \mathit{\kappa} (omlmathit), MATHEMATICAL ITALIC SMALL KAPPA
1D706^𝜆^\lambda^\mitlambda^A^mathalpha^^= \mathit{\lambda} (omlmathit), mathematical italic small lambda
1D707^𝜇^\mu^\mitmu^A^mathalpha^^= \mathit{\mu} (omlmathit), MATHEMATICAL ITALIC SMALL MU
1D708^𝜈^\nu^\mitnu^A^mathalpha^^= \mathit{\nu} (omlmathit), MATHEMATICAL ITALIC SMALL NU
1D709^𝜉^\xi^\mitxi^A^mathalpha^^= \mathit{\xi} (omlmathit), MATHEMATICAL ITALIC SMALL XI
1D70A^𝜊^^\mitomicron^A^mathalpha^^MATHEMATICAL ITALIC SMALL OMICRON
1D70B^𝜋^\pi^\mitpi^A^mathalpha^^= \mathit{\pi} (omlmathit), MATHEMATICAL ITALIC SMALL PI
1D70C^𝜌^\rho^\mitrho^A^mathalpha^^= \mathit{\rho} (omlmathit), MATHEMATICAL ITALIC SMALL RHO
1D70D^𝜍^\varsigma^\mitvarsigma^A^mathalpha^^= \mathit{\varsigma} (omlmathit), MATHEMATICAL ITALIC SMALL FINAL SIGMA
1D70E^𝜎^\sigma^\mitsigma^A^mathalpha^^= \mathit{\sigma} (omlmathit), MATHEMATICAL ITALIC SMALL SIGMA
1D70F^𝜏^\tau^\mittau^A^mathalpha^^= \mathit{\tau} (omlmathit), MATHEMATICAL ITALIC SMALL TAU
1D710^𝜐^\upsilon^\mitupsilon^A^mathalpha^^= \mathit{\upsilon} (omlmathit), MATHEMATICAL ITALIC SMALL UPSILON
1D711^𝜑^\varphi^\mitphi^A^mathalpha^^= \mathit{\varphi} (omlmathit), MATHEMATICAL ITALIC SMALL PHI
1D712^𝜒^\chi^\mitchi^A^mathalpha^^= \mathit{\chi} (omlmathit), MATHEMATICAL ITALIC SMALL CHI
1D713^𝜓^\psi^\mitpsi^A^mathalpha^^= \mathit{\psi} (omlmathit), MATHEMATICAL ITALIC SMALL PSI
1D714^𝜔^\omega^\mitomega^A^mathalpha^^= \mathit{\omega} (omlmathit), MATHEMATICAL ITALIC SMALL OMEGA
1D715^𝜕^\partial^\mitpartial^A^mathord^^= \mathit{\partial} (omlmathit), MATHEMATICAL ITALIC PARTIAL DIFFERENTIAL
1D716^𝜖^\epsilon^\mitvarepsilon^A^mathalpha^^= \mathit{\epsilon} (omlmathit), MATHEMATICAL ITALIC EPSILON SYMBOL
1D717^𝜗^\vartheta^\mitvartheta^A^mathalpha^^= \mathit{\vartheta} (omlmathit), MATHEMATICAL ITALIC THETA SYMBOL
1D718^𝜘^\varkappa^\mitvarkappa^A^mathalpha^amssymb^MATHEMATICAL ITALIC KAPPA SYMBOL
1D719^𝜙^\phi^\mitvarphi^A^mathalpha^^= \mathit{\phi} (omlmathit), MATHEMATICAL ITALIC PHI SYMBOL
1D71A^𝜚^\varrho^\mitvarrho^A^mathalpha^^= \mathit{\varrho} (omlmathit), MATHEMATICAL ITALIC RHO SYMBOL
1D71B^𝜛^\varpi^\mitvarpi^A^mathalpha^^= \mathit{\varpi} (omlmathit), MATHEMATICAL ITALIC PI SYMBOL
1D71C^𝜜^^\mbfitAlpha^A^mathalpha^^MATHEMATICAL BOLD ITALIC CAPITAL ALPHA
1D71D^𝜝^^\mbfitBeta^A^mathalpha^^MATHEMATICAL BOLD ITALIC CAPITAL BETA
1D71E^𝜞^\mathbfit{\Gamma}^\mbfitGamma^A^mathalpha^isomath^= \mathbold{\Gamma} (fixmath), MATHEMATICAL BOLD ITALIC CAPITAL GAMMA
1D71F^𝜟^\mathbfit{\Delta}^\mbfitDelta^A^mathalpha^isomath^= \mathbold{\Delta} (fixmath), MATHEMATICAL BOLD ITALIC CAPITAL DELTA
1D720^𝜠^^\mbfitEpsilon^A^mathalpha^^MATHEMATICAL BOLD ITALIC CAPITAL EPSILON
1D721^𝜡^^\mbfitZeta^A^mathalpha^^MATHEMATICAL BOLD ITALIC CAPITAL ZETA
1D722^𝜢^^\mbfitEta^A^mathalpha^^MATHEMATICAL BOLD ITALIC CAPITAL ETA
1D723^𝜣^\mathbfit{\Theta}^\mbfitTheta^A^mathalpha^isomath^= \mathbold{\Theta} (fixmath), MATHEMATICAL BOLD ITALIC CAPITAL THETA
1D724^𝜤^^\mbfitIota^A^mathalpha^^MATHEMATICAL BOLD ITALIC CAPITAL IOTA
1D725^𝜥^^\mbfitKappa^A^mathalpha^^MATHEMATICAL BOLD ITALIC CAPITAL KAPPA
1D726^𝜦^\mathbfit{\Lambda}^\mbfitLambda^A^mathalpha^isomath^= \mathbold{\Lambda} (fixmath), mathematical bold italic capital lambda
1D727^𝜧^^\mbfitMu^A^mathalpha^^MATHEMATICAL BOLD ITALIC CAPITAL MU
1D728^𝜨^^\mbfitNu^A^mathalpha^^MATHEMATICAL BOLD ITALIC CAPITAL NU
1D729^𝜩^\mathbfit{\Xi}^\mbfitXi^A^mathalpha^isomath^= \mathbold{\Xi} (fixmath), MATHEMATICAL BOLD ITALIC CAPITAL XI
1D72A^𝜪^^\mbfitOmicron^A^mathalpha^^MATHEMATICAL BOLD ITALIC CAPITAL OMICRON
1D72B^𝜫^\mathbfit{\Pi}^\mbfitPi^A^mathalpha^isomath^= \mathbold{\Pi} (fixmath), MATHEMATICAL BOLD ITALIC CAPITAL PI
1D72C^𝜬^^\mbfitRho^A^mathalpha^^MATHEMATICAL BOLD ITALIC CAPITAL RHO
1D72D^𝜭^^\mbfitvarTheta^A^mathalpha^^MATHEMATICAL BOLD ITALIC CAPITAL THETA SYMBOL
1D72E^𝜮^\mathbfit{\Sigma}^\mbfitSigma^A^mathalpha^isomath^= \mathbold{\Sigma} (fixmath), MATHEMATICAL BOLD ITALIC CAPITAL SIGMA
1D72F^𝜯^^\mbfitTau^A^mathalpha^^MATHEMATICAL BOLD ITALIC CAPITAL TAU
1D730^𝜰^\mathbfit{\Upsilon}^\mbfitUpsilon^A^mathalpha^isomath^= \mathbold{\Upsilon} (fixmath), MATHEMATICAL BOLD ITALIC CAPITAL UPSILON
1D731^𝜱^\mathbfit{\Phi}^\mbfitPhi^A^mathalpha^isomath^= \mathbold{\Phi} (fixmath), MATHEMATICAL BOLD ITALIC CAPITAL PHI
1D732^𝜲^^\mbfitChi^A^mathalpha^^MATHEMATICAL BOLD ITALIC CAPITAL CHI
1D733^𝜳^\mathbfit{\Psi}^\mbfitPsi^A^mathalpha^isomath^= \mathbold{\Psi} (fixmath), MATHEMATICAL BOLD ITALIC CAPITAL PSI
1D734^𝜴^\mathbfit{\Omega}^\mbfitOmega^A^mathalpha^isomath^= \mathbold{\Omega} (fixmath), MATHEMATICAL BOLD ITALIC CAPITAL OMEGA
1D735^𝜵^^\mbfitnabla^A^mathord^^MATHEMATICAL BOLD ITALIC NABLA
1D736^𝜶^\mathbfit{\alpha}^\mbfitalpha^A^mathalpha^isomath^= \mathbold{\alpha} (fixmath), MATHEMATICAL BOLD ITALIC SMALL ALPHA
1D737^𝜷^\mathbfit{\beta}^\mbfitbeta^A^mathalpha^isomath^= \mathbold{\beta} (fixmath), MATHEMATICAL BOLD ITALIC SMALL BETA
1D738^𝜸^\mathbfit{\gamma}^\mbfitgamma^A^mathalpha^isomath^= \mathbold{\gamma} (fixmath), MATHEMATICAL BOLD ITALIC SMALL GAMMA
1D739^𝜹^\mathbfit{\delta}^\mbfitdelta^A^mathalpha^isomath^= \mathbold{\delta} (fixmath), MATHEMATICAL BOLD ITALIC SMALL DELTA
1D73A^𝜺^\mathbfit{\varepsilon}^\mbfitepsilon^A^mathalpha^isomath^= \mathbold{\varepsilon} (fixmath), MATHEMATICAL BOLD ITALIC SMALL EPSILON
1D73B^𝜻^\mathbfit{\zeta}^\mbfitzeta^A^mathalpha^isomath^= \mathbold{\zeta} (fixmath), MATHEMATICAL BOLD ITALIC SMALL ZETA
1D73C^𝜼^\mathbfit{\eta}^\mbfiteta^A^mathalpha^isomath^= \mathbold{\eta} (fixmath), MATHEMATICAL BOLD ITALIC SMALL ETA
1D73D^𝜽^\mathbfit{\theta}^\mbfittheta^A^mathalpha^isomath^= \mathbold{\theta} (fixmath), MATHEMATICAL BOLD ITALIC SMALL THETA
1D73E^𝜾^\mathbfit{\iota}^\mbfitiota^A^mathalpha^isomath^= \mathbold{\iota} (fixmath), MATHEMATICAL BOLD ITALIC SMALL IOTA
1D73F^𝜿^\mathbfit{\kappa}^\mbfitkappa^A^mathalpha^isomath^= \mathbold{\kappa} (fixmath), MATHEMATICAL BOLD ITALIC SMALL KAPPA
1D740^𝝀^\mathbfit{\lambda}^\mbfitlambda^A^mathalpha^isomath^= \mathbold{\lambda} (fixmath), mathematical bold italic small lambda
1D741^𝝁^\mathbfit{\mu}^\mbfitmu^A^mathalpha^isomath^= \mathbold{\mu} (fixmath), MATHEMATICAL BOLD ITALIC SMALL MU
1D742^𝝂^\mathbfit{\nu}^\mbfitnu^A^mathalpha^isomath^= \mathbold{\nu} (fixmath), MATHEMATICAL BOLD ITALIC SMALL NU
1D743^𝝃^\mathbfit{\xi}^\mbfitxi^A^mathalpha^isomath^= \mathbold{\xi} (fixmath), MATHEMATICAL BOLD ITALIC SMALL XI
1D744^𝝄^^\mbfitomicron^A^mathalpha^^MATHEMATICAL BOLD ITALIC SMALL OMICRON
1D745^𝝅^\mathbfit{\pi}^\mbfitpi^A^mathalpha^isomath^= \mathbold{\pi} (fixmath), MATHEMATICAL BOLD ITALIC SMALL PI
1D746^𝝆^\mathbfit{\rho}^\mbfitrho^A^mathalpha^isomath^= \mathbold{\rho} (fixmath), MATHEMATICAL BOLD ITALIC SMALL RHO
1D747^𝝇^\mathbfit{\varsigma}^\mbfitvarsigma^A^mathalpha^isomath^= \mathbold{\varsigma} (fixmath), MATHEMATICAL BOLD ITALIC SMALL FINAL SIGMA
1D748^𝝈^\mathbfit{\sigma}^\mbfitsigma^A^mathalpha^isomath^= \mathbold{\sigma} (fixmath), MATHEMATICAL BOLD ITALIC SMALL SIGMA
1D749^𝝉^\mathbfit{\tau}^\mbfittau^A^mathalpha^isomath^= \mathbold{\tau} (fixmath), MATHEMATICAL BOLD ITALIC SMALL TAU
1D74A^𝝊^\mathbfit{\upsilon}^\mbfitupsilon^A^mathalpha^isomath^= \mathbold{\upsilon} (fixmath), MATHEMATICAL BOLD ITALIC SMALL UPSILON
1D74B^𝝋^\mathbfit{\varphi}^\mbfitphi^A^mathalpha^isomath^= \mathbold{\varphi} (fixmath), MATHEMATICAL BOLD ITALIC SMALL PHI
1D74C^𝝌^\mathbfit{\chi}^\mbfitchi^A^mathalpha^isomath^= \mathbold{\chi} (fixmath), MATHEMATICAL BOLD ITALIC SMALL CHI
1D74D^𝝍^\mathbfit{\psi}^\mbfitpsi^A^mathalpha^isomath^= \mathbold{\psi} (fixmath), MATHEMATICAL BOLD ITALIC SMALL PSI
1D74E^𝝎^\mathbfit{\omega}^\mbfitomega^A^mathalpha^isomath^= \mathbold{\omega} (fixmath), MATHEMATICAL BOLD ITALIC SMALL OMEGA
1D74F^𝝏^^\mbfitpartial^A^mathord^^MATHEMATICAL BOLD ITALIC PARTIAL DIFFERENTIAL
1D750^𝝐^\mathbfit{\epsilon}^\mbfitvarepsilon^A^mathalpha^isomath^= \mathbold{\epsilon} (fixmath), MATHEMATICAL BOLD ITALIC EPSILON SYMBOL
1D751^𝝑^\mathbfit{\vartheta}^\mbfitvartheta^A^mathalpha^isomath^= \mathbold{\vartheta} (fixmath), MATHEMATICAL BOLD ITALIC THETA SYMBOL
1D752^𝝒^^\mbfitvarkappa^A^mathalpha^^MATHEMATICAL BOLD ITALIC KAPPA SYMBOL
1D753^𝝓^\mathbfit{\phi}^\mbfitvarphi^A^mathalpha^isomath^= \mathbold{\phi} (fixmath), MATHEMATICAL BOLD ITALIC PHI SYMBOL
1D754^𝝔^\mathbfit{\varrho}^\mbfitvarrho^A^mathalpha^isomath^= \mathbold{\varrho} (fixmath), MATHEMATICAL BOLD ITALIC RHO SYMBOL
1D755^𝝕^\mathbfit{\varpi}^\mbfitvarpi^A^mathalpha^isomath^= \mathbold{\varpi} (fixmath), MATHEMATICAL BOLD ITALIC PI SYMBOL
1D756^𝝖^^\mbfsansAlpha^A^mathalpha^^MATHEMATICAL SANS-SERIF BOLD CAPITAL ALPHA
1D757^𝝗^^\mbfsansBeta^A^mathalpha^^MATHEMATICAL SANS-SERIF BOLD CAPITAL BETA
1D758^𝝘^\mathsfbf{\Gamma}^\mbfsansGamma^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD CAPITAL GAMMA
1D759^𝝙^\mathsfbf{\Delta}^\mbfsansDelta^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD CAPITAL DELTA
1D75A^𝝚^^\mbfsansEpsilon^A^mathalpha^^MATHEMATICAL SANS-SERIF BOLD CAPITAL EPSILON
1D75B^𝝛^^\mbfsansZeta^A^mathalpha^^MATHEMATICAL SANS-SERIF BOLD CAPITAL ZETA
1D75C^𝝜^^\mbfsansEta^A^mathalpha^^MATHEMATICAL SANS-SERIF BOLD CAPITAL ETA
1D75D^𝝝^\mathsfbf{\Theta}^\mbfsansTheta^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD CAPITAL THETA
1D75E^𝝞^^\mbfsansIota^A^mathalpha^^MATHEMATICAL SANS-SERIF BOLD CAPITAL IOTA
1D75F^𝝟^^\mbfsansKappa^A^mathalpha^^MATHEMATICAL SANS-SERIF BOLD CAPITAL KAPPA
1D760^𝝠^\mathsfbf{\Lambda}^\mbfsansLambda^A^mathalpha^mathsfbf^mathematical sans-serif bold capital lambda
1D761^𝝡^^\mbfsansMu^A^mathalpha^^MATHEMATICAL SANS-SERIF BOLD CAPITAL MU
1D762^𝝢^^\mbfsansNu^A^mathalpha^^MATHEMATICAL SANS-SERIF BOLD CAPITAL NU
1D763^𝝣^\mathsfbf{\Xi}^\mbfsansXi^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD CAPITAL XI
1D764^𝝤^^\mbfsansOmicron^A^mathalpha^^MATHEMATICAL SANS-SERIF BOLD CAPITAL OMICRON
1D765^𝝥^\mathsfbf{\Pi}^\mbfsansPi^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD CAPITAL PI
1D766^𝝦^^\mbfsansRho^A^mathalpha^^MATHEMATICAL SANS-SERIF BOLD CAPITAL RHO
1D767^𝝧^^\mbfsansvarTheta^A^mathalpha^^MATHEMATICAL SANS-SERIF BOLD CAPITAL THETA SYMBOL
1D768^𝝨^\mathsfbf{\Sigma}^\mbfsansSigma^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD CAPITAL SIGMA
1D769^𝝩^^\mbfsansTau^A^mathalpha^^MATHEMATICAL SANS-SERIF BOLD CAPITAL TAU
1D76A^𝝪^\mathsfbf{\Upsilon}^\mbfsansUpsilon^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD CAPITAL UPSILON
1D76B^𝝫^\mathsfbf{\Phi}^\mbfsansPhi^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD CAPITAL PHI
1D76C^𝝬^^\mbfsansChi^A^mathalpha^^MATHEMATICAL SANS-SERIF BOLD CAPITAL CHI
1D76D^𝝭^\mathsfbf{\Psi}^\mbfsansPsi^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD CAPITAL PSI
1D76E^𝝮^\mathsfbf{\Omega}^\mbfsansOmega^A^mathalpha^mathsfbf^MATHEMATICAL SANS-SERIF BOLD CAPITAL OMEGA
1D76F^𝝯^^\mbfsansnabla^A^mathord^^MATHEMATICAL SANS-SERIF BOLD NABLA
1D770^𝝰^\mathsfbf{\alpha}^\mbfsansalpha^A^mathalpha^omlmathsfbf^MATHEMATICAL SANS-SERIF BOLD SMALL ALPHA
1D771^𝝱^\mathsfbf{\beta}^\mbfsansbeta^A^mathalpha^omlmathsfbf^MATHEMATICAL SANS-SERIF BOLD SMALL BETA
1D772^𝝲^\mathsfbf{\gamma}^\mbfsansgamma^A^mathalpha^omlmathsfbf^MATHEMATICAL SANS-SERIF BOLD SMALL GAMMA
1D773^𝝳^\mathsfbf{\delta}^\mbfsansdelta^A^mathalpha^omlmathsfbf^MATHEMATICAL SANS-SERIF BOLD SMALL DELTA
1D774^𝝴^\mathsfbf{\varepsilon}^\mbfsansepsilon^A^mathalpha^omlmathsfbf^MATHEMATICAL SANS-SERIF BOLD SMALL EPSILON
1D775^𝝵^\mathsfbf{\zeta}^\mbfsanszeta^A^mathalpha^omlmathsfbf^MATHEMATICAL SANS-SERIF BOLD SMALL ZETA
1D776^𝝶^\mathsfbf{\eta}^\mbfsanseta^A^mathalpha^omlmathsfbf^MATHEMATICAL SANS-SERIF BOLD SMALL ETA
1D777^𝝷^\mathsfbf{\theta}^\mbfsanstheta^A^mathalpha^omlmathsfbf^MATHEMATICAL SANS-SERIF BOLD SMALL THETA
1D778^𝝸^\mathsfbf{\iota}^\mbfsansiota^A^mathalpha^omlmathsfbf^MATHEMATICAL SANS-SERIF BOLD SMALL IOTA
1D779^𝝹^\mathsfbf{\kappa}^\mbfsanskappa^A^mathalpha^omlmathsfbf^MATHEMATICAL SANS-SERIF BOLD SMALL KAPPA
1D77A^𝝺^\mathsfbf{\lambda}^\mbfsanslambda^A^mathalpha^omlmathsfbf^mathematical sans-serif bold small lambda
1D77B^𝝻^\mathsfbf{\mu}^\mbfsansmu^A^mathalpha^omlmathsfbf^MATHEMATICAL SANS-SERIF BOLD SMALL MU
1D77C^𝝼^\mathsfbf{\nu}^\mbfsansnu^A^mathalpha^omlmathsfbf^MATHEMATICAL SANS-SERIF BOLD SMALL NU
1D77D^𝝽^\mathsfbf{\xi}^\mbfsansxi^A^mathalpha^omlmathsfbf^MATHEMATICAL SANS-SERIF BOLD SMALL XI
1D77E^𝝾^^\mbfsansomicron^A^mathalpha^^MATHEMATICAL SANS-SERIF BOLD SMALL OMICRON
1D77F^𝝿^\mathsfbf{\pi}^\mbfsanspi^A^mathalpha^omlmathsfbf^MATHEMATICAL SANS-SERIF BOLD SMALL PI
1D780^𝞀^\mathsfbf{\rho}^\mbfsansrho^A^mathalpha^omlmathsfbf^MATHEMATICAL SANS-SERIF BOLD SMALL RHO
1D781^𝞁^\mathsfbf{\varsigma}^\mbfsansvarsigma^A^mathalpha^omlmathsfbf^MATHEMATICAL SANS-SERIF BOLD SMALL FINAL SIGMA
1D782^𝞂^\mathsfbf{\sigma}^\mbfsanssigma^A^mathalpha^omlmathsfbf^MATHEMATICAL SANS-SERIF BOLD SMALL SIGMA
1D783^𝞃^\mathsfbf{\tau}^\mbfsanstau^A^mathalpha^omlmathsfbf^MATHEMATICAL SANS-SERIF BOLD SMALL TAU
1D784^𝞄^\mathsfbf{\upsilon}^\mbfsansupsilon^A^mathalpha^omlmathsfbf^MATHEMATICAL SANS-SERIF BOLD SMALL UPSILON
1D785^𝞅^\mathsfbf{\varphi}^\mbfsansphi^A^mathalpha^omlmathsfbf^MATHEMATICAL SANS-SERIF BOLD SMALL PHI
1D786^𝞆^\mathsfbf{\chi}^\mbfsanschi^A^mathalpha^omlmathsfbf^MATHEMATICAL SANS-SERIF BOLD SMALL CHI
1D787^𝞇^\mathsfbf{\psi}^\mbfsanspsi^A^mathalpha^omlmathsfbf^MATHEMATICAL SANS-SERIF BOLD SMALL PSI
1D788^𝞈^\mathsfbf{\omega}^\mbfsansomega^A^mathalpha^omlmathsfbf^MATHEMATICAL SANS-SERIF BOLD SMALL OMEGA
1D789^𝞉^^\mbfsanspartial^A^mathord^^MATHEMATICAL SANS-SERIF BOLD PARTIAL DIFFERENTIAL
1D78A^𝞊^\mathsfbf{\epsilon}^\mbfsansvarepsilon^A^mathalpha^omlmathsfbf^MATHEMATICAL SANS-SERIF BOLD EPSILON SYMBOL
1D78B^𝞋^\mathsfbf{\vartheta}^\mbfsansvartheta^A^mathalpha^omlmathsfbf^MATHEMATICAL SANS-SERIF BOLD THETA SYMBOL
1D78C^𝞌^^\mbfsansvarkappa^A^mathalpha^^MATHEMATICAL SANS-SERIF BOLD KAPPA SYMBOL
1D78D^𝞍^\mathsfbf{\phi}^\mbfsansvarphi^A^mathalpha^omlmathsfbf^MATHEMATICAL SANS-SERIF BOLD PHI SYMBOL
1D78E^𝞎^\mathsfbf{\varrho}^\mbfsansvarrho^A^mathalpha^omlmathsfbf^MATHEMATICAL SANS-SERIF BOLD RHO SYMBOL
1D78F^𝞏^\mathsfbf{\varpi}^\mbfsansvarpi^A^mathalpha^omlmathsfbf^MATHEMATICAL SANS-SERIF BOLD PI SYMBOL
1D790^𝞐^^\mbfitsansAlpha^A^mathalpha^^MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL ALPHA
1D791^𝞑^^\mbfitsansBeta^A^mathalpha^^MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL BETA
1D792^𝞒^\mathsfbfit{\Gamma}^\mbfitsansGamma^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL GAMMA
1D793^𝞓^\mathsfbfit{\Delta}^\mbfitsansDelta^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL DELTA
1D794^𝞔^^\mbfitsansEpsilon^A^mathalpha^^MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL EPSILON
1D795^𝞕^^\mbfitsansZeta^A^mathalpha^^MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL ZETA
1D796^𝞖^^\mbfitsansEta^A^mathalpha^^MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL ETA
1D797^𝞗^\mathsfbfit{\Theta}^\mbfitsansTheta^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL THETA
1D798^𝞘^^\mbfitsansIota^A^mathalpha^^MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL IOTA
1D799^𝞙^^\mbfitsansKappa^A^mathalpha^^MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL KAPPA
1D79A^𝞚^\mathsfbfit{\Lambda}^\mbfitsansLambda^A^mathalpha^isomath^mathematical sans-serif bold italic capital lambda
1D79B^𝞛^^\mbfitsansMu^A^mathalpha^^MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL MU
1D79C^𝞜^^\mbfitsansNu^A^mathalpha^^MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL NU
1D79D^𝞝^\mathsfbfit{\Xi}^\mbfitsansXi^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL XI
1D79E^𝞞^^\mbfitsansOmicron^A^mathalpha^^MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL OMICRON
1D79F^𝞟^\mathsfbfit{\Pi}^\mbfitsansPi^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL PI
1D7A0^𝞠^^\mbfitsansRho^A^mathalpha^^MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL RHO
1D7A1^𝞡^^\mbfitsansvarTheta^A^mathalpha^^MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL THETA SYMBOL
1D7A2^𝞢^\mathsfbfit{\Sigma}^\mbfitsansSigma^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL SIGMA
1D7A3^𝞣^^\mbfitsansTau^A^mathalpha^^MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL TAU
1D7A4^𝞤^\mathsfbfit{\Upsilon}^\mbfitsansUpsilon^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL UPSILON
1D7A5^𝞥^\mathsfbfit{\Phi}^\mbfitsansPhi^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL PHI
1D7A6^𝞦^^\mbfitsansChi^A^mathalpha^^MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL CHI
1D7A7^𝞧^\mathsfbfit{\Psi}^\mbfitsansPsi^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL PSI
1D7A8^𝞨^\mathsfbfit{\Omega}^\mbfitsansOmega^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL OMEGA
1D7A9^𝞩^^\mbfitsansnabla^A^mathord^^MATHEMATICAL SANS-SERIF BOLD ITALIC NABLA
1D7AA^𝞪^\mathsfbfit{\alpha}^\mbfitsansalpha^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL ALPHA
1D7AB^𝞫^\mathsfbfit{\beta}^\mbfitsansbeta^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL BETA
1D7AC^𝞬^\mathsfbfit{\gamma}^\mbfitsansgamma^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL GAMMA
1D7AD^𝞭^\mathsfbfit{\delta}^\mbfitsansdelta^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL DELTA
1D7AE^𝞮^\mathsfbfit{\varepsilon}^\mbfitsansepsilon^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL EPSILON
1D7AF^𝞯^\mathsfbfit{\zeta}^\mbfitsanszeta^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL ZETA
1D7B0^𝞰^\mathsfbfit{\eta}^\mbfitsanseta^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL ETA
1D7B1^𝞱^\mathsfbfit{\theta}^\mbfitsanstheta^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL THETA
1D7B2^𝞲^\mathsfbfit{\iota}^\mbfitsansiota^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL IOTA
1D7B3^𝞳^\mathsfbfit{\kappa}^\mbfitsanskappa^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL KAPPA
1D7B4^𝞴^\mathsfbfit{\lambda}^\mbfitsanslambda^A^mathalpha^isomath^mathematical sans-serif bold italic small lambda
1D7B5^𝞵^\mathsfbfit{\mu}^\mbfitsansmu^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL MU
1D7B6^𝞶^\mathsfbfit{\nu}^\mbfitsansnu^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL NU
1D7B7^𝞷^\mathsfbfit{\xi}^\mbfitsansxi^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL XI
1D7B8^𝞸^^\mbfitsansomicron^A^mathalpha^^MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL OMICRON
1D7B9^𝞹^\mathsfbfit{\pi}^\mbfitsanspi^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL PI
1D7BA^𝞺^\mathsfbfit{\rho}^\mbfitsansrho^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL RHO
1D7BB^𝞻^\mathsfbfit{\varsigma}^\mbfitsansvarsigma^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL FINAL SIGMA
1D7BC^𝞼^\mathsfbfit{\sigma}^\mbfitsanssigma^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL SIGMA
1D7BD^𝞽^\mathsfbfit{\tau}^\mbfitsanstau^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL TAU
1D7BE^𝞾^\mathsfbfit{\upsilon}^\mbfitsansupsilon^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL UPSILON
1D7BF^𝞿^\mathsfbfit{\varphi}^\mbfitsansphi^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL PHI
1D7C0^𝟀^\mathsfbfit{\chi}^\mbfitsanschi^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL CHI
1D7C1^𝟁^\mathsfbfit{\psi}^\mbfitsanspsi^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL PSI
1D7C2^𝟂^\mathsfbfit{\omega}^\mbfitsansomega^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL OMEGA
1D7C3^𝟃^^\mbfitsanspartial^A^mathord^^MATHEMATICAL SANS-SERIF BOLD ITALIC PARTIAL DIFFERENTIAL
1D7C4^𝟄^\mathsfbfit{\epsilon}^\mbfitsansvarepsilon^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC EPSILON SYMBOL
1D7C5^𝟅^\mathsfbfit{\vartheta}^\mbfitsansvartheta^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC THETA SYMBOL
1D7C6^𝟆^^\mbfitsansvarkappa^A^mathalpha^^MATHEMATICAL SANS-SERIF BOLD ITALIC KAPPA SYMBOL
1D7C7^𝟇^\mathsfbfit{\phi}^\mbfitsansvarphi^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC PHI SYMBOL
1D7C8^𝟈^\mathsfbfit{\varrho}^\mbfitsansvarrho^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC RHO SYMBOL
1D7C9^𝟉^\mathsfbfit{\varpi}^\mbfitsansvarpi^A^mathalpha^isomath^MATHEMATICAL SANS-SERIF BOLD ITALIC PI SYMBOL
1D7CA^𝟊^^\mbfDigamma^A^mathalpha^^MATHEMATICAL BOLD CAPITAL DIGAMMA
1D7CB^𝟋^^\mbfdigamma^A^mathalpha^^MATHEMATICAL BOLD SMALL DIGAMMA
1D7CE^𝟎^\mathbf{0}^^N^mathord^^mathematical bold digit 0
1D7CF^𝟏^\mathbf{1}^^N^mathord^^mathematical bold digit 1
1D7D0^𝟐^\mathbf{2}^^N^mathord^^mathematical bold digit 2
1D7D1^𝟑^\mathbf{3}^^N^mathord^^mathematical bold digit 3
1D7D2^𝟒^\mathbf{4}^^N^mathord^^mathematical bold digit 4
1D7D3^𝟓^\mathbf{5}^^N^mathord^^mathematical bold digit 5
1D7D4^𝟔^\mathbf{6}^^N^mathord^^mathematical bold digit 6
1D7D5^𝟕^\mathbf{7}^^N^mathord^^mathematical bold digit 7
1D7D6^𝟖^\mathbf{8}^^N^mathord^^mathematical bold digit 8
1D7D7^𝟗^\mathbf{9}^^N^mathord^^mathematical bold digit 9
1D7D8^𝟘^\mathbb{0}^\Bbbzero^N^mathord^bbold^mathematical double-struck digit 0
1D7D9^𝟙^\mathbb{1}^\Bbbone^N^mathord^bbold fourier^= \mathds{1} (dsfont), mathematical double-struck digit 1
1D7DA^𝟚^\mathbb{2}^\Bbbtwo^N^mathord^bbold^mathematical double-struck digit 2
1D7DB^𝟛^\mathbb{3}^\Bbbthree^N^mathord^bbold^mathematical double-struck digit 3
1D7DC^𝟜^\mathbb{4}^\Bbbfour^N^mathord^bbold^mathematical double-struck digit 4
1D7DD^𝟝^\mathbb{5}^\Bbbfive^N^mathord^bbold^mathematical double-struck digit 5
1D7DE^𝟞^\mathbb{6}^\Bbbsix^N^mathord^bbold^mathematical double-struck digit 6
1D7DF^𝟟^\mathbb{7}^\Bbbseven^N^mathord^bbold^mathematical double-struck digit 7
1D7E0^𝟠^\mathbb{8}^\Bbbeight^N^mathord^bbold^mathematical double-struck digit 8
1D7E1^𝟡^\mathbb{9}^\Bbbnine^N^mathord^bbold^mathematical double-struck digit 9
1D7E2^𝟢^\mathsf{0}^\msanszero^N^mathord^^mathematical sans-serif digit 0
1D7E3^𝟣^\mathsf{1}^\msansone^N^mathord^^mathematical sans-serif digit 1
1D7E4^𝟤^\mathsf{2}^\msanstwo^N^mathord^^mathematical sans-serif digit 2
1D7E5^𝟥^\mathsf{3}^\msansthree^N^mathord^^mathematical sans-serif digit 3
1D7E6^𝟦^\mathsf{4}^\msansfour^N^mathord^^mathematical sans-serif digit 4
1D7E7^𝟧^\mathsf{5}^\msansfive^N^mathord^^mathematical sans-serif digit 5
1D7E8^𝟨^\mathsf{6}^\msanssix^N^mathord^^mathematical sans-serif digit 6
1D7E9^𝟩^\mathsf{7}^\msansseven^N^mathord^^mathematical sans-serif digit 7
1D7EA^𝟪^\mathsf{8}^\msanseight^N^mathord^^mathematical sans-serif digit 8
1D7EB^𝟫^\mathsf{9}^\msansnine^N^mathord^^mathematical sans-serif digit 9
1D7EC^𝟬^\mathsfbf{0}^\mbfsanszero^N^mathord^mathsfbf^mathematical sans-serif bold digit 0
1D7ED^𝟭^\mathsfbf{1}^\mbfsansone^N^mathord^mathsfbf^mathematical sans-serif bold digit 1
1D7EE^𝟮^\mathsfbf{2}^\mbfsanstwo^N^mathord^mathsfbf^mathematical sans-serif bold digit 2
1D7EF^𝟯^\mathsfbf{3}^\mbfsansthree^N^mathord^mathsfbf^mathematical sans-serif bold digit 3
1D7F0^𝟰^\mathsfbf{4}^\mbfsansfour^N^mathord^mathsfbf^mathematical sans-serif bold digit 4
1D7F1^𝟱^\mathsfbf{5}^\mbfsansfive^N^mathord^mathsfbf^mathematical sans-serif bold digit 5
1D7F2^𝟲^\mathsfbf{6}^\mbfsanssix^N^mathord^mathsfbf^mathematical sans-serif bold digit 6
1D7F3^𝟳^\mathsfbf{7}^\mbfsansseven^N^mathord^mathsfbf^mathematical sans-serif bold digit 7
1D7F4^𝟴^\mathsfbf{8}^\mbfsanseight^N^mathord^mathsfbf^mathematical sans-serif bold digit 8
1D7F5^𝟵^\mathsfbf{9}^\mbfsansnine^N^mathord^mathsfbf^mathematical sans-serif bold digit 9
1D7F6^𝟶^\mathtt{0}^\mttzero^N^mathord^^mathematical monospace digit 0
1D7F7^𝟷^\mathtt{1}^\mttone^N^mathord^^mathematical monospace digit 1
1D7F8^𝟸^\mathtt{2}^\mtttwo^N^mathord^^mathematical monospace digit 2
1D7F9^𝟹^\mathtt{3}^\mttthree^N^mathord^^mathematical monospace digit 3
1D7FA^𝟺^\mathtt{4}^\mttfour^N^mathord^^mathematical monospace digit 4
1D7FB^𝟻^\mathtt{5}^\mttfive^N^mathord^^mathematical monospace digit 5
1D7FC^𝟼^\mathtt{6}^\mttsix^N^mathord^^mathematical monospace digit 6
1D7FD^𝟽^\mathtt{7}^\mttseven^N^mathord^^mathematical monospace digit 7
1D7FE^𝟾^\mathtt{8}^\mtteight^N^mathord^^mathematical monospace digit 8
1D7FF^𝟿^\mathtt{9}^\mttnine^N^mathord^^mathematical monospace digit 9
elyxer-1.2.5/forks/jras-elyxer/src/conf/base.cfg0000644000175000017500000010344712117061342021043 0ustar  chennochenno#! /usr/bin/env python
# -*- coding: utf-8 -*-

#   eLyXer -- convert LyX source files to HTML output.
#
#   Copyright (C) 2009-2010 Alex Fernández
#
#   This program is free software: 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 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
#   GNU General Public License for more details.
#
#   You should have received a copy of the GNU General Public License
#   along with this program.  If not, see .

# --end--


[BibTeXConfig.replaced]
--:—
..:.

[BibStylesConfig.defaulttags]
surname:
authors:
YY:??

[BibStylesConfig.default]
cite:$index
default:$authors: $title.{{ $publisher,} $year.}{ URL $url.}{ $note.}
@article:$authors: “$title”, $journal,{ pp. $pages,} $year.{ URL $url.}{ $note.}
@book:{$authors: }$title{ ($editor, ed.)}.{{ $publisher,} $year.}{ URL $url.}{ $note.}
@booklet:$authors: $title.{{ $publisher,} $year.}{ URL $url.}{ $note.}
@conference:$authors: “$title”, $journal,{ pp. $pages,} $year.{ URL $url.}{ $note.}
@inbook:$authors: $title.{{ $publisher,} $year.}{ URL $url.}{ $note.}
@incollection:$authors: $title{ in $booktitle{ ($editor, ed.)}}.{{ $publisher,} $year.}{ URL $url.}{ $note.}
@inproceedings:$authors: “$title”, $booktitle,{ pp. $pages,} $year.{ URL $url.}{ $note.}
@manual:$authors: $title.{{ $publisher,} $year.}{ URL $url.}{ $note.}
@mastersthesis:$authors: $title.{{ $publisher,} $year.}{ URL $url.}{ $note.}
@misc:$authors: $title.{{ $publisher,}{ $howpublished,} $year.}{ URL $url.}{ $note.}
@phdthesis:$authors: $title.{{ $publisher,} $year.}{ URL $url.}{ $note.}
@proceedings:$authors: “$title”, $journal,{ pp. $pages,} $year.{ URL $url.}{ $note.}
@techreport:$authors: $title, $year.{ URL $url.}{ $note.}
@unpublished:$authors: “$title”, $journal, $year.{ URL $url.}{ $note.}

[BibStylesConfig.abbrvnat]
cite:$surname($year)
default:$authors. $title. $publisher, $year.{ URL $url.}{ $note.}
@article:$authors. $title. $journal,{ {$volume:}$pages,} $month $year.{ doi: $doi.}{ URL $url.}{ $note.}

[BibStylesConfig.alpha]
cite:$Sur$YY
default:$authors. $title.{ $journal,} $year.{ $url.}{ $filename.}{ $note.}
@article:$authors. $title.{ $journal{, {$volume}{($number)}}{: $pages}{, $year}.}{ $url.}{ $filename.}{ $note.}

[BibStylesConfig.authordate2]
cite:$surname, $year
default:$authors. $year. $title. $publisher.{ URL $url.}{ $note.}
@article:$authors. $year. $title. $journal, $volume($number), $pages.{ URL $url.}{ $note.}
@book:$authors. $year. $title. $publisher.{ URL $url.}{ $note.}

[BibStylesConfig.plain]
cite:$index
default:{$authors. }$title.{{ $publisher,} $year.}{ URL $url.}{ $note.}
@article:$authors. $title.{ $journal{, {$volume}{($number)}}{:$pages}{, $year}.}{ URL $url.}{ $note.}
@book:$authors. $title. $publisher,{ $month} $year.{ URL $url.}{ $note.}
@incollection:$authors. $title.{ In $booktitle {($editor, ed.)}.} $publisher,{ $month} $year.{ URL $url.}{ $note.}
@inproceedings:$authors. $title. { $booktitle{, {$volume}{($number)}}{:$pages}{, $year}.}{ URL $url.}{ $note.}

[BibStylesConfig.ieeetr]
cite:$index
default:$authors, “$title”. $year.{ URL $url.}{ $note.}
@article:$authors, “$title”, $journal, vol. $volume, no. $number, pp. $pages, $year.{ URL $url.}{ $note.}
@book:$authors, $title. $publisher, $year.{ URL $url.}{ $note.}

[BibStylesConfig.vancouver]
cite:$index
default:$authors. $title; {$publisher, }$year.{ $howpublished.}{ URL: $url.}{ $note.}
@article:$authors. $title. $journal, $year{;{$volume}{($number)}{:$pages}}.{ URL: $url.}{ $note.}
@book:$authors. $title. {$publisher, }$year.{ URL: $url.}{ $note.}

[ContainerConfig.endings]
Align:\end_layout
BarredText:\bar
BoldText:\series
Cell::>

[EscapeConfig.html]
/>:>

[EscapeConfig.nonunicode]
 : 

[EscapeConfig.iso885915]
 :&#8197;
 : 
 : 

[FormulaConfig.alphacommands]
# italic Greek alphabet
\varGamma:Γ
\varDelta:∆
\varTheta:Θ
\varLambda:Λ
\varXi:Ξ
\varPi:Π
\varSigma:Σ
\varUpsilon:Υ
\varPhi:Φ
\varPsi:Ψ
\varOmega:Ω
\alpha:α
\beta:β
\delta:δ
\epsilon:ϵ
\gamma:γ
\eta:η
\iota:ι
\kappa:κ
\lambda:λ
\mu:μ
\nu:ν
\omega:ω
\phi:φ
\pi:π
\psi:ψ
\rho:ρ
\sigma:σ
\tau:τ
\theta:θ
\upsilon:υ
\varepsilon:ε
\varkappa:ϰ
\varphi:φ
\varpi:ϖ
\varrho:ϱ
\varsigma:ς
\vartheta:ϑ
\xi:ξ
\zeta:ζ
# MarkusKuhn
\oe:œ
\OE:Œ
\ae:æ
\AE:Æ
\aa:å
\AA:Å
\o:ø
\O:Ø
\l:ł
\L:Ł
\ss:ß
\textcrh:ħ
# GünterMilde
\i:ı
\j:ȷ
\imath:ı
\jmath:ȷ
# 20101130 from BibTeXConfig.escaped
\DH:Ð
\TH:Þ
\dh:ð
\th:þ
# 20110108
\AmS:AmS
# Milde 20110709 (http://milde.users.sourceforge.net/LUCR/Math/)
\Koppa:Ϟ
\Stigma:Ϛ
\sampi:ϡ
\Sampi:Ϡ
\koppa:ϟ
\digamma:ϝ
\stigma:ϛ
\varbeta:ϐ
\eth:ð
\Angstroem:Å
\Micro:µ
\tcohm:Ω

[FormulaConfig.array]
begin:\begin
cellseparator:&
end:\end
rowseparator:\\

[FormulaConfig.bigbrackets]
(:[⎛,⎜,⎝]
):[⎞,⎟,⎠]
[:[⎡,⎢,⎣]
]:[⎤,⎥,⎦]
{:[⎧,⎪,⎨,⎩]
}:[⎫,⎪,⎬,⎭]
|:[|]
∥:[∥]

[FormulaConfig.commands]
\!:
\%:%
\,: 
\;: 
\:: 
\CIRCLE:●
\CheckedBox:☑
\Circle:○
\Downarrow:⇓
\Im:ℑ
\LEFTCIRCLE:◖
\LEFTcircle:◐
\Leftarrow:⇐
\Longleftarrow:⟸
\Longrightarrow:⟹
\Pr:Pr
\RIGHTCIRCLE:◗
\RIGHTcircle:◑
\Re:ℜ
\Square:☐
\Uparrow:⇑
\Updownarrow:⇕
\XBox:☒
\\:
\_:_ \aleph:ℵ \amalg:∐ \angle:∠ \aquarius:♒ \arccos:arccos \arcsin:arcsin \arctan:arctan \arg:arg \aries:♈ \ast:∗ \asymp:≍ \backslash:\ \beth:ℶ \bigcap:∩ \bigcirc:○ \bigcup:∪ \bigodot:⊙ \bigoplus:⊕ \bigotimes:⊗ \bigsqcup:⊔ \bigstar:★ \biguplus:⊎ \bigvee:∨ \bigwedge:∧ \blacksmiley:☻ \blacktriangleright:▶ \bot:⊥ \bowtie:⋈ \box:▫ \bullet:• \cancer:♋ \cap:∩ \capricornus:♑ \cdot:⋅ \cdots:⋯ \centerdot:∙ \chi:χ \circ:○ \clubsuit:♣ \cong:≅ \coprod:∐ \cos:cos \cosh:cosh \cot:cot \coth:coth \csc:csc \cup:∪ \dagger:† \daleth:ℸ \dashv:⊣ \ddagger:‡ \ddots:⋱ \deg:deg \det:det \diamond:◇ \diamondsuit:♦ \dim:dim \div:÷ \doteq:≐ \dots:… \downarrow:↓ \earth:♁ \ell:ℓ \emptyset:∅ \exists:∃ \exp:exp \female:♀ \forall:∀ \frownie:☹ \gcd:gcd \gemini:♊ \gets:← \gg:≫ \gimel:ℷ \hbar:ℏ \heartsuit:♥ \hom:hom \hookleftarrow:↩ \hookrightarrow:↪ \imath:ı \inf:inf \infty:∞ \invneg:⌐ \jmath:ȷ \jupiter:♃ \ker:ker \langle:⟨ \ldots:… \leadsto:⇝ \leftharpoondown:↽ \leftharpoonup:↼ \leftmoon:☾ \leftrightarrow:↔ \leo:♌ \lg:lg \libra:♎ \liminf:liminf \limsup:limsup \ll:≪ \ln:ln \log:log \longleftarrow:⟵ \longrightarrow:⟶ \lozenge:◊ \lyxlock: \male:♂ \mapsto:↦ \maltese:✠ \max:max \mercury:☿ \mho:℧ \mid:∣ \min:min \models:⊨ \mp:∓ \nabla:∇ \nearrow:↗ \neg:¬ \neptune:♆ \ni:∋ \nonumber: \not:¬ \nwarrow:↖ \odot:⊙ \oint: \ominus:⊖ \oplus:⊕ \oslash:⊘ \otimes:⊗ \parallel:∥ \partial:∂ \perp:⊥ \pisces:♓ \pluto:♇ \pm:± \prec:≺ \preceq:≼ \prime:′ \prompto:∝ \qquad: \quad: \quarternote:♩ \rangle:⟩ \rightharpooondown:⇁ \rightharpooonup:⇀ \rightleftharpoons:⇌ \rightmoon:☽ \sagittarius:♐ \saturn:♄ \scorpio:♏ \searrow:↘ \sec:sec \setminus:∖ \simeq:≃ \sin:sin \sinh:sinh \slash:∕ \smiley:☺ \spadesuit:♠ \sqcap:⊓ \sqcup:⊔ \sqsubset:⊏ \sqsubseteq:⊑ \sqsupset:⊐ \sqsupseteq:⊒ \square:□ \star:⋆ \succ:≻ \succeq:≽ \sun:☼ \sup:sup \surd:√ \swarrow:↙ \tan:tan \tanh:tanh \taurus:♉ \textbackslash:\ \top:⊤ \triangleleft:⊲ \triangleright:▷ \twonotes:♫ \unlhd:⊴ \unrhl:⊵ \uparrow:↑ \updownarrow:↕ \uplus:⊎ \uranus:♅ \varclubsuit:♧ \vardiamondsuit:♦ \varheartsuit:♥ \varspadesuit:♤ \vdash:⊢ \vee:∨ \virgo:♍ \wedge:∧ \wp:℘ \wr:≀ \{:{ \}:} # MarkusKuhn \Box:□ \|:∥ \triangle:△ \Diamond:◇ \flat:♭ \natural:♮ \sharp:♯ \lhd:⊲ \bigtriangleup:△ \bigtriangledown:▽ \rhd:⊳ \unrhd:⊵ \smile:⌣ \frown:⌢ \Join:⨝ \not<:≮ \not>:≯ \not=:≠ \longleftrightarrow:⟷ \Longleftrightarrow:⟺ \longmapsto:⟼ \rightharpoonup:⇀ \rightharpoondown:⇁ \lbrack:[ \lbrace:{ \lfloor:⌊ \lceil:⌈ \rbrack:] \rbrace:} \rfloor:⌋ \rceil:⌉ \owns:∋ \land:∧ \lor:∨ \lnot:¬ \vert:∣ \Vert:∥ \leq):≤ \geq):≥ \lbrace):{ \rbrace):} \rightarrow):→ \leftarrow):← \ni):∋ \wedge):∧ \vee):∨ \neg):¬ \vdots:⋮ \S:§ \P:¶ \dag:† \ddag:‡ \copyright:© # financial \pounds:£ \euro:€ \yen:¥ \$:$ # 20091028 \checkmark:✓ \blacklozenge:⧫ \blacktriangle:▲ \blacktriangledown:▼ \nexists:∄ \mathcircumflex:^ # 20091128 \varnothing:∅ \backprime:‵ \notin:∉ \hfill: \circledR:® \hslash:ℏ # 20091203 \gtrless:≷ \complement:∁ \measuredangle:∡ \sphericalangle:∢ \nmid:∤ \circeq:≗ \lessgtr:≶ \nparallel:∦ # Jens Nöckel \leftthreetimes:⋋ \rightthreetimes:⋌ \ltimes:⋉ \rtimes:⋊ \divideontimes:⋇ \dotplus:∔ \dotdiv:∸ \oiint: \oiiint: \ointclockwise: \landupint: \ointctrclockwise: \iint: \iiint: \idotsint:∫⋯∫ \barwedge:⊼ \veebar:⊻ \doublebarwedge:⌆ \backepsilon:∍ \therefore:∴ \because:∵ \boxdot:⊡ \circledast:⊛ \circledcirc:⊚ \circleddash:⊝ \EUR:€ \nvdash:⊬ \vDash:⊨ \nvDash:⊭ \Vdash:⊩ \nVDash:⊯ \Vvdash:⊪ \multimap:⊸ \Cup:⋓ \udot:⊍ \Cap:⋒ \Yup:⅄ \nequiv:≢ \triangleq:≜ \Corresponds:≙ \coloneqq:≔ \Coloneqq:⩴ \eqcolon:≕ \eqcirc:≖ \doteqdot:≑ \risingdotseq:≓ \fallingdotseq:≒ \nsimeq:≄ \backsimeq:⋍ \ncong:≇ \nsim:≁ \napprox:≉ \eqsim:≂ \bumpeq:≏ \Bumpeq:≎ \nless:≮ \ngtr:≯ \lll:⋘ \ggg:⋙ \nleqslant:≰ \leqslant:≤ \geqslant:≥ \ngeqslant:≱ \nlessgtr:≸ \ngtrless:≹ \lneqq:≨ \leqq:≦ \geqq:≧ \gneqq:≩ \lnsim:⋦ \lesssim:≲ \gtrsim:≳ \gnsim:⋧ \nprec:⊀ \nsucc:⊁ \ntriangleleft:⋪ \ntriangleright:⋫ \trianglelefteq:⊴ \trianglerighteq:⊵ \ntrianglelefteq:⋬ \ntrianglerighteq:⋭ \preccurlyeq:≼ \succcurlyeq:≽ \nsucccurlyeq:⋡ \precsim:≾ \succsim:≿ \succnsim:⋩ \lesseqgtr:⋛ \gtreqless:⋚ \gtreqqless:⪌ \lesseqqgtr:⪋ \gtrdot:⋗ \lessdot:⋖ \Subset:⋐ \Supset:⋑ \nsupset:⊅ \nsubseteq:⊈ \subseteqq:⫅ \supseteqq:⫆ \subsetneqq:⫋ \supsetneqq:⫌ \nsupseteq:⊉ \nsqsubset:⊏̸ \notni:∌ \pitchfork:⋔ \between:≬ \notslash:⌿ \notbackslash:⍀ \nleftarrow:↚ \nrightarrow:↛ \nleftrightarrow:↮ \lightning:↯ \nLeftrightarrow:⇎ \APLuparrowbox:⍐ \APLdownarrowbox:⍗ \APLleftarrowbox:⍇ \APLrightarrowbox:⍈ \pointer:➪ \nLeftarrow:⇍ \nRightarrow:⇏ \Lleftarrow:⇚ \Rrightarrow:⇛ \Lsh:↰ \Rsh:↱ \curvearrowleft:↶ \curvearrowright:↷ \leftrightarrows:⇆ \rightleftarrows:⇄ \upharpoonleft:↿ \downharpoonleft:⇃ \downharpoonright:⇂ \upharpoonright:↾ \leftarrowtobar:⇤ \rightarrowtobar:⇥ \leftrightharpoons:⇋ \leftleftharpoons:⥢ \rightrightharpoons:⥤ \Mapsfrom:⇐| \Mapsto:|⇒ \mapsfrom:↤ \dashleftarrow:⇠ \upuparrows:⇈ \downdownarrows:⇊ \leftleftarrows:⇇ \rightrightarrows:⇉ \leftarrowtail:↢ \rightarrowtail:↣ \twoheadleftarrow:↞ \twoheadrightarrow:↠ \looparrowleft:↫ \looparrowright:↬ # 20100124 \blacksquare:■ \ :  # non-italic Greek symbols \Gamma:Γ \Delta:Δ \Theta:Θ \Lambda:Λ \Xi:Ξ \Pi:Π \Sigma:Σ \Upsilon:Υ \Phi:Φ \Psi:Ψ \Omega:Ω # 20100509 \diagup:╱ \diagdown:╲ # 20100520 \officialeuro:€ # 20100823 \textasciitilde:~ \textasciicircum:^ \textendash:— \textquotedblleft:“ \textquotedblright:” # 20100912 \textless:< \textgreater:> # 20101130 from BibTeXConfig.escaped \textordfeminine:ª \textregistered:® \textordmasculine:º \texttrademark:™ \&:& \#:# # 20101214 \newline:
# 2011-01-03 from Günther Milde \Game:⅁ # 20110107 \textvisiblespace: # 20110120 \nolimits: # Pascal Francq \textsection:§ \textdegree:° \guillemotleft:« \guillemotright:» \texteuro:€ \textellipsis:… \textquoteright:’ \textrightarrow:→ \texttwosuperior:² \textcopyright:©' \textemdash:— # Milde 20110709 (http://milde.users.sourceforge.net/LUCR/Math/) \rblot:⦊ \rsub:⩥ \sphat: \medbullet:⚫ \biohazard:☣ \Lbag:⟅ \llcorner:⌞ \ExponetialE:ⅇ \sslash:⫽ \boxcircle:⧇ \recycle:♻ \blacktriangleup:▴ \talloblong:⫾ \anchor:⚓ \interleave:⫴ \APLcomment:⍝ \smalltriangleleft:◃ \Lparen:⦅ \AC:∿ \smalltriangleright:▹ \RHD:▶ \circledbslash:⦸ \lblot:⦉ \circledless:⧀ \dsub:⩤ \yinyang:☯ \sixteenthnote:♬ \intercal:⊺ \cat:⁀ \lang:⟪ \APLlog:⍟ \Sun:☉ \curlywedge:⋏ \rimg:⦈ \boxbslash:⧅ \circledgtr:⧁ \boxbar:◫ \Qoppa:Ϙ \ulcorner:⌜ \wasylozenge:⌑ \sptilde:~ \cent:¢ \smallsetminus:∖ \warning:⚠ \APLinv:⌹ \smalltriangleup:▵ \qoppa:ϙ \swords:⚔ \circlearrowright:↻ \diameter:⌀ \Diamonddot:⟐ \eighthnote:♪ \urcorner:⌝ \CapitalDifferentialD:ⅅ \lrcorner:⌟ \boxast:⧆ \boxplus:⊞ \DifferentialD:ⅆ \boxminus:⊟ \Diamondblack:◆ \lgroup:⟮ \fcmp:⨾ \boxtimes:⊠ \limg:⦇ \Finv:Ⅎ \Rbag:⟆ \radiation:☢ \circlearrowleft:↺ \llbracket:⟦ \arrowbullet:➢ \pencil:✎ \LHD:◀ \pointright:☞ \blacktriangleleft:◂ \medcirc:⚪ \boxbox:⧈ \spot:⦁ \Rparen:⦆ \ballotx:✗ \second:″ \ComplexI:ⅈ \Euler:ℇ \ComplexJ:ⅉ \rightangle:∟ \rgroup:⟯ \spddot:¨ \invamp:⅋ \rrbracket:⟧ \third:‴ \smalltriangledown:▿ \curlyvee:⋎ \skull:☠ \fourth:⁗ \steaming:☕ \APLinput:⍞ \rang:⟫ \boxslash:⧄ [FormulaConfig.spacedcommands] \Leftrightarrow:⇔ \Rightarrow:⇒ \approx:≈ \dashrightarrow:⇢ \equiv:≡ \ge:≥ \geq:≥ \implies: ⇒  \in:∈ \le:≤ \leftarrow:← \leq:≤ \ne:≠ \neq:≠ \not\in:∉ \propto:∝ \rightarrow:→ \rightsquigarrow:⇝ \sim:~ \subset:⊂ \subseteq:⊆ \supset:⊃ \supseteq:⊇ \times:× \to:→ # Milde 20110709 (http://milde.users.sourceforge.net/LUCR/Math/) \nsqsupseteq:⋣ \bij:⤖ \nsqsubseteq:⋢ \subsetneq:⊊ \finj:⤕ \llcurly:⪻ \RightArrowBar:⇥ \NestedLessLess:⪡ \curlyeqprec:⋞ \LeftDownTeeVector:⥡ \pfun:⇸ \Doteq:≑ \downuparrows:⇵ \precnsim:⋨ \lnapprox:⪉ \nsubset:⊄ \lneq:⪇ \Equal:⩵ \coloneq:≔ \hash:⋕ \vartriangleleft:⊲ \leftupdownharpoon:⥑ \precnapprox:⪹ \rightslice:⪧ \updownharpoons:⥮ \multimapboth:⧟ \RightTeeVector:⥛ \npreceq:⋠ \Longmapsto:⟾ \leftrightharpoonup:⥎ \Bot:⫫ \dlsh:↲ \Top:⫪ \downupharpoons:⥯ \backsim:∽ \rightleftharpoon:⥋ \nleq:≰ \RightVectorBar:⥓ \NotGreaterTilde:≵ \NestedGreaterGreater:⪢ \MapsUp:↥ \DownLeftVectorBar:⥖ \lessapprox:⪅ \eqslantgtr:⪖ \barrightharpoon:⥭ \barleftharpoon:⥫ \strictif:⥽ \leftarrowtriangle:⇽ \supsetneq:⊋ \gnapprox:⪊ \Swarrow:⇙ \LeftDownVectorBar:⥙ \notasymp:≭ \LeftUpVectorBar:⥘ \gtrapprox:⪆ \nni:∌ \Proportion:∷ \eqslantless:⪕ \succnapprox:⪺ \leftrightharpoondown:⥐ \VDash:⊫ \downdownharpoons:⥥ \approxeq:≊ \ffun:⇻ \leftrightarrowtriangle:⇿ \NotLessTilde:≴ \DownLeftTeeVector:⥞ \updownarrows:⇅ \Nearrow:⇗ \Nwarrow:⇖ \DownArrowBar:⤓ \barin:⋶ \Longmapsfrom:⟽ \multimapdotbothA:⊶ \LeftVectorBar:⥒ \Same:⩶ \RightUpTeeVector:⥜ \succeqq:⪴ \strictfi:⥼ \iddots:⋰ \pinj:⤔ \RightTriangleBar:⧐ \leftbarharpoon:⥪ \ggcurly:⪼ \nsucceq:⋡ \nVdash:⊮ \leftsquigarrow:⇜ \LeftUpTeeVector:⥠ \Searrow:⇘ \multimapdotbothB:⊷ \DownRightTeeVector:⥟ \leftrightsquigarrow:↭ \LeftArrowBar:⇤ \UpArrowBar:⤒ \psur:⤀ \DownRightVectorBar:⥗ \drsh:↳ \LeftTriangleBar:⧏ \RightUpVectorBar:⥔ \LeftTeeVector:⥚ \rightbarharpoon:⥬ \leftslice:⪦ \preceqq:⪳ \gneq:⪈ \rightarrowtriangle:⇾ \precapprox:⪷ \NotGreaterLess:≹ \longmapsfrom:⟻ \vartriangleright:⊳ \rightupdownharpoon:⥏ \ngeq:≱ \RightDownTeeVector:⥝ \RightDownVectorBar:⥕ \leftrightharpoon:⥊ \curlyeqsucc:⋟ \multimapinv:⟜ \succapprox:⪸ \corresponds:≙ \upupharpoons:⥣ \MapsDown:↧ [FormulaConfig.decoratedcommand] # 20101130 from BibTeXConfig.escaped #!`:¡ #?`:¿ [FormulaConfig.decoratingfunctions] \overleftarrow:⟵ \overrightarrow:⟶ \widehat:^ [FormulaConfig.combiningfunctions] \acute:́ \bar:̄ \breve:̆ \c:̧ \check:̌ \dot:̇ \ddot:̈ \dddot:⃛ \grave:̀ \hat:̂ \mathring:̊ \overleftarrow:⃖ \overrightarrow:⃗ \r:̊ \s:̩ \textsubring:̥ \tilde:̃ \vec:⃗ # 20101130 from BibTeXConfig.escaped \`:̀ \':́ \^:̂ \~:̃ \":̈ \textcircled:⃝ \v:̌ [FormulaConfig.environments] align:[r,l] eqnarray:[r,c,l] gathered:[l,l] [FormulaConfig.endings] bracket:} complex:\] endafter:} endbefore:\end{ squarebracket:] [FormulaConfig.fontfunctions] \boldsymbol:b \mathbb:span class="blackboard" \mathbf:b \mathcal:span class="scriptfont" \mathfrak:span class="fraktur" \mathit:i \mathrm:span class="mathrm" \mathsf:span class="mathsf" \mathtt:tt \mathscr:span class="scriptfont" # simplified fonts \mathbb{A}:𝔸 \mathbb{B}:𝔹 \mathbb{C}:ℂ \mathbb{D}:𝔻 \mathbb{E}:𝔼 \mathbb{F}:𝔽 \mathbb{G}:𝔾 \mathbb{H}:ℍ \mathbb{J}:𝕁 \mathbb{K}:𝕂 \mathbb{L}:𝕃 \mathbb{N}:ℕ \mathbb{O}:𝕆 \mathbb{P}:ℙ \mathbb{Q}:ℚ \mathbb{R}:ℝ \mathbb{S}:𝕊 \mathbb{T}:𝕋 \mathbb{W}:𝕎 \mathbb{Z}:ℤ \mathfrak{C}:ℭ \mathfrak{F}:𝔉 \mathfrak{H}:ℌ \mathfrak{I}:ℑ \mathfrak{R}:ℜ \mathfrak{Z}:ℨ \mathring{A}:Å \mathring{U}:Ů \mathring{a}:å \mathring{u}:ů \mathring{w}:ẘ \mathring{y}:ẙ \mathscr{B}:ℬ \mathscr{E}:ℰ \mathscr{F}:ℱ \mathscr{H}:ℋ \mathscr{I}:ℐ \mathscr{L}:ℒ \mathscr{M}:ℳ \mathscr{R}:ℛ \mathcal{B}:ℬ \mathcal{E}:ℰ \mathcal{F}:ℱ \mathcal{H}:ℋ \mathcal{I}:ℐ \mathcal{L}:ℒ \mathcal{M}:ℳ \mathcal{R}:ℛ [FormulaConfig.hybridfunctions] \sqrt:[[$0]{$1},f0{f1{$0}f2{√}f4{(}f3{$1}f4{)}},span class="sqrt",sup class="root",span class="radical",span class="root",span class="ignored"] \unit:[[$0]{$1},$0f0{$1.font},span class="unit"] \frac:[{$1}{$2},f0{f3{(}f1{$1}f3{)/(}f2{$2}f3{)}},span class="fraction",span class="numerator",span class="denominator",span class="ignored"] \cfrac:[[$p!]{$1}{$2},f0{f3{(}f1{$1}f3{)/(}f2{$2}f3{)}},span class="fullfraction",span class="numerator align-$p",span class="denominator",span class="ignored"] \dfrac:[{$1}{$2},f0{f3{(}f1{$1}f3{)/(}f2{$2}f3{)}},span class="fullfraction",span class="numerator",span class="denominator",span class="ignored"] \nicefrac:[{$1}{$2},f0{f1{$1}⁄f2{$2}},span class="fraction",sup class="numerator",sub class="denominator",span class="ignored"] \unitfrac:[[$0]{$1}{$2},$0f0{f1{$1.font}⁄f2{$2.font}},span class="fraction",sup class="unit",sub class="unit"] \binom:[{$1}{$2},f2{(}f0{f1{$1}f1{$2}}f2{)},span class="binom",span class="binomstack",span class="bigsymbol"] \dbinom:[{$1}{$2},(f0{f1{f2{$1}}f1{f2{ }}f1{f2{$2}}}),span class="binomial",span class="binomrow",span class="binomcell"] \tbinom:[{$1}{$2},(f0{f1{f2{$1}}f1{f2{ }}f1{f2{$2}}}),span class="binomial",span class="binomrow",span class="binomcell"] \hspace:[{$p!},f0{ },span class="hspace" style="width: $p;"] \vspace:[{$p!},f0{ },span class="vspace" style="height: $p;"] \raisebox:[{$p!}{$1},f0{$1.font},span class="raisebox" style="vertical-align: $p;"] \leftroot:[{$p!},f0{ },span class="leftroot" style="width: $p;px"] \uproot:[{$p!},f0{ },span class="uproot" style="width: $p;px"] \renewenvironment:[{$1!}{$2!}{$3!},] \color:[{$p!}{$1},f0{$1},span style="color: $p;"] \textcolor:[{$p!}{$1},f0{$1},span style="color: $p;"] \colorbox:[{$p!}{$1},f0{$1},span class="colorbox" style="background: $p;"] \stackrel:[{$1}{$2},f0{f1{$1}f2{$2}},span class="stackrel",span class="upstackrel",span class="downstackrel"] \fbox:[{$1},f0{$1},span class="fbox"] \boxed:[{$1},f0{$1},span class="boxed"] \framebox:[[$p!][$q!]{$1},f0{$1},span class="framebox align-$q" style="width: $p;"] \fcolorbox:[{$p!}{$q!}{$1},f0{$1},span class="boxed" style="border-color: $p; background: $q;"] \url:[{$u!},f0{$u},a href="$u"] \href:[[$o]{$u!}{$t!},f0{$t},a href="$u"] \parbox:[[$p!]{$w!}{$1},f0{1},div class="Boxed" style="width: $w;"] \rule:[[$v!]{$w!}{$h!},f0/,hr class="line" style="width: $w; height: $h;"] \fboxrule:[{$p!},f0{},ignored] \fboxsep:[{$p!},f0{},ignored] \scriptscriptstyle:[{$1},f0{$1},span class="scriptscriptstyle"] \scriptstyle:[{$1},f0{$1},span class="scriptstyle"] \displaystyle:[{$1},f0{$1},span class="displaystyle"] \textstyle:[{$1},f0{$1},span class="textstyle"] \thispagestyle:[{$p!},f0{},ignored] \frontmatter:[,f0{},ignored] \mainmatter:[,f0{},ignored] \backmatter:[,f0{},ignored] \markboth:[{$p!}{$q!},f0{},ignored] \markright:[{$p!},f0{},ignored] \fancyfoot:[[$p!]{$q!},f0{},ignored] \fancyhead:[[$p!]{$q!},f0{},ignored] \addcontentsline:[{$p!}{$q!}{$r!},f0{},ignored] \addtocontents:[{$p!}{$q!},f0{},ignored] [FormulaConfig.hybridsizes] \frac:$1+$2 \cfrac:$1+$2 \dfrac:$1+$2 \binom:$1+$2 \dbinom:$1+$2+1 \tbinom:$1+$2+1 [FormulaConfig.misccommands] \newcommand:MacroDefinition \renewcommand:MacroDefinition \setcounter:SetCounterFunction \tag:FormulaTag \tag*:FormulaTag \limits:LimitPreviousCommand \today:TodayCommand [FormulaConfig.limitcommands] \sum:∑ \int:∫ \intop:∫ \prod:∏ \smallint:∫ \lim:lim # Milde 20110709 (http://milde.users.sourceforge.net/LUCR/Math/) \zproject:⨡ \bigsqcap:⨅ \varprod:⨉ \sqint:⨖ \fint:⨏ \zcmp:⨟ \zpipe:⨠ \zhide:⧹ \biginterleave:⫼ \iiiint:⨌ \varointclockwise:∲ [FormulaConfig.bigsymbols] ∑:[⎲,⎳] ∫:[⌠,⌡] [FormulaConfig.labelfunctions] \label:a name="#" [FormulaConfig.textfunctions] \mbox:span class="mbox" \text:span class="text" \textipa:span class="textipa" \textnormal:span class="textnormal" \textrm:span class="textrm" \textsf:span class="textsf" \texttt:tt \textit:i \textbf:b \textsl:i \textsc:span class="versalitas" \textup:span class="normal" [FormulaConfig.modified] : : &: ':’ +: +  ,:,  -: −  /: ⁄  <: <  =: =  >: >  @: ~: $: [FormulaConfig.onefunctions] \bar:span class="bar" \begin{array}:span class="arraydef" \big:span class="symbol" \Big:span class="bigsymbol" \bigg:span class="largesymbol" \Bigg:span class="hugesymbol" \bigl:span class="bigsymbol" \bigr:span class="bigsymbol" \hphantom:span class="phantom" \overline:span class="overline" \phantom:span class="phantom" \underline:u \vphantom:span class="phantom" \underbrace:span class="underbrace" \overbrace:span class="overbrace" \ensuremath:span class="ensuremath" \noindent:span class="noindent" \centering:span class="align-center" [FormulaConfig.bracketcommands] \left:span class="symbol" \middle:span class="symbol" \right:span class="symbol" # simplified matched brackets \left.: \right.: [FormulaConfig.starts] beginafter:} beginbefore:\begin{ bracket:{ command:\ complex:\[ simple:$ squarebracket:[ unnumbered:* comment:% [FormulaConfig.symbolfunctions] ^:sup _:sub [FormulaConfig.unmodified] characters:[.,*,€,(,),[,],:,·,!,;,|,§,"] [FormulaConfig.urls] googlecharts:http://chart.googleapis.com/chart?cht=tx&chl= [GeneralConfig.version] date:2011-11-22 number:1.2.4 lyxformat:413 [HeaderConfig.parameters] branch:\branch endbranch:\end_branch lstset:\lstset pdftitle:\pdf_title documentclass:\textclass paragraphseparation:\paragraph_separation tocdepth:\tocdepth secnumdepth:\secnumdepth language:\language beginpreamble:\begin_preamble endpreamble:\end_preamble outputchanges:\output_changes [HeaderConfig.styles] article:[article,aastex,aapaper,acmsiggraph,sigplanconf,achemso,amsart,apa,arab-article,armenian-article,article-beamer,chess,dtk,elsarticle,heb-article,IEEEtran,iopart,kluwer,scrarticle-beamer,scrartcl,extarticle,paper,mwart,revtex4,spie,svglobal3,ltugboat,agu-dtd,jgrga,agums,entcs,egs,ijmpc,ijmpd,singlecol-new,doublecol-new,isprs,tarticle,jsarticle,jarticle,jss,literate-article,siamltex,cl2emult,llncs,svglobal,svjog,svprobth] book:[book,amsbook,scrbook,extbook,tufte-book,report,extreport,scrreprt,memoir,tbook,jsbook,jbook,mwbk,svmono,svmult,treport,jreport,mwrep] [ImageConfig.converters] imagemagick:convert[ -density $scale][ -define $format:use-cropbox=true] "$input" "$output" inkscape:inkscape "$input" --export-png="$output" lyx:lyx -C "$input" "$output" [ImageConfig.cropboxformats] .pdf:pdf .eps:ps .ps:ps [ImageConfig.formats] vector:[.svg,.eps] default:.png [LayoutConfig.groupable] allowed:[StringContainer,Constant,TaggedText,Align,TextFamily,EmphaticText,VersalitasText,BarredText,SizeText,ColorText,LangLine,Formula] [NewfangleConfig.constants] startmark:=< startcommand:\ endmark:> chunkref:chunkref{ endcommand:} [NumberingConfig.layouts] ordered:[Chapter,Section,Subsection,Subsubsection,Paragraph] roman:[Part,Book] [NumberingConfig.sequence] symbols:[*,**,†,‡,§,§§,¶,¶¶,#,##] [StyleConfig.quotes] ald:» als:› ard:« ars:‹ eld:“ els:‘ erd:” ers:’ fld:« fls:‹ frd:» frs:› gld:„ gls:‚ grd:“ grs:‘ pld:„ pls:‚ prd:” prs:’ sld:” srd:” [StyleConfig.hspaces] \enskip{}:  \hfill{}: \hspace*{\fill}:  \hspace*{}: \hspace{}:  \negthinspace{}: \qquad{}:   \quad{}:  \space{}:  \thinspace{}:  ~:  [StyleConfig.vspaces] defskip:
smallskip:
medskip:
bigskip:
vfill:
[StyleConfig.size] ignoredtexts:[col,text,line,page,theight,pheight] [StyleConfig.referenceformats] # @ is the label number, # is page number (always 1), ↕ a direction arrow, # $ the title, and ¶ is the part name (like Chapter) # on-page is the string " on page " internationalized. ref:@↕ eqref:(@↕) pageref:#↕ vref:@on-page#↕ vpageref:on-page#↕ formatted:¶↕ nameref:$↕ [TagConfig.barred] under:u [TagConfig.family] sans:span class="sans" typewriter:tt [TagConfig.flex] CharStyle:Code:span class="code" Code:span class="code" CharStyle:MenuItem:span class="menuitem" MenuItem:span class="menuitem" Noun:span class="noun" Strong:span class="strong" [TagConfig.layouts] Center:div Chapter:h? Date:h2 Paragraph:div Part:h1 Quotation:blockquote Quote:blockquote Section:h? Subsection:h? Subsubsection:h? [TagConfig.group] layouts:[Quotation,Quote] [TagConfig.listitems] Enumerate:ol Itemize:ul [TagConfig.notes] Comment: Greyedout:span class="greyedout" Note: [TagConfig.shaped] italic:i slanted:i smallcaps:span class="versalitas" [TagConfig.script] superscript:sup subscript:sub [TOCConfig.extracttitle] allowed:[StringContainer,Constant,Space] cloned:[TextFamily,EmphaticText,VersalitasText,BarredText,SizeText,ColorText,LangLine,Formula] extracted:[PlainLayout,TaggedText,Align,Caption,StandardLayout,FlexInset] [TOCConfig.extractplain] allowed:[StringContainer,Constant,TaggedText,Align,TextFamily,EmphaticText,VersalitasText,BarredText,SizeText,ColorText,LangLine,Formula] cloned:[] extracted:[] [TranslationConfig.constants] abstract:Abstract bibliography:Bibliography references:References index:Index nomenclature:Nomenclature toc:Table of Contents toc-for:Contents for Part:Part Book:Book Chapter:Chapter Section:Section Subsection:Subsection Subsubsection:Subsubsection Paragraph:Paragraph figure:figure float-algorithm:Algorithm float-figure:Figure float-listing:Listing float-table:Table float-tableau:Tableau list-algorithm:List of Algorithms list-figure:List of Figures list-table:List of Tables list-tableau:List of Tableaux on-page: on page jsmath-warning:Warning: jsmath-requires: requires JavaScript to correctly process the mathematics on this page. jsmath-enable:Please enable JavaScript on your browser. next:Next prev:Prev up:Up generated-by:Document generated by generated-on: on main-page:Main page Appendix:Appendix footnotes:Footnotes [TranslationConfig.languages] english:en spanish:es deutsch:de ngerman:de dutch:nl french:fr british:en american:en russian:ru elyxer-1.2.5/forks/jras-elyxer/src/coalesce.py0000755000175000017500000000753612117061342020660 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20090309 # Coalesces (unifies) all into one file to generate a distributable file. import sys import os.path from elyxer.io.fileline import * from elyxer.util.trace import Trace class Coalescer(object): "Coalesce a set of files into a single file," "so that it can be distributed." "Currently works for Python (.py) and CSS (.css) files." def __init__(self): self.comments = True self.files = [] self.directory = '' self.writer = None self.python = False def convert(self, filename, directory = ''): "Convert the filename adding the appropriate directories." if os.path.exists(filename): return filename newname = os.path.join(self.directory, filename) if os.path.exists(newname): return newname newname = os.path.join(directory, filename) if os.path.exists(newname): return newname Trace.error('Missing file ' + filename) return None def getreader(self, filename): "Get a line reader." if filename in self.files: # already parsed; skip return None self.files.append(filename) return LineReader(filename) def readargs(self, args): "Read arguments from the command line" del args[0] if len(args) == 0: self.usage() return self.filename = self.convert(args[0]) self.directory = os.path.dirname(args[0]) del args[0] fileout = sys.stdout if len(args) > 0: fileout = args[0] del args[0] if len(args) > 0: usage() return self.writer = LineWriter(fileout) def usage(self): Trace.error('Usage: coalesce.py filein [fileout]') return def coalesceall(self): "Coalesce all files from the root reader." if not self.writer: return self.coalesce(self.filename) self.writer.close() def coalesce(self, filename): "Coalesce all files used in filein to fileout" if filename.endswith('.py'): self.python = True reader = self.getreader(filename) if not reader: return while not reader.finished(): line = reader.currentline() included = self.getincluded(line) if included: self.comments = False newname = self.convert(included, os.path.dirname(filename)) if newname: self.coalesce(newname) else: # make imports with no target file work self.writer.writeline(line) elif self.iscomment(line): if self.comments: self.writer.writeline(line) else: self.writer.writeline(line) reader.nextline() reader.close() def getincluded(self, line): "Get the name of the included file, or None." if line.startswith('from'): return line.split()[1].replace('.', '/') + '.py' if line.startswith('@import'): return line.split()[1].replace('"', '').rstrip(';') return None def iscomment(self, line): "Find out if the line is a comment. Only removes Python comments." if self.python and line.startswith('#'): return True return False coalescer = Coalescer() coalescer.readargs(sys.argv) coalescer.coalesceall() elyxer-1.2.5/forks/jras-elyxer/src/load-elyxer.py0000755000175000017500000000170612117061342021320 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20090308 # eLyXer main script # http://www.nongnu.org/elyxer/ import sys from elyxer.main.convert import * if __name__ == '__main__': main() elyxer-1.2.5/forks/jras-elyxer/loremipsumize.py0000755000175000017500000020402212117061347021211 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20091210 # Lorem-ipsumize a document: replace all alphanumeric texts longer than two words with "Lorem ipsum" and leave the symbols. import sys import sys import codecs import sys class Trace(object): "A tracing class" debugmode = False quietmode = False showlinesmode = False prefix = None def debug(cls, message): "Show a debug message" if not Trace.debugmode or Trace.quietmode: return Trace.show(message, sys.stdout) def message(cls, message): "Show a trace message" if Trace.quietmode: return if Trace.prefix and Trace.showlinesmode: message = Trace.prefix + message Trace.show(message, sys.stdout) def error(cls, message): "Show an error message" message = '* ' + message if Trace.prefix and Trace.showlinesmode: message = Trace.prefix + message Trace.show(message, sys.stderr) def fatal(cls, message): "Show an error message and terminate" Trace.error('FATAL: ' + message) exit(-1) def show(cls, message, channel): "Show a message out of a channel" if sys.version_info < (3,0): message = message.encode('utf-8') channel.write(message + '\n') debug = classmethod(debug) message = classmethod(message) error = classmethod(error) fatal = classmethod(fatal) show = classmethod(show) class LineReader(object): "Reads a file line by line" def __init__(self, filename): if isinstance(filename, file): self.file = filename else: self.file = codecs.open(filename, 'rU', 'utf-8') self.linenumber = 1 self.lastline = None self.current = None self.mustread = True self.depleted = False try: self.readline() except UnicodeDecodeError: # try compressed file import gzip self.file = gzip.open(filename, 'rb') self.readline() def setstart(self, firstline): "Set the first line to read." for i in range(firstline): self.file.readline() self.linenumber = firstline def setend(self, lastline): "Set the last line to read." self.lastline = lastline def currentline(self): "Get the current line" if self.mustread: self.readline() return self.current def nextline(self): "Go to next line" if self.depleted: Trace.fatal('Read beyond file end') self.mustread = True def readline(self): "Read a line from elyxer.file" self.current = self.file.readline() if not isinstance(self.file, codecs.StreamReaderWriter): self.current = self.current.decode('utf-8') if len(self.current) == 0: self.depleted = True self.current = self.current.rstrip('\n\r') self.linenumber += 1 self.mustread = False Trace.prefix = 'Line ' + unicode(self.linenumber) + ': ' if self.linenumber % 1000 == 0: Trace.message('Parsing') def finished(self): "Find out if the file is finished" if self.lastline and self.linenumber == self.lastline: return True if self.mustread: self.readline() return self.depleted def close(self): self.file.close() class LineWriter(object): "Writes a file as a series of lists" file = False def __init__(self, filename): if isinstance(filename, file): self.file = filename self.filename = None else: self.filename = filename def write(self, strings): "Write a list of strings" for string in strings: if not isinstance(string, basestring): Trace.error('Not a string: ' + unicode(string) + ' in ' + unicode(strings)) return self.writestring(string) def writestring(self, string): "Write a string" if not self.file: self.file = codecs.open(self.filename, 'w', "utf-8") if self.file == sys.stdout and sys.version_info < (3,0): string = string.encode('utf-8') self.file.write(string) def writeline(self, line): "Write a line to file" self.writestring(line + '\n') def close(self): self.file.close() class BibStylesConfig(object): "Configuration class from elyxer.config file" abbrvnat = { u'@article':u'$authors. $title. $journal,{ {$volume:}$pages,} $month $year.{ doi: $doi.}{ URL $url.}{ $note.}', u'cite':u'$surname($year)', u'default':u'$authors. $title. $publisher, $year.{ URL $url.}{ $note.}', } alpha = { u'@article':u'$authors. $title.{ $journal{, {$volume}{($number)}}{: $pages}{, $year}.}{ $url.}{ $filename.}{ $note.}', u'cite':u'$Sur$YY', u'default':u'$authors. $title.{ $journal,} $year.{ $url.}{ $filename.}{ $note.}', } authordate2 = { u'@article':u'$authors. $year. $title. $journal, $volume($number), $pages.{ URL $url.}{ $note.}', u'@book':u'$authors. $year. $title. $publisher.{ URL $url.}{ $note.}', u'cite':u'$surname, $year', u'default':u'$authors. $year. $title. $publisher.{ URL $url.}{ $note.}', } default = { u'@article':u'$authors: “$title”, $journal,{ pp. $pages,} $year.{ URL $url.}{ $note.}', u'@book':u'{$authors: }$title{ ($editor, ed.)}.{{ $publisher,} $year.}{ URL $url.}{ $note.}', u'@booklet':u'$authors: $title.{{ $publisher,} $year.}{ URL $url.}{ $note.}', u'@conference':u'$authors: “$title”, $journal,{ pp. $pages,} $year.{ URL $url.}{ $note.}', u'@inbook':u'$authors: $title.{{ $publisher,} $year.}{ URL $url.}{ $note.}', u'@incollection':u'$authors: $title{ in $booktitle{ ($editor, ed.)}}.{{ $publisher,} $year.}{ URL $url.}{ $note.}', u'@inproceedings':u'$authors: “$title”, $booktitle,{ pp. $pages,} $year.{ URL $url.}{ $note.}', u'@manual':u'$authors: $title.{{ $publisher,} $year.}{ URL $url.}{ $note.}', u'@mastersthesis':u'$authors: $title.{{ $publisher,} $year.}{ URL $url.}{ $note.}', u'@misc':u'$authors: $title.{{ $publisher,}{ $howpublished,} $year.}{ URL $url.}{ $note.}', u'@phdthesis':u'$authors: $title.{{ $publisher,} $year.}{ URL $url.}{ $note.}', u'@proceedings':u'$authors: “$title”, $journal,{ pp. $pages,} $year.{ URL $url.}{ $note.}', u'@techreport':u'$authors: $title, $year.{ URL $url.}{ $note.}', u'@unpublished':u'$authors: “$title”, $journal, $year.{ URL $url.}{ $note.}', u'cite':u'$index', u'default':u'$authors: $title.{{ $publisher,} $year.}{ URL $url.}{ $note.}', } defaulttags = { u'YY':u'??', u'authors':u'', u'surname':u'', } ieeetr = { u'@article':u'$authors, “$title”, $journal, vol. $volume, no. $number, pp. $pages, $year.{ URL $url.}{ $note.}', u'@book':u'$authors, $title. $publisher, $year.{ URL $url.}{ $note.}', u'cite':u'$index', u'default':u'$authors, “$title”. $year.{ URL $url.}{ $note.}', } plain = { u'@article':u'$authors. $title.{ $journal{, {$volume}{($number)}}{:$pages}{, $year}.}{ URL $url.}{ $note.}', u'@book':u'$authors. $title. $publisher,{ $month} $year.{ URL $url.}{ $note.}', u'@incollection':u'$authors. $title.{ In $booktitle {($editor, ed.)}.} $publisher,{ $month} $year.{ URL $url.}{ $note.}', u'@inproceedings':u'$authors. $title. { $booktitle{, {$volume}{($number)}}{:$pages}{, $year}.}{ URL $url.}{ $note.}', u'cite':u'$index', u'default':u'{$authors. }$title.{{ $publisher,} $year.}{ URL $url.}{ $note.}', } vancouver = { u'@article':u'$authors. $title. $journal, $year{;{$volume}{($number)}{:$pages}}.{ URL: $url.}{ $note.}', u'@book':u'$authors. $title. {$publisher, }$year.{ URL: $url.}{ $note.}', u'cite':u'$index', u'default':u'$authors. $title; {$publisher, }$year.{ $howpublished.}{ URL: $url.}{ $note.}', } class BibTeXConfig(object): "Configuration class from elyxer.config file" replaced = { u'--':u'—', u'..':u'.', } class ContainerConfig(object): "Configuration class from elyxer.config file" endings = { u'Align':u'\\end_layout', u'BarredText':u'\\bar', u'BoldText':u'\\series', u'Cell':u'':u'>', } html = { u'/>':u'>', } iso885915 = { u' ':u' ', u' ':u' ', u' ':u' ', } nonunicode = { u' ':u' ', } class FormulaConfig(object): "Configuration class from elyxer.config file" alphacommands = { u'\\AA':u'Å', u'\\AE':u'Æ', u'\\AmS':u'AmS', u'\\Angstroem':u'Å', u'\\DH':u'Ð', u'\\Koppa':u'Ϟ', u'\\L':u'Ł', u'\\Micro':u'µ', u'\\O':u'Ø', u'\\OE':u'Œ', u'\\Sampi':u'Ϡ', u'\\Stigma':u'Ϛ', u'\\TH':u'Þ', u'\\aa':u'å', u'\\ae':u'æ', u'\\alpha':u'α', u'\\beta':u'β', u'\\delta':u'δ', u'\\dh':u'ð', u'\\digamma':u'ϝ', u'\\epsilon':u'ϵ', u'\\eta':u'η', u'\\eth':u'ð', u'\\gamma':u'γ', u'\\i':u'ı', u'\\imath':u'ı', u'\\iota':u'ι', u'\\j':u'ȷ', u'\\jmath':u'ȷ', u'\\kappa':u'κ', u'\\koppa':u'ϟ', u'\\l':u'ł', u'\\lambda':u'λ', u'\\mu':u'μ', u'\\nu':u'ν', u'\\o':u'ø', u'\\oe':u'œ', u'\\omega':u'ω', u'\\phi':u'φ', u'\\pi':u'π', u'\\psi':u'ψ', u'\\rho':u'ρ', u'\\sampi':u'ϡ', u'\\sigma':u'σ', u'\\ss':u'ß', u'\\stigma':u'ϛ', u'\\tau':u'τ', u'\\tcohm':u'Ω', u'\\textcrh':u'ħ', u'\\th':u'þ', u'\\theta':u'θ', u'\\upsilon':u'υ', u'\\varDelta':u'∆', u'\\varGamma':u'Γ', u'\\varLambda':u'Λ', u'\\varOmega':u'Ω', u'\\varPhi':u'Φ', u'\\varPi':u'Π', u'\\varPsi':u'Ψ', u'\\varSigma':u'Σ', u'\\varTheta':u'Θ', u'\\varUpsilon':u'Υ', u'\\varXi':u'Ξ', u'\\varbeta':u'ϐ', u'\\varepsilon':u'ε', u'\\varkappa':u'ϰ', u'\\varphi':u'φ', u'\\varpi':u'ϖ', u'\\varrho':u'ϱ', u'\\varsigma':u'ς', u'\\vartheta':u'ϑ', u'\\xi':u'ξ', u'\\zeta':u'ζ', } array = { u'begin':u'\\begin', u'cellseparator':u'&', u'end':u'\\end', u'rowseparator':u'\\\\', } bigbrackets = { u'(':[u'⎛',u'⎜',u'⎝',], u')':[u'⎞',u'⎟',u'⎠',], u'[':[u'⎡',u'⎢',u'⎣',], u']':[u'⎤',u'⎥',u'⎦',], u'{':[u'⎧',u'⎪',u'⎨',u'⎩',], u'|':[u'|',], u'}':[u'⎫',u'⎪',u'⎬',u'⎭',], u'∥':[u'∥',], } bigsymbols = { u'∑':[u'⎲',u'⎳',], u'∫':[u'⌠',u'⌡',], } bracketcommands = { u'\\left':u'span class="symbol"', u'\\left.':u'', u'\\middle':u'span class="symbol"', u'\\right':u'span class="symbol"', u'\\right.':u'', } combiningfunctions = { u'\\"':u'̈', u'\\\'':u'́', u'\\^':u'̂', u'\\`':u'̀', u'\\acute':u'́', u'\\bar':u'̄', u'\\breve':u'̆', u'\\c':u'̧', u'\\check':u'̌', u'\\dddot':u'⃛', u'\\ddot':u'̈', u'\\dot':u'̇', u'\\grave':u'̀', u'\\hat':u'̂', u'\\mathring':u'̊', u'\\overleftarrow':u'⃖', u'\\overrightarrow':u'⃗', u'\\r':u'̊', u'\\s':u'̩', u'\\textcircled':u'⃝', u'\\textsubring':u'̥', u'\\tilde':u'̃', u'\\v':u'̌', u'\\vec':u'⃗', u'\\~':u'̃', } commands = { u'\\ ':u' ', u'\\!':u'', u'\\#':u'#', u'\\$':u'$', u'\\%':u'%', u'\\&':u'&', u'\\,':u' ', u'\\:':u' ', u'\\;':u' ', u'\\AC':u'∿', u'\\APLcomment':u'⍝', u'\\APLdownarrowbox':u'⍗', u'\\APLinput':u'⍞', u'\\APLinv':u'⌹', u'\\APLleftarrowbox':u'⍇', u'\\APLlog':u'⍟', u'\\APLrightarrowbox':u'⍈', u'\\APLuparrowbox':u'⍐', u'\\Box':u'□', u'\\Bumpeq':u'≎', u'\\CIRCLE':u'●', u'\\Cap':u'⋒', u'\\CapitalDifferentialD':u'ⅅ', u'\\CheckedBox':u'☑', u'\\Circle':u'○', u'\\Coloneqq':u'⩴', u'\\ComplexI':u'ⅈ', u'\\ComplexJ':u'ⅉ', u'\\Corresponds':u'≙', u'\\Cup':u'⋓', u'\\Delta':u'Δ', u'\\Diamond':u'◇', u'\\Diamondblack':u'◆', u'\\Diamonddot':u'⟐', u'\\DifferentialD':u'ⅆ', u'\\Downarrow':u'⇓', u'\\EUR':u'€', u'\\Euler':u'ℇ', u'\\ExponetialE':u'ⅇ', u'\\Finv':u'Ⅎ', u'\\Game':u'⅁', u'\\Gamma':u'Γ', u'\\Im':u'ℑ', u'\\Join':u'⨝', u'\\LEFTCIRCLE':u'◖', u'\\LEFTcircle':u'◐', u'\\LHD':u'◀', u'\\Lambda':u'Λ', u'\\Lbag':u'⟅', u'\\Leftarrow':u'⇐', u'\\Lleftarrow':u'⇚', u'\\Longleftarrow':u'⟸', u'\\Longleftrightarrow':u'⟺', u'\\Longrightarrow':u'⟹', u'\\Lparen':u'⦅', u'\\Lsh':u'↰', u'\\Mapsfrom':u'⇐|', u'\\Mapsto':u'|⇒', u'\\Omega':u'Ω', u'\\P':u'¶', u'\\Phi':u'Φ', u'\\Pi':u'Π', u'\\Pr':u'Pr', u'\\Psi':u'Ψ', u'\\Qoppa':u'Ϙ', u'\\RHD':u'▶', u'\\RIGHTCIRCLE':u'◗', u'\\RIGHTcircle':u'◑', u'\\Rbag':u'⟆', u'\\Re':u'ℜ', u'\\Rparen':u'⦆', u'\\Rrightarrow':u'⇛', u'\\Rsh':u'↱', u'\\S':u'§', u'\\Sigma':u'Σ', u'\\Square':u'☐', u'\\Subset':u'⋐', u'\\Sun':u'☉', u'\\Supset':u'⋑', u'\\Theta':u'Θ', u'\\Uparrow':u'⇑', u'\\Updownarrow':u'⇕', u'\\Upsilon':u'Υ', u'\\Vdash':u'⊩', u'\\Vert':u'∥', u'\\Vvdash':u'⊪', u'\\XBox':u'☒', u'\\Xi':u'Ξ', u'\\Yup':u'⅄', u'\\\\':u'
', u'\\_':u'_', u'\\aleph':u'ℵ', u'\\amalg':u'∐', u'\\anchor':u'⚓', u'\\angle':u'∠', u'\\aquarius':u'♒', u'\\arccos':u'arccos', u'\\arcsin':u'arcsin', u'\\arctan':u'arctan', u'\\arg':u'arg', u'\\aries':u'♈', u'\\arrowbullet':u'➢', u'\\ast':u'∗', u'\\asymp':u'≍', u'\\backepsilon':u'∍', u'\\backprime':u'‵', u'\\backsimeq':u'⋍', u'\\backslash':u'\\', u'\\ballotx':u'✗', u'\\barwedge':u'⊼', u'\\because':u'∵', u'\\beth':u'ℶ', u'\\between':u'≬', u'\\bigcap':u'∩', u'\\bigcirc':u'○', u'\\bigcup':u'∪', u'\\bigodot':u'⊙', u'\\bigoplus':u'⊕', u'\\bigotimes':u'⊗', u'\\bigsqcup':u'⊔', u'\\bigstar':u'★', u'\\bigtriangledown':u'▽', u'\\bigtriangleup':u'△', u'\\biguplus':u'⊎', u'\\bigvee':u'∨', u'\\bigwedge':u'∧', u'\\biohazard':u'☣', u'\\blacklozenge':u'⧫', u'\\blacksmiley':u'☻', u'\\blacksquare':u'■', u'\\blacktriangle':u'▲', u'\\blacktriangledown':u'▼', u'\\blacktriangleleft':u'◂', u'\\blacktriangleright':u'▶', u'\\blacktriangleup':u'▴', u'\\bot':u'⊥', u'\\bowtie':u'⋈', u'\\box':u'▫', u'\\boxast':u'⧆', u'\\boxbar':u'◫', u'\\boxbox':u'⧈', u'\\boxbslash':u'⧅', u'\\boxcircle':u'⧇', u'\\boxdot':u'⊡', u'\\boxminus':u'⊟', u'\\boxplus':u'⊞', u'\\boxslash':u'⧄', u'\\boxtimes':u'⊠', u'\\bullet':u'•', u'\\bumpeq':u'≏', u'\\cancer':u'♋', u'\\cap':u'∩', u'\\capricornus':u'♑', u'\\cat':u'⁀', u'\\cdot':u'⋅', u'\\cdots':u'⋯', u'\\cent':u'¢', u'\\centerdot':u'∙', u'\\checkmark':u'✓', u'\\chi':u'χ', u'\\circ':u'○', u'\\circeq':u'≗', u'\\circlearrowleft':u'↺', u'\\circlearrowright':u'↻', u'\\circledR':u'®', u'\\circledast':u'⊛', u'\\circledbslash':u'⦸', u'\\circledcirc':u'⊚', u'\\circleddash':u'⊝', u'\\circledgtr':u'⧁', u'\\circledless':u'⧀', u'\\clubsuit':u'♣', u'\\coloneqq':u'≔', u'\\complement':u'∁', u'\\cong':u'≅', u'\\coprod':u'∐', u'\\copyright':u'©', u'\\cos':u'cos', u'\\cosh':u'cosh', u'\\cot':u'cot', u'\\coth':u'coth', u'\\csc':u'csc', u'\\cup':u'∪', u'\\curlyvee':u'⋎', u'\\curlywedge':u'⋏', u'\\curvearrowleft':u'↶', u'\\curvearrowright':u'↷', u'\\dag':u'†', u'\\dagger':u'†', u'\\daleth':u'ℸ', u'\\dashleftarrow':u'⇠', u'\\dashv':u'⊣', u'\\ddag':u'‡', u'\\ddagger':u'‡', u'\\ddots':u'⋱', u'\\deg':u'deg', u'\\det':u'det', u'\\diagdown':u'╲', u'\\diagup':u'╱', u'\\diameter':u'⌀', u'\\diamond':u'◇', u'\\diamondsuit':u'♦', u'\\dim':u'dim', u'\\div':u'÷', u'\\divideontimes':u'⋇', u'\\dotdiv':u'∸', u'\\doteq':u'≐', u'\\doteqdot':u'≑', u'\\dotplus':u'∔', u'\\dots':u'…', u'\\doublebarwedge':u'⌆', u'\\downarrow':u'↓', u'\\downdownarrows':u'⇊', u'\\downharpoonleft':u'⇃', u'\\downharpoonright':u'⇂', u'\\dsub':u'⩤', u'\\earth':u'♁', u'\\eighthnote':u'♪', u'\\ell':u'ℓ', u'\\emptyset':u'∅', u'\\eqcirc':u'≖', u'\\eqcolon':u'≕', u'\\eqsim':u'≂', u'\\euro':u'€', u'\\exists':u'∃', u'\\exp':u'exp', u'\\fallingdotseq':u'≒', u'\\fcmp':u'⨾', u'\\female':u'♀', u'\\flat':u'♭', u'\\forall':u'∀', u'\\fourth':u'⁗', u'\\frown':u'⌢', u'\\frownie':u'☹', u'\\gcd':u'gcd', u'\\gemini':u'♊', u'\\geq)':u'≥', u'\\geqq':u'≧', u'\\geqslant':u'≥', u'\\gets':u'←', u'\\gg':u'≫', u'\\ggg':u'⋙', u'\\gimel':u'ℷ', u'\\gneqq':u'≩', u'\\gnsim':u'⋧', u'\\gtrdot':u'⋗', u'\\gtreqless':u'⋚', u'\\gtreqqless':u'⪌', u'\\gtrless':u'≷', u'\\gtrsim':u'≳', u'\\guillemotleft':u'«', u'\\guillemotright':u'»', u'\\hbar':u'ℏ', u'\\heartsuit':u'♥', u'\\hfill':u' ', u'\\hom':u'hom', u'\\hookleftarrow':u'↩', u'\\hookrightarrow':u'↪', u'\\hslash':u'ℏ', u'\\idotsint':u'∫⋯∫', u'\\iiint':u'', u'\\iint':u'', u'\\imath':u'ı', u'\\inf':u'inf', u'\\infty':u'∞', u'\\intercal':u'⊺', u'\\interleave':u'⫴', u'\\invamp':u'⅋', u'\\invneg':u'⌐', u'\\jmath':u'ȷ', u'\\jupiter':u'♃', u'\\ker':u'ker', u'\\land':u'∧', u'\\landupint':u'', u'\\lang':u'⟪', u'\\langle':u'⟨', u'\\lblot':u'⦉', u'\\lbrace':u'{', u'\\lbrace)':u'{', u'\\lbrack':u'[', u'\\lceil':u'⌈', u'\\ldots':u'…', u'\\leadsto':u'⇝', u'\\leftarrow)':u'←', u'\\leftarrowtail':u'↢', u'\\leftarrowtobar':u'⇤', u'\\leftharpoondown':u'↽', u'\\leftharpoonup':u'↼', u'\\leftleftarrows':u'⇇', u'\\leftleftharpoons':u'⥢', u'\\leftmoon':u'☾', u'\\leftrightarrow':u'↔', u'\\leftrightarrows':u'⇆', u'\\leftrightharpoons':u'⇋', u'\\leftthreetimes':u'⋋', u'\\leo':u'♌', u'\\leq)':u'≤', u'\\leqq':u'≦', u'\\leqslant':u'≤', u'\\lessdot':u'⋖', u'\\lesseqgtr':u'⋛', u'\\lesseqqgtr':u'⪋', u'\\lessgtr':u'≶', u'\\lesssim':u'≲', u'\\lfloor':u'⌊', u'\\lg':u'lg', u'\\lgroup':u'⟮', u'\\lhd':u'⊲', u'\\libra':u'♎', u'\\lightning':u'↯', u'\\limg':u'⦇', u'\\liminf':u'liminf', u'\\limsup':u'limsup', u'\\ll':u'≪', u'\\llbracket':u'⟦', u'\\llcorner':u'⌞', u'\\lll':u'⋘', u'\\ln':u'ln', u'\\lneqq':u'≨', u'\\lnot':u'¬', u'\\lnsim':u'⋦', u'\\log':u'log', u'\\longleftarrow':u'⟵', u'\\longleftrightarrow':u'⟷', u'\\longmapsto':u'⟼', u'\\longrightarrow':u'⟶', u'\\looparrowleft':u'↫', u'\\looparrowright':u'↬', u'\\lor':u'∨', u'\\lozenge':u'◊', u'\\lrcorner':u'⌟', u'\\ltimes':u'⋉', u'\\lyxlock':u'', u'\\male':u'♂', u'\\maltese':u'✠', u'\\mapsfrom':u'↤', u'\\mapsto':u'↦', u'\\mathcircumflex':u'^', u'\\max':u'max', u'\\measuredangle':u'∡', u'\\medbullet':u'⚫', u'\\medcirc':u'⚪', u'\\mercury':u'☿', u'\\mho':u'℧', u'\\mid':u'∣', u'\\min':u'min', u'\\models':u'⊨', u'\\mp':u'∓', u'\\multimap':u'⊸', u'\\nLeftarrow':u'⇍', u'\\nLeftrightarrow':u'⇎', u'\\nRightarrow':u'⇏', u'\\nVDash':u'⊯', u'\\nabla':u'∇', u'\\napprox':u'≉', u'\\natural':u'♮', u'\\ncong':u'≇', u'\\nearrow':u'↗', u'\\neg':u'¬', u'\\neg)':u'¬', u'\\neptune':u'♆', u'\\nequiv':u'≢', u'\\newline':u'
', u'\\nexists':u'∄', u'\\ngeqslant':u'≱', u'\\ngtr':u'≯', u'\\ngtrless':u'≹', u'\\ni':u'∋', u'\\ni)':u'∋', u'\\nleftarrow':u'↚', u'\\nleftrightarrow':u'↮', u'\\nleqslant':u'≰', u'\\nless':u'≮', u'\\nlessgtr':u'≸', u'\\nmid':u'∤', u'\\nolimits':u'', u'\\nonumber':u'', u'\\not':u'¬', u'\\not<':u'≮', u'\\not=':u'≠', u'\\not>':u'≯', u'\\notbackslash':u'⍀', u'\\notin':u'∉', u'\\notni':u'∌', u'\\notslash':u'⌿', u'\\nparallel':u'∦', u'\\nprec':u'⊀', u'\\nrightarrow':u'↛', u'\\nsim':u'≁', u'\\nsimeq':u'≄', u'\\nsqsubset':u'⊏̸', u'\\nsubseteq':u'⊈', u'\\nsucc':u'⊁', u'\\nsucccurlyeq':u'⋡', u'\\nsupset':u'⊅', u'\\nsupseteq':u'⊉', u'\\ntriangleleft':u'⋪', u'\\ntrianglelefteq':u'⋬', u'\\ntriangleright':u'⋫', u'\\ntrianglerighteq':u'⋭', u'\\nvDash':u'⊭', u'\\nvdash':u'⊬', u'\\nwarrow':u'↖', u'\\odot':u'⊙', u'\\officialeuro':u'€', u'\\oiiint':u'', u'\\oiint':u'', u'\\oint':u'', u'\\ointclockwise':u'', u'\\ointctrclockwise':u'', u'\\ominus':u'⊖', u'\\oplus':u'⊕', u'\\oslash':u'⊘', u'\\otimes':u'⊗', u'\\owns':u'∋', u'\\parallel':u'∥', u'\\partial':u'∂', u'\\pencil':u'✎', u'\\perp':u'⊥', u'\\pisces':u'♓', u'\\pitchfork':u'⋔', u'\\pluto':u'♇', u'\\pm':u'±', u'\\pointer':u'➪', u'\\pointright':u'☞', u'\\pounds':u'£', u'\\prec':u'≺', u'\\preccurlyeq':u'≼', u'\\preceq':u'≼', u'\\precsim':u'≾', u'\\prime':u'′', u'\\prompto':u'∝', u'\\qoppa':u'ϙ', u'\\qquad':u' ', u'\\quad':u' ', u'\\quarternote':u'♩', u'\\radiation':u'☢', u'\\rang':u'⟫', u'\\rangle':u'⟩', u'\\rblot':u'⦊', u'\\rbrace':u'}', u'\\rbrace)':u'}', u'\\rbrack':u']', u'\\rceil':u'⌉', u'\\recycle':u'♻', u'\\rfloor':u'⌋', u'\\rgroup':u'⟯', u'\\rhd':u'⊳', u'\\rightangle':u'∟', u'\\rightarrow)':u'→', u'\\rightarrowtail':u'↣', u'\\rightarrowtobar':u'⇥', u'\\rightharpoondown':u'⇁', u'\\rightharpoonup':u'⇀', u'\\rightharpooondown':u'⇁', u'\\rightharpooonup':u'⇀', u'\\rightleftarrows':u'⇄', u'\\rightleftharpoons':u'⇌', u'\\rightmoon':u'☽', u'\\rightrightarrows':u'⇉', u'\\rightrightharpoons':u'⥤', u'\\rightthreetimes':u'⋌', u'\\rimg':u'⦈', u'\\risingdotseq':u'≓', u'\\rrbracket':u'⟧', u'\\rsub':u'⩥', u'\\rtimes':u'⋊', u'\\sagittarius':u'♐', u'\\saturn':u'♄', u'\\scorpio':u'♏', u'\\searrow':u'↘', u'\\sec':u'sec', u'\\second':u'″', u'\\setminus':u'∖', u'\\sharp':u'♯', u'\\simeq':u'≃', u'\\sin':u'sin', u'\\sinh':u'sinh', u'\\sixteenthnote':u'♬', u'\\skull':u'☠', u'\\slash':u'∕', u'\\smallsetminus':u'∖', u'\\smalltriangledown':u'▿', u'\\smalltriangleleft':u'◃', u'\\smalltriangleright':u'▹', u'\\smalltriangleup':u'▵', u'\\smile':u'⌣', u'\\smiley':u'☺', u'\\spadesuit':u'♠', u'\\spddot':u'¨', u'\\sphat':u'', u'\\sphericalangle':u'∢', u'\\spot':u'⦁', u'\\sptilde':u'~', u'\\sqcap':u'⊓', u'\\sqcup':u'⊔', u'\\sqsubset':u'⊏', u'\\sqsubseteq':u'⊑', u'\\sqsupset':u'⊐', u'\\sqsupseteq':u'⊒', u'\\square':u'□', u'\\sslash':u'⫽', u'\\star':u'⋆', u'\\steaming':u'☕', u'\\subseteqq':u'⫅', u'\\subsetneqq':u'⫋', u'\\succ':u'≻', u'\\succcurlyeq':u'≽', u'\\succeq':u'≽', u'\\succnsim':u'⋩', u'\\succsim':u'≿', u'\\sun':u'☼', u'\\sup':u'sup', u'\\supseteqq':u'⫆', u'\\supsetneqq':u'⫌', u'\\surd':u'√', u'\\swarrow':u'↙', u'\\swords':u'⚔', u'\\talloblong':u'⫾', u'\\tan':u'tan', u'\\tanh':u'tanh', u'\\taurus':u'♉', u'\\textasciicircum':u'^', u'\\textasciitilde':u'~', u'\\textbackslash':u'\\', u'\\textcopyright':u'©\'', u'\\textdegree':u'°', u'\\textellipsis':u'…', u'\\textemdash':u'—', u'\\textendash':u'—', u'\\texteuro':u'€', u'\\textgreater':u'>', u'\\textless':u'<', u'\\textordfeminine':u'ª', u'\\textordmasculine':u'º', u'\\textquotedblleft':u'“', u'\\textquotedblright':u'”', u'\\textquoteright':u'’', u'\\textregistered':u'®', u'\\textrightarrow':u'→', u'\\textsection':u'§', u'\\texttrademark':u'™', u'\\texttwosuperior':u'²', u'\\textvisiblespace':u' ', u'\\therefore':u'∴', u'\\third':u'‴', u'\\top':u'⊤', u'\\triangle':u'△', u'\\triangleleft':u'⊲', u'\\trianglelefteq':u'⊴', u'\\triangleq':u'≜', u'\\triangleright':u'▷', u'\\trianglerighteq':u'⊵', u'\\twoheadleftarrow':u'↞', u'\\twoheadrightarrow':u'↠', u'\\twonotes':u'♫', u'\\udot':u'⊍', u'\\ulcorner':u'⌜', u'\\unlhd':u'⊴', u'\\unrhd':u'⊵', u'\\unrhl':u'⊵', u'\\uparrow':u'↑', u'\\updownarrow':u'↕', u'\\upharpoonleft':u'↿', u'\\upharpoonright':u'↾', u'\\uplus':u'⊎', u'\\upuparrows':u'⇈', u'\\uranus':u'♅', u'\\urcorner':u'⌝', u'\\vDash':u'⊨', u'\\varclubsuit':u'♧', u'\\vardiamondsuit':u'♦', u'\\varheartsuit':u'♥', u'\\varnothing':u'∅', u'\\varspadesuit':u'♤', u'\\vdash':u'⊢', u'\\vdots':u'⋮', u'\\vee':u'∨', u'\\vee)':u'∨', u'\\veebar':u'⊻', u'\\vert':u'∣', u'\\virgo':u'♍', u'\\warning':u'⚠', u'\\wasylozenge':u'⌑', u'\\wedge':u'∧', u'\\wedge)':u'∧', u'\\wp':u'℘', u'\\wr':u'≀', u'\\yen':u'¥', u'\\yinyang':u'☯', u'\\{':u'{', u'\\|':u'∥', u'\\}':u'}', } decoratedcommand = { } decoratingfunctions = { u'\\overleftarrow':u'⟵', u'\\overrightarrow':u'⟶', u'\\widehat':u'^', } endings = { u'bracket':u'}', u'complex':u'\\]', u'endafter':u'}', u'endbefore':u'\\end{', u'squarebracket':u']', } environments = { u'align':[u'r',u'l',], u'eqnarray':[u'r',u'c',u'l',], u'gathered':[u'l',u'l',], } fontfunctions = { u'\\boldsymbol':u'b', u'\\mathbb':u'span class="blackboard"', u'\\mathbb{A}':u'𝔸', u'\\mathbb{B}':u'𝔹', u'\\mathbb{C}':u'ℂ', u'\\mathbb{D}':u'𝔻', u'\\mathbb{E}':u'𝔼', u'\\mathbb{F}':u'𝔽', u'\\mathbb{G}':u'𝔾', u'\\mathbb{H}':u'ℍ', u'\\mathbb{J}':u'𝕁', u'\\mathbb{K}':u'𝕂', u'\\mathbb{L}':u'𝕃', u'\\mathbb{N}':u'ℕ', u'\\mathbb{O}':u'𝕆', u'\\mathbb{P}':u'ℙ', u'\\mathbb{Q}':u'ℚ', u'\\mathbb{R}':u'ℝ', u'\\mathbb{S}':u'𝕊', u'\\mathbb{T}':u'𝕋', u'\\mathbb{W}':u'𝕎', u'\\mathbb{Z}':u'ℤ', u'\\mathbf':u'b', u'\\mathcal':u'span class="scriptfont"', u'\\mathcal{B}':u'ℬ', u'\\mathcal{E}':u'ℰ', u'\\mathcal{F}':u'ℱ', u'\\mathcal{H}':u'ℋ', u'\\mathcal{I}':u'ℐ', u'\\mathcal{L}':u'ℒ', u'\\mathcal{M}':u'ℳ', u'\\mathcal{R}':u'ℛ', u'\\mathfrak':u'span class="fraktur"', u'\\mathfrak{C}':u'ℭ', u'\\mathfrak{F}':u'𝔉', u'\\mathfrak{H}':u'ℌ', u'\\mathfrak{I}':u'ℑ', u'\\mathfrak{R}':u'ℜ', u'\\mathfrak{Z}':u'ℨ', u'\\mathit':u'i', u'\\mathring{A}':u'Å', u'\\mathring{U}':u'Ů', u'\\mathring{a}':u'å', u'\\mathring{u}':u'ů', u'\\mathring{w}':u'ẘ', u'\\mathring{y}':u'ẙ', u'\\mathrm':u'span class="mathrm"', u'\\mathscr':u'span class="scriptfont"', u'\\mathscr{B}':u'ℬ', u'\\mathscr{E}':u'ℰ', u'\\mathscr{F}':u'ℱ', u'\\mathscr{H}':u'ℋ', u'\\mathscr{I}':u'ℐ', u'\\mathscr{L}':u'ℒ', u'\\mathscr{M}':u'ℳ', u'\\mathscr{R}':u'ℛ', u'\\mathsf':u'span class="mathsf"', u'\\mathtt':u'tt', } hybridfunctions = { u'\\addcontentsline':[u'{$p!}{$q!}{$r!}',u'f0{}',u'ignored',], u'\\addtocontents':[u'{$p!}{$q!}',u'f0{}',u'ignored',], u'\\backmatter':[u'',u'f0{}',u'ignored',], u'\\binom':[u'{$1}{$2}',u'f2{(}f0{f1{$1}f1{$2}}f2{)}',u'span class="binom"',u'span class="binomstack"',u'span class="bigsymbol"',], u'\\boxed':[u'{$1}',u'f0{$1}',u'span class="boxed"',], u'\\cfrac':[u'[$p!]{$1}{$2}',u'f0{f3{(}f1{$1}f3{)/(}f2{$2}f3{)}}',u'span class="fullfraction"',u'span class="numerator align-$p"',u'span class="denominator"',u'span class="ignored"',], u'\\color':[u'{$p!}{$1}',u'f0{$1}',u'span style="color: $p;"',], u'\\colorbox':[u'{$p!}{$1}',u'f0{$1}',u'span class="colorbox" style="background: $p;"',], u'\\dbinom':[u'{$1}{$2}',u'(f0{f1{f2{$1}}f1{f2{ }}f1{f2{$2}}})',u'span class="binomial"',u'span class="binomrow"',u'span class="binomcell"',], u'\\dfrac':[u'{$1}{$2}',u'f0{f3{(}f1{$1}f3{)/(}f2{$2}f3{)}}',u'span class="fullfraction"',u'span class="numerator"',u'span class="denominator"',u'span class="ignored"',], u'\\displaystyle':[u'{$1}',u'f0{$1}',u'span class="displaystyle"',], u'\\fancyfoot':[u'[$p!]{$q!}',u'f0{}',u'ignored',], u'\\fancyhead':[u'[$p!]{$q!}',u'f0{}',u'ignored',], u'\\fbox':[u'{$1}',u'f0{$1}',u'span class="fbox"',], u'\\fboxrule':[u'{$p!}',u'f0{}',u'ignored',], u'\\fboxsep':[u'{$p!}',u'f0{}',u'ignored',], u'\\fcolorbox':[u'{$p!}{$q!}{$1}',u'f0{$1}',u'span class="boxed" style="border-color: $p; background: $q;"',], u'\\frac':[u'{$1}{$2}',u'f0{f3{(}f1{$1}f3{)/(}f2{$2}f3{)}}',u'span class="fraction"',u'span class="numerator"',u'span class="denominator"',u'span class="ignored"',], u'\\framebox':[u'[$p!][$q!]{$1}',u'f0{$1}',u'span class="framebox align-$q" style="width: $p;"',], u'\\frontmatter':[u'',u'f0{}',u'ignored',], u'\\href':[u'[$o]{$u!}{$t!}',u'f0{$t}',u'a href="$u"',], u'\\hspace':[u'{$p!}',u'f0{ }',u'span class="hspace" style="width: $p;"',], u'\\leftroot':[u'{$p!}',u'f0{ }',u'span class="leftroot" style="width: $p;px"',], u'\\mainmatter':[u'',u'f0{}',u'ignored',], u'\\markboth':[u'{$p!}{$q!}',u'f0{}',u'ignored',], u'\\markright':[u'{$p!}',u'f0{}',u'ignored',], u'\\nicefrac':[u'{$1}{$2}',u'f0{f1{$1}⁄f2{$2}}',u'span class="fraction"',u'sup class="numerator"',u'sub class="denominator"',u'span class="ignored"',], u'\\parbox':[u'[$p!]{$w!}{$1}',u'f0{1}',u'div class="Boxed" style="width: $w;"',], u'\\raisebox':[u'{$p!}{$1}',u'f0{$1.font}',u'span class="raisebox" style="vertical-align: $p;"',], u'\\renewenvironment':[u'{$1!}{$2!}{$3!}',u'',], u'\\rule':[u'[$v!]{$w!}{$h!}',u'f0/',u'hr class="line" style="width: $w; height: $h;"',], u'\\scriptscriptstyle':[u'{$1}',u'f0{$1}',u'span class="scriptscriptstyle"',], u'\\scriptstyle':[u'{$1}',u'f0{$1}',u'span class="scriptstyle"',], u'\\sqrt':[u'[$0]{$1}',u'f0{f1{$0}f2{√}f4{(}f3{$1}f4{)}}',u'span class="sqrt"',u'sup class="root"',u'span class="radical"',u'span class="root"',u'span class="ignored"',], u'\\stackrel':[u'{$1}{$2}',u'f0{f1{$1}f2{$2}}',u'span class="stackrel"',u'span class="upstackrel"',u'span class="downstackrel"',], u'\\tbinom':[u'{$1}{$2}',u'(f0{f1{f2{$1}}f1{f2{ }}f1{f2{$2}}})',u'span class="binomial"',u'span class="binomrow"',u'span class="binomcell"',], u'\\textcolor':[u'{$p!}{$1}',u'f0{$1}',u'span style="color: $p;"',], u'\\textstyle':[u'{$1}',u'f0{$1}',u'span class="textstyle"',], u'\\thispagestyle':[u'{$p!}',u'f0{}',u'ignored',], u'\\unit':[u'[$0]{$1}',u'$0f0{$1.font}',u'span class="unit"',], u'\\unitfrac':[u'[$0]{$1}{$2}',u'$0f0{f1{$1.font}⁄f2{$2.font}}',u'span class="fraction"',u'sup class="unit"',u'sub class="unit"',], u'\\uproot':[u'{$p!}',u'f0{ }',u'span class="uproot" style="width: $p;px"',], u'\\url':[u'{$u!}',u'f0{$u}',u'a href="$u"',], u'\\vspace':[u'{$p!}',u'f0{ }',u'span class="vspace" style="height: $p;"',], } hybridsizes = { u'\\binom':u'$1+$2', u'\\cfrac':u'$1+$2', u'\\dbinom':u'$1+$2+1', u'\\dfrac':u'$1+$2', u'\\frac':u'$1+$2', u'\\tbinom':u'$1+$2+1', } labelfunctions = { u'\\label':u'a name="#"', } limitcommands = { u'\\biginterleave':u'⫼', u'\\bigsqcap':u'⨅', u'\\fint':u'⨏', u'\\iiiint':u'⨌', u'\\int':u'∫', u'\\intop':u'∫', u'\\lim':u'lim', u'\\prod':u'∏', u'\\smallint':u'∫', u'\\sqint':u'⨖', u'\\sum':u'∑', u'\\varointclockwise':u'∲', u'\\varprod':u'⨉', u'\\zcmp':u'⨟', u'\\zhide':u'⧹', u'\\zpipe':u'⨠', u'\\zproject':u'⨡', } misccommands = { u'\\limits':u'LimitPreviousCommand', u'\\newcommand':u'MacroDefinition', u'\\renewcommand':u'MacroDefinition', u'\\setcounter':u'SetCounterFunction', u'\\tag':u'FormulaTag', u'\\tag*':u'FormulaTag', u'\\today':u'TodayCommand', } modified = { u'\n':u'', u' ':u'', u'$':u'', u'&':u' ', u'\'':u'’', u'+':u' + ', u',':u', ', u'-':u' − ', u'/':u' ⁄ ', u'<':u' < ', u'=':u' = ', u'>':u' > ', u'@':u'', u'~':u'', } onefunctions = { u'\\Big':u'span class="bigsymbol"', u'\\Bigg':u'span class="hugesymbol"', u'\\bar':u'span class="bar"', u'\\begin{array}':u'span class="arraydef"', u'\\big':u'span class="symbol"', u'\\bigg':u'span class="largesymbol"', u'\\bigl':u'span class="bigsymbol"', u'\\bigr':u'span class="bigsymbol"', u'\\centering':u'span class="align-center"', u'\\ensuremath':u'span class="ensuremath"', u'\\hphantom':u'span class="phantom"', u'\\noindent':u'span class="noindent"', u'\\overbrace':u'span class="overbrace"', u'\\overline':u'span class="overline"', u'\\phantom':u'span class="phantom"', u'\\underbrace':u'span class="underbrace"', u'\\underline':u'u', u'\\vphantom':u'span class="phantom"', } spacedcommands = { u'\\Bot':u'⫫', u'\\Doteq':u'≑', u'\\DownArrowBar':u'⤓', u'\\DownLeftTeeVector':u'⥞', u'\\DownLeftVectorBar':u'⥖', u'\\DownRightTeeVector':u'⥟', u'\\DownRightVectorBar':u'⥗', u'\\Equal':u'⩵', u'\\LeftArrowBar':u'⇤', u'\\LeftDownTeeVector':u'⥡', u'\\LeftDownVectorBar':u'⥙', u'\\LeftTeeVector':u'⥚', u'\\LeftTriangleBar':u'⧏', u'\\LeftUpTeeVector':u'⥠', u'\\LeftUpVectorBar':u'⥘', u'\\LeftVectorBar':u'⥒', u'\\Leftrightarrow':u'⇔', u'\\Longmapsfrom':u'⟽', u'\\Longmapsto':u'⟾', u'\\MapsDown':u'↧', u'\\MapsUp':u'↥', u'\\Nearrow':u'⇗', u'\\NestedGreaterGreater':u'⪢', u'\\NestedLessLess':u'⪡', u'\\NotGreaterLess':u'≹', u'\\NotGreaterTilde':u'≵', u'\\NotLessTilde':u'≴', u'\\Nwarrow':u'⇖', u'\\Proportion':u'∷', u'\\RightArrowBar':u'⇥', u'\\RightDownTeeVector':u'⥝', u'\\RightDownVectorBar':u'⥕', u'\\RightTeeVector':u'⥛', u'\\RightTriangleBar':u'⧐', u'\\RightUpTeeVector':u'⥜', u'\\RightUpVectorBar':u'⥔', u'\\RightVectorBar':u'⥓', u'\\Rightarrow':u'⇒', u'\\Same':u'⩶', u'\\Searrow':u'⇘', u'\\Swarrow':u'⇙', u'\\Top':u'⫪', u'\\UpArrowBar':u'⤒', u'\\VDash':u'⊫', u'\\approx':u'≈', u'\\approxeq':u'≊', u'\\backsim':u'∽', u'\\barin':u'⋶', u'\\barleftharpoon':u'⥫', u'\\barrightharpoon':u'⥭', u'\\bij':u'⤖', u'\\coloneq':u'≔', u'\\corresponds':u'≙', u'\\curlyeqprec':u'⋞', u'\\curlyeqsucc':u'⋟', u'\\dashrightarrow':u'⇢', u'\\dlsh':u'↲', u'\\downdownharpoons':u'⥥', u'\\downuparrows':u'⇵', u'\\downupharpoons':u'⥯', u'\\drsh':u'↳', u'\\eqslantgtr':u'⪖', u'\\eqslantless':u'⪕', u'\\equiv':u'≡', u'\\ffun':u'⇻', u'\\finj':u'⤕', u'\\ge':u'≥', u'\\geq':u'≥', u'\\ggcurly':u'⪼', u'\\gnapprox':u'⪊', u'\\gneq':u'⪈', u'\\gtrapprox':u'⪆', u'\\hash':u'⋕', u'\\iddots':u'⋰', u'\\implies':u' ⇒ ', u'\\in':u'∈', u'\\le':u'≤', u'\\leftarrow':u'←', u'\\leftarrowtriangle':u'⇽', u'\\leftbarharpoon':u'⥪', u'\\leftrightarrowtriangle':u'⇿', u'\\leftrightharpoon':u'⥊', u'\\leftrightharpoondown':u'⥐', u'\\leftrightharpoonup':u'⥎', u'\\leftrightsquigarrow':u'↭', u'\\leftslice':u'⪦', u'\\leftsquigarrow':u'⇜', u'\\leftupdownharpoon':u'⥑', u'\\leq':u'≤', u'\\lessapprox':u'⪅', u'\\llcurly':u'⪻', u'\\lnapprox':u'⪉', u'\\lneq':u'⪇', u'\\longmapsfrom':u'⟻', u'\\multimapboth':u'⧟', u'\\multimapdotbothA':u'⊶', u'\\multimapdotbothB':u'⊷', u'\\multimapinv':u'⟜', u'\\nVdash':u'⊮', u'\\ne':u'≠', u'\\neq':u'≠', u'\\ngeq':u'≱', u'\\nleq':u'≰', u'\\nni':u'∌', u'\\not\\in':u'∉', u'\\notasymp':u'≭', u'\\npreceq':u'⋠', u'\\nsqsubseteq':u'⋢', u'\\nsqsupseteq':u'⋣', u'\\nsubset':u'⊄', u'\\nsucceq':u'⋡', u'\\pfun':u'⇸', u'\\pinj':u'⤔', u'\\precapprox':u'⪷', u'\\preceqq':u'⪳', u'\\precnapprox':u'⪹', u'\\precnsim':u'⋨', u'\\propto':u'∝', u'\\psur':u'⤀', u'\\rightarrow':u'→', u'\\rightarrowtriangle':u'⇾', u'\\rightbarharpoon':u'⥬', u'\\rightleftharpoon':u'⥋', u'\\rightslice':u'⪧', u'\\rightsquigarrow':u'⇝', u'\\rightupdownharpoon':u'⥏', u'\\sim':u'~', u'\\strictfi':u'⥼', u'\\strictif':u'⥽', u'\\subset':u'⊂', u'\\subseteq':u'⊆', u'\\subsetneq':u'⊊', u'\\succapprox':u'⪸', u'\\succeqq':u'⪴', u'\\succnapprox':u'⪺', u'\\supset':u'⊃', u'\\supseteq':u'⊇', u'\\supsetneq':u'⊋', u'\\times':u'×', u'\\to':u'→', u'\\updownarrows':u'⇅', u'\\updownharpoons':u'⥮', u'\\upupharpoons':u'⥣', u'\\vartriangleleft':u'⊲', u'\\vartriangleright':u'⊳', } starts = { u'beginafter':u'}', u'beginbefore':u'\\begin{', u'bracket':u'{', u'command':u'\\', u'comment':u'%', u'complex':u'\\[', u'simple':u'$', u'squarebracket':u'[', u'unnumbered':u'*', } symbolfunctions = { u'^':u'sup', u'_':u'sub', } textfunctions = { u'\\mbox':u'span class="mbox"', u'\\text':u'span class="text"', u'\\textbf':u'b', u'\\textipa':u'span class="textipa"', u'\\textit':u'i', u'\\textnormal':u'span class="textnormal"', u'\\textrm':u'span class="textrm"', u'\\textsc':u'span class="versalitas"', u'\\textsf':u'span class="textsf"', u'\\textsl':u'i', u'\\texttt':u'tt', u'\\textup':u'span class="normal"', } unmodified = { u'characters':[u'.',u'*',u'€',u'(',u')',u'[',u']',u':',u'·',u'!',u';',u'|',u'§',u'"',], } urls = { u'googlecharts':u'http://chart.googleapis.com/chart?cht=tx&chl=', } class GeneralConfig(object): "Configuration class from elyxer.config file" version = { u'date':u'2013-03-10', u'lyxformat':u'413', u'number':u'1.2.4', } class HeaderConfig(object): "Configuration class from elyxer.config file" parameters = { u'beginpreamble':u'\\begin_preamble', u'branch':u'\\branch', u'documentclass':u'\\textclass', u'endbranch':u'\\end_branch', u'endpreamble':u'\\end_preamble', u'language':u'\\language', u'lstset':u'\\lstset', u'outputchanges':u'\\output_changes', u'paragraphseparation':u'\\paragraph_separation', u'pdftitle':u'\\pdf_title', u'secnumdepth':u'\\secnumdepth', u'tocdepth':u'\\tocdepth', } styles = { u'article':[u'article',u'aastex',u'aapaper',u'acmsiggraph',u'sigplanconf',u'achemso',u'amsart',u'apa',u'arab-article',u'armenian-article',u'article-beamer',u'chess',u'dtk',u'elsarticle',u'heb-article',u'IEEEtran',u'iopart',u'kluwer',u'scrarticle-beamer',u'scrartcl',u'extarticle',u'paper',u'mwart',u'revtex4',u'spie',u'svglobal3',u'ltugboat',u'agu-dtd',u'jgrga',u'agums',u'entcs',u'egs',u'ijmpc',u'ijmpd',u'singlecol-new',u'doublecol-new',u'isprs',u'tarticle',u'jsarticle',u'jarticle',u'jss',u'literate-article',u'siamltex',u'cl2emult',u'llncs',u'svglobal',u'svjog',u'svprobth',], u'book':[u'book',u'amsbook',u'scrbook',u'extbook',u'tufte-book',u'report',u'extreport',u'scrreprt',u'memoir',u'tbook',u'jsbook',u'jbook',u'mwbk',u'svmono',u'svmult',u'treport',u'jreport',u'mwrep',], } class ImageConfig(object): "Configuration class from elyxer.config file" converters = { u'imagemagick':u'convert[ -density $scale][ -define $format:use-cropbox=true] "$input" "$output"', u'inkscape':u'inkscape "$input" --export-png="$output"', u'lyx':u'lyx -C "$input" "$output"', } cropboxformats = { u'.eps':u'ps', u'.pdf':u'pdf', u'.ps':u'ps', } formats = { u'default':u'.png', u'vector':[u'.svg',u'.eps',], } class LayoutConfig(object): "Configuration class from elyxer.config file" groupable = { u'allowed':[u'StringContainer',u'Constant',u'TaggedText',u'Align',u'TextFamily',u'EmphaticText',u'VersalitasText',u'BarredText',u'SizeText',u'ColorText',u'LangLine',u'Formula',], } class NewfangleConfig(object): "Configuration class from elyxer.config file" constants = { u'chunkref':u'chunkref{', u'endcommand':u'}', u'endmark':u'>', u'startcommand':u'\\', u'startmark':u'=<', } class NumberingConfig(object): "Configuration class from elyxer.config file" layouts = { u'ordered':[u'Chapter',u'Section',u'Subsection',u'Subsubsection',u'Paragraph',], u'roman':[u'Part',u'Book',], } sequence = { u'symbols':[u'*',u'**',u'†',u'‡',u'§',u'§§',u'¶',u'¶¶',u'#',u'##',], } class StyleConfig(object): "Configuration class from elyxer.config file" hspaces = { u'\\enskip{}':u' ', u'\\hfill{}':u' ', u'\\hspace*{\\fill}':u' ', u'\\hspace*{}':u'', u'\\hspace{}':u' ', u'\\negthinspace{}':u'', u'\\qquad{}':u'  ', u'\\quad{}':u' ', u'\\space{}':u' ', u'\\thinspace{}':u' ', u'~':u' ', } quotes = { u'ald':u'»', u'als':u'›', u'ard':u'«', u'ars':u'‹', u'eld':u'“', u'els':u'‘', u'erd':u'”', u'ers':u'’', u'fld':u'«', u'fls':u'‹', u'frd':u'»', u'frs':u'›', u'gld':u'„', u'gls':u'‚', u'grd':u'“', u'grs':u'‘', u'pld':u'„', u'pls':u'‚', u'prd':u'”', u'prs':u'’', u'sld':u'”', u'srd':u'”', } referenceformats = { u'eqref':u'(@↕)', u'formatted':u'¶↕', u'nameref':u'$↕', u'pageref':u'#↕', u'ref':u'@↕', u'vpageref':u'on-page#↕', u'vref':u'@on-page#↕', } size = { u'ignoredtexts':[u'col',u'text',u'line',u'page',u'theight',u'pheight',], } vspaces = { u'bigskip':u'
', u'defskip':u'
', u'medskip':u'
', u'smallskip':u'
', u'vfill':u'
', } class TOCConfig(object): "Configuration class from elyxer.config file" extractplain = { u'allowed':[u'StringContainer',u'Constant',u'TaggedText',u'Align',u'TextFamily',u'EmphaticText',u'VersalitasText',u'BarredText',u'SizeText',u'ColorText',u'LangLine',u'Formula',], u'cloned':[u'',], u'extracted':[u'',], } extracttitle = { u'allowed':[u'StringContainer',u'Constant',u'Space',], u'cloned':[u'TextFamily',u'EmphaticText',u'VersalitasText',u'BarredText',u'SizeText',u'ColorText',u'LangLine',u'Formula',], u'extracted':[u'PlainLayout',u'TaggedText',u'Align',u'Caption',u'StandardLayout',u'FlexInset',], } class TagConfig(object): "Configuration class from elyxer.config file" barred = { u'under':u'u', } family = { u'sans':u'span class="sans"', u'typewriter':u'tt', } flex = { u'CharStyle:Code':u'span class="code"', u'CharStyle:MenuItem':u'span class="menuitem"', u'Code':u'span class="code"', u'MenuItem':u'span class="menuitem"', u'Noun':u'span class="noun"', u'Strong':u'span class="strong"', } group = { u'layouts':[u'Quotation',u'Quote',], } layouts = { u'Center':u'div', u'Chapter':u'h?', u'Date':u'h2', u'Paragraph':u'div', u'Part':u'h1', u'Quotation':u'blockquote', u'Quote':u'blockquote', u'Section':u'h?', u'Subsection':u'h?', u'Subsubsection':u'h?', } listitems = { u'Enumerate':u'ol', u'Itemize':u'ul', } notes = { u'Comment':u'', u'Greyedout':u'span class="greyedout"', u'Note':u'', } script = { u'subscript':u'sub', u'superscript':u'sup', } shaped = { u'italic':u'i', u'slanted':u'i', u'smallcaps':u'span class="versalitas"', } class TranslationConfig(object): "Configuration class from elyxer.config file" constants = { u'Appendix':u'Appendix', u'Book':u'Book', u'Chapter':u'Chapter', u'Paragraph':u'Paragraph', u'Part':u'Part', u'Section':u'Section', u'Subsection':u'Subsection', u'Subsubsection':u'Subsubsection', u'abstract':u'Abstract', u'bibliography':u'Bibliography', u'figure':u'figure', u'float-algorithm':u'Algorithm ', u'float-figure':u'Figure ', u'float-listing':u'Listing ', u'float-table':u'Table ', u'float-tableau':u'Tableau ', u'footnotes':u'Footnotes', u'generated-by':u'Document generated by ', u'generated-on':u' on ', u'index':u'Index', u'jsmath-enable':u'Please enable JavaScript on your browser.', u'jsmath-requires':u' requires JavaScript to correctly process the mathematics on this page. ', u'jsmath-warning':u'Warning: ', u'list-algorithm':u'List of Algorithms', u'list-figure':u'List of Figures', u'list-table':u'List of Tables', u'list-tableau':u'List of Tableaux', u'main-page':u'Main page', u'next':u'Next', u'nomenclature':u'Nomenclature', u'on-page':u' on page ', u'prev':u'Prev', u'references':u'References', u'toc':u'Table of Contents', u'toc-for':u'Contents for ', u'up':u'Up', } languages = { u'american':u'en', u'british':u'en', u'deutsch':u'de', u'dutch':u'nl', u'english':u'en', u'french':u'fr', u'ngerman':u'de', u'russian':u'ru', u'spanish':u'es', } class Globable(object): """A bit of text which can be globbed (lumped together in bits). Methods current(), skipcurrent(), checkfor() and isout() have to be implemented by subclasses.""" leavepending = False def __init__(self): self.endinglist = EndingList() def checkbytemark(self): "Check for a Unicode byte mark and skip it." if self.finished(): return if ord(self.current()) == 0xfeff: self.skipcurrent() def isout(self): "Find out if we are out of the position yet." Trace.error('Unimplemented isout()') return True def current(self): "Return the current character." Trace.error('Unimplemented current()') return '' def checkfor(self, string): "Check for the given string in the current position." Trace.error('Unimplemented checkfor()') return False def finished(self): "Find out if the current text has finished." if self.isout(): if not self.leavepending: self.endinglist.checkpending() return True return self.endinglist.checkin(self) def skipcurrent(self): "Return the current character and skip it." Trace.error('Unimplemented skipcurrent()') return '' def glob(self, currentcheck): "Glob a bit of text that satisfies a check on the current char." glob = '' while not self.finished() and currentcheck(): glob += self.skipcurrent() return glob def globalpha(self): "Glob a bit of alpha text" return self.glob(lambda: self.current().isalpha()) def globnumber(self): "Glob a row of digits." return self.glob(lambda: self.current().isdigit()) def isidentifier(self): "Return if the current character is alphanumeric or _." if self.current().isalnum() or self.current() == '_': return True return False def globidentifier(self): "Glob alphanumeric and _ symbols." return self.glob(self.isidentifier) def isvalue(self): "Return if the current character is a value character:" "not a bracket or a space." if self.current().isspace(): return False if self.current() in '{}()': return False return True def globvalue(self): "Glob a value: any symbols but brackets." return self.glob(self.isvalue) def skipspace(self): "Skip all whitespace at current position." return self.glob(lambda: self.current().isspace()) def globincluding(self, magicchar): "Glob a bit of text up to (including) the magic char." glob = self.glob(lambda: self.current() != magicchar) + magicchar self.skip(magicchar) return glob def globexcluding(self, excluded): "Glob a bit of text up until (excluding) any excluded character." return self.glob(lambda: self.current() not in excluded) def pushending(self, ending, optional = False): "Push a new ending to the bottom" self.endinglist.add(ending, optional) def popending(self, expected = None): "Pop the ending found at the current position" if self.isout() and self.leavepending: return expected ending = self.endinglist.pop(self) if expected and expected != ending: Trace.error('Expected ending ' + expected + ', got ' + ending) self.skip(ending) return ending def nextending(self): "Return the next ending in the queue." nextending = self.endinglist.findending(self) if not nextending: return None return nextending.ending class EndingList(object): "A list of position endings" def __init__(self): self.endings = [] def add(self, ending, optional = False): "Add a new ending to the list" self.endings.append(PositionEnding(ending, optional)) def pickpending(self, pos): "Pick any pending endings from a parse position." self.endings += pos.endinglist.endings def checkin(self, pos): "Search for an ending" if self.findending(pos): return True return False def pop(self, pos): "Remove the ending at the current position" if pos.isout(): Trace.error('No ending out of bounds') return '' ending = self.findending(pos) if not ending: Trace.error('No ending at ' + pos.current()) return '' for each in reversed(self.endings): self.endings.remove(each) if each == ending: return each.ending elif not each.optional: Trace.error('Removed non-optional ending ' + each) Trace.error('No endings left') return '' def findending(self, pos): "Find the ending at the current position" if len(self.endings) == 0: return None for index, ending in enumerate(reversed(self.endings)): if ending.checkin(pos): return ending if not ending.optional: return None return None def checkpending(self): "Check if there are any pending endings" if len(self.endings) != 0: Trace.error('Pending ' + unicode(self) + ' left open') def __unicode__(self): "Printable representation" string = 'endings [' for ending in self.endings: string += unicode(ending) + ',' if len(self.endings) > 0: string = string[:-1] return string + ']' class PositionEnding(object): "An ending for a parsing position" def __init__(self, ending, optional): self.ending = ending self.optional = optional def checkin(self, pos): "Check for the ending" return pos.checkfor(self.ending) def __unicode__(self): "Printable representation" string = 'Ending ' + self.ending if self.optional: string += ' (optional)' return string class Position(Globable): """A position in a text to parse. Including those in Globable, functions to implement by subclasses are: skip(), identifier(), extract(), isout() and current().""" def __init__(self): Globable.__init__(self) def skip(self, string): "Skip a string" Trace.error('Unimplemented skip()') def identifier(self): "Return an identifier for the current position." Trace.error('Unimplemented identifier()') return 'Error' def extract(self, length): "Extract the next string of the given length, or None if not enough text," "without advancing the parse position." Trace.error('Unimplemented extract()') return None def checkfor(self, string): "Check for a string at the given position." return string == self.extract(len(string)) def checkforlower(self, string): "Check for a string in lower case." extracted = self.extract(len(string)) if not extracted: return False return string.lower() == self.extract(len(string)).lower() def skipcurrent(self): "Return the current character and skip it." current = self.current() self.skip(current) return current def next(self): "Advance the position and return the next character." self.skipcurrent() return self.current() def checkskip(self, string): "Check for a string at the given position; if there, skip it" if not self.checkfor(string): return False self.skip(string) return True def error(self, message): "Show an error message and the position identifier." Trace.error(message + ': ' + self.identifier()) class TextPosition(Position): "A parse position based on a raw text." def __init__(self, text): "Create the position from elyxer.some text." Position.__init__(self) self.pos = 0 self.text = text self.checkbytemark() def skip(self, string): "Skip a string of characters." self.pos += len(string) def identifier(self): "Return a sample of the remaining text." length = 30 if self.pos + length > len(self.text): length = len(self.text) - self.pos return '*' + self.text[self.pos:self.pos + length] + '*' def isout(self): "Find out if we are out of the text yet." return self.pos >= len(self.text) def current(self): "Return the current character, assuming we are not out." return self.text[self.pos] def extract(self, length): "Extract the next string of the given length, or None if not enough text." if self.pos + length > len(self.text): return None return self.text[self.pos : self.pos + length] class FilePosition(Position): "A parse position based on an underlying file." def __init__(self, filename): "Create the position from a file." Position.__init__(self) self.reader = LineReader(filename) self.pos = 0 self.checkbytemark() def skip(self, string): "Skip a string of characters." length = len(string) while self.pos + length > len(self.reader.currentline()): length -= len(self.reader.currentline()) - self.pos + 1 self.nextline() self.pos += length def currentline(self): "Get the current line of the underlying file." return self.reader.currentline() def nextline(self): "Go to the next line." self.reader.nextline() self.pos = 0 def linenumber(self): "Return the line number of the file." return self.reader.linenumber + 1 def identifier(self): "Return the current line and line number in the file." before = self.reader.currentline()[:self.pos - 1] after = self.reader.currentline()[self.pos:] return 'line ' + unicode(self.getlinenumber()) + ': ' + before + '*' + after def isout(self): "Find out if we are out of the text yet." if self.pos > len(self.reader.currentline()): if self.pos > len(self.reader.currentline()) + 1: Trace.error('Out of the line ' + self.reader.currentline() + ': ' + unicode(self.pos)) self.nextline() return self.reader.finished() def current(self): "Return the current character, assuming we are not out." if self.pos == len(self.reader.currentline()): return '\n' if self.pos > len(self.reader.currentline()): Trace.error('Out of the line ' + self.reader.currentline() + ': ' + unicode(self.pos)) return '*' return self.reader.currentline()[self.pos] def extract(self, length): "Extract the next string of the given length, or None if not enough text." if self.pos + length > len(self.reader.currentline()): return None return self.reader.currentline()[self.pos : self.pos + length] files = list() def getreader(filename): "Get a reader for lines" if filename in files: # already parsed; skip return None files.append(filename) return LineReader(filename) def readargs(args): "Read arguments from the command line" del args[0] if len(args) == 0: usage() return None, None if args[0] == '-h' or args[0] == '--help': usage() return None, None reader = getreader(args[0]) del args[0] fileout = sys.stdout if len(args) > 0: fileout = args[0] del args[0] if len(args) > 0: usage() return writer = LineWriter(fileout) return reader, writer def usage(): "Show command line help." Trace.error('Usage: loremipsumize.py filein [fileout]') Trace.error('Mask your document using nonsensical words (Lorem Ipsum).') Trace.error('Part of the eLyXer package (http://elyxer.nongnu.org/).') Trace.error(' Options:') Trace.error(' --help: show this message and quit.') return class LoremIpsumizer(object): starts = '@\\' def loremipsumize(self, reader, writer): "Convert all texts longer than two words to 'lorem ipsum'." if not reader: return while not reader.finished(): line = self.processline(reader.currentline()) writer.writeline(line) reader.nextline() reader.close() def processline(self, line): "Process a single line and return the result." if len(line) == 0: return '' if line[0] in LoremIpsumizer.starts: return line pos = TextPosition(line) result = '' while not pos.finished(): result += self.parsepos(pos) return result def parsepos(self, pos): "Parse the current position, return the result." if pos.current().isalpha() or pos.current().isdigit(): alpha = pos.glob(lambda current: current.isalpha() or current.isspace() or current.isdigit()) if len(alpha.split()) > 2: return "lorem ipsum" return alpha if pos.current().isspace(): return pos.skipspace() return pos.skipcurrent() reader, writer = readargs(sys.argv) if reader: LoremIpsumizer().loremipsumize(reader, writer) writer.close() elyxer-1.2.5/forks/jras-elyxer/convert-guides0000755000175000017500000000250712117061342020613 0ustar chennochenno#!/bin/bash # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # Alex 20100131: convert all LyX guides # convert all LyX files in the given directory and its subdirectories report="\nConversion errors:\n" function convertall { for file in "$@"; do name=$(dirname "$file")/$(basename "$file" .lyx) ./elyxer.py --quiet --css ../docs/lyx.css "$name.lyx" "$name.html" result=$? if [ $result == "0" ]; then echo "$name.lyx OK"; fi if [ $result != "0" ]; then echo "$name.lyx KO" report="$report conversion of $name.lyx failed\n" fi done } echo "Converting all LyX guides in $1" convertall $1/*.lyx convertall $1/**/*.lyx echo -e $report elyxer-1.2.5/forks/jras-elyxer/create-version0000755000175000017500000000470312117061342020603 0ustar chennochenno#!/bin/bash # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # Alex 20090316: create a release VERSION=$(./elyxer.py --hardversion) DATE=$(./elyxer.py --versiondate) echo "Creating version $VERSION from $DATE" # Insert version date in changelog src/textchange.py "unreleased" $DATE docs/changelog.lyx ./elyxer.py --title="eLyXer changelog" --css "lyx.css" docs/changelog.lyx docs/changelog.html # Tag and push code git tag -a -m "Version $VERSION from $DATE to be released" $VERSION git push # Add version to setup.py for PyPI cp src/setup.py setup.py src/textchange.py "unknown" $VERSION setup.py # make compressed files rm -rf dist/elyxer-$VERSION mkdir -p dist/elyxer-$VERSION rsync -a --exclude "build" --exclude "dist" \ --exclude ".git" --exclude "samples" \ --exclude "docs/cvs" --exclude "patch" \ --exclude "docs/jsMath" --exclude "docs/MathJax" \ --exclude "extras" --exclude "open-env" \ --exclude "test/*test.html" --exclude "test/subdir/*test.html" \ --exclude "test/parts/*part-test*.html" \ --exclude "docs/#*#" \ . dist/elyxer-$VERSION/ cd dist/elyxer-$VERSION find . -name "*.pyc" | xargs rm -f find . -name "*.swp" | xargs rm -f find . -name "*.lyx~" | xargs rm -f find . -name "#*#" | xargs rm -f cd .. tar -czf elyxer-$VERSION.tar.gz elyxer-$VERSION rm -f elyxer-$VERSION.zip zip -qr elyxer-$VERSION.zip elyxer-$VERSION/* # Sign packages gpg -b elyxer-$VERSION.tar.gz gpg -b elyxer-$VERSION.zip # Upload to savannah scp elyxer-$VERSION.tar.gz elyxer-$VERSION.tar.gz.sig alexfernandez@dl.sv.nongnu.org:/releases/elyxer/ scp elyxer-$VERSION.zip elyxer-$VERSION.zip.sig alexfernandez@dl.sv.nongnu.org:/releases/elyxer/ # Upload docs cd ../docs ./upload.sh cd .. # Register with the PyPI python setup.py register elyxer-1.2.5/forks/jras-elyxer/make0000755000175000017500000000627512117061342016600 0ustar chennochenno#!/bin/bash # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # Alex 20090310: make script to generate "binary" # create executable files cd src ./exportconfig.py py ./coalesce.py load-elyxer.py ../elyxer.py ./coalesce.py loremipsumize.py ../loremipsumize.py ./coalesce.py math2html.py ../math2html.py ./licensify.py freebsd-license ../math2html.py cd .. chmod 755 elyxer.py chmod 755 loremipsumize.py chmod 755 math2html.py # create CSS files cd src ./coalesce.py css/master.css ../docs/lyx.css ./coalesce.py css/math.css ../docs/math.css ./licensify.py css/freebsd-license.css ../docs/math.css cd .. # internationalize cd src ./exportconfig.py po cd ../po for file in *.po; do lang=$(basename "$file" .po) mkdir -p locale/$lang/LC_MESSAGES msgfmt -o locale/$lang/LC_MESSAGES/elyxer.mo $lang.po done cd .. # remove artifacts rm -f docs/*.lyx~ rm -f test/*.lyx~ rm -f test/subdir/*.lyx~ # prepare documentation ./elyxer.py --title "eLyXer User Guide" --css "lyx.css" docs/userguide.lyx docs/userguide.html ./elyxer.py --tocfor "userguide.html" --target "contents" --css "toc.css" docs/userguide.lyx docs/userguide-toc.html ./elyxer.py --title="eLyxer Developer Guide" --css "lyx.css" docs/devguide.lyx docs/devguide.html ./elyxer.py --title=eLyXer --css "lyx.css" docs/index.lyx docs/index.html ./elyxer.py --title="eLyXer changelog" --css "lyx.css" docs/changelog.lyx docs/changelog.html ./elyxer.py --title="eLyxer Math Showcase (non-Unicode edition)" --css "lyx.css" docs/math.lyx docs/math.html ./elyxer.py --title="eLyxer Math Showcase (Unicode edition)" --unicode --css "lyx.css" docs/math.lyx docs/math-unicode.html ./elyxer.py --title="eLyxer Math Showcase (ISO-8859-15 edition)" --iso885915 --css "lyx.css" docs/math.lyx docs/math-iso885915.html ./elyxer.py --title="eLyxer Math Showcase (HTML edition)" --html --css "lyx.css" docs/math.lyx docs/math-html.html ./elyxer.py --title="eLyxer Math Showcase (MathJax remote edition)" --mathjax remote --css "lyx.css" docs/math.lyx docs/math-mathjax.html ./elyxer.py --title="eLyxer Math Showcase (MathJax local edition)" --mathjax "./MathJax" --css "lyx.css" docs/math.lyx docs/math-mathjax-local.html ./elyxer.py --title="eLyxer Math Showcase (Google Charts edition)" --googlecharts --css "lyx.css" docs/math.lyx docs/math-googlecharts.html # insert current version VERSION=$(./elyxer.py --hardversion) DATE=$(./elyxer.py --versiondate) cd src ./textchange.py "the latest version" "the latest version $VERSION, created on $DATE," ../docs/index.html cd .. # run the test suite ./run-tests elyxer-1.2.5/forks/jras-elyxer/elyxer.py0000755000175000017500000116206512117061347017630 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20090308 # eLyXer main script # http://www.nongnu.org/elyxer/ import sys import os.path import sys import codecs import sys class Trace(object): "A tracing class" debugmode = False quietmode = False showlinesmode = False prefix = None def debug(cls, message): "Show a debug message" if not Trace.debugmode or Trace.quietmode: return Trace.show(message, sys.stdout) def message(cls, message): "Show a trace message" if Trace.quietmode: return if Trace.prefix and Trace.showlinesmode: message = Trace.prefix + message Trace.show(message, sys.stdout) def error(cls, message): "Show an error message" message = '* ' + message if Trace.prefix and Trace.showlinesmode: message = Trace.prefix + message Trace.show(message, sys.stderr) def fatal(cls, message): "Show an error message and terminate" Trace.error('FATAL: ' + message) exit(-1) def show(cls, message, channel): "Show a message out of a channel" if sys.version_info < (3,0): message = message.encode('utf-8') channel.write(message + '\n') debug = classmethod(debug) message = classmethod(message) error = classmethod(error) fatal = classmethod(fatal) show = classmethod(show) class LineReader(object): "Reads a file line by line" def __init__(self, filename): if isinstance(filename, file): self.file = filename else: self.file = codecs.open(filename, 'rU', 'utf-8') self.linenumber = 1 self.lastline = None self.current = None self.mustread = True self.depleted = False try: self.readline() except UnicodeDecodeError: # try compressed file import gzip self.file = gzip.open(filename, 'rb') self.readline() def setstart(self, firstline): "Set the first line to read." for i in range(firstline): self.file.readline() self.linenumber = firstline def setend(self, lastline): "Set the last line to read." self.lastline = lastline def currentline(self): "Get the current line" if self.mustread: self.readline() return self.current def nextline(self): "Go to next line" if self.depleted: Trace.fatal('Read beyond file end') self.mustread = True def readline(self): "Read a line from elyxer.file" self.current = self.file.readline() if not isinstance(self.file, codecs.StreamReaderWriter): self.current = self.current.decode('utf-8') if len(self.current) == 0: self.depleted = True self.current = self.current.rstrip('\n\r') self.linenumber += 1 self.mustread = False Trace.prefix = 'Line ' + unicode(self.linenumber) + ': ' if self.linenumber % 1000 == 0: Trace.message('Parsing') def finished(self): "Find out if the file is finished" if self.lastline and self.linenumber == self.lastline: return True if self.mustread: self.readline() return self.depleted def close(self): self.file.close() class LineWriter(object): "Writes a file as a series of lists" file = False def __init__(self, filename): if isinstance(filename, file): self.file = filename self.filename = None else: self.filename = filename def write(self, strings): "Write a list of strings" for string in strings: if not isinstance(string, basestring): Trace.error('Not a string: ' + unicode(string) + ' in ' + unicode(strings)) return self.writestring(string) def writestring(self, string): "Write a string" if not self.file: self.file = codecs.open(self.filename, 'w', "utf-8") if self.file == sys.stdout and sys.version_info < (3,0): string = string.encode('utf-8') self.file.write(string) def writeline(self, line): "Write a line to file" self.writestring(line + '\n') def close(self): self.file.close() import os.path import sys class BibStylesConfig(object): "Configuration class from elyxer.config file" abbrvnat = { u'@article':u'$authors. $title. $journal,{ {$volume:}$pages,} $month $year.{ doi: $doi.}{ URL $url.}{ $note.}', u'cite':u'$surname($year)', u'default':u'$authors. $title. $publisher, $year.{ URL $url.}{ $note.}', } alpha = { u'@article':u'$authors. $title.{ $journal{, {$volume}{($number)}}{: $pages}{, $year}.}{ $url.}{ $filename.}{ $note.}', u'cite':u'$Sur$YY', u'default':u'$authors. $title.{ $journal,} $year.{ $url.}{ $filename.}{ $note.}', } authordate2 = { u'@article':u'$authors. $year. $title. $journal, $volume($number), $pages.{ URL $url.}{ $note.}', u'@book':u'$authors. $year. $title. $publisher.{ URL $url.}{ $note.}', u'cite':u'$surname, $year', u'default':u'$authors. $year. $title. $publisher.{ URL $url.}{ $note.}', } default = { u'@article':u'$authors: “$title”, $journal,{ pp. $pages,} $year.{ URL $url.}{ $note.}', u'@book':u'{$authors: }$title{ ($editor, ed.)}.{{ $publisher,} $year.}{ URL $url.}{ $note.}', u'@booklet':u'$authors: $title.{{ $publisher,} $year.}{ URL $url.}{ $note.}', u'@conference':u'$authors: “$title”, $journal,{ pp. $pages,} $year.{ URL $url.}{ $note.}', u'@inbook':u'$authors: $title.{{ $publisher,} $year.}{ URL $url.}{ $note.}', u'@incollection':u'$authors: $title{ in $booktitle{ ($editor, ed.)}}.{{ $publisher,} $year.}{ URL $url.}{ $note.}', u'@inproceedings':u'$authors: “$title”, $booktitle,{ pp. $pages,} $year.{ URL $url.}{ $note.}', u'@manual':u'$authors: $title.{{ $publisher,} $year.}{ URL $url.}{ $note.}', u'@mastersthesis':u'$authors: $title.{{ $publisher,} $year.}{ URL $url.}{ $note.}', u'@misc':u'$authors: $title.{{ $publisher,}{ $howpublished,} $year.}{ URL $url.}{ $note.}', u'@phdthesis':u'$authors: $title.{{ $publisher,} $year.}{ URL $url.}{ $note.}', u'@proceedings':u'$authors: “$title”, $journal,{ pp. $pages,} $year.{ URL $url.}{ $note.}', u'@techreport':u'$authors: $title, $year.{ URL $url.}{ $note.}', u'@unpublished':u'$authors: “$title”, $journal, $year.{ URL $url.}{ $note.}', u'cite':u'$index', u'default':u'$authors: $title.{{ $publisher,} $year.}{ URL $url.}{ $note.}', } defaulttags = { u'YY':u'??', u'authors':u'', u'surname':u'', } ieeetr = { u'@article':u'$authors, “$title”, $journal, vol. $volume, no. $number, pp. $pages, $year.{ URL $url.}{ $note.}', u'@book':u'$authors, $title. $publisher, $year.{ URL $url.}{ $note.}', u'cite':u'$index', u'default':u'$authors, “$title”. $year.{ URL $url.}{ $note.}', } plain = { u'@article':u'$authors. $title.{ $journal{, {$volume}{($number)}}{:$pages}{, $year}.}{ URL $url.}{ $note.}', u'@book':u'$authors. $title. $publisher,{ $month} $year.{ URL $url.}{ $note.}', u'@incollection':u'$authors. $title.{ In $booktitle {($editor, ed.)}.} $publisher,{ $month} $year.{ URL $url.}{ $note.}', u'@inproceedings':u'$authors. $title. { $booktitle{, {$volume}{($number)}}{:$pages}{, $year}.}{ URL $url.}{ $note.}', u'cite':u'$index', u'default':u'{$authors. }$title.{{ $publisher,} $year.}{ URL $url.}{ $note.}', } vancouver = { u'@article':u'$authors. $title. $journal, $year{;{$volume}{($number)}{:$pages}}.{ URL: $url.}{ $note.}', u'@book':u'$authors. $title. {$publisher, }$year.{ URL: $url.}{ $note.}', u'cite':u'$index', u'default':u'$authors. $title; {$publisher, }$year.{ $howpublished.}{ URL: $url.}{ $note.}', } class BibTeXConfig(object): "Configuration class from elyxer.config file" replaced = { u'--':u'—', u'..':u'.', } class ContainerConfig(object): "Configuration class from elyxer.config file" endings = { u'Align':u'\\end_layout', u'BarredText':u'\\bar', u'BoldText':u'\\series', u'Cell':u'':u'>', } html = { u'/>':u'>', } iso885915 = { u' ':u' ', u' ':u' ', u' ':u' ', } nonunicode = { u' ':u' ', } class FormulaConfig(object): "Configuration class from elyxer.config file" alphacommands = { u'\\AA':u'Å', u'\\AE':u'Æ', u'\\AmS':u'AmS', u'\\Angstroem':u'Å', u'\\DH':u'Ð', u'\\Koppa':u'Ϟ', u'\\L':u'Ł', u'\\Micro':u'µ', u'\\O':u'Ø', u'\\OE':u'Œ', u'\\Sampi':u'Ϡ', u'\\Stigma':u'Ϛ', u'\\TH':u'Þ', u'\\aa':u'å', u'\\ae':u'æ', u'\\alpha':u'α', u'\\beta':u'β', u'\\delta':u'δ', u'\\dh':u'ð', u'\\digamma':u'ϝ', u'\\epsilon':u'ϵ', u'\\eta':u'η', u'\\eth':u'ð', u'\\gamma':u'γ', u'\\i':u'ı', u'\\imath':u'ı', u'\\iota':u'ι', u'\\j':u'ȷ', u'\\jmath':u'ȷ', u'\\kappa':u'κ', u'\\koppa':u'ϟ', u'\\l':u'ł', u'\\lambda':u'λ', u'\\mu':u'μ', u'\\nu':u'ν', u'\\o':u'ø', u'\\oe':u'œ', u'\\omega':u'ω', u'\\phi':u'φ', u'\\pi':u'π', u'\\psi':u'ψ', u'\\rho':u'ρ', u'\\sampi':u'ϡ', u'\\sigma':u'σ', u'\\ss':u'ß', u'\\stigma':u'ϛ', u'\\tau':u'τ', u'\\tcohm':u'Ω', u'\\textcrh':u'ħ', u'\\th':u'þ', u'\\theta':u'θ', u'\\upsilon':u'υ', u'\\varDelta':u'∆', u'\\varGamma':u'Γ', u'\\varLambda':u'Λ', u'\\varOmega':u'Ω', u'\\varPhi':u'Φ', u'\\varPi':u'Π', u'\\varPsi':u'Ψ', u'\\varSigma':u'Σ', u'\\varTheta':u'Θ', u'\\varUpsilon':u'Υ', u'\\varXi':u'Ξ', u'\\varbeta':u'ϐ', u'\\varepsilon':u'ε', u'\\varkappa':u'ϰ', u'\\varphi':u'φ', u'\\varpi':u'ϖ', u'\\varrho':u'ϱ', u'\\varsigma':u'ς', u'\\vartheta':u'ϑ', u'\\xi':u'ξ', u'\\zeta':u'ζ', } array = { u'begin':u'\\begin', u'cellseparator':u'&', u'end':u'\\end', u'rowseparator':u'\\\\', } bigbrackets = { u'(':[u'⎛',u'⎜',u'⎝',], u')':[u'⎞',u'⎟',u'⎠',], u'[':[u'⎡',u'⎢',u'⎣',], u']':[u'⎤',u'⎥',u'⎦',], u'{':[u'⎧',u'⎪',u'⎨',u'⎩',], u'|':[u'|',], u'}':[u'⎫',u'⎪',u'⎬',u'⎭',], u'∥':[u'∥',], } bigsymbols = { u'∑':[u'⎲',u'⎳',], u'∫':[u'⌠',u'⌡',], } bracketcommands = { u'\\left':u'span class="symbol"', u'\\left.':u'', u'\\middle':u'span class="symbol"', u'\\right':u'span class="symbol"', u'\\right.':u'', } combiningfunctions = { u'\\"':u'̈', u'\\\'':u'́', u'\\^':u'̂', u'\\`':u'̀', u'\\acute':u'́', u'\\bar':u'̄', u'\\breve':u'̆', u'\\c':u'̧', u'\\check':u'̌', u'\\dddot':u'⃛', u'\\ddot':u'̈', u'\\dot':u'̇', u'\\grave':u'̀', u'\\hat':u'̂', u'\\mathring':u'̊', u'\\overleftarrow':u'⃖', u'\\overrightarrow':u'⃗', u'\\r':u'̊', u'\\s':u'̩', u'\\textcircled':u'⃝', u'\\textsubring':u'̥', u'\\tilde':u'̃', u'\\v':u'̌', u'\\vec':u'⃗', u'\\~':u'̃', } commands = { u'\\ ':u' ', u'\\!':u'', u'\\#':u'#', u'\\$':u'$', u'\\%':u'%', u'\\&':u'&', u'\\,':u' ', u'\\:':u' ', u'\\;':u' ', u'\\AC':u'∿', u'\\APLcomment':u'⍝', u'\\APLdownarrowbox':u'⍗', u'\\APLinput':u'⍞', u'\\APLinv':u'⌹', u'\\APLleftarrowbox':u'⍇', u'\\APLlog':u'⍟', u'\\APLrightarrowbox':u'⍈', u'\\APLuparrowbox':u'⍐', u'\\Box':u'□', u'\\Bumpeq':u'≎', u'\\CIRCLE':u'●', u'\\Cap':u'⋒', u'\\CapitalDifferentialD':u'ⅅ', u'\\CheckedBox':u'☑', u'\\Circle':u'○', u'\\Coloneqq':u'⩴', u'\\ComplexI':u'ⅈ', u'\\ComplexJ':u'ⅉ', u'\\Corresponds':u'≙', u'\\Cup':u'⋓', u'\\Delta':u'Δ', u'\\Diamond':u'◇', u'\\Diamondblack':u'◆', u'\\Diamonddot':u'⟐', u'\\DifferentialD':u'ⅆ', u'\\Downarrow':u'⇓', u'\\EUR':u'€', u'\\Euler':u'ℇ', u'\\ExponetialE':u'ⅇ', u'\\Finv':u'Ⅎ', u'\\Game':u'⅁', u'\\Gamma':u'Γ', u'\\Im':u'ℑ', u'\\Join':u'⨝', u'\\LEFTCIRCLE':u'◖', u'\\LEFTcircle':u'◐', u'\\LHD':u'◀', u'\\Lambda':u'Λ', u'\\Lbag':u'⟅', u'\\Leftarrow':u'⇐', u'\\Lleftarrow':u'⇚', u'\\Longleftarrow':u'⟸', u'\\Longleftrightarrow':u'⟺', u'\\Longrightarrow':u'⟹', u'\\Lparen':u'⦅', u'\\Lsh':u'↰', u'\\Mapsfrom':u'⇐|', u'\\Mapsto':u'|⇒', u'\\Omega':u'Ω', u'\\P':u'¶', u'\\Phi':u'Φ', u'\\Pi':u'Π', u'\\Pr':u'Pr', u'\\Psi':u'Ψ', u'\\Qoppa':u'Ϙ', u'\\RHD':u'▶', u'\\RIGHTCIRCLE':u'◗', u'\\RIGHTcircle':u'◑', u'\\Rbag':u'⟆', u'\\Re':u'ℜ', u'\\Rparen':u'⦆', u'\\Rrightarrow':u'⇛', u'\\Rsh':u'↱', u'\\S':u'§', u'\\Sigma':u'Σ', u'\\Square':u'☐', u'\\Subset':u'⋐', u'\\Sun':u'☉', u'\\Supset':u'⋑', u'\\Theta':u'Θ', u'\\Uparrow':u'⇑', u'\\Updownarrow':u'⇕', u'\\Upsilon':u'Υ', u'\\Vdash':u'⊩', u'\\Vert':u'∥', u'\\Vvdash':u'⊪', u'\\XBox':u'☒', u'\\Xi':u'Ξ', u'\\Yup':u'⅄', u'\\\\':u'
', u'\\_':u'_', u'\\aleph':u'ℵ', u'\\amalg':u'∐', u'\\anchor':u'⚓', u'\\angle':u'∠', u'\\aquarius':u'♒', u'\\arccos':u'arccos', u'\\arcsin':u'arcsin', u'\\arctan':u'arctan', u'\\arg':u'arg', u'\\aries':u'♈', u'\\arrowbullet':u'➢', u'\\ast':u'∗', u'\\asymp':u'≍', u'\\backepsilon':u'∍', u'\\backprime':u'‵', u'\\backsimeq':u'⋍', u'\\backslash':u'\\', u'\\ballotx':u'✗', u'\\barwedge':u'⊼', u'\\because':u'∵', u'\\beth':u'ℶ', u'\\between':u'≬', u'\\bigcap':u'∩', u'\\bigcirc':u'○', u'\\bigcup':u'∪', u'\\bigodot':u'⊙', u'\\bigoplus':u'⊕', u'\\bigotimes':u'⊗', u'\\bigsqcup':u'⊔', u'\\bigstar':u'★', u'\\bigtriangledown':u'▽', u'\\bigtriangleup':u'△', u'\\biguplus':u'⊎', u'\\bigvee':u'∨', u'\\bigwedge':u'∧', u'\\biohazard':u'☣', u'\\blacklozenge':u'⧫', u'\\blacksmiley':u'☻', u'\\blacksquare':u'■', u'\\blacktriangle':u'▲', u'\\blacktriangledown':u'▼', u'\\blacktriangleleft':u'◂', u'\\blacktriangleright':u'▶', u'\\blacktriangleup':u'▴', u'\\bot':u'⊥', u'\\bowtie':u'⋈', u'\\box':u'▫', u'\\boxast':u'⧆', u'\\boxbar':u'◫', u'\\boxbox':u'⧈', u'\\boxbslash':u'⧅', u'\\boxcircle':u'⧇', u'\\boxdot':u'⊡', u'\\boxminus':u'⊟', u'\\boxplus':u'⊞', u'\\boxslash':u'⧄', u'\\boxtimes':u'⊠', u'\\bullet':u'•', u'\\bumpeq':u'≏', u'\\cancer':u'♋', u'\\cap':u'∩', u'\\capricornus':u'♑', u'\\cat':u'⁀', u'\\cdot':u'⋅', u'\\cdots':u'⋯', u'\\cent':u'¢', u'\\centerdot':u'∙', u'\\checkmark':u'✓', u'\\chi':u'χ', u'\\circ':u'○', u'\\circeq':u'≗', u'\\circlearrowleft':u'↺', u'\\circlearrowright':u'↻', u'\\circledR':u'®', u'\\circledast':u'⊛', u'\\circledbslash':u'⦸', u'\\circledcirc':u'⊚', u'\\circleddash':u'⊝', u'\\circledgtr':u'⧁', u'\\circledless':u'⧀', u'\\clubsuit':u'♣', u'\\coloneqq':u'≔', u'\\complement':u'∁', u'\\cong':u'≅', u'\\coprod':u'∐', u'\\copyright':u'©', u'\\cos':u'cos', u'\\cosh':u'cosh', u'\\cot':u'cot', u'\\coth':u'coth', u'\\csc':u'csc', u'\\cup':u'∪', u'\\curlyvee':u'⋎', u'\\curlywedge':u'⋏', u'\\curvearrowleft':u'↶', u'\\curvearrowright':u'↷', u'\\dag':u'†', u'\\dagger':u'†', u'\\daleth':u'ℸ', u'\\dashleftarrow':u'⇠', u'\\dashv':u'⊣', u'\\ddag':u'‡', u'\\ddagger':u'‡', u'\\ddots':u'⋱', u'\\deg':u'deg', u'\\det':u'det', u'\\diagdown':u'╲', u'\\diagup':u'╱', u'\\diameter':u'⌀', u'\\diamond':u'◇', u'\\diamondsuit':u'♦', u'\\dim':u'dim', u'\\div':u'÷', u'\\divideontimes':u'⋇', u'\\dotdiv':u'∸', u'\\doteq':u'≐', u'\\doteqdot':u'≑', u'\\dotplus':u'∔', u'\\dots':u'…', u'\\doublebarwedge':u'⌆', u'\\downarrow':u'↓', u'\\downdownarrows':u'⇊', u'\\downharpoonleft':u'⇃', u'\\downharpoonright':u'⇂', u'\\dsub':u'⩤', u'\\earth':u'♁', u'\\eighthnote':u'♪', u'\\ell':u'ℓ', u'\\emptyset':u'∅', u'\\eqcirc':u'≖', u'\\eqcolon':u'≕', u'\\eqsim':u'≂', u'\\euro':u'€', u'\\exists':u'∃', u'\\exp':u'exp', u'\\fallingdotseq':u'≒', u'\\fcmp':u'⨾', u'\\female':u'♀', u'\\flat':u'♭', u'\\forall':u'∀', u'\\fourth':u'⁗', u'\\frown':u'⌢', u'\\frownie':u'☹', u'\\gcd':u'gcd', u'\\gemini':u'♊', u'\\geq)':u'≥', u'\\geqq':u'≧', u'\\geqslant':u'≥', u'\\gets':u'←', u'\\gg':u'≫', u'\\ggg':u'⋙', u'\\gimel':u'ℷ', u'\\gneqq':u'≩', u'\\gnsim':u'⋧', u'\\gtrdot':u'⋗', u'\\gtreqless':u'⋚', u'\\gtreqqless':u'⪌', u'\\gtrless':u'≷', u'\\gtrsim':u'≳', u'\\guillemotleft':u'«', u'\\guillemotright':u'»', u'\\hbar':u'ℏ', u'\\heartsuit':u'♥', u'\\hfill':u' ', u'\\hom':u'hom', u'\\hookleftarrow':u'↩', u'\\hookrightarrow':u'↪', u'\\hslash':u'ℏ', u'\\idotsint':u'∫⋯∫', u'\\iiint':u'', u'\\iint':u'', u'\\imath':u'ı', u'\\inf':u'inf', u'\\infty':u'∞', u'\\intercal':u'⊺', u'\\interleave':u'⫴', u'\\invamp':u'⅋', u'\\invneg':u'⌐', u'\\jmath':u'ȷ', u'\\jupiter':u'♃', u'\\ker':u'ker', u'\\land':u'∧', u'\\landupint':u'', u'\\lang':u'⟪', u'\\langle':u'⟨', u'\\lblot':u'⦉', u'\\lbrace':u'{', u'\\lbrace)':u'{', u'\\lbrack':u'[', u'\\lceil':u'⌈', u'\\ldots':u'…', u'\\leadsto':u'⇝', u'\\leftarrow)':u'←', u'\\leftarrowtail':u'↢', u'\\leftarrowtobar':u'⇤', u'\\leftharpoondown':u'↽', u'\\leftharpoonup':u'↼', u'\\leftleftarrows':u'⇇', u'\\leftleftharpoons':u'⥢', u'\\leftmoon':u'☾', u'\\leftrightarrow':u'↔', u'\\leftrightarrows':u'⇆', u'\\leftrightharpoons':u'⇋', u'\\leftthreetimes':u'⋋', u'\\leo':u'♌', u'\\leq)':u'≤', u'\\leqq':u'≦', u'\\leqslant':u'≤', u'\\lessdot':u'⋖', u'\\lesseqgtr':u'⋛', u'\\lesseqqgtr':u'⪋', u'\\lessgtr':u'≶', u'\\lesssim':u'≲', u'\\lfloor':u'⌊', u'\\lg':u'lg', u'\\lgroup':u'⟮', u'\\lhd':u'⊲', u'\\libra':u'♎', u'\\lightning':u'↯', u'\\limg':u'⦇', u'\\liminf':u'liminf', u'\\limsup':u'limsup', u'\\ll':u'≪', u'\\llbracket':u'⟦', u'\\llcorner':u'⌞', u'\\lll':u'⋘', u'\\ln':u'ln', u'\\lneqq':u'≨', u'\\lnot':u'¬', u'\\lnsim':u'⋦', u'\\log':u'log', u'\\longleftarrow':u'⟵', u'\\longleftrightarrow':u'⟷', u'\\longmapsto':u'⟼', u'\\longrightarrow':u'⟶', u'\\looparrowleft':u'↫', u'\\looparrowright':u'↬', u'\\lor':u'∨', u'\\lozenge':u'◊', u'\\lrcorner':u'⌟', u'\\ltimes':u'⋉', u'\\lyxlock':u'', u'\\male':u'♂', u'\\maltese':u'✠', u'\\mapsfrom':u'↤', u'\\mapsto':u'↦', u'\\mathcircumflex':u'^', u'\\max':u'max', u'\\measuredangle':u'∡', u'\\medbullet':u'⚫', u'\\medcirc':u'⚪', u'\\mercury':u'☿', u'\\mho':u'℧', u'\\mid':u'∣', u'\\min':u'min', u'\\models':u'⊨', u'\\mp':u'∓', u'\\multimap':u'⊸', u'\\nLeftarrow':u'⇍', u'\\nLeftrightarrow':u'⇎', u'\\nRightarrow':u'⇏', u'\\nVDash':u'⊯', u'\\nabla':u'∇', u'\\napprox':u'≉', u'\\natural':u'♮', u'\\ncong':u'≇', u'\\nearrow':u'↗', u'\\neg':u'¬', u'\\neg)':u'¬', u'\\neptune':u'♆', u'\\nequiv':u'≢', u'\\newline':u'
', u'\\nexists':u'∄', u'\\ngeqslant':u'≱', u'\\ngtr':u'≯', u'\\ngtrless':u'≹', u'\\ni':u'∋', u'\\ni)':u'∋', u'\\nleftarrow':u'↚', u'\\nleftrightarrow':u'↮', u'\\nleqslant':u'≰', u'\\nless':u'≮', u'\\nlessgtr':u'≸', u'\\nmid':u'∤', u'\\nolimits':u'', u'\\nonumber':u'', u'\\not':u'¬', u'\\not<':u'≮', u'\\not=':u'≠', u'\\not>':u'≯', u'\\notbackslash':u'⍀', u'\\notin':u'∉', u'\\notni':u'∌', u'\\notslash':u'⌿', u'\\nparallel':u'∦', u'\\nprec':u'⊀', u'\\nrightarrow':u'↛', u'\\nsim':u'≁', u'\\nsimeq':u'≄', u'\\nsqsubset':u'⊏̸', u'\\nsubseteq':u'⊈', u'\\nsucc':u'⊁', u'\\nsucccurlyeq':u'⋡', u'\\nsupset':u'⊅', u'\\nsupseteq':u'⊉', u'\\ntriangleleft':u'⋪', u'\\ntrianglelefteq':u'⋬', u'\\ntriangleright':u'⋫', u'\\ntrianglerighteq':u'⋭', u'\\nvDash':u'⊭', u'\\nvdash':u'⊬', u'\\nwarrow':u'↖', u'\\odot':u'⊙', u'\\officialeuro':u'€', u'\\oiiint':u'', u'\\oiint':u'', u'\\oint':u'', u'\\ointclockwise':u'', u'\\ointctrclockwise':u'', u'\\ominus':u'⊖', u'\\oplus':u'⊕', u'\\oslash':u'⊘', u'\\otimes':u'⊗', u'\\owns':u'∋', u'\\parallel':u'∥', u'\\partial':u'∂', u'\\pencil':u'✎', u'\\perp':u'⊥', u'\\pisces':u'♓', u'\\pitchfork':u'⋔', u'\\pluto':u'♇', u'\\pm':u'±', u'\\pointer':u'➪', u'\\pointright':u'☞', u'\\pounds':u'£', u'\\prec':u'≺', u'\\preccurlyeq':u'≼', u'\\preceq':u'≼', u'\\precsim':u'≾', u'\\prime':u'′', u'\\prompto':u'∝', u'\\qoppa':u'ϙ', u'\\qquad':u' ', u'\\quad':u' ', u'\\quarternote':u'♩', u'\\radiation':u'☢', u'\\rang':u'⟫', u'\\rangle':u'⟩', u'\\rblot':u'⦊', u'\\rbrace':u'}', u'\\rbrace)':u'}', u'\\rbrack':u']', u'\\rceil':u'⌉', u'\\recycle':u'♻', u'\\rfloor':u'⌋', u'\\rgroup':u'⟯', u'\\rhd':u'⊳', u'\\rightangle':u'∟', u'\\rightarrow)':u'→', u'\\rightarrowtail':u'↣', u'\\rightarrowtobar':u'⇥', u'\\rightharpoondown':u'⇁', u'\\rightharpoonup':u'⇀', u'\\rightharpooondown':u'⇁', u'\\rightharpooonup':u'⇀', u'\\rightleftarrows':u'⇄', u'\\rightleftharpoons':u'⇌', u'\\rightmoon':u'☽', u'\\rightrightarrows':u'⇉', u'\\rightrightharpoons':u'⥤', u'\\rightthreetimes':u'⋌', u'\\rimg':u'⦈', u'\\risingdotseq':u'≓', u'\\rrbracket':u'⟧', u'\\rsub':u'⩥', u'\\rtimes':u'⋊', u'\\sagittarius':u'♐', u'\\saturn':u'♄', u'\\scorpio':u'♏', u'\\searrow':u'↘', u'\\sec':u'sec', u'\\second':u'″', u'\\setminus':u'∖', u'\\sharp':u'♯', u'\\simeq':u'≃', u'\\sin':u'sin', u'\\sinh':u'sinh', u'\\sixteenthnote':u'♬', u'\\skull':u'☠', u'\\slash':u'∕', u'\\smallsetminus':u'∖', u'\\smalltriangledown':u'▿', u'\\smalltriangleleft':u'◃', u'\\smalltriangleright':u'▹', u'\\smalltriangleup':u'▵', u'\\smile':u'⌣', u'\\smiley':u'☺', u'\\spadesuit':u'♠', u'\\spddot':u'¨', u'\\sphat':u'', u'\\sphericalangle':u'∢', u'\\spot':u'⦁', u'\\sptilde':u'~', u'\\sqcap':u'⊓', u'\\sqcup':u'⊔', u'\\sqsubset':u'⊏', u'\\sqsubseteq':u'⊑', u'\\sqsupset':u'⊐', u'\\sqsupseteq':u'⊒', u'\\square':u'□', u'\\sslash':u'⫽', u'\\star':u'⋆', u'\\steaming':u'☕', u'\\subseteqq':u'⫅', u'\\subsetneqq':u'⫋', u'\\succ':u'≻', u'\\succcurlyeq':u'≽', u'\\succeq':u'≽', u'\\succnsim':u'⋩', u'\\succsim':u'≿', u'\\sun':u'☼', u'\\sup':u'sup', u'\\supseteqq':u'⫆', u'\\supsetneqq':u'⫌', u'\\surd':u'√', u'\\swarrow':u'↙', u'\\swords':u'⚔', u'\\talloblong':u'⫾', u'\\tan':u'tan', u'\\tanh':u'tanh', u'\\taurus':u'♉', u'\\textasciicircum':u'^', u'\\textasciitilde':u'~', u'\\textbackslash':u'\\', u'\\textcopyright':u'©\'', u'\\textdegree':u'°', u'\\textellipsis':u'…', u'\\textemdash':u'—', u'\\textendash':u'—', u'\\texteuro':u'€', u'\\textgreater':u'>', u'\\textless':u'<', u'\\textordfeminine':u'ª', u'\\textordmasculine':u'º', u'\\textquotedblleft':u'“', u'\\textquotedblright':u'”', u'\\textquoteright':u'’', u'\\textregistered':u'®', u'\\textrightarrow':u'→', u'\\textsection':u'§', u'\\texttrademark':u'™', u'\\texttwosuperior':u'²', u'\\textvisiblespace':u' ', u'\\therefore':u'∴', u'\\third':u'‴', u'\\top':u'⊤', u'\\triangle':u'△', u'\\triangleleft':u'⊲', u'\\trianglelefteq':u'⊴', u'\\triangleq':u'≜', u'\\triangleright':u'▷', u'\\trianglerighteq':u'⊵', u'\\twoheadleftarrow':u'↞', u'\\twoheadrightarrow':u'↠', u'\\twonotes':u'♫', u'\\udot':u'⊍', u'\\ulcorner':u'⌜', u'\\unlhd':u'⊴', u'\\unrhd':u'⊵', u'\\unrhl':u'⊵', u'\\uparrow':u'↑', u'\\updownarrow':u'↕', u'\\upharpoonleft':u'↿', u'\\upharpoonright':u'↾', u'\\uplus':u'⊎', u'\\upuparrows':u'⇈', u'\\uranus':u'♅', u'\\urcorner':u'⌝', u'\\vDash':u'⊨', u'\\varclubsuit':u'♧', u'\\vardiamondsuit':u'♦', u'\\varheartsuit':u'♥', u'\\varnothing':u'∅', u'\\varspadesuit':u'♤', u'\\vdash':u'⊢', u'\\vdots':u'⋮', u'\\vee':u'∨', u'\\vee)':u'∨', u'\\veebar':u'⊻', u'\\vert':u'∣', u'\\virgo':u'♍', u'\\warning':u'⚠', u'\\wasylozenge':u'⌑', u'\\wedge':u'∧', u'\\wedge)':u'∧', u'\\wp':u'℘', u'\\wr':u'≀', u'\\yen':u'¥', u'\\yinyang':u'☯', u'\\{':u'{', u'\\|':u'∥', u'\\}':u'}', } decoratedcommand = { } decoratingfunctions = { u'\\overleftarrow':u'⟵', u'\\overrightarrow':u'⟶', u'\\widehat':u'^', } endings = { u'bracket':u'}', u'complex':u'\\]', u'endafter':u'}', u'endbefore':u'\\end{', u'squarebracket':u']', } environments = { u'align':[u'r',u'l',], u'eqnarray':[u'r',u'c',u'l',], u'gathered':[u'l',u'l',], } fontfunctions = { u'\\boldsymbol':u'b', u'\\mathbb':u'span class="blackboard"', u'\\mathbb{A}':u'𝔸', u'\\mathbb{B}':u'𝔹', u'\\mathbb{C}':u'ℂ', u'\\mathbb{D}':u'𝔻', u'\\mathbb{E}':u'𝔼', u'\\mathbb{F}':u'𝔽', u'\\mathbb{G}':u'𝔾', u'\\mathbb{H}':u'ℍ', u'\\mathbb{J}':u'𝕁', u'\\mathbb{K}':u'𝕂', u'\\mathbb{L}':u'𝕃', u'\\mathbb{N}':u'ℕ', u'\\mathbb{O}':u'𝕆', u'\\mathbb{P}':u'ℙ', u'\\mathbb{Q}':u'ℚ', u'\\mathbb{R}':u'ℝ', u'\\mathbb{S}':u'𝕊', u'\\mathbb{T}':u'𝕋', u'\\mathbb{W}':u'𝕎', u'\\mathbb{Z}':u'ℤ', u'\\mathbf':u'b', u'\\mathcal':u'span class="scriptfont"', u'\\mathcal{B}':u'ℬ', u'\\mathcal{E}':u'ℰ', u'\\mathcal{F}':u'ℱ', u'\\mathcal{H}':u'ℋ', u'\\mathcal{I}':u'ℐ', u'\\mathcal{L}':u'ℒ', u'\\mathcal{M}':u'ℳ', u'\\mathcal{R}':u'ℛ', u'\\mathfrak':u'span class="fraktur"', u'\\mathfrak{C}':u'ℭ', u'\\mathfrak{F}':u'𝔉', u'\\mathfrak{H}':u'ℌ', u'\\mathfrak{I}':u'ℑ', u'\\mathfrak{R}':u'ℜ', u'\\mathfrak{Z}':u'ℨ', u'\\mathit':u'i', u'\\mathring{A}':u'Å', u'\\mathring{U}':u'Ů', u'\\mathring{a}':u'å', u'\\mathring{u}':u'ů', u'\\mathring{w}':u'ẘ', u'\\mathring{y}':u'ẙ', u'\\mathrm':u'span class="mathrm"', u'\\mathscr':u'span class="scriptfont"', u'\\mathscr{B}':u'ℬ', u'\\mathscr{E}':u'ℰ', u'\\mathscr{F}':u'ℱ', u'\\mathscr{H}':u'ℋ', u'\\mathscr{I}':u'ℐ', u'\\mathscr{L}':u'ℒ', u'\\mathscr{M}':u'ℳ', u'\\mathscr{R}':u'ℛ', u'\\mathsf':u'span class="mathsf"', u'\\mathtt':u'tt', } hybridfunctions = { u'\\addcontentsline':[u'{$p!}{$q!}{$r!}',u'f0{}',u'ignored',], u'\\addtocontents':[u'{$p!}{$q!}',u'f0{}',u'ignored',], u'\\backmatter':[u'',u'f0{}',u'ignored',], u'\\binom':[u'{$1}{$2}',u'f2{(}f0{f1{$1}f1{$2}}f2{)}',u'span class="binom"',u'span class="binomstack"',u'span class="bigsymbol"',], u'\\boxed':[u'{$1}',u'f0{$1}',u'span class="boxed"',], u'\\cfrac':[u'[$p!]{$1}{$2}',u'f0{f3{(}f1{$1}f3{)/(}f2{$2}f3{)}}',u'span class="fullfraction"',u'span class="numerator align-$p"',u'span class="denominator"',u'span class="ignored"',], u'\\color':[u'{$p!}{$1}',u'f0{$1}',u'span style="color: $p;"',], u'\\colorbox':[u'{$p!}{$1}',u'f0{$1}',u'span class="colorbox" style="background: $p;"',], u'\\dbinom':[u'{$1}{$2}',u'(f0{f1{f2{$1}}f1{f2{ }}f1{f2{$2}}})',u'span class="binomial"',u'span class="binomrow"',u'span class="binomcell"',], u'\\dfrac':[u'{$1}{$2}',u'f0{f3{(}f1{$1}f3{)/(}f2{$2}f3{)}}',u'span class="fullfraction"',u'span class="numerator"',u'span class="denominator"',u'span class="ignored"',], u'\\displaystyle':[u'{$1}',u'f0{$1}',u'span class="displaystyle"',], u'\\fancyfoot':[u'[$p!]{$q!}',u'f0{}',u'ignored',], u'\\fancyhead':[u'[$p!]{$q!}',u'f0{}',u'ignored',], u'\\fbox':[u'{$1}',u'f0{$1}',u'span class="fbox"',], u'\\fboxrule':[u'{$p!}',u'f0{}',u'ignored',], u'\\fboxsep':[u'{$p!}',u'f0{}',u'ignored',], u'\\fcolorbox':[u'{$p!}{$q!}{$1}',u'f0{$1}',u'span class="boxed" style="border-color: $p; background: $q;"',], u'\\frac':[u'{$1}{$2}',u'f0{f3{(}f1{$1}f3{)/(}f2{$2}f3{)}}',u'span class="fraction"',u'span class="numerator"',u'span class="denominator"',u'span class="ignored"',], u'\\framebox':[u'[$p!][$q!]{$1}',u'f0{$1}',u'span class="framebox align-$q" style="width: $p;"',], u'\\frontmatter':[u'',u'f0{}',u'ignored',], u'\\href':[u'[$o]{$u!}{$t!}',u'f0{$t}',u'a href="$u"',], u'\\hspace':[u'{$p!}',u'f0{ }',u'span class="hspace" style="width: $p;"',], u'\\leftroot':[u'{$p!}',u'f0{ }',u'span class="leftroot" style="width: $p;px"',], u'\\mainmatter':[u'',u'f0{}',u'ignored',], u'\\markboth':[u'{$p!}{$q!}',u'f0{}',u'ignored',], u'\\markright':[u'{$p!}',u'f0{}',u'ignored',], u'\\nicefrac':[u'{$1}{$2}',u'f0{f1{$1}⁄f2{$2}}',u'span class="fraction"',u'sup class="numerator"',u'sub class="denominator"',u'span class="ignored"',], u'\\parbox':[u'[$p!]{$w!}{$1}',u'f0{1}',u'div class="Boxed" style="width: $w;"',], u'\\raisebox':[u'{$p!}{$1}',u'f0{$1.font}',u'span class="raisebox" style="vertical-align: $p;"',], u'\\renewenvironment':[u'{$1!}{$2!}{$3!}',u'',], u'\\rule':[u'[$v!]{$w!}{$h!}',u'f0/',u'hr class="line" style="width: $w; height: $h;"',], u'\\scriptscriptstyle':[u'{$1}',u'f0{$1}',u'span class="scriptscriptstyle"',], u'\\scriptstyle':[u'{$1}',u'f0{$1}',u'span class="scriptstyle"',], u'\\sqrt':[u'[$0]{$1}',u'f0{f1{$0}f2{√}f4{(}f3{$1}f4{)}}',u'span class="sqrt"',u'sup class="root"',u'span class="radical"',u'span class="root"',u'span class="ignored"',], u'\\stackrel':[u'{$1}{$2}',u'f0{f1{$1}f2{$2}}',u'span class="stackrel"',u'span class="upstackrel"',u'span class="downstackrel"',], u'\\tbinom':[u'{$1}{$2}',u'(f0{f1{f2{$1}}f1{f2{ }}f1{f2{$2}}})',u'span class="binomial"',u'span class="binomrow"',u'span class="binomcell"',], u'\\textcolor':[u'{$p!}{$1}',u'f0{$1}',u'span style="color: $p;"',], u'\\textstyle':[u'{$1}',u'f0{$1}',u'span class="textstyle"',], u'\\thispagestyle':[u'{$p!}',u'f0{}',u'ignored',], u'\\unit':[u'[$0]{$1}',u'$0f0{$1.font}',u'span class="unit"',], u'\\unitfrac':[u'[$0]{$1}{$2}',u'$0f0{f1{$1.font}⁄f2{$2.font}}',u'span class="fraction"',u'sup class="unit"',u'sub class="unit"',], u'\\uproot':[u'{$p!}',u'f0{ }',u'span class="uproot" style="width: $p;px"',], u'\\url':[u'{$u!}',u'f0{$u}',u'a href="$u"',], u'\\vspace':[u'{$p!}',u'f0{ }',u'span class="vspace" style="height: $p;"',], } hybridsizes = { u'\\binom':u'$1+$2', u'\\cfrac':u'$1+$2', u'\\dbinom':u'$1+$2+1', u'\\dfrac':u'$1+$2', u'\\frac':u'$1+$2', u'\\tbinom':u'$1+$2+1', } labelfunctions = { u'\\label':u'a name="#"', } limitcommands = { u'\\biginterleave':u'⫼', u'\\bigsqcap':u'⨅', u'\\fint':u'⨏', u'\\iiiint':u'⨌', u'\\int':u'∫', u'\\intop':u'∫', u'\\lim':u'lim', u'\\prod':u'∏', u'\\smallint':u'∫', u'\\sqint':u'⨖', u'\\sum':u'∑', u'\\varointclockwise':u'∲', u'\\varprod':u'⨉', u'\\zcmp':u'⨟', u'\\zhide':u'⧹', u'\\zpipe':u'⨠', u'\\zproject':u'⨡', } misccommands = { u'\\limits':u'LimitPreviousCommand', u'\\newcommand':u'MacroDefinition', u'\\renewcommand':u'MacroDefinition', u'\\setcounter':u'SetCounterFunction', u'\\tag':u'FormulaTag', u'\\tag*':u'FormulaTag', u'\\today':u'TodayCommand', } modified = { u'\n':u'', u' ':u'', u'$':u'', u'&':u' ', u'\'':u'’', u'+':u' + ', u',':u', ', u'-':u' − ', u'/':u' ⁄ ', u'<':u' < ', u'=':u' = ', u'>':u' > ', u'@':u'', u'~':u'', } onefunctions = { u'\\Big':u'span class="bigsymbol"', u'\\Bigg':u'span class="hugesymbol"', u'\\bar':u'span class="bar"', u'\\begin{array}':u'span class="arraydef"', u'\\big':u'span class="symbol"', u'\\bigg':u'span class="largesymbol"', u'\\bigl':u'span class="bigsymbol"', u'\\bigr':u'span class="bigsymbol"', u'\\centering':u'span class="align-center"', u'\\ensuremath':u'span class="ensuremath"', u'\\hphantom':u'span class="phantom"', u'\\noindent':u'span class="noindent"', u'\\overbrace':u'span class="overbrace"', u'\\overline':u'span class="overline"', u'\\phantom':u'span class="phantom"', u'\\underbrace':u'span class="underbrace"', u'\\underline':u'u', u'\\vphantom':u'span class="phantom"', } spacedcommands = { u'\\Bot':u'⫫', u'\\Doteq':u'≑', u'\\DownArrowBar':u'⤓', u'\\DownLeftTeeVector':u'⥞', u'\\DownLeftVectorBar':u'⥖', u'\\DownRightTeeVector':u'⥟', u'\\DownRightVectorBar':u'⥗', u'\\Equal':u'⩵', u'\\LeftArrowBar':u'⇤', u'\\LeftDownTeeVector':u'⥡', u'\\LeftDownVectorBar':u'⥙', u'\\LeftTeeVector':u'⥚', u'\\LeftTriangleBar':u'⧏', u'\\LeftUpTeeVector':u'⥠', u'\\LeftUpVectorBar':u'⥘', u'\\LeftVectorBar':u'⥒', u'\\Leftrightarrow':u'⇔', u'\\Longmapsfrom':u'⟽', u'\\Longmapsto':u'⟾', u'\\MapsDown':u'↧', u'\\MapsUp':u'↥', u'\\Nearrow':u'⇗', u'\\NestedGreaterGreater':u'⪢', u'\\NestedLessLess':u'⪡', u'\\NotGreaterLess':u'≹', u'\\NotGreaterTilde':u'≵', u'\\NotLessTilde':u'≴', u'\\Nwarrow':u'⇖', u'\\Proportion':u'∷', u'\\RightArrowBar':u'⇥', u'\\RightDownTeeVector':u'⥝', u'\\RightDownVectorBar':u'⥕', u'\\RightTeeVector':u'⥛', u'\\RightTriangleBar':u'⧐', u'\\RightUpTeeVector':u'⥜', u'\\RightUpVectorBar':u'⥔', u'\\RightVectorBar':u'⥓', u'\\Rightarrow':u'⇒', u'\\Same':u'⩶', u'\\Searrow':u'⇘', u'\\Swarrow':u'⇙', u'\\Top':u'⫪', u'\\UpArrowBar':u'⤒', u'\\VDash':u'⊫', u'\\approx':u'≈', u'\\approxeq':u'≊', u'\\backsim':u'∽', u'\\barin':u'⋶', u'\\barleftharpoon':u'⥫', u'\\barrightharpoon':u'⥭', u'\\bij':u'⤖', u'\\coloneq':u'≔', u'\\corresponds':u'≙', u'\\curlyeqprec':u'⋞', u'\\curlyeqsucc':u'⋟', u'\\dashrightarrow':u'⇢', u'\\dlsh':u'↲', u'\\downdownharpoons':u'⥥', u'\\downuparrows':u'⇵', u'\\downupharpoons':u'⥯', u'\\drsh':u'↳', u'\\eqslantgtr':u'⪖', u'\\eqslantless':u'⪕', u'\\equiv':u'≡', u'\\ffun':u'⇻', u'\\finj':u'⤕', u'\\ge':u'≥', u'\\geq':u'≥', u'\\ggcurly':u'⪼', u'\\gnapprox':u'⪊', u'\\gneq':u'⪈', u'\\gtrapprox':u'⪆', u'\\hash':u'⋕', u'\\iddots':u'⋰', u'\\implies':u' ⇒ ', u'\\in':u'∈', u'\\le':u'≤', u'\\leftarrow':u'←', u'\\leftarrowtriangle':u'⇽', u'\\leftbarharpoon':u'⥪', u'\\leftrightarrowtriangle':u'⇿', u'\\leftrightharpoon':u'⥊', u'\\leftrightharpoondown':u'⥐', u'\\leftrightharpoonup':u'⥎', u'\\leftrightsquigarrow':u'↭', u'\\leftslice':u'⪦', u'\\leftsquigarrow':u'⇜', u'\\leftupdownharpoon':u'⥑', u'\\leq':u'≤', u'\\lessapprox':u'⪅', u'\\llcurly':u'⪻', u'\\lnapprox':u'⪉', u'\\lneq':u'⪇', u'\\longmapsfrom':u'⟻', u'\\multimapboth':u'⧟', u'\\multimapdotbothA':u'⊶', u'\\multimapdotbothB':u'⊷', u'\\multimapinv':u'⟜', u'\\nVdash':u'⊮', u'\\ne':u'≠', u'\\neq':u'≠', u'\\ngeq':u'≱', u'\\nleq':u'≰', u'\\nni':u'∌', u'\\not\\in':u'∉', u'\\notasymp':u'≭', u'\\npreceq':u'⋠', u'\\nsqsubseteq':u'⋢', u'\\nsqsupseteq':u'⋣', u'\\nsubset':u'⊄', u'\\nsucceq':u'⋡', u'\\pfun':u'⇸', u'\\pinj':u'⤔', u'\\precapprox':u'⪷', u'\\preceqq':u'⪳', u'\\precnapprox':u'⪹', u'\\precnsim':u'⋨', u'\\propto':u'∝', u'\\psur':u'⤀', u'\\rightarrow':u'→', u'\\rightarrowtriangle':u'⇾', u'\\rightbarharpoon':u'⥬', u'\\rightleftharpoon':u'⥋', u'\\rightslice':u'⪧', u'\\rightsquigarrow':u'⇝', u'\\rightupdownharpoon':u'⥏', u'\\sim':u'~', u'\\strictfi':u'⥼', u'\\strictif':u'⥽', u'\\subset':u'⊂', u'\\subseteq':u'⊆', u'\\subsetneq':u'⊊', u'\\succapprox':u'⪸', u'\\succeqq':u'⪴', u'\\succnapprox':u'⪺', u'\\supset':u'⊃', u'\\supseteq':u'⊇', u'\\supsetneq':u'⊋', u'\\times':u'×', u'\\to':u'→', u'\\updownarrows':u'⇅', u'\\updownharpoons':u'⥮', u'\\upupharpoons':u'⥣', u'\\vartriangleleft':u'⊲', u'\\vartriangleright':u'⊳', } starts = { u'beginafter':u'}', u'beginbefore':u'\\begin{', u'bracket':u'{', u'command':u'\\', u'comment':u'%', u'complex':u'\\[', u'simple':u'$', u'squarebracket':u'[', u'unnumbered':u'*', } symbolfunctions = { u'^':u'sup', u'_':u'sub', } textfunctions = { u'\\mbox':u'span class="mbox"', u'\\text':u'span class="text"', u'\\textbf':u'b', u'\\textipa':u'span class="textipa"', u'\\textit':u'i', u'\\textnormal':u'span class="textnormal"', u'\\textrm':u'span class="textrm"', u'\\textsc':u'span class="versalitas"', u'\\textsf':u'span class="textsf"', u'\\textsl':u'i', u'\\texttt':u'tt', u'\\textup':u'span class="normal"', } unmodified = { u'characters':[u'.',u'*',u'€',u'(',u')',u'[',u']',u':',u'·',u'!',u';',u'|',u'§',u'"',], } urls = { u'googlecharts':u'http://chart.googleapis.com/chart?cht=tx&chl=', } class GeneralConfig(object): "Configuration class from elyxer.config file" version = { u'date':u'2013-03-10', u'lyxformat':u'413', u'number':u'1.2.4', } class HeaderConfig(object): "Configuration class from elyxer.config file" parameters = { u'beginpreamble':u'\\begin_preamble', u'branch':u'\\branch', u'documentclass':u'\\textclass', u'endbranch':u'\\end_branch', u'endpreamble':u'\\end_preamble', u'language':u'\\language', u'lstset':u'\\lstset', u'outputchanges':u'\\output_changes', u'paragraphseparation':u'\\paragraph_separation', u'pdftitle':u'\\pdf_title', u'secnumdepth':u'\\secnumdepth', u'tocdepth':u'\\tocdepth', } styles = { u'article':[u'article',u'aastex',u'aapaper',u'acmsiggraph',u'sigplanconf',u'achemso',u'amsart',u'apa',u'arab-article',u'armenian-article',u'article-beamer',u'chess',u'dtk',u'elsarticle',u'heb-article',u'IEEEtran',u'iopart',u'kluwer',u'scrarticle-beamer',u'scrartcl',u'extarticle',u'paper',u'mwart',u'revtex4',u'spie',u'svglobal3',u'ltugboat',u'agu-dtd',u'jgrga',u'agums',u'entcs',u'egs',u'ijmpc',u'ijmpd',u'singlecol-new',u'doublecol-new',u'isprs',u'tarticle',u'jsarticle',u'jarticle',u'jss',u'literate-article',u'siamltex',u'cl2emult',u'llncs',u'svglobal',u'svjog',u'svprobth',], u'book':[u'book',u'amsbook',u'scrbook',u'extbook',u'tufte-book',u'report',u'extreport',u'scrreprt',u'memoir',u'tbook',u'jsbook',u'jbook',u'mwbk',u'svmono',u'svmult',u'treport',u'jreport',u'mwrep',], } class ImageConfig(object): "Configuration class from elyxer.config file" converters = { u'imagemagick':u'convert[ -density $scale][ -define $format:use-cropbox=true] "$input" "$output"', u'inkscape':u'inkscape "$input" --export-png="$output"', u'lyx':u'lyx -C "$input" "$output"', } cropboxformats = { u'.eps':u'ps', u'.pdf':u'pdf', u'.ps':u'ps', } formats = { u'default':u'.png', u'vector':[u'.svg',u'.eps',], } class LayoutConfig(object): "Configuration class from elyxer.config file" groupable = { u'allowed':[u'StringContainer',u'Constant',u'TaggedText',u'Align',u'TextFamily',u'EmphaticText',u'VersalitasText',u'BarredText',u'SizeText',u'ColorText',u'LangLine',u'Formula',], } class NewfangleConfig(object): "Configuration class from elyxer.config file" constants = { u'chunkref':u'chunkref{', u'endcommand':u'}', u'endmark':u'>', u'startcommand':u'\\', u'startmark':u'=<', } class NumberingConfig(object): "Configuration class from elyxer.config file" layouts = { u'ordered':[u'Chapter',u'Section',u'Subsection',u'Subsubsection',u'Paragraph',], u'roman':[u'Part',u'Book',], } sequence = { u'symbols':[u'*',u'**',u'†',u'‡',u'§',u'§§',u'¶',u'¶¶',u'#',u'##',], } class StyleConfig(object): "Configuration class from elyxer.config file" hspaces = { u'\\enskip{}':u' ', u'\\hfill{}':u' ', u'\\hspace*{\\fill}':u' ', u'\\hspace*{}':u'', u'\\hspace{}':u' ', u'\\negthinspace{}':u'', u'\\qquad{}':u'  ', u'\\quad{}':u' ', u'\\space{}':u' ', u'\\thinspace{}':u' ', u'~':u' ', } quotes = { u'ald':u'»', u'als':u'›', u'ard':u'«', u'ars':u'‹', u'eld':u'“', u'els':u'‘', u'erd':u'”', u'ers':u'’', u'fld':u'«', u'fls':u'‹', u'frd':u'»', u'frs':u'›', u'gld':u'„', u'gls':u'‚', u'grd':u'“', u'grs':u'‘', u'pld':u'„', u'pls':u'‚', u'prd':u'”', u'prs':u'’', u'sld':u'”', u'srd':u'”', } referenceformats = { u'eqref':u'(@↕)', u'formatted':u'¶↕', u'nameref':u'$↕', u'pageref':u'#↕', u'ref':u'@↕', u'vpageref':u'on-page#↕', u'vref':u'@on-page#↕', } size = { u'ignoredtexts':[u'col',u'text',u'line',u'page',u'theight',u'pheight',], } vspaces = { u'bigskip':u'
', u'defskip':u'
', u'medskip':u'
', u'smallskip':u'
', u'vfill':u'
', } class TOCConfig(object): "Configuration class from elyxer.config file" extractplain = { u'allowed':[u'StringContainer',u'Constant',u'TaggedText',u'Align',u'TextFamily',u'EmphaticText',u'VersalitasText',u'BarredText',u'SizeText',u'ColorText',u'LangLine',u'Formula',], u'cloned':[u'',], u'extracted':[u'',], } extracttitle = { u'allowed':[u'StringContainer',u'Constant',u'Space',], u'cloned':[u'TextFamily',u'EmphaticText',u'VersalitasText',u'BarredText',u'SizeText',u'ColorText',u'LangLine',u'Formula',], u'extracted':[u'PlainLayout',u'TaggedText',u'Align',u'Caption',u'StandardLayout',u'FlexInset',], } class TagConfig(object): "Configuration class from elyxer.config file" barred = { u'under':u'u', } family = { u'sans':u'span class="sans"', u'typewriter':u'tt', } flex = { u'CharStyle:Code':u'span class="code"', u'CharStyle:MenuItem':u'span class="menuitem"', u'Code':u'span class="code"', u'MenuItem':u'span class="menuitem"', u'Noun':u'span class="noun"', u'Strong':u'span class="strong"', } group = { u'layouts':[u'Quotation',u'Quote',], } layouts = { u'Center':u'div', u'Chapter':u'h?', u'Date':u'h2', u'Paragraph':u'div', u'Part':u'h1', u'Quotation':u'blockquote', u'Quote':u'blockquote', u'Section':u'h?', u'Subsection':u'h?', u'Subsubsection':u'h?', } listitems = { u'Enumerate':u'ol', u'Itemize':u'ul', } notes = { u'Comment':u'', u'Greyedout':u'span class="greyedout"', u'Note':u'', } script = { u'subscript':u'sub', u'superscript':u'sup', } shaped = { u'italic':u'i', u'slanted':u'i', u'smallcaps':u'span class="versalitas"', } class TranslationConfig(object): "Configuration class from elyxer.config file" constants = { u'Appendix':u'Appendix', u'Book':u'Book', u'Chapter':u'Chapter', u'Paragraph':u'Paragraph', u'Part':u'Part', u'Section':u'Section', u'Subsection':u'Subsection', u'Subsubsection':u'Subsubsection', u'abstract':u'Abstract', u'bibliography':u'Bibliography', u'figure':u'figure', u'float-algorithm':u'Algorithm ', u'float-figure':u'Figure ', u'float-listing':u'Listing ', u'float-table':u'Table ', u'float-tableau':u'Tableau ', u'footnotes':u'Footnotes', u'generated-by':u'Document generated by ', u'generated-on':u' on ', u'index':u'Index', u'jsmath-enable':u'Please enable JavaScript on your browser.', u'jsmath-requires':u' requires JavaScript to correctly process the mathematics on this page. ', u'jsmath-warning':u'Warning: ', u'list-algorithm':u'List of Algorithms', u'list-figure':u'List of Figures', u'list-table':u'List of Tables', u'list-tableau':u'List of Tableaux', u'main-page':u'Main page', u'next':u'Next', u'nomenclature':u'Nomenclature', u'on-page':u' on page ', u'prev':u'Prev', u'references':u'References', u'toc':u'Table of Contents', u'toc-for':u'Contents for ', u'up':u'Up', } languages = { u'american':u'en', u'british':u'en', u'deutsch':u'de', u'dutch':u'nl', u'english':u'en', u'french':u'fr', u'ngerman':u'de', u'russian':u'ru', u'spanish':u'es', } class CommandLineParser(object): "A parser for runtime options" def __init__(self, options): self.options = options def parseoptions(self, args): "Parse command line options" if len(args) == 0: return None while len(args) > 0 and args[0].startswith('--'): key, value = self.readoption(args) if not key: return 'Option ' + value + ' not recognized' if not value: return 'Option ' + key + ' needs a value' setattr(self.options, key, value) return None def readoption(self, args): "Read the key and value for an option" arg = args[0][2:] del args[0] if '=' in arg: key = self.readequalskey(arg, args) else: key = arg.replace('-', '') if not hasattr(self.options, key): return None, key current = getattr(self.options, key) if isinstance(current, bool): return key, True # read value if len(args) == 0: return key, None if args[0].startswith('"'): initial = args[0] del args[0] return key, self.readquoted(args, initial) value = args[0].decode('utf-8') del args[0] if isinstance(current, list): current.append(value) return key, current return key, value def readquoted(self, args, initial): "Read a value between quotes" Trace.error('Oops') value = initial[1:] while len(args) > 0 and not args[0].endswith('"') and not args[0].startswith('--'): Trace.error('Appending ' + args[0]) value += ' ' + args[0] del args[0] if len(args) == 0 or args[0].startswith('--'): return None value += ' ' + args[0:-1] return value def readequalskey(self, arg, args): "Read a key using equals" split = arg.split('=', 1) key = split[0] value = split[1] args.insert(0, value) return key class Options(object): "A set of runtime options" instance = None location = None nocopy = False copyright = False debug = False quiet = False version = False hardversion = False versiondate = False html = False help = False showlines = True unicode = False iso885915 = False css = [] title = None directory = None destdirectory = None toc = False toctarget = '' tocfor = None forceformat = None lyxformat = False target = None splitpart = None memory = True lowmem = False nobib = False converter = 'imagemagick' raw = False jsmath = None mathjax = None nofooter = False simplemath = False template = None noconvert = False notoclabels = False letterfoot = True numberfoot = False symbolfoot = False hoverfoot = True marginfoot = False endfoot = False supfoot = True alignfoot = False footnotes = None imageformat = None copyimages = False googlecharts = False embedcss = [] branches = dict() def parseoptions(self, args): "Parse command line options" Options.location = args[0] del args[0] parser = CommandLineParser(Options) result = parser.parseoptions(args) if result: Trace.error(result) self.usage() self.processoptions() def processoptions(self): "Process all options parsed." if Options.help: self.usage() if Options.version: self.showversion() if Options.hardversion: self.showhardversion() if Options.versiondate: self.showversiondate() if Options.lyxformat: self.showlyxformat() if Options.splitpart: try: Options.splitpart = int(Options.splitpart) if Options.splitpart <= 0: Trace.error('--splitpart requires a number bigger than zero') self.usage() except: Trace.error('--splitpart needs a numeric argument, not ' + Options.splitpart) self.usage() if Options.lowmem or Options.toc or Options.tocfor: Options.memory = False self.parsefootnotes() if Options.forceformat and not Options.imageformat: Options.imageformat = Options.forceformat if Options.imageformat == 'copy': Options.copyimages = True if Options.css == []: Options.css = ['http://elyxer.nongnu.org/lyx.css'] if Options.html: Options.simplemath = True if Options.toc and not Options.tocfor: Trace.error('Option --toc is deprecated; use --tocfor "page" instead') Options.tocfor = Options.toctarget if Options.nocopy: Trace.error('Option --nocopy is deprecated; it is no longer needed') if Options.jsmath: Trace.error('Option --jsmath is deprecated; use --mathjax instead') # set in Trace if necessary for param in dir(Trace): if param.endswith('mode'): setattr(Trace, param, getattr(self, param[:-4])) def usage(self): "Show correct usage" Trace.error('Usage: ' + os.path.basename(Options.location) + ' [options] [filein] [fileout]') Trace.error('Convert LyX input file "filein" to HTML file "fileout".') Trace.error('If filein (or fileout) is not given use standard input (or output).') Trace.error('Main program of the eLyXer package (http://elyxer.nongnu.org/).') self.showoptions() def parsefootnotes(self): "Parse footnotes options." if not Options.footnotes: return Options.marginfoot = False Options.letterfoot = False Options.hoverfoot = False options = Options.footnotes.split(',') for option in options: footoption = option + 'foot' if hasattr(Options, footoption): setattr(Options, footoption, True) else: Trace.error('Unknown footnotes option: ' + option) if not Options.endfoot and not Options.marginfoot and not Options.hoverfoot: Options.hoverfoot = True if not Options.numberfoot and not Options.symbolfoot: Options.letterfoot = True def showoptions(self): "Show all possible options" Trace.error(' Common options:') Trace.error(' --help: show this online help') Trace.error(' --quiet: disables all runtime messages') Trace.error('') Trace.error(' Advanced options:') Trace.error(' --debug: enable debugging messages (for developers)') Trace.error(' --version: show version number and release date') Trace.error(' --lyxformat: return the highest LyX version supported') Trace.error(' Options for HTML output:') Trace.error(' --title "title": set the generated page title') Trace.error(' --css "file.css": use a custom CSS file') Trace.error(' --embedcss "file.css": embed styles from a CSS file into the output') Trace.error(' --html: output HTML 4.0 instead of the default XHTML') Trace.error(' --unicode: full Unicode output') Trace.error(' --iso885915: output a document with ISO-8859-15 encoding') Trace.error(' --nofooter: remove the footer "generated by eLyXer"') Trace.error(' --simplemath: do not generate fancy math constructions') Trace.error(' Options for image output:') Trace.error(' --directory "img_dir": look for images in the specified directory') Trace.error(' --destdirectory "dest": put converted images into this directory') Trace.error(' --imageformat ".ext": image output format, or "copy" to copy images') Trace.error(' --noconvert: do not convert images, use in original locations') Trace.error(' --converter "inkscape": use an alternative program to convert images') Trace.error(' Options for footnote display:') Trace.error(' --numberfoot: mark footnotes with numbers instead of letters') Trace.error(' --symbolfoot: mark footnotes with symbols (*, **...)') Trace.error(' --hoverfoot: show footnotes as hovering text (default)') Trace.error(' --marginfoot: show footnotes on the page margin') Trace.error(' --endfoot: show footnotes at the end of the page') Trace.error(' --supfoot: use superscript for footnote markers (default)') Trace.error(' --alignfoot: use aligned text for footnote markers') Trace.error(' --footnotes "options": specify several comma-separated footnotes options') Trace.error(' Available options are: "number", "symbol", "hover", "margin", "end",') Trace.error(' "sup", "align"') Trace.error(' Advanced output options:') Trace.error(' --splitpart "depth": split the resulting webpage at the given depth') Trace.error(' --tocfor "page": generate a TOC that points to the given page') Trace.error(' --target "frame": make all links point to the given frame') Trace.error(' --notoclabels: omit the part labels in the TOC, such as Chapter') Trace.error(' --lowmem: do the conversion on the fly (conserve memory)') Trace.error(' --raw: generate HTML without header or footer.') Trace.error(' --mathjax remote: use MathJax remotely to display equations') Trace.error(' --mathjax "URL": use MathJax from the given URL to display equations') Trace.error(' --googlecharts: use Google Charts to generate formula images') Trace.error(' --template "file": use a template, put everything in ') Trace.error(' --copyright: add a copyright notice at the bottom') Trace.error(' Deprecated options:') Trace.error(' --toc: (deprecated) create a table of contents') Trace.error(' --toctarget "page": (deprecated) generate a TOC for the given page') Trace.error(' --nocopy: (deprecated) maintained for backwards compatibility') Trace.error(' --jsmath "URL": use jsMath from the given URL to display equations') sys.exit() def showversion(self): "Return the current eLyXer version string" string = 'eLyXer version ' + GeneralConfig.version['number'] string += ' (' + GeneralConfig.version['date'] + ')' Trace.error(string) sys.exit() def showhardversion(self): "Return just the version string" Trace.message(GeneralConfig.version['number']) sys.exit() def showversiondate(self): "Return just the version dte" Trace.message(GeneralConfig.version['date']) sys.exit() def showlyxformat(self): "Return just the lyxformat parameter" Trace.message(GeneralConfig.version['lyxformat']) sys.exit() class BranchOptions(object): "A set of options for a branch" def __init__(self, name): self.name = name self.options = {'color':'#ffffff'} def set(self, key, value): "Set a branch option" if not key.startswith(ContainerConfig.string['startcommand']): Trace.error('Invalid branch option ' + key) return key = key.replace(ContainerConfig.string['startcommand'], '') self.options[key] = value def isselected(self): "Return if the branch is selected" if not 'selected' in self.options: return False return self.options['selected'] == '1' def __unicode__(self): "String representation" return 'options for ' + self.name + ': ' + unicode(self.options) import gettext class DocumentParameters(object): "Global parameters for the document." pdftitle = None indentstandard = False tocdepth = 10 startinglevel = 0 maxdepth = 10 language = None bibliography = None outputchanges = False displaymode = False class Translator(object): "Reads the configuration file and tries to find a translation." "Otherwise falls back to the messages in the config file." instance = None def translate(cls, key): "Get the translated message for a key." return cls.instance.getmessage(key) translate = classmethod(translate) def __init__(self): self.translation = None self.first = True def findtranslation(self): "Find the translation for the document language." self.langcodes = None if not DocumentParameters.language: Trace.error('No language in document') return if not DocumentParameters.language in TranslationConfig.languages: Trace.error('Unknown language ' + DocumentParameters.language) return if TranslationConfig.languages[DocumentParameters.language] == 'en': return langcodes = [TranslationConfig.languages[DocumentParameters.language]] try: self.translation = gettext.translation('elyxer', None, langcodes) except IOError: Trace.error('No translation for ' + unicode(langcodes)) def getmessage(self, key): "Get the translated message for the given key." if self.first: self.findtranslation() self.first = False message = self.getuntranslated(key) if not self.translation: return message try: message = self.translation.ugettext(message) except IOError: pass return message def getuntranslated(self, key): "Get the untranslated message." if not key in TranslationConfig.constants: Trace.error('Cannot translate ' + key) return key return TranslationConfig.constants[key] Translator.instance = Translator() class NumberCounter(object): "A counter for numbers (by default)." "The type can be changed to return letters, roman numbers..." name = None value = None mode = None master = None letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' symbols = NumberingConfig.sequence['symbols'] romannumerals = [ ('M', 1000), ('CM', 900), ('D', 500), ('CD', 400), ('C', 100), ('XC', 90), ('L', 50), ('XL', 40), ('X', 10), ('IX', 9), ('V', 5), ('IV', 4), ('I', 1) ] def __init__(self, name): "Give a name to the counter." self.name = name def setmode(self, mode): "Set the counter mode. Can be changed at runtime." self.mode = mode return self def init(self, value): "Set an initial value." self.value = value def gettext(self): "Get the next value as a text string." return unicode(self.value) def getletter(self): "Get the next value as a letter." return self.getsequence(self.letters) def getsymbol(self): "Get the next value as a symbol." return self.getsequence(self.symbols) def getsequence(self, sequence): "Get the next value from elyxer.a sequence." return sequence[(self.value - 1) % len(sequence)] def getroman(self): "Get the next value as a roman number." result = '' number = self.value for numeral, value in self.romannumerals: if number >= value: result += numeral * (number / value) number = number % value return result def getvalue(self): "Get the current value as configured in the current mode." if not self.mode or self.mode in ['text', '1']: return self.gettext() if self.mode == 'A': return self.getletter() if self.mode == 'a': return self.getletter().lower() if self.mode == 'I': return self.getroman() if self.mode == '*': return self.getsymbol() Trace.error('Unknown counter mode ' + self.mode) return self.gettext() def getnext(self): "Increase the current value and get the next value as configured." if not self.value: self.value = 0 self.value += 1 return self.getvalue() def reset(self): "Reset the counter." self.value = 0 def __unicode__(self): "Return a printable representation." result = 'Counter ' + self.name if self.mode: result += ' in mode ' + self.mode return result class DependentCounter(NumberCounter): "A counter which depends on another one (the master)." def setmaster(self, master): "Set the master counter." self.master = master self.last = self.master.getvalue() return self def getnext(self): "Increase or, if the master counter has changed, restart." if self.last != self.master.getvalue(): self.reset() value = NumberCounter.getnext(self) self.last = self.master.getvalue() return value def getvalue(self): "Get the value of the combined counter: master.dependent." return self.master.getvalue() + '.' + NumberCounter.getvalue(self) class NumberGenerator(object): "A number generator for unique sequences and hierarchical structures. Used in:" " * ordered part numbers: Chapter 3, Section 5.3." " * unique part numbers: Footnote 15, Bibliography cite [15]." " * chaptered part numbers: Figure 3.15, Equation (8.3)." " * unique roman part numbers: Part I, Book IV." chaptered = None generator = None romanlayouts = [x.lower() for x in NumberingConfig.layouts['roman']] orderedlayouts = [x.lower() for x in NumberingConfig.layouts['ordered']] counters = dict() appendix = None def deasterisk(self, type): "Remove the possible asterisk in a layout type." return type.replace('*', '') def isunique(self, type): "Find out if the layout type corresponds to a unique part." return self.isroman(type) def isroman(self, type): "Find out if the layout type should have roman numeration." return self.deasterisk(type).lower() in self.romanlayouts def isinordered(self, type): "Find out if the layout type corresponds to an (un)ordered part." return self.deasterisk(type).lower() in self.orderedlayouts def isnumbered(self, type): "Find out if the type for a layout corresponds to a numbered layout." if '*' in type: return False if self.isroman(type): return True if not self.isinordered(type): return False if self.getlevel(type) > DocumentParameters.maxdepth: return False return True def isunordered(self, type): "Find out if the type contains an asterisk, basically." return '*' in type def getlevel(self, type): "Get the level that corresponds to a layout type." if self.isunique(type): return 0 if not self.isinordered(type): Trace.error('Unknown layout type ' + type) return 0 type = self.deasterisk(type).lower() level = self.orderedlayouts.index(type) + 1 return level - DocumentParameters.startinglevel def getparttype(self, type): "Obtain the type for the part: without the asterisk, " "and switched to Appendix if necessary." if NumberGenerator.appendix and self.getlevel(type) == 1: return 'Appendix' return self.deasterisk(type) def generate(self, type): "Generate a number for a layout type." "Unique part types such as Part or Book generate roman numbers: Part I." "Ordered part types return dot-separated tuples: Chapter 5, Subsection 2.3.5." "Everything else generates unique numbers: Bibliography [1]." "Each invocation results in a new number." return self.getcounter(type).getnext() def getcounter(self, type): "Get the counter for the given type." type = type.lower() if not type in self.counters: self.counters[type] = self.create(type) return self.counters[type] def create(self, type): "Create a counter for the given type." if self.isnumbered(type) and self.getlevel(type) > 1: index = self.orderedlayouts.index(type) above = self.orderedlayouts[index - 1] master = self.getcounter(above) return self.createdependent(type, master) counter = NumberCounter(type) if self.isroman(type): counter.setmode('I') return counter def getdependentcounter(self, type, master): "Get (or create) a counter of the given type that depends on another." if not type in self.counters or not self.counters[type].master: self.counters[type] = self.createdependent(type, master) return self.counters[type] def createdependent(self, type, master): "Create a dependent counter given the master." return DependentCounter(type).setmaster(master) def startappendix(self): "Start appendices here." firsttype = self.orderedlayouts[DocumentParameters.startinglevel] counter = self.getcounter(firsttype) counter.setmode('A').reset() NumberGenerator.appendix = True class ChapteredGenerator(NumberGenerator): "Generate chaptered numbers, as in Chapter.Number." "Used in equations, figures: Equation (5.3), figure 8.15." def generate(self, type): "Generate a number which goes with first-level numbers (chapters). " "For the article classes a unique number is generated." if DocumentParameters.startinglevel > 0: return NumberGenerator.generator.generate(type) chapter = self.getcounter('Chapter') return self.getdependentcounter(type, chapter).getnext() NumberGenerator.chaptered = ChapteredGenerator() NumberGenerator.generator = NumberGenerator() class Parser(object): "A generic parser" def __init__(self): self.begin = 0 self.parameters = dict() def parseheader(self, reader): "Parse the header" header = reader.currentline().split() reader.nextline() self.begin = reader.linenumber return header def parseparameter(self, reader): "Parse a parameter" if reader.currentline().strip().startswith('<'): key, value = self.parsexml(reader) self.parameters[key] = value return split = reader.currentline().strip().split(' ', 1) reader.nextline() if len(split) == 0: return key = split[0] if len(split) == 1: self.parameters[key] = True return if not '"' in split[1]: self.parameters[key] = split[1].strip() return doublesplit = split[1].split('"') self.parameters[key] = doublesplit[1] def parsexml(self, reader): "Parse a parameter in xml form: " strip = reader.currentline().strip() reader.nextline() if not strip.endswith('>'): Trace.error('XML parameter ' + strip + ' should be <...>') split = strip[1:-1].split() if len(split) == 0: Trace.error('Empty XML parameter <>') return None, None key = split[0] del split[0] if len(split) == 0: return key, dict() attrs = dict() for attr in split: if not '=' in attr: Trace.error('Erroneous attribute for ' + key + ': ' + attr) attr += '="0"' parts = attr.split('=') attrkey = parts[0] value = parts[1].split('"')[1] attrs[attrkey] = value return key, attrs def parseending(self, reader, process): "Parse until the current ending is found" if not self.ending: Trace.error('No ending for ' + unicode(self)) return while not reader.currentline().startswith(self.ending): process() def parsecontainer(self, reader, contents): container = self.factory.createcontainer(reader) if container: container.parent = self.parent contents.append(container) def __unicode__(self): "Return a description" return self.__class__.__name__ + ' (' + unicode(self.begin) + ')' class LoneCommand(Parser): "A parser for just one command line" def parse(self,reader): "Read nothing" return [] class TextParser(Parser): "A parser for a command and a bit of text" stack = [] def __init__(self, container): Parser.__init__(self) self.ending = None if container.__class__.__name__ in ContainerConfig.endings: self.ending = ContainerConfig.endings[container.__class__.__name__] self.endings = [] def parse(self, reader): "Parse lines as long as they are text" TextParser.stack.append(self.ending) self.endings = TextParser.stack + [ContainerConfig.endings['Layout'], ContainerConfig.endings['Inset'], self.ending] contents = [] while not self.isending(reader): self.parsecontainer(reader, contents) return contents def isending(self, reader): "Check if text is ending" current = reader.currentline().split() if len(current) == 0: return False if current[0] in self.endings: if current[0] in TextParser.stack: TextParser.stack.remove(current[0]) else: TextParser.stack = [] return True return False class ExcludingParser(Parser): "A parser that excludes the final line" def parse(self, reader): "Parse everything up to (and excluding) the final line" contents = [] self.parseending(reader, lambda: self.parsecontainer(reader, contents)) return contents class BoundedParser(ExcludingParser): "A parser bound by a final line" def parse(self, reader): "Parse everything, including the final line" contents = ExcludingParser.parse(self, reader) # skip last line reader.nextline() return contents class BoundedDummy(Parser): "A bound parser that ignores everything" def parse(self, reader): "Parse the contents of the container" self.parseending(reader, lambda: reader.nextline()) # skip last line reader.nextline() return [] class StringParser(Parser): "Parses just a string" def parseheader(self, reader): "Do nothing, just take note" self.begin = reader.linenumber + 1 return [] def parse(self, reader): "Parse a single line" contents = reader.currentline() reader.nextline() return contents class InsetParser(BoundedParser): "Parses a LyX inset" def parse(self, reader): "Parse inset parameters into a dictionary" startcommand = ContainerConfig.string['startcommand'] while reader.currentline() != '' and not reader.currentline().startswith(startcommand): self.parseparameter(reader) return BoundedParser.parse(self, reader) class ContainerOutput(object): "The generic HTML output for a container." def gethtml(self, container): "Show an error." Trace.error('gethtml() not implemented for ' + unicode(self)) def isempty(self): "Decide if the output is empty: by default, not empty." return False class EmptyOutput(ContainerOutput): def gethtml(self, container): "Return empty HTML code." return [] def isempty(self): "This output is particularly empty." return True class FixedOutput(ContainerOutput): "Fixed output" def gethtml(self, container): "Return constant HTML code" return container.html class ContentsOutput(ContainerOutput): "Outputs the contents converted to HTML" def gethtml(self, container): "Return the HTML code" html = [] if container.contents == None: return html for element in container.contents: if not hasattr(element, 'gethtml'): Trace.error('No html in ' + element.__class__.__name__ + ': ' + unicode(element)) return html html += element.gethtml() return html class TaggedOutput(ContentsOutput): "Outputs an HTML tag surrounding the contents." tag = None breaklines = False empty = False def settag(self, tag, breaklines=False, empty=False): "Set the value for the tag and other attributes." self.tag = tag if breaklines: self.breaklines = breaklines if empty: self.empty = empty return self def setbreaklines(self, breaklines): "Set the value for breaklines." self.breaklines = breaklines return self def gethtml(self, container): "Return the HTML code." if self.empty: return [self.selfclosing(container)] html = [self.open(container)] html += ContentsOutput.gethtml(self, container) html.append(self.close(container)) return html def open(self, container): "Get opening line." if not self.checktag(): return '' open = '<' + self.tag + '>' if self.breaklines: return open + '\n' return open def close(self, container): "Get closing line." if not self.checktag(): return '' close = '' if self.breaklines: return '\n' + close + '\n' return close def selfclosing(self, container): "Get self-closing line." if not self.checktag(): return '' selfclosing = '<' + self.tag + '/>' if self.breaklines: return selfclosing + '\n' return selfclosing def checktag(self): "Check that the tag is valid." if not self.tag: Trace.error('No tag in ' + unicode(container)) return False if self.tag == '': return False return True class FilteredOutput(ContentsOutput): "Returns the output in the contents, but filtered:" "some strings are replaced by others." def __init__(self): "Initialize the filters." self.filters = [] def addfilter(self, original, replacement): "Add a new filter: replace the original by the replacement." self.filters.append((original, replacement)) def gethtml(self, container): "Return the HTML code" result = [] html = ContentsOutput.gethtml(self, container) for line in html: result.append(self.filter(line)) return result def filter(self, line): "Filter a single line with all available filters." for original, replacement in self.filters: if original in line: line = line.replace(original, replacement) return line class StringOutput(ContainerOutput): "Returns a bare string as output" def gethtml(self, container): "Return a bare string" return [container.string] class Cloner(object): "An object used to clone other objects." def clone(cls, original): "Return an exact copy of an object." "The original object must have an empty constructor." return cls.create(original.__class__) def create(cls, type): "Create an object of a given class." clone = type.__new__(type) clone.__init__() return clone clone = classmethod(clone) create = classmethod(create) class ContainerExtractor(object): "A class to extract certain containers." def __init__(self, config): "The config parameter is a map containing three lists: allowed, copied and extracted." "Each of the three is a list of class names for containers." "Allowed containers are included as is into the result." "Cloned containers are cloned and placed into the result." "Extracted containers are looked into." "All other containers are silently ignored." self.allowed = config['allowed'] self.cloned = config['cloned'] self.extracted = config['extracted'] def extract(self, container): "Extract a group of selected containers from elyxer.a container." list = [] locate = lambda c: c.__class__.__name__ in self.allowed + self.cloned recursive = lambda c: c.__class__.__name__ in self.extracted process = lambda c: self.process(c, list) container.recursivesearch(locate, recursive, process) return list def process(self, container, list): "Add allowed containers, clone cloned containers and add the clone." name = container.__class__.__name__ if name in self.allowed: list.append(container) elif name in self.cloned: list.append(self.safeclone(container)) else: Trace.error('Unknown container class ' + name) def safeclone(self, container): "Return a new container with contents only in a safe list, recursively." clone = Cloner.clone(container) clone.output = container.output clone.contents = self.extract(container) return clone class Globable(object): """A bit of text which can be globbed (lumped together in bits). Methods current(), skipcurrent(), checkfor() and isout() have to be implemented by subclasses.""" leavepending = False def __init__(self): self.endinglist = EndingList() def checkbytemark(self): "Check for a Unicode byte mark and skip it." if self.finished(): return if ord(self.current()) == 0xfeff: self.skipcurrent() def isout(self): "Find out if we are out of the position yet." Trace.error('Unimplemented isout()') return True def current(self): "Return the current character." Trace.error('Unimplemented current()') return '' def checkfor(self, string): "Check for the given string in the current position." Trace.error('Unimplemented checkfor()') return False def finished(self): "Find out if the current text has finished." if self.isout(): if not self.leavepending: self.endinglist.checkpending() return True return self.endinglist.checkin(self) def skipcurrent(self): "Return the current character and skip it." Trace.error('Unimplemented skipcurrent()') return '' def glob(self, currentcheck): "Glob a bit of text that satisfies a check on the current char." glob = '' while not self.finished() and currentcheck(): glob += self.skipcurrent() return glob def globalpha(self): "Glob a bit of alpha text" return self.glob(lambda: self.current().isalpha()) def globnumber(self): "Glob a row of digits." return self.glob(lambda: self.current().isdigit()) def isidentifier(self): "Return if the current character is alphanumeric or _." if self.current().isalnum() or self.current() == '_': return True return False def globidentifier(self): "Glob alphanumeric and _ symbols." return self.glob(self.isidentifier) def isvalue(self): "Return if the current character is a value character:" "not a bracket or a space." if self.current().isspace(): return False if self.current() in '{}()': return False return True def globvalue(self): "Glob a value: any symbols but brackets." return self.glob(self.isvalue) def skipspace(self): "Skip all whitespace at current position." return self.glob(lambda: self.current().isspace()) def globincluding(self, magicchar): "Glob a bit of text up to (including) the magic char." glob = self.glob(lambda: self.current() != magicchar) + magicchar self.skip(magicchar) return glob def globexcluding(self, excluded): "Glob a bit of text up until (excluding) any excluded character." return self.glob(lambda: self.current() not in excluded) def pushending(self, ending, optional = False): "Push a new ending to the bottom" self.endinglist.add(ending, optional) def popending(self, expected = None): "Pop the ending found at the current position" if self.isout() and self.leavepending: return expected ending = self.endinglist.pop(self) if expected and expected != ending: Trace.error('Expected ending ' + expected + ', got ' + ending) self.skip(ending) return ending def nextending(self): "Return the next ending in the queue." nextending = self.endinglist.findending(self) if not nextending: return None return nextending.ending class EndingList(object): "A list of position endings" def __init__(self): self.endings = [] def add(self, ending, optional = False): "Add a new ending to the list" self.endings.append(PositionEnding(ending, optional)) def pickpending(self, pos): "Pick any pending endings from a parse position." self.endings += pos.endinglist.endings def checkin(self, pos): "Search for an ending" if self.findending(pos): return True return False def pop(self, pos): "Remove the ending at the current position" if pos.isout(): Trace.error('No ending out of bounds') return '' ending = self.findending(pos) if not ending: Trace.error('No ending at ' + pos.current()) return '' for each in reversed(self.endings): self.endings.remove(each) if each == ending: return each.ending elif not each.optional: Trace.error('Removed non-optional ending ' + each) Trace.error('No endings left') return '' def findending(self, pos): "Find the ending at the current position" if len(self.endings) == 0: return None for index, ending in enumerate(reversed(self.endings)): if ending.checkin(pos): return ending if not ending.optional: return None return None def checkpending(self): "Check if there are any pending endings" if len(self.endings) != 0: Trace.error('Pending ' + unicode(self) + ' left open') def __unicode__(self): "Printable representation" string = 'endings [' for ending in self.endings: string += unicode(ending) + ',' if len(self.endings) > 0: string = string[:-1] return string + ']' class PositionEnding(object): "An ending for a parsing position" def __init__(self, ending, optional): self.ending = ending self.optional = optional def checkin(self, pos): "Check for the ending" return pos.checkfor(self.ending) def __unicode__(self): "Printable representation" string = 'Ending ' + self.ending if self.optional: string += ' (optional)' return string class Position(Globable): """A position in a text to parse. Including those in Globable, functions to implement by subclasses are: skip(), identifier(), extract(), isout() and current().""" def __init__(self): Globable.__init__(self) def skip(self, string): "Skip a string" Trace.error('Unimplemented skip()') def identifier(self): "Return an identifier for the current position." Trace.error('Unimplemented identifier()') return 'Error' def extract(self, length): "Extract the next string of the given length, or None if not enough text," "without advancing the parse position." Trace.error('Unimplemented extract()') return None def checkfor(self, string): "Check for a string at the given position." return string == self.extract(len(string)) def checkforlower(self, string): "Check for a string in lower case." extracted = self.extract(len(string)) if not extracted: return False return string.lower() == self.extract(len(string)).lower() def skipcurrent(self): "Return the current character and skip it." current = self.current() self.skip(current) return current def next(self): "Advance the position and return the next character." self.skipcurrent() return self.current() def checkskip(self, string): "Check for a string at the given position; if there, skip it" if not self.checkfor(string): return False self.skip(string) return True def error(self, message): "Show an error message and the position identifier." Trace.error(message + ': ' + self.identifier()) class TextPosition(Position): "A parse position based on a raw text." def __init__(self, text): "Create the position from elyxer.some text." Position.__init__(self) self.pos = 0 self.text = text self.checkbytemark() def skip(self, string): "Skip a string of characters." self.pos += len(string) def identifier(self): "Return a sample of the remaining text." length = 30 if self.pos + length > len(self.text): length = len(self.text) - self.pos return '*' + self.text[self.pos:self.pos + length] + '*' def isout(self): "Find out if we are out of the text yet." return self.pos >= len(self.text) def current(self): "Return the current character, assuming we are not out." return self.text[self.pos] def extract(self, length): "Extract the next string of the given length, or None if not enough text." if self.pos + length > len(self.text): return None return self.text[self.pos : self.pos + length] class FilePosition(Position): "A parse position based on an underlying file." def __init__(self, filename): "Create the position from a file." Position.__init__(self) self.reader = LineReader(filename) self.pos = 0 self.checkbytemark() def skip(self, string): "Skip a string of characters." length = len(string) while self.pos + length > len(self.reader.currentline()): length -= len(self.reader.currentline()) - self.pos + 1 self.nextline() self.pos += length def currentline(self): "Get the current line of the underlying file." return self.reader.currentline() def nextline(self): "Go to the next line." self.reader.nextline() self.pos = 0 def linenumber(self): "Return the line number of the file." return self.reader.linenumber + 1 def identifier(self): "Return the current line and line number in the file." before = self.reader.currentline()[:self.pos - 1] after = self.reader.currentline()[self.pos:] return 'line ' + unicode(self.getlinenumber()) + ': ' + before + '*' + after def isout(self): "Find out if we are out of the text yet." if self.pos > len(self.reader.currentline()): if self.pos > len(self.reader.currentline()) + 1: Trace.error('Out of the line ' + self.reader.currentline() + ': ' + unicode(self.pos)) self.nextline() return self.reader.finished() def current(self): "Return the current character, assuming we are not out." if self.pos == len(self.reader.currentline()): return '\n' if self.pos > len(self.reader.currentline()): Trace.error('Out of the line ' + self.reader.currentline() + ': ' + unicode(self.pos)) return '*' return self.reader.currentline()[self.pos] def extract(self, length): "Extract the next string of the given length, or None if not enough text." if self.pos + length > len(self.reader.currentline()): return None return self.reader.currentline()[self.pos : self.pos + length] class Container(object): "A container for text and objects in a lyx file" partkey = None parent = None begin = None def __init__(self): self.contents = list() def process(self): "Process contents" pass def gethtml(self): "Get the resulting HTML" html = self.output.gethtml(self) if isinstance(html, basestring): Trace.error('Raw string ' + html) html = [html] return self.escapeall(html) def escapeall(self, lines): "Escape all lines in an array according to the output options." result = [] for line in lines: if Options.html: line = self.escape(line, EscapeConfig.html) if Options.iso885915: line = self.escape(line, EscapeConfig.iso885915) line = self.escapeentities(line) elif not Options.unicode: line = self.escape(line, EscapeConfig.nonunicode) result.append(line) return result def escape(self, line, replacements = EscapeConfig.entities): "Escape a line with replacements from elyxer.a map" pieces = replacements.keys() # do them in order pieces.sort() for piece in pieces: if piece in line: line = line.replace(piece, replacements[piece]) return line def escapeentities(self, line): "Escape all Unicode characters to HTML entities." result = '' pos = TextPosition(line) while not pos.finished(): if ord(pos.current()) > 128: codepoint = hex(ord(pos.current())) if codepoint == '0xd835': codepoint = hex(ord(pos.next()) + 0xf800) result += '&#' + codepoint[1:] + ';' else: result += pos.current() pos.skipcurrent() return result def searchall(self, type): "Search for all embedded containers of a given type" list = [] self.searchprocess(type, lambda container: list.append(container)) return list def searchremove(self, type): "Search for all containers of a type and remove them" list = self.searchall(type) for container in list: container.parent.contents.remove(container) return list def searchprocess(self, type, process): "Search for elements of a given type and process them" self.locateprocess(lambda container: isinstance(container, type), process) def locateprocess(self, locate, process): "Search for all embedded containers and process them" for container in self.contents: container.locateprocess(locate, process) if locate(container): process(container) def recursivesearch(self, locate, recursive, process): "Perform a recursive search in the container." for container in self.contents: if recursive(container): container.recursivesearch(locate, recursive, process) if locate(container): process(container) def extracttext(self): "Extract all text from elyxer.allowed containers." result = '' constants = ContainerExtractor(ContainerConfig.extracttext).extract(self) for constant in constants: result += constant.string return result def group(self, index, group, isingroup): "Group some adjoining elements into a group" if index >= len(self.contents): return if hasattr(self.contents[index], 'grouped'): return while index < len(self.contents) and isingroup(self.contents[index]): self.contents[index].grouped = True group.contents.append(self.contents[index]) self.contents.pop(index) self.contents.insert(index, group) def remove(self, index): "Remove a container but leave its contents" container = self.contents[index] self.contents.pop(index) while len(container.contents) > 0: self.contents.insert(index, container.contents.pop()) def tree(self, level = 0): "Show in a tree" Trace.debug(" " * level + unicode(self)) for container in self.contents: container.tree(level + 1) def getparameter(self, name): "Get the value of a parameter, if present." if not name in self.parameters: return None return self.parameters[name] def getparameterlist(self, name): "Get the value of a comma-separated parameter as a list." paramtext = self.getparameter(name) if not paramtext: return [] return paramtext.split(',') def hasemptyoutput(self): "Check if the parent's output is empty." current = self.parent while current: if current.output.isempty(): return True current = current.parent return False def __unicode__(self): "Get a description" if not self.begin: return self.__class__.__name__ return self.__class__.__name__ + '@' + unicode(self.begin) class BlackBox(Container): "A container that does not output anything" def __init__(self): self.parser = LoneCommand() self.output = EmptyOutput() self.contents = [] class LyXFormat(BlackBox): "Read the lyxformat command" def process(self): "Show warning if version < 276" version = int(self.header[1]) if version < 276: Trace.error('Warning: unsupported old format version ' + str(version)) if version > int(GeneralConfig.version['lyxformat']): Trace.error('Warning: unsupported new format version ' + str(version)) class StringContainer(Container): "A container for a single string" parsed = None def __init__(self): self.parser = StringParser() self.output = StringOutput() self.string = '' def process(self): "Replace special chars from elyxer.the contents." if self.parsed: self.string = self.replacespecial(self.parsed) self.parsed = None def replacespecial(self, line): "Replace all special chars from elyxer.a line" replaced = self.escape(line, EscapeConfig.entities) replaced = self.changeline(replaced) if ContainerConfig.string['startcommand'] in replaced and len(replaced) > 1: # unprocessed commands if self.begin: message = 'Unknown command at ' + unicode(self.begin) + ': ' else: message = 'Unknown command: ' Trace.error(message + replaced.strip()) return replaced def changeline(self, line): line = self.escape(line, EscapeConfig.chars) if not ContainerConfig.string['startcommand'] in line: return line line = self.escape(line, EscapeConfig.commands) return line def extracttext(self): "Return all text." return self.string def __unicode__(self): "Return a printable representation." result = 'StringContainer' if self.begin: result += '@' + unicode(self.begin) ellipsis = '...' if len(self.string.strip()) <= 15: ellipsis = '' return result + ' (' + self.string.strip()[:15] + ellipsis + ')' class Constant(StringContainer): "A constant string" def __init__(self, text): self.contents = [] self.string = text self.output = StringOutput() def __unicode__(self): return 'Constant: ' + self.string class TaggedText(Container): "Text inside a tag" output = None def __init__(self): self.parser = TextParser(self) self.output = TaggedOutput() def complete(self, contents, tag, breaklines=False): "Complete the tagged text and return it" self.contents = contents self.output.tag = tag self.output.breaklines = breaklines return self def constant(self, text, tag, breaklines=False): "Complete the tagged text with a constant" constant = Constant(text) return self.complete([constant], tag, breaklines) def __unicode__(self): "Return a printable representation." if not hasattr(self.output, 'tag'): return 'Emtpy tagged text' if not self.output.tag: return 'Tagged ' return 'Tagged <' + self.output.tag + '>' class ContainerSize(object): "The size of a container." width = None height = None maxwidth = None maxheight = None scale = None def set(self, width = None, height = None): "Set the proper size with width and height." self.setvalue('width', width) self.setvalue('height', height) return self def setmax(self, maxwidth = None, maxheight = None): "Set max width and/or height." self.setvalue('maxwidth', maxwidth) self.setvalue('maxheight', maxheight) return self def readparameters(self, container): "Read some size parameters off a container." self.setparameter(container, 'width') self.setparameter(container, 'height') self.setparameter(container, 'scale') self.checkvalidheight(container) return self def setparameter(self, container, name): "Read a size parameter off a container, and set it if present." value = container.getparameter(name) self.setvalue(name, value) def setvalue(self, name, value): "Set the value of a parameter name, only if it's valid." value = self.processparameter(value) if value: setattr(self, name, value) def checkvalidheight(self, container): "Check if the height parameter is valid; otherwise erase it." heightspecial = container.getparameter('height_special') if self.height and self.extractnumber(self.height) == '1' and heightspecial == 'totalheight': self.height = None def processparameter(self, value): "Do the full processing on a parameter." if not value: return None if self.extractnumber(value) == '0': return None for ignored in StyleConfig.size['ignoredtexts']: if ignored in value: value = value.replace(ignored, '') return value def extractnumber(self, text): "Extract the first number in the given text." result = '' decimal = False for char in text: if char.isdigit(): result += char elif char == '.' and not decimal: result += char decimal = True else: return result return result def checkimage(self, width, height): "Check image dimensions, set them if possible." if width: self.maxwidth = unicode(width) + 'px' if self.scale and not self.width: self.width = self.scalevalue(width) if height: self.maxheight = unicode(height) + 'px' if self.scale and not self.height: self.height = self.scalevalue(height) if self.width and not self.height: self.height = 'auto' if self.height and not self.width: self.width = 'auto' def scalevalue(self, value): "Scale the value according to the image scale and return it as unicode." scaled = value * int(self.scale) / 100 return unicode(int(scaled)) + 'px' def removepercentwidth(self): "Remove percent width if present, to set it at the figure level." if not self.width: return None if not '%' in self.width: return None width = self.width self.width = None if self.height == 'auto': self.height = None return width def addstyle(self, container): "Add the proper style attribute to the output tag." if not isinstance(container.output, TaggedOutput): Trace.error('No tag to add style, in ' + unicode(container)) if not self.width and not self.height and not self.maxwidth and not self.maxheight: # nothing to see here; move along return tag = ' style="' tag += self.styleparameter('width') tag += self.styleparameter('maxwidth') tag += self.styleparameter('height') tag += self.styleparameter('maxheight') if tag[-1] == ' ': tag = tag[:-1] tag += '"' container.output.tag += tag def styleparameter(self, name): "Get the style for a single parameter." value = getattr(self, name) if value: return name.replace('max', 'max-') + ': ' + value + '; ' return '' class QuoteContainer(Container): "A container for a pretty quote" def __init__(self): self.parser = BoundedParser() self.output = FixedOutput() def process(self): "Process contents" self.type = self.header[2] if not self.type in StyleConfig.quotes: Trace.error('Quote type ' + self.type + ' not found') self.html = ['"'] return self.html = [StyleConfig.quotes[self.type]] class LyXLine(Container): "A Lyx line" def __init__(self): self.parser = LoneCommand() self.output = FixedOutput() def process(self): self.html = ['
'] class EmphaticText(TaggedText): "Text with emphatic mode" def process(self): self.output.tag = 'i' class ShapedText(TaggedText): "Text shaped (italic, slanted)" def process(self): self.type = self.header[1] if not self.type in TagConfig.shaped: Trace.error('Unrecognized shape ' + self.header[1]) self.output.tag = 'span' return self.output.tag = TagConfig.shaped[self.type] class VersalitasText(TaggedText): "Text in versalitas" def process(self): self.output.tag = 'span class="versalitas"' class ColorText(TaggedText): "Colored text" def process(self): self.color = self.header[1] self.output.tag = 'span class="' + self.color + '"' class SizeText(TaggedText): "Sized text" def process(self): self.size = self.header[1] self.output.tag = 'span class="' + self.size + '"' class BoldText(TaggedText): "Bold text" def process(self): self.output.tag = 'b' class TextFamily(TaggedText): "A bit of text from elyxer.a different family" def process(self): "Parse the type of family" self.type = self.header[1] if not self.type in TagConfig.family: Trace.error('Unrecognized family ' + type) self.output.tag = 'span' return self.output.tag = TagConfig.family[self.type] class Hfill(TaggedText): "Horizontall fill" def process(self): self.output.tag = 'span class="hfill"' class BarredText(TaggedText): "Text with a bar somewhere" def process(self): "Parse the type of bar" self.type = self.header[1] if not self.type in TagConfig.barred: Trace.error('Unknown bar type ' + self.type) self.output.tag = 'span' return self.output.tag = TagConfig.barred[self.type] class LangLine(TaggedText): "A line with language information" def process(self): "Only generate a span with lang info when the language is recognized." lang = self.header[1] if not lang in TranslationConfig.languages: self.output = ContentsOutput() return isolang = TranslationConfig.languages[lang] self.output = TaggedOutput().settag('span lang="' + isolang + '"', False) class InsetLength(BlackBox): "A length measure inside an inset." def process(self): self.length = self.header[1] class Space(Container): "A space of several types" def __init__(self): self.parser = InsetParser() self.output = FixedOutput() def process(self): self.type = self.header[2] if self.type not in StyleConfig.hspaces: Trace.error('Unknown space type ' + self.type) self.html = [' '] return self.html = [StyleConfig.hspaces[self.type]] length = self.getlength() if not length: return self.output = TaggedOutput().settag('span class="hspace"', False) ContainerSize().set(length).addstyle(self) def getlength(self): "Get the space length from elyxer.the contents or parameters." if len(self.contents) == 0 or not isinstance(self.contents[0], InsetLength): return None return self.contents[0].length class VerticalSpace(Container): "An inset that contains a vertical space." def __init__(self): self.parser = InsetParser() self.output = FixedOutput() def process(self): "Set the correct tag" self.type = self.header[2] if self.type not in StyleConfig.vspaces: self.output = TaggedOutput().settag('div class="vspace" style="height: ' + self.type + ';"', True) return self.html = [StyleConfig.vspaces[self.type]] class Align(Container): "Bit of aligned text" def __init__(self): self.parser = ExcludingParser() self.output = TaggedOutput().setbreaklines(True) def process(self): self.output.tag = 'div class="' + self.header[1] + '"' class Newline(Container): "A newline" def __init__(self): self.parser = LoneCommand() self.output = FixedOutput() def process(self): "Process contents" self.html = ['
\n'] class NewPage(Newline): "A new page" def process(self): "Process contents" self.html = ['


\n

\n'] class Separator(Container): "A separator string which is not extracted by extracttext()." def __init__(self, constant): self.output = FixedOutput() self.contents = [] self.html = [constant] class StrikeOut(TaggedText): "Striken out text." def process(self): "Set the output tag to strike." self.output.tag = 'strike' class StartAppendix(BlackBox): "Mark to start an appendix here." "From this point on, all chapters become appendices." def process(self): "Activate the special numbering scheme for appendices, using letters." NumberGenerator.generator.startappendix() class Link(Container): "A link to another part of the document" anchor = None url = None type = None page = None target = None destination = None title = None def __init__(self): "Initialize the link, add target if configured." self.contents = [] self.parser = InsetParser() self.output = LinkOutput() if Options.target: self.target = Options.target def complete(self, text, anchor = None, url = None, type = None, title = None): "Complete the link." self.contents = [Constant(text)] if anchor: self.anchor = anchor if url: self.url = url if type: self.type = type if title: self.title = title return self def computedestination(self): "Use the destination link to fill in the destination URL." if not self.destination: return self.url = '' if self.destination.anchor: self.url = '#' + self.destination.anchor if self.destination.page: self.url = self.destination.page + self.url def setmutualdestination(self, destination): "Set another link as destination, and set its destination to this one." self.destination = destination destination.destination = self def __unicode__(self): "Return a printable representation." result = 'Link' if self.anchor: result += ' #' + self.anchor if self.url: result += ' to ' + self.url return result class URL(Link): "A clickable URL" def process(self): "Read URL from elyxer.parameters" target = self.escape(self.getparameter('target')) self.url = target type = self.getparameter('type') if type: self.url = self.escape(type) + target name = self.getparameter('name') if not name: name = target self.contents = [Constant(name)] class FlexURL(URL): "A flexible URL" def process(self): "Read URL from elyxer.contents" self.url = self.extracttext() class LinkOutput(ContainerOutput): "A link pointing to some destination" "Or an anchor (destination)" def gethtml(self, link): "Get the HTML code for the link" type = link.__class__.__name__ if link.type: type = link.type tag = 'a class="' + type + '"' if link.anchor: tag += ' name="' + link.anchor + '"' if link.destination: link.computedestination() if link.url: tag += ' href="' + link.url + '"' if link.target: tag += ' target="' + link.target + '"' if link.title: tag += ' title="' + link.title + '"' return TaggedOutput().settag(tag).gethtml(link) class Postprocessor(object): "Postprocess a container keeping some context" stages = [] def __init__(self): self.stages = StageDict(Postprocessor.stages, self) self.current = None self.last = None def postprocess(self, next): "Postprocess a container and its contents." self.postrecursive(self.current) result = self.postcurrent(next) self.last = self.current self.current = next return result def postrecursive(self, container): "Postprocess the container contents recursively" if not hasattr(container, 'contents'): return if len(container.contents) == 0: return if hasattr(container, 'postprocess'): if not container.postprocess: return postprocessor = Postprocessor() contents = [] for element in container.contents: post = postprocessor.postprocess(element) if post: contents.append(post) # two rounds to empty the pipeline for i in range(2): post = postprocessor.postprocess(None) if post: contents.append(post) container.contents = contents def postcurrent(self, next): "Postprocess the current element taking into account next and last." stage = self.stages.getstage(self.current) if not stage: return self.current return stage.postprocess(self.last, self.current, next) class StageDict(object): "A dictionary of stages corresponding to classes" def __init__(self, classes, postprocessor): "Instantiate an element from elyxer.each class and store as a dictionary" instances = self.instantiate(classes, postprocessor) self.stagedict = dict([(x.processedclass, x) for x in instances]) def instantiate(self, classes, postprocessor): "Instantiate an element from elyxer.each class" stages = [x.__new__(x) for x in classes] for element in stages: element.__init__() element.postprocessor = postprocessor return stages def getstage(self, element): "Get the stage for a given element, if the type is in the dict" if not element.__class__ in self.stagedict: return None return self.stagedict[element.__class__] class Label(Link): "A label to be referenced" names = dict() lastlayout = None def __init__(self): Link.__init__(self) self.lastnumbered = None def process(self): "Process a label container." key = self.getparameter('name') self.create(' ', key) self.lastnumbered = Label.lastlayout def create(self, text, key, type = 'Label'): "Create the label for a given key." self.key = key self.complete(text, anchor = key, type = type) Label.names[key] = self if key in Reference.references: for reference in Reference.references[key]: reference.destination = self return self def findpartkey(self): "Get the part key for the latest numbered container seen." numbered = self.numbered(self) if numbered and numbered.partkey: return numbered.partkey return '' def numbered(self, container): "Get the numbered container for the label." if container.partkey: return container if not container.parent: if self.lastnumbered: return self.lastnumbered return None return self.numbered(container.parent) def __unicode__(self): "Return a printable representation." if not hasattr(self, 'key'): return 'Unnamed label' return 'Label ' + self.key class Reference(Link): "A reference to a label." references = dict() key = 'none' def process(self): "Read the reference and set the arrow." self.key = self.getparameter('reference') if self.key in Label.names: self.direction = u'↑' label = Label.names[self.key] else: self.direction = u'↓' label = Label().complete(' ', self.key, 'preref') self.destination = label self.formatcontents() if not self.key in Reference.references: Reference.references[self.key] = [] Reference.references[self.key].append(self) def formatcontents(self): "Format the reference contents." formatkey = self.getparameter('LatexCommand') if not formatkey: formatkey = 'ref' self.formatted = u'↕' if formatkey in StyleConfig.referenceformats: self.formatted = StyleConfig.referenceformats[formatkey] else: Trace.error('Unknown reference format ' + formatkey) self.replace(u'↕', self.direction) self.replace('#', '1') self.replace('on-page', Translator.translate('on-page')) partkey = self.destination.findpartkey() # only if partkey and partkey.number are not null, send partkey.number self.replace('@', partkey and partkey.number) self.replace(u'¶', partkey and partkey.tocentry) if not '$' in self.formatted or not partkey or not partkey.titlecontents: # there is a $ left, but it should go away on preprocessing self.contents = [Constant(self.formatted)] return pieces = self.formatted.split('$') self.contents = [Constant(pieces[0])] for piece in pieces[1:]: self.contents += partkey.titlecontents self.contents.append(Constant(piece)) def replace(self, key, value): "Replace a key in the format template with a value." if not key in self.formatted: return if not value: value = '' self.formatted = self.formatted.replace(key, value) def __unicode__(self): "Return a printable representation." return 'Reference ' + self.key class HeaderParser(Parser): "Parses the LyX header" def parse(self, reader): "Parse header parameters into a dictionary, return the preamble." contents = [] self.parseending(reader, lambda: self.parseline(reader, contents)) # skip last line reader.nextline() return contents def parseline(self, reader, contents): "Parse a single line as a parameter or as a start" line = reader.currentline() if line.startswith(HeaderConfig.parameters['branch']): self.parsebranch(reader) return elif line.startswith(HeaderConfig.parameters['lstset']): LstParser().parselstset(reader) return elif line.startswith(HeaderConfig.parameters['beginpreamble']): contents.append(self.factory.createcontainer(reader)) return # no match self.parseparameter(reader) def parsebranch(self, reader): "Parse all branch definitions." branch = reader.currentline().split()[1] reader.nextline() subparser = HeaderParser().complete(HeaderConfig.parameters['endbranch']) subparser.parse(reader) options = BranchOptions(branch) for key in subparser.parameters: options.set(key, subparser.parameters[key]) Options.branches[branch] = options def complete(self, ending): "Complete the parser with the given ending." self.ending = ending return self class PreambleParser(Parser): "A parser for the LyX preamble." preamble = [] def parse(self, reader): "Parse the full preamble with all statements." self.ending = HeaderConfig.parameters['endpreamble'] self.parseending(reader, lambda: self.parsepreambleline(reader)) return [] def parsepreambleline(self, reader): "Parse a single preamble line." PreambleParser.preamble.append(reader.currentline()) reader.nextline() class LstParser(object): "Parse global and local lstparams." globalparams = dict() def parselstset(self, reader): "Parse a declaration of lstparams in lstset." paramtext = self.extractlstset(reader) if not '{' in paramtext: Trace.error('Missing opening bracket in lstset: ' + paramtext) return lefttext = paramtext.split('{')[1] croppedtext = lefttext[:-1] LstParser.globalparams = self.parselstparams(croppedtext) def extractlstset(self, reader): "Extract the global lstset parameters." paramtext = '' while not reader.finished(): paramtext += reader.currentline() reader.nextline() if paramtext.endswith('}'): return paramtext Trace.error('Could not find end of \\lstset settings; aborting') def parsecontainer(self, container): "Parse some lstparams from elyxer.a container." container.lstparams = LstParser.globalparams.copy() paramlist = container.getparameterlist('lstparams') container.lstparams.update(self.parselstparams(paramlist)) def parselstparams(self, paramlist): "Process a number of lstparams from elyxer.a list." paramdict = dict() for param in paramlist: if not '=' in param: if len(param.strip()) > 0: Trace.error('Invalid listing parameter ' + param) else: key, value = param.split('=', 1) paramdict[key] = value return paramdict import datetime import os import codecs class BulkFile(object): "A file to treat in bulk" encodings = ['utf-8','Cp1252'] def __init__(self, filename): self.filename = filename self.temp = self.filename + '.temp' def readall(self): "Read the whole file" for encoding in BulkFile.encodings: try: return self.readcodec(encoding) except UnicodeDecodeError: pass Trace.error('No suitable encoding for ' + self.filename) return [] def readcodec(self, encoding): "Read the whole file with the given encoding" filein = codecs.open(self.filename, 'rU', encoding) lines = filein.readlines() result = [] for line in lines: result.append(line.strip('\r\n') + '\n') filein.close() return result def getfiles(self): "Get reader and writer for a file name" reader = LineReader(self.filename) writer = LineWriter(self.temp) return reader, writer def swaptemp(self): "Swap the temp file for the original" os.chmod(self.temp, os.stat(self.filename).st_mode) os.rename(self.temp, self.filename) def __unicode__(self): "Get the unicode representation" return 'file ' + self.filename class HTMLTemplate(object): "A template for HTML generation." current = None def getheader(self): "Get the header (before content) of the template." return [] def convertheader(self): "Convert the header and all variables." return self.convert(self.getheader()) def convertfooter(self): "Convert the footer and all variables." return self.convert(self.getfooter()) def convert(self, html): "Convert a bit of HTML replacing all variables." varmap = VariableMap() for index, line in enumerate(html): if '\n'] def getfooter(self): "Get the raw footer." return ['\n\n'] class FileTemplate(HTMLTemplate): "A template read from elyxer.a file." divider = '' def read(self): "Read the file, separate header and footer." self.header = [] lines = [] for line in self.templatelines(): if FileTemplate.divider == line: self.header = lines lines = [] else: lines.append(line) if self.header == []: Trace.error('No ' + FileTemplate.divider + ' in template') self.header = lines lines = [] self.footer = lines return self def templatelines(self): "Read all lines in the template, separate content into its own line." template = BulkFile(Options.template).readall() for line in template: if not FileTemplate.divider in line: yield line else: split = line.split(FileTemplate.divider) for part in split[:-1]: yield part yield FileTemplate.divider yield split[-1] def getheader(self): "Return the header (before content)." return self.header def getfooter(self): "Return the footer (after the content)." return self.footer class DefaultTemplate(HTMLTemplate): "The default HTML template when not configured." def getheader(self): "Get the default header (before content)." html = [] if not Options.html: html.append(u'"?>\n') html.append(u'\n') html.append(u'\n') else: html.append(u'\n') html.append(u'\n') html.append(u'\n') html.append(u'\n') html.append(u'\n') html.append(u'\n') html += self.getcss() html.append(u'<!--$title-->\n') if Options.jsmath: html.append(u'\n') html.append(u'\n') if Options.mathjax: if Options.mathjax == 'remote': html.append(u'\n') else: html.append(u'\n') html.append('\n') html.append('\n') html.append('
\n') if Options.jsmath or Options.mathjax: if Options.mathjax: html.append(u'\n') html.append(u'\n') return html def getcss(self): "Get the CSS headers, both linked and embedded." html = [] for cssdoc in Options.css: if cssdoc != '': html.append(u'\n') for cssfile in Options.embedcss: html.append(u'\n') return html def getfooter(self): "Get the default footer (after content)." html = [] html.append('\n') footer = self.createfooter() if len(footer) > 0: html.append('\n') html += footer html.append('
\n') html.append('\n') html.append('\n') return html def createfooter(self): "Create the footer proper." html = [] if Options.copyright: html.append('\n') if Options.nofooter: return html html.append('\n') return html class VariableMap(object): "A map with all replacement variables." def __init__(self): self.variables = dict() self.variables['title'] = DocumentTitle().getvalue() self.variables['author'] = DocumentAuthor().getvalue() self.variables['version'] = GeneralConfig.version['number'] + ' (' \ + GeneralConfig.version['date'] + ')' self.variables['year'] = unicode(datetime.date.today().year) self.variables['date'] = datetime.date.today().isoformat() self.variables['datetime'] = datetime.datetime.now().isoformat() self.variables['css'] = Options.css[0] if Options.iso885915: self.variables['encoding'] = 'ISO-8859-1' else: self.variables['encoding'] = 'UTF-8' if Options.jsmath: self.variables['jsmath'] = Options.jsmath if Options.mathjax: self.variables['mathjax'] = Options.mathjax def replace(self, line): "Replace all variables in a line." result = '' pos = TextPosition(line) while not pos.finished(): if pos.checkskip(''): Trace.error('Weird template format in ' + line) return value class DocumentTitle(object): "The title of the whole document." title = None def getvalue(self): "Return the correct title from elyxer.the option or the PDF title." if Options.title: return Options.title if DocumentTitle.title: return DocumentTitle.title if DocumentParameters.pdftitle: return DocumentParameters.pdftitle return 'Converted document' class DocumentAuthor(object): "The author of the document." author = '' def appendauthor(cls, authorline): "Append a line with author information." cls.author += authorline appendauthor = classmethod(appendauthor) def getvalue(self): "Get the document author." return DocumentAuthor.author class HeaderOutput(ContainerOutput): "Returns the HTML headers" def gethtml(self, container): "Return a constant header" return HTMLTemplate.get().convertheader() class FooterOutput(ContentsOutput): "Return the HTML code for the footer" def gethtml(self, container): "Footer HTML" contents = ContentsOutput.gethtml(self, container) return contents + HTMLTemplate.get().convertfooter() class InsetText(Container): "An inset of text in a lyx file" def __init__(self): self.parser = BoundedParser() self.output = ContentsOutput() class Inset(Container): "A generic inset in a LyX document" def __init__(self): self.contents = list() self.parser = InsetParser() self.output = TaggedOutput().setbreaklines(True) def process(self): self.type = self.header[1] self.output.tag = 'span class="' + self.type + '"' def __unicode__(self): return 'Inset of type ' + self.type class NewlineInset(Newline): "A newline or line break in an inset" def __init__(self): self.parser = InsetParser() self.output = FixedOutput() class NewPageInset(NewPage): "A new page command." def __init__(self): self.parser = InsetParser() self.output = FixedOutput() class Branch(Container): "A branch within a LyX document" def __init__(self): self.parser = InsetParser() self.output = TaggedOutput().settag('span class="branch"', True) def process(self): "Disable inactive branches" self.branch = self.header[2] if not self.isactive(): Trace.debug('Branch ' + self.branch + ' not active') self.output = EmptyOutput() def isactive(self): "Check if the branch is active" if not self.branch in Options.branches: Trace.error('Invalid branch ' + self.branch) return True branch = Options.branches[self.branch] return branch.isselected() class ShortTitle(Container): "A short title to display (always hidden)" def __init__(self): self.parser = InsetParser() self.output = EmptyOutput() class FlexInset(Container): "A flexible inset, generic version." def __init__(self): self.parser = InsetParser() self.output = TaggedOutput().settag('span', False) def process(self): "Set the correct flex tag." self.type = self.header[2] if self.type in TagConfig.flex: self.output.settag(TagConfig.flex[self.type], False) else: self.output.settag('span class="' + self.type + '"', False) class InfoInset(Container): "A LyX Info inset" def __init__(self): self.parser = InsetParser() self.output = TaggedOutput().settag('span class="Info"', False) def process(self): "Set the shortcut as text" self.type = self.getparameter('type') self.contents = [Constant(self.getparameter('arg'))] class BoxInset(Container): "A box inset" def __init__(self): self.parser = InsetParser() self.output = TaggedOutput().settag('div', True) def process(self): "Set the correct tag" self.type = self.header[2] self.output.settag('div class="' + self.type + '"', True) ContainerSize().readparameters(self).addstyle(self) class PhantomText(Container): "A line of invisible text (white over white)." def __init__(self): self.parser = InsetParser() self.output = TaggedOutput().settag('span class="phantom"', False) class LineInset(LyXLine): "A LaTeX ruler, but parsed as an inset." def __init__(self): self.parser = InsetParser() self.output = FixedOutput() class Caption(Container): "A caption for a figure or a table" def __init__(self): self.parser = InsetParser() self.output = TaggedOutput().settag('div class="caption"', True) def create(self, message): "Create a caption with a given message." self.contents = [Constant(message)] return self class ScriptInset(Container): "Sub- or super-script in an inset." def __init__(self): self.parser = InsetParser() self.output = TaggedOutput().settag('span', False) def process(self): "Set the correct script tag." self.type = self.header[2] if not self.type in TagConfig.script: Trace.error('Unknown script type ' + self.type) return self.output.settag(TagConfig.script[self.type], False) class PartKey(object): "A key to identify a given document part (chapter, section...)." partkey = None tocentry = None anchortext = None number = None filename = None titlecontents = None header = False def __init__(self): self.level = 0 def createindex(self, partkey): "Create a part key for an index page." self.partkey = partkey self.tocentry = partkey self.filename = partkey return self def createfloat(self, float): "Create a part key for a float." self.number = NumberGenerator.chaptered.generate(float.type) self.partkey = Translator.translate('float-' + float.type) + self.number if Options.notoclabels: self.tocentry = self.number else: self.tocentry = self.partkey self.readtitle(float) return self def createsubfloat(self, number): "Create the part key for a subfloat." self.partkey = '(' + number + ')' self.number = number return self def createformula(self, number): "Create the part key for a formula." self.number = number self.partkey = 'formula-' + number self.tocentry = '(' + number + ')' return self def createheader(self, headorfooter): "Create the part key for a header or footer." self.partkey = headorfooter self.tocentry = None self.header = True return self def createanchor(self, partkey): "Create an anchor for the page." self.partkey = partkey self.tocentry = partkey self.header = True return self def createmain(self): "Create the part key for the main page." self.partkey = '' self.tocentry = DocumentTitle().getvalue() return self def addtoclabel(self, container): "Create the label for the TOC, and add it to the container." labeltext = '' if self.anchortext: labeltext = self.anchortext container.contents.insert(0, Separator(u' ')) label = Label().create(labeltext, self.partkey, type='toc') container.contents.insert(0, label) def readtitle(self, container): "Read the title of the TOC entry." shorttitles = container.searchall(ShortTitle) if len(shorttitles) > 0: self.titlecontents = [] for shorttitle in shorttitles: self.titlecontents += shorttitle.contents return extractor = ContainerExtractor(TOCConfig.extracttitle) captions = container.searchall(Caption) if len(captions) == 1: self.titlecontents = extractor.extract(captions[0]) return self.titlecontents = extractor.extract(container) def __unicode__(self): "Return a printable representation." return 'Part key for ' + self.partkey class LayoutPartKey(PartKey): "The part key for a layout." generator = NumberGenerator() def create(self, layout): "Set the layout for which we are creating the part key." self.processtype(layout.type) self.readtitle(layout) return self def processtype(self, type): "Process the layout type." self.level = self.generator.getlevel(type) self.number = self.generator.generate(type) anchortype = self.getanchortype(type) self.partkey = 'toc-' + anchortype + '-' + self.number self.tocentry = self.gettocentry(type) self.filename = self.getfilename(type) if self.generator.isnumbered(type): if not self.tocentry: self.tocentry = '' else: self.tocentry += ' ' self.tocentry += self.number self.anchortext = self.getanchortext(type) def getanchortype(self, type): "Get the type for the anchor." parttype = self.generator.getparttype(type) if self.generator.isunordered(type): parttype += '-' return parttype def gettocentry(self, type): "Get the entry for the TOC: Chapter, Section..." if Options.notoclabels: return '' return Translator.translate(self.generator.getparttype(type)) def addtotocentry(self, text): "Add some text to the tocentry; create if None." if not self.tocentry: self.tocentry = '' self.tocentry += text def getanchortext(self, type): "Get the text for the anchor given to a layout type." if self.generator.isunique(type): return self.tocentry + '.' return self.number def getfilename(self, type): "Get the filename to be used if splitpart is active." if self.level == Options.splitpart and self.generator.isnumbered(type): return self.number if self.level <= Options.splitpart: return self.partkey.replace('toc-', '') return None def needspartkey(self, layout): "Find out if a layout needs a part key." if self.generator.isunique(layout.type): return True return self.generator.isinordered(layout.type) def __unicode__(self): "Get a printable representation." return 'Part key for layout ' + self.tocentry class PartKeyGenerator(object): "Number a layout with the relevant attributes." partkeyed = [] layoutpartkey = LayoutPartKey() def forlayout(cls, layout): "Get the part key for a layout." if layout.hasemptyoutput(): return None if not cls.layoutpartkey.needspartkey(layout): return None Label.lastlayout = layout cls.partkeyed.append(layout) return LayoutPartKey().create(layout) def forindex(cls, index): "Get the part key for an index or nomenclature." if index.hasemptyoutput(): return None cls.partkeyed.append(index) return PartKey().createindex(index.name) forlayout = classmethod(forlayout) forindex = classmethod(forindex) import unicodedata import urllib class FormulaParser(Parser): "Parses a formula" def parseheader(self, reader): "See if the formula is inlined" self.begin = reader.linenumber + 1 type = self.parsetype(reader) if not type: reader.nextline() type = self.parsetype(reader) if not type: Trace.error('Unknown formula type in ' + reader.currentline().strip()) return ['unknown'] return [type] def parsetype(self, reader): "Get the formula type from the first line." if reader.currentline().find(FormulaConfig.starts['simple']) >= 0: return 'inline' if reader.currentline().find(FormulaConfig.starts['complex']) >= 0: return 'block' if reader.currentline().find(FormulaConfig.starts['unnumbered']) >= 0: return 'block' if reader.currentline().find(FormulaConfig.starts['beginbefore']) >= 0: return 'numbered' return None def parse(self, reader): "Parse the formula until the end" formula = self.parseformula(reader) while not reader.currentline().startswith(self.ending): stripped = reader.currentline().strip() if len(stripped) > 0: Trace.error('Unparsed formula line ' + stripped) reader.nextline() reader.nextline() return formula def parseformula(self, reader): "Parse the formula contents" simple = FormulaConfig.starts['simple'] if simple in reader.currentline(): rest = reader.currentline().split(simple, 1)[1] if simple in rest: # formula is $...$ return self.parsesingleliner(reader, simple, simple) # formula is multiline $...$ return self.parsemultiliner(reader, simple, simple) if FormulaConfig.starts['complex'] in reader.currentline(): # formula of the form \[...\] return self.parsemultiliner(reader, FormulaConfig.starts['complex'], FormulaConfig.endings['complex']) beginbefore = FormulaConfig.starts['beginbefore'] beginafter = FormulaConfig.starts['beginafter'] if beginbefore in reader.currentline(): if reader.currentline().strip().endswith(beginafter): current = reader.currentline().strip() endsplit = current.split(beginbefore)[1].split(beginafter) startpiece = beginbefore + endsplit[0] + beginafter endbefore = FormulaConfig.endings['endbefore'] endafter = FormulaConfig.endings['endafter'] endpiece = endbefore + endsplit[0] + endafter return startpiece + self.parsemultiliner(reader, startpiece, endpiece) + endpiece Trace.error('Missing ' + beginafter + ' in ' + reader.currentline()) return '' begincommand = FormulaConfig.starts['command'] beginbracket = FormulaConfig.starts['bracket'] if begincommand in reader.currentline() and beginbracket in reader.currentline(): endbracket = FormulaConfig.endings['bracket'] return self.parsemultiliner(reader, beginbracket, endbracket) Trace.error('Formula beginning ' + reader.currentline() + ' is unknown') return '' def parsesingleliner(self, reader, start, ending): "Parse a formula in one line" line = reader.currentline().strip() if not start in line: Trace.error('Line ' + line + ' does not contain formula start ' + start) return '' if not line.endswith(ending): Trace.error('Formula ' + line + ' does not end with ' + ending) return '' index = line.index(start) rest = line[index + len(start):-len(ending)] reader.nextline() return rest def parsemultiliner(self, reader, start, ending): "Parse a formula in multiple lines" formula = '' line = reader.currentline() if not start in line: Trace.error('Line ' + line.strip() + ' does not contain formula start ' + start) return '' index = line.index(start) line = line[index + len(start):].strip() while not line.endswith(ending): formula += line + '\n' reader.nextline() line = reader.currentline() formula += line[:-len(ending)] reader.nextline() return formula class MacroParser(FormulaParser): "A parser for a formula macro." def parseheader(self, reader): "See if the formula is inlined" self.begin = reader.linenumber + 1 return ['inline'] def parse(self, reader): "Parse the formula until the end" formula = self.parsemultiliner(reader, self.parent.start, self.ending) reader.nextline() return formula class FormulaBit(Container): "A bit of a formula" type = None size = 1 original = '' def __init__(self): "The formula bit type can be 'alpha', 'number', 'font'." self.contents = [] self.output = ContentsOutput() def setfactory(self, factory): "Set the internal formula factory." self.factory = factory return self def add(self, bit): "Add any kind of formula bit already processed" self.contents.append(bit) self.original += bit.original bit.parent = self def skiporiginal(self, string, pos): "Skip a string and add it to the original formula" self.original += string if not pos.checkskip(string): Trace.error('String ' + string + ' not at ' + pos.identifier()) def computesize(self): "Compute the size of the bit as the max of the sizes of all contents." if len(self.contents) == 0: return 1 self.size = max([element.size for element in self.contents]) return self.size def clone(self): "Return a copy of itself." return self.factory.parseformula(self.original) def __unicode__(self): "Get a string representation" return self.__class__.__name__ + ' read in ' + self.original class TaggedBit(FormulaBit): "A tagged string in a formula" def constant(self, constant, tag): "Set the constant and the tag" self.output = TaggedOutput().settag(tag) self.add(FormulaConstant(constant)) return self def complete(self, contents, tag, breaklines = False): "Set the constant and the tag" self.contents = contents self.output = TaggedOutput().settag(tag, breaklines) return self def selfcomplete(self, tag): "Set the self-closing tag, no contents (as in
)." self.output = TaggedOutput().settag(tag, empty = True) return self class FormulaConstant(Constant): "A constant string in a formula" def __init__(self, string): "Set the constant string" Constant.__init__(self, string) self.original = string self.size = 1 self.type = None def computesize(self): "Compute the size of the constant: always 1." return self.size def clone(self): "Return a copy of itself." return FormulaConstant(self.original) def __unicode__(self): "Return a printable representation." return 'Formula constant: ' + self.string class RawText(FormulaBit): "A bit of text inside a formula" def detect(self, pos): "Detect a bit of raw text" return pos.current().isalpha() def parsebit(self, pos): "Parse alphabetic text" alpha = pos.globalpha() self.add(FormulaConstant(alpha)) self.type = 'alpha' class FormulaSymbol(FormulaBit): "A symbol inside a formula" modified = FormulaConfig.modified unmodified = FormulaConfig.unmodified['characters'] def detect(self, pos): "Detect a symbol" if pos.current() in FormulaSymbol.unmodified: return True if pos.current() in FormulaSymbol.modified: return True return False def parsebit(self, pos): "Parse the symbol" if pos.current() in FormulaSymbol.unmodified: self.addsymbol(pos.current(), pos) return if pos.current() in FormulaSymbol.modified: self.addsymbol(FormulaSymbol.modified[pos.current()], pos) return Trace.error('Symbol ' + pos.current() + ' not found') def addsymbol(self, symbol, pos): "Add a symbol" self.skiporiginal(pos.current(), pos) self.contents.append(FormulaConstant(symbol)) class FormulaNumber(FormulaBit): "A string of digits in a formula" def detect(self, pos): "Detect a digit" return pos.current().isdigit() def parsebit(self, pos): "Parse a bunch of digits" digits = pos.glob(lambda: pos.current().isdigit()) self.add(FormulaConstant(digits)) self.type = 'number' class Comment(FormulaBit): "A LaTeX comment: % to the end of the line." start = FormulaConfig.starts['comment'] def detect(self, pos): "Detect the %." return pos.current() == self.start def parsebit(self, pos): "Parse to the end of the line." self.original += pos.globincluding('\n') class WhiteSpace(FormulaBit): "Some white space inside a formula." def detect(self, pos): "Detect the white space." return pos.current().isspace() def parsebit(self, pos): "Parse all whitespace." self.original += pos.skipspace() def __unicode__(self): "Return a printable representation." return 'Whitespace: *' + self.original + '*' class Bracket(FormulaBit): "A {} bracket inside a formula" start = FormulaConfig.starts['bracket'] ending = FormulaConfig.endings['bracket'] def __init__(self): "Create a (possibly literal) new bracket" FormulaBit.__init__(self) self.inner = None def detect(self, pos): "Detect the start of a bracket" return pos.checkfor(self.start) def parsebit(self, pos): "Parse the bracket" self.parsecomplete(pos, self.innerformula) return self def parsetext(self, pos): "Parse a text bracket" self.parsecomplete(pos, self.innertext) return self def parseliteral(self, pos): "Parse a literal bracket" self.parsecomplete(pos, self.innerliteral) return self def parsecomplete(self, pos, innerparser): "Parse the start and end marks" if not pos.checkfor(self.start): Trace.error('Bracket should start with ' + self.start + ' at ' + pos.identifier()) return None self.skiporiginal(self.start, pos) pos.pushending(self.ending) innerparser(pos) self.original += pos.popending(self.ending) self.computesize() def innerformula(self, pos): "Parse a whole formula inside the bracket" while not pos.finished(): self.add(self.factory.parseany(pos)) def innertext(self, pos): "Parse some text inside the bracket, following textual rules." specialchars = FormulaConfig.symbolfunctions.keys() specialchars.append(FormulaConfig.starts['command']) specialchars.append(FormulaConfig.starts['bracket']) specialchars.append(Comment.start) while not pos.finished(): if pos.current() in specialchars: self.add(self.factory.parseany(pos)) if pos.checkskip(' '): self.original += ' ' else: self.add(FormulaConstant(pos.skipcurrent())) def innerliteral(self, pos): "Parse a literal inside the bracket, which does not generate HTML." self.literal = '' while not pos.finished() and not pos.current() == self.ending: if pos.current() == self.start: self.parseliteral(pos) else: self.literal += pos.skipcurrent() self.original += self.literal class SquareBracket(Bracket): "A [] bracket inside a formula" start = FormulaConfig.starts['squarebracket'] ending = FormulaConfig.endings['squarebracket'] def clone(self): "Return a new square bracket with the same contents." bracket = SquareBracket() bracket.contents = self.contents return bracket class MathsProcessor(object): "A processor for a maths construction inside the FormulaProcessor." def process(self, contents, index): "Process an element inside a formula." Trace.error('Unimplemented process() in ' + unicode(self)) def __unicode__(self): "Return a printable description." return 'Maths processor ' + self.__class__.__name__ class FormulaProcessor(object): "A processor specifically for formulas." processors = [] def process(self, bit): "Process the contents of every formula bit, recursively." self.processcontents(bit) self.processinsides(bit) self.traversewhole(bit) def processcontents(self, bit): "Process the contents of a formula bit." if not isinstance(bit, FormulaBit): return bit.process() for element in bit.contents: self.processcontents(element) def processinsides(self, bit): "Process the insides (limits, brackets) in a formula bit." if not isinstance(bit, FormulaBit): return for index, element in enumerate(bit.contents): for processor in self.processors: processor.process(bit.contents, index) # continue with recursive processing self.processinsides(element) def traversewhole(self, formula): "Traverse over the contents to alter variables and space units." last = None for bit, contents in self.traverse(formula): if bit.type == 'alpha': self.italicize(bit, contents) elif bit.type == 'font' and last and last.type == 'number': bit.contents.insert(0, FormulaConstant(u' ')) last = bit def traverse(self, bit): "Traverse a formula and yield a flattened structure of (bit, list) pairs." for element in bit.contents: if hasattr(element, 'type') and element.type: yield (element, bit.contents) elif isinstance(element, FormulaBit): for pair in self.traverse(element): yield pair def italicize(self, bit, contents): "Italicize the given bit of text." index = contents.index(bit) contents[index] = TaggedBit().complete([bit], 'i') class Formula(Container): "A LaTeX formula" def __init__(self): self.parser = FormulaParser() self.output = TaggedOutput().settag('span class="formula"') def process(self): "Convert the formula to tags" if self.header[0] == 'inline': DocumentParameters.displaymode = False else: DocumentParameters.displaymode = True self.output.settag('div class="formula"', True) if Options.jsmath: self.jsmath() elif Options.mathjax: self.mathjax() elif Options.googlecharts: self.googlecharts() else: self.classic() def jsmath(self): "Make the contents for jsMath." if self.header[0] != 'inline': self.output = TaggedOutput().settag('div class="math"') else: self.output = TaggedOutput().settag('span class="math"') self.contents = [Constant(self.parsed)] def mathjax(self): "Make the contents for MathJax." self.output.tag = 'span class="MathJax_Preview"' tag = 'script type="math/tex' if self.header[0] != 'inline': tag += ';mode=display' self.contents = [TaggedText().constant(self.parsed, tag + '"', True)] def googlecharts(self): "Make the contents using Google Charts http://code.google.com/apis/chart/." url = FormulaConfig.urls['googlecharts'] + urllib.quote_plus(self.parsed) img = '' + self.parsed + '' self.contents = [Constant(img)] def classic(self): "Make the contents using classic output generation with XHTML and CSS." whole = FormulaFactory().parseformula(self.parsed) FormulaProcessor().process(whole) whole.parent = self self.contents = [whole] def parse(self, pos): "Parse using a parse position instead of self.parser." if pos.checkskip('$$'): self.parsedollarblock(pos) elif pos.checkskip('$'): self.parsedollarinline(pos) elif pos.checkskip('\\('): self.parseinlineto(pos, '\\)') elif pos.checkskip('\\['): self.parseblockto(pos, '\\]') else: pos.error('Unparseable formula') self.process() return self def parsedollarinline(self, pos): "Parse a $...$ formula." self.header = ['inline'] self.parsedollar(pos) def parsedollarblock(self, pos): "Parse a $$...$$ formula." self.header = ['block'] self.parsedollar(pos) if not pos.checkskip('$'): pos.error('Formula should be $$...$$, but last $ is missing.') def parsedollar(self, pos): "Parse to the next $." pos.pushending('$') self.parsed = pos.globexcluding('$') pos.popending('$') def parseinlineto(self, pos, limit): "Parse a \\(...\\) formula." self.header = ['inline'] self.parseupto(pos, limit) def parseblockto(self, pos, limit): "Parse a \\[...\\] formula." self.header = ['block'] self.parseupto(pos, limit) def parseupto(self, pos, limit): "Parse a formula that ends with the given command." pos.pushending(limit) self.parsed = pos.glob(lambda: True) pos.popending(limit) def __unicode__(self): "Return a printable representation." if self.partkey and self.partkey.number: return 'Formula (' + self.partkey.number + ')' return 'Unnumbered formula' class WholeFormula(FormulaBit): "Parse a whole formula" def detect(self, pos): "Not outside the formula is enough." return not pos.finished() def parsebit(self, pos): "Parse with any formula bit" while not pos.finished(): self.add(self.factory.parseany(pos)) class FormulaFactory(object): "Construct bits of formula" # bit types will be appended later types = [FormulaSymbol, RawText, FormulaNumber, Bracket, Comment, WhiteSpace] skippedtypes = [Comment, WhiteSpace] defining = False def __init__(self): "Initialize the map of instances." self.instances = dict() def detecttype(self, type, pos): "Detect a bit of a given type." if pos.finished(): return False return self.instance(type).detect(pos) def instance(self, type): "Get an instance of the given type." if not type in self.instances or not self.instances[type]: self.instances[type] = self.create(type) return self.instances[type] def create(self, type): "Create a new formula bit of the given type." return Cloner.create(type).setfactory(self) def clearskipped(self, pos): "Clear any skipped types." while not pos.finished(): if not self.skipany(pos): return return def skipany(self, pos): "Skip any skipped types." for type in self.skippedtypes: if self.instance(type).detect(pos): return self.parsetype(type, pos) return None def parseany(self, pos): "Parse any formula bit at the current location." for type in self.types + self.skippedtypes: if self.detecttype(type, pos): return self.parsetype(type, pos) Trace.error('Unrecognized formula at ' + pos.identifier()) return FormulaConstant(pos.skipcurrent()) def parsetype(self, type, pos): "Parse the given type and return it." bit = self.instance(type) self.instances[type] = None returnedbit = bit.parsebit(pos) if returnedbit: return returnedbit.setfactory(self) return bit def parseformula(self, formula): "Parse a string of text that contains a whole formula." pos = TextPosition(formula) whole = self.create(WholeFormula) if whole.detect(pos): whole.parsebit(pos) return whole # no formula found if not pos.finished(): Trace.error('Unknown formula at: ' + pos.identifier()) whole.add(TaggedBit().constant(formula, 'span class="unknown"')) return whole class FormulaCommand(FormulaBit): "A LaTeX command inside a formula" types = [] start = FormulaConfig.starts['command'] commandmap = None def detect(self, pos): "Find the current command." return pos.checkfor(FormulaCommand.start) def parsebit(self, pos): "Parse the command." command = self.extractcommand(pos) bit = self.parsewithcommand(command, pos) if bit: return bit if command.startswith('\\up') or command.startswith('\\Up'): upgreek = self.parseupgreek(command, pos) if upgreek: return upgreek if not self.factory.defining: Trace.error('Unknown command ' + command) self.output = TaggedOutput().settag('span class="unknown"') self.add(FormulaConstant(command)) return None def parsewithcommand(self, command, pos): "Parse the command type once we have the command." for type in FormulaCommand.types: if command in type.commandmap: return self.parsecommandtype(command, type, pos) return None def parsecommandtype(self, command, type, pos): "Parse a given command type." bit = self.factory.create(type) bit.setcommand(command) returned = bit.parsebit(pos) if returned: return returned return bit def extractcommand(self, pos): "Extract the command from elyxer.the current position." if not pos.checkskip(FormulaCommand.start): pos.error('Missing command start ' + FormulaCommand.start) return if pos.finished(): return self.emptycommand(pos) if pos.current().isalpha(): # alpha command command = FormulaCommand.start + pos.globalpha() # skip mark of short command pos.checkskip('*') return command # symbol command return FormulaCommand.start + pos.skipcurrent() def emptycommand(self, pos): """Check for an empty command: look for command disguised as ending. Special case against '{ \{ \} }' situation.""" command = '' if not pos.isout(): ending = pos.nextending() if ending and pos.checkskip(ending): command = ending return FormulaCommand.start + command def parseupgreek(self, command, pos): "Parse the Greek \\up command.." if len(command) < 4: return None if command.startswith('\\up'): upcommand = '\\' + command[3:] elif pos.checkskip('\\Up'): upcommand = '\\' + command[3:4].upper() + command[4:] else: Trace.error('Impossible upgreek command: ' + command) return upgreek = self.parsewithcommand(upcommand, pos) if upgreek: upgreek.type = 'font' return upgreek class CommandBit(FormulaCommand): "A formula bit that includes a command" def setcommand(self, command): "Set the command in the bit" self.command = command if self.commandmap: self.original += command self.translated = self.commandmap[self.command] def parseparameter(self, pos): "Parse a parameter at the current position" self.factory.clearskipped(pos) if pos.finished(): return None parameter = self.factory.parseany(pos) self.add(parameter) return parameter def parsesquare(self, pos): "Parse a square bracket" self.factory.clearskipped(pos) if not self.factory.detecttype(SquareBracket, pos): return None bracket = self.factory.parsetype(SquareBracket, pos) self.add(bracket) return bracket def parseliteral(self, pos): "Parse a literal bracket." self.factory.clearskipped(pos) if not self.factory.detecttype(Bracket, pos): if not pos.isvalue(): Trace.error('No literal parameter found at: ' + pos.identifier()) return None return pos.globvalue() bracket = Bracket().setfactory(self.factory) self.add(bracket.parseliteral(pos)) return bracket.literal def parsesquareliteral(self, pos): "Parse a square bracket literally." self.factory.clearskipped(pos) if not self.factory.detecttype(SquareBracket, pos): return None bracket = SquareBracket().setfactory(self.factory) self.add(bracket.parseliteral(pos)) return bracket.literal def parsetext(self, pos): "Parse a text parameter." self.factory.clearskipped(pos) if not self.factory.detecttype(Bracket, pos): Trace.error('No text parameter for ' + self.command) return None bracket = Bracket().setfactory(self.factory).parsetext(pos) self.add(bracket) return bracket class EmptyCommand(CommandBit): "An empty command (without parameters)" commandmap = FormulaConfig.commands def parsebit(self, pos): "Parse a command without parameters" self.contents = [FormulaConstant(self.translated)] class SpacedCommand(CommandBit): "An empty command which should have math spacing in formulas." commandmap = FormulaConfig.spacedcommands def parsebit(self, pos): "Place as contents the command translated and spaced." self.contents = [FormulaConstant(u' ' + self.translated + u' ')] class AlphaCommand(EmptyCommand): "A command without paramters whose result is alphabetical" commandmap = FormulaConfig.alphacommands def parsebit(self, pos): "Parse the command and set type to alpha" EmptyCommand.parsebit(self, pos) self.type = 'alpha' class OneParamFunction(CommandBit): "A function of one parameter" commandmap = FormulaConfig.onefunctions simplified = False def parsebit(self, pos): "Parse a function with one parameter" self.output = TaggedOutput().settag(self.translated) self.parseparameter(pos) self.simplifyifpossible() def simplifyifpossible(self): "Try to simplify to a single character." if self.original in self.commandmap: self.output = FixedOutput() self.html = [self.commandmap[self.original]] self.simplified = True class SymbolFunction(CommandBit): "Find a function which is represented by a symbol (like _ or ^)" commandmap = FormulaConfig.symbolfunctions def detect(self, pos): "Find the symbol" return pos.current() in SymbolFunction.commandmap def parsebit(self, pos): "Parse the symbol" self.setcommand(pos.current()) pos.skip(self.command) self.output = TaggedOutput().settag(self.translated) self.parseparameter(pos) class TextFunction(CommandBit): "A function where parameters are read as text." commandmap = FormulaConfig.textfunctions def parsebit(self, pos): "Parse a text parameter" self.output = TaggedOutput().settag(self.translated) self.parsetext(pos) def process(self): "Set the type to font" self.type = 'font' class LabelFunction(CommandBit): "A function that acts as a label" commandmap = FormulaConfig.labelfunctions def parsebit(self, pos): "Parse a literal parameter" self.key = self.parseliteral(pos) def process(self): "Add an anchor with the label contents." self.type = 'font' self.label = Label().create(' ', self.key, type = 'eqnumber') self.contents = [self.label] # store as a Label so we know it's been seen Label.names[self.key] = self.label class FontFunction(OneParamFunction): "A function of one parameter that changes the font" commandmap = FormulaConfig.fontfunctions def process(self): "Simplify if possible using a single character." self.type = 'font' self.simplifyifpossible() FormulaFactory.types += [FormulaCommand, SymbolFunction] FormulaCommand.types = [ AlphaCommand, EmptyCommand, OneParamFunction, FontFunction, LabelFunction, TextFunction, SpacedCommand, ] class BigSymbol(object): "A big symbol generator." symbols = FormulaConfig.bigsymbols def __init__(self, symbol): "Create the big symbol." self.symbol = symbol def getpieces(self): "Get an array with all pieces." if not self.symbol in self.symbols: return [self.symbol] if self.smalllimit(): return [self.symbol] return self.symbols[self.symbol] def smalllimit(self): "Decide if the limit should be a small, one-line symbol." if not DocumentParameters.displaymode: return True if len(self.symbols[self.symbol]) == 1: return True return Options.simplemath class BigBracket(BigSymbol): "A big bracket generator." def __init__(self, size, bracket, alignment='l'): "Set the size and symbol for the bracket." self.size = size self.original = bracket self.alignment = alignment self.pieces = None if bracket in FormulaConfig.bigbrackets: self.pieces = FormulaConfig.bigbrackets[bracket] def getpiece(self, index): "Return the nth piece for the bracket." function = getattr(self, 'getpiece' + unicode(len(self.pieces))) return function(index) def getpiece1(self, index): "Return the only piece for a single-piece bracket." return self.pieces[0] def getpiece3(self, index): "Get the nth piece for a 3-piece bracket: parenthesis or square bracket." if index == 0: return self.pieces[0] if index == self.size - 1: return self.pieces[-1] return self.pieces[1] def getpiece4(self, index): "Get the nth piece for a 4-piece bracket: curly bracket." if index == 0: return self.pieces[0] if index == self.size - 1: return self.pieces[3] if index == (self.size - 1)/2: return self.pieces[2] return self.pieces[1] def getcell(self, index): "Get the bracket piece as an array cell." piece = self.getpiece(index) span = 'span class="bracket align-' + self.alignment + '"' return TaggedBit().constant(piece, span) def getcontents(self): "Get the bracket as an array or as a single bracket." if self.size == 1 or not self.pieces: return self.getsinglebracket() rows = [] for index in range(self.size): cell = self.getcell(index) rows.append(TaggedBit().complete([cell], 'span class="arrayrow"')) return [TaggedBit().complete(rows, 'span class="array"')] def getsinglebracket(self): "Return the bracket as a single sign." if self.original == '.': return [TaggedBit().constant('', 'span class="emptydot"')] return [TaggedBit().constant(self.original, 'span class="symbol"')] class FormulaEquation(CommandBit): "A simple numbered equation." piece = 'equation' def parsebit(self, pos): "Parse the array" self.output = ContentsOutput() self.add(self.factory.parsetype(WholeFormula, pos)) class FormulaCell(FormulaCommand): "An array cell inside a row" def setalignment(self, alignment): self.alignment = alignment self.output = TaggedOutput().settag('span class="arraycell align-' + alignment +'"', True) return self def parsebit(self, pos): self.factory.clearskipped(pos) if pos.finished(): return self.add(self.factory.parsetype(WholeFormula, pos)) class FormulaRow(FormulaCommand): "An array row inside an array" cellseparator = FormulaConfig.array['cellseparator'] def setalignments(self, alignments): self.alignments = alignments self.output = TaggedOutput().settag('span class="arrayrow"', True) return self def parsebit(self, pos): "Parse a whole row" index = 0 pos.pushending(self.cellseparator, optional=True) while not pos.finished(): cell = self.createcell(index) cell.parsebit(pos) self.add(cell) index += 1 pos.checkskip(self.cellseparator) if len(self.contents) == 0: self.output = EmptyOutput() def createcell(self, index): "Create the cell that corresponds to the given index." alignment = self.alignments[index % len(self.alignments)] return self.factory.create(FormulaCell).setalignment(alignment) class MultiRowFormula(CommandBit): "A formula with multiple rows." def parserows(self, pos): "Parse all rows, finish when no more row ends" self.rows = [] first = True for row in self.iteraterows(pos): if first: first = False else: # intersparse empty rows self.addempty() row.parsebit(pos) self.addrow(row) self.size = len(self.rows) def iteraterows(self, pos): "Iterate over all rows, end when no more row ends" rowseparator = FormulaConfig.array['rowseparator'] while True: pos.pushending(rowseparator, True) row = self.factory.create(FormulaRow) yield row.setalignments(self.alignments) if pos.checkfor(rowseparator): self.original += pos.popending(rowseparator) else: return def addempty(self): "Add an empty row." row = self.factory.create(FormulaRow).setalignments(self.alignments) for index, originalcell in enumerate(self.rows[-1].contents): cell = row.createcell(index) cell.add(FormulaConstant(u' ')) row.add(cell) self.addrow(row) def addrow(self, row): "Add a row to the contents and to the list of rows." self.rows.append(row) self.add(row) class FormulaArray(MultiRowFormula): "An array within a formula" piece = 'array' def parsebit(self, pos): "Parse the array" self.output = TaggedOutput().settag('span class="array"', False) self.parsealignments(pos) self.parserows(pos) def parsealignments(self, pos): "Parse the different alignments" # vertical self.valign = 'c' literal = self.parsesquareliteral(pos) if literal: self.valign = literal # horizontal literal = self.parseliteral(pos) self.alignments = [] for l in literal: self.alignments.append(l) class FormulaMatrix(MultiRowFormula): "A matrix (array with center alignment)." piece = 'matrix' def parsebit(self, pos): "Parse the matrix, set alignments to 'c'." self.output = TaggedOutput().settag('span class="array"', False) self.valign = 'c' self.alignments = ['c'] self.parserows(pos) class FormulaCases(MultiRowFormula): "A cases statement" piece = 'cases' def parsebit(self, pos): "Parse the cases" self.output = ContentsOutput() self.alignments = ['l', 'l'] self.parserows(pos) for row in self.contents: for cell in row.contents: cell.output.settag('span class="case align-l"', True) cell.contents.append(FormulaConstant(u' ')) array = TaggedBit().complete(self.contents, 'span class="bracketcases"', True) brace = BigBracket(len(self.contents), '{', 'l') self.contents = brace.getcontents() + [array] class EquationEnvironment(MultiRowFormula): "A \\begin{}...\\end equation environment with rows and cells." def parsebit(self, pos): "Parse the whole environment." self.output = TaggedOutput().settag('span class="environment"', False) environment = self.piece.replace('*', '') if environment in FormulaConfig.environments: self.alignments = FormulaConfig.environments[environment] else: Trace.error('Unknown equation environment ' + self.piece) self.alignments = ['l'] self.parserows(pos) class BeginCommand(CommandBit): "A \\begin{}...\end command and what it entails (array, cases, aligned)" commandmap = {FormulaConfig.array['begin']:''} types = [FormulaEquation, FormulaArray, FormulaCases, FormulaMatrix] def parsebit(self, pos): "Parse the begin command" command = self.parseliteral(pos) bit = self.findbit(command) ending = FormulaConfig.array['end'] + '{' + command + '}' pos.pushending(ending) bit.parsebit(pos) self.add(bit) self.original += pos.popending(ending) self.size = bit.size def findbit(self, piece): "Find the command bit corresponding to the \\begin{piece}" for type in BeginCommand.types: if piece.replace('*', '') == type.piece: return self.factory.create(type) bit = self.factory.create(EquationEnvironment) bit.piece = piece return bit FormulaCommand.types += [BeginCommand] import datetime class CombiningFunction(OneParamFunction): commandmap = FormulaConfig.combiningfunctions def parsebit(self, pos): "Parse a combining function." self.type = 'alpha' combining = self.translated parameter = self.parsesingleparameter(pos) if not parameter: Trace.error('Empty parameter for combining function ' + self.command) elif len(parameter.extracttext()) != 1: Trace.error('Applying combining function ' + self.command + ' to invalid string "' + parameter.extracttext() + '"') self.contents.append(Constant(combining)) def parsesingleparameter(self, pos): "Parse a parameter, or a single letter." self.factory.clearskipped(pos) if pos.finished(): Trace.error('Error while parsing single parameter at ' + pos.identifier()) return None if self.factory.detecttype(Bracket, pos) \ or self.factory.detecttype(FormulaCommand, pos): return self.parseparameter(pos) letter = FormulaConstant(pos.skipcurrent()) self.add(letter) return letter class DecoratingFunction(OneParamFunction): "A function that decorates some bit of text" commandmap = FormulaConfig.decoratingfunctions def parsebit(self, pos): "Parse a decorating function" self.type = 'alpha' symbol = self.translated self.symbol = TaggedBit().constant(symbol, 'span class="symbolover"') self.parameter = self.parseparameter(pos) self.output = TaggedOutput().settag('span class="withsymbol"') self.contents.insert(0, self.symbol) self.parameter.output = TaggedOutput().settag('span class="undersymbol"') self.simplifyifpossible() class LimitCommand(EmptyCommand): "A command which accepts limits above and below, in display mode." commandmap = FormulaConfig.limitcommands def parsebit(self, pos): "Parse a limit command." pieces = BigSymbol(self.translated).getpieces() self.output = TaggedOutput().settag('span class="limits"') for piece in pieces: self.contents.append(TaggedBit().constant(piece, 'span class="limit"')) class LimitPreviousCommand(LimitCommand): "A command to limit the previous command." commandmap = None def parsebit(self, pos): "Do nothing." self.output = TaggedOutput().settag('span class="limits"') self.factory.clearskipped(pos) def __unicode__(self): "Return a printable representation." return 'Limit previous command' class LimitsProcessor(MathsProcessor): "A processor for limits inside an element." def process(self, contents, index): "Process the limits for an element." if Options.simplemath: return if self.checklimits(contents, index): self.modifylimits(contents, index) if self.checkscript(contents, index) and self.checkscript(contents, index + 1): self.modifyscripts(contents, index) def checklimits(self, contents, index): "Check if the current position has a limits command." if not DocumentParameters.displaymode: return False if self.checkcommand(contents, index + 1, LimitPreviousCommand): self.limitsahead(contents, index) return False if not isinstance(contents[index], LimitCommand): return False return self.checkscript(contents, index + 1) def limitsahead(self, contents, index): "Limit the current element based on the next." contents[index + 1].add(contents[index].clone()) contents[index].output = EmptyOutput() def modifylimits(self, contents, index): "Modify a limits commands so that the limits appear above and below." limited = contents[index] subscript = self.getlimit(contents, index + 1) limited.contents.append(subscript) if self.checkscript(contents, index + 1): superscript = self.getlimit(contents, index + 1) else: superscript = TaggedBit().constant(u' ', 'sup class="limit"') limited.contents.insert(0, superscript) def getlimit(self, contents, index): "Get the limit for a limits command." limit = self.getscript(contents, index) limit.output.tag = limit.output.tag.replace('script', 'limit') return limit def modifyscripts(self, contents, index): "Modify the super- and subscript to appear vertically aligned." subscript = self.getscript(contents, index) # subscript removed so instead of index + 1 we get index again superscript = self.getscript(contents, index) scripts = TaggedBit().complete([superscript, subscript], 'span class="scripts"') contents.insert(index, scripts) def checkscript(self, contents, index): "Check if the current element is a sub- or superscript." return self.checkcommand(contents, index, SymbolFunction) def checkcommand(self, contents, index, type): "Check for the given type as the current element." if len(contents) <= index: return False return isinstance(contents[index], type) def getscript(self, contents, index): "Get the sub- or superscript." bit = contents[index] bit.output.tag += ' class="script"' del contents[index] return bit class BracketCommand(OneParamFunction): "A command which defines a bracket." commandmap = FormulaConfig.bracketcommands def parsebit(self, pos): "Parse the bracket." OneParamFunction.parsebit(self, pos) def create(self, direction, character): "Create the bracket for the given character." self.original = character self.command = '\\' + direction self.contents = [FormulaConstant(character)] return self class BracketProcessor(MathsProcessor): "A processor for bracket commands." def process(self, contents, index): "Convert the bracket using Unicode pieces, if possible." if Options.simplemath: return if self.checkleft(contents, index): return self.processleft(contents, index) def processleft(self, contents, index): "Process a left bracket." rightindex = self.findright(contents, index + 1) if not rightindex: return size = self.findmax(contents, index, rightindex) self.resize(contents[index], size) self.resize(contents[rightindex], size) def checkleft(self, contents, index): "Check if the command at the given index is left." return self.checkdirection(contents[index], '\\left') def checkright(self, contents, index): "Check if the command at the given index is right." return self.checkdirection(contents[index], '\\right') def checkdirection(self, bit, command): "Check if the given bit is the desired bracket command." if not isinstance(bit, BracketCommand): return False return bit.command == command def findright(self, contents, index): "Find the right bracket starting at the given index, or 0." depth = 1 while index < len(contents): if self.checkleft(contents, index): depth += 1 if self.checkright(contents, index): depth -= 1 if depth == 0: return index index += 1 return None def findmax(self, contents, leftindex, rightindex): "Find the max size of the contents between the two given indices." sliced = contents[leftindex:rightindex] return max([element.size for element in sliced]) def resize(self, command, size): "Resize a bracket command to the given size." character = command.extracttext() alignment = command.command.replace('\\', '') bracket = BigBracket(size, character, alignment) command.output = ContentsOutput() command.contents = bracket.getcontents() class TodayCommand(EmptyCommand): "Shows today's date." commandmap = None def parsebit(self, pos): "Parse a command without parameters" self.output = FixedOutput() self.html = [datetime.date.today().strftime('%b %d, %Y')] FormulaCommand.types += [ DecoratingFunction, CombiningFunction, LimitCommand, BracketCommand, ] FormulaProcessor.processors += [ LimitsProcessor(), BracketProcessor(), ] class ParameterDefinition(object): "The definition of a parameter in a hybrid function." "[] parameters are optional, {} parameters are mandatory." "Each parameter has a one-character name, like {$1} or {$p}." "A parameter that ends in ! like {$p!} is a literal." "Example: [$1]{$p!} reads an optional parameter $1 and a literal mandatory parameter p." parambrackets = [('[', ']'), ('{', '}')] def __init__(self): self.name = None self.literal = False self.optional = False self.value = None self.literalvalue = None def parse(self, pos): "Parse a parameter definition: [$0], {$x}, {$1!}..." for (opening, closing) in ParameterDefinition.parambrackets: if pos.checkskip(opening): if opening == '[': self.optional = True if not pos.checkskip('$'): Trace.error('Wrong parameter name, did you mean $' + pos.current() + '?') return None self.name = pos.skipcurrent() if pos.checkskip('!'): self.literal = True if not pos.checkskip(closing): Trace.error('Wrong parameter closing ' + pos.skipcurrent()) return None return self Trace.error('Wrong character in parameter template: ' + pos.skipcurrent()) return None def read(self, pos, function): "Read the parameter itself using the definition." if self.literal: if self.optional: self.literalvalue = function.parsesquareliteral(pos) else: self.literalvalue = function.parseliteral(pos) if self.literalvalue: self.value = FormulaConstant(self.literalvalue) elif self.optional: self.value = function.parsesquare(pos) else: self.value = function.parseparameter(pos) def __unicode__(self): "Return a printable representation." result = 'param ' + self.name if self.value: result += ': ' + unicode(self.value) else: result += ' (empty)' return result class ParameterFunction(CommandBit): "A function with a variable number of parameters defined in a template." "The parameters are defined as a parameter definition." def readparams(self, readtemplate, pos): "Read the params according to the template." self.params = dict() for paramdef in self.paramdefs(readtemplate): paramdef.read(pos, self) self.params['$' + paramdef.name] = paramdef def paramdefs(self, readtemplate): "Read each param definition in the template" pos = TextPosition(readtemplate) while not pos.finished(): paramdef = ParameterDefinition().parse(pos) if paramdef: yield paramdef def getparam(self, name): "Get a parameter as parsed." if not name in self.params: return None return self.params[name] def getvalue(self, name): "Get the value of a parameter." return self.getparam(name).value def getliteralvalue(self, name): "Get the literal value of a parameter." param = self.getparam(name) if not param or not param.literalvalue: return None return param.literalvalue class HybridFunction(ParameterFunction): """ A parameter function where the output is also defined using a template. The template can use a number of functions; each function has an associated tag. Example: [f0{$1},span class="fbox"] defines a function f0 which corresponds to a span of class fbox, yielding $1. Literal parameters can be used in tags definitions: [f0{$1},span style="color: $p;"] yields $1, where $p is a literal parameter. Sizes can be specified in hybridsizes, e.g. adding parameter sizes. By default the resulting size is the max of all arguments. Sizes are used to generate the right parameters. A function followed by a single / is output as a self-closing XHTML tag: [f0/,hr] will generate
. """ commandmap = FormulaConfig.hybridfunctions def parsebit(self, pos): "Parse a function with [] and {} parameters" readtemplate = self.translated[0] writetemplate = self.translated[1] self.readparams(readtemplate, pos) self.contents = self.writeparams(writetemplate) self.computehybridsize() def writeparams(self, writetemplate): "Write all params according to the template" return self.writepos(TextPosition(writetemplate)) def writepos(self, pos): "Write all params as read in the parse position." result = [] while not pos.finished(): if pos.checkskip('$'): param = self.writeparam(pos) if param: result.append(param) elif pos.checkskip('f'): function = self.writefunction(pos) if function: function.type = None result.append(function) elif pos.checkskip('('): result.append(self.writebracket('left', '(')) elif pos.checkskip(')'): result.append(self.writebracket('right', ')')) else: result.append(FormulaConstant(pos.skipcurrent())) return result def writeparam(self, pos): "Write a single param of the form $0, $x..." name = '$' + pos.skipcurrent() if not name in self.params: Trace.error('Unknown parameter ' + name) return None if not self.params[name]: return None if pos.checkskip('.'): self.params[name].value.type = pos.globalpha() return self.params[name].value def writefunction(self, pos): "Write a single function f0,...,fn." tag = self.readtag(pos) if not tag: return None if pos.checkskip('/'): # self-closing XHTML tag, such as
return TaggedBit().selfcomplete(tag) if not pos.checkskip('{'): Trace.error('Function should be defined in {}') return None pos.pushending('}') contents = self.writepos(pos) pos.popending() if len(contents) == 0: return None return TaggedBit().complete(contents, tag) def readtag(self, pos): "Get the tag corresponding to the given index. Does parameter substitution." if not pos.current().isdigit(): Trace.error('Function should be f0,...,f9: f' + pos.current()) return None index = int(pos.skipcurrent()) if 2 + index > len(self.translated): Trace.error('Function f' + unicode(index) + ' is not defined') return None tag = self.translated[2 + index] if not '$' in tag: return tag for variable in self.params: if variable in tag: param = self.params[variable] if not param.literal: Trace.error('Parameters in tag ' + tag + ' should be literal: {' + variable + '!}') continue if param.literalvalue: value = param.literalvalue else: value = '' tag = tag.replace(variable, value) return tag def writebracket(self, direction, character): "Return a new bracket looking at the given direction." return self.factory.create(BracketCommand).create(direction, character) def computehybridsize(self): "Compute the size of the hybrid function." if not self.command in HybridSize.configsizes: self.computesize() return self.size = HybridSize().getsize(self) # set the size in all elements at first level for element in self.contents: element.size = self.size class HybridSize(object): "The size associated with a hybrid function." configsizes = FormulaConfig.hybridsizes def getsize(self, function): "Read the size for a function and parse it." sizestring = self.configsizes[function.command] for name in function.params: if name in sizestring: size = function.params[name].value.computesize() sizestring = sizestring.replace(name, unicode(size)) if '$' in sizestring: Trace.error('Unconverted variable in hybrid size: ' + sizestring) return 1 return eval(sizestring) FormulaCommand.types += [HybridFunction] class MacroDefinition(CommandBit): "A function that defines a new command (a macro)." macros = dict() def parsebit(self, pos): "Parse the function that defines the macro." self.output = EmptyOutput() self.parameternumber = 0 self.defaults = [] self.factory.defining = True self.parseparameters(pos) self.factory.defining = False Trace.debug('New command ' + self.newcommand + ' (' + \ unicode(self.parameternumber) + ' parameters)') self.macros[self.newcommand] = self def parseparameters(self, pos): "Parse all optional parameters (number of parameters, default values)" "and the mandatory definition." self.newcommand = self.parsenewcommand(pos) # parse number of parameters literal = self.parsesquareliteral(pos) if literal: self.parameternumber = int(literal) # parse all default values bracket = self.parsesquare(pos) while bracket: self.defaults.append(bracket) bracket = self.parsesquare(pos) # parse mandatory definition self.definition = self.parseparameter(pos) def parsenewcommand(self, pos): "Parse the name of the new command." self.factory.clearskipped(pos) if self.factory.detecttype(Bracket, pos): return self.parseliteral(pos) if self.factory.detecttype(FormulaCommand, pos): return self.factory.create(FormulaCommand).extractcommand(pos) Trace.error('Unknown formula bit in defining function at ' + pos.identifier()) return 'unknown' def instantiate(self): "Return an instance of the macro." return self.definition.clone() class MacroParameter(FormulaBit): "A parameter from elyxer.a macro." def detect(self, pos): "Find a macro parameter: #n." return pos.checkfor('#') def parsebit(self, pos): "Parse the parameter: #n." if not pos.checkskip('#'): Trace.error('Missing parameter start #.') return self.number = int(pos.skipcurrent()) self.original = '#' + unicode(self.number) self.contents = [TaggedBit().constant('#' + unicode(self.number), 'span class="unknown"')] class MacroFunction(CommandBit): "A function that was defined using a macro." commandmap = MacroDefinition.macros def parsebit(self, pos): "Parse a number of input parameters." self.output = FilteredOutput() self.values = [] macro = self.translated self.parseparameters(pos, macro) self.completemacro(macro) def parseparameters(self, pos, macro): "Parse as many parameters as are needed." self.parseoptional(pos, list(macro.defaults)) self.parsemandatory(pos, macro.parameternumber - len(macro.defaults)) if len(self.values) < macro.parameternumber: Trace.error('Missing parameters in macro ' + unicode(self)) def parseoptional(self, pos, defaults): "Parse optional parameters." optional = [] while self.factory.detecttype(SquareBracket, pos): optional.append(self.parsesquare(pos)) if len(optional) > len(defaults): break for value in optional: default = defaults.pop() if len(value.contents) > 0: self.values.append(value) else: self.values.append(default) self.values += defaults def parsemandatory(self, pos, number): "Parse a number of mandatory parameters." for index in range(number): parameter = self.parsemacroparameter(pos, number - index) if not parameter: return self.values.append(parameter) def parsemacroparameter(self, pos, remaining): "Parse a macro parameter. Could be a bracket or a single letter." "If there are just two values remaining and there is a running number," "parse as two separater numbers." self.factory.clearskipped(pos) if pos.finished(): return None if self.factory.detecttype(FormulaNumber, pos): return self.parsenumbers(pos, remaining) return self.parseparameter(pos) def parsenumbers(self, pos, remaining): "Parse the remaining parameters as a running number." "For example, 12 would be {1}{2}." number = self.factory.parsetype(FormulaNumber, pos) if not len(number.original) == remaining: return number for digit in number.original: value = self.factory.create(FormulaNumber) value.add(FormulaConstant(digit)) value.type = number self.values.append(value) return None def completemacro(self, macro): "Complete the macro with the parameters read." self.contents = [macro.instantiate()] replaced = [False] * len(self.values) for parameter in self.searchall(MacroParameter): index = parameter.number - 1 if index >= len(self.values): Trace.error('Macro parameter index out of bounds: ' + unicode(index)) return replaced[index] = True parameter.contents = [self.values[index].clone()] for index in range(len(self.values)): if not replaced[index]: self.addfilter(index, self.values[index]) def addfilter(self, index, value): "Add a filter for the given parameter number and parameter value." original = '#' + unicode(index + 1) value = ''.join(self.values[0].gethtml()) self.output.addfilter(original, value) class FormulaMacro(Formula): "A math macro defined in an inset." def __init__(self): self.parser = MacroParser() self.output = EmptyOutput() def __unicode__(self): "Return a printable representation." return 'Math macro' FormulaFactory.types += [ MacroParameter ] FormulaCommand.types += [ MacroFunction, ] class SideNote(Container): "A side note that appears at the right." def __init__(self): self.parser = InsetParser() self.output = TaggedOutput() def process(self): "Enclose everything in a marginal span." self.output.settag('span class="Marginal"', True) class FootnoteMarker(Container): "A marker for a footnote." def __init__(self): "Set the correct span class." self.contents = [] span = 'span class="SupFootMarker"' if Options.alignfoot: span = 'span class="AlignFootMarker"' self.output = TaggedOutput().settag(span, False) mode = 'A' if Options.numberfoot: mode = '1' if Options.symbolfoot: mode = '*' NumberGenerator.generator.getcounter('Footnote').setmode(mode) def create(self): "Create the marker for a footnote." self.order = NumberGenerator.generator.generate('Footnote') if Options.endfoot: self.link = Link().complete(self.getmark(), 'footmarker-' + self.order) self.createcontents() return self def createanchor(self, marker): "Create the anchor for a footnote. Adds a link for end footnotes." self.order = marker.order if Options.endfoot: self.link = Link().complete(self.getmark(), 'footnote-' + self.order) self.link.setmutualdestination(marker.link) self.createcontents() return self def createlabel(self, marker): "Create the label for a footnote. Used in hoverfoot and marginfoot." self.order = marker.order self.contents = [Constant(self.getmark())] space = Constant(u' ') self.contents = [space] + self.contents + [space] return self def createcontents(self): "Create the contents of the marker." if Options.endfoot: self.contents = [self.link] else: self.contents = [Constant(self.getmark())] space = Constant(u' ') self.contents = [space] + self.contents + [space] def getmark(self): "Get the mark to be displayed in the marker based on the order." if Options.symbolfoot: return self.order else: return '[' + self.order + ']' class Footnote(Container): "A footnote to the main text." def __init__(self): self.parser = InsetParser() self.output = TaggedOutput().settag('span class="FootOuter"', False) def process(self): "Add a counter for the footnote." "Can be numeric or a letter depending on runtime options." marker = FootnoteMarker().create() anchor = FootnoteMarker().createanchor(marker) label = FootnoteMarker().createlabel(marker) notecontents = list(self.contents) self.contents = [marker] if Options.hoverfoot: self.contents.append(self.createnote([label] + notecontents, 'span class="HoverFoot"')) if Options.marginfoot: self.contents.append(self.createnote([label] + notecontents, 'span class="MarginFoot"')) if Options.endfoot: EndFootnotes.footnotes.append(self.createnote([anchor] + notecontents, 'div class="EndFoot"')) def createnote(self, contents, tag): "Create a note with the given contents and HTML tag." return TaggedText().complete(contents, tag, False) class EndFootnotes(Container): "The collection of footnotes at the document end." footnotes = [] def __init__(self): "Generate all footnotes and a proper header for them all." self.output = ContentsOutput() header = TaggedText().constant(Translator.translate('footnotes'), 'h1 class="index"') self.contents = [header] + self.footnotes class Note(Container): "A LyX note of several types" def __init__(self): self.parser = InsetParser() self.output = EmptyOutput() def process(self): "Hide note and comment, dim greyed out" self.type = self.header[2] if TagConfig.notes[self.type] == '': return self.output = TaggedOutput().settag(TagConfig.notes[self.type], True) class LyXHeader(Container): "Reads the header, outputs the HTML header" def __init__(self): self.contents = [] self.parser = HeaderParser() self.output = HeaderOutput() self.parameters = dict() self.partkey = PartKey().createheader('header') def process(self): "Find pdf title" DocumentParameters.pdftitle = self.getheaderparameter('pdftitle') documentclass = self.getheaderparameter('documentclass') if documentclass in HeaderConfig.styles['article']: DocumentParameters.startinglevel = 1 if documentclass in HeaderConfig.styles['book']: DocumentParameters.bibliography = 'bibliography' else: DocumentParameters.bibliography = 'references' if self.getheaderparameter('paragraphseparation') == 'indent': DocumentParameters.indentstandard = True DocumentParameters.tocdepth = self.getlevel('tocdepth') DocumentParameters.maxdepth = self.getlevel('secnumdepth') DocumentParameters.language = self.getheaderparameter('language') if self.getheaderparameter('outputchanges') == 'true': DocumentParameters.outputchanges = True return self def getheaderparameter(self, configparam): "Get a parameter configured in HeaderConfig." key = HeaderConfig.parameters[configparam] if not key in self.parameters: return None return self.parameters[key] def getlevel(self, configparam): "Get a level read as a parameter from elyxer.HeaderConfig." paramvalue = self.getheaderparameter(configparam) if not paramvalue: return 0 value = int(paramvalue) if DocumentParameters.startinglevel == 1: return value return value + 1 class LyXPreamble(Container): "The preamble at the beginning of a LyX file. Parsed for macros." def __init__(self): self.parser = PreambleParser() self.output = EmptyOutput() self.factory = FormulaFactory() def process(self): "Parse the LyX preamble, if needed." if len(PreambleParser.preamble) == 0: return pos = TextPosition('\n'.join(PreambleParser.preamble)) while not pos.finished(): if self.detectfunction(pos): self.parsefunction(pos) else: pos.globincluding('\n') PreambleParser.preamble = [] def detectfunction(self, pos): "Detect a macro definition or a preamble function." for function in FormulaConfig.misccommands: if pos.checkfor(function): return True return False def parsefunction(self, pos): "Parse a single command." self.factory.parsetype(FormulaCommand, pos) class LyXFooter(Container): "Reads the footer, outputs the HTML footer" def __init__(self): self.contents = [] self.parser = BoundedDummy() self.output = FooterOutput() self.partkey = PartKey().createheader('footer') def process(self): "Include any footnotes at the end." if EndFootnotes.footnotes: endnotes = EndFootnotes() self.contents = [endnotes] class Layout(Container): "A layout (block of text) inside a lyx file" type = 'none' def __init__(self): "Initialize the layout." self.contents = [] self.parser = BoundedParser() self.output = TaggedOutput().setbreaklines(True) def process(self): "Get the type and numerate if necessary." self.type = self.header[1] if self.type in TagConfig.layouts: self.output.tag = TagConfig.layouts[self.type] + ' class="' + self.type + '"' elif self.type.replace('*', '') in TagConfig.layouts: self.output.tag = TagConfig.layouts[self.type.replace('*', '')] self.output.tag += ' class="' + self.type.replace('*', '-') + '"' else: self.output.tag = 'div class="' + self.type + '"' self.numerate() def numerate(self): "Numerate if necessary." partkey = PartKeyGenerator.forlayout(self) if partkey: self.partkey = partkey self.output.tag = self.output.tag.replace('?', unicode(partkey.level)) def __unicode__(self): "Return a printable representation." if self.partkey: return 'Layout ' + self.type + ' #' + unicode(self.partkey.partkey) return 'Layout of type ' + self.type class StandardLayout(Layout): "A standard layout -- can be a true div or nothing at all" indentation = False def process(self): self.type = 'standard' self.output = ContentsOutput() def complete(self, contents): "Set the contents and return it." self.process() self.contents = contents return self class Title(Layout): "The title of the whole document" def process(self): self.type = 'title' self.output.tag = 'h1 class="title"' title = self.extracttext() DocumentTitle.title = title Trace.message('Title: ' + title) class Author(Layout): "The document author" def process(self): self.type = 'author' self.output.tag = 'h2 class="author"' author = self.extracttext() Trace.debug('Author: ' + author) DocumentAuthor.appendauthor(author) class Abstract(Layout): "A paper abstract" done = False def process(self): self.type = 'abstract' self.output.tag = 'div class="abstract"' if Abstract.done: return message = Translator.translate('abstract') tagged = TaggedText().constant(message, 'p class="abstract-message"', True) self.contents.insert(0, tagged) Abstract.done = True class FirstWorder(Layout): "A layout where the first word is extracted" def extractfirstword(self): "Extract the first word as a list" return self.extractfromcontents(self.contents) def extractfromcontents(self, contents): "Extract the first word in contents." firstcontents = [] while len(contents) > 0: if self.isfirstword(contents[0]): firstcontents.append(contents[0]) del contents[0] return firstcontents if self.spaceincontainer(contents[0]): extracted = self.extractfromcontainer(contents[0]) firstcontents.append(extracted) return firstcontents firstcontents.append(contents[0]) del contents[0] return firstcontents def extractfromcontainer(self, container): "Extract the first word from a container cloning it including its output." if isinstance(container, StringContainer): return self.extractfromstring(container) result = Cloner.clone(container) result.output = container.output result.contents = self.extractfromcontents(container.contents) return result def extractfromstring(self, container): "Extract the first word from elyxer.a string container." if not ' ' in container.string: Trace.error('No space in string ' + container.string) return container split = container.string.split(' ', 1) container.string = split[1] return Constant(split[0]) def spaceincontainer(self, container): "Find out if the container contains a space somewhere." return ' ' in container.extracttext() def isfirstword(self, container): "Find out if the container is valid as a first word." if not isinstance(container, FirstWord): return False return not container.isempty() class FirstWord(Container): "A container which is in itself a first word, unless it's empty." "Should be inherited by other containers, e.g. ERT." def isempty(self): "Find out if the first word is empty." Trace.error('Unimplemented isempty()') return True class Description(FirstWorder): "A description layout" def process(self): "Set the first word to bold" self.type = 'Description' self.output.tag = 'div class="Description"' firstword = self.extractfirstword() if not firstword: return tag = 'span class="Description-entry"' self.contents.insert(0, TaggedText().complete(firstword, tag)) self.contents.insert(1, Constant(u' ')) class List(FirstWorder): "A list layout" def process(self): "Set the first word to bold" self.type = 'List' self.output.tag = 'div class="List"' firstword = self.extractfirstword() if not firstword: return first = TaggedText().complete(firstword, 'span class="List-entry"') second = TaggedText().complete(self.contents, 'span class="List-contents"') self.contents = [first, second] class PlainLayout(Layout): "A plain layout" def process(self): "Output just as contents." self.output = ContentsOutput() self.type = 'Plain' def makevisible(self): "Make the layout visible, output as tagged text." self.output = TaggedOutput().settag('div class="PlainVisible"', True) class LyXCode(Layout): "A bit of LyX-Code." def process(self): "Output as pre." self.output.tag = 'pre class="LyX-Code"' for newline in self.searchall(Newline): index = newline.parent.contents.index(newline) newline.parent.contents[index] = Constant('\n') class PostLayout(object): "Numerate an indexed layout" processedclass = Layout def postprocess(self, last, layout, next): "Group layouts and/or number them." if layout.type in TagConfig.group['layouts']: return self.group(last, layout) if layout.partkey: self.number(layout) return layout def group(self, last, layout): "Group two layouts if they are the same type." if not self.isgroupable(layout) or not self.isgroupable(last) or last.type != layout.type: return layout layout.contents = last.contents + [Constant('
\n')] + layout.contents last.contents = [] last.output = EmptyOutput() return layout def isgroupable(self, container): "Check that the container can be grouped." if not isinstance(container, Layout): return False for element in container.contents: if not element.__class__.__name__ in LayoutConfig.groupable['allowed']: return False return True def number(self, layout): "Generate a number and place it before the text" layout.partkey.addtoclabel(layout) class PostStandard(object): "Convert any standard spans in root to divs" processedclass = StandardLayout def postprocess(self, last, standard, next): "Switch to div, and clear if empty." type = 'Standard' if self.isempty(standard): standard.output = EmptyOutput() return standard if DocumentParameters.indentstandard: if isinstance(last, StandardLayout): type = 'Indented' else: type = 'Unindented' standard.output = TaggedOutput().settag('div class="' + type + '"', True) return standard def isempty(self, standard): "Find out if the standard layout is empty." for element in standard.contents: if not element.output.isempty(): return False return True class PostPlainLayout(PostLayout): "Numerate a plain layout" processedclass = PlainLayout def postprocess(self, last, plain, next): "Group plain layouts." if not self.istext(last) or not self.istext(plain): return plain plain.makevisible() return self.group(last, plain) def istext(self, container): "Find out if the container is only text." if not isinstance(container, PlainLayout): return False extractor = ContainerExtractor(TOCConfig.extractplain) text = extractor.extract(container) return (len(text) > 0) class PostLyXCode(object): "Coalesce contiguous LyX-Code layouts." processedclass = LyXCode def postprocess(self, last, lyxcode, next): "Coalesce if last was also LyXCode" if not isinstance(last, LyXCode): return lyxcode if hasattr(last, 'first'): lyxcode.first = last.first else: lyxcode.first = last toappend = lyxcode.first.contents toappend.append(Constant('\n')) toappend += lyxcode.contents lyxcode.output = EmptyOutput() return lyxcode Postprocessor.stages += [ PostLayout, PostStandard, PostLyXCode, PostPlainLayout ] class BiblioCitation(Container): "A complete bibliography citation (possibly with many cites)." citations = dict() def __init__(self): self.parser = InsetParser() self.output = TaggedOutput().settag('span class="bibcites"') self.contents = [] def process(self): "Process the complete citation and all cites within." self.contents = [Constant('[')] keys = self.getparameterlist('key') for key in keys: self.contents += [BiblioCite().create(key), Constant(', ')] if len(keys) > 0: # remove trailing , self.contents.pop() self.contents.append(Constant(']')) class BiblioCite(Link): "Cite of a bibliography entry" cites = dict() def create(self, key): "Create the cite to the given key." self.key = key number = NumberGenerator.generator.generate('bibliocite') ref = BiblioReference().create(key, number) self.complete(number, 'cite-' + number, type='bibliocite') self.setmutualdestination(ref) if not key in BiblioCite.cites: BiblioCite.cites[key] = [] BiblioCite.cites[key].append(self) return self class Bibliography(Container): "A bibliography layout containing an entry" def __init__(self): self.parser = BoundedParser() self.output = TaggedOutput().settag('p class="biblio"', True) class BiblioHeader(Container): "The header of the bibliography." def __init__(self): "Create the header for the bibliography section." self.type = 'biblio' self.output = ContentsOutput() self.name = Translator.translate(DocumentParameters.bibliography) self.contents = [TaggedText().constant(self.name, 'h1 class="biblio"', True)] def addtotoc(self, parent): "Add the bibliography header to the TOC." self.parent = parent self.partkey = PartKeyGenerator.forindex(self) if not self.partkey: return self.partkey.addtoclabel(self) while parent: parent.partkey = self.partkey parent = parent.parent class PostBiblio(object): "Insert a Bibliography legend before the first item" processedclass = Bibliography def postprocess(self, last, element, next): "If we have the first bibliography insert a tag" if isinstance(last, Bibliography) or Options.nobib: return element layout = StandardLayout() header = BiblioHeader() header.addtotoc(layout) layout.complete([header, element]) return layout Postprocessor.stages += [PostBiblio] class BiblioReference(Link): "A reference to a bibliographical entry." references = dict() def create(self, key, number): "Create the reference with the given key and number." self.key = key self.complete(number, 'biblio-' + number, type='biblioentry') if not key in BiblioReference.references: BiblioReference.references[key] = [] BiblioReference.references[key].append(self) return self class BiblioEntry(Container): "A bibliography entry" entries = dict() def __init__(self): self.parser = InsetParser() self.output = TaggedOutput().settag('span class="entry"') self.contents = [] def process(self): "Process the cites for the entry's key" self.citeref = [Constant(NumberGenerator.generator.generate('biblioentry'))] self.processcites(self.getparameter('key')) def processcites(self, key): "Get all the cites of the entry" self.key = key if not key in BiblioReference.references: self.contents.append(Constant('[-] ')) return self.contents = [Constant('[')] for ref in BiblioReference.references[key]: self.contents.append(ref) self.contents.append(Constant(',')) self.contents.pop(-1) self.contents.append(Constant('] ')) class Processor(object): "Process a container and its contents." prestages = [] skipfiltered = ['LyXHeader', 'LyXFooter', 'Title', 'Author', 'TableOfContents'] def __init__(self, filtering): "Set filtering mode (to skip postprocessing)." "With filtering on, the classes in skipfiltered are not processed at all." self.filtering = filtering self.postprocessor = Postprocessor() def process(self, container): "Do the whole processing on a container." if self.filtering and container.__class__.__name__ in self.skipfiltered: return None container = self.preprocess(container) self.processcontainer(container) if not container: # do not postprocess empty containers from elyxer.here return container return self.postprocess(container) def preprocess(self, root): "Preprocess a root container with all prestages." if not root: return None for stage in self.prestages: root = stage.preprocess(root) if not root: return None return root def processcontainer(self, container): "Process a container and its contents, recursively." if not container: return for element in container.contents: self.processcontainer(element) container.process() def postprocess(self, container): "Postprocess a container, unless filtering is on." if self.filtering: return container return self.postprocessor.postprocess(container) class ListInset(Container): "An inset with a list, normally made of links." def __init__(self): self.parser = InsetParser() self.output = ContentsOutput() def sortdictionary(self, dictionary): "Sort all entries in the dictionary" keys = dictionary.keys() # sort by name keys.sort() return keys sortdictionary = classmethod(sortdictionary) class ListOf(ListInset): "A list of entities (figures, tables, algorithms)" def process(self): "Parse the header and get the type" self.type = self.header[2] text = Translator.translate('list-' + self.type) self.contents = [TaggedText().constant(text, 'div class="tocheader"', True)] class TableOfContents(ListInset): "Table of contents" def process(self): "Parse the header and get the type" self.create(Translator.translate('toc')) def create(self, heading): "Create a table of contents with the given heading text." self.output = TaggedOutput().settag('div class="fulltoc"', True) self.contents = [TaggedText().constant(heading, 'div class="tocheader"', True)] return self def add(self, entry): "Add a new entry to the TOC." if entry: self.contents.append(entry) class IndexReference(Link): "A reference to an entry in the alphabetical index." name = 'none' def process(self): "Put entry in index" name = self.getparameter('name') if name: self.name = name.strip() else: self.name = self.extracttext() IndexEntry.get(self.name).addref(self) def __unicode__(self): "Return a printable representation." return 'Reference to ' + self.name class IndexHeader(Link): "The header line for an index entry. Keeps all arrows." keyescapes = {'!':'', '|':'-', ' ':'-', '--':'-', ',':'', '\\':'', '@':'_', u'°':''} def create(self, names): "Create the header for the given index entry." self.output = TaggedOutput().settag('p class="printindex"', True) self.name = names[-1] keys = [self.escape(part, self.keyescapes) for part in names] self.key = '-'.join(keys) self.anchor = Link().complete('', 'index-' + self.key, None, 'printindex') self.contents = [self.anchor, Constant(self.name + ': ')] self.arrows = [] return self def addref(self, reference): "Create an arrow pointing to a reference." reference.index = unicode(len(self.arrows)) reference.destination = self.anchor reference.complete(u'↓', 'entry-' + self.key + '-' + reference.index) arrow = Link().complete(u'↑', type = 'IndexArrow') arrow.destination = reference if len(self.arrows) > 0: self.contents.append(Constant(u', ')) self.arrows.append(arrow) self.contents.append(arrow) def __unicode__(self): "Return a printable representation." return 'Index header for ' + self.name class IndexGroup(Container): "A group of entries in the alphabetical index, for an entry." root = None def create(self): "Create an index group." self.entries = dict() self.output = EmptyOutput() return self def findentry(self, names): "Find the entry with the given names." if self == IndexGroup.root: self.output = ContentsOutput() else: self.output = TaggedOutput().settag('div class="indexgroup"', True) lastname = names[-1] if not lastname in self.entries: self.entries[lastname] = IndexEntry().create(names) return self.entries[lastname] def sort(self): "Sort all entries in the group." for key in ListInset.sortdictionary(self.entries): entry = self.entries[key] entry.group.sort() self.contents.append(entry) def __unicode__(self): "Return a printable representation." return 'Index group' IndexGroup.root = IndexGroup().create() class IndexEntry(Container): "An entry in the alphabetical index." "When an index entry is of the form 'part1 ! part2 ...', " "a hierarchical structure in the form of an IndexGroup is constructed." "An index entry contains a mandatory header, and an optional group." def create(self, names): "Create an index entry with the given name." self.output = ContentsOutput() self.header = IndexHeader().create(names) self.group = IndexGroup().create() self.contents = [self.header, self.group] return self def addref(self, reference): "Add a reference to the entry." self.header.addref(reference) def get(cls, name): "Get the index entry for the given name." group = IndexGroup.root parts = IndexEntry.splitname(name) readparts = [] for part in parts: readparts.append(part) entry = group.findentry(readparts) group = entry.group return entry def splitname(cls, name): "Split a name in parts divided by !." return [part.strip() for part in name.split('!')] def __unicode__(self): "Return a printable representation." return 'Index entry for ' + self.header.name get = classmethod(get) splitname = classmethod(splitname) class PrintIndex(ListInset): "Command to print an index" def process(self): "Create the alphabetic index" self.name = Translator.translate('index') self.partkey = PartKeyGenerator.forindex(self) if not self.partkey: return self.contents = [TaggedText().constant(self.name, 'h1 class="index"')] self.partkey.addtoclabel(self) IndexGroup.root.sort() self.contents.append(IndexGroup.root) class NomenclatureEntry(Link): "An entry of LyX nomenclature" entries = dict() def process(self): "Put entry in index" symbol = self.getparameter('symbol') description = self.getparameter('description') key = symbol.replace(' ', '-').lower() if key in NomenclatureEntry.entries: Trace.error('Duplicated nomenclature entry ' + key) self.complete(u'↓', 'noment-' + key) entry = Link().complete(u'↑', 'nom-' + key) entry.symbol = symbol entry.description = description self.setmutualdestination(entry) NomenclatureEntry.entries[key] = entry class PrintNomenclature(ListInset): "Print all nomenclature entries" def process(self): "Create the nomenclature." self.name = Translator.translate('nomenclature') self.partkey = PartKeyGenerator.forindex(self) if not self.partkey: return self.contents = [TaggedText().constant(self.name, 'h1 class="nomenclature"')] self.partkey.addtoclabel(self) for key in self.sortdictionary(NomenclatureEntry.entries): entry = NomenclatureEntry.entries[key] contents = [entry, Constant(entry.symbol + u' ' + entry.description)] text = TaggedText().complete(contents, 'div class="Nomenclated"', True) self.contents.append(text) class PreListInset(object): "Preprocess any container that contains a list inset." def preprocess(self, container): "Preprocess a container, extract any list inset and return it." listinsets = container.searchall(ListInset) if len(listinsets) == 0: return container if len(container.contents) > 1: return container return listinsets[0] Processor.prestages += [PreListInset()] class TableParser(BoundedParser): "Parse the whole table" headers = ContainerConfig.table['headers'] def __init__(self): BoundedParser.__init__(self) self.columns = list() def parseheader(self, reader): "Parse table headers" reader.nextline() while self.startswithheader(reader): self.parseparameter(reader) return [] def startswithheader(self, reader): "Check if the current line starts with a header line" for start in TableParser.headers: if reader.currentline().strip().startswith(start): return True return False class TablePartParser(BoundedParser): "Parse a table part (row or cell)" def parseheader(self, reader): "Parse the header" tablekey, parameters = self.parsexml(reader) self.parameters = parameters return list() class ColumnParser(LoneCommand): "Parse column properties" def parseheader(self, reader): "Parse the column definition" key, parameters = self.parsexml(reader) self.parameters = parameters return [] class Table(Container): "A lyx table" def __init__(self): self.parser = TableParser() self.output = TaggedOutput().settag('table', True) self.columns = [] def process(self): "Set the columns on every row" index = 0 while index < len(self.contents): element = self.contents[index] if isinstance(element, Column): self.columns.append(element) del self.contents[index] elif isinstance(element, BlackBox): del self.contents[index] elif isinstance(element, Row): element.setcolumns(self.columns) index += 1 else: Trace.error('Unknown element type ' + element.__class__.__name__ + ' in table: ' + unicode(element.contents[0])) index += 1 class Row(Container): "A row in a table" def __init__(self): self.parser = TablePartParser() self.output = TaggedOutput().settag('tr', True) self.columns = list() def setcolumns(self, columns): "Process alignments for every column" if len(columns) != len(self.contents): Trace.error('Columns: ' + unicode(len(columns)) + ', cells: ' + unicode(len(self.contents))) return for index, cell in enumerate(self.contents): columns[index].set(cell) class Column(Container): "A column definition in a table" def __init__(self): self.parser = ColumnParser() self.output = EmptyOutput() def process(self): "Read size parameters if present." self.size = ContainerSize().readparameters(self) def set(self, cell): "Set alignments in the corresponding cell" alignment = self.getparameter('alignment') if alignment == 'block': alignment = 'justify' cell.setattribute('align', alignment) valignment = self.getparameter('valignment') cell.setattribute('valign', valignment) self.size.addstyle(cell) class Cell(Container): "A cell in a table" def __init__(self): self.parser = TablePartParser() self.output = TaggedOutput().settag('td', True) def setmulticolumn(self, span): "Set the cell as multicolumn" self.setattribute('colspan', span) def setattribute(self, attribute, value): "Set a cell attribute in the tag" self.output.tag += ' ' + attribute + '="' + unicode(value) + '"' class PostTable(object): "Postprocess a table" processedclass = Table def postprocess(self, last, table, next): "Postprocess a table: long table, multicolumn rows" self.longtable(table) for row in table.contents: index = 0 while index < len(row.contents): self.checkforplain(row, index) self.checkmulticolumn(row, index) index += 1 return table def longtable(self, table): "Postprocess a long table, removing unwanted rows" features = table.getparameter('features') if not features: return if not 'islongtable' in features: return if features['islongtable'] != 'true': return if self.hasrow(table, 'endfirsthead'): self.removerows(table, 'endhead') if self.hasrow(table, 'endlastfoot'): self.removerows(table, 'endfoot') def hasrow(self, table, attrname): "Find out if the table has a row of first heads" for row in table.contents: if row.getparameter(attrname): return True return False def removerows(self, table, attrname): "Remove the head rows, since the table has first head rows." for row in table.contents: if row.getparameter(attrname): row.output = EmptyOutput() def checkforplain(self, row, index): "Make plain layouts visible if necessary." cell = row.contents[index] plainlayouts = cell.searchall(PlainLayout) if len(plainlayouts) <= 1: return for plain in plainlayouts: plain.makevisible() def checkmulticolumn(self, row, index): "Process a multicolumn attribute" cell = row.contents[index] mc = cell.getparameter('multicolumn') if not mc: return if mc != '1': Trace.error('Unprocessed multicolumn=' + unicode(multicolumn) + ' cell ' + unicode(cell)) return total = 1 index += 1 while self.checkbounds(row, index): del row.contents[index] total += 1 cell.setmulticolumn(total) def checkbounds(self, row, index): "Check if the index is within bounds for the row" if index >= len(row.contents): return False mc = row.contents[index].getparameter('multicolumn') if mc != '2': return False return True Postprocessor.stages.append(PostTable) import struct import sys import os import shutil import os import os.path import codecs class Path(object): "Represents a generic path" def exists(self): "Check if the file exists" return os.path.exists(self.path) def open(self): "Open the file as readonly binary" return codecs.open(self.path, 'rb') def getmtime(self): "Return last modification time" return os.path.getmtime(self.path) def hasexts(self, exts): "Check if the file has one of the given extensions." for ext in exts: if self.hasext(ext): return True return False def hasext(self, ext): "Check if the file has the given extension" return self.getext() == ext def getext(self): "Get the current extension of the file." base, ext = os.path.splitext(self.path) return ext def __unicode__(self): "Return a unicode string representation" return self.path def __eq__(self, path): "Compare to another path" if not hasattr(path, 'path'): return False return self.path == path.path class InputPath(Path): "Represents an input file" def __init__(self, url): "Create the input path based on url" self.url = url self.path = url if not os.path.isabs(url): self.path = os.path.join(Options.directory, url) class OutputPath(Path): "Represents an output file" def __init__(self, inputpath): "Create the output path based on an input path" self.url = inputpath.url if os.path.isabs(self.url): self.url = os.path.basename(self.url) self.path = os.path.join(Options.destdirectory, self.url) def changeext(self, ext): "Change extension to the given one" base, oldext = os.path.splitext(self.path) self.path = base + ext base, oldext = os.path.splitext(self.url) self.url = base + ext def exists(self): "Check if the file exists" return os.path.exists(self.path) def createdirs(self): "Create any intermediate directories that don't exist" dir = os.path.dirname(self.path) if len(dir) > 0 and not os.path.exists(dir): os.makedirs(dir) def removebackdirs(self): "Remove any occurrences of ../ (or ..\ on Windows)" self.path = os.path.normpath(self.path) backdir = '..' + os.path.sep while self.path.startswith(backdir): self.path = self.path[len(backdir):] while self.url.startswith('../'): self.url = self.url[len('../'):] class Image(Container): "An embedded image" defaultformat = ImageConfig.formats['default'] size = None copy = None def __init__(self): self.parser = InsetParser() self.output = TaggedOutput() self.type = 'embedded' def process(self): "Place the url, convert the image if necessary." self.origin = InputPath(self.getparameter('filename')) self.destination = self.getdestination(self.origin) self.size = ContainerSize().readparameters(self) if self.origin.exists(): ImageConverter.instance.convert(self) else: Trace.error('Image ' + unicode(self.origin) + ' not found') self.setsize() self.settag() def getdestination(self, origin): "Convert origin path to destination path." "Changes extension of destination to output image format." destination = OutputPath(origin) if Options.noconvert: return destination self.convertformat(destination) destination.removebackdirs() return destination def convertformat(self, destination): "Convert the format of the destination image." if Options.copyimages: return imageformat = '.jpg' forcedest = Image.defaultformat if Options.imageformat: imageformat = Options.imageformat forcedest = Options.imageformat if not destination.hasext(imageformat): destination.changeext(forcedest) def setsize(self): "Set the size attributes width and height." width, height = ImageFile(self.destination).getdimensions() self.size.checkimage(width, height) def scalevalue(self, value): "Scale the value according to the image scale and return it as unicode." scaled = value * int(self.size.scale) / 100 return unicode(int(scaled)) + 'px' def settag(self): "Set the output tag for the image." tag = 'img class="' + self.type + '"' if self.origin.exists(): url = self.destination.url else: url = self.origin.url alt = Translator.translate('figure') + ' ' + url tag += ' src="' + url + '" alt="' + alt + '"' emptytag = True if self.destination.hasext('.svg'): self.contents = [Constant(alt)] tag = 'object class="' + self.type + '" data="' + url + '"' emptytag = False self.output.settag(tag, True, empty=emptytag) self.size.addstyle(self) class ImageConverter(object): "A converter from elyxer.one image file to another." vectorformats = ImageConfig.formats['vector'] cropboxformats = ImageConfig.cropboxformats active = True instance = None def convert(self, image): "Convert an image to PNG" if not ImageConverter.active or Options.noconvert: return if image.origin.path == image.destination.path: return if image.destination.exists(): if image.origin.getmtime() <= image.destination.getmtime(): # file has not changed; do not convert return image.destination.createdirs() if Options.copyimages: Trace.debug('Copying ' + image.origin.path + ' to ' + image.destination.path) shutil.copy2(image.origin.path, image.destination.path) return converter, command = self.buildcommand(image) try: Trace.debug(converter + ' command: "' + command + '"') result = os.system(command.encode(sys.getfilesystemencoding())) if result != 0: Trace.error(converter + ' not installed; images will not be processed') ImageConverter.active = False return Trace.message('Converted ' + unicode(image.origin) + ' to ' + unicode(image.destination)) except OSError, exception: Trace.error('Error while converting image ' + unicode(image.origin) + ': ' + unicode(exception)) def buildcommand(self, image): "Build the command to convert the image." if Options.converter in ImageConfig.converters: command = ImageConfig.converters[Options.converter] else: command = Options.converter; params = self.getparams(image) for param in params: command = command.replace('$' + param, unicode(params[param])) # remove unwanted options while '[' in command and ']' in command: command = self.removeparam(command) return Options.converter, command def removeparam(self, command): "Remove an unwanted param." if command.index('[') > command.index(']'): Trace.error('Converter command should be [...$...]: ' + command) exit() before = command[:command.index('[')] after = command[command.index(']') + 1:] between = command[command.index('[') + 1:command.index(']')] if '$' in between: return before + after return before + between + after def getparams(self, image): "Get the parameters for ImageMagick conversion" params = dict() params['input'] = image.origin params['output'] = image.destination if image.origin.hasexts(self.vectorformats): scale = 100 if image.size.scale: scale = image.size.scale # descale image.size.scale = None params['scale'] = scale if image.origin.getext() in self.cropboxformats: params['format'] = self.cropboxformats[image.origin.getext()] return params ImageConverter.instance = ImageConverter() class ImageFile(object): "A file corresponding to an image (JPG or PNG)" dimensions = dict() def __init__(self, path): "Create the file based on its path" self.path = path def getdimensions(self): "Get the dimensions of a JPG or PNG image" if not self.path.exists(): return None, None if unicode(self.path) in ImageFile.dimensions: return ImageFile.dimensions[unicode(self.path)] dimensions = (None, None) if self.path.hasext('.png'): dimensions = self.getpngdimensions() elif self.path.hasext('.jpg'): dimensions = self.getjpgdimensions() elif self.path.hasext('.svg'): dimensions = self.getsvgdimensions() ImageFile.dimensions[unicode(self.path)] = dimensions return dimensions def getpngdimensions(self): "Get the dimensions of a PNG image" pngfile = self.path.open() pngfile.seek(16) width = self.readlong(pngfile) height = self.readlong(pngfile) pngfile.close() return (width, height) def getjpgdimensions(self): "Get the dimensions of a JPEG image" jpgfile = self.path.open() start = self.readword(jpgfile) if start != int('ffd8', 16): Trace.error(unicode(self.path) + ' not a JPEG file') return (None, None) self.skipheaders(jpgfile, ['ffc0', 'ffc2']) self.seek(jpgfile, 3) height = self.readword(jpgfile) width = self.readword(jpgfile) jpgfile.close() return (width, height) def getsvgdimensions(self): "Get the dimensions of a SVG image." return (None, None) def skipheaders(self, file, hexvalues): "Skip JPEG headers until one of the parameter headers is found" headervalues = [int(value, 16) for value in hexvalues] header = self.readword(file) safetycounter = 0 while header not in headervalues and safetycounter < 30: length = self.readword(file) if length == 0: Trace.error('End of file ' + file.name) return self.seek(file, length - 2) header = self.readword(file) safetycounter += 1 def readlong(self, file): "Read a long (32-bit) value from elyxer.file" return self.readformat(file, '>L', 4) def readword(self, file): "Read a 16-bit value from elyxer.file" return self.readformat(file, '>H', 2) def readformat(self, file, format, bytes): "Read any format from elyxer.file" read = file.read(bytes) if read == '' or len(read) < bytes: Trace.error('EOF reached') return 0 tuple = struct.unpack(format, read) return tuple[0] def seek(self, file, bytes): "Seek forward, just by reading the given number of bytes" file.read(bytes) class ListItem(Container): "An element in a list" type = 'none' def __init__(self): "Create a list item." self.parser = BoundedParser() self.output = ContentsOutput() def process(self): "Set the correct type and contents." self.type = self.header[1] tag = TaggedText().complete(self.contents, 'li', True) self.contents = [tag] def __unicode__(self): return self.type + ' item @ ' + unicode(self.begin) class DeeperList(Container): "A nested list" def __init__(self): "Create a nested list element." self.parser = BoundedParser() self.output = ContentsOutput() self.contents = [] def process(self): "Create the deeper list" if len(self.contents) == 0: Trace.error('Empty deeper list') return def __unicode__(self): result = 'deeper list @ ' + unicode(self.begin) + ': [' for element in self.contents: result += unicode(element) + ', ' return result[:-2] + ']' class PendingList(object): "A pending list" def __init__(self): self.contents = [] self.type = None def additem(self, item): "Add a list item" self.contents += item.contents if not self.type: self.type = item.type def adddeeper(self, deeper): "Add a deeper list item" if self.empty(): self.insertfake() self.contents[-1].contents += deeper.contents def generate(self): "Get the resulting list" if not self.type: tag = 'ul' else: tag = TagConfig.listitems[self.type] text = TaggedText().complete(self.contents, tag, True) self.__init__() return text def isduewithitem(self, item): "Decide whether the pending list must be generated before the given item" if not self.type: return False if self.type != item.type: return True return False def isduewithnext(self, next): "Applies only if the list is finished with next item." if not next: return True if not isinstance(next, ListItem) and not isinstance(next, DeeperList): return True return False def empty(self): return len(self.contents) == 0 def insertfake(self): "Insert a fake item" item = TaggedText().constant('', 'li class="nested"', True) self.contents = [item] self.type = 'Itemize' def __unicode__(self): result = 'pending ' + unicode(self.type) + ': [' for element in self.contents: result += unicode(element) + ', ' if len(self.contents) > 0: result = result[:-2] return result + ']' class PostListItem(object): "Postprocess a list item" processedclass = ListItem def postprocess(self, last, item, next): "Add the item to pending and return an empty item" if not hasattr(self.postprocessor, 'list'): self.postprocessor.list = PendingList() self.postprocessor.list.additem(item) if self.postprocessor.list.isduewithnext(next): return self.postprocessor.list.generate() if isinstance(next, ListItem) and self.postprocessor.list.isduewithitem(next): return self.postprocessor.list.generate() return BlackBox() class PostDeeperList(object): "Postprocess a deeper list" processedclass = DeeperList def postprocess(self, last, deeper, next): "Append to the list in the postprocessor" if not hasattr(self.postprocessor, 'list'): self.postprocessor.list = PendingList() self.postprocessor.list.adddeeper(deeper) if self.postprocessor.list.isduewithnext(next): return self.postprocessor.list.generate() return BlackBox() Postprocessor.stages += [PostListItem, PostDeeperList] class Float(Container): "A floating inset" type = 'none' def __init__(self): self.parser = InsetParser() self.output = TaggedOutput().settag('div class="float"', True) def process(self): "Get the float type." self.type = self.header[2] self.processnumber() self.processfloats() self.processtags() def isparent(self): "Find out whether the float is the parent float or is contained in another float." current = self.parent while current: if isinstance(current, Float): return False current = current.parent return True def processnumber(self): "Number a float if it isn't numbered." if not self.isparent(): # do nothing; parent will take care of numbering return self.partkey = PartKey().createfloat(self) def processtags(self): "Process the HTML tags." tagged = self.embed() self.applywideningtag(tagged) def embed(self): "Embed the whole contents in a div." embeddedtag = self.getembeddedtag() tagged = TaggedText().complete(self.contents, embeddedtag, True) self.contents = [tagged] return tagged def processfloats(self): "Process all floats contained inside." floats = self.searchall(Float) counter = NumberCounter('subfloat').setmode('a') for subfloat in floats: subfloat.output.tag = subfloat.output.tag.replace('div', 'span') subfloat.partkey = PartKey().createsubfloat(counter.getnext()) def getembeddedtag(self): "Get the tag for the embedded object." floats = self.searchall(Float) if len(floats) > 0: return 'div class="multi' + self.type + '"' return 'div class="' + self.type + '"' def applywideningtag(self, container): "Apply the tag to set float width, if present." images = self.searchall(Image) if len(images) != 1: return '' image = images[0] if not image.size: return width = image.size.removepercentwidth() if not width: return image.type = 'figure' ContainerSize().setmax(width).addstyle(container) image.settag() def searchinside(self, type): "Search for a given type in the contents" return self.searchincontents(self.contents, type) def searchincontents(self, contents, type): "Search in the given contents for the required type." list = [] for element in contents: list += self.searchinelement(element, type) return list def searchinelement(self, element, type): "Search for a given type outside floats" if isinstance(element, Float): return [] if isinstance(element, type): return [element] return self.searchincontents(element.contents, type) def __unicode__(self): "Return a printable representation" return 'Floating inset of type ' + self.type class Wrap(Float): "A wrapped (floating) float" def processtags(self): "Add the widening tag to the parent tag." self.embed() placement = self.getparameter('placement') if not placement: placement = 'o' self.output.tag = 'div class="wrap-' + placement + '"' self.applywideningtag(self) class Listing(Container): "A code listing" processor = None def __init__(self): self.parser = InsetParser() self.output = TaggedOutput().settag('div class="listing"', True) self.numbered = None def process(self): "Remove all layouts" self.counter = 0 self.type = 'listing' self.processparams() if Listing.processor: Listing.processor.preprocess(self) for container in self.extractcontents(): if container: self.contents.append(container) if 'caption' in self.lstparams: text = self.lstparams['caption'][1:-1] self.contents.insert(0, Caption().create(text)) if Listing.processor: Listing.processor.postprocess(self) def extractcontents(self): "Extract all contents one container at a time." oldcontents = self.contents self.contents = [] inpre = [] for container in oldcontents: if self.iscaption(container): yield self.completepre(inpre) inpre = [] yield container else: inpre += self.extract(container) yield self.completepre(inpre) def processparams(self): "Process listing parameteres." LstParser().parsecontainer(self) if 'numbers' in self.lstparams: self.numbered = self.lstparams['numbers'] def iscaption(self, container): "Find out if the container has a caption (which should not be in
)."
    return (len(container.searchall(Caption)) > 0)

  def completepre(self, listinpre):
    "Complete the 
 tag with whatever has already been added."
    if len(listinpre) == 0:
      return None
    return TaggedText().complete(listinpre, 'pre class="listing"', False)

  def extract(self, container):
    "Extract the container's contents and return them"
    if isinstance(container, StringContainer):
      return self.modifystring(container)
    if isinstance(container, StandardLayout):
      return self.modifylayout(container)
    if isinstance(container, PlainLayout):
      return self.modifylayout(container)
    Trace.error('Unexpected container ' + container.__class__.__name__ +
        ' in listing')
    container.tree()
    return []

  def modifystring(self, string):
    "Modify a listing string"
    if string.string == '':
      string.string = u'​'
    return self.modifycontainer(string)

  def modifylayout(self, layout):
    "Modify a standard layout"
    if len(layout.contents) == 0:
      layout.contents = [Constant(u'​')]
    return self.modifycontainer(layout)

  def modifycontainer(self, container):
    "Modify a listing container"
    contents = [container, Constant('\n')]
    if self.numbered:
      self.counter += 1
      tag = 'span class="number-' + self.numbered + '"'
      contents.insert(0, TaggedText().constant(unicode(self.counter), tag))
    return contents

class FloatNumber(Container):
  "Holds the number for a float in the caption."

  def __init__(self):
    self.output = ContentsOutput()

  def create(self, float):
    "Create the float number."
    self.contents = [Constant(float.partkey.partkey)]
    return self

class PostFloat(object):
  "Postprocess a float: number it and move the label"

  processedclass = Float

  def postprocess(self, last, float, next):
    "Move the label to the top and number the caption"
    number = FloatNumber().create(float)
    for caption in float.searchinside(Caption):
      self.postlabels(float, caption)
      caption.contents = [number, Separator(u' ')] + caption.contents
    return float

  def postlabels(self, float, caption):
    "Search for labels and move them to the top"
    labels = caption.searchremove(Label)
    if len(labels) == 0 and float.partkey.tocentry:
      labels = [Label().create(' ', float.partkey.partkey.replace(' ', '-'))]
    float.contents = labels + float.contents

class PostWrap(PostFloat):
  "For a wrap: exactly like a float"

  processedclass = Wrap

Postprocessor.stages += [PostFloat, PostWrap]



class IncludeInset(Container):
  "A child document included within another."

  # the converter factory will be set in converter.py
  converterfactory = None
  filename = None

  def __init__(self):
    self.parser = InsetParser()
    self.output = ContentsOutput()

  def process(self):
    "Include the provided child document"
    self.filename = os.path.join(Options.directory, self.getparameter('filename'))
    Trace.debug('Child document: ' + self.filename)
    LstParser().parsecontainer(self)
    command = self.getparameter('LatexCommand')
    if command == 'verbatiminput':
      self.readverbatim()
      return
    elif command == 'lstinputlisting':
      self.readlisting()
      return
    self.processinclude()

  def processinclude(self):
    "Process a regular include: standard child document."
    self.contents = []
    olddir = Options.directory
    newdir = os.path.dirname(self.getparameter('filename'))
    if newdir != '':
      Trace.debug('Child dir: ' + newdir)
      Options.directory = os.path.join(Options.directory, newdir)
    try:
      self.convertinclude()
    finally:
      Options.directory = olddir

  def convertinclude(self):
    "Convert an included document."
    try:
      converter = IncludeInset.converterfactory.create(self)
    except:
      Trace.error('Could not read ' + self.filename + ', please check that the file exists and has read permissions.')
      return
    if self.hasemptyoutput():
      return
    converter.convert()
    self.contents = converter.getcontents()

  def readverbatim(self):
    "Read a verbatim document."
    self.contents = [TaggedText().complete(self.readcontents(), 'pre', True)]

  def readlisting(self):
    "Read a document as a listing."
    listing = Listing()
    listing.contents = self.readcontents()
    listing.parameters = self.parameters
    listing.process()
    self.contents = [listing]

  def readcontents(self):
    "Read the contents of a complete file."
    contents = list()
    lines = BulkFile(self.filename).readall()
    for line in lines:
      contents.append(Constant(line))
    return contents

  def __unicode__(self):
    "Return a printable description."
    if not self.filename:
      return 'Included unnamed file'
    return 'Included "' + self.filename + '"'






class ChangeInserted(Container):
  "A change which consists of an insertion."

  def __init__(self):
    self.parser = TextParser(self)
    if DocumentParameters.outputchanges:
      self.output = TaggedOutput().settag('span class="inserted"')
    else:
      self.output = ContentsOutput()

class ChangeDeleted(TaggedText):
  "A change which consists of a deletion."

  def __init__(self):
    self.parser = TextParser(self)
    if DocumentParameters.outputchanges:
      self.output = TaggedOutput().settag('span class="deleted"')
    else:
      self.output = EmptyOutput()












class ERT(FirstWord):
  "Evil Red Text: embedded TeX code."
  "Considered as a first word for descriptions."

  def __init__(self):
    self.parser = InsetParser()
    self.output = ContentsOutput()

  def process(self):
    "Process all TeX code, formulas, commands."
    text = ''
    separator = ''
    for container in self.contents:
      text += separator + container.extracttext()
      separator = '\n'
    pos = TextPosition(text)
    pos.leavepending = True
    code = TeXCode()
    code.parse(pos)
    self.contents = [code]

  def isempty(self):
    "Find out if the ERT is empty or not."
    if len(self.contents) == 0:
      return True
    if len(self.contents) > 1:
      Trace.error('Unknown ERT length 2')
      return False
    texcode = self.contents[0]
    return len(texcode.contents) == 0

class TeXCode(Container):
  "A parser and processor for TeX code."

  texseparators = ['{', '\\', '}', '$', '%']
  replaced = BibTeXConfig.replaced
  factory = FormulaFactory()
  endinglist = EndingList()

  def __init__(self):
    self.contents = []
    self.output = ContentsOutput()

  def parse(self, pos):
    "Parse some TeX code."
    self.parserecursive(pos)
    if pos.leavepending:
      self.endinglist.pickpending(pos)

  def findlaststring(self):
    "Find the last string in the contents."
    if len(self.contents) == 0:
      return None
    string = self.contents[-1]
    if not isinstance(string, StringContainer):
      return None
    return string

  def add(self, piece):
    "Add a new piece to the tag."
    if isinstance(piece, basestring):
      self.addtext(piece)
    else:
      self.contents.append(piece)

  def addtext(self, piece):
    "Add a text string to the tag."
    last = self.findlaststring()
    if last:
      last.string += piece
      return
    self.contents.append(Constant(piece))

  def parserecursive(self, pos):
    "Parse brackets or quotes recursively."
    while not pos.finished():
      self.parsetext(pos)
      if pos.finished():
        return
      elif pos.checkfor('{'):
        self.parseopenbracket(pos)
      elif pos.checkfor('}'):
        self.parseclosebracket(pos)
      elif pos.checkfor('\\'):
        self.parseescaped(pos)
      elif pos.checkfor('$'):
        self.parseformula(pos)
      elif pos.checkfor('%'):
        self.parsecomment(pos)
      else:
        pos.error('Unexpected character ' + pos.current())
        pos.skipcurrent()

  def parsetext(self, pos):
    "Parse a bit of text, excluding separators and compressing spaces."
    text = self.parsecompressingspace(pos)
    if text == '':
      return
    for key in self.replaced:
      if key in text:
        text = text.replace(key, self.replaced[key])
    self.add(text)

  def parsecompressingspace(self, pos):
    "Parse some text excluding value separators and compressing spaces."
    parsed = ''
    while not pos.finished():
      parsed += pos.glob(lambda: self.excludespaces(pos))
      if not pos.finished() and pos.current().isspace():
        parsed += ' '
        pos.skipspace()
      else:
        return parsed
    return parsed

  def excludespaces(self, pos):
    "Exclude value separators and spaces."
    current = pos.current()
    if current in self.texseparators:
      return False
    if current.isspace():
      return False
    return True

  def parseescaped(self, pos):
    "Parse an escaped string \\*."
    if pos.checkfor('\\(') or pos.checkfor('\\['):
      # start of formula commands
      self.parseformula(pos)
      return
    if not self.factory.detecttype(FormulaCommand, pos):
      pos.error('Not an escape sequence')
      return
    self.add(self.factory.parsetype(FormulaCommand, pos))

  def parseopenbracket(self, pos):
    "Parse a { bracket."
    if not pos.checkskip('{'):
      pos.error('Missing opening { bracket')
      return
    pos.pushending('}')
    self.parserecursive(pos)
    pos.popending('}')

  def parseclosebracket(self, pos):
    "Parse a } bracket."
    ending = self.endinglist.findending(pos)
    if not ending:
      Trace.error('Unexpected closing } bracket')
    else:
      self.endinglist.pop(pos)
    if not pos.checkskip('}'):
      pos.error('Missing closing } bracket')
      return

  def parseformula(self, pos):
    "Parse a whole formula."
    formula = Formula().parse(pos)
    self.add(formula)

  def parsecomment(self, pos):
    "Parse a TeX comment: % to the end of the line."
    pos.globexcluding('\n')

  def __unicode__(self):
    "Return a printable representation."
    return 'TeX code: ' + self.extracttext()



class BibTagParser(object):
  "A parser for BibTeX tags."

  nameseparators = ['{', '=', '"', '#']

  def __init__(self):
    self.key = None
    tags = BibStylesConfig.defaulttags
    self.tags = dict((x, BibTag().constant(tags[x])) for x in tags)

  def parse(self, pos):
    "Parse the entry between {}."
    self.type = pos.globexcluding(self.nameseparators).strip()
    if not pos.checkskip('{'):
      pos.error('Entry should start with {')
      return
    pos.pushending('}')
    self.parsetags(pos)
    pos.popending('}')
    pos.skipspace()

  def parsetags(self, pos):
    "Parse all tags in the entry."
    pos.skipspace()
    while not pos.finished():
      if pos.checkskip('{'):
        pos.error('Unmatched {')
        return
      pos.pushending(',', True)
      self.parsetag(pos)
      if pos.checkfor(','):
        pos.popending(',')
  
  def parsetag(self, pos):
    "Parse a single tag."
    (key, value) = self.getkeyvalue(pos)
    if not key:
      return
    if not value:
      self.key = key
      return
    name = key.lower()
    self.tags[name] = value
    if hasattr(self, 'dissect' + name):
      dissector = getattr(self, 'dissect' + name)
      dissector(value.extracttext())
    if not pos.finished():
      remainder = pos.globexcluding(',')
      pos.error('Ignored ' + remainder + ' before comma')

  def getkeyvalue(self, pos):
    "Parse a string of the form key=value."
    piece = pos.globexcluding(self.nameseparators).strip()
    if pos.finished():
      return (piece, None)
    if not pos.checkskip('='):
      pos.error('Undesired character in tag name ' + piece)
      pos.skipcurrent()
      return (piece, None)
    key = piece.lower()
    pos.skipspace()
    value = self.parsevalue(pos)
    return (key, value)

  def parsevalue(self, pos):
    "Parse the value for a tag."
    tag = BibTag()
    pos.skipspace()
    if pos.checkfor(','):
      pos.error('Unexpected ,')
      return tag.error()
    tag.parse(pos)
    return tag

  def dissectauthor(self, authortag):
    "Dissect the author tag into pieces."
    authorsplit = authortag.split(' and ')
    if len(authorsplit) == 0:
      return
    authorlist = []
    for authorname in authorsplit:
      author = BibAuthor().parse(authorname)
      authorlist.append(author)
    initials = ''
    authors = ''
    if len(authorlist) == 1:
      initials = authorlist[0].surname[0:3]
      authors = unicode(authorlist[0])
    else:
      for author in authorlist:
        initials += author.surname[0:1]
        authors += unicode(author) + ', '
      authors = authors[:-2]
    self.tags['surname'] = BibTag().constant(authorlist[0].surname)
    self.tags['Sur'] = BibTag().constant(initials)
    self.tags['authors'] = BibTag().constant(authors)

  def dissectyear(self, yeartag):
    "Dissect the year tag into pieces, looking for 4 digits in a row."
    pos = TextPosition(yeartag)
    while not pos.finished():
      if pos.current().isdigit():
        number = pos.globnumber()
        if len(number) == 4:
          self.tags['YY'] = BibTag().constant(number[2:])
          return
      else:
        pos.skipcurrent()

  def dissectfile(self, filetag):
    "Extract the filename from elyxer.the file tag as ':filename:FORMAT'."
    if not filetag.startswith(':'):
      return
    bits = filetag.split(':')
    if len(bits) != 3:
      return
    self.tags['filename'] = BibTag().constant(bits[1])
    self.tags['format'] = BibTag().constant(bits[2])

  def gettag(self, key):
    "Get the tag for a given key."
    if not key in self.tags:
      return None
    return self.tags[key]

  def gettagtext(self, key):
    "Get the tag for a key as raw text."
    return self.gettag(key).extracttext()

class BibTag(Container):
  "A tag in a BibTeX file."

  valueseparators = ['{', '"', '#', '}']
  stringdefs = dict()

  def __init__(self):
    self.contents = []
    self.output = ContentsOutput()

  def constant(self, text):
    "Initialize for a single constant."
    self.contents = [Constant(text)]
    return self

  def error(self):
    "To use when parsing resulted in an error."
    return self.constant('')

  def parse(self, pos):
    "Parse brackets or quotes at the first level."
    while not pos.finished():
      self.parsetext(pos)
      if pos.finished():
        return
      elif pos.checkfor('{'):
        self.parsebracket(pos)
      elif pos.checkfor('"'):
        self.parsequoted(pos)
      elif pos.checkfor('#'):
        self.parsehash(pos)
      else:
        pos.error('Unexpected character ' + pos.current())
        pos.skipcurrent()

  def parsetext(self, pos):
    "Parse a bit of text, try to substitute strings with string defs."
    text = pos.globexcluding(self.valueseparators)
    key = text.strip()
    if key == '':
      return
    if key in self.stringdefs:
      self.add(self.stringdefs[key])
      return
    self.add(Constant(key))

  def add(self, piece):
    "Add a new piece to the tag."
    self.contents.append(piece)

  def parsetex(self, pos):
    "Parse some TeX code."
    tex = TeXCode()
    tex.parse(pos)
    self.add(tex)

  def parsebracket(self, pos):
    "Parse a {} bracket"
    if not pos.checkskip('{'):
      pos.error('Missing opening { in bracket')
      return
    pos.pushending('}')
    self.parsetex(pos)
    pos.popending('}')

  def parsequoted(self, pos):
    "Parse a piece of quoted text"
    if not pos.checkskip('"'):
      pos.error('Missing opening " in quote')
      return
    pos.pushending('"')
    self.parsetex(pos)
    pos.popending('"')
    pos.skipspace()

  def parsehash(self, pos):
    "Parse a hash mark #."
    if not pos.checkskip('#'):
      pos.error('Missing # in hash')
      return

  def __unicode__(self):
    "Return a printable representation."
    return 'BibTag: ' + self.extracttext()

class BibAuthor(object):
  "A BibTeX individual author."

  def __init__(self):
    self.surname = ''
    self.firstnames = []

  def parse(self, tag):
    "Parse an individual author tag."
    if ',' in tag:
      self.parsecomma(tag)
    else:
      self.parsewithoutcomma(tag)
    return self

  def parsecomma(self, tag):
    "Parse an author with a comma: Python, M."
    bits = tag.split(',')
    if len(bits) > 2:
      Trace.error('Too many commas in ' + tag)
    self.surname = bits[0].strip()
    self.parsefirstnames(bits[1].strip())

  def parsewithoutcomma(self, tag):
    "Parse an author without a comma: M. Python."
    bits = tag.rsplit(None, 1)
    if len(bits) == 0:
      Trace.error('Empty author')
      ppp()
      return
    self.surname = bits[-1].strip()
    if len(bits) == 1:
      return
    self.parsefirstnames(bits[0].strip())

  def parsefirstnames(self, firstnames):
    "Parse the first name."
    for firstname in firstnames.split():
      self.firstnames.append(firstname)

  def getinitial(self):
    "Get the main initial for the author."
    if len(self.surname) == 0:
      return ''
    return self.surname[0].toupper()

  def __unicode__(self):
    "Return a printable representation."
    result = ''
    for firstname in self.firstnames:
      result += firstname + ' '
    return result + self.surname



class BibTeX(Container):
  "Show a BibTeX bibliography and all referenced entries"

  def __init__(self):
    self.parser = InsetParser()
    self.output = ContentsOutput()

  def process(self):
    "Read all bibtex files and process them."
    self.entries = []
    self.contents = [self.createheader()]
    bibliography = Translator.translate('bibliography')
    files = self.getparameterlist('bibfiles')
    showall = False
    if self.getparameter('btprint') == 'btPrintAll':
      showall = True
    for file in files:
      bibfile = BibFile(file, showall)
      bibfile.parse()
      self.entries += bibfile.entries
      Trace.message('Parsed ' + unicode(bibfile))
    self.entries.sort(key = unicode)
    self.applystyle()

  def createheader(self):
    "Create the header for the bibliography."
    header = BiblioHeader()
    if 'bibtotoc' in self.getparameterlist('options'):
      header.addtotoc(self)
    return header

  def applystyle(self):
    "Read the style and apply it to all entries"
    style = self.readstyle()
    for entry in self.entries:
      entry.template = style['default']
      entry.citetemplate = style['cite']
      type = entry.type.lower()
      if type in style:
        entry.template = style[type]
      entry.process()
      self.contents.append(entry)

  def readstyle(self):
    "Read the style from elyxer.the bibliography options"
    for option in self.getparameterlist('options'):
      if hasattr(BibStylesConfig, option):
        return getattr(BibStylesConfig, option)
    return BibStylesConfig.default

class BibFile(object):
  "A BibTeX file"

  def __init__(self, filename, showall):
    "Create the BibTeX file"
    self.filename = filename + '.bib'
    self.showall = showall
    self.added = 0
    self.ignored = 0
    self.entries = []

  def parse(self):
    "Parse the BibTeX file and extract all entries."
    try:
      self.parsefile()
    except IOError:
      Trace.error('Error reading ' + self.filename + '; make sure the file exists and can be read.')

  def parsefile(self):
    "Parse the whole file."
    bibpath = InputPath(self.filename)
    if Options.lowmem:
      pos = FilePosition(bibpath.path)
    else:
      bulkfile = BulkFile(bibpath.path)
      text = ''.join(bulkfile.readall())
      pos = TextPosition(text)
    while not pos.finished():
      pos.skipspace()
      if pos.checkskip(','):
        pos.skipspace()
      self.parseentry(pos)

  def parseentry(self, pos):
    "Parse a single entry"
    for entry in BibEntry.instances:
      if entry.detect(pos):
        newentry = Cloner.clone(entry)
        newentry.parse(pos)
        if not newentry.isvisible():
          return
        if self.showall or newentry.isreferenced():
          self.entries.append(newentry)
          self.added += 1
        else:
          Trace.debug('Ignored entry ' + unicode(newentry))
          self.ignored += 1
        return
    # Skip the whole line since it's a comment outside an entry
    pos.globincluding('\n').strip()

  def __unicode__(self):
    "String representation"
    string = self.filename + ': ' + unicode(self.added) + ' entries added, '
    string += unicode(self.ignored) + ' entries ignored'
    return string

class BibEntry(Container):
  "An entry in a BibTeX file"

  instances = []

  def detect(self, pos):
    "Throw an error."
    Trace.error('Tried to detect() in ' + unicode(self))

  def parse(self, pos):
    "Throw an error."
    Trace.error('Tried to parse() in ' + unicode(self))

  def isvisible(self):
    "Return if the entry should be visible. Throws an error."
    Trace.error('Function isvisible() not implemented for ' + unicode(self))

  def isreferenced(self):
    "Return if the entry is referenced. Throws an error."
    Trace.error('Function isreferenced() not implemented for ' + unicode(self))

  def __unicode__(self):
    "Return a string representation"
    return 'BibTeX entry ' + self.__class__.__name__

class CommentEntry(BibEntry):
  "A simple comment."

  def detect(self, pos):
    "Detect the special entry"
    return pos.checkfor('%')

  def parse(self, pos):
    "Parse all consecutive comment lines."
    while pos.checkfor('%'):
      pos.globincluding('\n')

  def isvisible(self):
    "A comment entry is never visible."
    return False

  def __unicode__(self):
    "Return a string representation"
    return 'Comment'

class SpecialEntry(BibEntry):
  "A special entry"

  types = ['@preamble', '@comment']

  def __init__(self):
    self.contents = []
    self.output = EmptyOutput()

  def detect(self, pos):
    "Detect the special entry"
    for type in self.types:
      if pos.checkforlower(type):
        return True
    return False

  def parse(self, pos):
    "Parse and ignore."
    self.type = 'special'
    pos.globincluding('{')
    pos.pushending('}')
    while not pos.finished():
      if pos.checkfor('{'):
        self.parse(pos)
      else:
        pos.skipcurrent()
    pos.popending()

  def isvisible(self):
    "A special entry is never visible."
    return False

  def __unicode__(self):
    "Return a string representation"
    return self.type

class StringEntry(SpecialEntry):
  "A string definition. The definition can later be used in other entries."

  parser = BibTagParser()
  start = '@string'
  key = None

  def detect(self, pos):
    "Detect the string definition."
    return pos.checkforlower(self.start)

  def parse(self, pos):
    "Parse a single tag, which will define a string."
    self.type = self.start
    if not self.checkstart(pos):
      return
    pos.skipspace()
    if not pos.checkskip('{'):
      Trace.error('Missing opening { in ' + unicode(self))
      pos.globincluding('\n')
      return
    pos.pushending('}')
    (self.key, value) = self.parser.getkeyvalue(pos)
    BibTag.stringdefs[self.key] = value
    pos.popending('}')

  def checkstart(self, pos):
    "Check that the entry starts with @string."
    if not pos.checkskip('@'):
      Trace.error('Missing @ from elyxer.string definition')
      return False
    name = '@' + pos.globalpha()
    if not name.lower() == self.start.lower():
      Trace.error('Invalid start @' + name +', missing ' + self.start + ' from elyxer.' + unicode(self))
      pos.globincluding('\n')
      return False
    return True

  def __unicode__(self):
    "Return a printable representation."
    result = 'string definition'
    if self.key:
      result += ' for ' + self.key
    return result


BibEntry.instances += [CommentEntry(), SpecialEntry(), StringEntry()]






class PubEntry(BibEntry):
  "A publication entry"

  def __init__(self):
    self.output = TaggedOutput().settag('p class="biblio"', True)

  def detect(self, pos):
    "Detect a publication entry."
    return pos.checkfor('@')

  def parse(self, pos):
    "Parse the publication entry."
    self.parser = BibTagParser()
    self.parser.parse(pos)
    self.type = self.parser.type

  def isvisible(self):
    "A publication entry is always visible."
    return True

  def isreferenced(self):
    "Check if the entry is referenced."
    if not self.parser.key:
      return False
    return self.parser.key in BiblioReference.references

  def process(self):
    "Process the entry."
    self.index = NumberGenerator.generator.generate('pubentry')
    self.parser.tags['index'] = Constant(self.index)
    biblio = BiblioEntry()
    biblio.citeref = self.createref()
    biblio.processcites(self.parser.key)
    self.contents = [biblio, Constant(' ')]
    self.contents += self.entrycontents()

  def entrycontents(self):
    "Get the contents of the entry."
    return self.translatetemplate(self.template)

  def createref(self):
    "Create the reference to cite."
    return self.translatetemplate(self.citetemplate)

  def translatetemplate(self, template):
    "Translate a complete template into a list of contents."
    pos = TextPosition(template)
    part = BibPart(self.parser.tags).parse(pos)
    for variable in part.searchall(BibVariable):
      if variable.empty():
        Trace.error('Error parsing BibTeX template for ' + unicode(self) + ': '
            + unicode(variable) + ' is empty')
    return [part]

  def __unicode__(self):
    "Return a string representation"
    string = ''
    if 'author' in self.parser.tags:
      string += self.parser.gettagtext('author') + ': '
    if 'title' in self.parser.tags:
      string += '"' + self.parser.gettagtext('title') + '"'
    return string

class BibPart(Container):
  "A part of a BibTeX template."

  def __init__(self, tags):
    self.output = ContentsOutput()
    self.contents = []
    self.tags = tags
    self.quotes = 0

  def parse(self, pos):
    "Parse a part of a template, return a list of contents."
    while not pos.finished():
      self.add(self.parsepiece(pos))
    return self

  def parsepiece(self, pos):
    "Get the next piece of the template, return if it was empty."
    if pos.checkfor('{'):
      return self.parsebraces(pos)
    elif pos.checkfor('$'):
      return self.parsevariable(pos)
    result = ''
    while not pos.finished() and not pos.current() in '{$':
      if pos.current() == '"':
        self.quotes += 1
      result += pos.skipcurrent()
    return Constant(result)

  def parsebraces(self, pos):
    "Parse a pair of curly braces {}."
    if not pos.checkskip('{'):
      Trace.error('Missing { in braces.')
      return None
    pos.pushending('}')
    part = BibPart(self.tags).parse(pos)
    pos.popending('}')
    empty = part.emptyvariables()
    if empty:
      return None
    return part

  def parsevariable(self, pos):
    "Parse a variable $name."
    var = BibVariable(self.tags).parse(pos)
    if self.quotes % 2 == 1:
      # odd number of quotes; don't add spans in an attribute
      var.removetag()
    return var

  def emptyvariables(self):
    "Find out if there are only empty variables in the part."
    for variable in self.searchall(BibVariable):
      if not variable.empty():
        return False
    return True

  def add(self, piece):
    "Add a new piece to the current part."
    if not piece:
      return
    if self.redundantdot(piece):
      # remove extra dot
      piece.string = piece.string[1:]
    self.contents.append(piece)
    piece.parent = self

  def redundantdot(self, piece):
    "Find out if there is a redundant dot in the next piece."
    if not isinstance(piece, Constant):
      return False
    if not piece.string.startswith('.'):
      return False
    if len(self.contents) == 0:
      return False
    if not isinstance(self.contents[-1], BibVariable):
      return False
    if not self.contents[-1].extracttext().endswith('.'):
      return False
    return True

class BibVariable(Container):
  "A variable in a BibTeX template."
  
  def __init__(self, tags):
    self.output = TaggedOutput()
    self.contents = []
    self.tags = tags

  def parse(self, pos):
    "Parse the variable name."
    if not pos.checkskip('$'):
      Trace.error('Missing $ in variable name.')
      return self
    self.key = pos.globalpha()
    self.output.tag = 'span class="bib-' + self.key + '"'
    self.processtags()
    return self

  def processtags(self):
    "Find the tag with the appropriate key in the list of tags."
    if not self.key in self.tags:
      return
    result = self.tags[self.key]
    self.contents = [result]

  def empty(self):
    "Find out if the variable is empty."
    if not self.contents:
      return True
    if self.extracttext() == '':
      return True
    return False

  def removetag(self):
    "Remove the output tag and leave just the contents."
    self.output = ContentsOutput()

  def __unicode__(self):
    "Return a printable representation."
    result = 'variable ' + self.key
    if not self.empty():
      result += ':' + self.extracttext()
    return result

BibEntry.instances += [PubEntry()]






class NewfangledChunk(Layout):
  "A chunk of literate programming."

  names = dict()
  firsttime = True

  def process(self):
    "Process the literate chunk."
    self.output.tag = 'div class="chunk"'
    self.type = 'chunk'
    text = self.extracttext()
    parts = text.split(',')
    if len(parts) < 1:
      Trace.error('Not enough parameters in ' + text)
      return
    self.name = parts[0]
    self.number = self.order()
    self.createlinks()
    self.contents = [self.left, self.declaration(), self.right]
    ChunkProcessor.lastchunk = self

  def order(self):
    "Create the order number for the chunk."
    return NumberGenerator.generator.generate('chunk')

  def createlinks(self):
    "Create back and forward links."
    self.leftlink = Link().complete(self.number, 'chunk:' + self.number, type='chunk')
    self.left = TaggedText().complete([self.leftlink], 'span class="chunkleft"', False)
    self.right = TaggedText().constant('', 'span class="chunkright"', False)
    if not self.name in NewfangledChunk.names:
      NewfangledChunk.names[self.name] = []
    else:
      last = NewfangledChunk.names[self.name][-1]
      forwardlink = Link().complete(self.number + u'→', 'chunkback:' + last.number, type='chunk')
      backlink = Link().complete(u'←' + last.number + u' ', 'chunkforward:' + self.number, type='chunk')
      forwardlink.setmutualdestination(backlink)
      last.right.contents.append(forwardlink)
      self.right.contents.append(backlink)
    NewfangledChunk.names[self.name].append(self)
    self.origin = self.createorigin()
    if self.name in NewfangledChunkRef.references:
      for ref in NewfangledChunkRef.references[self.name]:
        self.linkorigin(ref.origin)

  def createorigin(self):
    "Create a link that points to the chunks' origin."
    link = Link()
    self.linkorigin(link)
    return link

  def linkorigin(self, link):
    "Create a link to the origin."
    start = NewfangledChunk.names[self.name][0]
    link.complete(start.number, type='chunk')
    link.destination = start.leftlink
    link.computedestination()

  def declaration(self):
    "Get the chunk declaration."
    contents = []
    text = u'⟨' + self.name + '[' + unicode(len(NewfangledChunk.names[self.name])) + '] '
    contents.append(Constant(text))
    contents.append(self.origin)
    text = ''
    if NewfangledChunk.firsttime:
      Listing.processor = ChunkProcessor()
      NewfangledChunk.firsttime = False
    text += u'⟩'
    if len(NewfangledChunk.names[self.name]) > 1:
      text += '+'
    text += u'≡'
    contents.append(Constant(text))
    return TaggedText().complete(contents, 'span class="chunkdecl"', True)

class ChunkProcessor(object):
  "A processor for listings that belong to chunks."

  lastchunk = None
  counters = dict()
  endcommand = '}'
  chunkref = 'chunkref'

  def preprocess(self, listing):
    "Preprocess a listing: set the starting counter."
    if not ChunkProcessor.lastchunk:
      return
    name = ChunkProcessor.lastchunk.name
    if not name in ChunkProcessor.counters:
      ChunkProcessor.counters[name] = 0
    listing.counter = ChunkProcessor.counters[name]
    for command, container, index in self.commandsinlisting(listing):
      chunkref = self.getchunkref(command)
      if chunkref:
        self.insertchunkref(chunkref, container, index)

  def commandsinlisting(self, listing):
    "Find all newfangle commands in a listing."
    for container in listing.contents:
      for index in range(len(container.contents) - 2):
        if self.findinelement(container, index):
          third = container.contents[index + 2].string
          end = third.index(NewfangleConfig.constants['endmark'])
          command = third[:end]
          lenstart = len(NewfangleConfig.constants['startmark'])
          container.contents[index].string = container.contents[index].string[:-lenstart]
          del container.contents[index + 1]
          container.contents[index + 1].string = third[end + len(NewfangleConfig.constants['endmark']):]
          yield command, container, index

  def findinelement(self, container, index):
    "Find a newfangle command in an element."
    for i in range(2):
      if not isinstance(container.contents[index + i], StringContainer):
        return False
    first = container.contents[index].string
    second = container.contents[index + 1].string
    third = container.contents[index + 2].string
    if not first.endswith(NewfangleConfig.constants['startmark']):
      return False
    if second != NewfangleConfig.constants['startcommand']:
      return False
    if not NewfangleConfig.constants['endmark'] in third:
      return False
    return True

  def getchunkref(self, command):
    "Get the contents of a chunkref command, if present."
    if not command.startswith(NewfangleConfig.constants['chunkref']):
      return None
    if not NewfangleConfig.constants['endcommand'] in command:
      return None
    start = len(NewfangleConfig.constants['chunkref'])
    end = command.index(NewfangleConfig.constants['endcommand'])
    return command[start:end]

  def insertchunkref(self, ref, container, index):
    "Insert a chunkref after the given index at the given container."
    chunkref = NewfangledChunkRef().complete(ref)
    container.contents.insert(index + 1, chunkref)

  def postprocess(self, listing):
    "Postprocess a listing: store the ending counter for next chunk."
    if not ChunkProcessor.lastchunk:
      return
    ChunkProcessor.counters[ChunkProcessor.lastchunk.name] = listing.counter

class NewfangledChunkRef(Inset):
  "A reference to a chunk."

  references = dict()

  def process(self):
    "Show the reference."
    self.output.tag = 'span class="chunkref"'
    self.ref = self.extracttext()
    self.addbits()

  def complete(self, ref):
    "Complete the reference to the given string."
    self.output = ContentsOutput()
    self.ref = ref
    self.contents = [Constant(self.ref)]
    self.addbits()
    return self

  def addbits(self):
    "Add the bits to the reference."
    if not self.ref in NewfangledChunkRef.references:
      NewfangledChunkRef.references[self.ref] = []
    NewfangledChunkRef.references[self.ref].append(self)
    if self.ref in NewfangledChunk.names:
      start = NewfangledChunk.names[self.ref][0]
      self.origin = start.createorigin()
    else:
      self.origin = Link()
    self.contents.insert(0, Constant(u'⟨'))
    self.contents.append(Constant(' '))
    self.contents.append(self.origin)
    self.contents.append(Constant(u'⟩'))

  def __unicode__(self):
    "Return a printable representation."
    return 'Reference to chunk ' + self.ref






class SetCounterFunction(CommandBit):
  "A function which is used in the preamble to set a counter."

  def parsebit(self, pos):
    "Parse a function with [] and {} parameters."
    counter = self.parseliteral(pos)
    value = self.parseliteral(pos)
    try:
      self.setcounter(counter, int(value))
    except:
      Trace.error('Counter ' + counter + ' cannot be set to ' + value)

  def setcounter(self, counter, value):
    "Set a global counter."
    Trace.debug('Setting counter ' + unicode(counter) + ' to ' + unicode(value))
    NumberGenerator.generator.getcounter(counter).init(value)

class FormulaTag(CommandBit):
  "A \\tag command."

  def parsebit(self, pos):
    "Parse the tag and apply it."
    self.output = EmptyOutput()
    self.tag = self.parseliteral(pos)

class MiscCommand(CommandBit):
  "A generic command which maps to a command class."

  commandmap = FormulaConfig.misccommands

  def parsebit(self, pos):
    "Find the right command to parse and parse it."
    commandtype = globals()[self.translated]
    return self.parsecommandtype(self.translated, commandtype, pos)

FormulaCommand.types += [MiscCommand]



class ContainerFactory(object):
  "Creates containers depending on the first line"

  def __init__(self):
    "Read table that convert start lines to containers"
    types = dict()
    for start, typename in ContainerConfig.starts.iteritems():
      types[start] = globals()[typename]
    self.tree = ParseTree(types)

  def createcontainer(self, reader):
    "Parse a single container."
    #Trace.debug('processing "' + reader.currentline().strip() + '"')
    if reader.currentline() == '':
      reader.nextline()
      return None
    container = Cloner.create(self.tree.find(reader))
    container.start = reader.currentline().strip()
    self.parse(container, reader)
    return container

  def parse(self, container, reader):
    "Parse a container"
    parser = container.parser
    parser.parent = container
    parser.ending = self.getending(container)
    parser.factory = self
    container.header = parser.parseheader(reader)
    container.begin = parser.begin
    self.parsecontents(container, reader)
    container.parameters = parser.parameters
    container.parser = None

  def parsecontents(self, container, reader):
    "Parse the contents of a container."
    contents = container.parser.parse(reader)
    if isinstance(contents, basestring):
      # read a string, set as parsed
      container.parsed = contents
      container.contents = []
    else:
      container.contents = contents

  def getending(self, container):
    "Get the ending for a container"
    split = container.start.split()
    if len(split) == 0:
      return None
    start = split[0]
    if start in ContainerConfig.startendings:
      return ContainerConfig.startendings[start]
    classname = container.__class__.__name__
    if classname in ContainerConfig.endings:
      return ContainerConfig.endings[classname]
    if hasattr(container, 'ending'):
      Trace.error('Pending ending in ' + container.__class__.__name__)
      return container.ending
    return None

class ParseTree(object):
  "A parsing tree"

  default = '~~default~~'

  def __init__(self, types):
    "Create the parse tree"
    self.root = dict()
    for start, type in types.iteritems():
      self.addstart(type, start)

  def addstart(self, type, start):
    "Add a start piece to the tree"
    tree = self.root
    for piece in start.split():
      if not piece in tree:
        tree[piece] = dict()
      tree = tree[piece]
    if ParseTree.default in tree:
      Trace.error('Start ' + start + ' duplicated')
    tree[ParseTree.default] = type

  def find(self, reader):
    "Find the current sentence in the tree"
    branches = self.matchline(reader.currentline())
    while not ParseTree.default in branches[-1]:
      branches.pop()
    last = branches[-1]
    return last[ParseTree.default]

  def matchline(self, line):
    "Match a given line against the tree, as deep as possible."
    branches = [self.root]
    for piece in line.split(' '):
      current = branches[-1]
      piece = piece.rstrip('>')
      if piece in current:
        branches.append(current[piece])
      else:
        return branches
    return branches







class TOCEntry(Container):
  "A container for a TOC entry."

  def __init__(self):
    Container.__init__(self)
    self.branches = []

  def create(self, container):
    "Create the TOC entry for a container, consisting of a single link."
    if container.partkey.header:
      return self.header(container)
    self.contents = [self.createlink(container)]
    self.output = TaggedOutput().settag('div class="toc"', True)
    self.partkey = container.partkey
    return self

  def header(self, container):
    "Create a TOC entry for header and footer (0 depth)."
    self.partkey = container.partkey
    self.output = EmptyOutput()
    return self

  def createlink(self, container):
    "Create the link that will make the whole TOC entry."
    labels = container.searchall(Label)
    link = Link()
    if self.isanchor(labels):
      link.url = '#' + container.partkey.partkey
      if Options.tocfor:
        link.url = Options.tocfor + link.url
    else:
      label = labels[0]
      link.destination = label
    if container.partkey.tocentry:
      link.complete(container.partkey.tocentry)
    if container.partkey.titlecontents:
      if Options.notoclabels:
        separator = u' '
      else:
        separator = u': '
      if container.partkey.tocentry:
        link.contents.append(Constant(separator))
      link.contents += container.partkey.titlecontents
    return link

  def isanchor(self, labels):
    "Decide if the link is an anchor based on a set of labels."
    if len(labels) == 0:
      return True
    if not Options.tocfor:
      return False
    if Options.splitpart:
      return False
    return True

  def __unicode__(self):
    "Return a printable representation."
    if not self.partkey.tocentry:
      return 'Unnamed TOC entry'
    return 'TOC entry: ' + self.partkey.tocentry

class Indenter(object):
  "Manages and writes indentation for the TOC."

  def __init__(self):
    self.depth = 0

  def getindent(self, depth):
    indent = ''
    if depth > self.depth:
      indent = self.openindent(depth - self.depth)
    elif depth < self.depth:
      indent = self.closeindent(self.depth - depth)
    self.depth = depth
    return Constant(indent)

  def openindent(self, times):
    "Open the indenting div a few times."
    indent = ''
    for i in range(times):
      indent += '
\n' return indent def closeindent(self, times): "Close the indenting div a few times." indent = '' for i in range(times): indent += '
\n' return indent class IndentedEntry(Container): "An entry with an indentation." def __init__(self): self.output = ContentsOutput() def create(self, indent, entry): "Create the indented entry." self.entry = entry self.contents = [indent, entry] return self def __unicode__(self): "Return a printable documentation." return 'Indented ' + unicode(self.entry) class TOCTree(object): "A tree that contains the full TOC." def __init__(self): self.tree = [] self.branches = [] def store(self, entry): "Place the entry in a tree of entries." while len(self.tree) < entry.partkey.level: self.tree.append(None) if len(self.tree) > entry.partkey.level: self.tree = self.tree[:entry.partkey.level] stem = self.findstem() if len(self.tree) == 0: self.branches.append(entry) self.tree.append(entry) if stem: entry.stem = stem stem.branches.append(entry) def findstem(self): "Find the stem where our next element will be inserted." for element in reversed(self.tree): if element: return element return None class TOCConverter(object): "A converter from elyxer.containers to TOC entries." cache = dict() tree = TOCTree() def __init__(self): self.indenter = Indenter() def convertindented(self, container): "Convert a container into an indented TOC entry." entry = self.convert(container) if not entry: return None return self.indent(entry) def indent(self, entry): "Indent a TOC entry." indent = self.indenter.getindent(entry.partkey.level) return IndentedEntry().create(indent, entry) def convert(self, container): "Convert a container to a TOC entry." if not container.partkey: return None if container.partkey.partkey in self.cache: return TOCConverter.cache[container.partkey.partkey] if container.partkey.level > DocumentParameters.tocdepth: return None entry = TOCEntry().create(container) TOCConverter.cache[container.partkey.partkey] = entry TOCConverter.tree.store(entry) return entry class Basket(object): "A basket to place a set of containers. Can write them, store them..." def setwriter(self, writer): self.writer = writer return self class WriterBasket(Basket): "A writer of containers. Just writes them out to a writer." def write(self, container): "Write a container to the line writer." self.writer.write(container.gethtml()) def finish(self): "Mark as finished." self.writer.close() class KeeperBasket(Basket): "Keeps all containers stored." def __init__(self): self.contents = [] def write(self, container): "Keep the container." self.contents.append(container) def finish(self): "Finish the basket by flushing to disk." self.flush() def flush(self): "Flush the contents to the writer." for container in self.contents: self.writer.write(container.gethtml()) self.writer.close() class TOCBasket(Basket): "A basket to place the TOC of a document." def __init__(self): self.converter = TOCConverter() def setwriter(self, writer): Basket.setwriter(self, writer) Options.nocopy = True self.writer.write(LyXHeader().gethtml()) return self def write(self, container): "Write the table of contents for a container." entry = self.converter.convertindented(container) if entry: self.writer.write(entry.gethtml()) def finish(self): "Mark as finished." self.writer.write(LyXFooter().gethtml()) self.writer.close() class IntegralProcessor(object): "A processor for an integral document." def __init__(self): "Create the processor for the integral contents." self.storage = [] def locate(self, container): "Locate only containers of the processed type." return isinstance(container, self.processedtype) def store(self, container): "Store a new container." self.storage.append(container) def process(self): "Process the whole storage." for container in self.storage: self.processeach(container) class IntegralTOC(IntegralProcessor): "A processor for an integral TOC." processedtype = TableOfContents tocentries = [] def processeach(self, toc): "Fill in a Table of Contents." converter = TOCConverter() for container in PartKeyGenerator.partkeyed: toc.add(converter.convertindented(container)) # finish off with the footer to align indents toc.add(converter.convertindented(LyXFooter())) def writetotoc(self, entries, toc): "Write some entries to the TOC." for entry in entries: toc.contents.append(entry) class IntegralBiblioEntry(IntegralProcessor): "A processor for an integral bibliography entry." processedtype = BiblioEntry def processeach(self, entry): "Process each entry." number = NumberGenerator.generator.generate('integralbib') link = Link().complete('cite', 'biblio-' + number, type='biblioentry') link.contents = entry.citeref entry.contents = [Constant('['), link, Constant('] ')] if entry.key in BiblioCite.cites: for cite in BiblioCite.cites[entry.key]: cite.contents = entry.citeref cite.anchor = 'cite-' + number cite.destination = link class IntegralFloat(IntegralProcessor): "Store all floats in the document by type." processedtype = Float bytype = dict() def processeach(self, float): "Store each float by type." if not float.type in IntegralFloat.bytype: IntegralFloat.bytype[float.type] = [] IntegralFloat.bytype[float.type].append(float) class IntegralListOf(IntegralProcessor): "A processor for an integral list of floats." processedtype = ListOf def processeach(self, listof): "Fill in a list of floats." listof.output = TaggedOutput().settag('div class="fulltoc"', True) if not listof.type in IntegralFloat.bytype: Trace.message('No floats of type ' + listof.type) return for float in IntegralFloat.bytype[listof.type]: entry = self.processfloat(float) if entry: listof.contents.append(entry) def processfloat(self, float): "Get an entry for the list of floats." if not float.isparent(): return None return TOCEntry().create(float) class IntegralReference(IntegralProcessor): "A processor for a reference to a label." processedtype = Reference def processeach(self, reference): "Extract the text of the original label." reference.formatcontents() class MemoryBasket(KeeperBasket): "A basket which stores everything in memory, processes it and writes it." def __init__(self): "Create all processors in one go." KeeperBasket.__init__(self) self.processors = [ IntegralTOC(), IntegralBiblioEntry(), IntegralFloat(), IntegralListOf(), IntegralReference(), ] def finish(self): "Process everything which cannot be done in one pass and write to disk." self.process() self.flush() def process(self): "Process everything with the integral processors." self.searchintegral() for processor in self.processors: processor.process() def searchintegral(self): "Search for all containers for all integral processors." for container in self.contents: # container.tree() if self.integrallocate(container): self.integralstore(container) container.locateprocess(self.integrallocate, self.integralstore) def integrallocate(self, container): "Locate all integrals." for processor in self.processors: if processor.locate(container): return True return False def integralstore(self, container): "Store a container in one or more processors." for processor in self.processors: if processor.locate(container): processor.store(container) class SplitPartLink(IntegralProcessor): "A link processor for multi-page output." processedtype = Link def processeach(self, link): "Process each link and add the current page." link.page = self.page class NavigationLink(Container): "A link in the navigation header." def __init__(self, name): "Create the link for a given name (prev, next...)." self.name = name self.link = Link().complete(u' ', name, type=name) self.output = TaggedOutput().settag('span class="' + name + '"') self.contents = [self.link] def complete(self, container, after = False): "Complete the navigation link with destination container." "The 'after' parameter decides if the link goes after the part title." if not container.partkey: Trace.error('No part key for link name ' + unicode(container)) return self.link.contents = [Constant(Translator.translate(self.name))] partname = self.getpartname(container) separator = Constant(u' ') if after: self.contents = partname + [separator, self.link] else: self.contents = [self.link, separator] + partname def getpartname(self, container): "Get the part name for a container, title optional." partname = [Constant(container.partkey.tocentry)] if not container.partkey.titlecontents: return partname if Options.notoclabels: return container.partkey.titlecontents return partname + [Constant(': ')] + container.partkey.titlecontents def setdestination(self, destination): "Set the destination for this link." self.link.destination = destination def setmutualdestination(self, destination): "Set the destination for this link, and vice versa." self.link.setmutualdestination(destination.link) class UpAnchor(Link): "An anchor to the top of the page for the up links." def create(self, container): "Create the up anchor based on the first container." if not container.partkey: Trace.error('No part key for ' + unicode(container)) return None self.createliteral(container.partkey.tocentry) self.partkey.titlecontents = container.partkey.titlecontents return self def createmain(self): "Create the up anchor for the main page." return self.createliteral(Translator.translate('main-page')) def createliteral(self, literal): "Create the up anchor based on a literal string." self.complete('', '') self.output = EmptyOutput() self.partkey = PartKey().createanchor(literal) return self class SplitPartNavigation(object): "Used to create the navigation links for a new split page." def __init__(self): self.upanchors = [] self.lastcontainer = None self.nextlink = None self.lastnavigation = None def writefirstheader(self, basket): "Write the first header to the basket." anchor = self.createmainanchor() basket.write(anchor) basket.write(self.createnavigation(anchor)) def writeheader(self, basket, container): "Write the header to the basket." basket.write(LyXHeader()) basket.write(self.currentupanchor(container)) basket.write(self.createnavigation(container)) def writefooter(self, basket): "Write the footer to the basket." if self.lastnavigation: basket.write(self.lastnavigation) basket.write(LyXFooter()) def createnavigation(self, container): "Create the navigation bar with all links." prevlink = NavigationLink('prev') uplink = NavigationLink('up') if self.nextlink: prevlink.complete(self.lastcontainer) self.nextlink.complete(container, after=True) prevlink.setmutualdestination(self.nextlink) uplink.complete(self.getupdestination(container)) uplink.setdestination(self.getupdestination(container)) self.nextlink = NavigationLink('next') contents = [prevlink, Constant('\n'), uplink, Constant('\n'), self.nextlink] header = TaggedText().complete(contents, 'div class="splitheader"', True) self.lastcontainer = container self.lastnavigation = header return header def currentupanchor(self, container): "Update the internal list of up anchors, and return the current one." level = self.getlevel(container) while len(self.upanchors) > level: del self.upanchors[-1] while len(self.upanchors) < level: self.upanchors.append(self.upanchors[-1]) upanchor = UpAnchor().create(container) self.upanchors.append(upanchor) return upanchor def createmainanchor(self): "Create the up anchor to the main page." mainanchor = UpAnchor().createmain() self.upanchors.append(mainanchor) return mainanchor def getupdestination(self, container): "Get the name of the up page." level = self.getlevel(container) if len(self.upanchors) < level: uppage = self.upanchors[-1] else: uppage = self.upanchors[level - 1] return uppage def getlevel(self, container): "Get the level of the container." if not container.partkey: return 1 else: return container.partkey.level + 1 class SplitFileBasket(MemoryBasket): "A memory basket which contains a part split into a file, possibly with a TOC." def __init__(self): MemoryBasket.__init__(self) self.entrycount = 0 self.root = None self.converter = TOCConverter() def write(self, container): "Keep track of numbered layouts." MemoryBasket.write(self, container) if not container.partkey: return if container.partkey.header: return entry = self.converter.convert(container) if not entry: return self.entrycount += 1 self.root = entry def addtoc(self): "Add the table of contents if necessary." if self.entrycount != 1: return if self.root.branches == []: return text = Translator.translate('toc-for') + self.root.partkey.tocentry toc = TableOfContents().create(text) self.addbranches(self.root, toc) toc.add(self.converter.convertindented(LyXFooter())) self.write(toc) def addbranches(self, entry, toc): "Add an entry and all of its branches to the table of contents." for branch in entry.branches: toc.add(self.converter.indent(branch)) self.addbranches(branch, toc) class SplitPartBasket(Basket): "A basket used to split the output in different files." baskets = [] def setwriter(self, writer): if not hasattr(writer, 'filename') or not writer.filename: Trace.error('Cannot use standard output for split output; ' + 'please supply an output filename.') exit() self.writer = writer self.filename = writer.filename self.converter = TOCConverter() self.basket = MemoryBasket() self.basket.page = writer.filename return self def write(self, container): "Write a container, possibly splitting the file." self.basket.write(container) def splitbaskets(self): "Process the whole basket and create all baskets for split part pages." self.basket.process() basket = self.firstbasket() navigation = SplitPartNavigation() for container in self.basket.contents: if self.mustsplit(container): filename = self.getfilename(container) Trace.debug('New page ' + filename) basket.addtoc() navigation.writefooter(basket) basket = self.addbasket(filename) navigation.writeheader(basket, container) basket.write(container) if self.afterheader(container): navigation.writefirstheader(basket) self.mainanchor = navigation.upanchors[0] for basket in self.baskets: basket.process() def finish(self): "Process the whole basket, split into page baskets and flush all of them." self.splitbaskets() for basket in self.baskets: basket.flush() def afterheader(self, container): "Find out if this is the header on the file." return isinstance(container, LyXHeader) def firstbasket(self): "Create the first basket." return self.addbasket(self.filename, self.writer) def addbasket(self, filename, writer = None): "Add a new basket." if not writer: writer = LineWriter(filename) basket = SplitFileBasket() basket.setwriter(writer) self.baskets.append(basket) # set the page name everywhere basket.page = filename splitpartlink = SplitPartLink() splitpartlink.page = os.path.basename(basket.page) basket.processors = [splitpartlink] return basket def mustsplit(self, container): "Find out if the oputput file has to be split at this entry." if not container.partkey: return False if not container.partkey.filename: return False return True def getfilename(self, container): "Get the new file name for a given container." partname = container.partkey.filename basename = self.filename if Options.tocfor: basename = Options.tocfor base, extension = os.path.splitext(basename) return base + '-' + partname + extension class SplitTOCBasket(SplitPartBasket): "A basket which contains the TOC for a split part document." def finish(self): "Process the whole basket, split into page baskets and flush all of them." self.splitbaskets() tocbasket = TOCBasket().setwriter(self.writer) self.mainanchor.partkey = PartKey().createmain() tocbasket.write(self.mainanchor) for container in self.basket.contents: tocbasket.write(container) tocbasket.finish() class PostFormula(object): "Postprocess a formula" processedclass = Formula def postprocess(self, last, formula, next): "Postprocess any formulae" if Options.jsmath or Options.mathjax: return formula self.postnumbering(formula) return formula def postnumbering(self, formula): "Check if it's a numbered equation, insert number." if formula.header[0] != 'numbered': return functions = formula.searchremove(LabelFunction) if len(functions) == 0: label = self.createlabel(formula) elif len(functions) == 1: label = self.createlabel(formula, functions[0]) if len(functions) <= 1: label.parent = formula formula.contents.insert(0, label) return for function in functions: label = self.createlabel(formula, function) row = self.searchrow(function) label.parent = row row.contents.insert(0, label) def createlabel(self, formula, function = None): "Create a new label for a formula." "Add a label to a formula." tag = self.createtag(formula) partkey = PartKey().createformula(tag) if not formula.partkey: formula.partkey = partkey if not function: label = Label() label.create(partkey.tocentry + ' ', 'eq-' + tag, type="eqnumber") else: label = function.label label.complete(partkey.tocentry + ' ') return label def createtag(self, formula): "Create the label tag." tags = formula.searchall(FormulaTag) if len(tags) == 0: return NumberGenerator.chaptered.generate('formula') if len(tags) > 1: Trace.error('More than one tag in formula: ' + unicode(formula)) return tags[0].tag def searchrow(self, function): "Search for the row that contains the label function." if isinstance(function.parent, Formula) or isinstance(function.parent, FormulaRow): return function.parent return self.searchrow(function.parent) Postprocessor.stages.append(PostFormula) class eLyXerConverter(object): "Converter for a document in a lyx file. Places all output in a given basket." def __init__(self): self.filtering = False def setio(self, ioparser): "Set the InOutParser" self.reader = ioparser.getreader() self.basket = self.getbasket() self.basket.setwriter(ioparser.getwriter()) return self def getbasket(self): "Get the appropriate basket for the current options." if Options.tocfor: if Options.splitpart: return SplitTOCBasket() return TOCBasket() if Options.splitpart: return SplitPartBasket() if Options.memory: return MemoryBasket() return WriterBasket() def embed(self, reader): "Embed the results from elyxer.a reader into a memory basket." "Header and footer are ignored. Useful for embedding one document inside another." self.filtering = True self.reader = reader self.basket = MemoryBasket() return self def convert(self): "Perform the conversion for the document" try: self.processcontents() except (Exception): version = '[eLyXer version ' + GeneralConfig.version['number'] version += ' (' + GeneralConfig.version['date'] + ') in ' version += Options.location + '] ' Trace.error(version) Trace.error('Conversion failed at ' + self.reader.currentline()) raise def processcontents(self): "Parse the contents and write it by containers" factory = ContainerFactory() processor = Processor(self.filtering) while not self.reader.finished(): container = factory.createcontainer(self.reader) result = processor.process(container) self.writecontainer(result) result = processor.postprocess(None) self.writecontainer(result) if not self.filtering: self.basket.finish() def writecontainer(self, container): "Write each container to the correct basket." if not container: return includes = container.searchremove(IncludeInset) self.basket.write(container) # recursive processing for IncludeInset for include in includes: for element in include.contents: self.basket.write(element) def getcontents(self): "Return the contents of the basket." return self.basket.contents def __unicode__(self): "Printable representation." string = 'Converter with filtering ' + unicode(self.filtering) string += ' and basket ' + unicode(self.basket) return string class InOutParser(object): "Parse in and out arguments" def __init__(self): self.filein = sys.stdin self.fileout = sys.stdout def parse(self, args): "Parse command line arguments" self.filein = sys.stdin self.fileout = sys.stdout if len(args) < 2: Trace.quietmode = True if len(args) > 0: self.filein = args[0] del args[0] self.readdir(self.filein, 'directory') else: Options.directory = '.' if len(args) > 0: self.fileout = args[0] del args[0] self.readdir(self.fileout, 'destdirectory') else: Options.destdirectory = '.' if len(args) > 0: raise Exception('Unused arguments: ' + unicode(args)) return self def getreader(self): "Get the resulting reader." return LineReader(self.filein) def getwriter(self): "Get the resulting writer." return LineWriter(self.fileout) def readdir(self, filename, diroption): "Read the current directory if needed" if getattr(Options, diroption) != None: return setattr(Options, diroption, os.path.dirname(filename)) if getattr(Options, diroption) == '': setattr(Options, diroption, '.') class NullWriter(object): "A writer that goes nowhere." def write(self, list): "Do nothing." pass class ConverterFactory(object): "Create a converter fit for converting a filename and embedding the result." def create(self, container): "Create a converter for a given container, with filename" " and possibly other parameters." fullname = os.path.join(Options.directory, container.filename) reader = LineReader(container.filename) if 'firstline' in container.lstparams: reader.setstart(int(container.lstparams['firstline'])) if 'lastline' in container.lstparams: reader.setend(int(container.lstparams['lastline'])) return eLyXerConverter().embed(reader) IncludeInset.converterfactory = ConverterFactory() def convertdoc(args): "Read a whole document from the command line and write it." Options().parseoptions(args) ioparser = InOutParser().parse(args) converter = eLyXerConverter().setio(ioparser) converter.convert() def main(): "Main function, called if invoked from the command line" convertdoc(list(sys.argv)) if __name__ == '__main__': main() elyxer-1.2.5/forks/jras-elyxer/test/0000755000175000017500000000000012117061363016705 5ustar chennochennoelyxer-1.2.5/forks/jras-elyxer/test/index-1-6-lowmem-good.html0000644000175000017500000003177512117061342023441 0ustar chennochenno Index Test

Index Test

Table of Contents

Part I. The Making

1 Explanations

This chapter contains a lot of explanations for terms, which you might want to look up later. Because better sooner than later, although later has been repeated twice. Actually, thrice now.
Do you not want to look any of them up right now? No problem. You will be able to do it later, in the index.
Now we will add two cites in one, just because [1, 2].
As we will see in , not everything is clear.
You could also look down on someone, but that is not nice.

1.1Magical type face changes in the world

Little more can be added, at least at this point.

1.2Color and colour

At this other point, however, more could be added, but won’t.

Unnumbered Section

They have a right to live too.
  • A list would be nice here.
  • Because it corrupts the next chapter’s beginning.

2 Nomenclature

We should explain what an index is. We can do that with the nomenclature. Normally we will want to mix index and nomenclature terms. But what happens if we actually do? We will know later, when we generate the file.

2.1 Reminder

We have to remind the reader that things will be remembered.

2.2 Remainder

Whatever remains should be explained here.

Part II. The Additions

3 Bulk

We actually need a lot more text in order for our index to have more terms; so we can find out if the links are working. Since they are anchors inside the page, they might otherwise just take us to the top of the page, and we would not like that.
Yes, it would be bad for us. But on the other hand too much text can hide errors. So not much more text is needed.
Thanks for reading us.

Unnumbered Part

Unnumbered Chapter

This extra chapter contains nothing of interest except for a couple of unnumbered parts (one actual part and one chapter).
Table of Contents
List of Figures

Part III. Our Definition

4 The definition

A TOC is a Table Of Contents.

4.1 But I Already Knew That

You were lucky.

4.1.1 I Want My Money Back

There you have your 0€ back.

4.1.1.1 Completely Unfair Dude

Hey, I didn’t call you here.
A Paragraph For You
Totally uncalled for.
figure elyxer-svg.png
Figure 4.1 eLyXer logo

Unordered Section

Just to show that it works.
And now a list.
  1. First item.
  2. We will embed an ordered subsection here just to fake it.

    4.1.2 There We Go

  3. See if it’s in your TOC.
But There Is More
And nothing else.

A Appendix

An appendix here, an appendix there.

Index

able:

anchor:

error:

explained:

hand:

index: , , ,

later: , ,

link:

look:

down:

up: ,

page:

remembered:

sooner:

term:

terms:

text: , ,

thrice:

top of the page:

twice:

Nomenclature

generate An activity that requires a source and a destination, something like eLyXer does with files.
index A list of terms with a reference to where they occur.
nomenclature A list of common words with an explanation.

Bibliography

[-] WordReference.com: “definition of elixir”, accessed March 2009. http://www.wordreference.com/definition/elixir

[1] W3C: “HTML 4.01 Specification”, 24 December 1999. http://www.w3.org/TR/REC-html40/

[2] W3C: “HTML 4.01 Specification”, 24 December 1999. http://www.w3.org/TR/REC-html40/

elyxer-1.2.5/forks/jras-elyxer/test/decorations-1-6.lyx0000644000175000017500000003227412117061342022263 0ustar chennochenno#LyX 1.6.7 created this file. For more info see http://www.lyx.org/ \lyxformat 345 \begin_document \begin_header \textclass scrbook \begin_preamble % eLyXer -- convert LyX source files to HTML output. % % Copyright (C) 2009-2010 Alex Fernández % % This program is free software: 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 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 % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % DO NOT ALTER THIS PREAMBLE!!! % % This preamble is designed to ensure that the User's Guide prints % out as advertised. If you mess with this preamble, % parts of the User's Guide may not print out as expected. If you % have problems LaTeXing this file, please contact % the documentation team % email: lyx-docs@lists.lyx.org \usepackage{ifpdf} % part of the hyperref bundle \ifpdf % if pdflatex is used % set fonts for nicer pdf view \IfFileExists{lmodern.sty}{\usepackage{lmodern}}{} \fi % end if pdflatex is used % for correct jump positions whe clicking on a link to a float \usepackage[figure]{hypcap} % the pages of the TOC is numbered roman % and a pdf-bookmark for the TOC is added \let\myTOC\tableofcontents \renewcommand{\tableofcontents}{% \frontmatter \pdfbookmark[1]{\contentsname}{} \myTOC \mainmatter } % redefine the \LyX macro for PDF bookmarks \def\LyX{\texorpdfstring{% L\kern-.1667em\lower.25em\hbox{Y}\kern-.125emX\@} {LyX}} % define a short command for \textvisiblespace \newcommand{\spce}{\textvisiblespace} % macro for italic page numbers in the index \newcommand{\IndexDef}[1]{\textit{#1}} % redefine the greyed out note \end_preamble \options intoc,bibtotoc,idxtotoc,BCOR7mm,tablecaptionabove \use_default_options false \language english \inputencoding auto \font_roman default \font_sans default \font_typewriter default \font_default_family default \font_sc false \font_osf false \font_sf_scale 100 \font_tt_scale 100 \graphics default \paperfontsize 12 \spacing single \use_hyperref true \pdf_title "Decorations Test" \pdf_author "Alex Fernández" \pdf_subject "Taken from Guía de Usuario de Lyx, Ignacio García" \pdf_keywords "LyX" \pdf_bookmarks true \pdf_bookmarksnumbered true \pdf_bookmarksopen false \pdf_bookmarksopenlevel 1 \pdf_breaklinks false \pdf_pdfborder false \pdf_colorlinks true \pdf_backref false \pdf_pdfusetitle false \pdf_quoted_options "linkcolor=black, citecolor=black, urlcolor=blue, filecolor=blue,pdfpagelayout=OneColumn, pdfnewwindow=true,pdfstartview=XYZ, plainpages=false, pdfpagelabels,pdftex" \papersize default \use_geometry false \use_amsmath 1 \use_esint 0 \cite_engine basic \use_bibtopic false \paperorientation portrait \secnumdepth 3 \tocdepth 3 \paragraph_separation skip \defskip medskip \quotes_language english \papercolumns 1 \papersides 2 \paperpagestyle default \tracking_changes false \output_changes false \author "" \author "" \end_header \begin_body \begin_layout Title Decorations Test \end_layout \begin_layout Chapter Decorations \end_layout \begin_layout Standard A few examples taken from the Spanish Lyx User's Guide. \end_layout \begin_layout Standard An accent that looks like a hat: \begin_inset Formula $\hat{a}$ \end_inset , done using \series bold \backslash hat \begin_inset ERT status open \begin_layout Plain Layout \backslash spce \end_layout \end_inset a \series default within an equation. The following table shows commands to make decorations. \end_layout \begin_layout Standard \begin_inset Float table wide false sideways false status open \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout Decorations and commands. \end_layout \end_inset \end_layout \begin_layout Plain Layout \align center \begin_inset VSpace defskip \end_inset \begin_inset Tabular \begin_inset Text \begin_layout Plain Layout Name \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Command \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Sample \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout circumflex \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \series bold \backslash hat \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \begin_inset Formula $\hat{a}$ \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout grave \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \series bold \backslash grave \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \begin_inset Formula $\grave{m}$ \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout acute \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \series bold \backslash acute \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \begin_inset Formula $\acute{A}$ \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout diaeresis \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \series bold \backslash ddot \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \begin_inset Formula $\ddot{B}$ \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout tilde \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \series bold \backslash tilde \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \begin_inset Formula $\tilde{N}$ \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout dot \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \series bold \backslash dot \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \begin_inset Formula $\dot{L}$ \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout triple dot \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \series bold \backslash dddot \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \begin_inset Formula $\dddot{o}$ \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout breve \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \series bold \backslash breve \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \begin_inset Formula $\breve{g}$ \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout caron \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \series bold \backslash check \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \begin_inset Formula $\check{s}$ \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout bar \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \series bold \backslash bar \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \begin_inset Formula $\bar{l}$ \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout vector \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \series bold \backslash vec \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \begin_inset Formula $\vec{m}$ \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout long vector \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \series bold \backslash overrightarrow \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \begin_inset Formula $\overrightarrow{ABC}$ \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout wide hat \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \series bold \backslash widehat \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \begin_inset Formula $\widehat{house}$ \end_inset \end_layout \end_inset \end_inset \end_layout \end_inset \end_layout \begin_layout Standard Decorations should also appear correctly in unit names: \begin_inset Formula $100\mathrm{a\tilde{n}os}$ \end_inset and in superscripts: \begin_inset Formula $40^{100\mathrm{a\tilde{n}os}}$ \end_inset . \end_layout \begin_layout Standard That's all folks! \end_layout \end_body \end_document elyxer-1.2.5/forks/jras-elyxer/test/decorations-1-6-good.html0000644000175000017500000001106312117061342023332 0ustar chennochenno Decorations Test

Decorations Test

1 Decorations

A few examples taken from the Spanish Lyx User’s Guide.
An accent that looks like a hat: , done using \hat a within an equation. The following table shows commands to make decorations.
Table 1.1 Decorations and commands.
Name Command Sample
circumflex \hat
grave \grave
acute \acute
diaeresis \ddot
tilde \tilde
dot \dot
triple dot \dddot o⃛
breve \breve
caron \check
bar \bar l
vector \vec m⃗
long vector \overrightarrow ABC
wide hat \widehat ^house
Decorations should also appear correctly in unit names: 100 años and in superscripts: 40100 años.
That’s all folks!
elyxer-1.2.5/forks/jras-elyxer/test/math-1-6.lyx0000644000175000017500000005114112117061342020674 0ustar chennochenno#LyX 1.6.7 created this file. For more info see http://www.lyx.org/ \lyxformat 345 \begin_document \begin_header \textclass scrartcl \begin_preamble % eLyXer -- convert LyX source files to HTML output. % % Copyright (C) 2009-2010 Alex Fernández % % This program is free software: 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 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 % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % DO NOT ALTER THIS PREAMBLE!!! % % This preamble is designed to ensure that the User's Guide prints % out as advertised. If you mess with this preamble, % parts of the User's Guide may not print out as expected. If you % have problems LaTeXing this file, please contact % the documentation team % email: lyx-docs@lists.lyx.org \usepackage{ifpdf} % part of the hyperref bundle \ifpdf % if pdflatex is used % set fonts for nicer pdf view \IfFileExists{lmodern.sty}{\usepackage{lmodern}}{} \fi % end if pdflatex is used % for correct jump positions whe clicking on a link to a float \usepackage[figure]{hypcap} % the pages of the TOC is numbered roman % and a pdf-bookmark for the TOC is added \let\myTOC\tableofcontents \renewcommand{\tableofcontents}{% \frontmatter \pdfbookmark[1]{\contentsname}{} \myTOC \mainmatter } % redefine the \LyX macro for PDF bookmarks \def\LyX{\texorpdfstring{% L\kern-.1667em\lower.25em\hbox{Y}\kern-.125emX\@} {LyX}} % define a short command for \textvisiblespace \newcommand{\spce}{\textvisiblespace} % macro for italic page numbers in the index % test macro with a lot of spaces (bug #31243) \newcommand % Renewing a command with spaces and comments { \IndexDef } [1] { \textit {#1} } % test macro with two arguments \newcommand{\preambleroot}[2]{\sqrt[#1]{#2}} % redefine the greyed out note \usepackage{mathrsfs} \usepackage{upgreek} \end_preamble \options intoc,bibtotoc,idxtotoc,BCOR7mm,tablecaptionabove \use_default_options false \language english \inputencoding auto \font_roman default \font_sans default \font_typewriter default \font_default_family default \font_sc false \font_osf false \font_sf_scale 100 \font_tt_scale 100 \graphics default \paperfontsize 12 \spacing single \use_hyperref true \pdf_title "Math Test" \pdf_author "Alex Fernández" \pdf_subject "Taken from Guía de Usuario de Lyx, Ignacio García" \pdf_keywords "LyX" \pdf_bookmarks true \pdf_bookmarksnumbered true \pdf_bookmarksopen false \pdf_bookmarksopenlevel 1 \pdf_breaklinks false \pdf_pdfborder false \pdf_colorlinks true \pdf_backref false \pdf_pdfusetitle false \pdf_quoted_options "linkcolor=black, citecolor=black, urlcolor=blue, filecolor=blue,pdfpagelayout=OneColumn, pdfnewwindow=true,pdfstartview=XYZ, plainpages=false, pdfpagelabels,pdftex" \papersize default \use_geometry false \use_amsmath 1 \use_esint 0 \cite_engine basic \use_bibtopic false \paperorientation portrait \secnumdepth 3 \tocdepth 3 \paragraph_separation indent \defskip medskip \quotes_language english \papercolumns 1 \papersides 2 \paperpagestyle default \tracking_changes false \output_changes false \author "" \author "" \end_header \begin_body \begin_layout Title Math Test \end_layout \begin_layout Section Limits \end_layout \begin_layout Standard A limit: \begin_inset Formula \[ \lim_{x\rightarrow\infty}\lyxlock f(x),\] \end_inset which should appear as \begin_inset Formula $x\rightarrow\infty$ \end_inset in italics, and \begin_inset Quotes fld \end_inset lim \begin_inset Quotes frd \end_inset in plain style. Inlined: \begin_inset Formula $\lim_{x\rightarrow\infty}\lyxlock f(x)$ \end_inset . \end_layout \begin_layout Standard And why not, a sum: \begin_inset Formula \[ \sum_{i=1}^{\infty}a_{i},\] \end_inset where the sum's limits should appear below ( \begin_inset Formula $i=1$ \end_inset ) and above ( \begin_inset Formula $\infty$ \end_inset ) the \begin_inset Formula $\sum$ \end_inset but to the right. Inlined: \begin_inset Formula $\sum_{i=1}^{\infty}a_{i}.$ \end_inset Integral: \begin_inset Formula $\intop_{x=a}^{\infty}x\,\text{d}x.$ \end_inset Display mode: \begin_inset Formula \[ \intop_{x=a}^{\infty}x\,\text{d}x.\] \end_inset \end_layout \begin_layout Standard We can also integrate without limits: \begin_inset Formula $\int A\,\text{d}x$ \end_inset . \end_layout \begin_layout Standard A sum inside another element (red color): \end_layout \begin_layout Standard \begin_inset Formula \[ \textcolor{red}{\sum_{i=1}^{\infty}a_{i}}.\] \end_inset \end_layout \begin_layout Standard The placing of limits can be cofigured with the \family typewriter \backslash limits \family default and \family typewriter \backslash nolimits \family default macros: \begin_inset Formula \[ \lim\nolimits _{x\rightarrow\infty}\lyxlock f(x),\;\sum\nolimits _{i=1}^{\infty}x,\;\int\limits _{0}^{\infty}f(x)\,\mathrm{d}x\] \end_inset \end_layout \begin_layout Subsection Super- and Subscript \end_layout \begin_layout Standard When any element has both super- and subscript, they should appear like inlined limits, one above the other: \begin_inset Formula $a_{4}^{3}$ \end_inset . Also before an element: \begin_inset Formula $_{2}^{3}\text{He}$ \end_inset . In display mode: \end_layout \begin_layout Standard \begin_inset Formula \[ \sum_{i,j}a_{j}^{i}+\sum_{i,j}a_{i}^{j}=\sum_{i}a_{i}^{i},\] \end_inset \begin_inset Formula \[ _{1}^{2}\text{H}+{}_{1}^{2}\text{H}\rightarrow{}_{2}^{3}\text{He}+{}_{0}^{1}\text{n}.\] \end_inset \end_layout \begin_layout Section Numeration \end_layout \begin_layout Standard Equations can be numbered, like \begin_inset CommandInset ref LatexCommand ref reference "eq:first" \end_inset . \end_layout \begin_layout Standard \begin_inset Formula \begin{equation} y=x\label{eq:first}\end{equation} \end_inset \end_layout \begin_layout Standard And also like \begin_inset CommandInset ref LatexCommand ref reference "eq:second" \end_inset . \end_layout \begin_layout Standard \begin_inset Formula \begin{equation} x=3\label{eq:second}\end{equation} \end_inset \end_layout \begin_layout Standard Notice that eq. \begin_inset CommandInset ref LatexCommand ref reference "eq:second" \end_inset comes after eq. \begin_inset CommandInset ref LatexCommand ref reference "eq:first" \end_inset . \end_layout \begin_layout Standard Some equations can also be numbered, even if they don't have a label. \end_layout \begin_layout Standard \begin_inset Formula \begin{equation} x=2y\end{equation} \end_inset \end_layout \begin_layout Standard Other equations that contain * should not numbered, but perhaps aligned: \end_layout \begin_layout Standard \begin_inset Formula \begin{align*} left & & right\end{align*} \end_inset \end_layout \begin_layout Standard Some environments allow for multiple labels: \begin_inset Formula \begin{eqnarray} a & = & b\times c\label{eq:third}\\ c\times d\times e & = & i.\label{eq:fourth}\end{eqnarray} \end_inset \end_layout \begin_layout Standard Now a random environment: \begin_inset Formula $\begin{gathered}x\end{gathered} y$ \end_inset . \end_layout \begin_layout Section Brackets \end_layout \begin_layout Standard An array: \begin_inset Formula \[ \left[\begin{array}{lc} 12 & 2\\ 3 & 4\times y^{x}\end{array}\right]\] \end_inset And an inline array \begin_inset Formula $\left[\begin{array}[t]{cc} a & b\\ c & dio\end{array}\right]$ \end_inset . \end_layout \begin_layout Standard Arrays are separated by variable-size brackets: \begin_inset Formula $\left(\begin{array}{cc} a & b\\ c & d\end{array}\right)$ \end_inset \begin_inset Formula $\left[\begin{array}{cc} a & b\\ c & d\end{array}\right]$ \end_inset \begin_inset Formula $\left\{ \begin{array}{cc} a & b\\ c & d\end{array}\right\} $ \end_inset \begin_inset Formula $\left\langle \begin{array}{cc} a & b\\ c & d\end{array}\right\rangle $ \end_inset \begin_inset Formula $\left|\begin{array}{cc} a & b\\ c & d\end{array}\right|$ \end_inset which might also differ on right and left \begin_inset Formula $\left(\begin{array}{cc} a & b\\ c & d\end{array}\right)$ \end_inset or use the empty opening \begin_inset Formula $\left\{ \begin{array}{cc} a & b\\ c & d\end{array}\right.$ \end_inset or closing: \begin_inset Formula $\left.\begin{array}{cc} a & b\\ c & d\end{array}\right|$ \end_inset . There are also fixed-size big brackets: \begin_inset Formula $\left(a\right)$ \end_inset \begin_inset Formula $\left[b\right]$ \end_inset \begin_inset Formula $\left\{ c\right\} $ \end_inset \begin_inset Formula $\left\langle d\right\rangle $ \end_inset \begin_inset Formula $\left|e\right|$ \end_inset \begin_inset Formula $\bigl\langle f\bigr\rangle$ \end_inset . \end_layout \begin_layout Standard Aligned brackets can be present: \begin_inset Formula $\left(toText\right)$ \end_inset . One of them may be omitted: \begin_inset Formula $\left.toText\right)$ \end_inset . \end_layout \begin_layout Standard Aligned brackets can be applied to complex items: \begin_inset Formula \[ s\times\left(1+\left(\begin{array}{cc} a_{11} & a_{21}\\ a_{12} & a_{22}\end{array}\right)\times\left(\begin{array}{cc} 1 & -1\\ -1 & -1\end{array}\right)+\left\Vert \begin{array}{ccc} 1 & -1 & 0\\ -1 & 1 & 0\\ 0 & 0 & r\end{array}\right\Vert \right).\] \end_inset \end_layout \begin_layout Standard Math brackets should not be mistaken for TeX brackets: \begin_inset Formula $\frac{\mathcal{F}\left\{ s(x)\right\} }{2}$ \end_inset . \end_layout \begin_layout Section Fraction \end_layout \begin_layout Standard A big recursive fraction: \begin_inset Formula \[ \frac{1}{\left(1+\left(\frac{1}{1+\left(\frac{1}{1+2x}\lyxlock\right)}\lyxlock\right)\right)}\lyxlock\] \end_inset \end_layout \begin_layout Standard A nice fraction: \begin_inset Formula $\nicefrac{5}{6}$ \end_inset . \end_layout \begin_layout Standard A non-diminishing fraction containing alignments: \begin_inset Formula \[ \cfrac{1}{1+\left(\cfrac[l]{1}{1+x}\times\cfrac[r]{1}{1+x}\right)}.\] \end_inset \end_layout \begin_layout Standard A similar concept is a binomial coefficient: \begin_inset Formula $\binom{A+1}{B}.$ \end_inset It can be prettily presented: \begin_inset Formula \[ \dbinom{A}{B+1}.\] \end_inset \end_layout \begin_layout Standard A symbol can be stacked over another using \family typewriter \backslash stackrel \family default : \begin_inset Formula $x\stackrel{R}{\rightarrow}y$ \end_inset . Anything can be stacked: \begin_inset Formula $\stackrel{head}{heels}$ \end_inset . \end_layout \begin_layout Section Roots \end_layout \begin_layout Standard A square root: \begin_inset Formula $\sqrt{3}.$ \end_inset A root in a fraction: \begin_inset Formula $\sqrt{\frac{(78x+45y)\times\sqrt{Height}}{\sin(x+1)}+5}.$ \end_inset \end_layout \begin_layout Standard A more complex square root in a fraction: \begin_inset Formula \[ \frac{1}{\left(1+\sqrt{2}\left(\frac{1}{1+\sqrt{2}}\lyxlock\right)+\sqrt{\frac{1}{2}}\right)}\lyxlock.\] \end_inset \end_layout \begin_layout Standard Higher order roots: \begin_inset Formula $\sqrt[3]{x+y}$ \end_inset , \begin_inset Formula $\sqrt[x+1]{Weight}$ \end_inset . In a fraction: \begin_inset Formula \[ \frac{\sqrt[\nicefrac{7}{8}]{\frac{8}{4}x}}{\sqrt[s+5]{\frac{(78x+45y)\times\sqrt{Height}}{\sin(x+1)}+5}}\lyxlock.\] \end_inset \end_layout \begin_layout Section Decorations \end_layout \begin_layout Subsection Cases \end_layout \begin_layout Standard Used to switch several values. \end_layout \begin_layout Standard \begin_inset Formula \[ y=\begin{cases} x & i=0,\\ x+1 & i<3\end{cases}\] \end_inset \end_layout \begin_layout Standard Cases may have more than two rows: \end_layout \begin_layout Standard \begin_inset Formula \[ f(x)=\begin{cases} 0 & x<0,\\ \infty & x=0,\\ 0 & x>0\end{cases}\] \end_inset \end_layout \begin_layout Subsection Braces \end_layout \begin_layout Standard Values can be underbraced or overbraced. \begin_inset Formula \[ \underbrace{a-b}=\overbrace{c+d+e}+f.\] \end_inset \end_layout \begin_layout Standard Underbraces and overbraces can contain text. \begin_inset Formula \[ \overbrace{a-b}^{over}=\underbrace{c+\overbrace{d+e}^{over}+f}_{under}+g.\] \end_inset They can also be inlined: \begin_inset Formula $\overbrace{a+b}^{over}$ \end_inset . \end_layout \begin_layout Section Spacing \end_layout \begin_layout Standard The command \family typewriter \backslash raisebox \family default is useful to, surprisingly, raise a little box, \begin_inset Formula \[ \raisebox{2mm}{raised}over\raisebox{-2mm}{lowered}\textrm{ and back}.\] \end_inset Like \family typewriter \backslash mbox \family default , it puts its content in a text box. It can also be used just for spacing: \begin_inset Newline newline \end_inset \begin_inset Formula $\raisebox{5mm}{}B^{V}$ \end_inset . \end_layout \begin_layout Standard There are other spacing commands: \family typewriter \backslash hspace \family default \begin_inset Formula $a\hspace{4mm}b$ \end_inset , protected space \begin_inset Formula $a\ b$ \end_inset , and at \begin_inset Quotes eld \end_inset block level \begin_inset Quotes erd \end_inset \family typewriter \backslash vspace \family default : \begin_inset Formula $a\vspace{1cm}b$ \end_inset . \end_layout \begin_layout Standard There should be 1 \begin_inset space ~ \end_inset cm of vertical space above this paragraph. \end_layout \begin_layout Section Fonts \end_layout \begin_layout Standard This section tests font support. \end_layout \begin_layout Subsection Variables and Functions \end_layout \begin_layout Standard By default, letters denote variables and are taken from the \family typewriter \backslash mathnormal \family default font, which is italic: \begin_inset Formula $\alpha x+\alpha y=\alpha(x+y)$ \end_inset , with the exception of upright capital Greek letters, \begin_inset Formula $G\ne\Gamma$ \end_inset . Letters run together represent different variables: \begin_inset Formula $abcd=a\times b\times c\times d$ \end_inset . \end_layout \begin_layout Standard There has been some trouble over some commands like Greek letters; some of them should be italicized, as in: \begin_inset Formula $\mu$ \end_inset or \begin_inset Formula $\AA$ \end_inset . Others should not, as in \begin_inset Formula $\Omega$ \end_inset . Upright Greek letters are also available: \begin_inset Formula $\upmu\neq\mu$ \end_inset . An example from the LyX math guide: \begin_inset Formula \[ \uppi^{+}\to\upmu^{+}+\upnu_{\upmu}.\] \end_inset \end_layout \begin_layout Standard Functions names should be upright: \begin_inset Formula $\sin(2\pi),\log(x),\tan\delta$ \end_inset . \end_layout \begin_layout Subsection Mathematical Fonts \end_layout \begin_layout Standard Mathematical fonts used in equations include \begin_inset Formula $\mathrm{Roman}$ \end_inset ( \family typewriter \backslash mathrm \family default ), \begin_inset Formula $\mathsf{Sans\: Serif}$ \end_inset ( \family typewriter \backslash mathsf \family default ), \begin_inset Formula $\mathtt{Typewriter}$ \end_inset ( \family typewriter \backslash mathtt \family default ), \begin_inset Formula $\mathbf{Bold}$ \end_inset ( \family typewriter \backslash mathbf \family default ), \begin_inset Formula $\mathscr{SCRIPT}$ \end_inset ( \family typewriter \backslash mathscr \family default ), \begin_inset Formula $\mathcal{CALLIGRAPHIC}$ \end_inset ( \family typewriter \backslash mathcal \family default ), \begin_inset Formula $\mathbb{BLACKBOARD\: BOLD}$ \end_inset ( \family typewriter \noun on \backslash \noun default mathbb \family default ), and \begin_inset Formula $\mathfrak{Fraktur}$ \end_inset ( \family typewriter \backslash mathfrak \family default ). For the latter, some single characters are translated to their Unicode equivalents: \begin_inset Formula $\mathscr{F}$ \end_inset , \begin_inset Formula $\mathbb{F}$ \end_inset , \begin_inset Formula $\mathfrak{F}$ \end_inset . \end_layout \begin_layout Standard Regular text in a formula can be achieved via text font commands like \family typewriter \backslash textrm \family default : \begin_inset Formula $5\:\textrm{to}\:10$ \end_inset , via boxes like \backslash mbox (prevents line breaks): \begin_inset Formula $6\mbox{ is more than }5$ \end_inset , or the AMSmath \family typewriter \backslash text \family default macro (scales like math symbols) \begin_inset Formula $\text{base}_{\text{sub}}^{\text{super}}$ \end_inset . The content of an mbox is processed in LaTeX text mode. This allows text font commands, e.g. a switch to \family sans \series bold \shape italic sans-serif-bold-italic \family default \series default \shape default , or the phonetic alphabet: \begin_inset Formula $\mbox{\textbf{\textsf{\textbf{\textit{sfbfit}}}}, \textipa{tipa}}$ \end_inset . \end_layout \begin_layout Subsection Units \end_layout \begin_layout Standard Units should be written upright, either with \family typewriter \backslash mathrm \family default or with macros from the \family typewriter units \family default package, e.g. as simple unit, \begin_inset Formula $\unit{km}$ \end_inset , with magnitude, \begin_inset Formula $\unit[57]{km}$ \end_inset , with fractional unit, \begin_inset Formula $\unitfrac[200]{km}{h}$ \end_inset , or with a fraction before the units, \begin_inset Formula $\unit[\nicefrac{3}{2}]{km}$ \end_inset , \begin_inset Formula $\unit[\frac{7}{16}]{s}$ \end_inset . \end_layout \begin_layout Subsection Sizes \end_layout \begin_layout Standard Sizes can be specified in formulas: \begin_inset Formula ${\displaystyle \text{display}},{\textstyle \text{text}},{\scriptstyle \text{script}},{\scriptscriptstyle \text{scriptscript}}$ \end_inset . \end_layout \begin_layout Section Colors and Boxes \end_layout \begin_layout Standard A colored box: \begin_inset Formula $\colorbox{red}{aaa}$ \end_inset . \end_layout \begin_layout Standard A framed box: \begin_inset Formula $\framebox[2cm][c]{box}$ \end_inset . It can be aligned left: \begin_inset Formula $\framebox[2cm][l]{box}$ \end_inset or right: \begin_inset Formula $\framebox[2cm][r]{box}$ \end_inset . \end_layout \begin_layout Section Macros \end_layout \begin_layout Standard Definitions can be added as macros \begin_inset FormulaMacro \renewcommand{\stupidroot}[2]{\sqrt[#1]{#2}} {\sqrt[#1]{#2}} \end_inset . Then they can be used in formulae: \begin_inset Formula $\stupidroot{}{12}+\stupidroot 12$ \end_inset . \end_layout \begin_layout Standard Macro definitions can accept default parameters \begin_inset FormulaMacro \renewcommand{\defaultroot}[2][4][5]{\sqrt[#1]{#2}} {#1\sqrt{#2}} \end_inset . Again, useful in formulae: \begin_inset Formula $\defaultroot$ \end_inset . Default parameters can then be overriden: \begin_inset Formula $\defaultroot[][y]+\defaultroot[x]$ \end_inset . \end_layout \begin_layout Standard Other definitions from the preamble can be used: \begin_inset Formula $\preambleroot{3}{4}$ \end_inset . \end_layout \begin_layout Standard Definitions on the fly are also possible: \begin_inset Formula $\newcommand{\ontheflyroot}[2]{\sqrt[#1]{#2}}\ontheflyroot{7}{8}$ \end_inset , and used with different values: \begin_inset Formula $\ontheflyroot{a}{b}$ \end_inset . \end_layout \begin_layout Standard Macros may contain a literal parameter \begin_inset FormulaMacro \renewcommand{\colort}[1]{\colorbox{#1}{t}} {\colorbox{#1}{t}} \end_inset . It should parse correctly: \begin_inset Formula $\colort{red}$ \end_inset . \end_layout \begin_layout Standard A macro with four parameters from the LyX detailed math guide \begin_inset FormulaMacro \renewcommand{\qG}[4][1,\,2]{#2_{#1}=-\frac{#3}{2}\pm\sqrt{\frac{#3^{2}}{4}-#4}} \end_inset . Now in use: \begin_inset Formula $1+\qG x{(1-x)}5-B$ \end_inset . \end_layout \begin_layout Section Pathological Cases \end_layout \begin_layout Standard Empty equations have been known to fail: \begin_inset Formula $ $ \end_inset . \end_layout \begin_layout Standard An equation with an mbox containing a comment: \begin_inset Formula $\mbox{text %comment more}$ \end_inset , and a comment inside textrm: \begin_inset Formula $\textrm{text %comment more}$ \end_inset . Finally, a comment at the end of a text function: \begin_inset Formula $\mbox{only text%comment }$ \end_inset . \end_layout \begin_layout Section Bye-bye \end_layout \begin_layout Standard That's all folks! \end_layout \end_body \end_document elyxer-1.2.5/forks/jras-elyxer/test/appendix-1-6.lyx0000644000175000017500000005244412117061342021562 0ustar chennochenno#LyX 1.6.5 created this file. For more info see http://www.lyx.org/ \lyxformat 345 \begin_document \begin_header \textclass scrbook \begin_preamble % eLyXer -- convert LyX source files to HTML output. % % Copyright (C) 2009-2010 Alex Fernández % % This program is free software: 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 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 % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % DO NOT ALTER THIS PREAMBLE!!! % % This preamble is designed to ensure that the User's Guide prints % out as advertised. If you mess with this preamble, % parts of the User's Guide may not print out as expected. If you % have problems LaTeXing this file, please contact % the documentation team % email: lyx-docs@lists.lyx.org \usepackage{ifpdf} % part of the hyperref bundle \ifpdf % if pdflatex is used % set fonts for nicer pdf view \IfFileExists{lmodern.sty}{\usepackage{lmodern}}{} \fi % end if pdflatex is used % for correct jump positions whe clicking on a link to a float \usepackage[figure]{hypcap} % the pages of the TOC is numbered roman % and a pdf-bookmark for the TOC is added \let\myTOC\tableofcontents \renewcommand{\tableofcontents}{% \frontmatter \pdfbookmark[1]{\contentsname}{} \myTOC \mainmatter } % redefine the \LyX macro for PDF bookmarks \def\LyX{\texorpdfstring{% L\kern-.1667em\lower.25em\hbox{Y}\kern-.125emX\@} {LyX}} % define a short command for \textvisiblespace \newcommand{\spce}{\textvisiblespace} % macro for italic page numbers in the index \newcommand{\IndexDef}[1]{\textit{#1}} % redefine the greyed out note \end_preamble \options intoc,bibtotoc,idxtotoc,BCOR7mm,tablecaptionabove \use_default_options false \language english \inputencoding auto \font_roman default \font_sans default \font_typewriter default \font_default_family default \font_sc false \font_osf false \font_sf_scale 100 \font_tt_scale 100 \graphics default \paperfontsize 12 \spacing single \use_hyperref true \pdf_title "Appendix Test" \pdf_author "Alex Fernández" \pdf_subject "Containing Numeration and Other Appendixy things" \pdf_keywords "LyX eLyXer" \pdf_bookmarks true \pdf_bookmarksnumbered true \pdf_bookmarksopen false \pdf_bookmarksopenlevel 1 \pdf_breaklinks false \pdf_pdfborder false \pdf_colorlinks true \pdf_backref false \pdf_pdfusetitle false \pdf_quoted_options "linkcolor=black, citecolor=black, urlcolor=blue, filecolor=blue,pdfpagelayout=OneColumn, pdfnewwindow=true,pdfstartview=XYZ, plainpages=false, pdfpagelabels,pdftex" \papersize default \use_geometry false \use_amsmath 1 \use_esint 0 \cite_engine basic \use_bibtopic false \paperorientation portrait \secnumdepth 3 \tocdepth 3 \paragraph_separation skip \defskip medskip \quotes_language english \papercolumns 1 \papersides 2 \paperpagestyle default \tracking_changes false \output_changes false \author "" \author "" \end_header \begin_body \begin_layout Title Appendix Test \end_layout \begin_layout Author Alex Fernández (elyxer@gmail.com) \end_layout \begin_layout Standard \begin_inset CommandInset toc LatexCommand tableofcontents \end_inset \end_layout \begin_layout Standard \begin_inset FloatList figure \end_inset \end_layout \begin_layout Standard \begin_inset FloatList table \end_inset \end_layout \begin_layout Part Of How Our Hero Came and Went \end_layout \begin_layout Chapter The Coming \end_layout \begin_layout Standard Our hero came in. He was tired. He thought the world belonged to him. \end_layout \begin_layout Section The Meeting \end_layout \begin_layout Standard Our hero met with Laurinda. She was smiling. But our hero was not amused. His whiskers were dripping wet, he was astonishingly thirsty, and the contradic tion was killing him. \begin_inset Quotes eld \end_inset Give me some beer, woman! \begin_inset Quotes erd \end_inset , he ordered. \end_layout \begin_layout Section The Melting \end_layout \begin_layout Standard Laurinda smiled again. \begin_inset Quotes eld \end_inset But Wenceslau, you don't belong here. \begin_inset Quotes erd \end_inset What a stupid thing to say at that precise moment, our hero thought to himself. Only that it came out loud. At that precise moment he knew that the desired beer would not be forthcoming. \end_layout \begin_layout Standard He turned to the bartender and tried to obtain a beer by the very old method of purchasing it. But being ignored was not one of Laurinda's specialities. \end_layout \begin_layout Chapter The Going \end_layout \begin_layout Standard It could not last. Laurinda's hips were flapping, and she was hopping mad. \end_layout \begin_layout Section Our Hero's Imagination \end_layout \begin_layout Standard Our hero imagined her as a rabbit with long ears and a fine set of tusks. In a short time the image drifted to a walrus, and our hero could not help letting his sinister smile giving him away. Figure \begin_inset CommandInset ref LatexCommand ref reference "fig:rabbit-walrus" \end_inset shows a gross approximation of the rabbit-walrus. \end_layout \begin_layout Standard \begin_inset Float figure wide false sideways false status open \begin_layout Plain Layout \align center \begin_inset Graphics filename rabbit-walrus.svg \end_inset \end_layout \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout \begin_inset CommandInset label LatexCommand label name "fig:rabbit-walrus" \end_inset The rabbit-walrus. \end_layout \end_inset \end_layout \begin_layout Plain Layout \end_layout \end_inset \end_layout \begin_layout Section Laurinda's Anger \end_layout \begin_layout Standard \begin_inset Quotes eld \end_inset Wasn't it great \begin_inset Quotes erd \end_inset , said Laurinda. Actually she said it in the present tense, but our poor storytelling skills have changed that to a cheesy past. Don't do this at home, kids. You want to be regarded for your authenticity, and misquoting isn't going to help much. \end_layout \begin_layout Standard Anyway, back to the story. Laurinda wanted to hit him in the head with a big ham that she kept just for occassions like this, and being a solid Hitchcock fan she was ready to cook the ham afterwards and serve the resulting stew to any policemen that might come by. She was also a huge Almodóvar fan, but she was unaware that in an early film the divine Pedro had copied the scene. Actually both directors had copied the idea from a short story by Roald Dahl, very much worth reading. Although it must be said that in this story it was a lamb leg, which hardly offers the consistency and stiffness necessary to kill a sturdy husband. \end_layout \begin_layout Standard But who cares. Laurinda meanwhile had a funny appearance; if you want to see why please direct your eyes to figure \begin_inset CommandInset ref LatexCommand ref reference "fig:anger" \end_inset . \end_layout \begin_layout Standard \begin_inset Float figure wide false sideways false status open \begin_layout Plain Layout \align center \begin_inset Graphics filename laurindas-anger.svg \end_inset \end_layout \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout \begin_inset CommandInset label LatexCommand label name "fig:anger" \end_inset Laurinda's anger pictured in a mildly humorous tone. \end_layout \end_inset \end_layout \end_inset \end_layout \begin_layout Standard And yet, how furious was really Laurinda, whom we may optionally refer to as Melinda from now on? Table \begin_inset CommandInset ref LatexCommand ref reference "tab:anger-time" \end_inset vainly attempts to quantify it. \end_layout \begin_layout Standard \begin_inset Float table wide false sideways false status open \begin_layout Plain Layout \align center \begin_inset Tabular \begin_inset Text \begin_layout Plain Layout Anger \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Time \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 1 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 2 \end_layout \end_inset \end_inset \end_layout \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout \begin_inset CommandInset label LatexCommand label name "tab:anger-time" \end_inset Laurinda's anger as a function of time. \end_layout \end_inset \end_layout \end_inset \end_layout \begin_layout Standard For the sake of Laurinda's furiousness, here is figure \begin_inset CommandInset ref LatexCommand ref reference "fig:anger-again" \end_inset again. \end_layout \begin_layout Standard \begin_inset Float figure wide false sideways false status open \begin_layout Plain Layout \align center \begin_inset Graphics filename laurindas-anger.svg \end_inset \end_layout \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout \begin_inset CommandInset label LatexCommand label name "fig:anger-again" \end_inset Laurinda's anger, again. \end_layout \end_inset \end_layout \end_inset \end_layout \begin_layout Standard But how did Laurinda compute her anger? We cannot but speculate; here is a stupid suggestion in listing \begin_inset CommandInset ref LatexCommand ref reference "alg:computation" \end_inset . \end_layout \begin_layout Standard \begin_inset Float algorithm wide false sideways false status open \begin_layout Plain Layout anger = time - 1 \end_layout \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout \begin_inset CommandInset label LatexCommand label name "alg:computation" \end_inset Laurinda computes her anger. \end_layout \end_inset \end_layout \begin_layout Plain Layout \end_layout \end_inset \end_layout \begin_layout Standard The result is in table \begin_inset CommandInset ref LatexCommand ref reference "tab:anger-time-again" \end_inset , proving we were right all along. Also subtables \begin_inset CommandInset ref LatexCommand ref reference "tab:Only-Anger" \end_inset and \begin_inset CommandInset ref LatexCommand ref reference "tab:Only-Time" \end_inset show anger and time, respectively. \end_layout \begin_layout Standard \begin_inset Float table wide false sideways false status open \begin_layout Plain Layout \align center \begin_inset Float table wide false sideways false status open \begin_layout Plain Layout \align center \begin_inset Tabular \begin_inset Text \begin_layout Plain Layout Anger \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 1 \end_layout \end_inset \end_inset \end_layout \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout \begin_inset CommandInset label LatexCommand label name "tab:Only-Anger" \end_inset Only Anger. \end_layout \end_inset \end_layout \end_inset \begin_inset Float table wide false sideways false status open \begin_layout Plain Layout \align center \begin_inset Tabular \begin_inset Text \begin_layout Plain Layout Time \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 2 \end_layout \end_inset \end_inset \begin_inset Caption \begin_layout Plain Layout \begin_inset CommandInset label LatexCommand label name "tab:Only-Time" \end_inset Only Time. \end_layout \end_inset \end_layout \end_inset \end_layout \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout \begin_inset CommandInset label LatexCommand label name "tab:anger-time-again" \end_inset Laurinda's anger quantified, divided in two. \end_layout \end_inset \end_layout \end_inset \end_layout \begin_layout Standard Interested in that last table? Let us repeat it but without a label and with a table and a subtable \begin_inset CommandInset ref LatexCommand ref reference "tab:rabbit-walrus-encore" \end_inset . \end_layout \begin_layout Standard \begin_inset Float table wide false sideways false status open \begin_layout Plain Layout \align center \begin_inset Float table wide false sideways false status open \begin_layout Plain Layout Censored \end_layout \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout \begin_inset CommandInset label LatexCommand label name "tab:rabbit-walrus-encore" \end_inset The rabbit-walrus does an encore. \end_layout \end_inset \end_layout \begin_layout Plain Layout \end_layout \end_inset \begin_inset Tabular \begin_inset Text \begin_layout Plain Layout Anger \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Time \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 1 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 2 \end_layout \end_inset \end_inset \end_layout \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout One more time. \end_layout \end_inset \end_layout \end_inset \end_layout \begin_layout Section The Passing Away \end_layout \begin_layout Standard Our hero was passing by the village. He had only stopped to say \begin_inset Quotes eld \end_inset Hi! \begin_inset Quotes erd \end_inset Again here our lousy skills have made us spoil the quote, but this time for the opposite reasons: everyone knows how to say \begin_inset Quotes eld \end_inset Hi! \begin_inset Quotes erd \end_inset , so we don't need an actual quote. It is enough to report that the had stopped to say hi, even maybe qualifying it a bit to make do for the missing exclamation sign: he could have stopped to say a friendly hi. Getting all literary he could have stopped to say a longing hi, although this road leads to bizarreness. It could be cool though. \end_layout \begin_layout Standard But anyway. Laurinda was so mad, so hopping mad that she called her friend, the Assassin. He was not in town at that precise moment, but that didn't help our hero as he was just outside town killing people in a small barn. Just for practice. \end_layout \begin_layout Standard Our hero left the village, but Laurinda cunningly annotated the MAC address of his laptop's wifi card. The lack of networking knowledge on the part of our hero (who really couldn't tell a SYN packet from an ACK) was to play an important part in the story -- if he had known how to change the MAC address, which identified him with the precision of a surgeon's scalpel, he would have been safe. \end_layout \begin_layout Standard Let's not even get into that last scalpel metaphor, shall we not? It leaks worse than the Titanic. \end_layout \begin_layout Part Of How Our Hero Went No More \end_layout \begin_layout Chapter The Killing \end_layout \begin_layout Standard Our hero led a happy existence for a long time afterwards, randomly avoiding all points within connecting distance of a wifi network. It could not last. \end_layout \begin_layout Standard Our hero went to the next village, found a friendly Moonrams cafe and connected to the net. Quickly the assassin (who knew the very people that run the internet, and who by this display of nerdiness no longer merits the starting capital letter) traced a bunch of IP packets coming from our hero's MAC address. He deployed a team of murderous African bees, which as surely as a well-cared-f or AK-47 reached our hero and killed him with three fast stings. Of course they died afterwards, being bees and all, so it was an astounding feat this training of wild African bees just for this one murder. Maybe the Assassin merits that capital letter after all. \end_layout \begin_layout Section The Passing Away \end_layout \begin_layout Standard Our hero was undone. He was no more. He was, actually, an ex-hero. We shall narrate his wake soon. \end_layout \begin_layout Itemize But first a message from our kind sponsors. They want to present you the next section in this deeper inset. \end_layout \begin_deeper \begin_layout Section The Mourning \end_layout \begin_layout Standard Everyone cried in the ceremony. It was so sad that we need an image of this moment. You can find it in figure \begin_inset CommandInset ref LatexCommand ref reference "fig:mourning" \end_inset . \begin_inset Note Greyedout status open \begin_layout Plain Layout Mental note: never pay the artist beforehand. \end_layout \end_inset \end_layout \end_deeper \begin_layout Standard \begin_inset Float figure wide false sideways false status open \begin_layout Plain Layout \align center \begin_inset Graphics filename mourning.svg \end_inset \end_layout \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout \begin_inset CommandInset label LatexCommand label name "fig:mourning" \end_inset A crude approximation to our hero's mourning. \end_layout \end_inset \end_layout \end_inset \end_layout \begin_layout Standard And thusly everything happened. \end_layout \begin_layout Chapter The Mourning \end_layout \begin_layout Standard We have already talked at length about the mourning, and under sponsorship no less, so no further details will be given here. Suffice to say that our hero was mourned. A lot. \end_layout \begin_layout Chapter \start_of_appendix The Rebirth \end_layout \begin_layout Standard Surprising everyone, our hero was about to make a comeback. \end_layout \begin_layout Section Coming Again \end_layout \begin_layout Standard As it happened, our hero had never died; he had just faked his own death to find out his assassin. It was not difficult, what with the capital letter and all. \end_layout \begin_layout Section Two is Better than One \end_layout \begin_layout Standard How to make another comeback? This is left as an exercise to the reader. \end_layout \begin_layout Chapter Our Recommendation to Kids \end_layout \begin_layout Standard Never trust killer bees. Or Assassins. \end_layout \begin_layout Section Killer Bees and Their Perils \end_layout \begin_layout Standard A killer bee cannot be trained consistently, since it will die at the first sting. Better use killing wasps -- or, even better, solve your differencies talking. \end_layout \begin_layout Standard For the sake of your education, check figure \begin_inset CommandInset ref LatexCommand ref reference "fig:killer-bees" \end_inset . It shows a bunch of killer bees, or something. \end_layout \begin_layout Standard \begin_inset Float figure wide false sideways false status open \begin_layout Plain Layout \align center \begin_inset Graphics filename mourning.svg \end_inset \end_layout \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout \begin_inset CommandInset label LatexCommand label name "fig:killer-bees" \end_inset A gathering of killer bees. Supposedly. \end_layout \end_inset \end_layout \end_inset \end_layout \begin_layout Section Assassins: Inherently Unreliable \end_layout \begin_layout Standard Someone who kills people (even for business) is not someone you want to deal with. Watch \begin_inset Quotes eld \end_inset Fargo \begin_inset Quotes erd \end_inset by the Coen Brothers if you don't believe me. And remember: a hero under the belt is a feather on the hat. \end_layout \end_body \end_document elyxer-1.2.5/forks/jras-elyxer/test/change.lyx0000644000175000017500000000426212117061342020671 0ustar chennochenno#LyX 1.6.7 created this file. For more info see http://www.lyx.org/ \lyxformat 345 \begin_document \begin_header \textclass article \use_default_options true \language english \inputencoding auto \font_roman default \font_sans default \font_typewriter default \font_default_family default \font_sc false \font_osf false \font_sf_scale 100 \font_tt_scale 100 \graphics default \paperfontsize default \use_hyperref false \papersize default \use_geometry false \use_amsmath 1 \use_esint 1 \cite_engine basic \use_bibtopic false \paperorientation portrait \secnumdepth 3 \tocdepth 3 \paragraph_separation indent \defskip medskip \quotes_language english \papercolumns 1 \papersides 1 \paperpagestyle default \tracking_changes true \output_changes true \author "chenno,,," \end_header \begin_body \begin_layout Title Change Test \end_layout \begin_layout List \labelwidthstring 00.00.0000 \change_inserted 0 1283108483 Prisoner: \change_unchanged Well... I'd just like to say, m'lud, I've got a family... a wife and six kids... and I ho \change_deleted 0 1283108130 o \change_unchanged pe very much you don't have to take away my freedom... because... well, because m'lud freedom is a state much prized within the rea \change_inserted 0 1283108101 l \change_unchanged m of civilized society. It is a bond wherewith the savage man may charm the outward hatchments of his soul, and soothe the troubled brea \change_inserted 0 1283108102 s \change_unchanged t into a magnitude of quiet. It is most precious as a blessed balm, the saviour of princes, the harbinger of happiness, yea, the very stuff and pith of all we hold most dear. What frees the prisoner in his lonely cell, chained within the bondage of rude walls, far from the owl of Theb \change_deleted 0 1283108105 b \change_unchanged es? What fires and stirs the woodcock in his springe or wakes the drowsy apricot betides? What goddess doth the storm toss'd mariner offer her most tempestuous prayers to? Freedom! Freedom! Freedom! \change_inserted 0 1283108446 \end_layout \begin_layout List \labelwidthstring 00.00.0000 \change_inserted 0 1283108472 Judge: It's only a bloody parking offence. \change_unchanged \end_layout \end_body \end_document elyxer-1.2.5/forks/jras-elyxer/test/elyxer-svg.svg0000644000175000017500000015524512117061342021544 0ustar chennochenno image/svg+xml elyxer-1.2.5/forks/jras-elyxer/test/appendix-1-6-toc-good.html0000644000175000017500000000675512117061342023427 0ustar chennochenno Converted document elyxer-1.2.5/forks/jras-elyxer/test/figures-good.html0000644000175000017500000002556612117061342022200 0ustar chennochenno Figures Test

Figures Test

1 Floats

First, figure 1↓.
figure random.png
Figure 1 A random image
Next, figure 2↓.
figure lyx credits.png
(a) Random image A
figure lyx credits.png
(b) Random image B
Figure 2 Two random images
And last, 3↓.
figure random.png
(a) Random image A
figure random.png
(b) Random image B
figure random.png
(c) Random image C
Figure 3 Three random images
That’s all, folks.

2 Wraps

Now with wraps.
figure random.png
Figure 4 A wrapped image.
This image should wrap around the text. The text should be fairly complete and cover several paragraphs, but we might not get so much text. After all typing just because tends to bore the readers, who bear the grunt of the gruntwork of reading the resulting text.
figure random.png
Figure 5 Exterior wrapped image.
The next wrapping image should be smaller, and has default (outer) placement. Again, a lot of text would be required so the image fits around the text; the wrapped image will probably fall on some other page in the PDF, anyway.

3 Algorithms and Listings

We can also add a listing.
This listing appears here courtesy of the fine Ministry of Silly Walks.
And appear here it does alright.
And also a listing inside a float.
This listing appears here courtesy of the fine Ministry of Silly Walks.
And appear here it does alright.
Algorithm 1 An algorithm.
Another algorithm for the sake of it.
\my_first_tex_command
it does not work at all!
\end_command
Algorithm 2 Another algorithm, embedded.
Now the same text outside the algorithm.
\my_first_tex_command
it does not work at all!
\end_command
And an algorithm without caption.
\my_first_tex_command
it should work this time!
\end_command
Now a numbered listing.
1This listing has been numbered.
2Each line has its own number.
A numbered listing with a caption.
1This listing has a caption.
First caption which should not be numbered.
2It should not be numbered.
3These lines, on the other hand, should.
This second caption should not be numbered either.
As soon as we can get to it: a LyX-Code.
This is LyX-Code.
Code-LyX it’s not.
My heart will explode,
My tongue’s in a knot.
Another algorithm, this time without styling.
Who shall declare this good, that ill
When good and ill so intertwine
But to fulfil the vast design of an omniscient will.
When seeming again but turns to loss
When earthly treasure proves but dross
And what seems lost but turns again
To high eternal gain.
Algorithm 4 A poem by Dame Irene Stoat.
And many other things.

4 Boxes (Minipages)

We can insert a box here:
Well I, I think that, er, nobody who has gone abroad should be allowed back in the country. I mean, er, blimey, blimey if they’re not keen enough to stay here when they’re ’ere, why should we allow them back, er, at the tax-payers’ expense? I mean, be fair, I mean, I don’t eat squirrels do I? I mean well perhaps I do one or two but there’s no law against that, is there? It’s a free country. I mean if I want to eat a squirrel now and again, that’s me own business, innit? I mean, I’m no racialist. I, oh, oh...
A decorated centered box:
CONFUSE-A-CAT LIMITED
INCORPORATING
AMAZE-A-VOLE LTD
STUN-A-STOAT LTD
PUZZLE-A-PUMA LTD
STARTLE-A-THOMPSON’S GAZELLE LTD
BEWILDEREBEEST INC
DISTRACT-A-BEE
And a double-decorated box with a certain width:
Goodnight. Ding-ding-ding-ding-ding, five, four, three, two, one… Goodnight. Ding-ding-ding-ding-ding, five, four, three, two, one…
Five, four, three, two, one, zero!
It was fine doing that.
elyxer-1.2.5/forks/jras-elyxer/test/with images-1-5-html-good.html0000644000175000017500000000326612117061342024170 0ustar chennochenno Images Tests

Images Tests

figure elyxer-svg.png First image: regular path.
figure elyxer-svg.png Second image: convoluted path.
figure docs/elyxer.png Third image: from another directory.
figure mini-elyxer.jpg Fourth image: from a JPEG file.
figure square.png Fifth image: from a PNG file.
elyxer-1.2.5/forks/jras-elyxer/test/figures.lyx0000644000175000017500000003333212117061342021110 0ustar chennochenno#LyX 1.6.7 created this file. For more info see http://www.lyx.org/ \lyxformat 345 \begin_document \begin_header \textclass scrartcl \begin_preamble % eLyXer -- convert LyX source files to HTML output. % % Copyright (C) 2009-2010 Alex Fernández % % This program is free software: 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 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 % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . \end_preamble \use_default_options false \language english \inputencoding auto \font_roman default \font_sans default \font_typewriter default \font_default_family default \font_sc false \font_osf false \font_sf_scale 100 \font_tt_scale 100 \graphics default \paperfontsize default \spacing single \use_hyperref false \papersize default \use_geometry false \use_amsmath 1 \use_esint 1 \cite_engine basic \use_bibtopic false \paperorientation portrait \secnumdepth 3 \tocdepth 3 \paragraph_separation skip \defskip medskip \quotes_language english \papercolumns 1 \papersides 1 \paperpagestyle default \tracking_changes false \output_changes false \author "" \author "" \end_header \begin_body \begin_layout Title Figures Test \end_layout \begin_layout Standard \begin_inset FloatList figure \end_inset \end_layout \begin_layout Standard \begin_inset FloatList algorithm \end_inset \end_layout \begin_layout Section Floats \end_layout \begin_layout Standard First, figure \begin_inset CommandInset ref LatexCommand ref reference "fig:A-random-image" \end_inset . \end_layout \begin_layout Standard \begin_inset Float figure wide false sideways false status open \begin_layout Plain Layout \align center \begin_inset Graphics filename random.png width 50col% \end_inset \end_layout \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout \begin_inset CommandInset label LatexCommand label name "fig:A-random-image" \end_inset A random image \end_layout \end_inset \end_layout \begin_layout Plain Layout \end_layout \end_inset \end_layout \begin_layout Standard Next, figure \begin_inset CommandInset ref LatexCommand ref reference "fig:Two-random-images." \end_inset . \end_layout \begin_layout Standard \begin_inset Float figure wide false sideways false status open \begin_layout Plain Layout \begin_inset Float figure wide false sideways false status open \begin_layout Plain Layout \align center \begin_inset Graphics filename lyx credits.png width 50col% \end_inset \end_layout \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout Random image A \end_layout \end_inset \end_layout \end_inset \begin_inset Float figure wide false sideways false status open \begin_layout Plain Layout \align center \begin_inset Graphics filename lyx credits.png width 50col% \end_inset \end_layout \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout Random image B \end_layout \end_inset \end_layout \end_inset \begin_inset Caption \begin_layout Plain Layout \begin_inset CommandInset label LatexCommand label name "fig:Two-random-images." \end_inset Two random images \end_layout \end_inset \end_layout \end_inset \end_layout \begin_layout Standard And last, \begin_inset CommandInset ref LatexCommand ref reference "fig:Three-random-images" \end_inset . \end_layout \begin_layout Standard \begin_inset Float figure wide false sideways false status open \begin_layout Plain Layout \begin_inset Float figure wide false sideways false status open \begin_layout Plain Layout \align center \begin_inset Graphics filename random.png width 30col% \end_inset \end_layout \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout Random image A \end_layout \end_inset \end_layout \end_inset \begin_inset Float figure wide false sideways false status open \begin_layout Plain Layout \align center \begin_inset Graphics filename random.png width 30col% \end_inset \end_layout \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout Random image B \end_layout \end_inset \end_layout \end_inset \begin_inset Float figure wide false sideways false status open \begin_layout Plain Layout \align center \begin_inset Graphics filename random.png width 30col% \end_inset \end_layout \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout Random image C \end_layout \end_inset \end_layout \end_inset \end_layout \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout \begin_inset CommandInset label LatexCommand label name "fig:Three-random-images" \end_inset Three random images \end_layout \end_inset \end_layout \end_inset \end_layout \begin_layout Standard That's all, folks. \end_layout \begin_layout Section Wraps \end_layout \begin_layout Standard Now with wraps. \end_layout \begin_layout Standard \begin_inset Wrap figure lines 0 placement l overhang 0in width "50col%" status open \begin_layout Plain Layout \end_layout \begin_layout Plain Layout \align center \begin_inset Graphics filename random.png width 50col% \end_inset \end_layout \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout A wrapped image. \end_layout \end_inset \end_layout \end_inset \end_layout \begin_layout Standard This image should wrap around the text. The text should be fairly complete and cover several paragraphs, but we might not get so much text. After all typing just because tends to bore the readers, who bear the grunt of the gruntwork of reading the resulting text. \end_layout \begin_layout Standard \begin_inset Wrap figure lines 0 placement o overhang 0in width "4cm" status open \begin_layout Plain Layout \align center \begin_inset Graphics filename random.png width 4cm \end_inset \end_layout \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout Exterior wrapped image. \end_layout \end_inset \end_layout \end_inset \end_layout \begin_layout Standard The next wrapping image should be smaller, and has default (outer) placement. Again, a lot of text would be required so the image fits around the text; the wrapped image will probably fall on some other page in the PDF, anyway. \end_layout \begin_layout Section Algorithms and Listings \end_layout \begin_layout Standard We can also add a listing. \end_layout \begin_layout Standard \begin_inset listings inline false status open \begin_layout Plain Layout This listing appears here courtesy of the fine Ministry of Silly Walks. \end_layout \begin_layout Plain Layout And appear here it does alright. \end_layout \end_inset \end_layout \begin_layout Standard And also a listing inside a float. \end_layout \begin_layout Standard \begin_inset Float algorithm wide false sideways false status open \begin_layout Plain Layout \begin_inset listings inline false status open \begin_layout Plain Layout This listing appears here courtesy of the fine Ministry of Silly Walks. \end_layout \begin_layout Plain Layout And appear here it does alright. \end_layout \end_inset \end_layout \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout An algorithm. \end_layout \end_inset \end_layout \begin_layout Plain Layout \end_layout \end_inset \end_layout \begin_layout Standard Another algorithm for the sake of it. \end_layout \begin_layout Standard \begin_inset Float algorithm wide false sideways false status open \begin_layout Quotation \family typewriter \backslash my_first_tex_command \end_layout \begin_layout Quotation \family typewriter it does not work at all! \end_layout \begin_layout Quotation \family typewriter \backslash end_command \end_layout \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout Another algorithm, embedded. \end_layout \end_inset \end_layout \end_inset \end_layout \begin_layout Standard Now the same text outside the algorithm. \end_layout \begin_layout Quotation \family typewriter \backslash my_first_tex_command \end_layout \begin_layout Quotation \family typewriter it does not work at all! \end_layout \begin_layout Quotation \family typewriter \backslash end_command \end_layout \begin_layout Standard And an algorithm without caption. \end_layout \begin_layout Standard \begin_inset Float algorithm wide false sideways false status open \begin_layout Quotation \family typewriter \backslash my_first_tex_command \end_layout \begin_layout Quotation \family typewriter it should work this time! \end_layout \begin_layout Quotation \family typewriter \backslash end_command \end_layout \end_inset \end_layout \begin_layout Standard Now a numbered listing. \end_layout \begin_layout Standard \begin_inset listings lstparams "numbers=left,stepnumber=1" inline false status open \begin_layout Plain Layout This listing has been numbered. \end_layout \begin_layout Plain Layout Each line has its own number. \end_layout \end_inset \end_layout \begin_layout Standard A numbered listing with a caption. \end_layout \begin_layout Standard \begin_inset listings lstparams "numbers=left,stepnumber=1" inline false status open \begin_layout Plain Layout This listing has a caption. \end_layout \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout First caption which should not be numbered. \end_layout \end_inset \end_layout \begin_layout Plain Layout It should not be numbered. \end_layout \begin_layout Plain Layout These lines, on the other hand, should. \end_layout \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout This second caption should not be numbered either. \end_layout \end_inset \end_layout \end_inset \end_layout \begin_layout Standard As soon as we can get to it: a LyX-Code. \end_layout \begin_layout LyX-Code This is LyX-Code. \end_layout \begin_layout LyX-Code Code-LyX it's not. \end_layout \begin_layout LyX-Code My heart will explode, \end_layout \begin_layout LyX-Code My tongue's in a knot. \end_layout \begin_layout Standard Another algorithm, this time without styling. \end_layout \begin_layout Quote \begin_inset Float algorithm wide false sideways false status open \begin_layout Plain Layout Who shall declare this good, that ill \end_layout \begin_layout Plain Layout When good and ill so intertwine \end_layout \begin_layout Plain Layout But to fulfil the vast design of an omniscient will. \end_layout \begin_layout Plain Layout When seeming again but turns to loss \end_layout \begin_layout Plain Layout When earthly treasure proves but dross \end_layout \begin_layout Plain Layout And what seems lost but turns again \end_layout \begin_layout Plain Layout To high eternal gain. \end_layout \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout A poem by Dame Irene Stoat. \end_layout \end_inset \end_layout \end_inset \end_layout \begin_layout Standard And many other things. \end_layout \begin_layout Section Boxes (Minipages) \end_layout \begin_layout Standard We can insert a box here: \end_layout \begin_layout Standard \begin_inset Box Frameless position "t" hor_pos "c" has_inner_box 1 inner_pos "t" use_parbox 0 width "100col%" special "none" height "1in" height_special "totalheight" status open \begin_layout Plain Layout \noindent Well I, I think that, er, nobody who has gone abroad should be allowed back in the country. I mean, er, blimey, blimey if they're not keen enough to stay here when they're 'ere, why should we allow them back, er, at the tax-payers' expense? I mean, be fair, I mean, I don't eat squirrels do I? I mean well perhaps I do one or two but there's no law against that, is there? It's a free country. I mean if I want to eat a squirrel now and again, that's me own business, innit? I mean, I'm no racialist. I, oh, oh... \end_layout \end_inset \end_layout \begin_layout Standard A decorated centered box: \end_layout \begin_layout Standard \begin_inset Box Boxed position "t" hor_pos "c" has_inner_box 1 inner_pos "t" use_parbox 0 width "100col%" special "none" height "1in" height_special "totalheight" status open \begin_layout Plain Layout \noindent \align center CONFUSE-A-CAT LIMITED \end_layout \begin_layout Plain Layout \noindent \align center INCORPORATING \end_layout \begin_layout Plain Layout \noindent \align center AMAZE-A-VOLE LTD \end_layout \begin_layout Plain Layout \noindent \align center STUN-A-STOAT LTD \end_layout \begin_layout Plain Layout \noindent \align center PUZZLE-A-PUMA LTD \end_layout \begin_layout Plain Layout \noindent \align center STARTLE-A-THOMPSON'S GAZELLE LTD \end_layout \begin_layout Plain Layout \noindent \align center BEWILDEREBEEST INC \end_layout \begin_layout Plain Layout \noindent \align center DISTRACT-A-BEE \end_layout \end_inset \end_layout \begin_layout Standard And a double-decorated box with a certain width: \end_layout \begin_layout Standard \begin_inset Box Doublebox position "t" hor_pos "c" has_inner_box 1 inner_pos "t" use_parbox 0 width "60col%" special "none" height "1in" height_special "totalheight" status open \begin_layout Plain Layout Goodnight. Ding-ding-ding-ding-ding, five, four, three, two, one\SpecialChar \ldots{} Goodnight. Ding-ding-ding-ding-ding, five, four, three, two, one\SpecialChar \ldots{} \end_layout \begin_layout Plain Layout Five, four, three, two, one, zero! \end_layout \end_inset \end_layout \begin_layout Standard It was fine doing that. \end_layout \end_body \end_document elyxer-1.2.5/forks/jras-elyxer/test/plain-text.txt0000644000175000017500000000017212117061342021530 0ustar chennochennoPlain text document. To be included verbatim in a LyX document. Do not modify unless you want to test something. elyxer-1.2.5/forks/jras-elyxer/test/toc-book-good.html0000644000175000017500000000727112117061342022242 0ustar chennochenno Book TOC Test

Book TOC Test

List of Figures

Part I. Our Definition

1 The definition

A TOC is a Table Of Contents.

1.1 But I Already Knew That

You were lucky.

I Want My Money Back

There you have your 0€ back.

Completely Unfair Dude

Hey, I didn’t call you here.
A Paragraph For You
Totally uncalled for.
figure elyxer-svg.png
Figure 1.1 eLyXer logo

Unordered Section

Just to show that it works.
And now a list.
  1. First item.
  2. We will embed an ordered subsection here just to fake it.

    There We Go

  3. See if it’s in your TOC.
But There Is More
And nothing else.

A Appendix

An appendix here, an appendix there.
elyxer-1.2.5/forks/jras-elyxer/test/bibtex-alpha.bib0000644000175000017500000000132212117061342021716 0ustar chennochenno%% eLyXer: test BibTeX bibliography for alpha style. %% Created on 20100601 by Alex Fernandez. @article{alphavolume, Author = {E. Praline and B. Brooky}, Title = {The population explosion}, Number = {1}, Pages = {2--4}, Journal = {Just The Words}, Publisher = {Brooky \& Sons}, Volume = {1}, Year = {1969}, url = {http://www.ibras.dk/montypython/episode18.htm} } @article{alphabasic, Author = {B. Bishop and W. Belpit}, Journal = {Just The Words}, Publisher = {Grillomat Snack Bar, Paignton}, Title = {Your legs are so swollen}, Year = {1969}, file = :bibtex-good.html:HTML, url = http://www.ibras.dk/montypython/episode18.htm, note = {Found on \url{http://www.ibras.dk/montypython/episode18.htm}.} } elyxer-1.2.5/forks/jras-elyxer/test/file-1-6.lyx0000644000175000017500000000634312117061342020666 0ustar chennochenno#LyX 1.6.7 created this file. For more info see http://www.lyx.org/ \lyxformat 345 \begin_document \begin_header \textclass article \begin_preamble % eLyXer -- convert LyX source files to HTML output. % % Copyright (C) 2009-2010 Alex Fernández % % This program is free software: 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 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 % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . \end_preamble \use_default_options true \language english \inputencoding auto \font_roman default \font_sans default \font_typewriter default \font_default_family default \font_sc false \font_osf false \font_sf_scale 100 \font_tt_scale 100 \graphics default \paperfontsize default \spacing single \use_hyperref false \papersize default \use_geometry false \use_amsmath 1 \use_esint 1 \cite_engine basic \use_bibtopic false \paperorientation portrait \secnumdepth 3 \tocdepth 3 \paragraph_separation skip \defskip medskip \quotes_language english \papercolumns 1 \papersides 1 \paperpagestyle default \tracking_changes false \output_changes false \author "" \author "" \end_header \begin_body \begin_layout Title File Test \end_layout \begin_layout Author Created by Alex Fernández \end_layout \begin_layout Standard This document was created with LyX 1.6.2rc2, a great text editor. \end_layout \begin_layout Part The only part \end_layout \begin_layout Section The First Section \end_layout \begin_layout Standard With some text. \begin_inset Note Greyedout status open \begin_layout Plain Layout And a greyed out note. \end_layout \end_inset \end_layout \begin_layout Section* Another Section (Not Numbered) \end_layout \begin_layout Standard With some more text. \begin_inset Note Note status open \begin_layout Plain Layout And a note which should not appear at all. \end_layout \end_inset \begin_inset Note Comment status open \begin_layout Plain Layout Actually, two notes which should not appear. \end_layout \end_inset \end_layout \begin_layout Standard Now we include a different document. \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand include filename "helloworld.lyx" \end_inset \end_layout \begin_layout Standard And now a verbatim include. \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand verbatiminput filename "plain-text.txt" \end_inset \end_layout \begin_layout Standard \begin_inset Note Comment status open \begin_layout Plain Layout An include which should not appear since it's inside a comment. \begin_inset CommandInset include LatexCommand include filename "helloworld.lyx" \end_inset \end_layout \end_inset \end_layout \begin_layout Standard \begin_inset CommandInset index_print LatexCommand printindex \end_inset \end_layout \end_body \end_document elyxer-1.2.5/forks/jras-elyxer/test/image-scaling.lyx0000644000175000017500000000642612117061342022150 0ustar chennochenno#LyX 1.6.5 created this file. For more info see http://www.lyx.org/ \lyxformat 345 \begin_document \begin_header \textclass article \begin_preamble % eLyXer -- convert LyX source files to HTML output. % % Copyright (C) 2009-2010 Alex Fernández % % This program is free software: 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 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 % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . \end_preamble \use_default_options false \language english \inputencoding auto \font_roman default \font_sans default \font_typewriter default \font_default_family default \font_sc false \font_osf false \font_sf_scale 100 \font_tt_scale 100 \graphics default \paperfontsize default \spacing single \use_hyperref false \papersize default \use_geometry false \use_amsmath 1 \use_esint 1 \cite_engine basic \use_bibtopic false \paperorientation portrait \secnumdepth 3 \tocdepth 3 \paragraph_separation skip \defskip medskip \quotes_language english \papercolumns 1 \papersides 1 \paperpagestyle default \tracking_changes false \output_changes false \author "" \author "" \end_header \begin_body \begin_layout Title Image Scaling Tests \end_layout \begin_layout Section Scale \end_layout \begin_layout Standard \begin_inset Graphics filename elyxer.png \end_inset PNG unscaled. \end_layout \begin_layout Standard \begin_inset Graphics filename elyxer.png lyxscale 50 scale 50 \end_inset PNG scaled 50%. \end_layout \begin_layout Standard \begin_inset Graphics filename elyxer-eps.eps \end_inset Unscaled EPS. \end_layout \begin_layout Standard \begin_inset Graphics filename elyxer-eps.eps scale 50 \end_inset EPS scaled 50%. \end_layout \begin_layout Section Exploring Width \end_layout \begin_layout Standard \begin_inset Graphics filename elyxer.png lyxscale 50 width 50col% \end_inset 50% column width. \end_layout \begin_layout Standard \begin_inset Graphics filename elyxer.png lyxscale 50 width 5cm \end_inset 5cm wide. \end_layout \begin_layout Standard \begin_inset Graphics filename elyxer.png lyxscale 50 width 50line% \end_inset 50% line width. \end_layout \begin_layout Standard \begin_inset Graphics filename elyxer.png lyxscale 50 width 5mm \end_inset 5mm wide. \end_layout \begin_layout Section Exploring Height \end_layout \begin_layout Standard \begin_inset Graphics filename elyxer.png lyxscale 50 height 50col% \end_inset 50% column height. \end_layout \begin_layout Standard \begin_inset Graphics filename elyxer.png lyxscale 50 height 5cm \end_inset 5cm high. \end_layout \begin_layout Standard \begin_inset Graphics filename elyxer.png lyxscale 50 height 50page% \end_inset 50% page height. \end_layout \begin_layout Standard \begin_inset Graphics filename elyxer.png lyxscale 50 height 5mm \end_inset 5 mm high. \end_layout \end_body \end_document elyxer-1.2.5/forks/jras-elyxer/test/references-good.html0000644000175000017500000000460512117061342022644 0ustar chennochenno References Test

References Test

Alex Fernández (elyxer@gmail.com)

1 First Chapter

This first chapter contains the reference: 2↓, contained in chapter: 2↓.

1.1 Sectioned

This section contains a reference in brackets: (2↓). It should be on page: 1↓, and so be: 2 on page 1↓.
Adding a pretty reference: Chapter 2↓. Now a named reference: Second Chapter↓.

2 Second Chapter

This second chapter contains the label .

2.1 URIs

elyxer-1.2.5/forks/jras-elyxer/test/spacing-good.html0000644000175000017500000000724012117061342022145 0ustar chennochenno Spacing Test

Spacing Test

1 Paragraph

As our world turns more complex, paragraph spacing tends to be more and more important.
Some people would say that paragraph spacing is the first and foremost issue in our modern culture. Perhaps they can be said to be exaggerating, but not by much.

2 Issues in Horizontal Spacing

Some new issues arise every day. Today we would like to explore horizontal fill.
Cheese available
Red Leicester no
Tilsit no
Cheese available
Camembert runny
Cheddar no
These tables should be separated by equal horizontal spacing. Can it be done? It should.

2.1 Horizontal Space

The horizontal space is inserted using Insert ▷ Format ▷ Horizontal space. The result is as follows: a b c d e  f.
Custom spaces can also be used: 01cm1in.

2.2 Half Spaces

As reported by Uwe Stöhr: 22 m, 3.53 €. It is correctly converted to a thin space.

3 Issues in Vertical Spacing

Vertical spacing can also be added. Let us now separate a few sentences with it.
J. Losey
L. Anderson
S. Kubrick
P.P. Pasolini
O. Welles
The Late B. Forbes
elyxer-1.2.5/forks/jras-elyxer/test/descriptions-1-5.lyx0000644000175000017500000000663512117061342022460 0ustar chennochenno#LyX 1.5.7 created this file. For more info see http://www.lyx.org/ \lyxformat 276 \begin_document \begin_header \textclass article \begin_preamble % eLyXer -- convert LyX source files to HTML output. % % Copyright (C) 2009-2010 Alex Fernández % % This program is free software: 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 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 % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . \end_preamble \language english \inputencoding auto \font_roman default \font_sans default \font_typewriter default \font_default_family default \font_sc false \font_osf false \font_sf_scale 100 \font_tt_scale 100 \graphics default \paperfontsize default \spacing single \papersize default \use_geometry false \use_amsmath 1 \use_esint 1 \cite_engine basic \use_bibtopic false \paperorientation portrait \secnumdepth 3 \tocdepth 3 \paragraph_separation indent \defskip medskip \quotes_language english \papercolumns 1 \papersides 1 \paperpagestyle default \tracking_changes false \output_changes false \author "" \author "" \end_header \begin_body \begin_layout Title Descriptions Tests \end_layout \begin_layout Description First description. \end_layout \begin_layout Description Second\InsetSpace ~ description. \end_layout \begin_layout Description Third\InsetSpace ~ description\InsetSpace ~ which\InsetSpace ~ should\InsetSpace ~ hold\InsetSpace ~ all\InsetSpace ~ words but these. \end_layout \begin_layout Description Fourth description. \end_layout \begin_layout Description Fifth\InsetSpace \space{} description\InsetSpace \thinspace{} with odd spaces. \end_layout \begin_layout Description \family typewriter Mixed \family default font description. \end_layout \begin_layout Description \family typewriter An even \family default more difficult description with change of font in the middle. \end_layout \begin_layout Description \family typewriter A \color red n \family default i \color inherit mpossible description with intermixed changes of font and color. \end_layout \begin_layout Description A description which leads to \family typewriter fixed \color blue text \color red in \color inherit \color green dif \family default (fere) \family typewriter nt \color inherit \color magenta colors \family default \color inherit . And now \family typewriter \series bold some \series default more \family default . \end_layout \begin_layout Description \begin_inset ERT status open \begin_layout Standard \end_layout \end_inset ERT precedes this description, it should be kept. \end_layout \begin_layout Description \begin_inset ERT status open \begin_layout Standard ERT is the description \end_layout \end_inset and not only the first word. \end_layout \begin_layout Description \begin_inset LatexCommand index name "Word" \end_inset Word that leads a description and which appears in the Index. \end_layout \begin_layout Description \begin_inset LatexCommand printindex \end_inset \end_layout \end_body \end_document elyxer-1.2.5/forks/jras-elyxer/test/footnotes-1-6-hover-end-good.html0000644000175000017500000001637312117061342024736 0ustar chennochenno Footnotes Tests

Footnotes Tests

1 This is just some random section text used to insert some footnotes.[1] [1] And this is one of those footnotes. And this is a margin note, also tested here.

Lorem ipsum dolor sit amet, consectetur adipisicing[2] [2] adipisicing elit[3] [3] elit, sed do eiusmod eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa [4] [4] culpa qui officia [5] [5] officia deserunt mollit anim id est laborum.
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum[6] [6] laborum, laborum.
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do tempor incididunt ut [7] [7] ut labore[8] [8] labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis Duis aute irure dolor in reprehenderit in voluptate velit[9] [9] velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id id est laborum.

Nomenclature

eiusmod eiusmod indeed

References

Index

ullamco:

Footnotes

[1]And this is one of those footnotes.
[2]adipisicing
[3]elit
[4]culpa
[5]officia
[6]laborum, laborum
[7]ut
[8]labore
[9]velit
elyxer-1.2.5/forks/jras-elyxer/test/helloworld-embedcss-good.html0000644000175000017500000000201512117061342024452 0ustar chennochenno Converted document
Hello world
elyxer-1.2.5/forks/jras-elyxer/test/compressed.lyx0000644000175000017500000000174112117061342021607 0ustar chennochennoUn6}W X`HgmmQ 6FTl[c=,'NѴ/g9s&t:a#I"pNT y@Qe2%Lef3v`$[TXW@g+^+̭l*6K9lxޓpAIDŎIZ.P$m$'rl& ֭S2лa8tH#[dgmzc];QQ !Fo?Qk\Ԫ E a򓔚\mCʓ->a'45+$Md|G/UM.#َd5G z';#.C-@ޑ{0nI{d)UO७S HDQZӊ\4(a5}ϯn4y/tt3C?rZ+@#2'Lh@_fx2? o.f3҈F~2vv1 q$u+y.69}OTGF%G躺 &YH%lr֦I; [ɟF`.s.Dò!5¬fb-AFM٢&,м; B[Ʃ=BTJ/$B#h}q /f:{?*[ Iu36ŧ^}'y|ܔ}&ClͶYԉcUtډ  ,TeV+ݯ*ZO)4T[P(KT9@?ær)xNUw?/YZZT>蜟>Y@N~Eꖲ"K-ڧĸyC؞/۽E}Jtn+9t݋e*\P_,=}pMaᏒ1+Iܢ W~lVNYIPl1hlRR۬s셿(G7=Yelyxer-1.2.5/forks/jras-elyxer/test/toc-book-notoclabels-good.html0000644000175000017500000000714312117061342024543 0ustar chennochenno Book TOC Test

Book TOC Test

List of Figures

I. Our Definition

1 The definition

A TOC is a Table Of Contents.

1.1 But I Already Knew That

You were lucky.

I Want My Money Back

There you have your 0€ back.

Completely Unfair Dude

Hey, I didn’t call you here.
A Paragraph For You
Totally uncalled for.
figure elyxer-svg.png
Figure 1.1 eLyXer logo

Unordered Section

Just to show that it works.
And now a list.
  1. First item.
  2. We will embed an ordered subsection here just to fake it.

    There We Go

  3. See if it’s in your TOC.
But There Is More
And nothing else.

A Appendix

An appendix here, an appendix there.
elyxer-1.2.5/forks/jras-elyxer/test/helloworld.lyx0000644000175000017500000000321312117061342021612 0ustar chennochenno#LyX 1.6.5 created this file. For more info see http://www.lyx.org/ \lyxformat 345 \begin_document \begin_header \textclass article \begin_preamble % eLyXer -- convert LyX source files to HTML output. % % Copyright (C) 2009-2010 Alex Fernández % % This program is free software: 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 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 % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . \end_preamble \use_default_options false \language spanish \inputencoding auto \font_roman default \font_sans default \font_typewriter default \font_default_family default \font_sc false \font_osf false \font_sf_scale 100 \font_tt_scale 100 \graphics default \paperfontsize default \spacing single \use_hyperref false \papersize default \use_geometry false \use_amsmath 1 \use_esint 1 \cite_engine basic \use_bibtopic false \paperorientation portrait \secnumdepth 3 \tocdepth 3 \paragraph_separation skip \defskip medskip \quotes_language english \papercolumns 1 \papersides 1 \paperpagestyle default \tracking_changes false \output_changes false \author "" \author "" \end_header \begin_body \begin_layout Standard Hello world \end_layout \end_body \end_document elyxer-1.2.5/forks/jras-elyxer/test/lyx credits.png0000644000175000017500000005011412117061342021643 0ustar chennochennoPNG  IHDRjU pHYs+ IDATxit׵(khfog `%{o $ 49w; %h؎ $FBh`D7w﷾"nI87X]~Tw5vԽ%ڵבVթSuNϞ7* ZTPAE*>TPA} *PATPч *TPAE*S ۊtΈ3.&cV*0Cl+l8?'X|t1K?R? *L&??'tƗ~ڣ;ީ3E<3glh{4y\x~+֤-SJ~^g{߽?]l`vw>tʿ:.xto83/fAHC#hh{ t:>V(jʿ!4[zg݌ *P8h:>\Lr$/99ϬާZ$%iy} >B0U}ڵC=+J\O)%pD EBs'Σ^^ƣtJ}^$jCgYeiM3H40%3f1p˞JpfYzo߉7fyE=BoP.^ꖁ"n֖-2>8w8z1bT)T![t*>ײw~^yoj3\!IOgċ_Jnry+ #QCz*S*C&XxsS!yf_a'I췘o\VrވUG޺X6f~W[9tJ_hpY{a<9tۏTO-FK-Yo+/vR<Zz@>:HL2 gYeÿzv~7>vx~̲tgd[e*A$D5x>,ֶT;|XĭZy+/""h/֟yk=f_zaݧwZyW~Q=+/ڶ%^T_;y6KK썗vjqN.y}k1/\yvi-|,.$xϥ_2bg߸Bp`ޚbl-D {[Rqo^?Q}Q~(Sۖ%r˳v`yb^m_xwRz7ƹwcxTHUjرySץy+ѨrJ7ˢn&=/qwg ~BeްT-`T[xZj忧/l%?7r7?4s/?u>O/<3#'7}1;,~2vT>Q *C |8yC>UP$ݦO˫ś_ O;'1N@ Űuëřg6!<EH!x&a q^!3ts_G)Y<٥ `$2$ a&9H;("zp&G#p~H1fGlhQk=udg4Gp5zC†8)xU4\-W0˼`8{ڵZ9OG tJ(b]l:I0n/2!)x1*Q7hS@}xZNr҅O#Ɇ6$SX$o/zHѨ&8h Iyrܤy􈣉$Lq#I3UC 󔘍4E ;HSxׇ],l>2 b ATxJ`˖ @\z71/r-[6_E>aƼ$h4w}]SD4L=L@\pЄX5}\ފG6u88_Mތ3hSm]oȺk=(^6hRw2[lazhASxO]F^5h82 b4&fcd8}h,q>pܑ&vܵPݦ`^e.<8pT1E>w9l^fcLaRC,()#4$Fwp/'SHTJ@ M2l 6 `@D95RRM΄c H) '30ֵ)w%aݵ/NF3BЀc@UqpX(@Te<D;EQZS֎/2 ۱ IicХveQ( jP%" "˚Aʷ)rE4| ( Ӡ%:+e4ĺkN+E6PX`>^ `HFi7:P@C(+׏d ef8>ϋRf/I- l6‹h0Gc]{WRXqJ^SVfbλb 34(ƱEa$3MVJ~Ѐ>de(6@ },l&Z$hj >] ͭGĢhp(P4}žyrꓡi+f_i@k 6"rG4SV.U2=1 CC! Ynj|^P9gp{IbCz1ay^E-b 2K U*&s2Պeh g:@)e&%o)pMD854xڎu>x( 4T-?AQ1GBD+buN7:9?b( (8R@AC M#QbqP3X欍 / J 8`|a88\XьBKi ԝD|yAcа$H ҭ:#kJ Qb)|X$,eeAL6By>M.{r_F)?4,cļ`]Gs8~(4#tGĺ*Mt78},[KnRuq+ *6 + "вZ$R&oTxDppc@\_XPč8߆r$(k(.FF\dfܥPRp%40h %- v9Afǻx[8.@p6@O$/˜L)žUናeMi8Iۍ8Q)r=NeJbxRH$ưy@Cd}Ȍ8L]h+OX堅JfPDRL2 þLԈ^[M㾁& /'2ЦYwy:\Xc7o R`(:*@ PH@~D1%m&^ `_ 7Q{Nzڦm7teOS}/T}Pm  k910/ʼn0J!hPҲy)is X~"ӳ[6~ yӲisfȦC6]>d\9o ??1ڧQ&7ޣX3sxLJ^LHF#J uѲxk|XƲ,z' 7TQ>=γ)tU:d޴l ak#]}py3̈́E۶eHhڅیs!3r/o5beQ9H_uQFM֕kvvGKh_+o c3RzPlB㐔n6DB^;ʭB͕cp4BB` 1,4^UqlQR=VU0署$ƭXyl1YTg4]?b"c`_`ouo=PۖcR'Gm;Y>l_ K xIZu+nNch`{`5xTND,2? [wЦ{59j"``և}tsӽ՟_Y9x~yvo,'r_Њ 3{QaYe= 5j .kYd4#}#AC[42o(#I<Ūbs)AőUt* Kte p,+CIT_G*ʣY1t-MMSQT%ݩAk|"/~K?LAvEBB@`$u7CS@ MQN5nz*õfoԷɆIή˄K yh.sN% ^:E0NbpsQxyrGC,Jmmg11Fݠ MQ@3컹+>̖HQ@ϛcŁVqOMQ@K|](C"fAOA|_l_%̷~NWʛEE^GhD.sX"!J! cNuR"! Kd}VEst:#TXp1 s686b'I3%LťNfS>N5! Jwsօ>[t/Ϻu[{sDN℁cAS |fW*T]+qW>Da`y߈qG-m]+5Uz_o؏]ܲef a$Usu%ÑbdP^#eUl2ϋg3q}?xvRha.qHJaQN]{A2'(@3!uJ]qOdXC؊:7}x֌% lXYpeci)wجm&@aNqmq^Fcq2'P,F>plk(,x$)l&ьuX(2~pAl-HU{8#?`.H͂pb/"e̪>Xw၇ꩋ\jd9M asc_<<vfDxx>-(FF#QZZRmX䖖kZWN>wtߵy-#׈k_.UDQo_ekf="o?V B᱀?ؖfna^Dn hbjeVra ڿbZC_iT,sFfrߢ3*l(e1~#"wW@վiY˛ׄ_14jg,d(sAj;{RZju%C㶞:;$ZJWui+٨ XWk(h~!bh>8__?__?_ߔ6 vn7G=RNS M1m))m))|}ܖ*{#)T???V"u(Qo,&o&DnEg׭;*]u]0mik-k-PPcKiӦPmׯo[8m|3%;qt`j$4ñqHrIƧ#Դ6m5elk6KP@ĂI>\0vlF!+C,Ou\7g_cMlI1zj!sO^}~?zy $I׷5$??.m| lsi__o__o_y_ߡogTܡi]'F[e 2,.)TRF4ESMImwމ\T[wRGD 98vQ==nf?~R;YS~Sy`HR[E$5>&$\]BeϲNeU[X<ֺ՟\ɲ) pv޼E#џ2~wd~dnz_TIFå5"mT*hTS@ӌ`)iV˺{+5 ̋Y:MX XI*h>d#Rpq?o(jVlo峨PDҞIcKarTIZmWQ05?tz1rRKWׯH-ڊV\(xPaDBH-[Ͳ}ft_c.YD}ƹkCkFQUT[BmJ07׭ Wkv<1&1+Z}79Hыf .a/,2W4~.Z{1A*i4C4CqAjCt ҪAW)]pfRES C3LܶSuɯԝ04^vI^Yj.s=Y6LQ٦vf)Y26ZXa#Ev0O?_]2NmJǹ/6^y}5lo'|u_{^:_:vj>~qC IDATzd# mĔX 83 Mi@.#F7j^d{Blݧ7[7n OjuKB@vOѝ=U?pUt%bFos\E~@+[M*]U4 mF]znj*ӹ]VҗrOwzTG#^8gө>lGDq ǹ7#-[6l6:EB0},QVp` [}`zYw{R߷<鉇L[FO6\Qvmٲgf~%Jm:Yv;ˌ fvdڢi{ 9:x[s Mى*U}?Mi.Σ_R{# 杀亓xhMc{:X!ZJz}6lB:#mGK?R#}{8 EP UBxDXW"f^QҸcI %*S`EZ>Kq-8Lhwdh  cCBROe*D X}4Xdg6O4,J.`l㨬pYJ %T&*EO>"`18Sm%(:H%ZA:UJnXwbqHAkPd 8lVwxd*vimqhVzCL,  cYB*FTǺ뗔ZJ.d#d} CFkMiQ#D It"aBp DP+f-BT+֠a`C4A&),SOk^4XH[5,"q^fhe= M!JpsIt=e<ی,8VQa_ALf?h!ow'l(itLyRiKO$W;wu>||W/J^h WHbٖ!-G*ͫu==Ѝ%%C) uO204͌yKeY'o|UACNZsA?kAD(m_>uIlbvNyP  $d}q#wL65v?~]8Պq[hF.^e0~=%N3vq#!]Fl&e\Դf"4|vl?yxG}4/__|wmw>.7Q,Bznwˬ+l;y{-Ea(T^ͽRaThOtݢ7^ ۗU (p:%?00B EYΥkKK;WxPr3ީ&OT d Geȼh1_' @r6 -NzDZ059hn>=%Y%/etoDQXSV)bce.#4cBO2տx|;CS&}qwϗpY[B^v&ĸ~vzuϠXY~£2wW]]u]U !u]iHh{6=#0P5qpDE4WZyl涨򾞾" YdE)՜TB6uZXYv,{ƹDylK(J3lkie22nhF`Ќzٴ0_֛;L/zN4MQ4CӔigcrϓ'Y9w0 0^ֵvmFzw9y 0_Ad-kݏ_ 5wF]{66`;sv6$>~oXΦ! ~Al %Yem6>knli罨kiN94/cyFhFSNi ti(W錍ɭvm9&MPhO \M2\ Y[Ω8w[ZD__o|r|FBM:ۥ+Ru˪ΩeU@s $tCi_PBD@@ d86gCio9ӹqPtU `QZ_a@@e4ڏƥꎗU4rw#hJw^|{!#hfP̠WN@[ Cu5^9FI[9Xۚk!'Q""w-a!'` qG> lUjmJ.K>^^CAMyNv#͏v}YwgOwgO{]lYd2n43#SζܸRtM+8+n&Q DEh o,x8^fŭ#EfG/6@;"yڢ%p|Kc=Hvæy }Ͳ+>>⡹^wr eyt5Pb3 ,x׍n 9:a/^fǥ7I5 5.#5ΕQBJBwҢKsuEEQJK6TܹSa';IfұG.Vޏ%`!S㥉YeC 4hm9SHvh $z?x^ ͐c BKO-" /k#Skm+M;aӁN5ft梟c;ݟA>f,,EGT3aIϷ5MٯZ.6ۘmѥ hj*59_~@;=qXBxH7&pә=g9j56IB#-gJcG]KQRy&o8SCi:pݓںVzA{U)+!05{" 6pm-8o!6JHSCPa>7vq݇(;Ccf&xG6dhi&c?Z"< \`T*X>kEDlz߯5F q'7?~Qu ~mݒZ%}YRDΑĥj7Ǧ9 EQn*iT)m-@vY<㒲~w_ G# FOȪx G*ʦGsОp8-oz;:@g]v 5:j^vΐ5#6zyTfL%O- ݴVnGʓ>\>66q;ե-[6tw=ɁA3ܓV&RD5'6Wɜ_\3HO8&7SqA5g$C}&ӵZ5h/k6>;j>ֱ=阷,A B$<%;/- QFeu*䬜:>d7wG|y-\6CXxXf2Hޖ8l"V aC94=ԇSdXp4(㆓S I|)=k4T-`9HNbP(V=Czp!dC(V `)lh΃Yeca2dWXц`9 Oh){91b4ޞ1ZOy8 =CO'k.LM-hf\ˌ/}ERG[j,3yw8c{HƾnCtp6hfPCwQ|zQ.͏65Z$j;i͡A3 -$$<8m zJ4siJ DQ hg臜* YE6. CQ?M=^zoero>^iS4\pLjn1HU!#/*GmJ)}3B@k<-i=0v䛥'eI,%h*KAFhOln9.xĬ5^>9 INR)V.2V4h\lp^xȲ Je|_|׹YLb؎ z%oͺ/LS๖5~|s {l5{*[عh&ũށG|.`O )y<ߜ/5Ex , nC^(&)?En<7[w`:[ؑ}l5f<LP3~cBFƅo5 \×j4oܕe2e- z&Ðk 6?F:͸Hzks`;Y_\k;Zhb)ȰeX Ko2gX]%K'kaiE "g@D0E bȆ?@@Ěړ%ҍRY7W; EN]AV379lf##88.Rs{䵮G]EoEQuE?~ϫ3̠(Arg_CK->NK_Cwvv~pB;QyiP~Qyg_ogwn3m6CS̝놬]B)i9143(\;Eu睙nS4E/\UNSMW@ڊĝv)S]D=v^y`{WwO8p y3kūww=~0럿Fn;Ys_;fj ]Rg"\ވȫ&93u{{z_Q m+448 mzF1a{{z{zˢ35Mm6괹u=]†]eh ַtHٸ{gN jwm ҴڋCO;;g y tSڍ.IF(e/ЇH3<044N8iEp"9gwh&z8430hf")mnKS@፥ Bk=0$E4ﷴ*"R 7Ή[ͩt~( KuJQf',jCyEQ׺զF!`i[ Tr N[f rRC]7޴ڔ{8kzM#Q Kzk%g "1(!\DHϦ  }`[KǁA*-sj D$-1mђ Pdr!HM3 2+ ;,{Wem9y>)0$ĖylK BrGn8Y;,˰l.*rA;-;qfW']r~ R@;jaXh'ӇuyϧE_h~ICr 3oUuiyWs޺uKl>B#`8}9ErVl^cz.񸩌W|>rhћ}Q:rXj2"œHSV,5Fi-,KSi^"tNjYj"b#1>>?F8L+ө5 Mhܸ)+qXeNԯY['+X¶KҒMQÝ=BDoܷW*/(ӛJ,8OSM6hSW̦(x[H>yl3mg^Z"XshWAlAXqї'kXniyBvұʇ`ʌ )$tIDATWy0s!2cfH5;˺7[ a7 @ֵoEψ ߳+l[I3r wqβ8b x Ɲvm΍!mYz- wߊzb# h)-H؊tVJ:kxˌ~BfI(HUy]sjLP2n|^"VFiMQ\v]ɖ-\6\)-X_~ﳅBn 5r.-r-ҲP!FSm9_2Pun ^O[M\CߗnٲsfO-SGԩ.7dFMd'g4C|i)CiQN*zBqcP+>P,vDF2'O*g\ G ƒng5.h&41y[o:B}X+'bÀI[+l͋GsOMMYq g zCы S>L>вaB)0;NgK\!`1/2E%,ss?Aeco4Nf,aQv1,%E}4hQ ]t&MS'ϋMeNbuc.R-ϋexR VhKM4-U,Jo #M(؊e, 8,,ʠ*$A!Ԕ}CR>Rl,;dͨV]rsS~8a;+ 5Kʫ OdrY.Ak4_t| KWƋ6&ˌAC()#%XI$+sh^x;HX4VNA f^^vhpHJ4̞ 1D)p5[RޕS ,v-D˸u/)~!g[Dp4S]$1QQhVAO h5o尯XmJE~Fpp.ɫq3/hr&ob~&m"ZdAA{q4hb3ЈNL$F^2^̛h۬Wow)3V^>кM:^E}Lj}^TgmC8Op|devh̋7*oG}xh p xS9xּ7:M yBBаS><-@[o8vh2A4BËi1W1/D7`=Qr[ ATGnxʖ- G44qL} ƼGՠ 32 Nw>~ N6/| ЖFΤ#wv|^Ђz݇ Sy qe憀C_wR^#/eDɗ}VlxNl zY {S/O}xzħ~`ȩɼxS#/tzY)ͼƦ*Uhj˼xˢzYxzjm<G@31FòJuUP{;4>.5mkOz?u(UP,h|4~ < PRT7먠 * *PAT *CTPч *PPu+*DQE͗,:L( ((F3m:M3*PA7bucԵK]<|x}W+w鍤h3Ѻ *0|׵ŧQ/7ԇ *> -84M=i|eY:jXU h╽"C&ފ>Q.̋ *Lp LE]Rч *LxAa-gR2pIZT i͞lY7z~0Y"YA>TP'Ľ&쌹/ۇV  Bː騢STt0*ݏϗ?p `vF0;#xm;!d j\hA}oPA 'O(6EKsV 跚ļQ{aOY3?|1{ K~q'QU*PA"XZy?X9J\xÑ8[6~ժ a{w/0rN ~f+ТʼԆ"*KoYN㶎g̝}7|V_*PA R@y/` 'D ]Pϫ9+ZYZϾw=W 4pcqPU* D72l_l[E۷>{}Vx%xq`هz90`g7[T0h}~#%g.ә\{9;e:*PAO xUчkW}eS_k}}b~8>)xSLL?aT aR^w`]6Ge3b(ϵ+U ʁa}~>3[5^pߏG~34а9v5T *(e](Ja}||X K4Ey5g{=H:;uB>TPA o cßk+\{s>TPA9gq>VTP58>TPAʼ #hU *Ȁ* * #;@} ?#IENDB`elyxer-1.2.5/forks/jras-elyxer/test/version2.0.lyx0000644000175000017500000000333712117061342021353 0ustar chennochenno#LyX 2.0 created this file. For more info see http://www.lyx.org/ \lyxformat 413 \begin_document \begin_header \textclass scrbook \use_default_options true \maintain_unincluded_children false \language english \language_package default \inputencoding auto \fontencoding global \font_roman default \font_sans default \font_typewriter default \font_default_family default \use_non_tex_fonts false \font_sc false \font_osf false \font_sf_scale 100 \font_tt_scale 100 \graphics default \default_output_format default \output_sync 0 \bibtex_command default \index_command default \paperfontsize default \spacing single \use_hyperref false \papersize default \use_geometry false \use_amsmath 1 \use_esint 1 \use_mhchem 1 \use_mathdots 1 \cite_engine basic \use_bibtopic false \use_indices false \paperorientation portrait \suppress_date false \use_refstyle 0 \index Index \shortcut idx \color #008000 \end_index \secnumdepth 2 \tocdepth 2 \paragraph_separation indent \paragraph_indentation default \quotes_language english \papercolumns 1 \papersides 1 \paperpagestyle default \tracking_changes false \output_changes false \html_math_output 0 \html_css_as_file 0 \html_be_strict false \end_header \begin_body \begin_layout Title Version 2.0 Test \end_layout \begin_layout Standard Some random document for preliminary 2.0 tests. \end_layout \begin_layout Standard \begin_inset CommandInset href LatexCommand href name "Savannah bug 33961" target "https://savannah.nongnu.org/bugs/index.php?33961" \end_inset : Apparently \begin_inset script superscript \begin_layout Plain Layout super \end_layout \end_inset and \begin_inset script subscript \begin_layout Plain Layout subscript \end_layout \end_inset fails. \end_layout \end_body \end_document elyxer-1.2.5/forks/jras-elyxer/test/with images-1-5-good.html0000644000175000017500000000345512117061342023226 0ustar chennochenno Images Tests

Images Tests

figure elyxer-svg.png First image: regular path.
figure elyxer-svg.png Second image: convoluted path.
figure docs/elyxer.png Third image: from another directory.
figure mini-elyxer.jpg Fourth image: from a JPEG file.
figure square.png Fifth image: from a PNG file.
elyxer-1.2.5/forks/jras-elyxer/test/mini-elyxer.jpg0000644000175000017500000000304712117061342021652 0ustar chennochennoJFIFddC  !"$"$C2:"0!1A"Q2aRr#Bq'1A!"Qa2 ?죬jɣ 'UўIO@d/~#xCuO_L3M:!5;{{ 5,$}t3,%H)?s~ԋ8$3ΐ?XZ,T5U"OC bF˜9UJs;lz-OC)l$vtvu-5Jv;4UFG`A zquԣ#]`=u:B|^5ixbS~Jʇ ({}18|QSKQfE.뜖Wf0z7\,* DK/y{ Qk멧j(dsPsǼnq c;k]iN,cgl@K`W r"|DheIϗV$*n{|+3IJdD_EEqN6`,4OJr} :ݩ;ܷ.ਹ9U'.rA>ge>{:+_Ը.s!op|~&*6m^+3eɗļov%edvoQi@d+'9}`k<#BB7lJNdU5uSҼBHA7zC2:b\.skK45*ŠWKHV+Ĝ04_WTΪ4;$\/MNzι]]wGU|8?o};:Y8$֑>QDu5B㶧yQDJZ@![vN''2jh@ZoomǸ6Ҿ% u Ӿ,&$q%}smtTI(7=陼VǸܨiW[y7@븐ay = W&\7d۶J)9OW J?kZ-;j[픩MNU$Ē}$l5*4 u4j>:4hCF$@jth elyxer-1.2.5/forks/jras-elyxer/test/setcounter.lyx0000644000175000017500000000613012117061342021633 0ustar chennochenno#LyX 1.6.7 created this file. For more info see http://www.lyx.org/ \lyxformat 345 \begin_document \begin_header \textclass book \begin_preamble % eLyXer -- convert LyX source files to HTML output. % % Copyright (C) 2009-2010 Alex Fernández % % This program is free software: 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 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 % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . \setcounter{part}{2} \setcounter{chapter}{3} \setcounter{figure}{4} \setcounter{section}{1} \setcounter{subsection}{5} \end_preamble \use_default_options false \language english \inputencoding auto \font_roman default \font_sans default \font_typewriter default \font_default_family default \font_sc false \font_osf false \font_sf_scale 100 \font_tt_scale 100 \graphics default \paperfontsize default \spacing single \use_hyperref false \papersize default \use_geometry false \use_amsmath 1 \use_esint 1 \cite_engine basic \use_bibtopic false \paperorientation portrait \secnumdepth 2 \tocdepth 2 \paragraph_separation skip \defskip medskip \quotes_language english \papercolumns 1 \papersides 1 \paperpagestyle default \tracking_changes false \output_changes false \author "" \author "" \end_header \begin_body \begin_layout Title Setcounter Test \end_layout \begin_layout Standard \begin_inset CommandInset toc LatexCommand tableofcontents \end_inset \end_layout \begin_layout Standard \begin_inset FloatList figure \end_inset \end_layout \begin_layout Part Third Part \end_layout \begin_layout Chapter Chapter Four \end_layout \begin_layout Standard This is the fourth chapter, even if it comes out first. \end_layout \begin_layout Standard \begin_inset Float figure wide false sideways false status open \begin_layout Plain Layout \noindent \align center \begin_inset Graphics filename random.png scale 50 \end_inset \end_layout \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout Figure 4.1 it is. \end_layout \end_inset \end_layout \begin_layout Plain Layout \end_layout \end_inset \end_layout \begin_layout Section Section Four Point One \end_layout \begin_layout Standard This is the section 4.1, even if sections were bumped to 2. \end_layout \begin_layout Subsection Subsection 4.1.1 \end_layout \begin_layout Standard Ignoring the subsection \family typewriter \backslash setcounter \family default statement in the preamble. \end_layout \begin_layout Section Section Four Point Two \end_layout \begin_layout Standard Section 4.2 comes next. \end_layout \begin_layout Chapter Chapter Five \end_layout \begin_layout Standard The last one. \end_layout \end_body \end_document elyxer-1.2.5/forks/jras-elyxer/test/formula-good.html0000644000175000017500000000222712117061342022166 0ustar chennochenno Formula Test

Formula Test

Inline formula: a = b. Display formula:
b = a.
Numbered formula:
(1) c = c
No more, no less.
elyxer-1.2.5/forks/jras-elyxer/test/parts/0000755000175000017500000000000012117061363020036 5ustar chennochennoelyxer-1.2.5/forks/jras-elyxer/test/parts/index-1-6-part-good-Section--2.html0000644000175000017500000000446112117061342026046 0ustar chennochenno Article TOC Test

Unordered Section

Just to show that it works.
And now a list.
  1. First item.
  2. We will embed an ordered subsection here just to fake it.

    There We Go

  3. See if it’s in your TOC.
But There Is More
And nothing else.
Contents for Section
elyxer-1.2.5/forks/jras-elyxer/test/parts/index-1-6-part-good-3.html0000644000175000017500000000646612117061342024377 0ustar chennochenno Index Test
 Part II: The Additions Up Part II: The Additions Part: Unnumbered Part 

3 Bulk

We actually need a lot more text in order for our index to have more terms; so we can find out if the links are working. Since they are anchors inside the page, they might otherwise just take us to the top of the page, and we would not like that.
Yes, it would be bad for us. But on the other hand too much text can hide errors. So not much more text is needed.
Thanks for reading us.
 Part II: The Additions Up Part II: The Additions Part: Unnumbered Part 
elyxer-1.2.5/forks/jras-elyxer/test/parts/index-1-6-part-good-Part-II.html0000644000175000017500000000365612117061342025440 0ustar chennochenno Index Test
 Chapter 2: Nomenclature Up Main page Chapter 3: Bulk, or what used to be bulk text 

Part II. The Additions

 Chapter 2: Nomenclature Up Main page Chapter 3: Bulk, or what used to be bulk text 
elyxer-1.2.5/forks/jras-elyxer/test/parts/index-1-6-part-good-2.html0000644000175000017500000000615112117061342024365 0ustar chennochenno Index Test
 Chapter 1: Explanations Up Part I: The Making Part II: The Additions 

2 Nomenclature

We should explain what an index is. We can do that with the nomenclature. Normally we will want to mix index and nomenclature terms. But what happens if we actually do? We will know later, when we generate the file.

2.1 Reminder

We have to remind the reader that things will be remembered.

2.2 Remainder

Whatever remains should be explained here.
 Chapter 1: Explanations Up Part I: The Making Part II: The Additions 
elyxer-1.2.5/forks/jras-elyxer/test/parts/index-1-6-part-good-Part-I.html0000644000175000017500000000537012117061342025322 0ustar chennochenno Index Test
 Main page Up Main page Chapter 1: Explanations 

Part I. The Making

 Main page Up Main page Chapter 1: Explanations 
elyxer-1.2.5/forks/jras-elyxer/test/parts/index-1-6-part-good-A.html0000644000175000017500000000333112117061342024401 0ustar chennochenno Index Test
 Chapter 4: The definition Up Part III: Our Definition Index 

A Appendix

An appendix here, an appendix there.
 Chapter 4: The definition Up Part III: Our Definition Index 
elyxer-1.2.5/forks/jras-elyxer/test/parts/index-1-6-part-good-Part-III.html0000644000175000017500000000545412117061342025547 0ustar chennochenno Index Test
 Chapter: Unnumbered Chapter Up Main page Chapter 4: The definition 

Part III. Our Definition

 Chapter: Unnumbered Chapter Up Main page Chapter 4: The definition 
elyxer-1.2.5/forks/jras-elyxer/test/parts/index-1-6-part-good-Part--I.html0000644000175000017500000000366512117061342025404 0ustar chennochenno Index Test
 Chapter 3: Bulk, or what used to be bulk text Up Main page Chapter: Unnumbered Chapter 

Unnumbered Part

Contents for Part
 Chapter 3: Bulk, or what used to be bulk text Up Main page Chapter: Unnumbered Chapter 
elyxer-1.2.5/forks/jras-elyxer/test/parts/index-1-6-part-good-1.html0000644000175000017500000001065512117061342024370 0ustar chennochenno Index Test
 Part I: The Making Up Part I: The Making Chapter 2: Nomenclature 

1 Explanations

This chapter contains a lot of explanations for terms, which you might want to look up later. Because better sooner than later, although later has been repeated twice. Actually, thrice now.
Do you not want to look any of them up right now? No problem. You will be able to do it later, in the index.
Now we will add two cites in one, just because [2, 3].
As we will see in 3↓, not everything is clear.
You could also look down on someone, but that is not nice.

1.1Magical type face changes in the world

Little more can be added, at least at this point.

1.2Color and colour

At this other point, however, more could be added, but won’t.

Unnumbered Section

They have a right to live too.
  • A list would be nice here.
  • Because it corrupts the next chapter’s beginning.
 Part I: The Making Up Part I: The Making Chapter 2: Nomenclature 
elyxer-1.2.5/forks/jras-elyxer/test/parts/index-1-6-part-good-Nomenclature.html0000644000175000017500000000427712117061342026667 0ustar chennochenno Index Test
 Index Up Main page Bibliography 

Nomenclature

generate An activity that requires a source and a destination, something like eLyXer does with files.
index A list of terms with a reference to where they occur.
nomenclature A list of common words with an explanation.
 Index Up Main page Bibliography 
elyxer-1.2.5/forks/jras-elyxer/test/parts/index-1-6-frameset.html0000644000175000017500000000025012117061342024132 0ustar chennochenno elyxer-1.2.5/forks/jras-elyxer/test/parts/index-1-6-part-good-Bibliography.html0000644000175000017500000000373612117061342026645 0ustar chennochenno Index Test
 Nomenclature Up Main page

Bibliography

[1] WordReference.com: “definition of elixir”, accessed March 2009. http://www.wordreference.com/definition/elixir

[2] W3C: “HTML 4.01 Specification”, 24 December 1999. http://www.w3.org/TR/REC-html40/

[3] W3C: “HTML 4.01 Specification”, 24 December 1999. http://www.w3.org/TR/REC-html40/

elyxer-1.2.5/forks/jras-elyxer/test/parts/index-1-6-toc-good.html0000644000175000017500000001056112117061342024045 0ustar chennochenno Index Test elyxer-1.2.5/forks/jras-elyxer/test/parts/index-1-6-part-good-5.html0000644000175000017500000000413312117061342024366 0ustar chennochenno Article TOC Test

5 But I Already Knew That

You were lucky.

I Want My Money Back

There you have your 0€ back.

Completely Unfair Dude

Hey, I didn’t call you here.
A Paragraph For You
Totally uncalled for.
elyxer-1.2.5/forks/jras-elyxer/test/parts/index-1-6-toc-test.html0000644000175000017500000001056112117061363024077 0ustar chennochenno Index Test elyxer-1.2.5/forks/jras-elyxer/test/parts/elyxer-svg.png0000644000175000017500000010235112117061342022650 0ustar chennochennoPNG  IHDR_nbKGD X pHYsdd vpAgIDATx}w|iջdɽWt 5!$@H $! ͗PrC rS$Z l{%]q|Z gvfvvy9(Gr!q>r!ӅC9!-rC9[0r`90n#ra"G9øEs!qC}nv۷ottttttJRT… .\̜9s̙sᣍ~@x<x^{5oxcqM7X,xӦM6m_׿50}ӧ!b{o xgy Rp8l6f qؿBP(<3>8]N%X,:uԩSzAhrFٶT*J,^xOӟ{rÍ,}w}z5׈jZV B“W6&D|^>>[nݺu89C:rNQz^೟g?Y3f̘1Cl+Zbz„ &Lo߾}M0\`׾}k^X#ɖ͛7o<`֭[n=ݣCnpPYYYYYyG3> // @@"qF0N,8Q"ljjjjj:묳:ԟo9|#8|ÇE-3-8dIr'[5838Cw99hxㆍ6nn馛nr(#GGqA%fk׮]_$r =p8,Rm."JٳgϞ ̝;wܹms#q ̕ :eZ[[[[[E5믿?ݣCM{ pǎ;vH_/wp`0 ?NG^{}rxqD=BDI:Xexȗ9p,{99|Ks=sb3qx,ǀD2LAV@JR Dqat9ʋ0N5M ywySH$' )gKޠjI!O[t\. CP8}{6dlgȮ]v\r%\r n&nx'H|#W >H>^]۲USؽ{ݻ}s瀫ꪫ:ݣs7s4b2K:N$Ï;-r?9kNh}+_W\p\pV=CP0Ę%x<uH$8tFC ņXAWJljh :@5B<O8_AorDqŸ%@Νc$w$Dwwq{87Fc]+sk7F{--@0lLħFv`}60uqK$@ɖ?ªHėL9o B^/eL9L$B!Z~gNdr8> @3NMa8Csx``OwOwOg$"z[oN;ZZzz\.Z ==N{tp:=@Fcx"8F^Q6ɨ7v֖0aByy~>-mqca?Hr<"})/ 1/2T5fIY%H(X%>(~O\O||>ut w77w> KK+\n7f3{`Lz=i4)P4 `$8mOTV \yg6L~Lt==OvZ( H&c1"HzA{&@h j]PzBҳ8xqK 87567 bx" X,FN,Z4uje%0yrUUa!`Lǚ ? vdb_yE8)AP(J">RZ P(J$7onoVZaȑ~sp^PRRTK~]p՗_>e PPp~7FjTlEcјD>QYOvRbjG"776+WnDxW+_.ILZVI9[irU;zW;Z46 'Vضs"($ .; -) I.ٞ@cAUؒ?4ЬJ%/ZK rV՚@QQQ"~. kp2}D?ڵ֭;vtwC]qt"h(Iq̀Vk4׋9hb`65K/KEaґĵk| o܉ʀYKK`J2+٬k4@UJ%I0iD2IR<hFDbd2-Blk˾JR߫V[{7v`-+w Mm#=Շw:?=UW ɚ YNsDS?Z +*****F}-[}ZZfϮΊ8Rl7Xĉ'N*2l`<d a[`-0 9뮻ɌFcx}q @_Sgח ee!p۳\7L ,P"cbDUWs@_/ ^lTj5:0w~|艏1n .ᅣQvrªU{V\ӫ,,<'%>(G?oF<jl z!.nǭ.]|~`Ŋ+{/뮛>">}iʄ\t(&l b1zaA`fc'_G^O5F r*L:G'd2k׬YBbŋ/ 5W׿h<<ˆqK555555믽k/7ܱhX` ʉU JKm6,G(lB*4^N8>Ea7&eBPXeg"KPr 1z p:~߸Esc悂+>. Ri4aFfh4juxp  7pu3fU4X7FgR-;%%:ߏ 0޳g&薽 ^@ uPzQ]Uէ?կĉf*@کD'MM>D4_׬ M;= p$֖-U^-ȆrcȾcǮ]==d|Km%?yoV{ϣu T$a={zz)/z j.ۏYFlϦΙ3sfi)pyg]SYnX/jjk'LN22f/NG7H"Àӹe˻JtD.W_?V[,v;`6N8 bdkVrDˣ\nO3355TWrz0ɽ,y71A2fS}am:;r/TjupIf̸jihZ|$ |>_4JI+**(3;omBQPd JRT|xmׯXZl08aoX Z^PM'Es䕀^_RRUED' +ަ={#Gx}3f~jq4q'9̂-[P(;Z O8;4D<HdF__kDKx1*c,O-3W"ql4L|`EnXwyɫd/~fL&`Ui2Z`ܹ_sʹiuz2e9sn%R5{WI{er"^$x4tBu5%<6/PbyrT׮_xǀ/&`ڴ|#,Xz玖fS/[;?)N {kى!kabx9aq}^Ri zEŋ}}vZr\ٳYawtwG痉ٖ7})EE…WT+%l{͙S_L#~PU^~?js} ݗZ":m9sPM&EJpx}嗁w |O~~~&Ӌ7< }rc{IE",`0Ղ &y72y 4Kx|!ό+,r4|'m):o8nߗCbK/zdE""9[l;kP^p$J(ɃHھ]BtGmt>_Kˁ"b4y@/.N OmA&˟xڱcZ`˯XUNr(Ljlۓ8$E}rfiVUYcdKL\͈` DPUzad+Yg{WB޻>,ӱl#IRFE#;sY()"8УuFQoAo'R6n|MRY/׭{5 xϱd<hf]pF|8 ѱtق`¿ujbih9Sz2G% <ާ:(GG ue(*cKL@$r,Ejm6%#o|@XvÆtK~\_~2V/o6LNT__P^Eh2F"n|@w7 qΝPRl6W]OWy]x]۷*pHsݔ!~ 孒Iz1BE.)).XrI 's޼y^]N#"A```ݺ_WZ pnL)_p0$N2L&`(-$G}X\}}D|3:ٿ͋o*QZ*prǣ(?(c(vhj/;=&B7V:XR \哟Iʷ3oXq^:q\$HZNG=7(WoojsfΤ:]&fϟ:8%KN9碋(~1s:ɶ:8Hb8,RJdOq(0x,lv՘A {z$UJHuڱc: D"lS*5RY&wTE0u+O>  &ΙL@4j4g\6⓯#8xu0zx$⳥Y,6ĉ@__ooKKLFJZ{@?DJ"dpe/5])"_ VQU*P,>uۺW:/v8"rL-`ʔ"/o tz@omfssڵԸna3#͊%GXΝQ٪+|*+{!I[JdcN71=67wu9@⨱ >0P\&`0kkº:1vM;8 }tÆ'뮻ʩSPRGA_TE[{;vVfR`WXZ,WTdL@^y9>%HQ,ٹCCTvlLuȑ@xJ}|A&zTU}<]q7ڇ] t:E 3OZZIih:֖꫁l4~:lG͛Q|3^;}:pphLR\"Pb)Jںy3wȆ ںe &n"-[xܽGKZģUHz0 ,Ued߿mp={„f}T`Ҥ)Svؾ}ӦnԔ~ .¡u6ShTd2si%%?yf'L+*Uh#GF'AeZMha`vv (_HP 9(|?otf{'Ϝ}NMg>̚UZdɇ_ ;:$F{z3\X'Ϛum@OOwwK =5:75ҋ.jhniq(JS=? @'L&2Uj,8o}Kx&'PsswuIu. ?ȑ  Ob1)14xi!m `XZ֮4iR ~ ꫧwsΩpALώw㜹?1xqmן{48^ cpyٵkE;˓e5{zm_>{vx7F4 uu+Wگ~4665h~rP^^V\~UW}{O}kywݻWBA}m={eFhmݴTw<>wu.׶mk*̙W\h4_ԑZ(bH6p8`0dظnᦦXlz=LՁV/XCK|o[7( ÆqKk*;&M,(s'OِHbCC޽۷o$Jԏ:U9Ef;㌯|j L҆ ZظaPP@ѱe VӎÏ7MM}mFCJ%Gňh2i4dHIBlm=r$6n\k$@@]7PEQFwr 0"*c@8|HlRS Js$(Tc*BA6چ8xpa  (>@a2Io=ZOjz n _N⊥K*=>+(u*x]v٢E RWT9eݺ={ہUvlkBg/ r`T'*ahtwG"@oogg4J )V#"J}K];٬坂lwt(J%WTZsz.gO~̸!p8 ;iR)6*Ѩ̚E&a'\3mR #‹/Ry"A6,ʢqpR TW:$Q*EؔFѐhT"dp8"Jٽ.$SUuPX%'BqJ/BJ>kyT!Kz>kp0YBd8q2Gb1}I T )jMU~M&p/~v-,X|S~'9Bx{/֯߿or`۶ë=J= Jnj/ >}˴bm<( >cQ ۠ /F#"X 0&&I (DT 72`  Ӧ>0sf~>`it [>rٳu+wt $S\v ^r  â$>VJTRQx Wju:l|j5*P\\Zj0-/z{~'7o‚`PJ|,*"t:ry"Et[UU0sfYم<'G^w;;Kׯ`۟SdTV>JT&"e.tf~^O·onu}>RiB"~h4 //?_%O Iq9Z-NfJEq( `ggPTBmoomP0Iz1JˮJGU>E3"RaƬrQ6$ZhT!Z6*Idɮ7&O6nEEڿxزeffh)L&c1tn'U2.W_/I%.䱪S(P[A 55uuf30{y0s9yy驆,:4 v  B()``NP(ZjԪ 74Og9dopz W__0HHfQ*ɓb0 j5e )DR' j4B!z}RT0 E۾{vn3ibMCKO r+|n`׮ěBQ(x\F?Y 5p8 o>ݣz^x lFXLp:Is損#Fi11j+@Q%PIecf'AGGk/kϞ;)LǁŽlljȬ`#$*VD@8];+Wٹ! ?&BCL!" '@wwGG O*<;gXu# ,)-ٵkhT~[LLulZ-5~>^=kOKLH^CGuum<ҥ_DiHdω!H x, ~xnj_yDyG?NTUVĘ'N*{9ۉ8.m`v SQ B}0^dVFYfU!4I@t|1ft>J%_X$b$h&2"BoIYU%ekkK xd\^b֮]b 'On]ORʜ h}{$AS*ǶZ-ۻ曁 .hhE18M5͛z Wz/ єnFLMW%BRX鮻A1_oϼ 2g9A^?}{_g>N2PPihx|۶F/ ӠP'GIIi()"77{-7 o8_Z|=5xgd(ϴ_cyQ R8GDDŽ( ,9J0F/ -J3E]۶ TT?ϦOn_N-[6n<\Q*M&^n@'O;ڵ-_<ҥwTT8& Ru  2zaT#FBQ[ 8&ӝwm8Ip#m|9?TPhӦ/Y:Qj[,ƶ> .rZT@AAq^O*\2 dZVL74$Dj5BP@XrD^bjMl:y8}=tCN*ቜ`,KmBeN  1 /?"(/2EBDz=6 vSbfY;J'4~dR>|U5?[3i#M| ׿z۾ TTLzhӛZ2PXRTR̤*2b0k$PVr=_رM9i\Z{@2cbHm}4 %1zn*6@ l~Z-ep@磔.A|DtVB^[*P* I62%A":@A U|:y>؋G,AJeDT;R^^Yi0&"fhŠ{zC!੧x. `ƌ3v5(i<ġF"ΝnYg6^_Twliۿ{/} | /x ^OKӛ"}{熆~ʭ[FOp 7l>qr0sfU~W'+TORgSU3}_;+X*<>X2E! @jٴZ``/NA Ϫ4KDR"H$,WGIU%! RYF2I*'-(µIR '(*HU9ABVKN^f 8CG"dZhQZm;TxUJJJJt:!ɳ`pX=}` ??H4 SUV-\HFOzAC/WqJJ %Kv]:q2&5=Aw:OJ8p#'H9ƫ$g4vwl9BەJ 3v Y5|]  T;v]G6)RyS%d}t@߁~ʰ`FkJ԰La)T[tD*1r聁P$&"t"@n)$S&{dD+g"Z8KR%@2 QJ|&HZ"@ ǁPHHbaɯ;yOvZ$PPP\l0nEȚ9]]_>e׿/[v]"s$/m66;zJR&qn|+5J,LJu޽$9&hTyWZ5DPGT#;E|| .4?8`45YPA\6@s:[ZK.O T$N?-%>NPFi dcbgYH$u MXlLP, TD`*%^)%@X"#M.踉K"PNlMgN!$g65<Թ"^d԰FF =D+O06[^HIЉݻd@ƙ0N9]o߲ebɨ*,4)=YqzcDP=P*H9~(UrB*FC.KD\ɤqih &^1NǍPJJVoqϋֶm`4mJ 46D BdvldfG}3\ Ι^̦ `@`-Gְ75?2*hLiiyHHWI"epdmfŢVSj pLț6_tjuuT@mCCN'[K}xCDJll߿wߒ-[S>;v{G:$9KIy95xD%~PZJ, vMy  U?XBiDp?M ~` Q'87yR@IɊ5Ւ$w?p DJK'Oa;:LIUؤ!5IH/B;dKg@dnxTOPJ[(D&K<$Ad:/a; S|9U(JޟcmTsu{ PmڨڂA47*S٤!@b8X2: hnܺ4૯n닊J"zb(RJlTeW*dYY$Iңb0h BtV+ U|}]JUPl|,!21TJWTeAe $T.i`7D#g NR؊<:' OF5zhȟI2a0t;)R!NdddI ==ԎHH,ѵ81 ZFTTTWSYf*T_:;NXm>s>F/6;s {9QJeEi?>_El:sv Iy$}{AZVFD@Smy=*5m4(YU8B3DRdB!U~L{eRY"[H2I&@MGBa6j5Zttju^lStHZN @ns{~qr}1IQ6KK:;'M8_B~L0p^oX\Z({R?D8|!c$ IhҔiDj4 \bJ|lz'*K V*bNh繐j4JĞ)%dN6iJpߧ`;JR<^T*-XHE"4j%G^U<^T(L6L7?  Kw0r'?TN ."k(Dc̉L<*Hq r! JI׋WS y4AGKŒ+4%D5ĒIH_\.RWG,r> ddxhQTeh4_I It_89%'4X hnnj2щ%k}h ܩϓVKϪ5+k!YJPL$V9rxd5b` l3o߫>tSXC8sܹ4řc0h&'M*i&',J@ydp륪!΋E7GVeF"HB@(DK ;bT y(\QRIi?4e ӕRXI(TE%B(T%l\D}K:/pRɃT49#K-ORN|&B^τGi=%gyy: ($6*P3q$|f/1{;x<ce4z{C!a ;-_tnNDǑ~,DVS}EzstY#5e8`0M jmo~3mM4DE,Qqݥf|H#$=yGj"P(lOW5<`RNnl`c{ 'vԼSx< %FJ:* 9^-U*T9U*)5,sNUǤIV<1Ye@/%TL 8N0UU6""? b!I$+&>}rqv>n7IB"'$@~ޥrgiJ=?,#uNI`.h8(HBVL$nڲe?iij{A{* όVj3yDTa'"Y:X.GMڀj 91Q*8ZRAu:D(xVXLxh(Cի)BΓbjK( 񥄗}:eȽ,tDC#cI/l7,ҁD|Lrp _BN2A\4rUZlHU'aM7D\c(G/t0Z-9J+V<T?ko߼()۫iY$~ vǶL<Z#].%OkKi,FUV6iWRR^NKxs3RD~Ng2Q|"DJB^lė:AK|3R,R9P<]-Z2/oɍ bI&+v6-$@&}SCn4 FC2#9];S#֥*/{}Z2c-t:K*-2SJJHjiz.ZF#ߧRYPOkΛF7oӟ/{H/*yp]6 &KANxY,qcd#OSHǪn(DҺR MRﱔ4ӥ-1&]!ᴍ 382|}+)O/֠OH#pB`0śTzLCdBFB: VVr[ʽ{ ?*1Rl0)ҿ=SA94*>qƍ}G5i<ѨVϞ-p< /] ;2?F6}Pz< FKτ;zER9Fcc=WYᣉ@^ ەXiJ RQAuV$B^hqwma%2wX,)DJ-*H"Vyt:A:-Y ?$kbω`2鴣ߝFX(HA_*Rĉ{g~\, UEvVYF`XbɖpPА-ˏ̽ h,*@HRe44l@cYgu$NR%%FwK8ҥhqUe;bة {z߱Ty]rY~hVBD"ҏT@5ZKK?a2i4v `x8^x"7h!̈́ɬ*Ht A^ c|(%%[JE>EeE?6-z2`P#jJ-m h?};,'p(セ1ADJ$wcv`'zƩkEE9rQDRE!+`dqHX2eܦ'Ɨzq:Z-OZہ P6FdpE9M%H~@r=xkkI=NXHRtLldbjkt"XHt:=㱥UV⋀^WRRU iZNq(䁜)_X,`0PCFla6F٬5?cÇNNWT 8Dª7K^MqVU z<ҥZM9UUz=Ida*1:W`vq3K_8L,Yd[ @6Czf!L&S(D}*>'tY>__KS>pz}Qi #r"}uqhI$@Yu OMj6fA=#Դ2hB )3`t:b2YkV T`#'.u?vu:*uri~x8liiy ȑ;j?ni`@jj|>"&GU(Dd~ImP<+_>C*!& S(rr'L0hVj)m%T Xk# e`B$Y !¯JDx\Η$H&nBJKȴnk'ʺq#EV*IEDZ"nN;#o-*|Yu-553g<`AAUUmmm]v" |iJp̜Iq~ TRUbq>?vfsYىd:Dcxbd"DE#ܷ{`u̵׺\j5p?meeݟ[V+TB6S9<*+kjF`'_JEeL&Q .`Pt5yA4e #?ݝPq :T;x< eEu25TEy7:;>>K~逩^\>89^ӈZtS.X(r$d vvw[;.L៩~쟤7$<#ҚF"c~rHU{loip/⭷\py@II~P$ \w(Fs|BhQ9m#[N?%pn6{K^MX(m"AeZ/]fޟwzz#G={:;{$a`"O.V% @&' --@4g? I"|DO&MIJ4Z-`v;0}̙f3@yZ- d [J %pD,f`Lz}SbD 2)7olI뼬(H\B-/O9p}Q,B {Mk/l|G;kFAɳfz= ]xRm(,u Ӓ|, Jņiaȝ&%\nj0z0FJ|ttum~w={zG3oEN!ذa޶6`Φƞn"YU˩w DƍN:=$IPrȶakWGǪU R C]ڨ8|h^{hmA pV@yUUF#I^옪Ȼ54@iiYNTWqW6ljez^r: GU)lDK.tK! #s+WbKZJ or$TVJ3g8טWJ-zfauO&¨fKŵu31[$\t[jŋUr2Mq>paUƍ#ѨѨEcҥT';M,2"Bi@Ԯ4a18ON-Cj H؋ӯAD'I&KyJ|]]pÛ.<|1Ό<sΙ6M,N'rAAa`@$@iIg; С3hޠT*RACzzl )SiO)i0ş\1I0UU*[[Rw72k֜9V+x [JaljPȄjG/Re\6KHxS)%+B);tI$@aaQNG6Pv<^:b^΅PY2TDB I=l{$HV!co/ Xp3Ϥ N5b ++kC^07XRDtL 0 T*Rْ&i~JPg9HW==D4k;'}Wx߳ /GB08448ʕ?P*zDJJK' L^wwv]Kہbry:`DRՏX|(Ǜؾ}ŏ=xxg[,D%I~8MdDK|KcBSSOvZEH6B~BcF3 yq@N _4YF*5m#0WM{ >55f-Xp,h{JIq~vIdhhOnJN4&rg41F l?'vLؾRp* csZ~lLjp`I2z5Zb:FHx)vW(h$˜VӧSRYQ{"%wزԃ'o~SS#4={v ׬q+!:! $h4xU]8%C*u=g8Yt%Vs]7mS،$?燎gSXxH2~:_$^75Ӧ{ɈQ'M9Ng*~?tM 7߃RQEpO# YT:r x3e0Q eeTh2^.{.SJK]8Y@$y<=/'c„S`ɏl\:]& g̡C==\v;U>Ldqj2އBC`0(BBb]IrRK]/]‡"#E& Tdj?Y’K*1WnfIKIӦLvl>0 Q^zEԁO5TR6Gk>;2"yyBq )?!эFi [Z n1+--"p:} P=ɶ>jK,WIFMG7n|s{4A'qϞe˞zh?e@2I u:!4!B!S`8& 0k0ejjtK)*, k!AjuK|I=_x2jt9^hRh%KV˯xMM=*,0+l}m!./! FjbTﱨDɋt DE18HpX*@M 90Y\wnRR2G0.AKjk9UU?80m 7qo]K>%I|PyS&x?UEE',~2Q$EM6s}ܹf3tRh$7{RPas*f1 /y4!ǒW(CF**lGG{{8  PZZZRsAxzYVtd`s!Abbft*FÒ?1p- @f?X0 `ʔ9sK./} 0O@gmu[԰|NǮ]O>@4>bOϞ=[Tn`0$Rl&۞NG̑oյwxa p8j Z-{{)0yǎwZ[Lh:u:n*x6_i)l~ʿ-uwXhʶn| (-\**@.lp`a'ѦV+l6MExs?j2!†(H364f3UTh I˶! FEuk` #I1?JP(:S(W X Y/E=+=d2[cמyX!ipY4z=%ld0)BҜI^JmCM Hi(x}j-uƷDFC //۵cӟ.ՕI3/,-R*>J :;ID0 RRbO'W@2Ҁ]cǕ>1BM/(=^__ooWrĉWW"MD%U-v[N Vat:ZWU @M IDeeZ-e 9Mf .((,s!3Kiy*ytTl6Tde%|`9ϧ;%75F)Ӆ{q_bi sx {zIp)Kn2~憻,'Vqzڀ^OnشiMp]6Evzz]K'T0SG f:2h+us:6:\M/Jp0.6" c^{DeLd0gpDrbd㔼VJY(Jaƌ'._\q1j8t:nMoJJ,ڹsF cR'h@JEejJr D:A* )`D}9RbsS0`kJ7 dv«Jٹi;;wֲeb'W=\YcDTTSL⥑>nL5Rl媶j˥.0ֶn]Gw!G|3dDό|R*IsFIuum^Db2E"c;,5 iixTqb,) )t @TiqWS3a> [PqI"xSonO?hO1"&LX1kVs}qbD/h9_ⷿ ф}~~7mHu9epb{0v@8gO(vHe0Rɽr/S$U{Es Fܗ^\8*ǁΎzޔ {}}]] F#Kσ|U*N60y8^IՕ:rpR| k׶ڦ:lQ(Hh|o"[}餶՜k)nWH [Z_ճ{En/*ߗfR#![j`gg B􍊊*VGD\܀$3)$BAvSMƷd^+8oRT.'٪&L>s_1󥗞xxeo~s@{vgjN?tH&hh0lF#_[k6Fwi"R5f*tؘ'"3^  xrښɓ.eM]8Z2=eG "LUYq3ŨtZ-RR=.WkkOb˯_Lq#W\t)޾`}@7IsOtbdAA2V Px B9t|&<&'Y^_ R4J{mm]gV%[wo>/nQ '@[*Uy@E>_?XA5Vr2ߚ)S[s'wկ`zu#cHL,ÔN)MfsQ 64XNGHٛ+CdOZomm@oΝl")綱kjjoO=V)#b63?~:qF&N>7<M{hfwW2ifi^bV1K(((*R)CmDBZLzF<'u4'%{_s$$Bg dTP({|~>z{{zb1{)xG̹xɑ}B9T0NrԜ'? |snoӟ+W>? x\Llr3[U&XJ2 47Q̘QXt"ud:ommkh\\V*1r"L?gFVKe,&$T\Rmx6ML blSsG&*#mm@WlGRՍFϿ.70|p5ӧ;@MM^ތ_w+=6̘̙p!l19溧ԌFʵM$HӑK98,lU|J|RA Cx|wP)/Wn/g|S-N;2Zf.{Gᢋ x{vׁ޾tHNt"d)%nQlrhC%m.6HP\. *񉭀TRRY>n:͖=a.R5=9TrTz6eLp[Iv=~UZf+~Lp饟{g./brJGn طoښ'NL̙$2qlv;U:fJTwI)Hj3(:RsYpST^$/59mD?"dqw::(0zma ),|]o|yep,p̩;QfϾjή.@d$gV2mE"=kٜfj)_<D"dA M=l*g3$(*Zq7󟓄*-x<Ν/@0#ȽY" DŽ 4)=Y!!|>_j5OZ\KNQ;&8s'LF*() 8|xRJR(D01Ll{qg{(@To<IS*oOtົ;:q`ݺիC!P(.+_.kL&;9'lc NN8Fc+<46C7 |Nunsj@*{zdL|oD^/PJxߗ~f |0.ߟ{nM  RэghDQvh .30 }j8|]nu&K-^ÿ=3K_~:kɒS~$vK}+wZD׮Ofxx" u:t;L;9 )qR\EػKKqfH z$p=0gT6mk+` s3ޟUUyyӎ2\{p]7LD#UISc'/A᱈G S__(+>}޼3y763̆t[`vJ> hFF_0x@ t|ُmKv9poo/|xBӟ_߱gHd; $mmKEE60y) 0u*j)$9W!2<؎M|ݱx@8 45ZBlֶlf 8Hb[fJe,sM(..- jX BA8NQ\rq;8ߟH(`4Je~~c#־ PR<{p0pS6>H$(+7~/X._Dc%̟E|+?|T⬫;.7y y>nyݞdTFOq_ /]{^N`֎W_}=-[u\@;H&'NI"ˤksȶiJnJ%׃ *6@2pUUW +*IqZhh(('>6`"\ԧիW^F8^[Xs*omYg.Y|hzzdžիہw}^N nl8MFWxׁөD2]]5Œ)IDATOc#47a @(|G%Qֳ^VMޠј̀Ţ9$UVVk}PVf?tn|΁Kի6nܺu۶LG&cUyJJop%?ħ>$r_z閛/صOSJIc%%Βb٠x룏>M+V<r![E٬T{B…3ft7TTqƩq@sHA, @o]7I]6M0e PR2gYgQt_E99!->?d9Ç9!-rC9[0r`90n#ra"G9øEs!qC9!-rC9[0r&dk8%tEXtdate:create2010-01-22T02:44:07+01:00ZrUk%tEXtdate:modify2010-01-22T02:44:07+01:00+/FtEXtsvg:base-urifile:///home/chenno/projects/elyxer/test/./elyxer-svg.svgV#IENDB`elyxer-1.2.5/forks/jras-elyxer/test/parts/accept-all0000755000175000017500000000221212117061342021763 0ustar chennochenno#!/bin/bash # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # Alex 20100419: accept all splitpart test files as good echo "Accepting all eLyXer splitpart test files as good" echo "You should only do this if you have made a large change in all test files" echo " and you are sure that all files come out right!" # do it only for splitpart test files for oldfile in *test*.html; do newfile=${oldfile/"test"/"good"} mv -f "$oldfile" "$newfile" done elyxer-1.2.5/forks/jras-elyxer/test/parts/index-1-6-part-good-Index.html0000644000175000017500000001247512117061342025301 0ustar chennochenno Index Test
 Appendix A: Appendix Up Main page Nomenclature 

Index

able:

anchor:

error:

explained:

hand:

index: , , ,

later: , ,

link:

look:

down:

up: ,

page:

remembered:

sooner:

term:

terms:

text: , ,

thrice:

top of the page:

twice:

 Appendix A: Appendix Up Main page Nomenclature 
elyxer-1.2.5/forks/jras-elyxer/test/parts/index-1-6-part-good-4.html0000644000175000017500000000636712117061342024400 0ustar chennochenno Index Test
 Part III: Our Definition Up Part III: Our Definition Appendix A: Appendix 

4 The definition

A TOC is a Table Of Contents.

4.1 But I Already Knew That

You were lucky.

4.1.1 I Want My Money Back

There you have your 0€ back.

4.1.1.1 Completely Unfair Dude

Hey, I didn’t call you here.
A Paragraph For You
Totally uncalled for.
figure elyxer-svg.png
Figure 4.1 eLyXer logo

Unordered Section

Just to show that it works.
And now a list.
  1. First item.
  2. We will embed an ordered subsection here just to fake it.

    4.1.2 There We Go

  3. See if it’s in your TOC.
But There Is More
And nothing else.
 Part III: Our Definition Up Part III: Our Definition Appendix A: Appendix 
elyxer-1.2.5/forks/jras-elyxer/test/parts/index-1-6-part-good.html0000644000175000017500000001127212117061342024226 0ustar chennochenno Index Test elyxer-1.2.5/forks/jras-elyxer/test/parts/index-1-6-part-good-Chapter--1.html0000644000175000017500000001260512117061342026026 0ustar chennochenno Index Test elyxer-1.2.5/forks/jras-elyxer/test/template.html0000644000175000017500000000076612117061342021414 0ustar chennochenno <!--$title-->

(C)

elyxer-1.2.5/forks/jras-elyxer/test/languages-good.html0000644000175000017500000000171412117061342022467 0ustar chennochenno Converted document
This is some English text.
Esto es texto en español.
elyxer-1.2.5/forks/jras-elyxer/test/file-1-6-good.html0000644000175000017500000000345012117061342021740 0ustar chennochenno File Test

File Test

Created by Alex Fernández

This document was created with LyX 1.6.2rc2, a great text editor.

Part I. The only part

1 The First Section

With some text. And a greyed out note.

Another Section (Not Numbered)

With some more text.
Now we include a different document.
Hello world
And now a verbatim include.
Plain text document.
  To be included verbatim in a LyX document.

Do not modify unless you want to test something.


Index

elyxer-1.2.5/forks/jras-elyxer/test/toc-book.lyx0000644000175000017500000001031012117061342021150 0ustar chennochenno#LyX 1.6.7 created this file. For more info see http://www.lyx.org/ \lyxformat 345 \begin_document \begin_header \textclass book \begin_preamble % eLyXer -- convert LyX source files to HTML output. % % Copyright (C) 2009-2010 Alex Fernández % % This program is free software: 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 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 % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . \end_preamble \use_default_options false \language english \inputencoding auto \font_roman default \font_sans default \font_typewriter default \font_default_family default \font_sc false \font_osf false \font_sf_scale 100 \font_tt_scale 100 \graphics default \paperfontsize default \spacing single \use_hyperref false \papersize default \use_geometry false \use_amsmath 1 \use_esint 1 \cite_engine basic \use_bibtopic false \paperorientation portrait \secnumdepth 1 \tocdepth 2 \paragraph_separation skip \defskip medskip \quotes_language english \papercolumns 1 \papersides 1 \paperpagestyle default \tracking_changes false \output_changes false \author "" \author "" \end_header \begin_body \begin_layout Title Book TOC Test \end_layout \begin_layout Standard \begin_inset CommandInset toc LatexCommand tableofcontents \end_inset \end_layout \begin_layout Standard \begin_inset FloatList figure \end_inset \end_layout \begin_layout Part Our Definition \end_layout \begin_layout Chapter The definition \end_layout \begin_layout Standard A TOC is a Table Of Contents. \end_layout \begin_layout Standard \begin_inset Note Comment status open \begin_layout Section Hidden Section \end_layout \begin_layout Plain Layout This section should be hidden from mortals, and from the TOC. \end_layout \end_inset \end_layout \begin_layout Section But I Already Knew That \end_layout \begin_layout Standard You were lucky. \end_layout \begin_layout Subsection I Want My Money Back \end_layout \begin_layout Standard There you have your 0€ back. \end_layout \begin_layout Subsubsection Completely Unfair Dude \end_layout \begin_layout Standard Hey, I didn't call you here. \end_layout \begin_layout Paragraph A Paragraph For You \end_layout \begin_layout Standard Totally uncalled for. \end_layout \begin_layout Standard \begin_inset Float figure wide false sideways false status open \begin_layout Plain Layout \noindent \align center \begin_inset Graphics filename elyxer-svg.svg \end_inset \end_layout \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout eLyXer logo \end_layout \end_inset \end_layout \begin_layout Plain Layout \end_layout \end_inset \end_layout \begin_layout Section* Unordered Section \end_layout \begin_layout Standard Just to show that it works. \end_layout \begin_layout Standard And now a list. \end_layout \begin_layout Enumerate First item. \end_layout \begin_layout Enumerate We will embed an ordered subsection here just to fake it. \end_layout \begin_deeper \begin_layout Subsection There We Go \end_layout \end_deeper \begin_layout Enumerate See if it's in your TOC. \end_layout \begin_layout Paragraph But There Is More \end_layout \begin_layout Standard And nothing else. \end_layout \begin_layout Standard \begin_inset Note Comment status open \begin_layout Plain Layout \begin_inset CommandInset index_print LatexCommand printindex \end_inset \end_layout \end_inset \end_layout \begin_layout Chapter \start_of_appendix Appendix \end_layout \begin_layout Standard An appendix here, an appendix there. \end_layout \begin_layout Standard \begin_inset Note Comment status open \begin_layout Plain Layout \begin_inset CommandInset bibtex LatexCommand bibtex bibfiles "bibtex-plain" options "bibtotoc,plain" \end_inset \end_layout \end_inset \end_layout \end_body \end_document elyxer-1.2.5/forks/jras-elyxer/test/rabbit-walrus.svg0000644000175000017500000002462712117061342022214 0ustar chennochenno image/svg+xml elyxer-1.2.5/forks/jras-elyxer/test/math-1-6-good.html0000644000175000017500000013070412117061342021755 0ustar chennochenno Math Test

Math Test

1 Limits

A limit:
limx → ∞f(x), 
which should appear as x → ∞ in italics, and «lim» in plain style. Inlined: limx → ∞f(x).
And why not, a sum:
i = 1ai, 
where the sum’s limits should appear below (i = 1) and above () the but to the right. Inlined: i = 1ai. Integral: x = ax dx. Display mode:
x = ax dx.
We can also integrate without limits: A dx.
A sum inside another element (red color):
i = 1ai.
The placing of limits can be cofigured with the \limits and \nolimits macros:
limx → ∞f(x),  i = 1x,  0f(x) dx

1.1 Super- and Subscript

When any element has both super- and subscript, they should appear like inlined limits, one above the other: a34. Also before an element: 32 He. In display mode:
i, jaij + i, jaji = iaii, 
21 H + 21 H → 32 He + 10 n.

2 Numeration

Equations can be numbered, like 1↓.
(1) y = x
And also like 2↓.
(2) x = 3
Notice that eq. 2↑ comes after eq. 1↑.
Some equations can also be numbered, even if they don’t have a label.
(3) x = 2y
Other equations that contain * should not numbered, but perhaps aligned:
left right
Some environments allow for multiple labels:
(4) a  =  b × c (5) c × d × e  =  i.
Now a random environment: x y.

3 Brackets

An array:
12 2 3 4 × yx
And an inline array a b c dio .
Arrays are separated by variable-size brackets: a b c d a b c d a b c d a b c d ||| a b c d |||which might also differ on right and left a b c d or use the empty opening a b c d or closing: a b c d |||. There are also fixed-size big brackets: (a) [b] {c} d |e| f.
Aligned brackets can be present: (toText). One of them may be omitted: toText).
Aligned brackets can be applied to complex items:
s × 1 +  a11 a21 a12 a22  ×  1  − 1  − 1  − 1  +  1  − 1 0  − 1 1 0 0 0 r .
Math brackets should not be mistaken for TeX brackets: ({s(x)})/(2).

4 Fraction

A big recursive fraction:
(1)/(1 + (1)/(1 + (1)/(1 + 2x)))
A nice fraction: 56.
A non-diminishing fraction containing alignments:
(1)/(1 + (1)/(1 + x) × (1)/(1 + x)).
A similar concept is a binomial coefficient: (A + 1B). It can be prettily presented:
AB + 1.
A symbol can be stacked over another using \stackrel: xR → y. Anything can be stacked: headheels.

5 Roots

A square root: (3). A root in a fraction: (((78x + 45y) × (Height))/(sin(x + 1)) + 5).
A more complex square root in a fraction:
(1)/(1 + (2)(1)/(1 + (2)) + ((1)/(2))).
Higher order roots: 3(x + y), x + 1(Weight). In a fraction:
(78((8)/(4)x))/(s + 5(((78x + 45y) × (Height))/(sin(x + 1)) + 5)).

6 Decorations

6.1 Cases

Used to switch several values.
y =  x i = 0,         x + 1  i < 3 
Cases may have more than two rows:
f(x) =  0  x < 0,         ∞  x = 0,         0  x > 0 

6.2 Braces

Values can be underbraced or overbraced.
a − b = c + d + e + f.
Underbraces and overbraces can contain text.
a − bover = c + d + eover + funder + g.
They can also be inlined: a + bover.

7 Spacing

The command \raisebox is useful to, surprisingly, raise a little box,
raisedoverlowered and back.
Like \mbox, it puts its content in a text box. It can also be used just for spacing:
BV.
There are other spacing commands: \hspace a b, protected space a b, and at “block level” \vspace: a b.
There should be 1 cm of vertical space above this paragraph.

8 Fonts

This section tests font support.

8.1 Variables and Functions

By default, letters denote variables and are taken from the \mathnormal font, which is italic: αx + αy = α(x + y), with the exception of upright capital Greek letters, G ≠ Γ. Letters run together represent different variables: abcd = a × b × c × d.
There has been some trouble over some commands like Greek letters; some of them should be italicized, as in: μ or Å. Others should not, as in Ω. Upright Greek letters are also available: μ ≠ μ. An example from the LyX math guide:
π +  → μ +  + νμ.
Functions names should be upright: sin(2π), log(x), tanδ.

8.2 Mathematical Fonts

Mathematical fonts used in equations include Roman (\mathrm), Sans Serif (\mathsf), Typewriter (\mathtt), Bold (\mathbf), SCRIPT (\mathscr), CALLIGRAPHIC (\mathcal), BLACKBOARD BOLD (\mathbb), and Fraktur (\mathfrak). For the latter, some single characters are translated to their Unicode equivalents: , 𝔽, 𝔉.
Regular text in a formula can be achieved via text font commands like \textrm: 5  to 10, via boxes like \mbox (prevents line breaks): 6  is more than 5, or the AMSmath \text macro (scales like math symbols) basesupersub. The content of an mbox is processed in LaTeX text mode. This allows text font commands, e.g. a switch to sans-serif-bold-italic, or the phonetic alphabet: sfbfit, tipa.

8.3 Units

Units should be written upright, either with \mathrm or with macros from the units package, e.g. as simple unit, km, with magnitude, 57 km, with fractional unit, 200 kmh, or with a fraction before the units, 32 km, (7)/(16) s.

8.4 Sizes

Sizes can be specified in formulas: display, text, script, scriptscript.

9 Colors and Boxes

A colored box: aaa.
A framed box: box. It can be aligned left: box or right: box.

10 Macros

Definitions can be added as macros. Then they can be used in formulae: (12) + 1(2).
Macro definitions can accept default parameters. Again, useful in formulae: 4(5). Default parameters can then be overriden: 5(y) + x(4).
Other definitions from the preamble can be used: 3(4).
Definitions on the fly are also possible: 7(8), and used with different values: a(b).
Macros may contain a literal parameter. It should parse correctly: t.
A macro with four parameters from the LyX detailed math guide. Now in use: 1 + x1,  2 =  − ((1 − x))/(2)±(((1 − x)2)/(4) − 5) − B.

11 Pathological Cases

Empty equations have been known to fail: .
An equation with an mbox containing a comment: text more, and a comment inside textrm: text more. Finally, a comment at the end of a text function: only text.

12 Bye-bye

That’s all folks!
elyxer-1.2.5/forks/jras-elyxer/test/abstract-good.html0000644000175000017500000000217412117061342022325 0ustar chennochenno Abstract Test

Abstract Test

Abstract

This document is a test of the abstract capabilities of LyX.
When exported in LyX, this abstract should be shown contiguous.
Apart from the abstract, not much more yet.
elyxer-1.2.5/forks/jras-elyxer/test/setcounter-good.html0000644000175000017500000000600512117061342022712 0ustar chennochenno Setcounter Test

Setcounter Test

Part III. Third Part

4 Chapter Four

This is the fourth chapter, even if it comes out first.
figure random.png
Figure 4.1 Figure 4.1 it is.

4.1 Section Four Point One

This is the section 4.1, even if sections were bumped to 2.

4.1.1 Subsection 4.1.1

Ignoring the subsection \setcounter statement in the preamble.

4.2 Section Four Point Two

Section 4.2 comes next.

5 Chapter Five

The last one.
elyxer-1.2.5/forks/jras-elyxer/test/subdir/0000755000175000017500000000000012117061362020174 5ustar chennochennoelyxer-1.2.5/forks/jras-elyxer/test/subdir/appendix-1-6.lyx0000644000175000017500000005244412117061361023053 0ustar chennochenno#LyX 1.6.5 created this file. For more info see http://www.lyx.org/ \lyxformat 345 \begin_document \begin_header \textclass scrbook \begin_preamble % eLyXer -- convert LyX source files to HTML output. % % Copyright (C) 2009-2010 Alex Fernández % % This program is free software: 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 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 % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % DO NOT ALTER THIS PREAMBLE!!! % % This preamble is designed to ensure that the User's Guide prints % out as advertised. If you mess with this preamble, % parts of the User's Guide may not print out as expected. If you % have problems LaTeXing this file, please contact % the documentation team % email: lyx-docs@lists.lyx.org \usepackage{ifpdf} % part of the hyperref bundle \ifpdf % if pdflatex is used % set fonts for nicer pdf view \IfFileExists{lmodern.sty}{\usepackage{lmodern}}{} \fi % end if pdflatex is used % for correct jump positions whe clicking on a link to a float \usepackage[figure]{hypcap} % the pages of the TOC is numbered roman % and a pdf-bookmark for the TOC is added \let\myTOC\tableofcontents \renewcommand{\tableofcontents}{% \frontmatter \pdfbookmark[1]{\contentsname}{} \myTOC \mainmatter } % redefine the \LyX macro for PDF bookmarks \def\LyX{\texorpdfstring{% L\kern-.1667em\lower.25em\hbox{Y}\kern-.125emX\@} {LyX}} % define a short command for \textvisiblespace \newcommand{\spce}{\textvisiblespace} % macro for italic page numbers in the index \newcommand{\IndexDef}[1]{\textit{#1}} % redefine the greyed out note \end_preamble \options intoc,bibtotoc,idxtotoc,BCOR7mm,tablecaptionabove \use_default_options false \language english \inputencoding auto \font_roman default \font_sans default \font_typewriter default \font_default_family default \font_sc false \font_osf false \font_sf_scale 100 \font_tt_scale 100 \graphics default \paperfontsize 12 \spacing single \use_hyperref true \pdf_title "Appendix Test" \pdf_author "Alex Fernández" \pdf_subject "Containing Numeration and Other Appendixy things" \pdf_keywords "LyX eLyXer" \pdf_bookmarks true \pdf_bookmarksnumbered true \pdf_bookmarksopen false \pdf_bookmarksopenlevel 1 \pdf_breaklinks false \pdf_pdfborder false \pdf_colorlinks true \pdf_backref false \pdf_pdfusetitle false \pdf_quoted_options "linkcolor=black, citecolor=black, urlcolor=blue, filecolor=blue,pdfpagelayout=OneColumn, pdfnewwindow=true,pdfstartview=XYZ, plainpages=false, pdfpagelabels,pdftex" \papersize default \use_geometry false \use_amsmath 1 \use_esint 0 \cite_engine basic \use_bibtopic false \paperorientation portrait \secnumdepth 3 \tocdepth 3 \paragraph_separation skip \defskip medskip \quotes_language english \papercolumns 1 \papersides 2 \paperpagestyle default \tracking_changes false \output_changes false \author "" \author "" \end_header \begin_body \begin_layout Title Appendix Test \end_layout \begin_layout Author Alex Fernández (elyxer@gmail.com) \end_layout \begin_layout Standard \begin_inset CommandInset toc LatexCommand tableofcontents \end_inset \end_layout \begin_layout Standard \begin_inset FloatList figure \end_inset \end_layout \begin_layout Standard \begin_inset FloatList table \end_inset \end_layout \begin_layout Part Of How Our Hero Came and Went \end_layout \begin_layout Chapter The Coming \end_layout \begin_layout Standard Our hero came in. He was tired. He thought the world belonged to him. \end_layout \begin_layout Section The Meeting \end_layout \begin_layout Standard Our hero met with Laurinda. She was smiling. But our hero was not amused. His whiskers were dripping wet, he was astonishingly thirsty, and the contradic tion was killing him. \begin_inset Quotes eld \end_inset Give me some beer, woman! \begin_inset Quotes erd \end_inset , he ordered. \end_layout \begin_layout Section The Melting \end_layout \begin_layout Standard Laurinda smiled again. \begin_inset Quotes eld \end_inset But Wenceslau, you don't belong here. \begin_inset Quotes erd \end_inset What a stupid thing to say at that precise moment, our hero thought to himself. Only that it came out loud. At that precise moment he knew that the desired beer would not be forthcoming. \end_layout \begin_layout Standard He turned to the bartender and tried to obtain a beer by the very old method of purchasing it. But being ignored was not one of Laurinda's specialities. \end_layout \begin_layout Chapter The Going \end_layout \begin_layout Standard It could not last. Laurinda's hips were flapping, and she was hopping mad. \end_layout \begin_layout Section Our Hero's Imagination \end_layout \begin_layout Standard Our hero imagined her as a rabbit with long ears and a fine set of tusks. In a short time the image drifted to a walrus, and our hero could not help letting his sinister smile giving him away. Figure \begin_inset CommandInset ref LatexCommand ref reference "fig:rabbit-walrus" \end_inset shows a gross approximation of the rabbit-walrus. \end_layout \begin_layout Standard \begin_inset Float figure wide false sideways false status open \begin_layout Plain Layout \align center \begin_inset Graphics filename rabbit-walrus.svg \end_inset \end_layout \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout \begin_inset CommandInset label LatexCommand label name "fig:rabbit-walrus" \end_inset The rabbit-walrus. \end_layout \end_inset \end_layout \begin_layout Plain Layout \end_layout \end_inset \end_layout \begin_layout Section Laurinda's Anger \end_layout \begin_layout Standard \begin_inset Quotes eld \end_inset Wasn't it great \begin_inset Quotes erd \end_inset , said Laurinda. Actually she said it in the present tense, but our poor storytelling skills have changed that to a cheesy past. Don't do this at home, kids. You want to be regarded for your authenticity, and misquoting isn't going to help much. \end_layout \begin_layout Standard Anyway, back to the story. Laurinda wanted to hit him in the head with a big ham that she kept just for occassions like this, and being a solid Hitchcock fan she was ready to cook the ham afterwards and serve the resulting stew to any policemen that might come by. She was also a huge Almodóvar fan, but she was unaware that in an early film the divine Pedro had copied the scene. Actually both directors had copied the idea from a short story by Roald Dahl, very much worth reading. Although it must be said that in this story it was a lamb leg, which hardly offers the consistency and stiffness necessary to kill a sturdy husband. \end_layout \begin_layout Standard But who cares. Laurinda meanwhile had a funny appearance; if you want to see why please direct your eyes to figure \begin_inset CommandInset ref LatexCommand ref reference "fig:anger" \end_inset . \end_layout \begin_layout Standard \begin_inset Float figure wide false sideways false status open \begin_layout Plain Layout \align center \begin_inset Graphics filename laurindas-anger.svg \end_inset \end_layout \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout \begin_inset CommandInset label LatexCommand label name "fig:anger" \end_inset Laurinda's anger pictured in a mildly humorous tone. \end_layout \end_inset \end_layout \end_inset \end_layout \begin_layout Standard And yet, how furious was really Laurinda, whom we may optionally refer to as Melinda from now on? Table \begin_inset CommandInset ref LatexCommand ref reference "tab:anger-time" \end_inset vainly attempts to quantify it. \end_layout \begin_layout Standard \begin_inset Float table wide false sideways false status open \begin_layout Plain Layout \align center \begin_inset Tabular \begin_inset Text \begin_layout Plain Layout Anger \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Time \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 1 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 2 \end_layout \end_inset \end_inset \end_layout \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout \begin_inset CommandInset label LatexCommand label name "tab:anger-time" \end_inset Laurinda's anger as a function of time. \end_layout \end_inset \end_layout \end_inset \end_layout \begin_layout Standard For the sake of Laurinda's furiousness, here is figure \begin_inset CommandInset ref LatexCommand ref reference "fig:anger-again" \end_inset again. \end_layout \begin_layout Standard \begin_inset Float figure wide false sideways false status open \begin_layout Plain Layout \align center \begin_inset Graphics filename laurindas-anger.svg \end_inset \end_layout \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout \begin_inset CommandInset label LatexCommand label name "fig:anger-again" \end_inset Laurinda's anger, again. \end_layout \end_inset \end_layout \end_inset \end_layout \begin_layout Standard But how did Laurinda compute her anger? We cannot but speculate; here is a stupid suggestion in listing \begin_inset CommandInset ref LatexCommand ref reference "alg:computation" \end_inset . \end_layout \begin_layout Standard \begin_inset Float algorithm wide false sideways false status open \begin_layout Plain Layout anger = time - 1 \end_layout \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout \begin_inset CommandInset label LatexCommand label name "alg:computation" \end_inset Laurinda computes her anger. \end_layout \end_inset \end_layout \begin_layout Plain Layout \end_layout \end_inset \end_layout \begin_layout Standard The result is in table \begin_inset CommandInset ref LatexCommand ref reference "tab:anger-time-again" \end_inset , proving we were right all along. Also subtables \begin_inset CommandInset ref LatexCommand ref reference "tab:Only-Anger" \end_inset and \begin_inset CommandInset ref LatexCommand ref reference "tab:Only-Time" \end_inset show anger and time, respectively. \end_layout \begin_layout Standard \begin_inset Float table wide false sideways false status open \begin_layout Plain Layout \align center \begin_inset Float table wide false sideways false status open \begin_layout Plain Layout \align center \begin_inset Tabular \begin_inset Text \begin_layout Plain Layout Anger \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 1 \end_layout \end_inset \end_inset \end_layout \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout \begin_inset CommandInset label LatexCommand label name "tab:Only-Anger" \end_inset Only Anger. \end_layout \end_inset \end_layout \end_inset \begin_inset Float table wide false sideways false status open \begin_layout Plain Layout \align center \begin_inset Tabular \begin_inset Text \begin_layout Plain Layout Time \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 2 \end_layout \end_inset \end_inset \begin_inset Caption \begin_layout Plain Layout \begin_inset CommandInset label LatexCommand label name "tab:Only-Time" \end_inset Only Time. \end_layout \end_inset \end_layout \end_inset \end_layout \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout \begin_inset CommandInset label LatexCommand label name "tab:anger-time-again" \end_inset Laurinda's anger quantified, divided in two. \end_layout \end_inset \end_layout \end_inset \end_layout \begin_layout Standard Interested in that last table? Let us repeat it but without a label and with a table and a subtable \begin_inset CommandInset ref LatexCommand ref reference "tab:rabbit-walrus-encore" \end_inset . \end_layout \begin_layout Standard \begin_inset Float table wide false sideways false status open \begin_layout Plain Layout \align center \begin_inset Float table wide false sideways false status open \begin_layout Plain Layout Censored \end_layout \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout \begin_inset CommandInset label LatexCommand label name "tab:rabbit-walrus-encore" \end_inset The rabbit-walrus does an encore. \end_layout \end_inset \end_layout \begin_layout Plain Layout \end_layout \end_inset \begin_inset Tabular \begin_inset Text \begin_layout Plain Layout Anger \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Time \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 1 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 2 \end_layout \end_inset \end_inset \end_layout \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout One more time. \end_layout \end_inset \end_layout \end_inset \end_layout \begin_layout Section The Passing Away \end_layout \begin_layout Standard Our hero was passing by the village. He had only stopped to say \begin_inset Quotes eld \end_inset Hi! \begin_inset Quotes erd \end_inset Again here our lousy skills have made us spoil the quote, but this time for the opposite reasons: everyone knows how to say \begin_inset Quotes eld \end_inset Hi! \begin_inset Quotes erd \end_inset , so we don't need an actual quote. It is enough to report that the had stopped to say hi, even maybe qualifying it a bit to make do for the missing exclamation sign: he could have stopped to say a friendly hi. Getting all literary he could have stopped to say a longing hi, although this road leads to bizarreness. It could be cool though. \end_layout \begin_layout Standard But anyway. Laurinda was so mad, so hopping mad that she called her friend, the Assassin. He was not in town at that precise moment, but that didn't help our hero as he was just outside town killing people in a small barn. Just for practice. \end_layout \begin_layout Standard Our hero left the village, but Laurinda cunningly annotated the MAC address of his laptop's wifi card. The lack of networking knowledge on the part of our hero (who really couldn't tell a SYN packet from an ACK) was to play an important part in the story -- if he had known how to change the MAC address, which identified him with the precision of a surgeon's scalpel, he would have been safe. \end_layout \begin_layout Standard Let's not even get into that last scalpel metaphor, shall we not? It leaks worse than the Titanic. \end_layout \begin_layout Part Of How Our Hero Went No More \end_layout \begin_layout Chapter The Killing \end_layout \begin_layout Standard Our hero led a happy existence for a long time afterwards, randomly avoiding all points within connecting distance of a wifi network. It could not last. \end_layout \begin_layout Standard Our hero went to the next village, found a friendly Moonrams cafe and connected to the net. Quickly the assassin (who knew the very people that run the internet, and who by this display of nerdiness no longer merits the starting capital letter) traced a bunch of IP packets coming from our hero's MAC address. He deployed a team of murderous African bees, which as surely as a well-cared-f or AK-47 reached our hero and killed him with three fast stings. Of course they died afterwards, being bees and all, so it was an astounding feat this training of wild African bees just for this one murder. Maybe the Assassin merits that capital letter after all. \end_layout \begin_layout Section The Passing Away \end_layout \begin_layout Standard Our hero was undone. He was no more. He was, actually, an ex-hero. We shall narrate his wake soon. \end_layout \begin_layout Itemize But first a message from our kind sponsors. They want to present you the next section in this deeper inset. \end_layout \begin_deeper \begin_layout Section The Mourning \end_layout \begin_layout Standard Everyone cried in the ceremony. It was so sad that we need an image of this moment. You can find it in figure \begin_inset CommandInset ref LatexCommand ref reference "fig:mourning" \end_inset . \begin_inset Note Greyedout status open \begin_layout Plain Layout Mental note: never pay the artist beforehand. \end_layout \end_inset \end_layout \end_deeper \begin_layout Standard \begin_inset Float figure wide false sideways false status open \begin_layout Plain Layout \align center \begin_inset Graphics filename mourning.svg \end_inset \end_layout \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout \begin_inset CommandInset label LatexCommand label name "fig:mourning" \end_inset A crude approximation to our hero's mourning. \end_layout \end_inset \end_layout \end_inset \end_layout \begin_layout Standard And thusly everything happened. \end_layout \begin_layout Chapter The Mourning \end_layout \begin_layout Standard We have already talked at length about the mourning, and under sponsorship no less, so no further details will be given here. Suffice to say that our hero was mourned. A lot. \end_layout \begin_layout Chapter \start_of_appendix The Rebirth \end_layout \begin_layout Standard Surprising everyone, our hero was about to make a comeback. \end_layout \begin_layout Section Coming Again \end_layout \begin_layout Standard As it happened, our hero had never died; he had just faked his own death to find out his assassin. It was not difficult, what with the capital letter and all. \end_layout \begin_layout Section Two is Better than One \end_layout \begin_layout Standard How to make another comeback? This is left as an exercise to the reader. \end_layout \begin_layout Chapter Our Recommendation to Kids \end_layout \begin_layout Standard Never trust killer bees. Or Assassins. \end_layout \begin_layout Section Killer Bees and Their Perils \end_layout \begin_layout Standard A killer bee cannot be trained consistently, since it will die at the first sting. Better use killing wasps -- or, even better, solve your differencies talking. \end_layout \begin_layout Standard For the sake of your education, check figure \begin_inset CommandInset ref LatexCommand ref reference "fig:killer-bees" \end_inset . It shows a bunch of killer bees, or something. \end_layout \begin_layout Standard \begin_inset Float figure wide false sideways false status open \begin_layout Plain Layout \align center \begin_inset Graphics filename mourning.svg \end_inset \end_layout \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout \begin_inset CommandInset label LatexCommand label name "fig:killer-bees" \end_inset A gathering of killer bees. Supposedly. \end_layout \end_inset \end_layout \end_inset \end_layout \begin_layout Section Assassins: Inherently Unreliable \end_layout \begin_layout Standard Someone who kills people (even for business) is not someone you want to deal with. Watch \begin_inset Quotes eld \end_inset Fargo \begin_inset Quotes erd \end_inset by the Coen Brothers if you don't believe me. And remember: a hero under the belt is a feather on the hat. \end_layout \end_body \end_document elyxer-1.2.5/forks/jras-elyxer/test/subdir/mini-elyxer.jpg0000644000175000017500000000304712117061342023142 0ustar chennochennoJFIFddC  !"$"$C2:"0!1A"Q2aRr#Bq&1A!"Qa2 ?죬Jɣ*'b4gFn*dd#YgK߈mS%7LΈMF&Mf%I_]4*F D R vg)b2WHmahRUWH5= * dK.pW=)>*ڼj{UH[ޤ=,rIPgPvgRӣTyo:,IEPiatdxv @ǮG]4pbk#SJU S[|WHhV/%<픡  GqNAyu4mI R^ep6cWzCڕ\D?y{ Qk멧j(dsPsǼnV8i54[['dU1} %X+e9ai]`42CqitYYUl?jUU=UP%2"/8]uKl)XAЙ~ھ prޡ ?sRr$q]?׺)㢵K02'WʷrbnڨOz5*S?˦Z^<{ Kɐ1[9bVVGl E B2pXz'Fh[U%@ oӧ6ZZꚺi^Gn!$ _!]}nEJvb+d%$+Nrv@|j8k~D$U|OUO\SOSRN!=T-{dqWaHPcr$ d䞴_x j()KP(+~!XO!֦ EoO{o]+RPY[O1);ɜbGQW:ΆEH$kjbC~I#>n웊[ʆujh)ؘq*J l`xɵW:;M6풊NSR,<p yWVף[WTkLң~\DVޭ:RCNh;gwW *3j}ږe*S,rI$1$rI'[]b ×{ZG1А:4hғ4Ѣelyxer-1.2.5/forks/jras-elyxer/test/subdir/mourning.png0000644000175000017500000003177012117061361022547 0ustar chennochennoPNG  IHDR[$NQgAMA asRGB cHRMz&u0`:pQ<bKGD X pHYsdd2IDATxg\Tw9ӇA,4 `5{^Sl٘n4c{; D.Sv+,|\ g/9s'  xpE                        zr~§"\' Pn/(j_tMe/9M<\Unu=nRpE'|Qo--mΗIH{ḳuS4ƞS8\ ~T}Þ!X[kmZvM_YIZIڰϴ?xMl hz׶4~pS}TP?p~wؙmgC -z4R_R >-TJ*83́{EXcMɣg7v+3qH&InoO::yXUݗ:pY389\j5꘦OaH J`rz(K6=ޣp&qWG~0?C`؁g\|)kGܡ\9u'),g0epx8M?q޳ז[`~zzz̕W >X9}WڰmGl/utp{XG}$y`~ZJiul(mPS3cv58p&8OҞS]{ݳGNY^KKS[~s7+`~ԡ;>+T-HX/guhy&ߪ0)1-f,5(9[ׅ>5%Vrl_&~;'9}/oUQ{Yn֏k9<ԬWox}QlUVq8북#,1ːƸ]cHf&]Y]Sg~cwmUYEI7uoqV1~,˅2v^iko yj ėeSU26Ų?vrcwj:.1I"Kn ?DTKU)2f_MM'Ɣ=J٣^dh/ a3 `Wp~Oה $Ssjcc6Vo{ǕqkeŽ]. eNJeۤyu]ͱ?W?v(w=쭲m#{eA{ O|VV(r\|,f΂7}nƄPj#~8~BCS62<⃈>][oxs/Ϧ/ҧ(Uk\3a?i^]hW?vDUBŖ1j[~{J՗e[[FQiT4rqs4 ctF}Zy^ؑoQW<~ߐ}a<:PXvϭn-n0?vER+Ttjwlφu_1jg,cݯY,?kAǏRc;ҺȆ+c{K}wYqn:hXG gϞ=7a~N>zk.SM[ZCuU!$d2Q7h]t/'e9+ g!' ,}'|c3ULgtS[j q{蟰-o{EQ%]S{պɻhd@ɲe2Ύ>7U-mdUl$_}IMdm눽M/5ɩ`;cy|v= E>y;A2lφ6N?:sTYUx/[yqz8QIM6v1vklu>$e]Lc|b&I]lـ-`~{|LJyI^fKe͚ڷVz=Q̹OvJx4.k9n%zQ=(HD͒W>z8JQ]]|E|I|I\+WtԴ o^[-WQ ,0_31XI7,M 0ZI7NE(C<.#JLֹ͆Q-u~dFuA?Z'_FԫMol{žX.swjl=|㔉},SCā}˻wouذyGm9<7_7'o 1k@=V|Kb=w:/`0_6G%>`-6sSW<#,]\=P=F=RBp$S5h_I &0?0?`=wmi?Q;د,'hu RcRwW(܉?='}^UЧuB g-wZQ_enyP&uE|ȧG-0ųa"F_`lBaN&]#$?$Q~@r?yO|nkQm9&]hh2RuMwFQWԿ_H]cE'2^xb,=I7Ifǂ(v|h1cEE|uh5oԌZұ:lvLW۟x(TSfKe Vojؤu,7pn`x2BhA"Tɣx6lAp+Ap'Kǟ=;]]GQTgJ9ٗ]wu%/ +7ni/j|&Ǜ~Nf9߬.ٛS1XÆ &ոq#p3 a~Y~TRS.ي96Hmԍo~2`PqDbI|f̈́S5)Pd,2nɋbY¦ k}6Ivbßv+Jm{hC2Ky_k<3,r[covMWgQVR'՟\wZnzr酊YS^6f+a->bO |wOͤbQg[{~!nqٺ6ϴ:7&D\^`~g v 0?@0?@0?@0?@0?@0?@0?@0?@0?@0?@0?@@LƪyAیY7.߫pZo-jNh^=sy9' @à2x~05mL}_} 21#k'Q3fS?p</# [׼{~x$L38iWnUK1`~Pɀe%R;f3K;}4!ӑ+R/^/7:i="C_:gvJ}$~a~~C_U3{CVRC8+۔phVLu\Ԓm;>6`_0?NbDZ=9| zi[+b.X]mޡ_7_E]0?<VYn g༨iQN7j)C81: `~Xi\;|x;92\\ Y0/7sm3u>v&0m|f5<@eM[lUV[SC]W?i׆}IK -Kث)ByGE` x`jyfU[k e*׶ۯ팢n8gJ9ٗ-N\%`fAM_̏øuvۓJ[ [IZ&eu .909S\gI0uTjPW-Տ^QWua~Zc i)6!$BU뻵-` 3qhaOy~&|altK "{;M7Q-p @ƪyAݓwؼB` CjS۵nV6 8 <˛{ I4s_,ӂqۇHUT[8,2ʏJW<[-uc~O s%cȧ!SiY(њcK[c;pST mY<^:jJhs@}T^`~\cgKi~%>Car~9H߼gw2.8׎ Na~\Eƙ ΈӷfJY 8OmaZMmj7=WM63WkY]mmK-qjxeօZ5G4 ʢdž_#7WISv~4܆Tg]k똉Api++k.?+TsAsK W;lөuU×Ϡ~~`0?.ma½n~ 6UO6g24r|HnrLm+_QEFN~@V]sӟS$c 8bqnbKMEt8lS=R 5K[4c{H%+!N8 ,fw}nneѳN-G}l0?.O?)`c[~#$Bg֎ ׋:'DhIɍzSA} RcRw>}[5՛Ԩ{[iLy&u<:I&ƥpuGi۸u{ED~ᗹji5ǦռQ3]xs3=w3uspQ/ߛ+B֋%W-I^ccJҨ?W?.rڝ}>Z[ty }JJ]%J70$qh"i2tԓgGA'ts{&p2QN]DC4(oysِ!2x%kü{+hXwpm>g_76`a~ACB"}u},IS,~/6tŝl,d<_՝~ȫTo[yY-&ps$m%[]e2g>sXrWpBܫޑTQ8 68sʁk[n4N0?Nhأ,oS8n,Jqk=+[ tOޠpTZ^Zyr~#Ϲj/^&fUf$LO~.:řa~JG#>pBK]L&2us8ry` q~啹 Tw7LWR䭡nq6"wZRW8lyrCYa~AfA2T0?E#t2QG8n$^}sRp*|gs' tyTo nځ<6v}S\̧rs->oMCkiMf%7_#1^X&)`7l:O~1e7Z7ܠK.όAe\(6Q8@z]65;=xNy^oK]pS :,m[Zo}}Cq5lx?GImS o D˰Q?WIu6VP8Ab7!'~E7 [u ji۵ N-r'V*rdS:,j;m#ۮF 9 ,X.h^UoUsНLc'~EsBӊ6E/Se+`[*gHZw±a~FR*~H[IWm㞓>/6zH}tAe68͇6Khd6[gi3B]0?`##r;4Cui[m;CRz pflu0X/O]0?`#6K+P)򔟳ARnoPNƇy;|ֈ±a~ꮚ䝔v}n gN|wY8C6[++̓çO .嬕+)^?bQ-r*tvCMu3ڱp uc-;z%uɔX}M7|lz0M6ʩ[4{QW86XWXf!-R{|rgޝ;)5J~nqle V?' 7GVhWbٌ/6NN?'svyD٭~?V&䋻~O]QF{3_mf?s9u#1h+ԪVo/ A0?`E勪ݛI]ԋ31Զm͒? n g+҅~4xt8\@Mvr!-N^]k}u}pz+241ƎPWr+hHj%gV}YY3Ϸvfͱ<&|nyE V>@m'uˣݐDB+()R'' F4P?YO;~ 60?`u﷌n6ѹ͑(PWSU&(w8F5IEKXc0Oqqn-a~{ĉc_v׬nyznW=xXW/ޛhԔ6~[Rw.H)F5褚fx65)E4rY+#6֗B NK ឯ t _1,NZ&%E]8Anjvo[/ -0?Mn}&9^n_}?7sso֊mtWPH ٺg6gz2nS' dN?}!i7Z@z]61,oO7w<1Q (YVlOc_UekEp, buRM2;jnݢ~-BCBSjQ`~/MK{uյOgo=p-S/gT]}jAUE4ieXO"w=I@wsw{OM|=zm,mgHe*kDؤyvwZ.?̏U~ͧwg#J[nkv]6 H U p@_Qޘن7M150n gzb_w"U6n >Bԃ2~e';zpCCC]t?q&f(Sy}>mFa~Uw?=!yQ~H18) 9<G. g\(:! eSHTn|?>{}a~ڹǒyڍfZ&F]ueawbuzSk"p`ys,0;+F ʷŸBܨm#6&ěᓊ$Wnp/љr^9/'׻ߙw'N)u83?(+U`eOJ*..k6D%Nͼp!5&uu8'_2 }d?9r2ũ҂Rʽr%lܒ̩Y+~YU9b ҸY rvKnݹ]:lDž'a]Q %"l%̊ROÇI8YqRJsعm,oqS[r5. u؂KO9_| wEGPW-8Ez-*[pS]/Hm!$-tsC6'ͼ›{D` N>?wju]+AqdWs&0:G'ePWNsY~'Qu9FQ] nSYɤ`]N;?+6Vr{UQWu9HVKu< uV rǥkP'mΏlll5u< z=uX YenodeO]GF S+|~dzޓݠcjb#H][1 x8fweRWu9}orӱaWkX'Q<"-';cI4s_gBO uXKO)YBoG>KcAmO]gq/p +\n~,Vy4-x\Ԩ 8ɺg.S)[*N' 31֭=oONv*2)q ;Hp1]6п1-`-?BHtM)JRdc?s%Ιc_i҉xƻsy .>g2=s~TB*  M] тDv'xaGttsSua~QiT%rkI׿!d2~:2ųa-r->9 ǁEfYTKq]q]55cjT5kjT{kNi7u]RMo{j}SC7ZB's-.O!#9%~I&(y}mg?j/{7KyoVt&""4^ !|<ߵF6w7;E ˿Py2$aiNz@iLDDTn -g˰ -Hg #ɶMWt*W{h9F aU6 7MҙXPydptj8/;dmDDD¡q{4V:K5K %nODT};tsFH = DDDB%t3Ԓ޸5_'J8K֎ҙhX+tZ)0ԼisDDDavz x0J:K[2zd rnϟ;/L4otɿjd @ ?Le^p牊ڥ3ЄC} 7{,Dt`X`8(_Բ-P 3K`5;HΕDTi΂n'`؝w6 A}CBUC?zf6p:СbojnG;N: Qcc07{eҙJIa _UWϷzhr_ T?Mj@)ߕ{ Rm5# 3*,@G7SB4cs6F:ZՆUBp]lL4*>jP(.t}YpUܭ@Jg}>71@JgcB4#Q:T /ok_-% #'|=d( X͈[2lKg!sDo~H6Zh$3Ė$ QQ2Ns&3j9`2]!}X EXǟ#^kS5pZ\wtjo }פg PY5]>rHt v|8[Hg~,TBC7 kzs(|R];Smq`|1>ugԲC)12s38j,TzeN Y 1S_/h|]}BrtF/9N: _;WHg^,TB~w#D7Eyh6`mkbΠtB%t92 /PP<U6+*' cOR}XQϐBV8eHg!9M|՝6>eeqvW{گUvB =inrxtB% JgV&`xYՉ s-zP -!lx;NBVCYxc}w@+P8;w R(tqeF21HaY(߹ Kg ?BݸQ: UNSr1`%{(EN#=)45%-@祳{TBZʬt:L8!I%0~PYr/ogIgqW'.}pD:KxP ?_[`cR *Ӹa,t83 7Qr:'!XTؒJg[ B(c2S:KP3M\9bF7 P{$jGppKg *UC[&ےA;tF/ٵPGkptaRuަ& Ty3jE9xYv^zg#n2JձP sF?WTv1,BU9t3(% F3wBёKJg*U~qtg4sC2rIg-ϋXTMjȭ x0J: E"So4 X=.*qyL g@2;[5+lK$aJr?s(ʜ;Q M@ݣIgBY?o;˾o?OsFW8iPW[Ջś@׌ k@nF,Od$\BW86ܭYIx op,3WHgBfp(Vs#Tҁ۷2ө)ܣF:M56N 驔t 6ĥKZ( }2($P^{t ܠt9,Tj6~~ a6x1U'.A ;y !t!!r{FKg! F:_`tZוFKz>(hL:*5+vEH[-!L-6E: JͲ58`,?"/(xt0ND $g4oB/AB.1tR3KgB%rWvIgQZGr0;3= DfϮ[(A ȱz*vt*B] )ƽxJ 3cY/t*eoKg\>~ tj,XDV|ey'P\) D:!Ԭe'$*2 g9F$ NoXtRkH:CxP/ڻ3Ptƾ_:wm;R_ɿOn'%#[!TQf0'%#+%Xğu>OS:tsƤ3@)Ð^,TeO3oP: MPYMM;,DMXT#*T! j:"3sujġ^zYƴ-TaNY6/@}AJma ),Jny PeDTEG]G[&niCBt}=l2/.j{THL8g#EƷaW3QPp jt" m> hdZ Jz!|DeX4-(}0M{u3QeV%jet& *$Em.g=,DՉ )wA d+%,= .P^n0\Zx}ju?2T$wr TQ}s-A家\*z-m9S:QuaBE '3SaGJ"1{} sRH?udrBTXPӧJG('È$oC*P)WJaNJg DՁ ttr2x\:@UEZˀD4*TZ&]6n$檔g%?7D'e"My@nL=;tr(@6qKPK8o1)p샋*ocPxsORaIy9o_ ː[}>1]: Q8WU™.u뀉 xaoz*h-Wd8DtX,Th T1*W{{n[nذaÆ 3JR ;^m$::*4C3TB6;00*yW^y]wu]~駟~D2}*&jWoXdbB3w ?Нwywu}>O|~:J=df8cccc \U6\Г… MWM3# /JM;s]u]`ڵk׮^MQAtM7t _~_\A~iTtpNTJɴ;/THWWWWWԯcǎ;vL'J:r׿g?~~o'~mvm3y ;7.h/qQir 0Wej͛7o޼_}ϟ# = N}ȫnoWя~عsΝ;gqJپj?<((X4#3HP&}%\r%GRS}<0:kW9899/ٳgϞ=GJahƍ7nY*ụ3 3= ER:9->^x^8nnXf͚5ktBN_4Ms&[[eMoyqa9ԆjWvU1>DGMPH*}LW&[5yys56o޼yfs9s . .8} C2>PU0vBlڴiӦMm۶mvڵk0{ٳ6ںڣVm}sBhl}_Fw?+%L 65-]LiWR۶ hײe뮻..&x^믿/}K_QVd2}ZLS:[ Dá"wIW(|O@a.Kz{vr]z饗^zd˗/_|b27x7_/͛(q4{0)أBSz3WRuus@<>+&J^^ ȶ,jl,jɺ@Qmmi]X: Ч)Զ)3VxɿV ^ *~ ·YmL* L |{mI9%/PbBG`,* zߓJ+Pw@:_l`hQ* d+̌^Y3)XQ^MY(< / ;-/H`7*ɴDD<>%H :Om)Y}tdPO֌B'ywr2E "㷉3E I5,Th3?.(rǸ" MܴC:QԹͣU̝hXt DB,?VOJ'!F-X4)tߕ{ ,뤈`BӤQ!.@T,Thts *4MjtVIg r4)[X&z~ww?OʥP ^eIJ`v&y 6_4$SsyQ`b}B]-0?g#_,WR~}}~(ŶОUm._-85ߧz7XM=*R3o0 Nw7'f{DJ@X4 s%o xu^ nWuN NZ3W*w)qwԔDnQRvhY O.u+P^n}9dކ݋+o:۽oFWv,G8uzo(DSBN%44߽r%8[\׺"r6NJX=kwGb> [@N8bhY4܇2?]Zvx3w.ĶsnQ-U9I@vZp/yx w9%{# vI6H%{gZU.{sV^o ^I) n {zʷ'-80үd;njwH(WPjt}T锝:xGRkے7uJ͏8\R0|y+b 5LXK s?صK0g7YC?iF'C=E]oeS9Kg)I{tU: Qm`B7LΥ"{UZr1{ :hh=v|.P9E 4oV ¥SLP=R% sy?nt=5>$m*q ԝ=g/7(6PH  JPZ7?Hjρxɐxa ͸34[MpbBQ gK~OVU( 5yۀ}b*Crg2WPD攷 j Tg *Ew];U Q+pS ur :sO>)`oHDT}T(2?X=ulSɫJ0]xq3s@Oó۳z0zb"bnr|/Xz5ڏ=_Dt(P$W;] D 6b.ɭЌ#(QY3 =2/* {73i8G"%0o>ϗNs(3y%h翸g!ZDD4S,T(RQgkI8x5%@U@aDT;XP OU)֩[բKUF:]:U3*)* 7].ll^!PHq-2uPsUF~PhPPP@)IaSo.Ņ3Z`;DTXP$1k0=/rj.nArz)Y.vOtI jB" a^} da]ҍ};t "f,T(:K:W_eN0Ftk^0Ԧmh&"פS5_FV ݘjdݹaP^svUΑN391Uru}yt "F,Tezi&lSJ:[s(oO0RMDU դ 9 x+sCx!?S+2jT)5*ݘCW9˽A< $v\Z:4|W7:r\I7jBG?6NCDՄ զӼ?+CLQx`鮧}]ҭ:W:U*TEz5A o3ct]ph‹ $u9S={s 9ct{s=5)P,T'I+A]p)^/s1[uv6F^(XPmQ4fFY#f;3.HH?( )֑&,;;LߐKOBs&L.î0nLGDBjggst"/ɺۋK0Vk՛4;-&bB3> @Cө[u;[s\gZ|SJ!jBj>3 Z6D[sXm~X" )jKp?)}Y?7߯;cbzNADՄ F_)Cn}^?SSQ5aB5E6S/xNWˊ  Jx,T(7!LkNKq &_݉KSQ5aB5EEW:co0omc"NvP'ݪGm4WP)3g qI뮆khn&jY "ʠJI:$#:?_yi L4DT "𫑢$B {ee)*?]rX 0Yaa4nVK jBjJ on伕rNADՀ զzESX]*nǩwP%aB5IDN19cj1_\ni/ U  MK6%brj0ʹewK*ʣ};;]'Œ $u>ONq\_5'ҭ=:oDf,T6݂TtC>^.ڣ\[NDTXPMRB*COp-ҭ:b DF,T6y[qt>C59 ?l<ǼNADaBjN)^~.n r?ۘt " #*T-P\~-nNN |2P~N:  IO:šORAzt+g~t " *T3M!0a y6nn>_: Ijup:_:š١]_3v[9sjUα!aB5)x2hNq(5l:q9v$ʙ zU)D&,T&MX̑N1AE?Xe,0m|Wӧ[: I>7I`\c/>b,nL(""*TeH3+EJz;} ֦9CD/BjӨBոl>]:3#i}ܬ3BJP!*#DM ]vT}zLҭ:md": *DeOv֦O4Q)(XPmN1||OqtN=F&>`hN Iz)\+Y qt " 3*Tսs_rnsߔ*g݈NADaBjS\7+U/ sS6N]E~+jjD_`蒻s6 $4; !ׂe$t'c.׊Q!#`BW.|@ݢߨz*{6rW0;>vy;h#cB5xrS=iآs/ ڧU`QWY vjӺwJ!jBjҾxr3^o1! zкv{Z $8eqȇ 4}rS?^) ߘn<>%vvc<$q7fɳD4,Ty+b4'K%y}ŀTC[g ijrORY/ɓݕuj%dٱҭ'ZBjUFـJԷ>I-F`ĥ[\)3}@o0Ʀ2g^O9tPHЮ)cio\c|J3Kb-{PI+_DTKXP$h*2ecgtVNZjS O%w$ΐn%"* j]x8vVjzQ²c8F NDTXP$2\7e,R nYx4t3?bܓDDՏ E^J]ҭ:DSxqȦXj}D}Z(2X|ISiK)bVtPhP^\ԟN,SSnʼnb'Ar@U>DT^,T(TzCPleKn@][ggڛҭ (`BѰGQA.gܙNQE?]ܑ|=?5K7 ERV+ݦ♿IbgMY6H'(`BM#Kχy tJhݩ`^K'(`B0>Q,sntcJ< Njޯ:SQPHQO'y3/hͱBt`ا$w[թ^0cFN"&B~fρZ9Fk|a򇩳տ˒bXPfTX7/ӗPbwltSXPܩ?i /zJ4SvD= PVy>>tJ"*-zt6hnL3•_~ ̟%.ӡ_7SQPHQ'MI~D:uñ_w tD%,T(Rԃ*;ǍeSg$jD>U@A*#-U @c*N6U:̯oߘFID,T(ZWkɿ2)ZVoǏ+u `jo65gB"Eu}|طZ~^Z:]>6[S:Q%8I sq`:KN_1[˩`tJ |#h԰԰t"" """ -:QhP!""bBDDDBB  """ -*DDDZ,T(XQhP!""bBDDDBB  """ ̖*IENDB`elyxer-1.2.5/forks/jras-elyxer/test/subdir/laurindas-anger.png0000644000175000017500000005356012117061342023765 0ustar chennochennoPNG  IHDR[,ƽbKGD X pHYsdd vpAg[3=VIDATxwxe53d2B*TE .Vl(k]um]VײX J^BL1<_I<3w]{e C䮪> """DDDD¢BDDDŢBDDDŢBDDDŢBDDDŢBDDDŢBDDDŢBDDDŢBDDDŢBDDDŢBDDDŢBDDDŢBDDDŢBDDDŢBDDDŢBDDDŢBDDDŢBDDDŢBDDDŢBDDDŢBDDDŢBDDDŢBDDDŢBDDDŢBDDDŢBDDDŢBDDDŢBDDDŢBDDDŢBDDDŢBDDDz.!h ƄPAKHXTdjsշm_8J]?p=+[ni[Q-0LW6cMh@sioh@7T4P?b\T h @sJsN2U @1]x:^_ `li4Ӑ:I֧ph| VKfS4nP5A}oޯ J(BB!7|N 3I@1W)'1P{t>s2MҫNɵ[~e_-p]N.FepUe4kuoR/} k[e@m|@>s9i< ^fI$ON*:×OdLJMc-avudM2~R fwбsò-ـ{Wc֮mc ༰WuZ]dd<諓s7ƛ/L_f1P!y!350]>;ش иzwֹa`Tfڧ-umaMZ4  #LӠ92D,*QTkهm;=0̵NʞXZ5$.*=|J`))H5ZK?hl]4b4GW+KұI{\4N _#UHo6E$7u@w,pNuщe7t/="mIܓ!}S9_[?zh6?+26dѤgG],*|6 (g9A$'o&%]RF>({*QaQߑ~W4~8 ;-)ɢSEw43XPQ^k`?_8($:Qdرh>exi':fV-~&;P} A ~P9 w| [NCDx^u'?/FoZx)GTn{Q#: EC벁]>wuUE"8T\*={ʌ;qZTDE%ι6|cDԗ,e-#wwpRѩJ gDf*^x3]"TDǢ炯*@"PIGa@Oݿhns.}Mt*08)4{r;0Ŝ]'}P=bѩ(ޱ9ݎD SHeG쩛>~]t*W,*qΤβ NAD)dh2'j֖-_XT\ܼNjNADrZtœi s f[&^h4:h4CmZ^ojVk4*JkRZmt` >xGCC ;SZa+Pь07(:*]c~7>}Ltht: 0>!!+ 0o_mff rK訯_;s ~[t=涛üE +X_ح^|BO&NuCbb^0`QG=p}r' hogi?\.}n"OY4`M|B@VC~ڇ_ i}Aoi?ρ $%`ҤgA!R5sKSw_xpIISF3j[Dt8z^ξRuNw;U^̘wE՚3nPZ:efsJJiT4wͰ,B \B(%zϑRaF`ǖ7oT#~RSt:)5O%- n X22  S!_z hmYZtsRK8SqK'e7W3`۹遏u=ykڗ@leKtJN/eA!,I~pMM[N}MWO@w=pA tY;QQJ h\9Ȭl(JQY,Ç(:My[kO?6|\3x2m4mp, Nw׼E"LkHixGoMT423û$o ;;#,KB92j4@ Dxϗ YYD5rr'oN=D}<]XT"oh7h XiDZ\zhH#/6IIᢓۏ߯_x1kPJZsrƍT*&cKҵΓmE%JR ʜgkҧN#^M#B&/b}͊T(srΩh=\z텅Ү.4Ҷx1;֬ѣ刖PIGaۖD)x,V&9-@/9ȟ);ڀׯ_budEF)7RAde Maax͖t.ɅcJC{e_l'$s؛gsd`T*Zd Ɵ{w}] 777778;0 /////>3bedj `>Ff#.)=b6 FyLFG]ʊ^~2YEKR;j,oyW( %wlݺu֭Yf͚#(̙3gΜ TUUUUU|<%"p@/)҈grrA<9@]{UW*>:p4nO쮓?_ / =vr\y͛'TT6$B-8˹in,MN.(4Ic>[l_r n޳SA±kf @'Yt ~ 4U[lٲeSҔ4 w))-JEya92ËcSveD!>&=`i郢Q($fDemjZ3%2 r#톑K e˖-[fKR4Ht DQڹ ̐!Cّƍ7np\p"OISbnѤmi>{] __:ꨣ.\p$[攔;u3~(Q}ESyFt>%3wsV|̙3g`ĉ'NnnX|+&bk̈́t iG:V,Yd{{zq|Q^x^lڴiӦ םt(nU9+:EQĺXKN,(`I($jJNLNNNNN?@i$sQq΋kk#qn믿v]>?Zn߳>(kePӆr !3ŢS>/*!nJ|Dtj_KKâE-ZD_uOFVP( 9{"H/ѾO*(jvHz{6nܸqc뛑FHWz24h|߿UtǢQ9b*]TLz{'ƞ;uY]b5&vP?i:ut8 =_iu^^.@:e&S =+l}M9o<-?CtŢǼ5@ZH( .,5Ѻ Hy㺯o~֑[E2;*hkkHW7DP{$EW'D{ 3Wl{v;>Mk!ŵ$Z'sgq8?%:[Bq\y}v{k+Y\45<8M95EG](ص)E%ʂjwxV{NC`" ;nU۔=#?tS$eX)E%ʜIul)1n@8o ;"AZ" h ];'Jkm~Gt =i><GZb%<=>_0˖UVVWnw /FT(9e)eS(JuͣEȑ}!zW 4447][_l ?[JOʀztpv`,*Q uK}%:TjNД~b ǎ`0<һ".:74tŋw,+*+U%=RAsj][EP.([:Oc4t"nmÊյ'|"Gw46\Qz畺G*z\"''%S(J85B94l7lZX]Mv\]p8Νv{xퟓ gSQ^Iikko(/Ք#CDP.(qVn[ʡ'$dgN H޽uu VssKK?ʕᑔji YvKE > B!J^~a4&%NI -tB%)+kmmmzwܺu 2JHϓFXTE%J<5U":r$$ (:E4HSHK_H/`Od֬ٞrû**9#rEjm偄5S(Jnw{;:W<,:iFcr2`2%%':M_4 |Rޞ*VYYStNDln nmʤB%^cb"MX:cQ0[Z׋N!_:ɔX99)D;vr:G4 :R~|ҢjiHz?Œ`J)E%TwbLhVRrqᥡ H#(vu:b#-F{ 42}%H)86N<,*|78>mBh  %piooiiiQr#M UUK}EHWUYw/y E%4ٹRt zO|ۼ9foI#*.! 47GB#+i['; ^yLۓ#$`h9ږǪDIQ=`|?}pqkkҶg>|^tnVεhs~l¹񄋏aSd,*ݡzJ6ByXT"ĶeOnirKHHO2Dt͛#siawy*HW|>8u# nRt~z)naKN#?FŒDI:/ev/|$.4bArxѹtGm$.ݾgcO-!ƢEb7-@ݢSɟ^o6NArX#RYgXTiꯪC uPg6v'_^Oml%uFc0XSPwElo3GcfeͨT~ڤFyXT v@c7r+Yt*ju^Ҩ8ZZ-"{GT))Cܼm4a -Vt bQُ_4]7VuNw;,BR`39N6nB`0W[(:r%dkL}wOSk4r4kUDjo߰At 1{@t i} ޴^:fVN;@4bJڎBP(_~FA-s[G$Ѻ/%V -XhMh^.TYjWXxGCæM]EudMn"lqʍ(m^(:Tjh4N~lv{U myϏB⦨~x@ų\|?tS>Bt B51Qt;> ׯ_/:$?|)/nJ]{_g6ٹRtt-:Ԑ!ii))J%) ZSj >4 "Mq;=Ct16ilmN::lvF~MKKM0»L&Vb |zzڳ4AKzz4E7}'+^siO0,7mzj\ ''!,pQ*p:m]DQC.c;ovʪz hnvw'trl69\t:VքXfHOrs32Դ4 ''###HOOIʮ`8iѭ6|7ώ--v;PQ>&O͵XxeٞK]߅  >䣏:GFbͻv@Vbׯ6t@`~,6ii )sJtv٢"Z=hN|":IEm٣GNup~ <o@KK[[kTp8#IRX @AAvvNNx$0#_":Il٢"r܋mz@hA(?tT$**Z9E(77/p=Gtkhٚ;߮Zq㟽`j4JJ C 06,vҤQƌ,>5NgKS(#G*:rRmбz_FFS>MNg2tpnڵ9`]08c=η"b;-]oQ.wDVNWxeKKew߉u'vؘ1O~wZm'};+*ˁG7綾)S.{y&S^#\PDQ|á{XP-n17#8`"`.ϙ54ih--~ޮ NuӧqĄ |wNMH_}u>.x^zQtʾr?y0tqST$G+:slŵJsSL {<44RV&:r%N.L%:E싻4 @%TqY%nӦ_s^z3gˬY_,: 4U;~xKE/`0Tڪ@mo<荺rV>"~mQoONAr{J+5לwssNChlw>Of~755{Nwp.WkkEeX9y\)G]J*$)`6o~ms:c'nK.f>㌳"eݺ͛7mN;m9s7XH о;}30kSLu,o {%׿/ȭΞ}ϘqPHw#=y/\whjڲEt n] h4;[TR 0!:u_^}5>%]q_}50k'}bҥ?zM7= ~xDe.ώfd^Pz'n FCPwTV~=P_uN{k-DEuz֬[offkmq.(` ~V0?t'n=wB;_t>v( }<(:#>wEcm`SdiH2Vxu:D=hn+mJrEr֚5k—|!QH]?c'&_Nt io*WӋ xTE.;3}@h4ѩ^/#+ͻwG{4ޤb)Ogqۛ?D>tp9E# DpѩzӦM>x{~d2Fѩ`<7Iw8--w~TGOJr[mD Q4 yX ʯ@NC,$E)Sƌ;xGy1 991j$REoE?أ*S]hd)*xھ/xJv1g'A kvzH9 :m9h?S@nnfffT?jՓUD?أ}p XߋN[ -6SMh tڔ.CZ2ҎIE%%;O? ԯ_~Sv{}i 2hbn喬Sį)*ɛDI|$ct@VCӭ2k%"я粲; 1L0qT^M9Z& /Kx&S?ݑXq+nsޟ7.DI:zG#l 3=Tǩ~T=g6&wy}ۜY J_/S 1OKRץ\vXf+:E"<6kˡP_S5k5$1)17*WEž}D:8o[%$LfsOf֔_iN4̷)}ܜ4)WaN {U): 5 Pk#f'e^ӢmIS?O99S>5!bho[^ErM01_T\woD1ɹ`i ~z7y,;̛E?2R`Ѣ~y`̘aÆ93r#MY,fsFTҶ>V SbڛtG{L|)WnDїgϤ1juBƉ9WE? = f<+lPE{o~P+l|b;|D!`^) R>UH:/8/'Yjb״iq/˅^|qX5Qgzxd7?'*ШN\hCMz4EERj 9kȰ(Z:*F %տDg\Dz5{of|i:V|bO0k_:7fϸ6]$"I;i5=SU( AC:d_k~XW&-Ŕ5) 9sׁ?SNzNLvGjkV;_[ڝ@j^j^j^}`ennFFf&p}\suҥEvwHAysonFZFNE=%ڒD II!xLt +AMt 9Ӹ^Zwd_y2ey eg0u[@sJKKO+,c.gom%lͻJ:3zҶd]aqQ̆1;WNEqfKJ?\QR.@0"Vz'x4ph3½\K= !yY,dz\ͼ&/7|,_V Z1ضw{嶽@ˁ{bC0p9.Nyg;ܴ~V!IT}Dk;l*>g[)oBisɛ2:;fPMQvJ0gkjLgww;;ꁊJGE5а!ذh屖++W+9!iFJǕX%MO{Q#:􉵙&`{siHw#*R󔁀 (:Ew] !'Yg] on/D `DɈ%Q`ʾ5CndD+?qF j5>ivY(Z;6^*FD]`)Bt _QMG'Ft4_~ky-| SNA:5tؗl"RˎjDFcڰ3Db~%6SMhi(RmO%:QP5 ON\X -SXTQ*H}zu3yCkfVe":hLKl4~%%Yt~Hq=~J2lz+{U ]:iHtSҹSXTIf 卡'4)D/:ɑ+ӿER2Ϻ0_UߋNCv7o*_,:QtMmEM^)@XT`L ,~0i<5*NAefC(BK[բSЁDwN:Bt -Oml<)HAKz!A$e |0@s~-i<5+NA]ך2)G_0-eE TAިJ6LZt)=T^-: QtMES(ٲ=mt ,*]d [ޤD$'*6EƜ SUzcnFt "ڐlNA¢ED& /~cD펽6)HNnȨgvoYV, 'mHt :n2R.+Z/:*)HNT>E iuESD$hk\F)@XTX20]t )[NADrv%:J7i T urE yAT@֓ƓieErΚjv>;iNgEb-[N.6Ԗ$:J/T@isr`聢QW.oSt MS(Op{C&)@XT"@ >>gˆ WNDQS=ޏ۳NA¢!Z%eR Ё$W: A?ld4DotN<^=P}t ,*d?v )h Uɟyo@5)Ƅ^Kt ,lɮ':UGlI1LW@EǾpw֔O(:Nx.)SЁDXVNAGy` K=xi+uk9At QѬ<&_ϢXT"Q^ZHt ҏN
QiH 3*/"vxVԝ+:I8겗+i/:uFR2(Iq}U>Yb>¦'a4#*,m{R#[I4u@x ũP( vFP:D I;عKfi~}z24Yt::ԓgMV,:I_TB@it9B4DbIGw4mŢ.\o$NCufsynJR+w; ibicNqS`*?ܘc<#:VVׯ"+ݣb/N43DH1OΙ6$]t "ypRs:x(:Q NCbH),H,imNNK0 Ȏ⋊$dp1DR>OkJV4Dby[ {GGU_rD/[1STv5T4Zt)yp-x5SľD7qt RԨtZ Κ-: ~Z<(̝شM)bӾLꬒ9ЁNQ'}̡>8G`]!n"&_SĮSsERNCsEEY=t/aJ{kuNA$ޫ):E v[O~Ht:+*XJ Lt*n7E9 .)bOƒ f:O>@t:-*# e0Qt:ŘHtyibO [NBt ꪘ/*jVewCeTt 1:Mt "z-(:EvZJN#: uU^o zҚL!ᷜr ySOh*9j kW : O5ꓸFʍ[tء~J2l'29]tꮸ+*ic/`vSN%: >ŠH,ulT穪Uܕk_K8i<SPwmQdÓ@/Ȧ-\(ovD KRZ@7OLStR5kқ^u{PO}Qj/8Dýe9Y-:U {+=C |bDPdA"QZ(4#̀aR6|ѩj ,dNCŢmIly,@dުg]#\DHH.4^熾t⭀b-&: ڼTɏ< dxYt#h[(:W|E9+} 煍o`@1$$fw̽(oH٤K9Sn> }{q]Dv]5}mYPJ% *8}?-H*sT5~):QlѸ io>0[rRE? $ JT7ٳ(uG7@ݢSOᑔ̝" u~[݀;a 9mAp-BwLuf-`|(7#SZ;#_.cTD?JEEd*w=87֏TBDD Zӓb@3@t* wDcQLӪ Z  ?nۛuF{wSh,*2l}%@0mɾwГS=]s&l)H427(9G;Q@=NS;Ct3'dX*:Ƣ"s*$xB;D<ѹKf؃Ŗ3N3!ON{){l<~DD$ܞc:ݫw ׼Q@GfgCT'f.y?w.2&"Ƣ<&_@/l[r j9iy ֞!:zHuxi$qm âo@{eu?mv6}$8umipE?tGGoC-g^"" b\ۇjuwo?ι¶,>P1%ɟ$irѣXj Appendix Test

Appendix Test

Alex Fernández (elyxer@gmail.com)

Part I. Of How Our Hero Came and Went

1 The Coming

Our hero came in. He was tired. He thought the world belonged to him.

1.1 The Meeting

Our hero met with Laurinda. She was smiling. But our hero was not amused. His whiskers were dripping wet, he was astonishingly thirsty, and the contradiction was killing him. “Give me some beer, woman!”, he ordered.

1.2 The Melting

Laurinda smiled again. “But Wenceslau, you don’t belong here.” What a stupid thing to say at that precise moment, our hero thought to himself. Only that it came out loud. At that precise moment he knew that the desired beer would not be forthcoming.
He turned to the bartender and tried to obtain a beer by the very old method of purchasing it. But being ignored was not one of Laurinda’s specialities.

2 The Going

It could not last. Laurinda’s hips were flapping, and she was hopping mad.

2.1 Our Hero’s Imagination

Our hero imagined her as a rabbit with long ears and a fine set of tusks. In a short time the image drifted to a walrus, and our hero could not help letting his sinister smile giving him away. Figure 2.1↓ shows a gross approximation of the rabbit-walrus.
figure rabbit-walrus.png
Figure 2.1 The rabbit-walrus.

2.2 Laurinda’s Anger

“Wasn’t it great”, said Laurinda. Actually she said it in the present tense, but our poor storytelling skills have changed that to a cheesy past. Don’t do this at home, kids. You want to be regarded for your authenticity, and misquoting isn’t going to help much.
Anyway, back to the story. Laurinda wanted to hit him in the head with a big ham that she kept just for occassions like this, and being a solid Hitchcock fan she was ready to cook the ham afterwards and serve the resulting stew to any policemen that might come by. She was also a huge Almodóvar fan, but she was unaware that in an early film the divine Pedro had copied the scene. Actually both directors had copied the idea from a short story by Roald Dahl, very much worth reading. Although it must be said that in this story it was a lamb leg, which hardly offers the consistency and stiffness necessary to kill a sturdy husband.
But who cares. Laurinda meanwhile had a funny appearance; if you want to see why please direct your eyes to figure 2.2↓.
figure laurindas-anger.png
Figure 2.2 Laurinda’s anger pictured in a mildly humorous tone.
And yet, how furious was really Laurinda, whom we may optionally refer to as Melinda from now on? Table 2.1↓ vainly attempts to quantify it.
Anger Time
1 2
Table 2.1 Laurinda’s anger as a function of time.
For the sake of Laurinda’s furiousness, here is figure 2.3↓ again.
figure laurindas-anger.png
Figure 2.3 Laurinda’s anger, again.
But how did Laurinda compute her anger? We cannot but speculate; here is a stupid suggestion in listing 2.1↓.
anger = time - 1
Algorithm 2.1 Laurinda computes her anger.
The result is in table 2.2↓, proving we were right all along. Also subtables a↓ and b↓ show anger and time, respectively.
Anger
1
(a) Only Anger.
Time
2
(b) Only Time.
Table 2.2 Laurinda’s anger quantified, divided in two.
Interested in that last table? Let us repeat it but without a label and with a table and a subtable a↓.
Censored
(a) The rabbit-walrus does an encore.
Anger Time
1 2
Table 2.3 One more time.

2.3 The Passing Away

Our hero was passing by the village. He had only stopped to say “Hi!” Again here our lousy skills have made us spoil the quote, but this time for the opposite reasons: everyone knows how to say “Hi!”, so we don’t need an actual quote. It is enough to report that the had stopped to say hi, even maybe qualifying it a bit to make do for the missing exclamation sign: he could have stopped to say a friendly hi. Getting all literary he could have stopped to say a longing hi, although this road leads to bizarreness. It could be cool though.
But anyway. Laurinda was so mad, so hopping mad that she called her friend, the Assassin. He was not in town at that precise moment, but that didn’t help our hero as he was just outside town killing people in a small barn. Just for practice.
Our hero left the village, but Laurinda cunningly annotated the MAC address of his laptop’s wifi card. The lack of networking knowledge on the part of our hero (who really couldn’t tell a SYN packet from an ACK) was to play an important part in the story — if he had known how to change the MAC address, which identified him with the precision of a surgeon’s scalpel, he would have been safe.
Let’s not even get into that last scalpel metaphor, shall we not? It leaks worse than the Titanic.

Part II. Of How Our Hero Went No More

3 The Killing

Our hero led a happy existence for a long time afterwards, randomly avoiding all points within connecting distance of a wifi network. It could not last.
Our hero went to the next village, found a friendly Moonrams cafe and connected to the net. Quickly the assassin (who knew the very people that run the internet, and who by this display of nerdiness no longer merits the starting capital letter) traced a bunch of IP packets coming from our hero’s MAC address. He deployed a team of murderous African bees, which as surely as a well-cared-for AK-47 reached our hero and killed him with three fast stings. Of course they died afterwards, being bees and all, so it was an astounding feat this training of wild African bees just for this one murder. Maybe the Assassin merits that capital letter after all.

3.1 The Passing Away

Our hero was undone. He was no more. He was, actually, an ex-hero. We shall narrate his wake soon.
  • But first a message from our kind sponsors. They want to present you the next section in this deeper inset.

    3.2 The Mourning

    Everyone cried in the ceremony. It was so sad that we need an image of this moment. You can find it in figure 3.1↓. Mental note: never pay the artist beforehand.
figure mourning.png
Figure 3.1 A crude approximation to our hero’s mourning.
And thusly everything happened.

4 The Mourning

We have already talked at length about the mourning, and under sponsorship no less, so no further details will be given here. Suffice to say that our hero was mourned. A lot.

A The Rebirth

Surprising everyone, our hero was about to make a comeback.

A.1 Coming Again

As it happened, our hero had never died; he had just faked his own death to find out his assassin. It was not difficult, what with the capital letter and all.

A.2 Two is Better than One

How to make another comeback? This is left as an exercise to the reader.

B Our Recommendation to Kids

Never trust killer bees. Or Assassins.

B.1 Killer Bees and Their Perils

A killer bee cannot be trained consistently, since it will die at the first sting. Better use killing wasps — or, even better, solve your differencies talking.
For the sake of your education, check figure B.1↓. It shows a bunch of killer bees, or something.
figure mourning.png
Figure B.1 A gathering of killer bees. Supposedly.

B.2 Assassins: Inherently Unreliable

Someone who kills people (even for business) is not someone you want to deal with. Watch “Fargo” by the Coen Brothers if you don’t believe me. And remember: a hero under the belt is a feather on the hat.
elyxer-1.2.5/forks/jras-elyxer/test/subdir/image-directory-good.html0000644000175000017500000000261312117061342025074 0ustar chennochenno Image Directory Test

Image Directory Test

1 Directory

Just images that have to be taken from another directory.
figure mourning.png
Figure 1.1 An image from another directory
Nothing else.
elyxer-1.2.5/forks/jras-elyxer/test/helloworld-good.html0000644000175000017500000000152512117061342022674 0ustar chennochenno Converted document
Hello world
elyxer-1.2.5/forks/jras-elyxer/test/branches-1-5-good.html0000644000175000017500000000230012117061342022576 0ustar chennochenno Document with branches

Document with branches

First some stupid text.
Now some intermediately stupid text.
In this second branch, reddish, we have to be more careful: it is active.
Finally some terminally stupid text.
elyxer-1.2.5/forks/jras-elyxer/test/elyxer.png0000644000175000017500000005353412117061342020732 0ustar chennochennoPNG  IHDRooUB#bKGD X pHYs229 vpAgoowV9IDATx]w|TU~d{)(bZQϺkòXbE*DC {$3Ii7Bј~prry# B!ߌC4DixC4D@C! h7DC44>@ 4CFo殚j.p[m!`#-w[6 G#ˑSVOY=e5S/YɲO_1b:VtXk̘1cƌRT*VRT*e׮]vZ >>>>>x~!,_8&N8qD *****5 D"?=z>P/h zǟz8r{ DDDDDDX,o{<>_9 '''''8q4h@ ;h9h9h˛H$HNNNNN;]@ ?qP!,4fo١١r6`N3]tw?`h4 `[d[d[=vxwzwzw78|#6oOxe#F#RQp<ȳ [}%ҾK.; iH ۰4͸7!MH7o2_|-5 aUªU}4D[l}PT폶?(JV%>4Zm0Lh4QQKW,] _2~%12' QӿԿԿgL3g}}7B!ҩ~`ۨ\g%hjpq }r"iy'9TZJ=  bW`H"zɀwCj 8N hmmmGrΟ?bO<1w.T*R)vwv(zg K E7n]E1by~E 37]r~9A<ǰ2qln a))рFCPV*e2@*E"@"6C!z~x|ƓNRdX}bzb ,d?^O^{wPH"NF#7iccccc#k= ;G… rlN}C ?xPPPQA* z8͙7xQ-ND9+k༅cǦ:Ւn&mNZ]]^/f\TyM*^Obr(~eY Dj5Nt\fl|?YW~7O?Vk2]|1\yr⧋c<\4h:Ne1^z1EOmjS/Ow逷"<<HJpESn2FZpP0~[_Os_/q$&hTDhJ v19Lln6].`Cyd2L|nV-M.彔G{>(,\.8w05 tΖΖΖ% MMM﹟Т|Q([;@S$ 71CpYcLM22 n^PxAD&Jn8@2LrT"22 *o( \@~8S_UXƘ흝Ν=;39 Jd `~\ V4O=3Qs)ç f=:YǛ^lTlH82 H&^>} 33>h tv+Wv{sG>SSCj5P_v>l6MMNպaQ_)xcJZZl^t[#GmjEGp86fnv:|}Gt`S0?!~bGS%U+pl_xL>` &~.]ƻ?~̯WeKg{ 8qĈ$p -- hdd2׬)/6mǪ*וfl4ছnxk/|+`xv.Uߨc|7.g\B`0tWNX6X ;]]CL dZ-o`]mm]]]=y36_ --}DD$%~;h_$"twx<Og'q4r\|n<dH&"q\ @IB"Yl$#ǿ$/^P=zqKҷ;˻gw|y@S>h(ٙLv_<103fL.wTRU(4_ fFFPddtu< 0O.^{wz=t4 rqI]ꀻz/ |H.W(z8D;?ؾyё,ZɞǣԤ$DPJS۩qԹ3n Xoo޼u~Q4`q)sUcg/ֿsW~7g\T;wǟ??^{#xuىwF#-55&F/gf۾/ r_N"!%ـf xmݚ_] |G c:$=E"XVGG[=3ǍKL/_b^a&z2Vr90|xvTj^OFx{{{ȫȫȫnGIO2fȺalwjÕ[wk5H2;-0(Hr@u2P2Y \z JNVNynyop; XgG 0%->>"&zqU^NFv`kkĤT>$-66666،c/frᇅ\QttB”)@cc]ݾ0$UT)S&NLI (d2\"bc'Lc"PrM5%SN:wXP-pco x'U @4eQeJ &sf_H$k5bLPxG~pҝ8 0kDi/YG? N, efqnwy/Q{H~+9ӑĶYc"`**ہHMMIXs%$IT=hW WTX,@[":(eggfFE;gNVZmDČyqqqwfQ^y JV "v; 7ƙyZtǀD8_y-L.rl@ŵt;pݚwzc5%+Cg LB) ~8WTcwVvLu=rJHIIJ2ȍB2۸q&pqk "oҩSw製{7nx믾zX@!JNȑ PN_X~a'8]J?~O&j[7/M@dwX.qwI䂬,@ ɔp;,X.W(tjklʥ_~AuW40D 2LFp8N'cV23s;1؇dXX~_~z=ߟݙq6f"'f2xG4||FTP 9r̘/F6o^7Rr?՗ir90nܘ1ĉӦx#Ph#vM5yd`هf^Wm-xի|תRQ5@`cQ@,VfF H*=ߟI4koJ4m{}!x-p> п[I$D"` sl""(fsfYWvh#bc)8Y*<7 *:?p8غ8ѣX.|Ѣ_ήzdbijF#dfNBȠ0`.70МCs+)<|AG6:W= BKu)obBjJby" _oB4[|9P^jx| X^P-pXˬltѠKXm|1LR d}=9#?4>;z.\_"#L/]y#G"fddddJ Y/nn7%CaaUFAS&%Q\h4:]r20v 7p\[ n޷rɳz`? ZTP8@;\@cb@TbNAL`z_-X?A7x Yhbw4WlCrYŢ8qD൵f̘'\!6**&f82j|%YA!WsΚ ڵgOCp *wggeÆeeLq}>d;uuWQTU55lTEԈ &&"Bt]Eonno~iF@"9|xV r1tz#5m_].eĆY29_p7wŀd dB׮>wtP*gl6Բ1\4q〒G z~[o4 x۽8p;csW\`Q<'dfϞ1#=wH{q،:cƜ9W]EBsCUU'R˅H.w:-h޹&54Pi 생<hn޹3?XS.m2PV$ X'7^`ܲ WeL ; O(y<tkoqDLWV Çj5ZHk|N#FDG-KQ r~⒒fs9w.)ij[wU*F *8Wd$Lmm--SAtՕ6[UUe%uW_ h4]]?Lr䏷5km˓:53C]7^ww2*DIӠ)ujT 2//ч,[ \pIYY=lWK/KC懛3/1b؛n⃡m\TT] 46ju[[E`2jjvj~oX+4ǻ9G)R0xi<s]]d zOitk߰f`N~" ewO΂LT8K.6-'5*=]V`׮~z]h޽{O' 'L&̤$`sY4ee  fͪU6))EE}DGH$~5ˁWIN+|uN`Ҫ$f_ 55.THu0n]wK]¦9oxf5[|Ë}Ad\3gȑTsEN~?57UU@kkssu5hZBTTC\C` #T_j|yÀq~?tV+Z_OŎbb\& !HHH8, 4-u_ x"w,)ٷԙ3P z C!Bpr% B4664t^(XMH2Z?ϋ~So2~S. 6~5bM* Θ1|8T֭۽ؿc8)V[^k1¤*11WUF?DDTՀTVSJE%2/"kQUUR83f<^z) щx@|>@|QQ&J\[qt<ZZ~x:%TǹyXdl Qpa>H`aennjjt40vlVV\1*GԴldM=|2ՉUd  (_$Zv:<srlMԻ^v Iq10lP] DEq\I x tMRJN'tΛ@ >u*l21q@^@gft{Z,|3+TWW]M~;:D"@h B#+> hKr{|~4OF#|X hL&SXL~_ ^4x/`O@lbL~::g897m6*z^/NK}/̚ */+FP;:SXQ('$"ѢEH$ Ç+w,t6"z/qd\ ЯJ$`@uuECNU*Zi@e35'=/ @uT`~ - CǿR)dgjPkQ_b}py$>J$--@]]y߿wwP5.DJ[ jH@BBrFtuuvrp #Gtuͭ@Uնm? XEEǓ}EϧR4PV\)Q?dQ(Jr@ssS46׻\a#G@aTj:oiid4ry|#-}O/[9H~S3eJQ w=S^U.#'(/C\"F *}ob_8@j%hDp晓&EEj5P^^Zjɩ.`TBA|񱱀˕8mphcLfvvzd{^qEXؗ|+zQ.F?>* ;6"89s/j`V Lt) ik=tO#}/.`\i"7^|Zɧ+7~|,ߣq\̀]+o6?]6dX (2܁%~? @tJu-lȝV'Pc'|f!㨜a[Wf#\~j"ӔHx7˻VMRrs) 3,Dt_IY-'n~f[5yH NAի1cƏٱ1"/h$ ۷gB|u`펈 u*8/ 2_McW}~_=p#Pfo>J.*)[q^dc,L1&Mf2sw^|q#1hā\.CkuY/z` Qhb!p8~?~XSdgtNGJ$M"/{/ua CCm֦O$d q|Tټ(s0' x'|@||sX  b1lt\DR. 8!qH72D՗Dٹ޲JecC@dΝ}gMI &$DF ^18 #)*DBvLG`xDױi<jZ,55N'b </3;""2B w3cIk55UUޟE G L0eJTR)=' cA+O^*!I$`~zmz|?`C !?i,UW$)+DLы({oD"X495"0a;:VX;edn ! ɯ l$ Q"@+BJr*Un.M0z=EL&J).ՒJr⸈~aPh`h)dvk}xm>D Y+J'1 :\g TTHH =c{Dck65Q~]g QгZ'fd:BA{.Y$Ih~p/':6եMvq wa~F$A p-vs;ę;@"!%:v{c흝@KKGGm-‰l\\(DQRYYIo6Pl~.l6 xų΀x'64#,fLwbV ËfBT8~^oC"(q:8x 0Y9do=l/{Pt9a緙Q?3ً*4=gv˂ `~`{>nks78$0&$,ʢ^v$$Ѣ7N4=/l}8tS 8z\mH'w87&Sx";U*:?QI=R&s80a+0"3C?o_FEX2TVQ", w?Pw1C~4&z򿣖dz=?bmKV<&J3ˇ #~d>HvV c{HNPPP(^zcư&e6=44X;(CojɪU_Ouwɖ&[#lǮ]˖GΘqq*dfW_iE$="HERv4:?xbNg6E,&0uߙw h4d,?*;䋆4>fdde8=30?.f"',f#Nhhx$ *sN0n~RU2|D\pƻFOV }gy? WP iiU*[$N#0&]/.N$ۛ~cbpbJMl ZZ] d^ :;$YR"6 hyp3 d{8Є3}od\N:ݯ+ eeNOnH26q@#1#BAl%̘##kX;U*|t:99. de~?V+dl쭻.!d1?';LFYDCUiH}i =Cޒ)n3ݤtwuD@fGc vj'defRC B.g~!'d%&"fD>T_ Ԕ}VKGS l^uqW."h8UϮ\^/M}CqqXR)f34/BY93GCw^B/!!1Q)"d^LE:;m62c~Ch8^nj"2wFC`,E0Cpl9^4.fŖYc-b<8,hto?'~'߉_] ^fb|?t`rsr9 `T%H30ٞkX\Nt:]9X&(L.I/ ^IѨP\tS';1VDZtM*b6}>hm¯㙒BYIZmb=`9@#n'`bi51CzzFZMaYn6|| 6*$ٰogllR~ E=ct8b w8f2cTo@xЙ&GR 'rJkx,wkR{?r1%Cf&~@v<|x.)Dkoh-pdnt`DN98wRHd2Q=T* k0Qz=Eh[hlcYuuѣC6#F4667^&QhXl2=ʧDdTEd8DB:r90i鑑ZM]e ee.<4$$l$IHj}>͍t&S\+1! ~4a(r9mTTmlVШ43+#& )|GtֈjC?p_?ގNg{;=Q2o9Z'&55k48wP6/Om=K$uͳz (*kJݤ9:jL6v,F(~=7SV h4JRy*;G]6e. .S"4>x8JSS0(+VG]ݔ)@\e p<8̉ @?\5jXرm6^jkkm%rD2,e 118qL 㩩!H- _v;c@j)bXn~8]%$ ̘3*?1(\S(F2$'bRШBfkJr.DBMaDwuɋy6)I$lJko{uOKZ(4\Px+{ҾT}ftyVžoDb@3Br@甌*:+Q֓EE^Vu-#eK3Y#V*К :PݴDHx҈%$$'+dJn7q.T #\lp@xH/utI$mmb~G0ҘcbJRILF#M& .FŮtf"FݽQ$'ވq7DdXզBARƒEAMMd%Zh,V.ܓHU*"QM _ɢ}7Vg.*>#I&n45@ E+K_[*o*IS"2ضqv;ppCC~>a; @zp` '&ΞVF#%9LvefssL xP*1c8`5"rI ef*SyL\8"s0$~aL'޿K1͓jm@$ ! 5777SDZH{@.'?*Y@lkki#,ML pIDD]p h>E\+)nyw]pB]"WS򙕊&ر$k {nu:~y~$&5 !spy'Fq(M*=c6}T *$rj5 eeUU6yy?gNGrz_2Dd -  j_5)թJ&#u|s\?ڀ7oہ#Gn>S]d6t:l8!R)P&"jqŊ'eT*{>Ѳ Sib"qt Yߙ̂%Zd2h ~pIc>K?b"bۻpj#sT6[m- x^9f;lf l(p@̟G]D!kh4ضFC)V+|8.vo֋^U>PT-z?G=VTT[i`> ̛,N'{_a/B`RKnjjt/P0d2xoÇɟÇk4q9 %L@,oITS(hUHDaU(XǷ.Jan3fώFw_l2^dI\py\`2.WW qj֪Tr9q:4*h H}RW (܍ ?"2v CrB!|d15: X.0PDQa~@99HEQ͋(L+Mܕz?PܵiǷx9S.K?\';\ 2Ɣpa /PNvs [>hU0. t C c|9PTT]}@ `QW*)l82;rnDW(! [tI̊H3l&鄡e rR r9֚J)41?~ Şln7In4D%L?;W'(?wr)Z`ϲwnz>p j1Ht ѐhLJ"-lP<[Afw(ݽR)W*ccI٦`&"=eqœ}/P>(BPg8ŕJ5f̘1aB@}ZRTVj5՛4E҄e(}{^"1Ng\PV6}ƍG3>;1;PZzE5hH):Z&ƌ9Lp8:;YKI'̚ɷ(bJw1111F&zܷ9JyV\΂[ P-ʻO#暟a~ِ lSwaZ KN={""i`?>3bcBX C {/t:Tc8iٰn8o)FS!E/ӕZ^.F$QJtGGOY|`,ׄƵ0A8U2Лi27Cn@bbj*KX(҄\*O!@%L&ZBȌ4YP6'A(*ڽ k&2Ht:Lm#hv;0\ ]O\.O6}_}c~UGG}}Wа{X,n7BIN8PcQ;Zy{3Ƹ.,oe43(ݭBQpxH4Jܽ+[fZ/Ō+u8B**l)+:{G)]*.PjAdd`aߖ^`'3FqIWWgg(DT>8;r㡬VI,l *ZőÞJ*e~G*=:;vz]. t>˯Ӱ&)Wn9y{'%"I}|1jnBqGVkmtv66:ɔA] ]{^Pޅy!z7c,bF|z MP(ϵy~5|tƏ8HcFV+"1x|9VNNkT|EJ].KRh JYّ#>*`҃' k?\ H HLEҔ f͚camޅ@]v IS xN߽X p]H(:mm]]K!MOӱDTh/4<"DOlP Tvq4 czd~5VTh4ˆR< ҴRm|8BAf5UIdE ow:֮K?,C uW_KYׁO.Z_?7йB17Qf646:@kg11ّLƊV+RTFG$_@_I^Ȫ]Tvô/V|Q/Ȅ417\^^S47S&yku}v፷8^?*5߫|:j?n[۵hC5@^ޘ1 =b t8YA1x5e0I&>pPQ 4Y3]v3[y04Fl`ؽ#o5ws}ֳ–y|EA~ ܔF`Aoy,5޽&6YII@ddj*MHXXf)+l;sc/+-'z߱ef7_= (|pu7RisQ;7rdD-E2SR(6P2D!ɬly/Zj45_Q$~2ɿI)gn>pY3yύ럾h@}|?xj=?^8 ²p@Oa'7bt׵KZrݹeŸNH/K?j܂OUʥ g6mŊ*U{܀lTzi( >>*dRRe2.H*JyaPZ )jk:ee$1u`ܡagk&d04{߰C^8}<;N潿Vc^x_crxq60KR j߻^DYu]V[UwG_qʺOD<6N+u׿[ /rl@?e7(|'XZtC? vYq8T/v"#5]r-'wzŹOTG=Xd]:ʶ|/z:کx>ٝX?~4|'꓃/l'U3ɳ%+_{_٦5*V>`ϙ9(_e\.'~Xsqg~{{&/w5z<qC NS-~;՛w z1dݳu߁B]2zg~ppS;v^ٴ~f䗯5D=Y,3ogj׭Oڜq׶j~J /ō-ۀq-0ه.gw^t祋Oh}QQyp34_f {5ryTY0fW*PcMuDixV"f]u?o뗀5dMqY@Gv")c\,"H1BuM0跥މe|7uȣnk=MW;G\pFɳgg5Uu7 ohhh! h7DC44!!  ohhxC4D@ OE%tEXtdate:create2009-08-31T01:36:31+02:00p+T%tEXtdate:modify2009-08-31T01:36:31+02:00@tEXtsvg:base-urifile:///home/chenno/projects/elyxer/test/elyxer.svg*#IENDB`elyxer-1.2.5/forks/jras-elyxer/test/with images-1-5.lyx0000644000175000017500000000446712117061342022154 0ustar chennochenno#LyX 1.5.7 created this file. For more info see http://www.lyx.org/ \lyxformat 276 \begin_document \begin_header \textclass article \begin_preamble % eLyXer -- convert LyX source files to HTML output. % % Copyright (C) 2009-2010 Alex Fernández % % This program is free software: 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 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 % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . \end_preamble \language english \inputencoding auto \font_roman default \font_sans default \font_typewriter default \font_default_family default \font_sc false \font_osf false \font_sf_scale 100 \font_tt_scale 100 \graphics default \paperfontsize default \spacing single \papersize default \use_geometry false \use_amsmath 1 \use_esint 1 \cite_engine basic \use_bibtopic false \paperorientation portrait \secnumdepth 3 \tocdepth 3 \paragraph_separation skip \defskip medskip \quotes_language english \papercolumns 1 \papersides 1 \paperpagestyle default \tracking_changes false \output_changes false \author "" \author "" \end_header \begin_body \begin_layout Title Images Tests \end_layout \begin_layout Standard \begin_inset Graphics filename elyxer-svg.svg lyxscale 50 scale 50 \end_inset First image: regular path. \end_layout \begin_layout Standard \begin_inset Graphics filename elyxer-svg.svg lyxscale 50 scale 50 \end_inset Second image: convoluted path. \end_layout \begin_layout Standard \begin_inset Graphics filename ../docs/elyxer.svg lyxscale 50 scale 50 \end_inset Third image: from another directory. \end_layout \begin_layout Standard \begin_inset Graphics filename mini-elyxer.jpg \end_inset Fourth image: from a JPEG file. \end_layout \begin_layout Standard \begin_inset Graphics filename square.png lyxscale 1000 scale 1000 \end_inset Fifth image: from a PNG file. \end_layout \end_body \end_document elyxer-1.2.5/forks/jras-elyxer/test/docs/0000755000175000017500000000000012117061342017632 5ustar chennochennoelyxer-1.2.5/forks/jras-elyxer/test/docs/elyxer.png0000644000175000017500000010235512117061342021656 0ustar chennochennoPNG  IHDR_nbKGD X pHYs229 vpAgIDATx}w|iջdɽWt 5!$@H $! ͗PrC rS$Z l{%]q|Z gvfvvy9(Gr!q>r!ӅC9!-rC9[0r`90n#ra"G9øEs!qC}nv۷ottttttJRT… .\̜9s̙sᣍ~@x<x^{5oxcqM7X,xӦM6m_׿50}ӧ!b{o xgy Rp8l6f qؿBP(<3>8]N%X,:uԩSzAhrFٶT*J,^xOӟ{rÍ,}w}z5׈jZV B“W6&D|^>>[nݺu89C:rNQz^೟g?Y3f̘1Cl+Zbz„ &Lo߾}M0\`׾}k^X#ɖ͛7o<`֭[n=ݣCnpPYYYYYyG3> // @@"qF0N,8Q"ljjjjj:묳:ԟo9|#8|ÇE-3-8dIr'[5838Cw99hxㆍ6nn馛nr(#GGqA%fk׮]_$r =p8,Rm."JٳgϞ ̝;wܹms#q ̕ :eZ[[[[[E5믿?ݣCM{ pǎ;vH_/wp`0 ?NG^{}rxqD=BDI:Xexȗ9p,{99|Ks=sb3qx,ǀD2LAV@JR Dqat9ʋ0N5M ywySH$' )gKޠjI!O[t\. CP8}{6dlgȮ]v\r%\r n&nx'H|#W >H>^]۲USؽ{ݻ}s瀫ꪫ:ݣs7s4b2K:N$Ï;-r?9kNh}+_W\p\pV=CP0Ę%x<uH$8tFC ņXAWJljh :@5B<O8_AorDqŸ%@Νc$w$Dwwq{87Fc]+sk7F{--@0lLħFv`}60uqK$@ɖ?ªHėL9o B^/eL9L$B!Z~gNdr8> @3NMa8Csx``OwOwOg$"z[oN;ZZzz\.Z ==N{tp:=@Fcx"8F^Q6ɨ7v֖0aByy~>-mqca?Hr<"})/ 1/2T5fIY%H(X%>(~O\O||>ut w77w> KK+\n7f3{`Lz=i4)P4 `$8mOTV \yg6L~Lt==OvZ( H&c1"HzA{&@h j]PzBҳ8xqK 87567 bx" X,FN,Z4uje%0yrUUa!`Lǚ ? vdb_yE8)AP(J">RZ P(J$7onoVZaȑ~sp^PRRTK~]p՗_>e PPp~7FjTlEcјD>QYOvRbjG"776+WnDxW+_.ILZVI9[irU;zW;Z46 'Vضs"($ .; -) I.ٞ@cAUؒ?4ЬJ%/ZK rV՚@QQQ"~. kp2}D?ڵ֭;vtwC]qt"h(Iq̀Vk4׋9hb`65K/KEaґĵk| o܉ʀYKK`J2+٬k4@UJ%I0iD2IR<hFDbd2-Blk˾JR߫V[{7v`-+w Mm#=Շw:?=UW ɚ YNsDS?Z +*****F}-[}ZZfϮΊ8Rl7Xĉ'N*2l`<d a[`-0 9뮻ɌFcx}q @_Sgח ee!p۳\7L ,P"cbDUWs@_/ ^lTj5:0w~|艏1n .ᅣQvrªU{V\ӫ,,<'%>(G?oF<jl z!.nǭ.]|~`Ŋ+{/뮛>">}iʄ\t(&l b1zaA`fc'_G^O5F r*L:G'd2k׬YBbŋ/ 5W׿h<<ˆqK555555믽k/7ܱhX` ʉU JKm6,G(lB*4^N8>Ea7&eBPXeg"KPr 1z p:~߸Esc悂+>. Ri4aFfh4juxp  7pu3fU4X7FgR-;%%:ߏ 0޳g&薽 ^@ uPzQ]Uէ?կĉf*@کD'MM>D4_׬ M;= p$֖-U^-ȆrcȾcǮ]==d|Km%?yoV{ϣu T$a={zz)/z j.ۏYFlϦΙ3sfi)pyg]SYnX/jjk'LN22f/NG7H"Àӹe˻JtD.W_?V[,v;`6N8 bdkVrDˣ\nO3355TWrz0ɽ,y71A2fS}am:;r/TjupIf̸jihZ|$ |>_4JI+**(3;omBQPd JRT|xmׯXZl08aoX Z^PM'Es䕀^_RRUED' +ަ={#Gx}3f~jq4q'9̂-[P(;Z O8;4D<HdF__kDKx1*c,O-3W"ql4L|`EnXwyɫd/~fL&`Ui2Z`ܹ_sʹiuz2e9sn%R5{WI{er"^$x4tBu5%<6/PbyrT׮_xǀ/&`ڴ|#,Xz玖fS/[;?)N {kى!kabx9aq}^Ri zEŋ}}vZr\ٳYawtwG痉ٖ7})EE…WT+%l{͙S_L#~PU^~?js} ݗZ":m9sPM&EJpx}嗁w |O~~~&Ӌ7< }rc{IE",`0Ղ &y72y 4Kx|!ό+,r4|'m):o8nߗCbK/zdE""9[l;kP^p$J(ɃHھ]BtGmt>_Kˁ"b4y@/.N OmA&˟xڱcZ`˯XUNr(Ljlۓ8$E}rfiVUYcdKL\͈` DPUzad+Yg{WB޻>,ӱl#IRFE#;sY()"8УuFQoAo'R6n|MRY/׭{5 xϱd<hf]pF|8 ѱtق`¿ujbih9Sz2G% <ާ:(GG ue(*cKL@$r,Ejm6%#o|@XvÆtK~\_~2V/o6LNT__P^Eh2F"n|@w7 qΝPRl6W]OWy]x]۷*pHsݔ!~ 孒Iz1BE.)).XrI 's޼y^]N#"A```ݺ_WZ pnL)_p0$N2L&`(-$G}X\}}D|3:ٿ͋o*QZ*prǣ(?(c(vhj/;=&B7V:XR \哟Iʷ3oXq^:q\$HZNG=7(WoojsfΤ:]&fϟ:8%KN9碋(~1s:ɶ:8Hb8,RJdOq(0x,lv՘A {z$UJHuڱc: D"lS*5RY&wTE0u+O>  &ΙL@4j4g\6⓯#8xu0zx$⳥Y,6ĉ@__ooKKLFJZ{@?DJ"dpe/5])"_ VQU*P,>uۺW:/v8"rL-`ʔ"/o tz@omfssڵԸna3#͊%GXΝQ٪+|*+{!I[JdcN71=67wu9@⨱ >0P\&`0kkº:1vM;8 }tÆ'뮻ʩSPRGA_TE[{;vVfR`WXZ,WTdL@^y9>%HQ,ٹCCTvlLuȑ@xJ}|A&zTU}<]q7ڇ] t:E 3OZZIih:֖꫁l4~:lG͛Q|3^;}:pphLR\"Pb)Jںy3wȆ ںe &n"-[xܽGKZģUHz0 ,Ued߿mp={„f}T`Ҥ)Svؾ}ӦnԔ~ .¡u6ShTd2si%%?yf'L+*Uh#GF'AeZMha`vv (_HP 9(|?otf{'Ϝ}NMg>̚UZdɇ_ ;:$F{z3\X'Ϛum@OOwwK =5:75ҋ.jhniq(JS=? @'L&2Uj,8o}Kx&'PsswuIu. ?ȑ  Ob1)14xi!m `XZ֮4iR ~ ꫧwsΩpALώw㜹?1xqmן{48^ cpyٵkE;˓e5{zm_>{vx7F4 uu+Wگ~4665h~rP^^V\~UW}{O}kywݻWBA}m={eFhmݴTw<>wu.׶mk*̙W\h4_ԑZ(bH6p8`0dظnᦦXlz=LՁV/XCK|o[7( ÆqKk*;&M,(s'OِHbCC޽۷o$Jԏ:U9Ef;㌯|j L҆ ZظaPP@ѱe VӎÏ7MM}mFCJ%Gňh2i4dHIBlm=r$6n\k$@@]7PEQFwr 0"*c@8|HlRS Js$(Tc*BA6چ8xpa  (>@a2Io=ZOjz n _N⊥K*=>+(u*x]v٢E RWT9eݺ={ہUvlkBg/ r`T'*ahtwG"@oogg4J )V#"J}K];٬坂lwt(J%WTZsz.gO~̸!p8 ;iR)6*Ѩ̚E&a'\3mR #‹/Ry"A6,ʢqpR TW:$Q*EؔFѐhT"dp8"Jٽ.$SUuPX%'BqJ/BJ>kyT!Kz>kp0YBd8q2Gb1}I T )jMU~M&p/~v-,X|S~'9Bx{/֯߿or`۶ë=J= Jnj/ >}˴bm<( >cQ ۠ /F#"X 0&&I (DT 72`  Ӧ>0sf~>`it [>rٳu+wt $S\v ^r  â$>VJTRQx Wju:l|j5*P\\Zj0-/z{~'7o‚`PJ|,*"t:ry"Et[UU0sfYم<'G^w;;Kׯ`۟SdTV>JT&"e.tf~^O·onu}>RiB"~h4 //?_%O Iq9Z-NfJEq( `ggPTBmoomP0Iz1JˮJGU>E3"RaƬrQ6$ZhT!Z6*Idɮ7&O6nEEڿxزeffh)L&c1tn'U2.W_/I%.䱪S(P[A 55uuf30{y0s9yy驆,:4 v  B()``NP(ZjԪ 74Og9dopz W__0HHfQ*ɓb0 j5e )DR' j4B!z}RT0 E۾{vn3ibMCKO r+|n`׮ěBQ(x\F?Y 5p8 o>ݣz^x lFXLp:Is損#Fi11j+@Q%PIecf'AGGk/kϞ;)LǁŽlljȬ`#$*VD@8];+Wٹ! ?&BCL!" '@wwGG O*<;gXu# ,)-ٵkhT~[LLulZ-5~>^=kOKLH^CGuum<ҥ_DiHdω!H x, ~xnj_yDyG?NTUVĘ'N*{9ۉ8.m`v SQ B}0^dVFYfU!4I@t|1ft>J%_X$b$h&2"BoIYU%ekkK xd\^b֮]b 'On]ORʜ h}{$AS*ǶZ-ۻ曁 .hhE18M5͛z Wz/ єnFLMW%BRX鮻A1_oϼ 2g9A^?}{_g>N2PPihx|۶F/ ӠP'GIIi()"77{-7 o8_Z|=5xgd(ϴ_cyQ R8GDDŽ( ,9J0F/ -J3E]۶ TT?ϦOn_N-[6n<\Q*M&^n@'O;ڵ-_<ҥwTT8& Ru  2zaT#FBQ[ 8&ӝwm8Ip#m|9?TPhӦ/Y:Qj[,ƶ> .rZT@AAq^O*\2 dZVL74$Dj5BP@XrD^bjMl:y8}=tCN*ቜ`,KmBeN  1 /?"(/2EBDz=6 vSbfY;J'4~dR>|U5?[3i#M| ׿z۾ TTLzhӛZ2PXRTR̤*2b0k$PVr=_رM9i\Z{@2cbHm}4 %1zn*6@ l~Z-ep@磔.A|DtVB^[*P* I62%A":@A U|:y>؋G,AJeDT;R^^Yi0&"fhŠ{zC!੧x. `ƌ3v5(i<ġF"ΝnYg6^_Twliۿ{/} | /x ^OKӛ"}{熆~ʭ[FOp 7l>qr0sfU~W'+TORgSU3}_;+X*<>X2E! @jٴZ``/NA Ϫ4KDR"H$,WGIU%! RYF2I*'-(µIR '(*HU9ABVKN^f 8CG"dZhQZm;TxUJJJJt:!ɳ`pX=}` ??H4 SUV-\HFOzAC/WqJJ %Kv]:q2&5=Aw:OJ8p#'H9ƫ$g4vwl9BەJ 3v Y5|]  T;v]G6)RyS%d}t@߁~ʰ`FkJ԰La)T[tD*1r聁P$&"t"@n)$S&{dD+g"Z8KR%@2 QJ|&HZ"@ ǁPHHbaɯ;yOvZ$PPP\l0nEȚ9]]_>e׿/[v]"s$/m66;zJR&qn|+5J,LJu޽$9&hTyWZ5DPGT#;E|| .4?8`45YPA\6@s:[ZK.O T$N?-%>NPFi dcbgYH$u MXlLP, TD`*%^)%@X"#M.踉K"PNlMgN!$g65<Թ"^d԰FF =D+O06[^HIЉݻd@ƙ0N9]o߲ebɨ*,4)=YqzcDP=P*H9~(UrB*FC.KD\ɤqih &^1NǍPJJVoqϋֶm`4mJ 46D BdvldfG}3\ Ι^̦ `@`-Gְ75?2*hLiiyHHWI"epdmfŢVSj pLț6_tjuuT@mCCN'[K}xCDJll߿wߒ-[S>;v{G:$9KIy95xD%~PZJ, vMy  U?XBiDp?M ~` Q'87yR@IɊ5Ւ$w?p DJK'Oa;:LIUؤ!5IH/B;dKg@dnxTOPJ[(D&K<$Ad:/a; S|9U(JޟcmTsu{ PmڨڂA47*S٤!@b8X2: hnܺ4૯n닊J"zb(RJlTeW*dYY$Iңb0h BtV+ U|}]JUPl|,!21TJWTeAe $T.i`7D#g NR؊<:' OF5zhȟI2a0t;)R!NdddI ==ԎHH,ѵ81 ZFTTTWSYf*T_:;NXm>s>F/6;s {9QJeEi?>_El:sv Iy$}{AZVFD@Smy=*5m4(YU8B3DRdB!U~L{eRY"[H2I&@MGBa6j5Zttju^lStHZN @ns{~qr}1IQ6KK:;'M8_B~L0p^oX\Z({R?D8|!c$ IhҔiDj4 \bJ|lz'*K V*bNh繐j4JĞ)%dN6iJpߧ`;JR<^T*-XHE"4j%G^U<^T(L6L7?  Kw0r'?TN ."k(Dc̉L<*Hq r! JI׋WS y4AGKŒ+4%D5ĒIH_\.RWG,r> ddxhQTeh4_I It_89%'4X hnnj2щ%k}h ܩϓVKϪ5+k!YJPL$V9rxd5b` l3o߫>tSXC8sܹ4řc0h&'M*i&',J@ydp륪!΋E7GVeF"HB@(DK ;bT y(\QRIi?4e ӕRXI(TE%B(T%l\D}K:/pRɃT49#K-ORN|&B^τGi=%gyy: ($6*P3q$|f/1{;x<ce4z{C!a ;-_tnNDǑ~,DVS}EzstY#5e8`0M jmo~3mM4DE,Qqݥf|H#$=yGj"P(lOW5<`RNnl`c{ 'vԼSx< %FJ:* 9^-U*T9U*)5,sNUǤIV<1Ye@/%TL 8N0UU6""? b!I$+&>}rqv>n7IB"'$@~ޥrgiJ=?,#uNI`.h8(HBVL$nڲe?iij{A{* όVj3yDTa'"Y:X.GMڀj 91Q*8ZRAu:D(xVXLxh(Cի)BΓbjK( 񥄗}:eȽ,tDC#cI/l7,ҁD|Lrp _BN2A\4rUZlHU'aM7D\c(G/t0Z-9J+V<T?ko߼()۫iY$~ vǶL<Z#].%OkKi,FUV6iWRR^NKxs3RD~Ng2Q|"DJB^lė:AK|3R,R9P<]-Z2/oɍ bI&+v6-$@&}SCn4 FC2#9];S#֥*/{}Z2c-t:K*-2SJJHjiz.ZF#ߧRYPOkΛF7oӟ/{H/*yp]6 &KANxY,qcd#OSHǪn(DҺR MRﱔ4ӥ-1&]!ᴍ 382|}+)O/֠OH#pB`0śTzLCdBFB: VVr[ʽ{ ?*1Rl0)ҿ=SA94*>qƍ}G5i<ѨVϞ-p< /] ;2?F6}Pz< FKτ;zER9Fcc=WYᣉ@^ ەXiJ RQAuV$B^hqwma%2wX,)DJ-*H"Vyt:A:-Y ?$kbω`2鴣ߝFX(HA_*Rĉ{g~\, UEvVYF`XbɖpPА-ˏ̽ h,*@HRe44l@cYgu$NR%%FwK8ҥhqUe;bة {z߱Ty]rY~hVBD"ҏT@5ZKK?a2i4v `x8^x"7h!̈́ɬ*Ht A^ c|(%%[JE>EeE?6-z2`P#jJ-m h?};,'p(セ1ADJ$wcv`'zƩkEE9rQDRE!+`dqHX2eܦ'Ɨzq:Z-OZہ P6FdpE9M%H~@r=xkkI=NXHRtLldbjkt"XHt:=㱥UV⋀^WRRU iZNq(䁜)_X,`0PCFla6F٬5?cÇNNWT 8Dª7K^MqVU z<ҥZM9UUz=Ida*1:W`vq3K_8L,Yd[ @6Czf!L&S(D}*>'tY>__KS>pz}Qi #r"}uqhI$@Yu OMj6fA=#Դ2hB )3`t:b2YkV T`#'.u?vu:*uri~x8liiy ȑ;j?ni`@jj|>"&GU(Dd~ImP<+_>C*!& S(rr'L0hVj)m%T Xk# e`B$Y !¯JDx\Η$H&nBJKȴnk'ʺq#EV*IEDZ"nN;#o-*|Yu-553g<`AAUUmmm]v" |iJp̜Iq~ TRUbq>?vfsYىd:Dcxbd"DE#ܷ{`u̵׺\j5p?meeݟ[V+TB6S9<*+kjF`'_JEeL&Q .`Pt5yA4e #?ݝPq :T;x< eEu25TEy7:;>>K~逩^\>89^ӈZtS.X(r$d vvw[;.L៩~쟤7$<#ҚF"c~rHU{loip/⭷\py@II~P$ \w(Fs|BhQ9m#[N?%pn6{K^MX(m"AeZ/]fޟwzz#G={:;{$a`"O.V% @&' --@4g? I"|DO&MIJ4Z-`v;0}̙f3@yZ- d [J %pD,f`Lz}SbD 2)7olI뼬(H\B-/O9p}Q,B {Mk/l|G;kFAɳfz= ]xRm(,u Ӓ|, Jņiaȝ&%\nj0z0FJ|ttum~w={zG3oEN!ذa޶6`Φƞn"YU˩w DƍN:=$IPrȶakWGǪU R C]ڨ8|h^{hmA pV@yUUF#I^옪Ȼ54@iiYNTWqW6ljez^r: GU)lDK.tK! #s+WbKZJ or$TVJ3g8טWJ-zfauO&¨fKŵu31[$\t[jŋUr2Mq>paUƍ#ѨѨEcҥT';M,2"Bi@Ԯ4a18ON-Cj H؋ӯAD'I&KyJ|]]pÛ.<|1Ό<sΙ6M,N'rAAa`@$@iIg; С3hޠT*RACzzl )SiO)i0ş\1I0UU*[[Rw72k֜9V+x [JaljPȄjG/Re\6KHxS)%+B);tI$@aaQNG6Pv<^:b^΅PY2TDB I=l{$HV!co/ Xp3Ϥ N5b ++kC^07XRDtL 0 T*Rْ&i~JPg9HW==D4k;'}Wx߳ /GB08448ʕ?P*zDJJK' L^wwv]Kہbry:`DRՏX|(Ǜؾ}ŏ=xxg[,D%I~8MdDK|KcBSSOvZEH6B~BcF3 yq@N _4YF*5m#0WM{ >55f-Xp,h{JIq~vIdhhOnJN4&rg41F l?'vLؾRp* csZ~lLjp`I2z5Zb:FHx)vW(h$˜VӧSRYQ{"%wزԃ'o~SS#4={v ׬q+!:! $h4xU]8%C*u=g8Yt%Vs]7mS،$?燎gSXxH2~:_$^75Ӧ{ɈQ'M9Ng*~?tM 7߃RQEpO# YT:r x3e0Q eeTh2^.{.SJK]8Y@$y<=/'c„S`ɏl\:]& g̡C==\v;U>Ldqj2އBC`0(BBb]IrRK]/]‡"#E& Tdj?Y’K*1WnfIKIӦLvl>0 Q^zEԁO5TR6Gk>;2"yyBq )?!эFi [Z n1+--"p:} P=ɶ>jK,WIFMG7n|s{4A'qϞe˞zh?e@2I u:!4!B!S`8& 0k0ejjtK)*, k!AjuK|I=_x2jt9^hRh%KV˯xMM=*,0+l}m!./! FjbTﱨDɋt DE18HpX*@M 90Y\wnRR2G0.AKjk9UU?80m 7qo]K>%I|PyS&x?UEE',~2Q$EM6s}ܹf3tRh$7{RPas*f1 /y4!ǒW(CF**lGG{{8  PZZZRsAxzYVtd`s!Abbft*FÒ?1p- @f?X0 `ʔ9sK./} 0O@gmu[԰|NǮ]O>@4>bOϞ=[Tn`0$Rl&۞NG̑oյwxa p8j Z-{{)0yǎwZ[Lh:u:n*x6_i)l~ʿ-uwXhʶn| (-\**@.lp`a'ѦV+l6MExs?j2!†(H364f3UTh I˶! FEuk` #I1?JP(:S(W X Y/E=+=d2[cמyX!ipY4z=%ld0)BҜI^JmCM Hi(x}j-uƷDFC //۵cӟ.ՕI3/,-R*>J :;ID0 RRbO'W@2Ҁ]cǕ>1BM/(=^__ooWrĉWW"MD%U-v[N Vat:ZWU @M IDeeZ-e 9Mf .((,s!3Kiy*ytTl6Tde%|`9ϧ;%75F)Ӆ{q_bi sx {zIp)Kn2~憻,'Vqzڀ^OnشiMp]6Evzz]K'T0SG f:2h+us:6:\M/Jp0.6" c^{DeLd0gpDrbd㔼VJY(Jaƌ'._\q1j8t:nMoJJ,ڹsF cR'h@JEejJr D:A* )`D}9RbsS0`kJ7 dv«Jٹi;;wֲeb'W=\YcDTTSL⥑>nL5Rl媶j˥.0ֶn]Gw!G|3dDό|R*IsFIuum^Db2E"c;,5 iixTqb,) )t @TiqWS3a> [PqI"xSonO?hO1"&LX1kVs}qbD/h9_ⷿ ф}~~7mHu9epb{0v@8gO(vHe0Rɽr/S$U{Es Fܗ^\8*ǁΎzޔ {}}]] F#Kσ|U*N60y8^IՕ:rpR| k׶ڦ:lQ(Hh|o"[}餶՜k)nWH [Z_ճ{En/*ߗfR#![j`gg B􍊊*VGD\܀$3)$BAvSMƷd^+8oRT.'٪&L>s_1󥗞xxeo~s@{vgjN?tH&hh0lF#_[k6Fwi"R5f*tؘ'"3^  xrښɓ.eM]8Z2=eG "LUYq3ŨtZ-RR=.WkkOb˯_Lq#W\t)޾`}@7IsOtbdAA2V Px B9t|&<&'Y^_ R4J{mm]gV%[wo>/nQ '@[*Uy@E>_?XA5Vr2ߚ)S[s'wկ`zu#cHL,ÔN)MfsQ 64XNGHٛ+CdOZomm@oΝl")綱kjjoO=V)#b63?~:qF&N>7<M{hfwW2ifi^bV1K(((*R)CmDBZLzF<'u4'%{_s$$Bg dTP({|~>z{{zb1{)xG̹xɑ}B9T0NrԜ'? |snoӟ+W>? x\Llr3[U&XJ2 47Q̘QXt"ud:ommkh\\V*1r"L?gFVKe,&$T\Rmx6ML blSsG&*#mm@WlGRՍFϿ.70|p5ӧ;@MM^ތ_w+=6̘̙p!l19溧ԌFʵM$HӑK98,lU|J|RA Cx|wP)/Wn/g|S-N;2Zf.{Gᢋ x{vׁ޾tHNt"d)%nQlrhC%m.6HP\. *񉭀TRRY>n:͖=a.R5=9TrTz6eLp[Iv=~UZf+~Lp饟{g./brJGn طoښ'NL̙$2qlv;U:fJTwI)Hj3(:RsYpST^$/59mD?"dqw::(0zma ),|]o|yep,p̩;QfϾjή.@d$gV2mE"=kٜfj)_<D"dA M=l*g3$(*Zq7󟓄*-x<Ν/@0#ȽY" DŽ 4)=Y!!|>_j5OZ\KNQ;&8s'LF*() 8|xRJR(D01Ll{qg{(@To<IS*oOtົ;:q`ݺիC!P(.+_.kL&;9'lc NN8Fc+<46C7 |Nunsj@*{zdL|oD^/PJxߗ~f |0.ߟ{nM  RэghDQvh .30 }j8|]nu&K-^ÿ=3K_~:kɒS~$vK}+wZD׮Ofxx" u:t;L;9 )qR\EػKKqfH z$p=0gT6mk+` s3ޟUUyyӎ2\{p]7LD#UISc'/A᱈G S__(+>}޼3y763̆t[`vJ> hFF_0x@ t|ُmKv9poo/|xBӟ_߱gHd; $mmKEE60y) 0u*j)$9W!2<؎M|ݱx@8 45ZBlֶlf 8Hb[fJe,sM(..- jX BA8NQ\rq;8ߟH(`4Je~~c#־ PR<{p0pS6>H$(+7~/X._Dc%̟E|+?|T⬫;.7y y>nyݞdTFOq_ /]{^N`֎W_}=-[u\@;H&'NI"ˤksȶiJnJ%׃ *6@2pUUW +*IqZhh(('>6`"\ԧիW^F8^[Xs*omYg.Y|hzzdžիہw}^N nl8MFWxׁөD2]]5Œ)IDATOc#47a @(|G%Qֳ^VMޠј̀Ţ9$UVVk}PVf?tn|΁Kի6nܺu۶LG&cUyJJop%?ħ>$r_z閛/صOSJIc%%Βb٠x룏>M+V<r![E٬T{B…3ft7TTqƩq@sHA, @o]7I]6M0e PR2gYgQt_E99!->?d9Ç9!-rC9[0r`90n#ra"G9øEs!qC9!-rC9[0r&dk8%tEXtdate:create2009-08-31T01:36:31+02:00p+T%tEXtdate:modify2009-08-31T01:36:31+02:00JtEXtsvg:base-urifile:///home/chenno/projects/elyxer/test/./../docs/elyxer.svgJYdIENDB`elyxer-1.2.5/forks/jras-elyxer/test/docs/elyxer.jpg0000644000175000017500000001234512117061342021651 0ustar chennochennoJFIF22C       C oo" <!1A"Qa 2Bq#br$3R%S8 !1AQaq"23BRb ?=4h5{F;s=lٴiKɭS 8p_!@+(3_uwvd I"۽éV\ ||A5[[\;{BWKEDK3Jm)RХ; TF(F(F(F(F(#k?')9>8)L+: dF ?z:ү{м촬 q> "~d[rLxQL,ppOjDS)V|ԛU6z`2׃}G\$)Iz6 ڛOV'dUm&ƜkiS!1\JXC9LS$-C! ?_; .զ%]RɁ&R>~sYx,uN^ymlq(m *RprO;37HI 9!ws$Uǩ?1 ۫!kJֳHz8B@ ]#K"r H:ZZ+ɹAJdKZƠ{TIO.S *JBTqJqMCvoȎLVqըN`˗ɽux!Fr93ΟRҼ$em[TJ}46產{#}e]{ GYhdT噅T<PR~X=1ӗf[>0%7JUzHVzHE*PSWaPn PRJsܧ$̭HHRuI5P}%u>,k${c)!퐾 Wqfj*2rJ8RBiFM{\Ԫm=INe&#}}xg4EG8%Usg-SHbcfx  SaD`wJb._PFht$oN-@ZW4kTR\֪q)rDH5(>IS6ޮ)Tu d4\O}SKI?=rB M]qK_6S|i8#ƒV:0U4hfXG#M2?m՛պ#,"yGm(i( )jXBhjܱ$I앸BAH=V2aN-4}ڇ`HH _vu C6>&7Q;l#ѣF;vnP%12r%, 2I ##KĴG$čTR~Th }հ,]wtzUFHiD{zz]B5ӺPlSH4j2$CeխKRR"xtުU*4*ڔÈ#}NxER$o^ඎnzLݒ2J%R*$sAg q bb[*cp ~CKr8,)kԲJYpQY\k>X)׶ݭμ ~US % 6R[JBe CGgN 1G]O6n49u-ŎZZ,qd'=u@MT 5:0d8sNQwZ͸ijո,합d]SN^d1kv?+^jO<1*w%Ss'"ZNVYfIpoHuN-GTIԪYDߛ%EdF>(n+)邦vΊmOj9sR$)tjVg'^櫋cBƒuD@* F]<~pnAd-i1ĉ$+Ŷ~T='SXf^vEjz[ F^Bs0)PEDqFz]-ļ<0c6brbG)[׶=I}]@u [ Ȑ#py=zNwLʯq0ce0ᶵ%ST?OպV@ $IG=~Z<-P?5;!lsJ.uXWê9<~~; lT.,<HH)~G1tvHQ-Son^\gVv$q=ib8ZN/ Hsj1nѫT$'\JRU ADQTÍǪU[%\7k JՙjE*SKu=AGMC-nIn8[&ulW(Bz|iTT뎣JnNsa#A#ƨ}ţFW֥栅 y/"BhF1o:X;gHHF[ Cb;+':p~Mܧ(Iө46ٹrcS݋]^ZG8 =4W{m}yq_PIJJ֑[ѩTh.-K/bQ:)J.-X8kiooEI?5LT+=ګ=IU! KTS m8ꀦ = N;]e[90F!Ϗp+\ c?Û F#FeEښy m(aIROE=47iu.sgsOWס@ח WrD^lyMrK=N2u˧Wha#;\1M?lٍ=Ox. GP8#RKpm=:qn )^篦G}sn5xyƝO>QO n|Dmn 2uGʐRIVTzZ]-k* ȨB~!>Tˆe*%j<}ܓW5*a9aTiRJL!>@IJjqZiQr'=]>O{ ˻Rr @:Jow+:8#Aqkvz1ا-PeAe! A t]۵oP6 &Q?S Q)٘ܺV"Wj._vFBJAQ3ߋCPROB axm ''¾xcU>X?wAQA䢠H_ H'NZ*Ȏ؇mr?CWסEh\IG ny 4׉ m*ިEWh5q:n 9kPE? Fu) s,&DvʠXvҕ5 BV!d^j:Us\Pi2qqt6~n ckHle-iRQLrNBJNPJRY caSJoI٠\` f8)@+xOp ӟ D]5j0:}=$ #u^n:"ɯ3ө̏L'c68(1:(r2z*"}6Dƍ4jKU?uFD*[J͎}prMQY@Riy)^\ 9S΀qѦn[>"MI[M8B{|QڢiNZ :.+ :Uu=`MgܪW)̈́/*D)msIq'[h h6T#shyjwgk/je;WmQX/ JeM}>AN[F{r$?Hk{Veٔic^S 7(RIQI$뽣XfcSϝm}bxAQ-JLD\ :,~6d[WZ4}ClN^gXcR]"DZdHPrb䔀5ѠʰF+5elyxer-1.2.5/forks/jras-elyxer/test/table-1-6.lyx0000644000175000017500000007426212117061342021043 0ustar chennochenno#LyX 1.6.5 created this file. For more info see http://www.lyx.org/ \lyxformat 345 \begin_document \begin_header \textclass article \begin_preamble % eLyXer -- convert LyX source files to HTML output. % % Copyright (C) 2009-2010 Alex Fernández % % This program is free software: 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 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 % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . \end_preamble \use_default_options true \language english \inputencoding auto \font_roman default \font_sans default \font_typewriter default \font_default_family default \font_sc false \font_osf false \font_sf_scale 100 \font_tt_scale 100 \graphics default \paperfontsize default \spacing single \use_hyperref false \papersize default \use_geometry false \use_amsmath 1 \use_esint 1 \cite_engine basic \use_bibtopic false \paperorientation portrait \secnumdepth 3 \tocdepth 3 \paragraph_separation skip \defskip medskip \quotes_language english \papercolumns 1 \papersides 1 \paperpagestyle default \tracking_changes false \output_changes false \author "" \author "" \end_header \begin_body \begin_layout Title Table Test \end_layout \begin_layout Author Alex Fernández (elyxer@gmail.com) \end_layout \begin_layout Standard This test may contain several tables. \end_layout \begin_layout Section Longtable \end_layout \begin_layout Standard The first one comes straight from the LyX User Guide, shortened. \end_layout \begin_layout Standard \align center \begin_inset Tabular \begin_inset Text \begin_layout Plain Layout \series bold Example Phone List (ignore the names) \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \series bold NAME \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \series bold TEL. \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \series bold Example Phone List \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \series bold NAME \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \series bold TEL. \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \series bold continue ... \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \series bold Annovi \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Silvia \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 555 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \series bold Bertoli \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Stefano \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 555 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \series bold Bozzi \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Walter \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 555 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \series bold Cachia \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Maurizio \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 555 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \series bold Cinquemani \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Giusi \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 555 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \series bold Colin \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Bernard \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 555 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \series bold Dal Bosco \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Carolina \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 555 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \series bold Dalpiaz \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Annamaria \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 555 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \series bold Feliciello \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Domenico \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 555 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \series bold Focarelli \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Paola \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 555 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \series bold Galletti \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Oreste \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 555 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \series bold Rizzardi \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Paola \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 555 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \series bold Malfatti \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Luciano \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 555 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \series bold Meneguzzo \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Roberto \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 555 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \series bold Pirpamer \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Erich \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 555 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \series bold Radina \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Claudio \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 555 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \series bold Unterkalmsteiner \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Frieda \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 555 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \series bold Vigna \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Jürgen \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 999 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \series bold Winkler \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Franz \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 555 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \series bold End \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \end_inset \end_layout \begin_layout Section Multicolumn \end_layout \begin_layout Standard The second table contains some multicolumn cells. \end_layout \begin_layout Standard \align center \begin_inset Tabular \begin_inset Text \begin_layout Plain Layout 12 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 3 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 4 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 1 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 23 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 4 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 1 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 2 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 3 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 4 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 1234 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 1 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 234 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 12 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 34 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 123 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 4 \end_layout \end_inset \end_inset \end_layout \begin_layout Section Alignment \end_layout \begin_layout Standard Now for some non-standard alignments. \end_layout \begin_layout Standard \begin_inset Tabular \begin_inset Text \begin_layout Plain Layout left \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout center \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout right \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout left-top \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \begin_inset Graphics filename elyxer.png \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout right-top \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout left-middle \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout center-middle \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \begin_inset Graphics filename elyxer.png \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \begin_inset Graphics filename elyxer.png \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout center-bottom \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout right-bottom \end_layout \end_inset \end_inset \end_layout \begin_layout Standard Bit of a mess, wasn't it. \end_layout \begin_layout Section Multi-row \end_layout \begin_layout Standard A table with several rows per cell. \end_layout \begin_layout Standard \begin_inset Tabular \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \series bold \size footnotesize First Part \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \series bold \size footnotesize Second Part \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \size footnotesize First subpart \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \size footnotesize Second subpart \end_layout \begin_layout Plain Layout \size footnotesize Now with a supplementary row \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \size footnotesize Third subpart \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \size footnotesize Fourth subpart \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \series bold \size footnotesize row \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \size footnotesize The first row \end_layout \begin_layout Plain Layout \size footnotesize The second row \end_layout \begin_layout Plain Layout \size scriptsize The third row \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \size footnotesize Empty \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \size footnotesize The first row \end_layout \begin_layout Plain Layout \size footnotesize The second row \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \size footnotesize Empty too \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \series bold \size footnotesize row \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \size footnotesize Only three rows: first \end_layout \begin_layout Plain Layout \size footnotesize Only three rows: second \end_layout \begin_layout Plain Layout \size footnotesize Only three rows: fourth \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \size scriptsize Mostly empty \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \size footnotesize Not empty \end_layout \end_inset \end_inset \end_layout \end_body \end_document elyxer-1.2.5/forks/jras-elyxer/test/spacing.lyx0000644000175000017500000001556712117061342021102 0ustar chennochenno#LyX 1.6.7 created this file. For more info see http://www.lyx.org/ \lyxformat 345 \begin_document \begin_header \textclass article \begin_preamble % eLyXer -- convert LyX source files to HTML output. % % Copyright (C) 2009-2010 Alex Fernández % % This program is free software: 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 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 % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . \end_preamble \use_default_options false \language english \inputencoding auto \font_roman default \font_sans default \font_typewriter default \font_default_family default \font_sc false \font_osf false \font_sf_scale 100 \font_tt_scale 100 \graphics default \paperfontsize default \spacing single \use_hyperref false \papersize default \use_geometry false \use_amsmath 1 \use_esint 1 \cite_engine basic \use_bibtopic false \paperorientation portrait \secnumdepth 3 \tocdepth 3 \paragraph_separation indent \defskip medskip \quotes_language english \papercolumns 1 \papersides 1 \paperpagestyle default \tracking_changes false \output_changes false \author "" \author "" \end_header \begin_body \begin_layout Title Spacing Test \end_layout \begin_layout Section Paragraph \end_layout \begin_layout Standard As our world turns more complex, paragraph spacing tends to be more and more important. \end_layout \begin_layout Standard Some people would say that paragraph spacing is the first and foremost issue in our modern culture. Perhaps they can be said to be exaggerating, but not by much. \end_layout \begin_layout Section Issues in Horizontal Spacing \end_layout \begin_layout Standard Some new issues arise every day. Today we would like to explore horizontal fill. \end_layout \begin_layout Standard \begin_inset space \hfill{} \end_inset \begin_inset Tabular \begin_inset Text \begin_layout Plain Layout Cheese \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout available \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Red Leicester \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout no \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tilsit \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout no \end_layout \end_inset \end_inset \begin_inset space \hfill{} \end_inset \begin_inset Tabular \begin_inset Text \begin_layout Plain Layout Cheese \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout available \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Camembert \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout runny \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Cheddar \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout no \end_layout \end_inset \end_inset \begin_inset space \hfill{} \end_inset \end_layout \begin_layout Standard These tables should be separated by equal horizontal spacing. Can it be done? It should. \end_layout \begin_layout Subsection Horizontal Space \end_layout \begin_layout Standard The horizontal space is inserted using Insert\SpecialChar \menuseparator Format\SpecialChar \menuseparator Horizontal space. The result is as follows: a \begin_inset space \space{} \end_inset b \begin_inset space ~ \end_inset c \begin_inset space \enskip{} \end_inset d \begin_inset space \quad{} \end_inset e \begin_inset space \qquad{} \end_inset f. \end_layout \begin_layout Standard Custom spaces can also be used: 0 \begin_inset space \hspace{} \length 1cm \end_inset 1cm \begin_inset space \hspace{} \length 1in \end_inset 1in. \end_layout \begin_layout Subsection Half Spaces \end_layout \begin_layout Standard As reported by Uwe Stöhr: 22 \begin_inset space \thinspace{} \end_inset m, 3.53 \begin_inset space \thinspace{} \end_inset €. It is correctly converted to a thin space. \end_layout \begin_layout Section Issues in Vertical Spacing \end_layout \begin_layout Standard Vertical spacing can also be added. Let us now separate a few sentences with it. \end_layout \begin_layout Standard \begin_inset VSpace defskip \end_inset \end_layout \begin_layout Standard J. Losey \begin_inset VSpace smallskip \end_inset \end_layout \begin_layout Standard L. Anderson \begin_inset VSpace medskip \end_inset \end_layout \begin_layout Standard S. Kubrick \begin_inset VSpace bigskip \end_inset \end_layout \begin_layout Standard P.P. Pasolini \end_layout \begin_layout Standard \begin_inset VSpace 1.5ex \end_inset \end_layout \begin_layout Standard O. Welles \begin_inset VSpace 1in \end_inset \end_layout \begin_layout Standard The Late B. Forbes \end_layout \end_body \end_document elyxer-1.2.5/forks/jras-elyxer/test/bibtex-plain.bib0000644000175000017500000000262012117061342021736 0ustar chennochenno%% eLyXer: test BibTeX bibliography. %% Created on 20090905 by Alex Fernandez. @preamble { This text should be ignored. } @STRING{ tei = "The Spanish Inquisition" } @sTrIng { cleese = "Cleese, J.M." } @string{ inlowercase = "string in lowercase" } @article { randomref, Author = {Colonel, S.W.}, Journal = {Journal of the Society for Putting Things onto Other Things}, Number = {1}, Pages = {1348--1350}, Publisher = {Monty Python Ltd}, Title = {{Summary for Year 1969}}, Volume = {457}, Year = {1969}} Comment outside an entry @article{unused, Author = {Teabag, J.M.}, Journal = {Journal of the Silly Walking Committee}, Number = {384}, Silly-Putty = putty-silly, Pages = {589--1530}, Publisher = {Monty Python Ltd}, Title = {{Some Techniques from our French Cousins}}, Volume = {3}, Year = {1970}} @article{reduced, Author = {Pudey, Z.X.}, Journal = {Private Walkings}, Title = {My Silly Walks}, Year = {1970}} @COMMENT { Do not look at the pretty lights } @comment { "A comment including double quotes because we like it." } @book {pythonesque:1971, Author = cleese # " and Palin, M.E.", Date-Added = {2009-09-05 16:32:00 +0100}, Date-Modified = {2009-09-05 16:33:00 +0100}, Publisher = "Python Monty " # "Editions", Title = {{And Now for Something Different from Voigtl{\"a}nder}}, Year = {1971}, Conceptual-Disaster = {{\"O}berg} } elyxer-1.2.5/forks/jras-elyxer/test/elyxer-eps.png0000644000175000017500000002273412117061342021515 0ustar chennochennoPNG  IHDR:wbKGD X pHYsdd vpAgX @$IDATx}p}N>t-,#`˥83t`93@M`mjҤotJC&O&iJ3OfhqM0[~2"Jl" [/,ݝNoܭvng{ݻoyT*J8ˏww} (XEJAX>XzeWnW0a?CeK=67 ю XmF} fy,XqŨ#md+Psۃyn' 2,VHqko"e8re~EtX65sKBnoB7oSxkVGInajuկBUUF6aŪCS 5} ",VC 5pU[iTϞH D8bF uN{L=Rq80vb9 xAkFW@/."޳a b͈րnoW+ ,فr<8UEpz_q0NbU2<5øUDz5 a#*DZH0 <59BU311111Xw"3r|eeeeeeM1b%"?BU XzT2Q={p9d&SD*T!*ĸG{\kvv0alJ,O1Dq==b;ge +y5ʦ!b)ݻ+cBښ/BURӈ'bgRXǔ]tsWUF"Dp4H ͛xOoiC$rn_Yvk!0DP݈5V U{F-Rx裓'z(.+[򮻄KJKoM+p*SP՘o|Fh>Ko{#Y/\&{zKSэ :Bmmݾ}>VYܲQ7J$LG1n$"X1XA8?'"BөwܱlYmo~y wDZ!fg2.^{nX{jLa:DDuVuYڽMMx<75h?Yf(g˒% ,`=΍[AV"(NTd4Y"=yɯVE7j= CZد)=7[bjjjjjJyh?[bcc==DP8x1QIIyvMGAd ""M/@e (^#[zw??ℨZS )n!Rq"[5rKc?G^MTV6~sֳqp{`z!TڣZxdL&ɤ.Gq^WuDdEEEEEE"Ukjus?1sb㧞*".PBXF#B NK|k( BҬX굺T@:448qH 46A\RnJ/bB"Os7o޼y󈊋_ϨN$>XK8~ȵ~jPq˙H$$-Zٯ]v5"ᰒBnwPI$&&K ouF UQwjvjTDl_%^lh$ УokI&w\FOݻŲI7+\EjDH֨x {C RX yuY&{|t+FW7Jǭr,b 3=#EרVUuwa>s_X8b;yfޭ3J;,2ʎr‰Ҋ`*3802rk=ˏ|y5k+կ<P*nʷ "S6w'XF͹sw,[ʣشI*[>Pu2,T"m-w0ޫQܪ~EEg `FT>SDeHt[GnF06xRr(¨`GGO"?r`bg^KT9߅0:::ۍ~>2|oT+ekEZ"8r-+#IǤsé*ߺd@*evXDFoΥH5]:J /Dv]P͋D-L#9U0'P?.hȝf=XHnՃץH5(^!]").K,TcG fon{*JDD]]FO#Kt "׺:?)A']5ĚYGيs Z{:RƏjǏ?~<98R ?YVVuֳ:s܍GX-ۇ5RbA=5~WCGd,'wPϼH3ʗhŚr\aB{T=kyCZ\uyz.>szz/R.+-ۏ˥rŪzr-ܮ? pA+;>yg)U(nm#5fWu:'#U Jl>|-PoaѢ͛.6HFnz] k֗K uNAduӂ\ihhp̿=k7/=Ν+ֵguӯdnGAu)qqL?cX"+~Y (GGTSt0?&+J#ZPKޮ'r)4P5#͖9w6vuJA=vhu*@ݍHu/ﱻ*RDWOŚjpqي-U`dbh1I"11qٳD7tmWV||?ee+WmTkoB.r_PwY;/]mii¨He qDFɶ HF@(qynu@BDt_P}v``fU7PG*Ui[k O-#DETRRRRR\ |_~hh護S O_^*"zgg+TbU~ f=QW?E֭s{Z=^@"X,i4 FTjrr|ʕÇ#z!Rdr||tTyhY"kצS)SffΜtc{*`.bի@WǠcVZoɑB@D#>9w9|X{#Ps@OOLRD>{BZ2y/VunʪzbA\GF\y}[}Wx,vҹs0cߏ SO RD~,  n!,I vQBb99)*ԩ?'$?ؾ_$vOgg.\xdRY+pJJDFF2*|^Yd?.VG'Oj 7?9W? Cmp"Qq]}}D+V D'NLOΝĕ+srpZJDvD+r~M  W YEhH4sG%PH,b{߿dVwߏ~@tSSD'O򗉄hLױȭ׊:x||pYYcF"H$]BxWnht{$%*.I$rg^SS X[o߷/rjI^,"TXp8Dr,TwAdZ\\^^YIzUT|_uѪEJ=hC2 ~:?LފUU8%VbX,fu>obbh.VFht T{ѩS?Oj[ Z TOVvt7-+0U DXOђ% uF"kˠ =RVvZ[R< xndY#"PHDN-nm[bݶM9-VcH|df&ˑBpxlQZhTTBVUT-ZDžx!dWB?(Pe VUpXDXD"pǬP0: r+PWfMOQ$RR BM7bk--n@d SrS[;o"SqB,`u[7o޲G,#Yu..X[}*U`s{ULO˗GDeehN X/2WuseqL p`)>? eєxT*E##Qq}G(Qu}D G&g-\J}7ξfA_˥֮}ᅷ޲u)bx5EX,&`w뫪^xͽ+O#1>vDCEeB]hGϜ!J&OXNh<{VTaXc[X_n}Qn߈uÆ}*Y?~#Doyމ2Ѻ K崴ԀN>k*SO=0T9RZ'U9V^{̙3GxV[XEd#S^7bqP=o|r w(XPDd:߿V'ظQ0~ӧSO?P7]#n +^3֯׋\]Z"Rukky'o}kÆ[**p%ZT|>ׅW۷_@tk|nocSS[sN5]H3えUp}رω Xlt4vkWn6)s-;w54tK/^V^gy]hkPDhSZhE.,`r睟/ˍY2z)Ī.ڽ[,*T )= aY e fcGׂPczuPq %oDBԍr[3 %xrHI]=njΝ~=*5 rq )-ߌ1~=Ȃի)bMolWK/=eʷL~u#ƆU]FŷLfv# T"░ 6'ۖ [255i#V_8sň)8RerfrWF-8iwu_?;׮^[z͡~=D"گ{ncud U&DXcժ_Tq&'8!D$DY^EOv ryծ]VSL8Q}[(0bjˠ귩B-/-*"*..)|&Wqمۅϗ\H9zhÆ{\t0*TPZZUY?Pm@*gkhU OFzV*ʤS^hQQCª۱bŽ%e=e:б+VZEH ΦRohͱpa4ZWY7"^8~\[Zxz߻ݻ~۴fdD"2߃yVUFtkbpd̙C%jiy(r(>qhl,2GFDUXs?"둪\1bkX= )꒒͛++H rE ZyԂSAv#?X2Fܲ-. 3 :*hU=RرWRrJ ѫJGz*%gXBe{X%Oso'ʉ\\Fclc&=Z./=6Ӌ{YF~BkUU5Ԥ^XW'&\!ٺW gj`J(\54N92G~X⍔y}ȷ}diiWWEw74՚gq|j,U !ڎA (ZF1; ,MPBb n{V4-_ /TVn&n1}{vz^9jFe5Vv!Z~Xvn?ق~G$q|P}S8D[=B3`0tuקˢN!s+s&V. t*vVfC+z_!X4-cZCfB6 :?b J$ _/~uPWF]#CS- ,s#E[~fX_#Y kj-'->~B盽ŷ !ZLƑ1EH]47³bhitsqR)qܜ?>F P@XkiUUoSP"1`L==vީ[\Q ؈Vy*ػw%K*OS7>A#{߉*p8U5P? !Z:﻾^.Z+De2?"Xe@ Nlv|m2p@ "a=Qj( PL##VT* q\'bj.n,\駂d1#otk Nb$TEVWb u{#_-Bb֚qq7Nm)N8TC,\b?񒗪ܶBqxmN==bY_̴|t+,NL 77/s8ڊ n }!Wlt c)n%"D8*V-y=jD%/,xe{㉺ k)Pq,VfNЕXAƬx3Lna1:5K*=2 <GsDE^AR%tEXtdate:create2011-10-04T10:06:34+02:006%tEXtdate:modify2011-10-04T10:06:34+02:00킎8 tEXtps:HiResBoundingBox123x109+2+10AktEXtps:LevelAdobe-3.0 EPSF-3.0 pIENDB`elyxer-1.2.5/forks/jras-elyxer/test/bibtex-latin1.bib0000644000175000017500000000251712117061342022030 0ustar chennochenno@preamble { Please ignore. } @string { mykey = "myvalue" } @Article{AcentsTest, Author = {{Latin1 Accents !`\copyright{}\textordfeminine{}\textregistered{}\textordmasculine{}?` \`A\'A\^A\~A\"A\AA{}\r A\AE{}\c{C}\`E\'E\^E\"E\`I\'I\^I\"I\DH{}\~N \`O\'O\^O\~O\"O\O{}\`U\'U\^U\"U\'Y\TH{} \ss{}\`a\'a\^a\~a\"a\aa{}\ae{}\c{c}\`e\'e\^e\"e \`i\`\i\`{\i}\'{\i}\^{\i}\"{\i}\dh{}\~n \`o\'o\^o\~o\"o\o{}\`u\'u\^u\"u\'y\th{}\"y in Name}}, Title = {Latin1 Accents !`\copyright{}\textordfeminine{}\textregistered{}\textordmasculine{}?` \`{A}\'{A}\^{A}\~{A}\"{A}\AA{}\r {A}\AE{}\c{{C}}\`{E}\'{E}\^{E}\"{E}\`{I}\'{I}\^{I}\"{I}\DH{}\~{N} \`{O}\'{O}\^{O}\~{O}\"{O}\O{}\`{U}\'{U}\^{U}\"{U}\'{Y}\TH{} \ss{}\`a\'a\^a\~a\"a\aa{}\ae{}\c{c}\`e\'e\^e\"e \`i\`\i\`{\i}\'{\i}\^{\i}\"{\i}\dh{}\~n \`o\'o\^o\~o\"o\o{}\`u\'u\^u\"u\'y\th{}\"y in title}, Journal = {Test}, year = 2010 } @article{alphaeqs, Author = {Somebody in the $20^{th}$ Century}, Title = {Finding $\epsilon^{n}$ decimals of the number $\pi$}, Journal = {About \(\zeta\) in \(\pi\) things}, Year = {1934}, note = {According to The Society for $$\sum\epsilon^{n}$$ decimals of the number \[\sum\pi\], only 1 in $2n$ dentists read this magazine.} } elyxer-1.2.5/forks/jras-elyxer/test/with images-1-5-noconvert-good.html0000644000175000017500000000316012117061342025232 0ustar chennochenno Images Tests

Images Tests

figure elyxer-svg.svg First image: regular path.
figure elyxer-svg.svg Second image: convoluted path.
figure ../docs/elyxer.svg Third image: from another directory.
figure mini-elyxer.jpg Fourth image: from a JPEG file.
figure square.png Fifth image: from a PNG file.
elyxer-1.2.5/forks/jras-elyxer/test/elyxer-eps.eps0000644000175000017500000010413412117061342021513 0ustar chennochenno%!PS-Adobe-3.0 EPSF-3.0 %%Creator: inkscape 0.46 %%Pages: 1 %%Orientation: Portrait %%BoundingBox: 2 10 125 119 %%HiResBoundingBox: 2.2857151 10.705055 124.8714 118.85715 %%EndComments %%Page: 1 1 0 128 translate 0.8 -0.8 scale 0 0 0 setrgbcolor [] 0 setdash 1 setlinewidth 0 setlinejoin 0 setlinecap gsave [1 0 0 1 0 0] concat gsave [1 0 0 1 -549.09823 -447.62427] concat gsave [1.6412659 -0.049648468 0.045147815 1.8048788 539.20253 448.91643] concat gsave 0.12941177 0.12941177 0.12941177 setrgbcolor newpath 24.859391 31.907937 moveto 23.419824 24.350211 24.964801 11.778293 30.054438 8.9789918 curveto 35.144076 6.1796912 40.379124 5.3034583 41.760605 9.7424375 curveto 43.243834 14.508354 39.448349 16.768623 34.704351 20.597833 curveto 29.745701 24.600304 28.340109 28.103497 24.859391 31.907937 curveto closepath eofill grestore grestore gsave 0.40000001 0.5411765 0.68235296 setrgbcolor newpath 580.10453 531.54842 moveto 580.10453 531.54842 579.6867 492.49241 611.02396 486.97862 curveto 642.36123 481.46483 653.85156 533.84584 651.5535 542.11652 curveto 649.25543 550.3872 619.7687 571.03208 600.54851 564.13984 curveto 581.32832 557.24761 583.02934 548.08979 580.10453 531.54842 curveto closepath eofill grestore gsave << /ShadingType 2 /ColorSpace /DeviceRGB /Coords [61.980095 88.524223 51.749805 51.554661] /Extend [true true] /Domain [0 1] /Function << /FunctionType 3 /Functions [ << /FunctionType 2 /Domain [0 1] /C0 [1 1 1] /C1 [1 1 1] /N 1 >> ] /Domain [0 1] /Bounds [ ] /Encode [ 0 1 ] >> >> newpath 584.83412 532.92616 moveto 584.83412 532.92616 584.45739 497.71217 612.71194 492.74079 curveto 640.96649 487.7694 652.64504 537.06898 649.25449 542.45465 curveto 645.86394 547.84032 623.2603 556.95452 605.93085 550.74029 curveto 588.60139 544.52606 587.47121 547.84032 584.83412 532.92616 curveto closepath eoclip gsave [1.7854196 0 0 1.6604081 538.73934 444.56248] concat shfill grestore grestore gsave << /ShadingType 2 /ColorSpace /DeviceRGB /Coords [46.503231 26.114084 46.767101 52.293003] /Extend [true true] /Domain [0 1] /Function << /FunctionType 3 /Functions [ << /FunctionType 2 /Domain [0 1] /C0 [1 1 1] /C1 [1 1 1] /N 1 >> ] /Domain [0 1] /Bounds [ ] /Encode [ 0 1 ] >> >> newpath 581.25097 532.88232 moveto 581.25097 532.88232 580.83314 493.82631 612.1704 488.31252 curveto 643.50767 482.79873 656.4604 537.47714 652.69993 543.45042 curveto 648.93946 549.42369 623.86965 559.5323 604.64946 552.64007 curveto 585.42927 545.74783 584.17578 549.42369 581.25097 532.88232 curveto closepath eoclip gsave [1.7854196 0 0 1.6604081 538.73934 444.56248] concat shfill grestore grestore gsave 0.6156863 0.21960784 0.074509807 setrgbcolor newpath 605.59217 576.5777 moveto 605.59217 568.99624 620.95005 543.07752 627.46707 542.68271 curveto 634.13135 542.27897 630.66198 547.17083 635.67595 546.71134 curveto 640.68991 546.25186 649.04651 546.71134 650.71783 552.68462 curveto 652.38916 558.65789 652.80699 575.65874 647.37519 577.03719 curveto 641.9434 578.41563 637.34727 579.79408 634.42246 584.38891 curveto 631.49764 588.98373 622.72321 597.25442 614.36661 593.11907 curveto 606.18558 589.07062 605.59217 584.15916 605.59217 576.5777 curveto closepath eofill grestore gsave 0.87843138 0.80784315 0.11372549 setrgbcolor newpath 617.29142 580.71305 moveto 617.70925 577.95615 621.46972 558.1984 626.06585 554.98203 curveto 630.66198 551.76565 627.73717 558.1984 629.40849 561.41478 curveto 631.07981 564.63116 639.43642 551.76565 639.43642 557.27944 curveto 639.43642 562.79323 631.91547 566.46909 636.92944 565.55012 curveto 641.9434 564.63116 655.7318 560.03634 648.62868 566.00961 curveto 641.52557 571.98288 637.7651 580.71305 632.75114 577.95615 curveto 627.73717 575.19926 626.06585 583.92942 621.88755 583.92942 curveto 617.70925 583.92942 616.87359 583.92942 617.29142 580.71305 curveto closepath eofill grestore gsave << /ShadingType 2 /ColorSpace /DeviceRGB /Coords [50.659912 88.177994 53.563347 65.57518] /Extend [true true] /Domain [0 1] /Function << /FunctionType 3 /Functions [ << /FunctionType 2 /Domain [0 1] /C0 [0 0 0] /C1 [0 0 0] /N 1 >> ] /Domain [0 1] /Bounds [ ] /Encode [ 0 1 ] >> >> newpath 606.02896 575.57264 moveto 606.02896 567.99118 621.38684 542.07246 627.90386 541.67764 curveto 634.56814 541.2739 631.09877 546.16576 636.11273 545.70628 curveto 641.12669 545.2468 649.4833 545.70628 651.15463 551.67955 curveto 652.82595 557.65282 653.24378 574.65367 647.81197 576.03212 curveto 642.38019 577.41057 637.78406 578.78902 634.85925 583.38384 curveto 631.93443 587.97867 623.15999 596.24935 614.8034 592.11401 curveto 606.62237 588.06555 606.02896 583.1541 606.02896 575.57264 curveto closepath eoclip gsave [1.6300939 0 0 1.8186149 538.73934 444.56248] concat shfill grestore grestore gsave << /ShadingType 2 /ColorSpace /DeviceRGB /Coords [32.921471 69.997231 49.624016 77.805328] /Extend [true true] /Domain [0 1] /Function << /FunctionType 3 /Functions [ << /FunctionType 2 /Domain [0 1] /C0 [0 0 0] /C1 [0 0 0] /N 1 >> ] /Domain [0 1] /Bounds [ ] /Encode [ 0 1 ] >> >> newpath 622.72321 525.57515 moveto 667.84887 539.81911 lineto 703.36444 511.33119 lineto 622.72321 525.57515 lineto closepath eoclip gsave [2.896845 0 0 1.0233611 538.73934 444.56248] concat shfill grestore grestore gsave [1.9828475 0 0 2.1805117 515.32574 433.14447] concat gsave 0.95686275 0.95686275 0.95686275 setrgbcolor newpath 70.49148 30.108479 moveto 70.49148 35.025069 66.501204 39.015345 61.584614 39.015345 curveto 56.668024 39.015345 52.677748 35.025069 52.677748 30.108479 curveto 52.677748 25.191888 56.668024 21.201612 61.584614 21.201612 curveto 66.501204 21.201612 70.49148 25.191888 70.49148 30.108479 curveto closepath eofill grestore grestore gsave 0.6156863 0.21960784 0.074509807 setrgbcolor newpath 584.70066 544.87341 moveto 584.70066 544.87341 583.865 549.92772 587.62547 554.52255 curveto 591.38594 559.11737 606.84566 574.73977 601.41387 583.92942 curveto 595.98208 593.11907 581.77585 594.03804 576.76189 587.60528 curveto 571.74792 581.17253 553.3634 572.90184 553.78123 569.68547 curveto 554.19906 566.46909 547.09594 550.3872 558.37736 549.46824 curveto 569.65877 548.54927 577.17972 540.27859 580.52236 539.81911 curveto 583.865 539.35962 585.11849 541.65704 584.70066 544.87341 curveto closepath eofill grestore gsave 0.87843138 0.80784315 0.11372549 setrgbcolor newpath 581.77585 555.44151 moveto 581.77585 555.44151 585.95415 566.46909 590.13245 572.44236 curveto 594.31076 578.41563 588.87896 586.68632 583.44717 581.17253 curveto 578.01538 575.65874 560.88434 571.5234 561.30217 566.00961 curveto 561.72 560.49582 568.82311 570.60443 570.0766 566.00961 curveto 571.33009 561.41478 561.72 550.84669 566.73396 552.22513 curveto 571.74792 553.60358 575.5084 567.38806 576.76189 559.57685 curveto 578.01538 551.76565 576.34406 544.87341 581.77585 555.44151 curveto closepath eofill grestore gsave << /ShadingType 2 /ColorSpace /DeviceRGB /Coords [13.065491 85.119431 26.982304 67.89669] /Extend [true true] /Domain [0 1] /Function << /FunctionType 3 /Functions [ << /FunctionType 2 /Domain [0 1] /C0 [0 0 0] /C1 [0 0 0] /N 1 >> ] /Domain [0 1] /Bounds [ ] /Encode [ 0 1 ] >> >> newpath 585.18255 544.61321 moveto 585.18255 544.61321 584.34689 549.66752 588.10736 554.26234 curveto 591.86783 558.85717 607.32755 574.47957 601.89575 583.66922 curveto 596.46396 592.85887 582.25773 593.77784 577.24377 587.34508 curveto 572.22981 580.91233 553.84528 572.64164 554.26311 569.42527 curveto 554.68094 566.20889 547.57783 550.127 558.85924 549.20804 curveto 570.14066 548.28907 577.6616 540.01839 581.00424 539.55891 curveto 584.34689 539.09942 585.60038 541.39684 585.18255 544.61321 curveto closepath eoclip gsave [1.6986295 0 0 1.7452532 538.73934 444.56248] concat shfill grestore grestore gsave [1.5953948 0 0 1.754435 539.61141 446.55548] concat gsave 0.87450981 0.82352942 0.44705883 setrgbcolor newpath 70.49148 30.108479 moveto 70.49148 35.025069 66.501204 39.015345 61.584614 39.015345 curveto 56.668024 39.015345 52.677748 35.025069 52.677748 30.108479 curveto 52.677748 25.191888 56.668024 21.201612 61.584614 21.201612 curveto 66.501204 21.201612 70.49148 25.191888 70.49148 30.108479 curveto closepath eofill grestore grestore gsave [1.6418859 0 0 1.8055607 538.59447 444.01461] concat gsave 0 0 0 setrgbcolor newpath 67.437697 31.126406 moveto 67.437697 34.357308 64.815516 36.979489 61.584614 36.979489 curveto 58.353712 36.979489 55.731531 34.357308 55.731531 31.126406 curveto 55.731531 27.895504 58.353712 25.273323 61.584614 25.273323 curveto 64.815516 25.273323 67.437697 27.895504 67.437697 31.126406 curveto closepath eofill grestore grestore gsave 0.27058825 0.48627451 0.05882353 setrgbcolor newpath 581.35802 532.0079 moveto 581.35802 532.0079 590.96811 531.08894 587.62547 536.60273 curveto 584.28283 542.11652 573.00141 543.95445 580.10453 546.25186 curveto 587.20764 548.54927 624.81236 549.46824 628.99066 551.76565 curveto 633.16896 554.06306 621.05189 568.30702 613.11311 565.55012 curveto 605.17434 562.79323 593.89293 551.30617 582.19368 553.1441 curveto 570.49443 554.98203 559.21302 562.33375 558.79519 554.52255 curveto 558.37736 546.71134 567.56962 534.30532 581.35802 532.0079 curveto closepath eofill grestore gsave << /ShadingType 2 /ColorSpace /DeviceRGB /Coords [9.9581957 96.715332 22.288982 86.950264] /Extend [true true] /Domain [0 1] /Function << /FunctionType 3 /Functions [ << /FunctionType 2 /Domain [0 1] /C0 [1 1 1] /C1 [1 1 1] /N 1 >> ] /Domain [0 1] /Bounds [ ] /Encode [ 0 1 ] >> >> newpath 584.91531 528.92355 moveto 584.91531 528.92355 594.12586 528.0428 590.92219 533.32734 curveto 587.71852 538.61189 576.90615 540.3734 583.71394 542.5753 curveto 590.52173 544.77719 626.56298 545.65795 630.56756 547.85984 curveto 634.57215 550.06174 622.95886 563.71348 615.35015 561.07121 curveto 607.74144 558.42894 596.92906 547.41947 585.71623 549.18098 curveto 574.5034 550.9425 563.69102 557.98856 563.29056 550.50212 curveto 562.89011 543.01568 571.70019 531.12545 584.91531 528.92355 curveto closepath eoclip gsave [2.4909379 0 0 1.1901263 538.73934 444.56248] concat shfill grestore grestore gsave 0.32156864 0.57647061 0.074509807 setrgbcolor newpath 651.5535 540.27859 moveto 651.5535 540.27859 666.17755 545.3329 657.40312 547.17083 curveto 648.62868 549.00876 626.90151 546.71134 620.63406 551.30617 curveto 614.36661 555.90099 607.26349 570.60443 612.27746 573.36133 curveto 617.29142 576.11822 630.66198 560.49582 642.36123 558.1984 curveto 654.06048 555.90099 679.13029 557.27944 680.38378 552.68462 curveto 681.63727 548.08979 657.68987 534.19383 653.09374 534.19383 curveto 648.49761 534.19383 651.5535 540.27859 651.5535 540.27859 curveto closepath eofill grestore gsave [1.5138028 0 0 1.6647094 573.78363 440.3665] concat gsave << /ShadingType 2 /ColorSpace /DeviceRGB /Coords [39.077763 45.47282 38.935726 34.73687] /Extend [true true] /Domain [0 1] /Function << /FunctionType 3 /Functions [ << /FunctionType 2 /Domain [0 1] /C0 [0 0 0] /C1 [0 0 0] /N 1 >> ] /Domain [0 1] /Bounds [ ] /Encode [ 0 1 ] >> >> newpath 51.150857 35.452599 moveto 51.150857 40.509662 47.046573 44.613946 41.98951 44.613946 curveto 36.932446 44.613946 32.828162 40.509662 32.828162 35.452599 curveto 32.828162 30.395535 36.932446 26.291251 41.98951 26.291251 curveto 47.046573 26.291251 51.150857 30.395535 51.150857 35.452599 curveto closepath eoclip shfill grestore grestore gsave [1.9194088 0 0 2.110749 526.87749 437.18904] concat gsave 0.95686275 0.95686275 0.95686275 setrgbcolor newpath 51.150857 35.452599 moveto 51.150857 40.509662 47.046573 44.613946 41.98951 44.613946 curveto 36.932446 44.613946 32.828162 40.509662 32.828162 35.452599 curveto 32.828162 30.395535 36.932446 26.291251 41.98951 26.291251 curveto 47.046573 26.291251 51.150857 30.395535 51.150857 35.452599 curveto closepath eofill grestore grestore gsave [1.5138028 0 0 1.6647094 544.11762 452.31315] concat gsave 0.87450981 0.82352942 0.44705883 setrgbcolor newpath 51.150857 35.452599 moveto 51.150857 40.509662 47.046573 44.613946 41.98951 44.613946 curveto 36.932446 44.613946 32.828162 40.509662 32.828162 35.452599 curveto 32.828162 30.395535 36.932446 26.291251 41.98951 26.291251 curveto 47.046573 26.291251 51.150857 30.395535 51.150857 35.452599 curveto closepath eofill grestore grestore gsave [1.5138028 0 0 1.6647094 544.11762 451.85354] concat gsave << /ShadingType 2 /ColorSpace /DeviceRGB /Coords [39.077763 45.47282 38.935726 34.73687] /Extend [true true] /Domain [0 1] /Function << /FunctionType 3 /Functions [ << /FunctionType 2 /Domain [0 1] /C0 [0 0 0] /C1 [0 0 0] /N 1 >> ] /Domain [0 1] /Bounds [ ] /Encode [ 0 1 ] >> >> newpath 51.150857 35.452599 moveto 51.150857 40.509662 47.046573 44.613946 41.98951 44.613946 curveto 36.932446 44.613946 32.828162 40.509662 32.828162 35.452599 curveto 32.828162 30.395535 36.932446 26.291251 41.98951 26.291251 curveto 47.046573 26.291251 51.150857 30.395535 51.150857 35.452599 curveto closepath eoclip shfill grestore grestore gsave [1.6418859 0 0 1.8055607 539.38094 444.75289] concat gsave 0 0 0 setrgbcolor newpath 48.351557 36.216045 moveto 48.351557 39.587421 45.615368 42.32361 42.243992 42.32361 curveto 38.872616 42.32361 36.136427 39.587421 36.136427 36.216045 curveto 36.136427 32.84467 38.872616 30.10848 42.243992 30.10848 curveto 45.615368 30.10848 48.351557 32.84467 48.351557 36.216045 curveto closepath eofill grestore grestore gsave [1.2624477 0 0 1.3882974 552.1086 456.0066] concat gsave << /ShadingType 3 /ColorSpace /DeviceRGB /Coords [42.243992 36.216045 0 42.243992 36.216045 6.1075649] /Extend [true true] /Domain [0 1] /Function << /FunctionType 3 /Functions [ << /FunctionType 2 /Domain [0 1] /C0 [1 1 1] /C1 [1 1 1] /N 1 >> ] /Domain [0 1] /Bounds [ ] /Encode [ 0 1 ] >> >> newpath 48.351557 36.216045 moveto 48.351557 39.587421 45.615368 42.32361 42.243992 42.32361 curveto 38.872616 42.32361 36.136427 39.587421 36.136427 36.216045 curveto 36.136427 32.84467 38.872616 30.10848 42.243992 30.10848 curveto 45.615368 30.10848 48.351557 32.84467 48.351557 36.216045 curveto closepath eoclip shfill grestore grestore gsave [1.2624477 0 0 1.3882974 582.90721 446.3383] concat gsave << /ShadingType 3 /ColorSpace /DeviceRGB /Coords [42.243992 36.216045 0 42.243992 36.216045 6.1075649] /Extend [true true] /Domain [0 1] /Function << /FunctionType 3 /Functions [ << /FunctionType 2 /Domain [0 1] /C0 [1 1 1] /C1 [1 1 1] /N 1 >> ] /Domain [0 1] /Bounds [ ] /Encode [ 0 1 ] >> >> newpath 48.351557 36.216045 moveto 48.351557 39.587421 45.615368 42.32361 42.243992 42.32361 curveto 38.872616 42.32361 36.136427 39.587421 36.136427 36.216045 curveto 36.136427 32.84467 38.872616 30.10848 42.243992 30.10848 curveto 45.615368 30.10848 48.351557 32.84467 48.351557 36.216045 curveto closepath eoclip shfill grestore grestore gsave << /ShadingType 2 /ColorSpace /DeviceRGB /Coords [51.998035 87.448608 44.157574 78.630959] /Extend [true true] /Domain [0 1] /Function << /FunctionType 3 /Functions [ << /FunctionType 2 /Domain [0 1] /C0 [1 1 1] /C1 [1 1 1] /N 1 >> ] /Domain [0 1] /Bounds [ ] /Encode [ 0 1 ] >> >> newpath 649.96666 539.48867 moveto 649.96666 539.48867 664.59071 544.54298 655.81627 546.38091 curveto 647.04185 548.21884 625.31467 545.92142 619.04722 550.51625 curveto 612.77977 555.11107 605.67665 569.81451 610.69062 572.57141 curveto 615.70458 575.3283 629.07514 559.7059 640.77439 557.40848 curveto 652.47364 555.11107 677.54345 556.48952 678.79694 551.8947 curveto 680.05042 547.29987 656.10303 533.40391 651.5069 533.40391 curveto 646.91076 533.40391 649.96666 539.48867 649.96666 539.48867 curveto closepath eoclip gsave [2.2898233 0 0 1.2946538 538.73934 444.56248] concat shfill grestore grestore gsave [1.400681 -0.042370668 0.03852975 1.5403108 548.74078 452.34447] concat gsave << /ShadingType 2 /ColorSpace /DeviceRGB /Coords [50.072014 13.720966 26.487234 13.768328] /Extend [true true] /Domain [0 1] /Function << /FunctionType 3 /Functions [ << /FunctionType 2 /Domain [0 1] /C0 [1 1 1] /C1 [1 1 1] /N 1 >> ] /Domain [0 1] /Bounds [ ] /Encode [ 0 1 ] >> >> newpath 24.859391 31.907937 moveto 23.419824 24.350211 24.964801 11.778293 30.054438 8.9789918 curveto 35.144076 6.1796912 40.379124 5.3034583 41.760605 9.7424375 curveto 43.243834 14.508354 39.448349 16.768623 34.704351 20.597833 curveto 29.745701 24.600304 28.340109 28.103497 24.859391 31.907937 curveto closepath eoclip gsave [0.838005 0 0 1.19331 0 0] concat shfill grestore grestore grestore gsave << /ShadingType 2 /ColorSpace /DeviceRGB /Coords [84.674622 134.8858 79.578964 116.69227] /Extend [true true] /Domain [0 1] /Function << /FunctionType 3 /Functions [ << /FunctionType 2 /Domain [0 1] /C0 [1 1 1] /C1 [1 1 1] /N 1 >> ] /Domain [0 1] /Bounds [ ] /Encode [ 0 1 ] >> >> newpath 616.907 580.83088 moveto 617.32484 578.07397 621.08532 558.31616 625.68146 555.09978 curveto 630.27761 551.88339 627.35279 558.31616 629.02412 561.53256 curveto 630.69544 564.74894 639.05207 551.88339 639.05207 557.3972 curveto 639.05207 562.91101 631.5311 566.58688 636.54508 565.6679 curveto 641.55906 564.74894 655.3475 560.1541 648.24436 566.12739 curveto 641.14122 572.10068 637.38074 580.83088 632.36677 578.07397 curveto 627.35279 575.31707 625.68146 584.04726 621.50315 584.04726 curveto 617.32484 584.04726 616.48917 584.04726 616.907 580.83088 curveto closepath eoclip gsave [1.2747221 0 0 1.1373574 531.37626 430.58177] concat shfill grestore grestore gsave << /ShadingType 2 /ColorSpace /DeviceRGB /Coords [36.185604 131.57237 34.983452 109.63145] /Extend [true true] /Domain [0 1] /Function << /FunctionType 3 /Functions [ << /FunctionType 2 /Domain [0 1] /C0 [1 1 1] /C1 [1 1 1] /N 1 >> ] /Domain [0 1] /Bounds [ ] /Encode [ 0 1 ] >> >> newpath 581.39134 555.55926 moveto 581.39134 555.55926 585.56965 566.58688 589.74796 572.56017 curveto 593.92628 578.53345 588.49447 586.80416 583.06266 581.29036 curveto 577.63086 575.77656 560.49977 571.6412 560.9176 566.12739 curveto 561.33543 560.61358 568.43856 570.72224 569.69206 566.12739 curveto 570.94555 561.53256 561.33543 550.96442 566.34941 552.34288 curveto 571.36338 553.72133 575.12387 567.50584 576.37736 559.69462 curveto 577.63086 551.88339 575.95953 544.99114 581.39134 555.55926 curveto closepath eoclip gsave [1.1551703 0 0 1.2550639 531.37626 430.58177] concat shfill grestore grestore gsave [0.3512975 0 0 0.3512975 625.25272 503.74669] concat gsave [0 -0.525214 0.525214 0 11.42181 267.4213] concat gsave 0.34117648 0.63529414 0.05882353 setrgbcolor newpath 428.62836 222.16092 moveto 428.62836 323.67816 346.23755 406.06897 244.72031 406.06897 curveto 143.20306 406.06897 60.812256 323.67816 60.812256 222.16092 curveto 60.812256 120.64368 143.20306 38.252869 244.72031 38.252869 curveto 346.23755 38.252869 428.62836 120.64368 428.62836 222.16092 curveto closepath fill grestore 0.34117648 0.63529414 0.05882353 setrgbcolor [] 0 setdash 10.839739 setlinewidth 1 setlinejoin 0 setlinecap newpath 428.62836 222.16092 moveto 428.62836 323.67816 346.23755 406.06897 244.72031 406.06897 curveto 143.20306 406.06897 60.812256 323.67816 60.812256 222.16092 curveto 60.812256 120.64368 143.20306 38.252869 244.72031 38.252869 curveto 346.23755 38.252869 428.62836 120.64368 428.62836 222.16092 curveto closepath stroke grestore gsave [0 -0.525214 0.525214 0 11.42181 267.4213] concat gsave << /ShadingType 2 /ColorSpace /DeviceRGB /Coords [60.812256 222.16092 428.62836 222.16092] /Extend [true true] /Domain [0 1] /Function << /FunctionType 3 /Functions [ << /FunctionType 2 /Domain [0 1] /C0 [0.34509805 0.28627452 0.90980393] /C1 [0.12941177 0.074509807 0.6156863] /N 1 >> ] /Domain [0 1] /Bounds [ ] /Encode [ 0 1 ] >> >> newpath 428.62836 222.16092 moveto 428.62836 323.67816 346.23755 406.06897 244.72031 406.06897 curveto 143.20306 406.06897 60.812256 323.67816 60.812256 222.16092 curveto 60.812256 120.64368 143.20306 38.252869 244.72031 38.252869 curveto 346.23755 38.252869 428.62836 120.64368 428.62836 222.16092 curveto closepath clip shfill grestore grestore gsave [0 -0.525214 0.525214 0 11.42181 267.4213] concat gsave << /ShadingType 3 /ColorSpace /DeviceRGB /Coords [244.72031 222.16092 0 244.72031 222.16092 183.90805] /Extend [true true] /Domain [0 1] /Function << /FunctionType 3 /Functions [ << /FunctionType 2 /Domain [0 1] /C0 [1 1 1] /C1 [0.11764706 0.074509807 0.6156863] /N 1 >> << /FunctionType 2 /Domain [0 1] /C0 [0.11764706 0.074509807 0.6156863] /C1 [0.34509805 0.28627452 0.90980393] /N 1 >> ] /Domain [0 1] /Bounds [ 0.80000001 ] /Encode [ 0 1 0 1 ] >> >> newpath 428.62836 222.16092 moveto 428.62836 323.67816 346.23755 406.06897 244.72031 406.06897 curveto 143.20306 406.06897 60.812256 323.67816 60.812256 222.16092 curveto 60.812256 120.64368 143.20306 38.252869 244.72031 38.252869 curveto 346.23755 38.252869 428.62836 120.64368 428.62836 222.16092 curveto closepath clip shfill grestore grestore gsave [0 0.382405 0.382405 0 43.14837 21.00481] concat gsave << /ShadingType 3 /ColorSpace /DeviceRGB /Coords [49.709621 222.16092 0 49.709621 222.16092 183.90805] /Extend [true true] /Domain [0 1] /Function << /FunctionType 3 /Functions [ << /FunctionType 2 /Domain [0 1] /C0 [1 1 1] /C1 [1 1 1] /N 1 >> ] /Domain [0 1] /Bounds [ ] /Encode [ 0 1 ] >> >> newpath 428.62836 222.16092 moveto 428.62836 323.67816 346.23755 406.06897 244.72031 406.06897 curveto 143.20306 406.06897 60.812256 323.67816 60.812256 222.16092 curveto 60.812256 120.64368 143.20306 38.252869 244.72031 38.252869 curveto 346.23755 38.252869 428.62836 120.64368 428.62836 222.16092 curveto closepath clip gsave [1.353938 0 0 1.353938 -33.88875 -78.63119] concat shfill grestore grestore grestore gsave [0 -0.306725 0.412392 0 36.48655 251.3615] concat gsave << /ShadingType 3 /ColorSpace /DeviceRGB /Coords [69.944862 222.16092 0 69.944862 222.16092 183.90805] /Extend [true true] /Domain [0 1] /Function << /FunctionType 3 /Functions [ << /FunctionType 2 /Domain [0 1] /C0 [1 1 1] /C1 [1 1 1] /N 1 >> ] /Domain [0 1] /Bounds [ ] /Encode [ 0 1 ] >> >> newpath 428.62836 222.16092 moveto 428.62836 323.67816 346.23755 406.06897 244.72031 406.06897 curveto 143.20306 406.06897 60.812256 323.67816 60.812256 222.16092 curveto 60.812256 120.64368 143.20306 38.252869 244.72031 38.252869 curveto 346.23755 38.252869 428.62836 120.64368 428.62836 222.16092 curveto closepath clip gsave [1.353938 0 0 1.353938 -33.88875 -78.63119] concat shfill grestore grestore grestore gsave [0.525214 0 0 0.525214 -0.426697 22.2088] concat gsave << /ShadingType 2 /ColorSpace /DeviceRGB /Coords [98 240.92043 420 240.92043] /Extend [true true] /Domain [0 1] /Function << /FunctionType 3 /Functions [ << /FunctionType 2 /Domain [0 1] /C0 [1 1 1] /C1 [1 1 1] /N 1 >> ] /Domain [0 1] /Bounds [ ] /Encode [ 0 1 ] >> >> newpath 201.58219 398.66524 moveto 201.58219 398.66524 25.59643 220.69905 234.16166 39.888097 curveto -1.634599 220.03851 202.12567 397.72391 201.58219 398.66524 curveto closepath eoclip gsave [0.543478 -0.941332 0.941332 0.543478 -156.6701 314.8289] concat shfill grestore grestore gsave << /ShadingType 2 /ColorSpace /DeviceRGB /Coords [98 240.92043 420 240.92043] /Extend [true true] /Domain [0 1] /Function << /FunctionType 3 /Functions [ << /FunctionType 2 /Domain [0 1] /C0 [1 1 1] /C1 [1 1 1] /N 1 >> ] /Domain [0 1] /Bounds [ ] /Encode [ 0 1 ] >> >> newpath 418.06183 185.18557 moveto 418.06183 185.18557 240.09557 9.1998797 59.284695 217.76518 curveto 239.43502 -18.031148 417.12049 185.72905 418.06183 185.18557 curveto closepath eoclip gsave [-0.941332 0.543478 0.543478 0.941332 334.2253 -173.0667] concat shfill grestore grestore gsave << /ShadingType 2 /ColorSpace /DeviceRGB /Coords [98 240.92043 420 240.92043] /Extend [true true] /Domain [0 1] /Function << /FunctionType 3 /Functions [ << /FunctionType 2 /Domain [0 1] /C0 [1 1 1] /C1 [1 1 1] /N 1 >> ] /Domain [0 1] /Bounds [ ] /Encode [ 0 1 ] >> >> newpath 66.93794 267.02123 moveto 66.93794 267.02123 244.9042 443.00692 425.71507 234.44162 curveto 245.56475 470.23795 67.879272 266.47776 66.93794 267.02123 curveto closepath eoclip gsave [0.941332 -0.543478 -0.543478 -0.941332 150.7744 625.2735] concat shfill grestore grestore gsave << /ShadingType 2 /ColorSpace /DeviceRGB /Coords [98 240.92043 420 240.92043] /Extend [true true] /Domain [0 1] /Function << /FunctionType 3 /Functions [ << /FunctionType 2 /Domain [0 1] /C0 [1 1 1] /C1 [1 1 1] /N 1 >> ] /Domain [0 1] /Bounds [ ] /Encode [ 0 1 ] >> >> newpath 283.41758 47.541558 moveto 283.41758 47.541558 459.40333 225.50774 250.83811 406.3187 curveto 486.63436 226.16829 282.8741 48.482895 283.41758 47.541558 curveto closepath eoclip gsave [-0.543478 0.941332 -0.941332 -0.543478 641.6699 131.3779] concat shfill grestore grestore gsave << /ShadingType 3 /ColorSpace /DeviceRGB /Coords [246.35255 226.88303 0 246.35255 226.88303 154.3577] /Extend [true true] /Domain [0 1] /Function << /FunctionType 3 /Functions [ << /FunctionType 2 /Domain [0 1] /C0 [1 1 1] /C1 [1 1 1] /N 1 >> ] /Domain [0 1] /Bounds [ ] /Encode [ 0 1 ] >> >> newpath 92 316 moveto 92 316 262.42047 243.53212 400.71024 137.76606 curveto 239 206 91 316 92 316 curveto closepath eoclip gsave [1 -0.57734 0.12401 0.214795 -28.13556 320.3787] concat shfill grestore grestore gsave << /ShadingType 3 /ColorSpace /DeviceRGB /Coords [246.35255 226.88303 0 246.35255 226.88303 154.3577] /Extend [true true] /Domain [0 1] /Function << /FunctionType 3 /Functions [ << /FunctionType 2 /Domain [0 1] /C0 [1 1 1] /C1 [1 1 1] /N 1 >> ] /Domain [0 1] /Bounds [ ] /Encode [ 0 1 ] >> >> newpath 335.46957 381.23563 moveto 335.46957 381.23563 263.00169 210.81516 157.23563 72.525391 curveto 225.46957 234.23563 335.46957 382.23563 335.46957 381.23563 curveto closepath eoclip gsave [-0.57734 -1 0.214795 -0.12401 339.8483 501.3712] concat shfill grestore grestore grestore gsave [0.983093 0 0 0.983093 -24.81549 -4.294319] concat gsave << /ShadingType 3 /ColorSpace /DeviceRGB /Coords [156.5 148.5 0 156.5 148.5 19.5] /Extend [true true] /Domain [0 1] /Function << /FunctionType 3 /Functions [ << /FunctionType 2 /Domain [0 1] /C0 [1 1 1] /C1 [1 1 1] /N 1 >> << /FunctionType 2 /Domain [0 1] /C0 [1 1 1] /C1 [1 1 1] /N 1 >> ] /Domain [0 1] /Bounds [ 0.34999999 ] /Encode [ 0 1 0 1 ] >> >> newpath 176 148.5 moveto 176 159.264 167.264 168 156.5 168 curveto 145.736 168 137 159.264 137 148.5 curveto 137 137.736 145.736 129 156.5 129 curveto 167.264 129 176 137.736 176 148.5 curveto closepath clip shfill grestore grestore gsave [0.417478 0 0 0.417478 112.5483 29.80421] concat gsave << /ShadingType 3 /ColorSpace /DeviceRGB /Coords [156.5 148.5 0 156.5 148.5 19.5] /Extend [true true] /Domain [0 1] /Function << /FunctionType 3 /Functions [ << /FunctionType 2 /Domain [0 1] /C0 [1 1 1] /C1 [1 1 1] /N 1 >> << /FunctionType 2 /Domain [0 1] /C0 [1 1 1] /C1 [1 1 1] /N 1 >> ] /Domain [0 1] /Bounds [ 0.34999999 ] /Encode [ 0 1 0 1 ] >> >> newpath 176 148.5 moveto 176 159.264 167.264 168 156.5 168 curveto 145.736 168 137 159.264 137 148.5 curveto 137 137.736 145.736 129 156.5 129 curveto 167.264 129 176 137.736 176 148.5 curveto closepath clip shfill grestore grestore gsave [0.255874 0 0 0.255874 157.2722 63.78154] concat gsave << /ShadingType 3 /ColorSpace /DeviceRGB /Coords [156.5 148.5 0 156.5 148.5 19.5] /Extend [true true] /Domain [0 1] /Function << /FunctionType 3 /Functions [ << /FunctionType 2 /Domain [0 1] /C0 [1 1 1] /C1 [1 1 1] /N 1 >> << /FunctionType 2 /Domain [0 1] /C0 [1 1 1] /C1 [1 1 1] /N 1 >> ] /Domain [0 1] /Bounds [ 0.34999999 ] /Encode [ 0 1 0 1 ] >> >> newpath 176 148.5 moveto 176 159.264 167.264 168 156.5 168 curveto 145.736 168 137 159.264 137 148.5 curveto 137 137.736 145.736 129 156.5 129 curveto 167.264 129 176 137.736 176 148.5 curveto closepath clip shfill grestore grestore gsave [0.525214 0 0 0.525214 15.85494 9.603656] concat gsave << /ShadingType 3 /ColorSpace /DeviceRGB /Coords [156.5 148.5 0 156.5 148.5 19.5] /Extend [true true] /Domain [0 1] /Function << /FunctionType 3 /Functions [ << /FunctionType 2 /Domain [0 1] /C0 [1 1 1] /C1 [1 1 1] /N 1 >> << /FunctionType 2 /Domain [0 1] /C0 [1 1 1] /C1 [1 1 1] /N 1 >> ] /Domain [0 1] /Bounds [ 0.34999999 ] /Encode [ 0 1 0 1 ] >> >> newpath 176 148.5 moveto 176 159.264 167.264 168 156.5 168 curveto 145.736 168 137 159.264 137 148.5 curveto 137 137.736 145.736 129 156.5 129 curveto 167.264 129 176 137.736 176 148.5 curveto closepath clip shfill grestore grestore gsave [0.525214 0 0 0.525214 100.9397 30.61223] concat gsave << /ShadingType 3 /ColorSpace /DeviceRGB /Coords [156.5 148.5 0 156.5 148.5 19.5] /Extend [true true] /Domain [0 1] /Function << /FunctionType 3 /Functions [ << /FunctionType 2 /Domain [0 1] /C0 [1 1 1] /C1 [1 1 1] /N 1 >> << /FunctionType 2 /Domain [0 1] /C0 [1 1 1] /C1 [1 1 1] /N 1 >> ] /Domain [0 1] /Bounds [ 0.34999999 ] /Encode [ 0 1 0 1 ] >> >> newpath 176 148.5 moveto 176 159.264 167.264 168 156.5 168 curveto 145.736 168 137 159.264 137 148.5 curveto 137 137.736 145.736 129 156.5 129 curveto 167.264 129 176 137.736 176 148.5 curveto closepath clip shfill grestore grestore gsave [0.525214 0 0 0.525214 76.2546 115.6969] concat gsave << /ShadingType 3 /ColorSpace /DeviceRGB /Coords [156.5 148.5 0 156.5 148.5 19.5] /Extend [true true] /Domain [0 1] /Function << /FunctionType 3 /Functions [ << /FunctionType 2 /Domain [0 1] /C0 [1 1 1] /C1 [1 1 1] /N 1 >> << /FunctionType 2 /Domain [0 1] /C0 [1 1 1] /C1 [1 1 1] /N 1 >> ] /Domain [0 1] /Bounds [ 0.34999999 ] /Encode [ 0 1 0 1 ] >> >> newpath 176 148.5 moveto 176 159.264 167.264 168 156.5 168 curveto 145.736 168 137 159.264 137 148.5 curveto 137 137.736 145.736 129 156.5 129 curveto 167.264 129 176 137.736 176 148.5 curveto closepath clip shfill grestore grestore gsave [0.525214 0 0 0.525214 -10.93098 96.264] concat gsave << /ShadingType 3 /ColorSpace /DeviceRGB /Coords [156.5 148.5 0 156.5 148.5 19.5] /Extend [true true] /Domain [0 1] /Function << /FunctionType 3 /Functions [ << /FunctionType 2 /Domain [0 1] /C0 [1 1 1] /C1 [1 1 1] /N 1 >> << /FunctionType 2 /Domain [0 1] /C0 [1 1 1] /C1 [1 1 1] /N 1 >> ] /Domain [0 1] /Bounds [ 0.34999999 ] /Encode [ 0 1 0 1 ] >> >> newpath 176 148.5 moveto 176 159.264 167.264 168 156.5 168 curveto 145.736 168 137 159.264 137 148.5 curveto 137 137.736 145.736 129 156.5 129 curveto 167.264 129 176 137.736 176 148.5 curveto closepath clip shfill grestore grestore gsave [0.417478 0 0 0.417478 109.9222 127.494] concat gsave << /ShadingType 3 /ColorSpace /DeviceRGB /Coords [156.5 148.5 0 156.5 148.5 19.5] /Extend [true true] /Domain [0 1] /Function << /FunctionType 3 /Functions [ << /FunctionType 2 /Domain [0 1] /C0 [1 1 1] /C1 [1 1 1] /N 1 >> << /FunctionType 2 /Domain [0 1] /C0 [1 1 1] /C1 [1 1 1] /N 1 >> ] /Domain [0 1] /Bounds [ 0.34999999 ] /Encode [ 0 1 0 1 ] >> >> newpath 176 148.5 moveto 176 159.264 167.264 168 156.5 168 curveto 145.736 168 137 159.264 137 148.5 curveto 137 137.736 145.736 129 156.5 129 curveto 167.264 129 176 137.736 176 148.5 curveto closepath clip shfill grestore grestore gsave [0.255874 0 0 0.255874 123.1333 167.7739] concat gsave << /ShadingType 3 /ColorSpace /DeviceRGB /Coords [156.5 148.5 0 156.5 148.5 19.5] /Extend [true true] /Domain [0 1] /Function << /FunctionType 3 /Functions [ << /FunctionType 2 /Domain [0 1] /C0 [1 1 1] /C1 [1 1 1] /N 1 >> << /FunctionType 2 /Domain [0 1] /C0 [1 1 1] /C1 [1 1 1] /N 1 >> ] /Domain [0 1] /Bounds [ 0.34999999 ] /Encode [ 0 1 0 1 ] >> >> newpath 176 148.5 moveto 176 159.264 167.264 168 156.5 168 curveto 145.736 168 137 159.264 137 148.5 curveto 137 137.736 145.736 129 156.5 129 curveto 167.264 129 176 137.736 176 148.5 curveto closepath clip shfill grestore grestore gsave [0.417478 0 0 0.417478 13.28276 129.5949] concat gsave << /ShadingType 3 /ColorSpace /DeviceRGB /Coords [156.5 148.5 0 156.5 148.5 19.5] /Extend [true true] /Domain [0 1] /Function << /FunctionType 3 /Functions [ << /FunctionType 2 /Domain [0 1] /C0 [1 1 1] /C1 [1 1 1] /N 1 >> << /FunctionType 2 /Domain [0 1] /C0 [1 1 1] /C1 [1 1 1] /N 1 >> ] /Domain [0 1] /Bounds [ 0.34999999 ] /Encode [ 0 1 0 1 ] >> >> newpath 176 148.5 moveto 176 159.264 167.264 168 156.5 168 curveto 145.736 168 137 159.264 137 148.5 curveto 137 137.736 145.736 129 156.5 129 curveto 167.264 129 176 137.736 176 148.5 curveto closepath clip shfill grestore grestore gsave [0.417478 0 0 0.417478 13.28276 31.90504] concat gsave << /ShadingType 3 /ColorSpace /DeviceRGB /Coords [156.5 148.5 0 156.5 148.5 19.5] /Extend [true true] /Domain [0 1] /Function << /FunctionType 3 /Functions [ << /FunctionType 2 /Domain [0 1] /C0 [1 1 1] /C1 [1 1 1] /N 1 >> << /FunctionType 2 /Domain [0 1] /C0 [1 1 1] /C1 [1 1 1] /N 1 >> ] /Domain [0 1] /Bounds [ 0.34999999 ] /Encode [ 0 1 0 1 ] >> >> newpath 176 148.5 moveto 176 159.264 167.264 168 156.5 168 curveto 145.736 168 137 159.264 137 148.5 curveto 137 137.736 145.736 129 156.5 129 curveto 167.264 129 176 137.736 176 148.5 curveto closepath clip shfill grestore grestore gsave [0.255874 0 0 0.255874 19.66611 143.614] concat gsave << /ShadingType 3 /ColorSpace /DeviceRGB /Coords [156.5 148.5 0 156.5 148.5 19.5] /Extend [true true] /Domain [0 1] /Function << /FunctionType 3 /Functions [ << /FunctionType 2 /Domain [0 1] /C0 [1 1 1] /C1 [1 1 1] /N 1 >> << /FunctionType 2 /Domain [0 1] /C0 [1 1 1] /C1 [1 1 1] /N 1 >> ] /Domain [0 1] /Bounds [ 0.34999999 ] /Encode [ 0 1 0 1 ] >> >> newpath 176 148.5 moveto 176 159.264 167.264 168 156.5 168 curveto 145.736 168 137 159.264 137 148.5 curveto 137 137.736 145.736 129 156.5 129 curveto 167.264 129 176 137.736 176 148.5 curveto closepath clip shfill grestore grestore gsave [0.255874 0 0 0.255874 50.65376 36.99558] concat gsave << /ShadingType 3 /ColorSpace /DeviceRGB /Coords [156.5 148.5 0 156.5 148.5 19.5] /Extend [true true] /Domain [0 1] /Function << /FunctionType 3 /Functions [ << /FunctionType 2 /Domain [0 1] /C0 [1 1 1] /C1 [1 1 1] /N 1 >> << /FunctionType 2 /Domain [0 1] /C0 [1 1 1] /C1 [1 1 1] /N 1 >> ] /Domain [0 1] /Bounds [ 0.34999999 ] /Encode [ 0 1 0 1 ] >> >> newpath 176 148.5 moveto 176 159.264 167.264 168 156.5 168 curveto 145.736 168 137 159.264 137 148.5 curveto 137 137.736 145.736 129 156.5 129 curveto 167.264 129 176 137.736 176 148.5 curveto closepath clip shfill grestore grestore grestore gsave 0.72156864 0.20392157 0.015686275 setrgbcolor newpath 621.46972 524.65618 moveto 703.36444 498.92517 lineto 664.0884 533.38635 lineto 621.46972 524.65618 lineto closepath eofill grestore gsave << /ShadingType 2 /ColorSpace /DeviceRGB /Coords [58.108067 60.616997 42.782681 60.616997] /Extend [true true] /Domain [0 1] /Function << /FunctionType 3 /Functions [ << /FunctionType 2 /Domain [0 1] /C0 [1 1 1] /C1 [1 1 1] /N 1 >> ] /Domain [0 1] /Bounds [ ] /Encode [ 0 1 ] >> >> newpath 630.28777 523.32068 moveto 697.733 502.12964 lineto 665.38682 530.5105 lineto 630.28777 523.32068 lineto closepath eoclip gsave [2.6542399 0 0 1.1169018 538.73934 444.56248] concat shfill grestore grestore grestore grestore showpage %%EOF elyxer-1.2.5/forks/jras-elyxer/test/branches-1-5.lyx0000644000175000017500000000447212117061342021534 0ustar chennochenno#LyX 1.5.7 created this file. For more info see http://www.lyx.org/ \lyxformat 276 \begin_document \begin_header \textclass article \begin_preamble % eLyXer -- convert LyX source files to HTML output. % % Copyright (C) 2009-2010 Alex Fernández % % This program is free software: 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 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 % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . \end_preamble \language english \inputencoding auto \font_roman default \font_sans default \font_typewriter default \font_default_family default \font_sc false \font_osf false \font_sf_scale 100 \font_tt_scale 100 \graphics default \paperfontsize default \spacing single \papersize default \use_geometry false \use_amsmath 1 \use_esint 1 \cite_engine basic \use_bibtopic false \paperorientation portrait \branch First \selected 0 \color #faf0e6 \end_branch \branch Second \selected 1 \color #fa6a6a \end_branch \secnumdepth 3 \tocdepth 3 \paragraph_separation skip \defskip medskip \quotes_language english \papercolumns 1 \papersides 1 \paperpagestyle default \tracking_changes false \output_changes false \author "" \author "" \end_header \begin_body \begin_layout Title Document with branches \end_layout \begin_layout Standard First some stupid text. \end_layout \begin_layout Standard \begin_inset Branch First status collapsed \begin_layout Standard In this first branch, without color, we carn write whatever we want: it is inactive. \end_layout \end_inset \end_layout \begin_layout Standard Now some intermediately stupid text. \end_layout \begin_layout Standard \begin_inset Branch Second status open \begin_layout Standard In this second branch, reddish, we have to be more careful: it is active. \end_layout \end_inset \end_layout \begin_layout Standard Finally some terminally stupid text. \end_layout \end_body \end_document elyxer-1.2.5/forks/jras-elyxer/test/bibtex-good.html0000644000175000017500000002150012117061342021771 0ustar chennochenno BibTeX Test

BibTeX Test

1 Ethel the Frog

Some random text. With a random reference [2].

2 The Other Other Operation

And a book to prove that we have read one (untrue): [1].

3 Spiny Norman

We are going to need a reference here [3].

4 In the Grillomat

There are two kinds of vancouver references: with volume information[4] and without[5].

5 Alpha, Mr Belpit

Two references in one: [BB69, PB69]. Also, a repeated reference[BB69].

References

[1] J.M. Cleese, M.E. Palin. And Now for Something Different from Voigtländer. Python Monty Editions, 1971.

[2] S.W. Colonel. Summary for Year 1969. Journal of the Society for Putting Things onto Other Things, 457(1):1348—1350, 1969.

[3] Z.X. Pudey. My Silly Walks. Private Walkings, 1970.

References

[4] J. Linkman. A Little Hors d'Oeuvres. Just The Words, 1969;300(3):1—300. URL: http://www.ibras.dk/montypython/episode18.htm.

[5] J. Linkman. Our Main Course: Prawn Salad. Just The Words, 1969. URL: http://www.ibras.dk/montypython/episode18.htm.

References

[BB69] B. Bishop, W. Belpit. Your legs are so swollen. Just The Words, 1969. http://www.ibras.dk/montypython/episode18.htm. bibtex-good.html. Found on http://www.ibras.dk/montypython/episode18.htm.

[PB69] E. Praline, B. Brooky. The population explosion. Just The Words, 1(1): 2—4, 1969. http://www.ibras.dk/montypython/episode18.htm.

References

[Nam10] Latin1 Accents !`©ª®º?` ÀÁÂÃÄÅÅÆÇÈÉÊËÌÍÎÏÐÑ ÒÓÔÕÖØÙÚÛÜÝÞ ßàáâãäåæçèéêë ìı̀ı̀ı́ı̂ı̈ðñ òóôõöøùúûüýþÿ in Name. Latin1 Accents !`©ª®º?` ÀÁÂÃÄÅÅÆÇÈÉÊËÌÍÎÏÐÑ ÒÓÔÕÖØÙÚÛÜÝÞ ßàáâãäåæçèéêë ìı̀ı̀ı́ı̂ı̈ðñ òóôõöøùúûüýþÿ in title. Test, 2010.

[Cen34] Somebody in the Century. Finding ϵn decimals of the number π. About ζ in π things, 1934. According to The Society for

ϵn
decimals of the number
π
, only 1 in 2n dentists read this magazine.

elyxer-1.2.5/forks/jras-elyxer/test/abstract.lyx0000644000175000017500000000233712117061342021250 0ustar chennochenno#LyX 1.6.7 created this file. For more info see http://www.lyx.org/ \lyxformat 345 \begin_document \begin_header \textclass article \use_default_options true \begin_modules theorems-ams eqs-within-sections figs-within-sections \end_modules \language english \inputencoding auto \font_roman default \font_sans default \font_typewriter default \font_default_family default \font_sc false \font_osf false \font_sf_scale 100 \font_tt_scale 100 \graphics default \paperfontsize default \spacing single \use_hyperref false \papersize default \use_geometry false \use_amsmath 1 \use_esint 1 \cite_engine basic \use_bibtopic false \paperorientation portrait \secnumdepth 3 \tocdepth 3 \paragraph_separation indent \defskip medskip \quotes_language english \papercolumns 1 \papersides 1 \paperpagestyle default \tracking_changes false \output_changes false \author "" \author "" \end_header \begin_body \begin_layout Title Abstract Test \end_layout \begin_layout Abstract This document is a test of the abstract capabilities of LyX. \end_layout \begin_layout Abstract When exported in LyX, this abstract should be shown contiguous. \end_layout \begin_layout Standard Apart from the abstract, not much more yet. \end_layout \end_body \end_document elyxer-1.2.5/forks/jras-elyxer/test/appendix-1-6-frameset.html0000644000175000017500000000025112117061342023503 0ustar chennochenno elyxer-1.2.5/forks/jras-elyxer/test/with images-1-5-inkscape-good.html0000644000175000017500000000310112117061342025005 0ustar chennochenno Images Tests

Images Tests

figure elyxer-svg.png First image: regular path.
figure elyxer-svg.png Second image: convoluted path.
figure docs/elyxer.png Third image: from another directory.
figure mini-elyxer.jpg Fourth image: from a JPEG file.
figure square.png Fifth image: from a PNG file.
elyxer-1.2.5/forks/jras-elyxer/test/table-1-6-good.html0000644000175000017500000002336412117061342022116 0ustar chennochenno Table Test

Table Test

Alex Fernández (elyxer@gmail.com)

This test may contain several tables.

1 Longtable

The first one comes straight from the LyX User Guide, shortened.
Example Phone List (ignore the names)
NAME TEL.
Annovi Silvia 555
Bertoli Stefano 555
Bozzi Walter 555
Cachia Maurizio 555
Cinquemani Giusi 555
Colin Bernard 555
Dal Bosco Carolina 555
Dalpiaz Annamaria 555
Feliciello Domenico 555
Focarelli Paola 555
Galletti Oreste 555
Rizzardi Paola 555
Malfatti Luciano 555
Meneguzzo Roberto 555
Pirpamer Erich 555
Radina Claudio 555
Unterkalmsteiner Frieda 555
Vigna Jürgen 999
Winkler Franz 555
End

2 Multicolumn

The second table contains some multicolumn cells.
12 3 4
1 23 4
1 2 3 4
1234
1 234
12 34
123 4

3 Alignment

Now for some non-standard alignments.
left center right
left-top figure elyxer.png right-top
left-middle center-middle figure elyxer.png
figure elyxer.png center-bottom right-bottom
Bit of a mess, wasn’t it.

4 Multi-row

A table with several rows per cell.
First Part Second Part
First subpart
Second subpart
Now with a supplementary row
Third subpart Fourth subpart
row
The first row
The second row
The third row
Empty
The first row
The second row
Empty too
row
Only three rows: first
Only three rows: second
Only three rows: fourth
Mostly empty Not empty
elyxer-1.2.5/forks/jras-elyxer/test/elyxer-svg.jpg0000644000175000017500000002056012117061342021514 0ustar chennochennoJFIF22C       C " D!1AQa"2q #BR$r3b4CD&ds= !1AQ"aq2B#Rb3r ?ڞ4!4hЄhѥx|VdO.o CO٣ 'B/I#i ԑx?}R|oǘᦿj6.n.3oaLoSj)v;´(z0H ]FF4!4hЄhѣBFF4!4hЄhѣBvI㷵i+?nR0JQ(sOyµ/< Jz8tm@:\D2Ejp%fNnj žxA}Uw Ay O6Zd6\*dSg>iߟs!?LٓaR0R$FJ@R$N`:$%:)(I zJz%(BNy WFFzhBFF4!4hЄhѣBFFwMa6Wd  =m/SPZkT^\hB-n-^*ZrI9?={W![v-sRՆHq]s ˵U&3LEvLr BR9I]n?c쩵yaA*$7D6栟!+*J3u"C*){}KL Xf)8@22@)nF>4?KU=x| #Ȥ5}ݦ=qï:ƷjlVVy!gZyji}ZLm>Pa1ں_#?x/-dIn,@9v۾VKڗߩBT ɋ! (!+A)P{[ns%'>#*sJ7^"ۍ%b~k'C8}@Spl-Jfݏx["M1[ǟIǑQ,VzY8ZNX[ Ƕ[Z{V^ݽUԉM沐P(kvLio50/Ijҥ#3Y&zn~'Km @m$%/7x@ OSFI:Z;-5iصZTث=T':{WA%#`, ZG7em!GRTN"g Kl$IӵkºjR@~ZD96z!)g$Ƒ6/v'ԥd"a K@hѣShѯ r)JX#Uk \,atWA7wHvzG>F= -[ nv˰.zL pCTeJy_@~E}՘UK=SCb8*Zː*]Pj[RW4B}@'9¢tck iql4䓧h|Otk]k{ra. ;F辪ڵ7-^$OS;=#f~5~!BQ~ZM*_ LuiwhǑ ~yTWh)ZR#꺎 q4+#Sp"*dŰ6pR `mTxTڧ}7!Kj{ȤBwΈ w%= ΗRzW+]IoA^O™Aw;|u{SX|:'_T̟ՏC$MmzuFQn)F98ZȹxdaY+`ngCzvVgz F ɸmK M&XqlS~SU:#"m6šB^%"cy5@`$w%@bZ5Ol,@|yakqZ$kѐS$9$SpU] 9Ґ;Vfvo6wphیc<@2˩wj)?}D)P٨S5&,/4829GEQ4h"6=>빪L^}Ԩ$Xs\` \1r\ )+q$ I۽]jnm V]QL;Ld*3N8ڐ]QJTH9G-ދy[U)#sǺJ_TUFp{ s9N%SF-~#_rSQ\Go};πR\+Td(d G|)Ч8EjR[),-^#UWPz$Kfni-4jILpt#,gFn-58)Km>Ip9j_7%r}La0uH>|#LBz=ٜu镕 nVe ļ/}UrQF{i||zs'X4Bqj!k) ⠜

Ұ5 FW%sil)uq _~z_T ~͊%w:]q⡎CW4dGdyYPKPRHrһB#qLsA76p-f#CALpj/săᦫDˮj3y31*qDu2O쿸#[Ue@l-֪alAG c㞩e]oZb&ʖKg~PfJul8)[aq;BIDRNZq.|ti%qRYl.βGmv _jb Ae9(+3GܶsBEC8r<`8#Z9)$u9I#es7;^( ]o/nJ_T)peGu'ՇHj=o.)lss*5^[w"ňXp > A9`=T;5-ujh5S7^ǑOk[wSTUifk*<%39A Ny#0RS(P?=5RE.Jē#S^jS;rĪnPq$X}+S E<< Y=R;Y^Sk"@8GC:mc{b 6ܝi[d9&ba N{knݼؚ$iJI@J#&dU4'PIH9 DuvCHKM!(BJRC+x ]܋֓~Wui 3r ۵oꭽŶبLEˣAˡ0G-Ntk lr>lG0W`uZz[ˋ@G?'5C7jZSG}q$-q mą%@$<+L݀V܆/EG>-'<8McR1]!mE-~G|9VnV E}2JTϨey\k4Е)mcA /PjDtO K\A)Pjڞ;ͻәfX"RңhxO,|)QUH%P$Juy_G ]Y'kvz:H)v5~º [tʁ].ɒrcx&*Y[8d(YEӦj 1;jyzNIBK7yӢ݋ε⢳XЊp J <ӹGMwr:[|fTG1<20u%OlM)wV;$-,] Ʊ˗ ydի vjytU,_$0=<7IQu';U:{t\qԣ  B[aBW[4-aC88^g}BoMXuڱ_糖%6GBA #]`S`:_~ՀOcnZhy)\ 1 J!³H_;ږ>Sj!ާ8'vpgpv$}ħĆ? ף@@#g3d}UyunҦSv <$ WVݻ="ER&->LVՅ,gs?liګzz+3rZg)pK\A~.$(HB'NQ l.ﻴ?죻-B"Yq_yGjGF]n4X#FQF\Vk QI5FFGb[Eo2Jmą%i#yG4hFy;vdVX˦>E2R㴳) *F['لe8 Converted document

Hello world

(C) 2013

elyxer-1.2.5/forks/jras-elyxer/test/with images-1-5-jpg-good.html0000644000175000017500000000345512117061342024004 0ustar chennochenno Images Tests

Images Tests

figure elyxer-svg.jpg First image: regular path.
figure elyxer-svg.jpg Second image: convoluted path.
figure docs/elyxer.jpg Third image: from another directory.
figure mini-elyxer.jpg Fourth image: from a JPEG file.
figure square.jpg Fifth image: from a PNG file.
elyxer-1.2.5/forks/jras-elyxer/test/plain-text-good.html0000644000175000017500000000355212117061342022610 0ustar chennochenno Plain Text Test

Plain Text Test

This document will test whatever happens with plain text.

1 Paragraph Justification

Well, to discuss the implications of that sketch and to consider the moral problems raised by the law-enforcement methods involved we have a duck, a cat and a lizard.
Now first of all I’d like to put this question to you please, lizard. How effective do you consider the legal weapons employed by legal customs officers, nowadays?
Well while you’re thinking about that, I’d like to bring the duck in here, and ask her, if possible, to clarify the whole question of currency restrictions, and customs regulations in the world today.
Perhaps the cat would rather answer that?
That is all for now.
elyxer-1.2.5/forks/jras-elyxer/test/mourning.svg0000644000175000017500000001372312117061342021267 0ustar chennochenno image/svg+xml elyxer-1.2.5/forks/jras-elyxer/test/Test.java0000755000175000017500000000343112117061342020470 0ustar chennochenno// Comment. // A Test class based on Paul Hunter's Selection.java in MathToWeb. /* * Another comment. */ // A third comment. public class Test implements AnInterface { // Constructor public Test(int par1, int par2) { if (par1 > par2) { this.attr1 = par2; this.attr2 = par1; } else { attr1 = par1; attr2 = par2; } } public Test(Test original) { attr1 = original.attr2; attr2 = original.attr2; } // Empty constructor. public Test() { attr1 = -1; attr2 = -1; } public Object clone() // Embedded comment. { try { return super.clone(); // Another embedded comment } catch (CloneNotSupportedException e) { return null; } } public void indecrease() { this.attr1++; this.attr2--; } public void plusize() { return new Test(this.attr1++, this.attr2++); } public String toString() { return ("attr1 = " + attr1 + ", " + "attr2 = " + attr2); } public void message(String message, Test original) { for (int i = 0; i < message.length(); i++) { if(message.charAt(i) == '\'') { System.out.println("Quote in message"); } else if (message.charAt(i) == 'P') { System.out.println("P in message"); } try { System.out.println("Hullo"); } catch (Exception e) { // nothing to do here } } String mossage = (String)message; int value = (5 * 8) / 40; while (value != -1) { value--; } } public void runThread() { Test test = null; this.message("hello", (Test)test); new Thread(new Runnable() { public void run() { total = 0; int i = 0; while (i < 100) { total += i; } } }).start(); } public int attr1; public int attr2; } elyxer-1.2.5/forks/jras-elyxer/test/index-1-6.lyx0000644000175000017500000002630012117061342021051 0ustar chennochenno#LyX 1.6.7 created this file. For more info see http://www.lyx.org/ \lyxformat 345 \begin_document \begin_header \textclass book \begin_preamble % eLyXer -- convert LyX source files to HTML output. % % Copyright (C) 2009-2010 Alex Fernández % % This program is free software: 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 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 % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % DO NOT ALTER THIS PREAMBLE!!! % % This preamble is designed to ensure that the User's Guide prints % out as advertised. If you mess with this preamble, % parts of the User's Guide may not print out as expected. If you % have problems LaTeXing this file, please contact % the documentation team % email: lyx-docs@lists.lyx.org \usepackage{ifpdf} % part of the hyperref bundle \ifpdf % if pdflatex is used % set fonts for nicer pdf view \IfFileExists{lmodern.sty}{\usepackage{lmodern}}{} \fi % end if pdflatex is used % for correct jump positions whe clicking on a link to a float \usepackage[figure]{hypcap} % the pages of the TOC is numbered roman % and a pdf-bookmark for the TOC is added \let\myTOC\tableofcontents \renewcommand{\tableofcontents}{% \frontmatter \pdfbookmark[1]{\contentsname}{} \myTOC \mainmatter } % redefine the \LyX macro for PDF bookmarks \def\LyX{\texorpdfstring{% L\kern-.1667em\lower.25em\hbox{Y}\kern-.125emX\@} {LyX}} % define a short command for \textvisiblespace \newcommand{\spce}{\textvisiblespace} % macro for italic page numbers in the index \newcommand{\IndexDef}[1]{\textit{#1}} % redefine the greyed out note \end_preamble \options intoc,bibtotoc,idxtotoc,BCOR7mm,tablecaptionabove \use_default_options false \begin_modules theorems-ams eqs-within-sections figs-within-sections \end_modules \language english \inputencoding auto \font_roman default \font_sans default \font_typewriter default \font_default_family default \font_sc false \font_osf false \font_sf_scale 100 \font_tt_scale 100 \graphics default \paperfontsize 12 \spacing single \use_hyperref true \pdf_title "Index Test" \pdf_author "Alex Fernández" \pdf_subject "Reconstituted from various sources" \pdf_keywords "LyX" \pdf_bookmarks true \pdf_bookmarksnumbered true \pdf_bookmarksopen false \pdf_bookmarksopenlevel 1 \pdf_breaklinks false \pdf_pdfborder false \pdf_colorlinks true \pdf_backref false \pdf_pdfusetitle false \pdf_quoted_options "linkcolor=black, citecolor=black, urlcolor=blue, filecolor=blue,pdfpagelayout=OneColumn, pdfnewwindow=true,pdfstartview=XYZ, plainpages=false, pdfpagelabels,pdftex" \papersize default \use_geometry false \use_amsmath 1 \use_esint 0 \cite_engine basic \use_bibtopic false \paperorientation portrait \secnumdepth 3 \tocdepth 3 \paragraph_separation skip \defskip medskip \quotes_language english \papercolumns 1 \papersides 2 \paperpagestyle default \tracking_changes false \output_changes false \author "" \author "" \end_header \begin_body \begin_layout Title Index Test \end_layout \begin_layout Standard \begin_inset CommandInset toc LatexCommand tableofcontents \end_inset \end_layout \begin_layout Part The Making \end_layout \begin_layout Chapter Explanations \end_layout \begin_layout Standard This chapter contains a lot of explanations for terms \begin_inset Index status open \begin_layout Plain Layout terms \end_layout \end_inset , which you might want to \begin_inset Index status open \begin_layout Plain Layout look ! up \end_layout \end_inset look up later \begin_inset Index status open \begin_layout Plain Layout later \end_layout \end_inset . Because better sooner \begin_inset Index status open \begin_layout Plain Layout sooner \end_layout \end_inset than later, although later \begin_inset Index status open \begin_layout Plain Layout later \end_layout \end_inset has been repeated twice \begin_inset Index status open \begin_layout Plain Layout twice \end_layout \end_inset . Actually, thrice \begin_inset Index status open \begin_layout Plain Layout thrice \end_layout \end_inset now. \end_layout \begin_layout Standard Do you not want to look any of them up \begin_inset Index status open \begin_layout Plain Layout look ! up \end_layout \end_inset right now? No problem. You will be able \begin_inset Index status open \begin_layout Plain Layout able \end_layout \end_inset to do it later, in the index \begin_inset Index status open \begin_layout Plain Layout index \end_layout \end_inset . \end_layout \begin_layout Standard Now we will add two cites in one, just because \begin_inset CommandInset citation LatexCommand cite key "key-1,key-2" \end_inset . \end_layout \begin_layout Standard As we will see in \begin_inset CommandInset ref LatexCommand ref reference "cha:Bulk" \end_inset , not everything is clear. \end_layout \begin_layout Standard You could also look down \begin_inset Index status open \begin_layout Plain Layout look ! down \end_layout \end_inset on someone, but that is not nice. \end_layout \begin_layout Section \family typewriter Magical \family roman type \family default \emph on face \emph default \series medium changes \series default \noun on in \noun default \size normal the \size default world \end_layout \begin_layout Standard Little more can be added, at least at this point. \end_layout \begin_layout Section \color red Color \color inherit \begin_inset space ~ \end_inset and \lang british colour \end_layout \begin_layout Standard At this other point, however, more could be added, but won't. \end_layout \begin_layout Section* Unnumbered Section \end_layout \begin_layout Standard They have a right to live too. \end_layout \begin_layout Itemize A list would be nice here. \end_layout \begin_layout Itemize Because it corrupts the next chapter's beginning. \end_layout \begin_layout Chapter Nomenclature \end_layout \begin_layout Standard We should explain what an index \begin_inset Index status open \begin_layout Plain Layout index \end_layout \end_inset is. We can do that with the nomenclature \begin_inset CommandInset nomenclature LatexCommand nomenclature symbol "nomenclature" description "A list of common words with an explanation." \end_inset . Normally we will want to mix index \begin_inset CommandInset nomenclature LatexCommand nomenclature symbol "index" description "A list of terms with a reference to where they occur." \end_inset \begin_inset Index status open \begin_layout Plain Layout index \end_layout \end_inset and nomenclature terms. But what happens if we actually do? We will know later \begin_inset Index status open \begin_layout Plain Layout later \end_layout \end_inset , when we generate \begin_inset CommandInset nomenclature LatexCommand nomenclature symbol "generate" description "An activity that requires a source and a destination, something like eLyXer does with files." \end_inset the file. \end_layout \begin_layout Section Reminder \end_layout \begin_layout Standard We have to remind the reader that things will be remembered \begin_inset Index status open \begin_layout Plain Layout remembered \end_layout \end_inset . \end_layout \begin_layout Section Remainder \end_layout \begin_layout Standard Whatever remains should be explained \begin_inset Index status open \begin_layout Plain Layout explained \end_layout \end_inset here. \end_layout \begin_layout Part The Additions \end_layout \begin_layout Chapter Bulk \begin_inset OptArg status open \begin_layout Plain Layout Bulk, or what used to be bulk text \end_layout \end_inset \begin_inset CommandInset label LatexCommand label name "cha:Bulk" \end_inset \end_layout \begin_layout Standard We actually need a lot more text \begin_inset Index status open \begin_layout Plain Layout text \end_layout \end_inset in order for our index \begin_inset Index status open \begin_layout Plain Layout index \end_layout \end_inset to have more terms \begin_inset Index status open \begin_layout Plain Layout term \end_layout \end_inset ; so we can find out if the links \begin_inset Index status open \begin_layout Plain Layout link \end_layout \end_inset are working. Since they are anchors \begin_inset Index status open \begin_layout Plain Layout anchor \end_layout \end_inset inside the page \begin_inset Index status open \begin_layout Plain Layout page \end_layout \end_inset , they might otherwise just take us to the \begin_inset Index status open \begin_layout Plain Layout top of the page \end_layout \end_inset top of the page, and we would not like that. \end_layout \begin_layout Standard Yes, it would be bad for us. But on the other hand \begin_inset Index status open \begin_layout Plain Layout hand \end_layout \end_inset too much text \begin_inset Index status open \begin_layout Plain Layout text \end_layout \end_inset can hide \begin_inset Index status open \begin_layout Plain Layout error \end_layout \end_inset errors. So not much more text \begin_inset Index status open \begin_layout Plain Layout text \end_layout \end_inset is needed. \end_layout \begin_layout Standard Thanks for reading us. \end_layout \begin_layout Part* Unnumbered Part \end_layout \begin_layout Chapter* Unnumbered Chapter \end_layout \begin_layout Standard This extra chapter contains nothing of interest except for a couple of unnumbere d parts (one actual part and one chapter). \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand include filename "toc-book.lyx" \end_inset \end_layout \begin_layout Standard \begin_inset CommandInset index_print LatexCommand printindex \end_inset \end_layout \begin_layout Standard \begin_inset CommandInset nomencl_print LatexCommand printnomenclature \end_inset \end_layout \begin_layout Bibliography \begin_inset CommandInset bibitem LatexCommand bibitem key "wordreference-elixir" \end_inset WordReference.com: \begin_inset Quotes eld \end_inset definition of elixir \begin_inset Quotes erd \end_inset , accessed March 2009. \begin_inset Flex URL status collapsed \begin_layout Plain Layout http://www.wordreference.com/definition/elixir \end_layout \end_inset \end_layout \begin_layout Bibliography \begin_inset CommandInset bibitem LatexCommand bibitem key "key-1" \end_inset W3C: \begin_inset Quotes eld \end_inset HTML 4.01 Specification \begin_inset Quotes erd \end_inset , 24 December 1999. \begin_inset Flex URL status collapsed \begin_layout Plain Layout http://www.w3.org/TR/REC-html40/ \end_layout \end_inset \end_layout \begin_layout Bibliography \begin_inset CommandInset bibitem LatexCommand bibitem key "key-2" \end_inset W3C: \begin_inset Quotes eld \end_inset HTML 4.01 Specification \begin_inset Quotes erd \end_inset , 24 December 1999. \begin_inset Flex URL status collapsed \begin_layout Plain Layout http://www.w3.org/TR/REC-html40/ \end_layout \end_inset \end_layout \end_body \end_document elyxer-1.2.5/forks/jras-elyxer/test/footnotes-1-6-good.html0000644000175000017500000001273312117061342023045 0ustar chennochenno Footnotes Tests

Footnotes Tests

1 This is just some random section text used to insert some footnotes. [A]  [A] And this is one of those footnotes. And this is a margin note, also tested here.

Lorem ipsum dolor sit amet, consectetur adipisicing [B]  [B] adipisicing elit [C]  [C] elit, sed do eiusmod eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa  [D]  [D] culpa qui officia  [E]  [E] officia deserunt mollit anim id est laborum.
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum [F]  [F] laborum, laborum.
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do tempor incididunt ut  [G]  [G] ut labore [H]  [H] labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis Duis aute irure dolor in reprehenderit in voluptate velit [I]  [I] velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id id est laborum.

Nomenclature

eiusmod eiusmod indeed

References

Index

ullamco:

elyxer-1.2.5/forks/jras-elyxer/test/mourning.png0000644000175000017500000003417312117061342021256 0ustar chennochennoPNG  IHDR[,ƽbKGD X pHYsdd vpAg[3=7TIDATxw@sPQ+WiWjy+ m.53fjLDEbÁ3>?\[yρ<J""*+*T&?xW a ,p>e2E59!ĵ=7/ޥ J 5ީOn7GMDDeC¦l`}?=Yl=sˮ""r6r368׌_yEϿHnd~BDTapP\? H=+?.Cih9 ]!""gPQ@kt˩*@d\m:xl""*-*1 H{z&&<}yAEDDC%o@ިQEE`t-!o!"Pb8`Gܮ+TPWُ']ADD%šB8?`5s ""*)rȖ77 ֢k''yw9~""*.[E܍#EהܵW'_]ADDšBkH)H蚒+pOFtVtS-oo2>0wU újG)>SgS` Ӆ6 yM@Z?=4|b lJ^ xjO}:.qg뉈JCuG9 I7Eהªrխ.sE}G2poY~1T*8y/3pF2P5@΂e##"*S7\ϼ@;EהN.#l>?* Ngd*gxQm =ǽXڬ}DDǡB*]8Eה<+π ,`64,KDlD͸[?:`>`kؽ:czW\s9`Ϗ rRoRVFVpI#]4F#4DDTD:EtE)ll@HSױxZ|-Oou`˯'G #=Rfk߿ "'*_׻? `!\5%'S4uzjo]=8@M8'IDD%OTz;h$4a'z͒U<vo(k{u\/8TruL@njNsſh LsN˝m*W`{-s>Xۼ>~05DDP?HA- ]41{Ҧ*(Ήu_6DqПX5fFm=ÖgUs9+;wX)gid }4eGlE= &'6.uIX%S~RKNxI}Te/t)DDjšBy8!U?[5@- mqAwh׸Qҿ  GUnnvWhxs]fEb@_bcyIGtmhD3=娩 ^wCww[񈢼,rc?sH+”3G\\&vz.,))$r{SG>=奀2}@>ݍ@*]ʎCTC kk#$][`S3`_t@nRWB@U G4 zxWkR MM&ЪoKcsk*]nJ?-@ʶϰ9XH13zO,Qz}ӻ X0[D џhomkʏΒ3xᵉo=yFtMW42|~@n^tEOmk]A Q1 扦ykOj@@sg^G Eה½lTs^`G1Tp֤5iM@ ]S~MGxPqK97{2_W\3sl8TJ߼o: HjTHL.4s$:FyW5qFcʊC=gumV;fJͪ-Byh h"5kJ%*+Rh,i.vy5TtMٳllDWW n'-R\ ;mG2t+蚲_St+?F4_)=C'OʊC 4VYcNрRΖ+ꬨ) : EW8OzhʎCȉhosW26-F}LM}Ls{ tULEuyEtUv*De`@@V/ƈ)&Oz]^~44ڊ0L?Mڽ6It Uv*Deh_ [ u ^Ƭ ߯zߩk[CR/p7}8TΣ֎X a쮛˙|=\Ǿ/F4gDW8O-oAtѿiEU&Cj=^}@2Ùig5TXvkWҧ` c~·)s˷@UWwۦ%PV5>ZWu)^TGtUUYeƌ~"P!r!E_55L &q3_|T+ooo~u`y=%qpen/qU77: HڹjegC1iTCIr;w6ŀ}}c4r_=ʇ2[޽Ps@`v`w1*DDe$쏳?Nt|tz*#;c:p7 oR`ind73HA};ʝ mg\j5A@ Sͦ6 dlm P!"""╈DDDZ*DDDZ*DDDZ*DDDZ*DDDZ*DDDZ*DDDZ*DDDZ*DDDZ*DDDZ*DDDZ*DDDZ*DDDZ*DDDZ*DDDZ*DDDZ*DDDZ*DDDZ*DDDZ*DDDZ*DDDZ*DDDZ*DDDZZDquI!pث.l[a@U?zw]TSeRIQrcZ|߿t;eCz4w^u:PegAקZ՚!興p*:;왴w%,Ea~Qe/?mq'm_4 n+艈 ) SQm4=hҹG ZU=۶"p[oh-$rF~=Mièf:1`QšBb{^}3<Hik̀X4I%ѵ_{os&]'\Ь+nAm""<8TLmڿ? W~Sk&X͢JNgmW@ف*.*9uti}id|DW9m u^zA 8" C*kԹow\< ?V &rύbh]cZ\oFN@`S;[yJk1k6m]MNDW>~BNeΣ t5)MɹGopr?~Ht'*T*9O弒3pg}. o-6^Nt PRY`s9F/}!F}r YiIE*o1Z:/]bRy/ptndșc\JH%{恟{Dר_-_ DDPdϼy>(}'uXtDW*]!F?~alw""BŒbΛZ`]. w ""sT!1KcUR#m8wqtɸT~?^^/-ֹ@k6d_E;DD Y1sc1ǁ|7ѭ Mе. ޻Q(ߔ\i#Mn@hޝfZ֤-ǁDDDC\Mk3 @۱Y#o?s{&`~~0xyO>U< 4jtᣀ7޳g>""z"""R-TCTCTCTCTCTC=:"Ya7}THA݂Ma Myjv\@R(/|gw ԝZ\'VQšBDTF~[Ȫw\IcR`zsm  U.*DDNq2#;S,'R@JDjzoѕTYp9ɩSQ6G\zzEKUa 'r?v}}7`H4bDGREáBD$NMQ_Y+l> _֢Fz@f}B~]GCI~Y+c<};ˢkT ZUzAǀCtkȐy[tr9IlEWs٤wn "VX}Wـh5Z#I Q)Dˍ׷Fwƞ^EW}9ThYXkm5#Dӽ"P!"*) S+,ai1ȳ*%6}=1St 9 $μTR/@v3t0w﫠)D戎!gP!"b~ KyVوo"΋!gP!"tCɜ`TR'ם6>[t9 Vޢ+s1]Q 3P!"eY@t|fЪ1c8TBY6jhšBDG&@t4C7-8{z5TR*DD w]Ar+qWEWPIq *7 #<[*쪴*gu-Bt@ Wm(MIiYYhٛؗIӀëtJk]3ꄪv}ZHQֈnғW&q\HnjSU(IGtQE5ӷ+߿5pM΀1@?Fj(T ra Bəw!IGu]t.ײR?^[[Z'M!gI e*šBT ο?Zt㊾:¼^DWn]c,w/^m-šBTEEL.M]S|}IwؕvU77ԫkjvKDPi}U_t9C"3Nx:TxngϺIOvX<-E-I]C%B r Q1ܜwgT+Oե^]^CNAm ޖ̢+Q*D( VWg1䈮)G󌣽?n;uV1F@hf5(^ EW8T83q ԵUHLN>U#4݁?y굌k{c("/Kr qR>DW֤5iM@smj% {*#{Vw*֩@t0}ҘFL4 n+DP!*Gs!N4O޿5<1A~ 6;װ=`?c>c2*9E~eiTyɖdI}/xHW@.D{D [vHndk|fUITBzS#<ك1 n4k(8Qp?06޳#,0= KEݧtUv)y@6 6 D'1>1k6[H0@3W&Wŀclz> ]ܼAV"* *D at<ѷ@q0m8Sw5olU+t]z~} EKDDCH d]TR fnfi&i!L[=oc{ < `$sp޲@6 <tޱs|Z*Jc646Dl>O@zM\k.eyuk};ܧ35CDDáRAxũqCr!XA:>U*""R/m<2bǾ'&Jo&r#,&EWh*.GE䳆EW9EYhl 3@ 8""*w**=̩`_X$IʏFcZ qO5:y""¡R':8u)O"J肤@hZcc[@V^Lt5)eP\ld?RF*:% O~ua@6&R uq5_))F_{/xpkӷREq5uz\`ig@]׋r{罖څONIt9 OXiƀ N2>(ٻ7""9*~EʇX|ڗ2b=DDj8Tٞ^aBDTE7rxj0UDD e9ÁI2df{5nt ""R7ryɞ/×dYѤƉ#!4-)*""+*D3O~T%nF#!pq]xUDDG*$`uc>??{e>?@DF䏑񢫈J9;3hgWtnpdOBk9GNDT""R+rRuϼ*oR4O jԞzTtQšRN7Ƕ<^t9l*ge<m/*2}ڬ0̅9qk id""**elǨywn*Pi8oO^DE> :P)c)>y'/ ˁ=M H韲0e("C\{ڞk*Ţkي.rWKEU\*e$Nߊ!ʚclKDTV8Tȍ1Ygr/nش6 PqKˋ/n'ʋls1}3|־5DD3r3X͢k{LO#Pq d&YcEkU\p8Hc՘5f;DZl!rP)m;>Ѯ+d{_5jx~QtP)GDDא/P#_tP)Q Y>(O]CDDT1qNk!+w?\P` bP)zmkbZt6VzN&up8Iuki7d?Tp{=]tn_g "rr萊=oL79ȨmgT:]j{?8}lQkԏC>TXvkoD5nR&R)0k>!L""pi0p̉N&% 7j [:E7Ct%2R)Y@[y۷=v*""rVh5'vD88+W֚ƀͰSt%!@fN?QDDCEa@tggz\)8` H{<5,(zT۬:'=wk*""šRAwJ2 Z:!"yJקTU* ??tn_G?oBuDDC5[@l;ׇI= Ͱ̱6G5rYt $aʋ9݀Z||}h=:j窝EGU<*(P\v-;՗nǧ? 7o(o)n%ns4]Q8~|dt?ڽl>_B'!SZhW P!k@w9MrF99Ksyy?>׀.Q75_0d+t]J-3u S@I653c Change Test

Change Test

Prisoner:Well... I’d just like to say, m’lud, I’ve got a family... a wife and six kids... and I hoope very much you don’t have to take away my freedom... because... well, because m’lud freedom is a state much prized within the realm of civilized society. It is a bond wherewith the savage man may charm the outward hatchments of his soul, and soothe the troubled breast into a magnitude of quiet. It is most precious as a blessed balm, the saviour of princes, the harbinger of happiness, yea, the very stuff and pith of all we hold most dear. What frees the prisoner in his lonely cell, chained within the bondage of rude walls, far from the owl of Thebbes? What fires and stirs the woodcock in his springe or wakes the drowsy apricot betides? What goddess doth the storm toss’d mariner offer her most tempestuous prayers to? Freedom! Freedom! Freedom!
Judge:It’s only a bloody parking offence.
elyxer-1.2.5/forks/jras-elyxer/test/footnotes-1-6.lyx0000644000175000017500000001325012117061342021762 0ustar chennochenno#LyX 1.6.7 created this file. For more info see http://www.lyx.org/ \lyxformat 345 \begin_document \begin_header \textclass article \begin_preamble % eLyXer -- convert LyX source files to HTML output. % % Copyright (C) 2009-2010 Alex Fernández % % This program is free software: 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 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 % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . \end_preamble \use_default_options false \language english \inputencoding auto \font_roman default \font_sans default \font_typewriter default \font_default_family default \font_sc false \font_osf false \font_sf_scale 100 \font_tt_scale 100 \graphics default \paperfontsize default \spacing single \use_hyperref false \papersize default \use_geometry false \use_amsmath 1 \use_esint 1 \cite_engine basic \use_bibtopic false \paperorientation portrait \secnumdepth 3 \tocdepth 3 \paragraph_separation indent \defskip medskip \quotes_language english \papercolumns 1 \papersides 1 \paperpagestyle default \tracking_changes false \output_changes false \author "" \author "" \end_header \begin_body \begin_layout Title Footnotes Tests \end_layout \begin_layout Standard \begin_inset CommandInset toc LatexCommand tableofcontents \end_inset \end_layout \begin_layout Section This is just some random section text used to insert some footnotes. \begin_inset Foot status open \begin_layout Plain Layout And this is one of those footnotes. \end_layout \end_inset \begin_inset Marginal status open \begin_layout Plain Layout And this is a margin note, also tested here. \end_layout \end_inset \end_layout \begin_layout Standard Lorem ipsum dolor sit amet, consectetur adipisicing \begin_inset Foot status open \begin_layout Plain Layout adipisicing \end_layout \end_inset elit \begin_inset Foot status open \begin_layout Plain Layout elit \end_layout \end_inset , sed do eiusmod \begin_inset Marginal status open \begin_layout Plain Layout eiusmod \end_layout \end_inset tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa \begin_inset Foot status open \begin_layout Plain Layout culpa \end_layout \end_inset qui officia \begin_inset Foot status open \begin_layout Plain Layout officia \end_layout \end_inset deserunt mollit anim id est laborum. \end_layout \begin_layout Standard Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum \begin_inset Foot status open \begin_layout Plain Layout laborum, laborum \end_layout \end_inset . \end_layout \begin_layout Standard Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do \begin_inset CommandInset nomenclature LatexCommand nomenclature symbol "eiusmod" description "eiusmod indeed" \end_inset tempor incididunt ut \begin_inset Foot status open \begin_layout Plain Layout ut \end_layout \end_inset labore \begin_inset Foot status open \begin_layout Plain Layout labore \end_layout \end_inset et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco \begin_inset Index status open \begin_layout Plain Layout ullamco \end_layout \end_inset laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. \end_layout \begin_layout Standard Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod \begin_inset Marginal status open \begin_layout Plain Layout eiusmod \end_layout \end_inset tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis \begin_inset Marginal status open \begin_layout Plain Layout Duis \end_layout \end_inset aute irure dolor in reprehenderit in voluptate velit \begin_inset Foot status open \begin_layout Plain Layout velit \end_layout \end_inset esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id \begin_inset Marginal status open \begin_layout Plain Layout id \end_layout \end_inset est laborum. \end_layout \begin_layout Standard \begin_inset CommandInset nomencl_print LatexCommand printnomenclature \end_inset \end_layout \begin_layout Standard \begin_inset CommandInset bibtex LatexCommand bibtex bibfiles "bibtex-alpha" options "plain" \end_inset \end_layout \begin_layout Standard \begin_inset CommandInset index_print LatexCommand printindex \end_inset \end_layout \end_body \end_document elyxer-1.2.5/forks/jras-elyxer/test/copyimages/0000755000175000017500000000000012117061361021043 5ustar chennochennoelyxer-1.2.5/forks/jras-elyxer/test/copyimages/elyxer-svg.svg0000644000175000017500000015524512117061342023704 0ustar chennochenno image/svg+xml elyxer-1.2.5/forks/jras-elyxer/test/copyimages/with images-1-5-good.html0000644000175000017500000000315512117061342025363 0ustar chennochenno Images Tests

Images Tests

figure elyxer-svg.svg First image: regular path.
figure elyxer-svg.svg Second image: convoluted path.
figure docs/elyxer.svg Third image: from another directory.
figure mini-elyxer.jpg Fourth image: from a JPEG file.
figure square.png Fifth image: from a PNG file.
elyxer-1.2.5/forks/jras-elyxer/test/copyimages/mini-elyxer.jpg0000644000175000017500000000304712117061342024012 0ustar chennochennoJFIFddC  !"$"$C2:"0!1A"Q2aRr#Bq'1A!"Qa2 ?죬jɣ 'UўIO@d/~#xCuO_L3M:!5;{{ 5,$}t3,%H)?s~ԋ8$3ΐ?XZ,T5U"OC bF˜9UJs;lz-OC)l$vtvu-5Jv;4UFG`A zquԣ#]`=u:B|^5ixbS~Jʇ ({}18|QSKQfE.뜖Wf0z7\,* DK/y{ Qk멧j(dsPsǼnq c;k]iN,cgl@K`W r"|DheIϗV$*n{|+3IJdD_EEqN6`,4OJr} :ݩ;ܷ.ਹ9U'.rA>ge>{:+_Ը.s!op|~&*6m^+3eɗļov%edvoQi@d+'9}`k<#BB7lJNdU5uSҼBHA7zC2:b\.skK45*ŠWKHV+Ĝ04_WTΪ4;$\/MNzι]]wGU|8?o};:Y8$֑>QDu5B㶧yQDJZ@![vN''2jh@ZoomǸ6Ҿ% u Ӿ,&$q%}smtTI(7=陼VǸܨiW[y7@븐ay = W&\7d۶J)9OW J?kZ-;j[픩MNU$Ē}$l5*4 u4j>:4hCF$@jth elyxer-1.2.5/forks/jras-elyxer/test/copyimages/docs/0000755000175000017500000000000012117061361021773 5ustar chennochennoelyxer-1.2.5/forks/jras-elyxer/test/copyimages/docs/elyxer.svg0000644000175000017500000015524512117061342024037 0ustar chennochenno image/svg+xml elyxer-1.2.5/forks/jras-elyxer/test/copyimages/with images-1-5-test.html0000644000175000017500000000315512117061361025413 0ustar chennochenno Images Tests

Images Tests

figure elyxer-svg.svg First image: regular path.
figure elyxer-svg.svg Second image: convoluted path.
figure docs/elyxer.svg Third image: from another directory.
figure mini-elyxer.jpg Fourth image: from a JPEG file.
figure square.png Fifth image: from a PNG file.
elyxer-1.2.5/forks/jras-elyxer/test/copyimages/square.png0000644000175000017500000000025512117061342023052 0ustar chennochennoPNG  IHDRJ"sRGB pHYs  tIME +}D tEXtCommentCreated with GIMPWIDATcc`$\ ]IENDB`elyxer-1.2.5/forks/jras-elyxer/test/bibtex.lyx0000644000175000017500000000761512117061342020726 0ustar chennochenno#LyX 1.6.7 created this file. For more info see http://www.lyx.org/ \lyxformat 345 \begin_document \begin_header \textclass article \begin_preamble % eLyXer -- convert LyX source files to HTML output. % % Copyright (C) 2009-2010 Alex Fernández % % This program is free software: 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 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 % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . \end_preamble \use_default_options false \language english \inputencoding auto \font_roman default \font_sans default \font_typewriter default \font_default_family default \font_sc false \font_osf false \font_sf_scale 100 \font_tt_scale 100 \graphics default \paperfontsize default \spacing single \use_hyperref false \papersize default \use_geometry false \use_amsmath 1 \use_esint 1 \cite_engine basic \use_bibtopic false \paperorientation portrait \secnumdepth 3 \tocdepth 3 \paragraph_separation skip \defskip medskip \quotes_language english \papercolumns 1 \papersides 1 \paperpagestyle default \tracking_changes false \output_changes false \author "" \author "" \end_header \begin_body \begin_layout Title BibTeX Test \end_layout \begin_layout Standard \begin_inset CommandInset toc LatexCommand tableofcontents \end_inset \end_layout \begin_layout Section Ethel the Frog \end_layout \begin_layout Standard Some random text. With a random reference \begin_inset CommandInset citation LatexCommand cite key "randomref" \end_inset . \end_layout \begin_layout Section The Other Other Operation \end_layout \begin_layout Standard And a book to prove that we have read one (untrue): \begin_inset CommandInset citation LatexCommand cite key "pythonesque:1971" \end_inset . \end_layout \begin_layout Section Spiny Norman \end_layout \begin_layout Standard We are going to need a reference here \begin_inset CommandInset citation LatexCommand cite key "reduced" \end_inset . \end_layout \begin_layout Section In the Grillomat \end_layout \begin_layout Standard There are two kinds of vancouver references: with volume information \begin_inset CommandInset citation LatexCommand cite key "withvolume" \end_inset and without \begin_inset CommandInset citation LatexCommand cite key "withoutvolume" \end_inset . \end_layout \begin_layout Section Alpha, Mr Belpit \end_layout \begin_layout Standard Two references in one: \begin_inset CommandInset citation LatexCommand cite key "alphabasic,alphavolume" \end_inset . Also, a repeated reference \begin_inset CommandInset citation LatexCommand cite key "alphabasic" \end_inset . \end_layout \begin_layout Standard \begin_inset CommandInset bibtex LatexCommand bibtex bibfiles "bibtex-plain" options "bibtotoc,plain" \end_inset \end_layout \begin_layout Standard \begin_inset CommandInset bibtex LatexCommand bibtex bibfiles "bibtex-vancouver" options "vancouver" \end_inset \end_layout \begin_layout Standard \begin_inset CommandInset bibtex LatexCommand bibtex bibfiles "bibtex-alpha" options "alpha" \end_inset \end_layout \begin_layout Standard \begin_inset CommandInset bibtex LatexCommand bibtex btprint "btPrintAll" bibfiles "bibtex-latin1" options "alpha" \end_inset \end_layout \begin_layout Standard \begin_inset Note Comment status open \begin_layout Plain Layout \begin_inset CommandInset bibtex LatexCommand bibtex btprint "btPrintAll" bibfiles "bibtex-latin1" options "bibtotoc,alpha" \end_inset \end_layout \end_inset \end_layout \end_body \end_document elyxer-1.2.5/forks/jras-elyxer/test/toc-article-good.html0000644000175000017500000000625012117061342022727 0ustar chennochenno Article TOC Test

Article TOC Test

Part I. Our Definition

1 The definition

A TOC is a Table Of Contents.

2 But I Already Knew That

You were lucky.

I Want My Money Back

There you have your 0€ back.

Completely Unfair Dude

Hey, I didn’t call you here.
A Paragraph For You
Totally uncalled for.

Unordered Section

Just to show that it works.
And now a list.
  1. First item.
  2. We will embed an ordered subsection here just to fake it.

    There We Go

  3. See if it’s in your TOC.
But There Is More
And nothing else.

A Appendix

An appendix here, an appendix there.
elyxer-1.2.5/forks/jras-elyxer/test/languages.lyx0000644000175000017500000000255312117061342021413 0ustar chennochenno#LyX 2.0 created this file. For more info see http://www.lyx.org/ \lyxformat 413 \begin_document \begin_header \textclass article \use_default_options true \maintain_unincluded_children false \language russian \language_package default \inputencoding auto \fontencoding global \font_roman default \font_sans default \font_typewriter default \font_default_family default \use_non_tex_fonts false \font_sc false \font_osf false \font_sf_scale 100 \font_tt_scale 100 \graphics default \default_output_format default \output_sync 0 \bibtex_command default \index_command default \paperfontsize default \spacing single \use_hyperref false \papersize default \use_geometry false \use_amsmath 1 \use_esint 1 \use_mhchem 1 \use_mathdots 1 \cite_engine basic \use_bibtopic false \use_indices false \paperorientation portrait \suppress_date false \use_refstyle 1 \index Index \shortcut idx \color #008000 \end_index \secnumdepth 3 \tocdepth 3 \paragraph_separation indent \paragraph_indentation default \quotes_language english \papercolumns 1 \papersides 1 \paperpagestyle default \tracking_changes false \output_changes false \html_math_output 0 \html_css_as_file 0 \html_be_strict false \end_header \begin_body \begin_layout Standard \lang english This is some English text. \end_layout \begin_layout Standard \lang spanish Esto es texto en español. \end_layout \end_body \end_document elyxer-1.2.5/forks/jras-elyxer/test/laurindas-anger.svg0000644000175000017500000002425412117061342022506 0ustar chennochenno image/svg+xml elyxer-1.2.5/forks/jras-elyxer/test/random.png0000644000175000017500000003663112117061342020701 0ustar chennochennoPNG  IHDRXsRGBbKGD pHYs  tIME Z tEXtCommentCreated with GIMPW IDATxit\y&]kZX WɒEQʔ(oJd9m'۝X 褝LOM&=sN'g܎s>Jm2{ӉٖmŶIlDIP$A;[n;?. E =N*,Sϻ>/ZjZjZjZjZjK(oh& []/ սnQzR$s4h@+ T&n3eK np-5 M aJzڜ5 -snN8Xz %Y F*T";pTZ^ 1@G)u2Xk^۬ Lm9_SnT/p0ҏpO궦1rFAe.fڵ"ucu߬\䪳8/\DlĩvoSqKcoܪb $X!i2zi(8aS;| U&A3Uk~N(*@,Y[Xuإ` S `$eԮ&#^ *u; `V@rtW˪hq---ϬY}}}* |/鱥|PV |DoՒjD;[(իW7o6lY敎ﶴtر#i&M8"*0'ٳgE\0K]Do!ocD NވT YՅN!񶶶w}www[olggpa$_QMD]+˲n?tп:q]'Sή]tLҲXܩPJ3MB03aܬ$mw=}B<Μ9("ضͮbvv֐R644r"W > СCබ6ID@!3Rdc#R.T;Nq1,ƪUfNo?EgϞ5 aYΝ;m۶y'K/x122SN< tTbPAss/ኡk!$3r.4q[m۶C;o> b߾}um  nՇ?{キ><?~|R0sIJϾ3;@H)g0曫+)Rعs3dΝ;'8 @R;Vb/[c#.ƶmׯ6nnz^B0r뭷fEk׮^,\͛aÆGWJ}ruwwGl"Dto~irXx 3/"'W111!8>}mn\fMeY:X h}aVZn]L)ˡDԶgs%1H .ȑ#Ą "y {|Rо>@,+aƫj:tHAmooos]WϠ7wNLLd(Ҍ4aɓT.E* xy#VZK 7=zT4`-Dt;+ IfL `ut=Le׭[իWöm a(izzB-[p?w5\CahKw0stJBApa0M988hiW+e%T~A f4>}:xܹstQT;vVHmbDΝ;W55 "aȆa@j`l6Ka8%kA<GRYI4#"* !fAkk+_{;v)":u^xJ""23D\I^)uSh4wXy":*eYب_ flRnV/`_ӟt+J̜B644SSSZD$0 ttt{3K"zMDOܹRVK&''_:::&LthoowvYnhhpY:UL S\Y4=\O>WW}˲lذNOOx嗭U>u,FD"PJi !JB=o?3N׿e˫4Q?b_'nf0 Qȑ#'T*AN(4h泍8L\8$ubm@?洮pԀr?OvQ/CD- "ٿ<=M煈Ϫv6VQ33oC/^"af$a.RJ)N:bX\'Q0 OLL[n劀#e`6O{w3/DQf_ѷ{]3A㈵!zke| `ku q8p<~8yG p$,};ălWyW*K:q0$U_P~ߎ;`}˲V !EQt`ݮ(~^Yˈzj | {1ZADz.eaaZN>ͪKVԏ$c+}PV5>8G߼87oߏ<-Ϫ*<0'SnD,Fw ` 3Oѝ UcIFiFWWoڴiuĵnV!,}*+Pw{9waxcϞ=B{zĭ3ӯ>í333 xu,D@mT*6 07vppeDk>JDۘy0mBrjCCi4}0rQ^a,b5!N!bz`Hă=>V;/Į"RV(R@RAЩ!)PbnS@6xGⱡ+n%(}?00 eV5WJJle>lh#iZ13 rn:P(TSNR ^bQ%4n`N:(ǩ{B<}WZU>qD#"r`5Ѭ^O,ޠۥ@REI)) Caff#]R))咚Y "/R10` %:_/̇>":8NKcc::ipVLRPq#+%T2&BDX+tWCQ1(p}T*eT*A 8y-˂amjժ###K.\:7.亀똂ҏI8|eY|*4}޽{] hX׌]vr·1@n۶-lDtil%.Dd%c6kԱ48&XX * fJrɓK.$\w׹8|p.իDE7>Cs=B{ʺ'B?L<p3;U\(6 %(`-뙹\ҁylR"T*J%eJl&[Uma/? oߎ hwp]QO^X%Au166x~A6P&q!^Fui@$A~VDQRvX#\TnrgbJdNR,:e8FҥEXDRAk;sܶퟙCj؏ڀRrznR\y"P}7vwwGB哛u_9 {RQ "jRnRުbk;X,6lܸѳmLzViy(*CrYTUDQĪPȎmۓX6 ֳjgggivvX`&;Sd2/۶|7k;wհp1H@Bu!#u2s0 Sğ9lD\8 /7!n|t{ll DЀÇscc#DН?ʝb)%/*RRE !tJ{q'뺏?W_*r! 8p_  '"p \7#nE/㛉&3&"+L혘@RիWCQBnTRrTV\.ZZ]CYs8?1M;>}m^ض}Ur~+ I<:un-7=2^Y,П߅UpNDۙv* j-j* hjj8FMT*)Uv azzq8Cm߶F/O}ݬ@YM߾Kv)Pdx 3;DqdM8B̙3EuvvPhPWy* {GA$k#me]}uY}uwvvJ=r'dX3]ץS$\DJo Ar=3oR㯂QBpOOMLL`zzz{{q蘭 y[ CPkxpgeYq]w{ _|鹪 n(R 6_P|#jeO2~һBDtwyP]( ( mWc((;UVA 8H8αL&eY?,)u=B ݖ@PBnſM&l^ъ"%} ⾩vf6ra ((>c-n^$͚/6 07Ƨ =v чlWSIl\.GDDRJjRIJ%X,rLip0 2MSf٩|>(fdfG֬YS?0s-^C[3:).py+RFf9eYHfsAJӢZ_( *! Èǩ{: ;iqq 1rd F:0[UXZvnc5jUi!* y$pd2/۶۶lY!۶ H]vEj ^ߌ"z b[Rj`7 ߟͯ繧G2^@QT*Z.뺳 Gs>jYLeY__b!Xɶ\EkDӔK>`vvvvJ}FNT1E-8R0DcccExzzR a&sCf~ywwttL~_  :Xz@ԘB#|>;33ĉ| Ӭ ) Z* DtE#/ʛ6m ]m",N03U*.J{+3oxxxXS)\كwJz Zb۶ƍ|> ,eY-)% 7B/׬YZՐpxU| LDOaX)@ @^@|^ 6H4kkkڥҩ[5RľWADa?A)@~ÄE!h1(ˡGf2BRJ<"W*H4#Rg(e oʪO'^,I0B0P(v""+FT*ZR)%:<&|!nI#ț:SCJǣE?KR1@LFtwws.3Mv}g|O" yfMWYE)>MH!:;;ŦiW*eA"H~>f~E'!R*ȯOwnfͷ:ʼn'@eV 7o,D=(b 0 tܡ%"z$ia-6sⶓ*=",Ӑ8N<[YvmAaj})%yG*0 .{ G  o*{F%G\իgU BAdBIz+$퉢DtF"Gb*&ѦMgsL ڰi&}]IiIJj =VetV jxIP)@ުC[ƜP{T;f6l& T ]iWZ1V /8ߓR>S*[pHvhpl(uR\5}vzf1ODBerrtSvR?OIH){\z|!O-ALn߾V L5dl:s{~|;}c0 nB{w\.,raBNf0j1rXI#eal߾fv"j0?:<<, '";֭lbR-wMOO_~ߗf__٢~(>H:+ 5`D[̼ѓE '\!@eKK ݻ+?ŗ^zC=4qƳΙ.>*o?xEb,"\} D7J_ E7DTp3:cXa " \.,'(:}ZȓRx|||@̙3W< E4Ogm̖\D6K(ir&RwhOCskjpCY\}۶eUƉe˲öf+k׮Θ(˹ Ð*z!BWk7{Z v뙹ϵ'%u3;' (uҌMDBq]т>H>d#}2L;dbڋ'qzRJ\-)V}pkWl8%0>TFJ$y<ƫj.Y$D"\E֭[SpY)^fv;;zmY¯IfIS}H=p% .3'?ZtkTsq~x”p(_.!&z#ao~)LdcSa>\ ћ=,PM23 `0˲O|)LVp'U+yhs \.%N]BLA:3#**Jw3,A\ C?WA14@M}M"HzS\D";|Qz@Ѕ 7qPn,˂iRa'0U%@ i&K(4I0%]. 0A*ذm L "TLl=6\j-o$]ZMq2=)\+bfqO,^9LyKt΋GtIEKw !)@.E[GkuKH_JfjO48c՟ 4!(8{.ea\0X@_ &Q+V[ɦEҥ&,˪#4R, "%."3O19 ֤3S֒t0 R0 A|fVKqL@Gԏ꾫>D]`n:a" ژ8r)Z\.֯f2"I*񆈙TѲA<{y٭djٲ,誺i@&8Hμoq5'OwFb*XQE~}uCu! by-)*U/%Z9IR6.dtoQ"ξ}&#X"CCCQPQ CUA#Y5W6?J7b%jBfp]WHAl"M-P $ó۷ox*x<}-xLD:(.""NDUld E, qT՚']& b5i D%3dBQ Q^0szN6fvX\d;l6 4k?;3ua3 $nW{*`\J >#VB3g-~;gcY\.۶ \SOj)@(XlLUnSJ---]%"*VCQԖ1 چ瞓bBqnf{U'A*jbY }ʈGj>9$dTU 2I-Ȳ4@%ѝ{"6R,Ocf]iȋDbW.Ȋ0"#Pf@~`` x)@ "cN_^zn*0ʊ)@%0Vĭ,1HRT1ҟ*+Y~8pbޔyFbhj)@5XCD 8ͪ"^3R+ȲtM֪;SqBUijO]%liWs5jEBRQB(`s̼~lj2Ȳ6f6TѨODQ/(޽;uR,kXC'^" ]vɁԽJ- (FuRRE0 _UIS, =yRsjϝ;'OÇ3###"&kgZ[[L&#Md0jq/kKJVXXbnC*pGzd%] -JHr6\ zK76.r7R^BO )YFw 8-Q3K+[뙐ּ%W,kr͞Q1Lj),7b$.v%A?2Yf!d ؃7 PMRKf='|bF$x'X^Ԗ@nui\=s.1~mG܋ʼnUeMv t!wTTmֹS V6u.q1yҤ)@U8Iz5&\Y[=g#^v &ϣN> WI !N0PLfĩV͈\@/RK,GܐXTr`bRxqoەUұ "cN:sH!^sJ,=%YvƊƕßč7+@?<xQI Yjry䀊IC8nS\o׋W*v-(f!lu`E**⍽ +ֽl-$]b\R6IENDB`elyxer-1.2.5/forks/jras-elyxer/test/compressed-good.html0000644000175000017500000000213012117061342022656 0ustar chennochenno Compressed Test

Compressed Test

A simple test of a compressed document.

Part I. The Main Part

Nothing else here.

Index

elyxer-1.2.5/forks/jras-elyxer/test/lists-1-6-good.html0000644000175000017500000000677012117061342022167 0ustar chennochenno List Test

List Test

This document was created with LyX 1.6.2rc2, a great text editor. It is used to test lists, descriptions and item lists.

1 List and Description

Utenim ad minim veniam, quis nostrud exercitation
ullamcolaboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est
laborum.
Duis aute irure dolor in reprehenderit in
voluptate velit esse cillum dolore eu fugiat nulla pariatur.

2 Itemize and Enumerate

  1. First enumerated,
  2. second enumerated.
  • First itemized,
  • second itemized.

3 Lists with Levels

First a simple nested list.
  • Level one:
    • level two first item,
    • level two second item.
Now a more complex example.
  • First in first level:
    • first in second level,
    • second in second level,
  • second in first level:
    • now third on second level:
      • third level 1,
      • third level 2.
  • back to third in first level.
  1. Now 1st in 1st level:
    1. 1st on 2nd level:
      1. 1st on 3rd level!
      2. 2nd on 3rd level.
      • And now mixing 3rd level itemized,
      • and another.
    2. back to 2nd on 2nd street, sorry, level,
  2. and back to 1st level:
    Now with some non-list text.
    1. And an ordered list.
      Just the nested text.
      Repeated twice.
    2. Second element in the ordered list.
    • For a still more difficult number: unordered now.

    3.1 And now a new subsection.

  3. 3rd on 1st level.
elyxer-1.2.5/forks/jras-elyxer/test/square.jpg0000644000175000017500000000061112117061342020702 0ustar chennochennoJFIFCreated with GIMPC       C "!12AQa ?}w뺼eeN)v_5bEcoKKD[&+ T,q%␯Ե\W9U)FSV2cnxelyxer-1.2.5/forks/jras-elyxer/test/version2.0-good.html0000644000175000017500000000213312117061342022422 0ustar chennochenno Version 2.0 Test

Version 2.0 Test

Some random document for preliminary 2.0 tests.
Savannah bug 33961: Apparently super and subscript fails.
elyxer-1.2.5/forks/jras-elyxer/test/elyxer-svg.png0000644000175000017500000010234712117061342021524 0ustar chennochennoPNG  IHDR_nbKGD X pHYsdd vpAgIDATx}w|iջdɽWt 5!$@H $! ͗PrC rS$Z l{%]q|Z gvfvvy9(Gr!q>r!ӅC9!-rC9[0r`90n#ra"G9øEs!qC}nv۷ottttttJRT… .\̜9s̙sᣍ~@x<x^{5oxcqM7X,xӦM6m_׿50}ӧ!b{o xgy Rp8l6f qؿBP(<3>8]N%X,:uԩSzAhrFٶT*J,^xOӟ{rÍ,}w}z5׈jZV B“W6&D|^>>[nݺu89C:rNQz^೟g?Y3f̘1Cl+Zbz„ &Lo߾}M0\`׾}k^X#ɖ͛7o<`֭[n=ݣCnpPYYYYYyG3> // @@"qF0N,8Q"ljjjjj:묳:ԟo9|#8|ÇE-3-8dIr'[5838Cw99hxㆍ6nn馛nr(#GGqA%fk׮]_$r =p8,Rm."JٳgϞ ̝;wܹms#q ̕ :eZ[[[[[E5믿?ݣCM{ pǎ;vH_/wp`0 ?NG^{}rxqD=BDI:Xexȗ9p,{99|Ks=sb3qx,ǀD2LAV@JR Dqat9ʋ0N5M ywySH$' )gKޠjI!O[t\. CP8}{6dlgȮ]v\r%\r n&nx'H|#W >H>^]۲USؽ{ݻ}s瀫ꪫ:ݣs7s4b2K:N$Ï;-r?9kNh}+_W\p\pV=CP0Ę%x<uH$8tFC ņXAWJljh :@5B<O8_AorDqŸ%@Νc$w$Dwwq{87Fc]+sk7F{--@0lLħFv`}60uqK$@ɖ?ªHėL9o B^/eL9L$B!Z~gNdr8> @3NMa8Csx``OwOwOg$"z[oN;ZZzz\.Z ==N{tp:=@Fcx"8F^Q6ɨ7v֖0aByy~>-mqca?Hr<"})/ 1/2T5fIY%H(X%>(~O\O||>ut w77w> KK+\n7f3{`Lz=i4)P4 `$8mOTV \yg6L~Lt==OvZ( H&c1"HzA{&@h j]PzBҳ8xqK 87567 bx" X,FN,Z4uje%0yrUUa!`Lǚ ? vdb_yE8)AP(J">RZ P(J$7onoVZaȑ~sp^PRRTK~]p՗_>e PPp~7FjTlEcјD>QYOvRbjG"776+WnDxW+_.ILZVI9[irU;zW;Z46 'Vضs"($ .; -) I.ٞ@cAUؒ?4ЬJ%/ZK rV՚@QQQ"~. kp2}D?ڵ֭;vtwC]qt"h(Iq̀Vk4׋9hb`65K/KEaґĵk| o܉ʀYKK`J2+٬k4@UJ%I0iD2IR<hFDbd2-Blk˾JR߫V[{7v`-+w Mm#=Շw:?=UW ɚ YNsDS?Z +*****F}-[}ZZfϮΊ8Rl7Xĉ'N*2l`<d a[`-0 9뮻ɌFcx}q @_Sgח ee!p۳\7L ,P"cbDUWs@_/ ^lTj5:0w~|艏1n .ᅣQvrªU{V\ӫ,,<'%>(G?oF<jl z!.nǭ.]|~`Ŋ+{/뮛>">}iʄ\t(&l b1zaA`fc'_G^O5F r*L:G'd2k׬YBbŋ/ 5W׿h<<ˆqK555555믽k/7ܱhX` ʉU JKm6,G(lB*4^N8>Ea7&eBPXeg"KPr 1z p:~߸Esc悂+>. Ri4aFfh4juxp  7pu3fU4X7FgR-;%%:ߏ 0޳g&薽 ^@ uPzQ]Uէ?կĉf*@کD'MM>D4_׬ M;= p$֖-U^-ȆrcȾcǮ]==d|Km%?yoV{ϣu T$a={zz)/z j.ۏYFlϦΙ3sfi)pyg]SYnX/jjk'LN22f/NG7H"Àӹe˻JtD.W_?V[,v;`6N8 bdkVrDˣ\nO3355TWrz0ɽ,y71A2fS}am:;r/TjupIf̸jihZ|$ |>_4JI+**(3;omBQPd JRT|xmׯXZl08aoX Z^PM'Es䕀^_RRUED' +ަ={#Gx}3f~jq4q'9̂-[P(;Z O8;4D<HdF__kDKx1*c,O-3W"ql4L|`EnXwyɫd/~fL&`Ui2Z`ܹ_sʹiuz2e9sn%R5{WI{er"^$x4tBu5%<6/PbyrT׮_xǀ/&`ڴ|#,Xz玖fS/[;?)N {kى!kabx9aq}^Ri zEŋ}}vZr\ٳYawtwG痉ٖ7})EE…WT+%l{͙S_L#~PU^~?js} ݗZ":m9sPM&EJpx}嗁w |O~~~&Ӌ7< }rc{IE",`0Ղ &y72y 4Kx|!ό+,r4|'m):o8nߗCbK/zdE""9[l;kP^p$J(ɃHھ]BtGmt>_Kˁ"b4y@/.N OmA&˟xڱcZ`˯XUNr(Ljlۓ8$E}rfiVUYcdKL\͈` DPUzad+Yg{WB޻>,ӱl#IRFE#;sY()"8УuFQoAo'R6n|MRY/׭{5 xϱd<hf]pF|8 ѱtق`¿ujbih9Sz2G% <ާ:(GG ue(*cKL@$r,Ejm6%#o|@XvÆtK~\_~2V/o6LNT__P^Eh2F"n|@w7 qΝPRl6W]OWy]x]۷*pHsݔ!~ 孒Iz1BE.)).XrI 's޼y^]N#"A```ݺ_WZ pnL)_p0$N2L&`(-$G}X\}}D|3:ٿ͋o*QZ*prǣ(?(c(vhj/;=&B7V:XR \哟Iʷ3oXq^:q\$HZNG=7(WoojsfΤ:]&fϟ:8%KN9碋(~1s:ɶ:8Hb8,RJdOq(0x,lv՘A {z$UJHuڱc: D"lS*5RY&wTE0u+O>  &ΙL@4j4g\6⓯#8xu0zx$⳥Y,6ĉ@__ooKKLFJZ{@?DJ"dpe/5])"_ VQU*P,>uۺW:/v8"rL-`ʔ"/o tz@omfssڵԸna3#͊%GXΝQ٪+|*+{!I[JdcN71=67wu9@⨱ >0P\&`0kkº:1vM;8 }tÆ'뮻ʩSPRGA_TE[{;vVfR`WXZ,WTdL@^y9>%HQ,ٹCCTvlLuȑ@xJ}|A&zTU}<]q7ڇ] t:E 3OZZIih:֖꫁l4~:lG͛Q|3^;}:pphLR\"Pb)Jںy3wȆ ںe &n"-[xܽGKZģUHz0 ,Ued߿mp={„f}T`Ҥ)Svؾ}ӦnԔ~ .¡u6ShTd2si%%?yf'L+*Uh#GF'AeZMha`vv (_HP 9(|?otf{'Ϝ}NMg>̚UZdɇ_ ;:$F{z3\X'Ϛum@OOwwK =5:75ҋ.jhniq(JS=? @'L&2Uj,8o}Kx&'PsswuIu. ?ȑ  Ob1)14xi!m `XZ֮4iR ~ ꫧwsΩpALώw㜹?1xqmן{48^ cpyٵkE;˓e5{zm_>{vx7F4 uu+Wگ~4665h~rP^^V\~UW}{O}kywݻWBA}m={eFhmݴTw<>wu.׶mk*̙W\h4_ԑZ(bH6p8`0dظnᦦXlz=LՁV/XCK|o[7( ÆqKk*;&M,(s'OِHbCC޽۷o$Jԏ:U9Ef;㌯|j L҆ ZظaPP@ѱe VӎÏ7MM}mFCJ%Gňh2i4dHIBlm=r$6n\k$@@]7PEQFwr 0"*c@8|HlRS Js$(Tc*BA6چ8xpa  (>@a2Io=ZOjz n _N⊥K*=>+(u*x]v٢E RWT9eݺ={ہUvlkBg/ r`T'*ahtwG"@oogg4J )V#"J}K];٬坂lwt(J%WTZsz.gO~̸!p8 ;iR)6*Ѩ̚E&a'\3mR #‹/Ry"A6,ʢqpR TW:$Q*EؔFѐhT"dp8"Jٽ.$SUuPX%'BqJ/BJ>kyT!Kz>kp0YBd8q2Gb1}I T )jMU~M&p/~v-,X|S~'9Bx{/֯߿or`۶ë=J= Jnj/ >}˴bm<( >cQ ۠ /F#"X 0&&I (DT 72`  Ӧ>0sf~>`it [>rٳu+wt $S\v ^r  â$>VJTRQx Wju:l|j5*P\\Zj0-/z{~'7o‚`PJ|,*"t:ry"Et[UU0sfYم<'G^w;;Kׯ`۟SdTV>JT&"e.tf~^O·onu}>RiB"~h4 //?_%O Iq9Z-NfJEq( `ggPTBmoomP0Iz1JˮJGU>E3"RaƬrQ6$ZhT!Z6*Idɮ7&O6nEEڿxزeffh)L&c1tn'U2.W_/I%.䱪S(P[A 55uuf30{y0s9yy驆,:4 v  B()``NP(ZjԪ 74Og9dopz W__0HHfQ*ɓb0 j5e )DR' j4B!z}RT0 E۾{vn3ibMCKO r+|n`׮ěBQ(x\F?Y 5p8 o>ݣz^x lFXLp:Is損#Fi11j+@Q%PIecf'AGGk/kϞ;)LǁŽlljȬ`#$*VD@8];+Wٹ! ?&BCL!" '@wwGG O*<;gXu# ,)-ٵkhT~[LLulZ-5~>^=kOKLH^CGuum<ҥ_DiHdω!H x, ~xnj_yDyG?NTUVĘ'N*{9ۉ8.m`v SQ B}0^dVFYfU!4I@t|1ft>J%_X$b$h&2"BoIYU%ekkK xd\^b֮]b 'On]ORʜ h}{$AS*ǶZ-ۻ曁 .hhE18M5͛z Wz/ єnFLMW%BRX鮻A1_oϼ 2g9A^?}{_g>N2PPihx|۶F/ ӠP'GIIi()"77{-7 o8_Z|=5xgd(ϴ_cyQ R8GDDŽ( ,9J0F/ -J3E]۶ TT?ϦOn_N-[6n<\Q*M&^n@'O;ڵ-_<ҥwTT8& Ru  2zaT#FBQ[ 8&ӝwm8Ip#m|9?TPhӦ/Y:Qj[,ƶ> .rZT@AAq^O*\2 dZVL74$Dj5BP@XrD^bjMl:y8}=tCN*ቜ`,KmBeN  1 /?"(/2EBDz=6 vSbfY;J'4~dR>|U5?[3i#M| ׿z۾ TTLzhӛZ2PXRTR̤*2b0k$PVr=_رM9i\Z{@2cbHm}4 %1zn*6@ l~Z-ep@磔.A|DtVB^[*P* I62%A":@A U|:y>؋G,AJeDT;R^^Yi0&"fhŠ{zC!੧x. `ƌ3v5(i<ġF"ΝnYg6^_Twliۿ{/} | /x ^OKӛ"}{熆~ʭ[FOp 7l>qr0sfU~W'+TORgSU3}_;+X*<>X2E! @jٴZ``/NA Ϫ4KDR"H$,WGIU%! RYF2I*'-(µIR '(*HU9ABVKN^f 8CG"dZhQZm;TxUJJJJt:!ɳ`pX=}` ??H4 SUV-\HFOzAC/WqJJ %Kv]:q2&5=Aw:OJ8p#'H9ƫ$g4vwl9BەJ 3v Y5|]  T;v]G6)RyS%d}t@߁~ʰ`FkJ԰La)T[tD*1r聁P$&"t"@n)$S&{dD+g"Z8KR%@2 QJ|&HZ"@ ǁPHHbaɯ;yOvZ$PPP\l0nEȚ9]]_>e׿/[v]"s$/m66;zJR&qn|+5J,LJu޽$9&hTyWZ5DPGT#;E|| .4?8`45YPA\6@s:[ZK.O T$N?-%>NPFi dcbgYH$u MXlLP, TD`*%^)%@X"#M.踉K"PNlMgN!$g65<Թ"^d԰FF =D+O06[^HIЉݻd@ƙ0N9]o߲ebɨ*,4)=YqzcDP=P*H9~(UrB*FC.KD\ɤqih &^1NǍPJJVoqϋֶm`4mJ 46D BdvldfG}3\ Ι^̦ `@`-Gְ75?2*hLiiyHHWI"epdmfŢVSj pLț6_tjuuT@mCCN'[K}xCDJll߿wߒ-[S>;v{G:$9KIy95xD%~PZJ, vMy  U?XBiDp?M ~` Q'87yR@IɊ5Ւ$w?p DJK'Oa;:LIUؤ!5IH/B;dKg@dnxTOPJ[(D&K<$Ad:/a; S|9U(JޟcmTsu{ PmڨڂA47*S٤!@b8X2: hnܺ4૯n닊J"zb(RJlTeW*dYY$Iңb0h BtV+ U|}]JUPl|,!21TJWTeAe $T.i`7D#g NR؊<:' OF5zhȟI2a0t;)R!NdddI ==ԎHH,ѵ81 ZFTTTWSYf*T_:;NXm>s>F/6;s {9QJeEi?>_El:sv Iy$}{AZVFD@Smy=*5m4(YU8B3DRdB!U~L{eRY"[H2I&@MGBa6j5Zttju^lStHZN @ns{~qr}1IQ6KK:;'M8_B~L0p^oX\Z({R?D8|!c$ IhҔiDj4 \bJ|lz'*K V*bNh繐j4JĞ)%dN6iJpߧ`;JR<^T*-XHE"4j%G^U<^T(L6L7?  Kw0r'?TN ."k(Dc̉L<*Hq r! JI׋WS y4AGKŒ+4%D5ĒIH_\.RWG,r> ddxhQTeh4_I It_89%'4X hnnj2щ%k}h ܩϓVKϪ5+k!YJPL$V9rxd5b` l3o߫>tSXC8sܹ4řc0h&'M*i&',J@ydp륪!΋E7GVeF"HB@(DK ;bT y(\QRIi?4e ӕRXI(TE%B(T%l\D}K:/pRɃT49#K-ORN|&B^τGi=%gyy: ($6*P3q$|f/1{;x<ce4z{C!a ;-_tnNDǑ~,DVS}EzstY#5e8`0M jmo~3mM4DE,Qqݥf|H#$=yGj"P(lOW5<`RNnl`c{ 'vԼSx< %FJ:* 9^-U*T9U*)5,sNUǤIV<1Ye@/%TL 8N0UU6""? b!I$+&>}rqv>n7IB"'$@~ޥrgiJ=?,#uNI`.h8(HBVL$nڲe?iij{A{* όVj3yDTa'"Y:X.GMڀj 91Q*8ZRAu:D(xVXLxh(Cի)BΓbjK( 񥄗}:eȽ,tDC#cI/l7,ҁD|Lrp _BN2A\4rUZlHU'aM7D\c(G/t0Z-9J+V<T?ko߼()۫iY$~ vǶL<Z#].%OkKi,FUV6iWRR^NKxs3RD~Ng2Q|"DJB^lė:AK|3R,R9P<]-Z2/oɍ bI&+v6-$@&}SCn4 FC2#9];S#֥*/{}Z2c-t:K*-2SJJHjiz.ZF#ߧRYPOkΛF7oӟ/{H/*yp]6 &KANxY,qcd#OSHǪn(DҺR MRﱔ4ӥ-1&]!ᴍ 382|}+)O/֠OH#pB`0śTzLCdBFB: VVr[ʽ{ ?*1Rl0)ҿ=SA94*>qƍ}G5i<ѨVϞ-p< /] ;2?F6}Pz< FKτ;zER9Fcc=WYᣉ@^ ەXiJ RQAuV$B^hqwma%2wX,)DJ-*H"Vyt:A:-Y ?$kbω`2鴣ߝFX(HA_*Rĉ{g~\, UEvVYF`XbɖpPА-ˏ̽ h,*@HRe44l@cYgu$NR%%FwK8ҥhqUe;bة {z߱Ty]rY~hVBD"ҏT@5ZKK?a2i4v `x8^x"7h!̈́ɬ*Ht A^ c|(%%[JE>EeE?6-z2`P#jJ-m h?};,'p(セ1ADJ$wcv`'zƩkEE9rQDRE!+`dqHX2eܦ'Ɨzq:Z-OZہ P6FdpE9M%H~@r=xkkI=NXHRtLldbjkt"XHt:=㱥UV⋀^WRRU iZNq(䁜)_X,`0PCFla6F٬5?cÇNNWT 8Dª7K^MqVU z<ҥZM9UUz=Ida*1:W`vq3K_8L,Yd[ @6Czf!L&S(D}*>'tY>__KS>pz}Qi #r"}uqhI$@Yu OMj6fA=#Դ2hB )3`t:b2YkV T`#'.u?vu:*uri~x8liiy ȑ;j?ni`@jj|>"&GU(Dd~ImP<+_>C*!& S(rr'L0hVj)m%T Xk# e`B$Y !¯JDx\Η$H&nBJKȴnk'ʺq#EV*IEDZ"nN;#o-*|Yu-553g<`AAUUmmm]v" |iJp̜Iq~ TRUbq>?vfsYىd:Dcxbd"DE#ܷ{`u̵׺\j5p?meeݟ[V+TB6S9<*+kjF`'_JEeL&Q .`Pt5yA4e #?ݝPq :T;x< eEu25TEy7:;>>K~逩^\>89^ӈZtS.X(r$d vvw[;.L៩~쟤7$<#ҚF"c~rHU{loip/⭷\py@II~P$ \w(Fs|BhQ9m#[N?%pn6{K^MX(m"AeZ/]fޟwzz#G={:;{$a`"O.V% @&' --@4g? I"|DO&MIJ4Z-`v;0}̙f3@yZ- d [J %pD,f`Lz}SbD 2)7olI뼬(H\B-/O9p}Q,B {Mk/l|G;kFAɳfz= ]xRm(,u Ӓ|, Jņiaȝ&%\nj0z0FJ|ttum~w={zG3oEN!ذa޶6`Φƞn"YU˩w DƍN:=$IPrȶakWGǪU R C]ڨ8|h^{hmA pV@yUUF#I^옪Ȼ54@iiYNTWqW6ljez^r: GU)lDK.tK! #s+WbKZJ or$TVJ3g8טWJ-zfauO&¨fKŵu31[$\t[jŋUr2Mq>paUƍ#ѨѨEcҥT';M,2"Bi@Ԯ4a18ON-Cj H؋ӯAD'I&KyJ|]]pÛ.<|1Ό<sΙ6M,N'rAAa`@$@iIg; С3hޠT*RACzzl )SiO)i0ş\1I0UU*[[Rw72k֜9V+x [JaljPȄjG/Re\6KHxS)%+B);tI$@aaQNG6Pv<^:b^΅PY2TDB I=l{$HV!co/ Xp3Ϥ N5b ++kC^07XRDtL 0 T*Rْ&i~JPg9HW==D4k;'}Wx߳ /GB08448ʕ?P*zDJJK' L^wwv]Kہbry:`DRՏX|(Ǜؾ}ŏ=xxg[,D%I~8MdDK|KcBSSOvZEH6B~BcF3 yq@N _4YF*5m#0WM{ >55f-Xp,h{JIq~vIdhhOnJN4&rg41F l?'vLؾRp* csZ~lLjp`I2z5Zb:FHx)vW(h$˜VӧSRYQ{"%wزԃ'o~SS#4={v ׬q+!:! $h4xU]8%C*u=g8Yt%Vs]7mS،$?燎gSXxH2~:_$^75Ӧ{ɈQ'M9Ng*~?tM 7߃RQEpO# YT:r x3e0Q eeTh2^.{.SJK]8Y@$y<=/'c„S`ɏl\:]& g̡C==\v;U>Ldqj2އBC`0(BBb]IrRK]/]‡"#E& Tdj?Y’K*1WnfIKIӦLvl>0 Q^zEԁO5TR6Gk>;2"yyBq )?!эFi [Z n1+--"p:} P=ɶ>jK,WIFMG7n|s{4A'qϞe˞zh?e@2I u:!4!B!S`8& 0k0ejjtK)*, k!AjuK|I=_x2jt9^hRh%KV˯xMM=*,0+l}m!./! FjbTﱨDɋt DE18HpX*@M 90Y\wnRR2G0.AKjk9UU?80m 7qo]K>%I|PyS&x?UEE',~2Q$EM6s}ܹf3tRh$7{RPas*f1 /y4!ǒW(CF**lGG{{8  PZZZRsAxzYVtd`s!Abbft*FÒ?1p- @f?X0 `ʔ9sK./} 0O@gmu[԰|NǮ]O>@4>bOϞ=[Tn`0$Rl&۞NG̑oյwxa p8j Z-{{)0yǎwZ[Lh:u:n*x6_i)l~ʿ-uwXhʶn| (-\**@.lp`a'ѦV+l6MExs?j2!†(H364f3UTh I˶! FEuk` #I1?JP(:S(W X Y/E=+=d2[cמyX!ipY4z=%ld0)BҜI^JmCM Hi(x}j-uƷDFC //۵cӟ.ՕI3/,-R*>J :;ID0 RRbO'W@2Ҁ]cǕ>1BM/(=^__ooWrĉWW"MD%U-v[N Vat:ZWU @M IDeeZ-e 9Mf .((,s!3Kiy*ytTl6Tde%|`9ϧ;%75F)Ӆ{q_bi sx {zIp)Kn2~憻,'Vqzڀ^OnشiMp]6Evzz]K'T0SG f:2h+us:6:\M/Jp0.6" c^{DeLd0gpDrbd㔼VJY(Jaƌ'._\q1j8t:nMoJJ,ڹsF cR'h@JEejJr D:A* )`D}9RbsS0`kJ7 dv«Jٹi;;wֲeb'W=\YcDTTSL⥑>nL5Rl媶j˥.0ֶn]Gw!G|3dDό|R*IsFIuum^Db2E"c;,5 iixTqb,) )t @TiqWS3a> [PqI"xSonO?hO1"&LX1kVs}qbD/h9_ⷿ ф}~~7mHu9epb{0v@8gO(vHe0Rɽr/S$U{Es Fܗ^\8*ǁΎzޔ {}}]] F#Kσ|U*N60y8^IՕ:rpR| k׶ڦ:lQ(Hh|o"[}餶՜k)nWH [Z_ճ{En/*ߗfR#![j`gg B􍊊*VGD\܀$3)$BAvSMƷd^+8oRT.'٪&L>s_1󥗞xxeo~s@{vgjN?tH&hh0lF#_[k6Fwi"R5f*tؘ'"3^  xrښɓ.eM]8Z2=eG "LUYq3ŨtZ-RR=.WkkOb˯_Lq#W\t)޾`}@7IsOtbdAA2V Px B9t|&<&'Y^_ R4J{mm]gV%[wo>/nQ '@[*Uy@E>_?XA5Vr2ߚ)S[s'wկ`zu#cHL,ÔN)MfsQ 64XNGHٛ+CdOZomm@oΝl")綱kjjoO=V)#b63?~:qF&N>7<M{hfwW2ifi^bV1K(((*R)CmDBZLzF<'u4'%{_s$$Bg dTP({|~>z{{zb1{)xG̹xɑ}B9T0NrԜ'? |snoӟ+W>? x\Llr3[U&XJ2 47Q̘QXt"ud:ommkh\\V*1r"L?gFVKe,&$T\Rmx6ML blSsG&*#mm@WlGRՍFϿ.70|p5ӧ;@MM^ތ_w+=6̘̙p!l19溧ԌFʵM$HӑK98,lU|J|RA Cx|wP)/Wn/g|S-N;2Zf.{Gᢋ x{vׁ޾tHNt"d)%nQlrhC%m.6HP\. *񉭀TRRY>n:͖=a.R5=9TrTz6eLp[Iv=~UZf+~Lp饟{g./brJGn طoښ'NL̙$2qlv;U:fJTwI)Hj3(:RsYpST^$/59mD?"dqw::(0zma ),|]o|yep,p̩;QfϾjή.@d$gV2mE"=kٜfj)_<D"dA M=l*g3$(*Zq7󟓄*-x<Ν/@0#ȽY" DŽ 4)=Y!!|>_j5OZ\KNQ;&8s'LF*() 8|xRJR(D01Ll{qg{(@To<IS*oOtົ;:q`ݺիC!P(.+_.kL&;9'lc NN8Fc+<46C7 |Nunsj@*{zdL|oD^/PJxߗ~f |0.ߟ{nM  RэghDQvh .30 }j8|]nu&K-^ÿ=3K_~:kɒS~$vK}+wZD׮Ofxx" u:t;L;9 )qR\EػKKqfH z$p=0gT6mk+` s3ޟUUyyӎ2\{p]7LD#UISc'/A᱈G S__(+>}޼3y763̆t[`vJ> hFF_0x@ t|ُmKv9poo/|xBӟ_߱gHd; $mmKEE60y) 0u*j)$9W!2<؎M|ݱx@8 45ZBlֶlf 8Hb[fJe,sM(..- jX BA8NQ\rq;8ߟH(`4Je~~c#־ PR<{p0pS6>H$(+7~/X._Dc%̟E|+?|T⬫;.7y y>nyݞdTFOq_ /]{^N`֎W_}=-[u\@;H&'NI"ˤksȶiJnJ%׃ *6@2pUUW +*IqZhh(('>6`"\ԧիW^F8^[Xs*omYg.Y|hzzdžիہw}^N nl8MFWxׁөD2]]5Œ)IDATOc#47a @(|G%Qֳ^VMޠј̀Ţ9$UVVk}PVf?tn|΁Kի6nܺu۶LG&cUyJJop%?ħ>$r_z閛/صOSJIc%%Βb٠x룏>M+V<r![E٬T{B…3ft7TTqƩq@sHA, @o]7I]6M0e PR2gYgQt_E99!->?d9Ç9!-rC9[0r`90n#ra"G9øEs!qC9!-rC9[0r&dk8%tEXtdate:create2010-01-22T02:44:07+01:00ZrUk%tEXtdate:modify2010-01-22T02:44:07+01:00+/DtEXtsvg:base-urifile:///home/chenno/projects/elyxer/test/elyxer-svg.svgT IENDB`elyxer-1.2.5/forks/jras-elyxer/test/helloworld-raw-good.html0000644000175000017500000000011312117061342023453 0ustar chennochenno
Hello world
elyxer-1.2.5/forks/jras-elyxer/test/rabbit-walrus.png0000644000175000017500000003767712117061342022212 0ustar chennochennoPNG  IHDR[,ƽbKGD X pHYsdd vpAg[3=?JIDATxy|]u?sd_n(,Ȧ"8#WqtfQd~7ø⸎ JqԯETvJe,h6MIsM.sy=iܜ6YU0DDDD!M  """ -*DDDZ,T(XQhP!""bBDDDBB  """ -*DDDZ,T(XD}wܝm0t08) zlH~˙ _kh }6QR8 Tj @&9{3rJy^k6@ԎH?DDTXԌ],@_z E+$k/h'…ɔ@ Qp7;R ~ q5Y:U T-q+hͺߓL)""_"NaI(cw_O hQ"'\"w@KfR: y02wgtr0q#Ig"""itnotrt b kxX:IcJ:`mۤTRP >oVt&""4^ !|<ߵF6w7;E ˿Py2$aiNz@iLDDTn -g˰ -Hg #ɶMWt*W{h9F aU6 7MҙXPydptj8/;dmDDD¡q{4V:K5K %nODT};tsFH = DDDB%t3Ԓ޸5_'J8K֎ҙhX+tZ)0ԼisDDDavz x0J:K[2zd rnϟ;/L4otɿjd @ ?Le^p牊ڥ3ЄC} 7{,Dt`X`8(_Բ-P 3K`5;HΕDTi΂n'`؝w6 A}CBUC?zf6p:СbojnG;N: Qcc07{eҙJIa _UWϷzhr_ T?Mj@)ߕ{ Rm5# 3*,@G7SB4cs6F:ZՆUBp]lL4*>jP(.t}YpUܭ@Jg}>71@JgcB4#Q:T /ok_-% #'|=d( X͈[2lKg!sDo~H6Zh$3Ė$ QQ2Ns&3j9`2]!}X EXǟ#^kS5pZ\wtjo }פg PY5]>rHt v|8[Hg~,TBC7 kzs(|R];Smq`|1>ugԲC)12s38j,TzeN Y 1S_/h|]}BrtF/9N: _;WHg^,TB~w#D7Eyh6`mkbΠtB%t92 /PP<U6+*' cOR}XQϐBV8eHg!9M|՝6>eeqvW{گUvB =inrxtB% JgV&`xYՉ s-zP -!lx;NBVCYxc}w@+P8;w R(tqeF21HaY(߹ Kg ?BݸQ: UNSr1`%{(EN#=)45%-@祳{TBZʬt:L8!I%0~PYr/ogIgqW'.}pD:KxP ?_[`cR *Ӹa,t83 7Qr:'!XTؒJg[ B(c2S:KP3M\9bF7 P{$jGppKg *UC[&ےA;tF/ٵPGkptaRuަ& Ty3jE9xYv^zg#n2JձP sF?WTv1,BU9t3(% F3wBёKJg*U~qtg4sC2rIg-ϋXTMjȭ x0J: E"So4 X=.*qyL g@2;[5+lK$aJr?s(ʜ;Q M@ݣIgBY?o;˾o?OsFW8iPW[Ջś@׌ k@nF,Od$\BW86ܭYIx op,3WHgBfp(Vs#Tҁ۷2ө)ܣF:M56N 驔t 6ĥKZ( }2($P^{t ܠt9,Tj6~~ a6x1U'.A ;y !t!!r{FKg! F:_`tZוFKz>(hL:*5+vEH[-!L-6E: JͲ58`,?"/(xt0ND $g4oB/AB.1tR3KgB%rWvIgQZGr0;3= DfϮ[(A ȱz*vt*B] )ƽxJ 3cY/t*eoKg\>~ tj,XDV|ey'P\) D:!Ԭe'$*2 g9F$ NoXtRkH:CxP/ڻ3Ptƾ_:wm;R_ɿOn'%#[!TQf0'%#+%Xğu>OS:tsƤ3@)Ð^,TeO3oP: MPYMM;,DMXT#*T! j:"3sujġ^zYƴ-TaNY6/@}AJma ),Jny PeDTEG]G[&niCBt}=l2/.j{THL8g#EƷaW3QPp jt" m> hdZ Jz!|DeX4-(}0M{u3QeV%jet& *$Em.g=,DՉ )wA d+%,= .P^n0\Zx}ju?2T$wr TQ}s-A家\*z-m9S:QuaBE '3SaGJ"1{} sRH?udrBTXPӧJG('È$oC*P)WJaNJg DՁ ttr2x\:@UEZˀD4*TZ&]6n$檔g%?7D'e"My@nL=;tr(@6qKPK8o1)p샋*ocPxsORaIy9o_ ː[}>1]: Q8WU™.u뀉 xaoz*h-Wd8DtX,Th T1*W{{n[nذaÆ 3JR ;^m$::*4C3TB6;00*yW^y]wu]~駟~D2}*&jWoXdbB3w ?Нwywu}>O|~:J=df8cccc \U6\Г… MWM3# /JM;s]u]`ڵk׮^MQAtM7t _~_\A~iTtpNTJɴ;/THWWWWWԯcǎ;vL'J:r׿g?~~o'~mvm3y ;7.h/qQir 0Wej͛7o޼_}ϟ# = N}ȫnoWя~عsΝ;gqJپj?<((X4#3HP&}%\r%GRS}<0:kW9899/ٳgϞ=GJahƍ7nY*ụ3 3= ER:9->^x^8nnXf͚5ktBN_4Ms&[[eMoyqa9ԆjWvU1>DGMPH*}LW&[5yys56o޼yfs9s . .8} C2>PU0vBlڴiӦMm۶mvڵk0{ٳ6ںڣVm}sBhl}_Fw?+%L 65-]LiWR۶ hײe뮻..&x^믿/}K_QVd2}ZLS:[ Dá"wIW(|O@a.Kz{vr]z饗^zd˗/_|b27x7_/͛(q4{0)أBSz3WRuus@<>+&J^^ ȶ,jl,jɺ@Qmmi]X: Ч)Զ)3VxɿV ^ *~ ·YmL* L |{mI9%/PbBG`,* zߓJ+Pw@:_l`hQ* d+̌^Y3)XQ^MY(< / ;-/H`7*ɴDD<>%H :Om)Y}tdPO֌B'ywr2E "㷉3E I5,Th3?.(rǸ" MܴC:QԹͣU̝hXt DB,?VOJ'!F-X4)tߕ{ ,뤈`BӤQ!.@T,Thts *4MjtVIg r4)[X&z~ww?OʥP ^eIJ`v&y 6_4$SsyQ`b}B]-0?g#_,WR~}}~(ŶОUm._-85ߧz7XM=*R3o0 Nw7'f{DJ@X4 s%o xu^ nWuN NZ3W*w)qwԔDnQRvhY O.u+P^n}9dކ݋+o:۽oFWv,G8uzo(DSBN%44߽r%8[\׺"r6NJX=kwGb> [@N8bhY4܇2?]Zvx3w.ĶsnQ-U9I@vZp/yx w9%{# vI6H%{gZU.{sV^o ^I) n {zʷ'-80үd;njwH(WPjt}T锝:xGRkے7uJ͏8\R0|y+b 5LXK s?صK0g7YC?iF'C=E]oeS9Kg)I{tU: Qm`B7LΥ"{UZr1{ :hh=v|.P9E 4oV ¥SLP=R% sy?nt=5>$m*q ԝ=g/7(6PH  JPZ7?Hjρxɐxa ͸34[MpbBQ gK~OVU( 5yۀ}b*Crg2WPD攷 j Tg *Ew];U Q+pS ur :sO>)`oHDT}T(2?X=ulSɫJ0]xq3s@Oó۳z0zb"bnr|/Xz5ڏ=_Dt(P$W;] D 6b.ɭЌ#(QY3 =2/* {73i8G"%0o>ϗNs(3y%h翸g!ZDD4S,T(RQgkI8x5%@U@aDT;XP OU)֩[բKUF:]:U3*)* 7].ll^!PHq-2uPsUF~PhPPP@)IaSo.Ņ3Z`;DTXP$1k0=/rj.nArz)Y.vOtI jB" a^} da]ҍ};t "f,T(:K:W_eN0Ftk^0Ԧmh&"פS5_FV ݘjdݹaP^svUΑN391Uru}yt "F,Tezi&lSJ:[s(oO0RMDU դ 9 x+sCx!?S+2jT)5*ݘCW9˽A< $v\Z:4|W7:r\I7jBG?6NCDՄ զӼ?+CLQx`鮧}]ҭ:W:U*TEz5A o3ct]ph‹ $u9S={s 9ct{s=5)P,T'I+A]p)^/s1[uv6F^(XPmQ4fFY#f;3.HH?( )֑&,;;LߐKOBs&L.î0nLGDBjggst"/ɺۋK0Vk՛4;-&bB3> @Cө[u;[s\gZ|SJ!jBj>3 Z6D[sXm~X" )jKp?)}Y?7߯;cbzNADՄ F_)Cn}^?SSQ5aB5E6S/xNWˊ  Jx,T(7!LkNKq &_݉KSQ5aB5EEW:co0omc"NvP'ݪGm4WP)3g qI뮆khn&jY "ʠJI:$#:?_yi L4DT "𫑢$B {ee)*?]rX 0Yaa4nVK jBjJ on伕rNADՀ զzESX]*nǩwP%aB5IDN19cj1_\ni/ U  MK6%brj0ʹewK*ʣ};;]'Œ $u>ONq\_5'ҭ=:oDf,T6݂TtC>^.ڣ\[NDTXPMRB*COp-ҭ:b DF,T6y[qt>C59 ?l<ǼNADaBjN)^~.n r?ۘt " #*T-P\~-nNN |2P~N:  IO:šORAzt+g~t " *T3M!0a y6nn>_: Ijup:_:š١]_3v[9sjUα!aB5)x2hNq(5l:q9v$ʙ zU)D&,T&MX̑N1AE?Xe,0m|Wӧ[: I>7I`\c/>b,nL(""*TeH3+EJz;} ֦9CD/BjӨBոl>]:3#i}ܬ3BJP!*#DM ]vT}zLҭ:md": *DeOv֦O4Q)(XPmN1||OqtN=F&>`hN Iz)\+Y qt " 3*Tսs_rnsߔ*g݈NADaBjS\7+U/ sS6N]E~+jjD_`蒻s6 $4; !ׂe$t'c.׊Q!#`BW.|@ݢߨz*{6rW0;>vy;h#cB5xrS=iآs/ ڧU`QWY vjӺwJ!jBjҾxr3^o1! zкv{Z $8eqȇ 4}rS?^) ߘn<>%vvc<$q7fɳD4,Ty+b4'K%y}ŀTC[g ijrORY/ɓݕuj%dٱҭ'ZBjUFـJԷ>I-F`ĥ[\)3}@o0Ʀ2g^O9tPHЮ)cio\c|J3Kb-{PI+_DTKXP$h*2ecgtVNZjS O%w$ΐn%"* j]x8vVjzQ²c8F NDTXP$2\7e,R nYx4t3?bܓDDՏ E^J]ҭ:DSxqȦXj}D}Z(2X|ISiK)bVtPhP^\ԟN,SSnʼnb'Ar@U>DT^,T(TzCPleKn@][ggڛҭ (`BѰGQA.gܙNQE?]ܑ|=?5K7 ERV+ݦ♿IbgMY6H'(`BM#Kχy tJhݩ`^K'(`B0>Q,sntcJ< Njޯ:SQPHQO'y3/hͱBt`ا$w[թ^0cFN"&B~fρZ9Fk|a򇩳տ˒bXPfTX7/ӗPbwltSXPܩ?i /zJ4SvD= PVy>>tJ"*-zt6hnL3•_~ ̟%.ӡ_7SQPHQ'MI~D:uñ_w tD%,T(Rԃ*;ǍeSg$jD>U@A*#-U @c*N6U:̯oߘFID,T(ZWkɿ2)ZVoǏ+u `jo65gB"Eu}|طZ~^Z:]>6[S:Q%8I sq`:KN_1[˩`tJ |#h԰԰t"" """ -:QhP!""bBDDDBB  """ -*DDDZ,T(XQhP!""bBDDDBB  """ ̖*IENDB`elyxer-1.2.5/forks/jras-elyxer/test/references.lyx0000644000175000017500000000762412117061342021572 0ustar chennochenno#LyX 2.0.0svn created this file. For more info see http://www.lyx.org/ \lyxformat 410 \begin_document \begin_header \textclass book \begin_preamble % eLyXer -- convert LyX source files to HTML output. % % Copyright (C) 2009-2010 Alex Fernández % % This program is free software: 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 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 % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . \end_preamble \use_default_options true \maintain_unincluded_children false \language english \inputencoding auto \fontencoding global \font_roman default \font_sans default \font_typewriter default \font_default_family default \use_non_tex_fonts false \font_sc false \font_osf false \font_sf_scale 100 \font_tt_scale 100 \graphics default \default_output_format default \output_sync 0 \bibtex_command default \index_command default \paperfontsize default \spacing single \use_hyperref false \papersize default \use_geometry false \use_amsmath 1 \use_esint 1 \use_mhchem 1 \use_mathdots 1 \cite_engine basic \use_bibtopic false \use_indices false \paperorientation portrait \suppress_date false \use_refstyle 0 \index Index \shortcut idx \color #008000 \end_index \secnumdepth 3 \tocdepth 3 \paragraph_separation indent \paragraph_indentation default \quotes_language english \papercolumns 1 \papersides 1 \paperpagestyle default \tracking_changes false \output_changes false \html_math_output 0 \html_be_strict false \end_header \begin_body \begin_layout Title References Test \begin_inset Note Note status open \begin_layout Plain Layout This note should not appear in the resulting page title \end_layout \end_inset \end_layout \begin_layout Author Alex Fernández (elyxer@gmail.com) \end_layout \begin_layout Chapter First Chapter \end_layout \begin_layout Standard This first chapter contains the reference: \begin_inset CommandInset ref LatexCommand ref reference "cha:inchapter2" \end_inset , contained in chapter: \begin_inset CommandInset ref LatexCommand ref reference "cha:Second-Chapter" \end_inset . \end_layout \begin_layout Section Sectioned \end_layout \begin_layout Standard This section contains a reference in brackets: \begin_inset CommandInset ref LatexCommand eqref reference "cha:inchapter2" \end_inset . It should be on page: \begin_inset CommandInset ref LatexCommand pageref reference "cha:inchapter2" \end_inset , and so be: \begin_inset CommandInset ref LatexCommand vref reference "cha:inchapter2" \end_inset . \end_layout \begin_layout Standard Adding a pretty reference: \begin_inset CommandInset ref LatexCommand formatted reference "cha:inchapter2" \end_inset . Now a named reference: \begin_inset CommandInset ref LatexCommand nameref reference "cha:inchapter2" \end_inset . \end_layout \begin_layout Chapter Second Chapter \begin_inset CommandInset label LatexCommand label name "cha:Second-Chapter" \end_inset \end_layout \begin_layout Standard This second chapter contains the label \begin_inset CommandInset label LatexCommand label name "cha:inchapter2" \end_inset . \end_layout \begin_layout Section URIs \end_layout \begin_layout Standard Now a couple of test URIs: \begin_inset CommandInset href LatexCommand href name "Savannah interface" target "https://savannah.nongnu.org/bugs/?func=additem&group=elyxer" \end_inset , \begin_inset CommandInset href LatexCommand href target "https://savannah.nongnu.org/bugs/?func=additem&group=elyxer" \end_inset . \end_layout \end_body \end_document elyxer-1.2.5/forks/jras-elyxer/test/ert.lyx0000644000175000017500000000714612117061342020242 0ustar chennochenno#LyX 1.6.7 created this file. For more info see http://www.lyx.org/ \lyxformat 345 \begin_document \begin_header \textclass article \begin_preamble \usepackage{url} \usepackage{color} \end_preamble \use_default_options true \begin_modules theorems-ams eqs-within-sections figs-within-sections \end_modules \language english \inputencoding auto \font_roman default \font_sans default \font_typewriter default \font_default_family default \font_sc false \font_osf false \font_sf_scale 100 \font_tt_scale 100 \graphics default \paperfontsize default \spacing single \use_hyperref false \papersize default \use_geometry false \use_amsmath 1 \use_esint 1 \cite_engine basic \use_bibtopic false \paperorientation portrait \secnumdepth 3 \tocdepth 3 \paragraph_separation indent \defskip medskip \quotes_language english \papercolumns 1 \papersides 1 \paperpagestyle default \tracking_changes false \output_changes false \author "" \author "" \end_header \begin_body \begin_layout Title ERT Test \end_layout \begin_layout Standard This is a test for Evil Red Test ( \begin_inset ERT status open \begin_layout Plain Layout TeX \end_layout \end_inset code). \end_layout \begin_layout Standard Pure TeX can contain formulas: \begin_inset ERT status open \begin_layout Plain Layout Equation $a=b$ \end_layout \end_inset . This activates the dorky math mode. \end_layout \begin_layout Standard It can also contain arbitrary commands: \begin_inset ERT status open \begin_layout Plain Layout \backslash $ \backslash url{http://elyxer.nongnu.org/} \backslash Circle \end_layout \end_inset . \end_layout \begin_layout Standard ERTs can be left open \begin_inset ERT status open \begin_layout Plain Layout { \end_layout \end_inset and be closed afterwards \begin_inset ERT status open \begin_layout Plain Layout } with text \end_layout \end_inset . This allows us to apply commands to arbitrary text: \begin_inset ERT status open \begin_layout Plain Layout { \backslash color{red} \end_layout \end_inset this text should be red \begin_inset ERT status open \begin_layout Plain Layout } \end_layout \end_inset , \begin_inset ERT status open \begin_layout Plain Layout \backslash url{ \end_layout \end_inset http://should.be.an.url/ \begin_inset ERT status open \begin_layout Plain Layout } \end_layout \end_inset . \end_layout \begin_layout Standard ERTs can also be inserted in formulas: \end_layout \begin_layout Standard \begin_inset Formula \begin{equation} a=b\tag{{unnumbered}}.\end{equation} \end_inset \end_layout \begin_layout Standard Curly brackets can be inserted escaping them: \begin_inset ERT status open \begin_layout Plain Layout \backslash { like this \backslash } \end_layout \end_inset . Also in a formula: \begin_inset Formula $\{h\}$ \end_inset . Escaped curly brackets should not be confused with regular TeX brackets: \begin_inset ERT status open \begin_layout Plain Layout { \backslash { \backslash }} \end_layout \end_inset . \end_layout \begin_layout Standard A rule in an ERT: \begin_inset ERT status open \begin_layout Plain Layout \backslash rule{3cm}{2pt} \end_layout \end_inset . \end_layout \begin_layout Standard Other commands can be ignored: \begin_inset ERT status open \begin_layout Plain Layout \backslash fboxrule 3mm \backslash fboxsep 0.4mm \end_layout \end_inset . TeX comments should also be ignored: \begin_inset ERT status open \begin_layout Plain Layout %comment \end_layout \begin_layout Plain Layout but not text between comments. \end_layout \begin_layout Plain Layout % another comment \end_layout \end_inset \end_layout \end_body \end_document elyxer-1.2.5/forks/jras-elyxer/test/plain-text.lyx0000644000175000017500000000347012117061342021531 0ustar chennochenno#LyX 1.6.7 created this file. For more info see http://www.lyx.org/ \lyxformat 345 \begin_document \begin_header \textclass article \use_default_options true \language english \inputencoding auto \font_roman default \font_sans default \font_typewriter default \font_default_family default \font_sc false \font_osf false \font_sf_scale 100 \font_tt_scale 100 \graphics default \paperfontsize default \use_hyperref false \papersize default \use_geometry false \use_amsmath 1 \use_esint 1 \cite_engine basic \use_bibtopic false \paperorientation portrait \secnumdepth 3 \tocdepth 3 \paragraph_separation indent \defskip medskip \quotes_language english \papercolumns 1 \papersides 1 \paperpagestyle default \tracking_changes false \output_changes false \author "" \end_header \begin_body \begin_layout Title Plain Text Test \end_layout \begin_layout Standard This document will test whatever happens with plain text. \end_layout \begin_layout Section Paragraph Justification \end_layout \begin_layout Standard \align block Well, to discuss the implications of that sketch and to consider the moral problems raised by the law-enforcement methods involved we have a duck, a cat and a lizard. \end_layout \begin_layout Standard \align left Now first of all I'd like to put this question to you please, lizard. How effective do you consider the legal weapons employed by legal customs officers, nowadays? \end_layout \begin_layout Standard \align center Well while you're thinking about that, I'd like to bring the duck in here, and ask her, if possible, to clarify the whole question of currency restriction s, and customs regulations in the world today. \end_layout \begin_layout Standard \align right Perhaps the cat would rather answer that? \end_layout \begin_layout Standard That is all for now. \end_layout \end_body \end_document elyxer-1.2.5/forks/jras-elyxer/test/square.png0000644000175000017500000000025512117061342020712 0ustar chennochennoPNG  IHDRJ"sRGB pHYs  tIME +}D tEXtCommentCreated with GIMPWIDATcc`$\ ]IENDB`elyxer-1.2.5/forks/jras-elyxer/test/image-scaling-good.html0000644000175000017500000000624512117061342023225 0ustar chennochenno Image Scaling Tests

Image Scaling Tests

1 Scale

figure elyxer.png PNG unscaled.
figure elyxer.png PNG scaled 50%.
figure elyxer-eps.png Unscaled EPS.
figure elyxer-eps.png EPS scaled 50%.

2 Exploring Width

figure elyxer.png 50% column width.
figure elyxer.png 5cm wide.
figure elyxer.png 50% line width.
figure elyxer.png 5mm wide.

3 Exploring Height

figure elyxer.png 50% column height.
figure elyxer.png 5cm high.
figure elyxer.png 50% page height.
figure elyxer.png 5 mm high.
elyxer-1.2.5/forks/jras-elyxer/test/toc-article.lyx0000644000175000017500000000734712117061342021661 0ustar chennochenno#LyX 1.6.7 created this file. For more info see http://www.lyx.org/ \lyxformat 345 \begin_document \begin_header \textclass article \begin_preamble % eLyXer -- convert LyX source files to HTML output. % % Copyright (C) 2009-2010 Alex Fernández % % This program is free software: 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 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 % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . \end_preamble \use_default_options false \language english \inputencoding auto \font_roman default \font_sans default \font_typewriter default \font_default_family default \font_sc false \font_osf false \font_sf_scale 100 \font_tt_scale 100 \graphics default \paperfontsize default \spacing single \use_hyperref false \papersize default \use_geometry false \use_amsmath 1 \use_esint 1 \cite_engine basic \use_bibtopic false \paperorientation portrait \secnumdepth 1 \tocdepth 2 \paragraph_separation skip \defskip medskip \quotes_language english \papercolumns 1 \papersides 1 \paperpagestyle default \tracking_changes false \output_changes false \author "" \author "" \end_header \begin_body \begin_layout Title Article TOC Test \end_layout \begin_layout Standard \begin_inset CommandInset toc LatexCommand tableofcontents \end_inset \end_layout \begin_layout Part Our Definition \end_layout \begin_layout Section The definition \end_layout \begin_layout Standard A TOC is a Table Of Contents. \end_layout \begin_layout Standard \begin_inset Note Comment status open \begin_layout Section Hidden Section \end_layout \begin_layout Plain Layout This section should be hidden from mortals, and from the TOC. \end_layout \end_inset \end_layout \begin_layout Section But I Already Knew That \end_layout \begin_layout Standard You were lucky. \end_layout \begin_layout Subsection I Want My Money Back \end_layout \begin_layout Standard There you have your 0€ back. \end_layout \begin_layout Subsubsection Completely Unfair Dude \end_layout \begin_layout Standard Hey, I didn't call you here. \end_layout \begin_layout Paragraph A Paragraph For You \end_layout \begin_layout Standard Totally uncalled for. \end_layout \begin_layout Section* Unordered Section \end_layout \begin_layout Standard Just to show that it works. \end_layout \begin_layout Standard And now a list. \end_layout \begin_layout Enumerate First item. \end_layout \begin_layout Enumerate We will embed an ordered subsection here just to fake it. \end_layout \begin_deeper \begin_layout Subsection There We Go \end_layout \end_deeper \begin_layout Enumerate See if it's in your TOC. \end_layout \begin_layout Paragraph But There Is More \end_layout \begin_layout Standard And nothing else. \end_layout \begin_layout Standard \begin_inset Note Comment status open \begin_layout Plain Layout \begin_inset CommandInset index_print LatexCommand printindex \end_inset \end_layout \end_inset \end_layout \begin_layout Section \start_of_appendix Appendix \end_layout \begin_layout Standard An appendix here, an appendix there. \end_layout \begin_layout Standard \begin_inset Note Comment status open \begin_layout Plain Layout \begin_inset CommandInset bibtex LatexCommand bibtex bibfiles "bibtex-plain" options "bibtotoc,plain" \end_inset \end_layout \end_inset \end_layout \end_body \end_document elyxer-1.2.5/forks/jras-elyxer/test/laurindas-anger.png0000644000175000017500000005117112117061342022471 0ustar chennochennoPNG  IHDR[,ƽbKGD X pHYsdd vpAg[3=QMIDATxwU>gzٝe JHФ$rHQ^DQP"+A"b - =@*^ggvvzeBL23睙Lvlv=9ߣJ""""Q@DDD/,*DDDX,*DDDX,*DDDX,*DDDX,*DDDX,*DDDX,*DDDX,*DDDX,*DDDX,*DDDX,*DDDX,*DDDX,*DDDX,*DDDX,*DDDX,*DDDX,*DDDX,*DDDX,*DDDX,*DDDX,*DDDX,*DDDX,*DDDX,*DDDX,*DDDX,*DDDX,*DDDX,*DDDX,*DDDX,*DDDXZhPhd?Zכ̀JVk4S %X8 mm}@0߿e ۀD" z4jn:ШM&hM& jFcWH/M&@f@1m6@Ri4hRSߧIh VTB%,""UrA L$b1 ^u($/P78Z3Rs]0׷ir}x7X$q(LjVk0*VYf@V5ZIJ4ZC1J3Fo0"d lZn /Zhb՚LŀF#wJ*bD9,*78]]}==@_@$b1`@L&YX%%^( Zd60O f|>?׭(RU^oWcIiS`465&SUՌRS3gNjEƎE*Dްa2iE7{ZFc29xsokocw; ^Vǃ2lW1['vIG Cqq]DƢB>08304g/p:gYp8LY8XTh7mz > %:UIQz"l޼o|0KJkw}IXZ;CB.̥er99gΙg6d2F_O{StQA֨gɜ9gϛw%ңիO,PzUz zJJ=\PaaQahk{śnJ:JZqI&¢l@eQG};GEDEJ^Aٹo0fmj7^kn(XTh:;-nٸqrihGD5ǟp JqljNE,*%Û6:+?4D43gz*PUuW]%i}"0Q.aQ!qbزb  nѩh"uuv>FD IJ08z_‚BOᡡ6`/-[VhlXT ivhh͚_2Aܲ~08GO?-:谨`P7Qz{W|q~2x\t4cQ)p`_矋NAD" YK@[ۋ/|3HD|K7)JǃAGt "ܤn.E"d2D "%'On!u(H,*ў޾ ;˵צRZLt "R``f`嚫X)XT TQ1yDd@矿{JE Vk29D!"% 6mNݦHb<%DhoK?ٺm;.NVZFۥ h&ӗT*Z'H$aH$I łA  ^/@"G"? +ֆCN?JD|âB?~Y{Lt\&b  - ו_/ZnV+"w2HH088^og' tw BΝ@($ZsTuuK,DBPڱغ7DQ.PLœ&fsQQsl..nnNtx< @`hhf plkf xvVh*s~k@eGP`Q/ټwy@$tN#h'~:`UU͝˟$L$b1 to|>ksoGMn(.9SE\ǢB_ӳb\|׿N#J47tPY9}|$" ymmRq^z;w Dңh4td24ʧVk5F#Kh,-mir }Ν 7NM IM͜9&P\\_hL$K&0x8<2bכ ,oFC!{RDAK: ~A_RLj'f[H_b̙Q@D4Gˏpjj:?nBѩhOߓVk4:IE&zzڴ ֯l"^87v˵s'08GO? qNE+*W۷?uEɜ3/ hwn?>_uSJ֋.Ft*H{e̞#:E8MMɛٳ @h rG2G"@w'PaQ2f"tj̋.rJ8--yt,Yt10*+g8ޖBp|.`hO7iH4oo#)ƯK*+EB'*-mi9x<6l|SǠ#@_t?? 8sy&VtFT,*%x8Ck_~Yt~B-/om=tYO-n>KY0lo$x4*:}bgZS|CI&o@< yZZ:mә%%M$]]={7 L|q=fp?Y/cQ)x*==+Vdzae3QS3D@}a]}u4[Ap׬y%iH)XT T8v۷?%˗9Շ*: Qv45pPWwa3e~++$aQs?tw˖lsV^~Z՚Le^Y9w.P_\#EXp>{iH4^JGIZx֯?wַߒ6fN}_}u 6Q!7nᇁD"ŕ l*.&O~Z: D Jx6n׿к Eb)/Z[/yVO##W~ɤ'-TT,Xpe@Y_x4m,*9BS20O= {6mz5 x"Nٳ/X,E!R;x^f4jn&O7zJn%]Phppv``'`سyoP% Jh4z}4Dt65-^ D"08u?!:Vz zEE!b1z{~<ßo|5* * E>bڴ~kF toj5ktΚt)`4M$:eOvK^l. ky| /<~2)(#Mt*4,G_wv,[v]@WݗrҥS`ZS9GtKnܸWELcQɒD" &3qr5FZBN%%--'(ojfzѨ78(: e J;:^y?|?*ȷrQzTgN2v&ۮ¢a|SȎ+:Mj ]ZI9iZ^>k`6L,:|mm}^.cQy)r`'irWiIJFc0NIjZ ZtW^('HQ\pNw2ʊwݶmJi(]%.C֬y C!irVk4:0MRTS"!VRIDVMYT@0^үFb)):0s2v|w44yKmAF zn}~ZZN;MI':plPSSY MMuuP[[U%%@jC^ 1CD ʞfiNeey9WWjQq:9Ft@lo6NEŢfphhMt#zeLWLPZtG24:SQQZ сGwgcvl|vf=,*i8~lʃ(tD^UNeeY,t\\D2 /<Ӎ@(r!:Jz=tN&:Zy yS:"vȗvu-_~{taQI3Z3l*.&LōSMJ}3QJI%-6[yy>Y0ۻq#r^쳢Ёiu5fIj~[tܡ[,^QoT U^Y7AtJM8쫘&OޱX<2F ^ʿ#\n2l*i~e%|SOUO> -- z}QQmT'dںhCRZٸ*2.)7B!ڪ6˅@+gعd4M@4X]tL: fIrQ GMS_"@W=xɡdҲ`Q!3Z^'%7͎՞++F~t#~ En ||]>>(/*J-VQQm\TQgm˖NC{bQZ5_Z6w׾&:M.Do2td2xD柨|[YhjiލRɟwrAFy\.2Nvɏd-3NK_ʕJ:NC2 +)9~hL&"V Ie/sΝ;wsΝ;w./|9 $(cEb"#y&3(3b`3 ONC2 WVL>NѣJ&XLd%ҦO?O>O>$GfʛooygyF3^OJ^W uMTXᨩ90i0G'? >9oE)XT'teJsUhX, d|hOңߎyGy$W>-6ןkFʞ"^^:-e*F%k%q^%Q2㕭y%<&u֭[7o޼ysގ(H~4z=x|\?E \$Mqa2eО)˞3E>E$_0z])TB,*@O @ յv4E%Xlb)=ǢP8)k/ʞ\.˟ΩY J?E_,*YHD,*JIK ^bt8|颶GhۣQ/o߾@4PhdY, NAc!eۑW*'^U2Hƍ*:LaQɲX@<c+O*tLn8N4䏟2 {Ktâe#:'@wdDt\%.*Ogygs%\r%y Ê+qv /cQɲPھMt ڷ>Lܸu}w]ve]vD^&/Szx<6,[&:E`Qɲp&:[4*WZ:0 |Up8{|}Û7&ۖӃE%B!kv)|>_t7p 7<>=s=]y2}:& n>J,OWt:0UFcSGK{TE.,W^z5o}[0yɓ'6ʷq|7|3aÆ 6K,YdI:i4,*⌌}Y nޔ"ekd|[n̙3gΜP\(>Ν~q6E6dI ӳa4v<wrKmʺӇh"x<&cQɒ`gz)h|>iJ$΢$7#0{^x8ɤ4oo#ir$dA2 7NBrݢ3(8+҉[ :,*ݝ@< e'PsVNދ20+ (E"  sdX0ȕ24@(Β rqc~54ң}/ TBm[E],*to_'JfԋRIwSEyK::gݴiV`2+|i1Bb`3,ݮ̻ƎE%Â޾ \QC垞/a`{QVD" ʕݩ@+/[" W  I$bPn&wTMnM"/?"qOot #}WVw&fd'`Q; lH$8jNg6N1ᰴi[Zaɵ1~k%VLV{~CR2GNK.ʙ:EFȓE%C>n=dr:y=K>(mjtb+B7h6~\pz+k`x땊^n>]h@E%CBA^>8z&(:E:==JicM$yA'KZIٺuxXxɏ0xlyXrA4N`ŲPdH8vN;LID{>/UzV|6o?'N۴ihH'~?y%%HD"ޡ㥄 N;ʹsEȆ=7;`6Lx;7xɛS~ ezu9)&}ŤC6h4Ml3eG<ΟcQIX,px<' 6[MJt ht:,*,yӮR"?qw04J}J"y)_ٺ=$|t ݋\"gY,? $–D<I{U\.@ZDR>v4ŤO@?ZR\\Wp44^qxc{)TD{N7W/ Jb~f/mGmFK{(m&Ɍ`0y|AMMe%tڜ&_ҞGrl>F~'DX(/ܹOz&[Zr)xHg}xG p6{*/>&ˏ\.WLY"r 豨7^QqA`J?S.:htDFI%=LFӾOhwD$¢2z,*iLʻioΦ+nRǿj1,qnl{cc!GâfvN:\RX3fNCe4aw+{;WgZ`HwK/o:VdǣQ2=ZKϼ&ɤ4O"?nk4^n"݃$Hxhȣs@ǣQ>;Zg4\gDP& 0E'ڰahHıpX$M$ yqZ"wL篽]]k׊N<FP.oE޸Q>6]TP=DD|ܖ]4IM2NѨ70GEQ..M? aGD~NX;cQd2DۀX,T1Me0¼l0?lߞɳӓݽ14:06=j--4Qw@wS)^oҭ50+5w$_n71PR$:EaQ9t;nF|;vTwHdsL B!H@4 n3F)r>$D,tv.[v]wd붕N{ZE%wT61##]Ztc0X,_z?7o^Bt*"1Z>RO>",*o-~WgNE$ZV+tvʣIx\7p6o&wTNLSN{ ~EE.(;w>kaAI7mVT|>i*䕔d2b2UVN TZtUED" v @0?/DpnQ`P pWRS3g|v[ۋ/r n :UFA)hNQ]XY&7wnEEy9Muڮ.`jjDʼ6nܱc6`ǎΎp<`ߟHH0EjZd2v?h4j5`L `4z=tz=PTdl@iiqqq1PUUVV^TTh0e/Hsp^n l O8ՀJ̜YVt6jj5B͜dRz4;2"%VkCa?h4fsQ7$08}̙s饢Oww?󯽶|9rf͖-6x6ի\ˏdh1{5_’o^~|X߽ro/W.ilƲIS-*tK+tB{>L&TwS{|$Oʊѱrhl b~%:H_'mm|(pXt;?D{4%l֖ |Ba`ǎUcaT`tx<8'/@ J#@޶ǐM6wuWT:"cʔcSfY-ѩ&n֬ɓL~3Bt*:h4MЎ˗~NoNQx ==׋NAVk@yG~W)+NXSSSGG"ZIwO7x*%st:E%XT --G*z\ yQXjZ⋿ ?0N@QdZ\\,_:V^.:E)uuY#:b55͛d6KsJ+*$5u'uԢE߃>0PUUVƟs@R*hO1vѡ׾Q&}QD=.iHjtF`a--&~c!L>cTni3UqTLj h hF+V}Q 97uuVk2IymWAQVUH6B9|^s9餓O*UT$uxr8v/&Zٜ`()i~a o,:b067g-ZW9T5U`;몫kONJUY%^)ZχJc08 S(*}}6NAGuj몪&\A×uǟxhG9Hn4F;lYTxk=z=/llpQ .qEeOڪjZ&ȭCDuuuu_ÿp%gq晩D4:?o97_+>E Q4AIUG@Q@UWW]|jNw(<{׿.hɒ3H=(t6bc=tΘ1u*X,Hb3$j^g6Xhy_TED Qr싼ץAt_L$Ud2wGD?90sfkɢeN'mJ~/ӧMKI$"_{?ƒҦlƧb2UVN 6[9X :~WTv=8UNLJ,;cƤIrW^y5Kv͛ FcYiKET*9cɧNB){L̅5_~4/.K.8>̿d2Eh,-4It *ųf-] Vk & L$DgaUEEi)u)ᘴ||9#~\eɒ%K,no%{o7B!}0fmO|RfoiYx4-x(N{lE]tLA:eRZ*=1D,86\}^r O> \u\|1PTd)yDҥK.] {={/ouLQtYgNA,*bU^&iӮ|lvWI =dvE/x?ᩧ}8hԩؔ:V \}UW]}5ͳlf\\790!,ڃLʊӁ`wx<"ɛvc^~Oda8l(e0 !D";i͙g{gߥ7nڴi+++VXbyBCc` 7t7fodt QgzMDWTdG̻" + =)\dSF_6}QhH$wU8":v{*NzD%HdzwMU}2iӦMzy]wzu֭[lݺm֭@oOOwo??? խp@VAJKˀӧM>8OiHɌ&(.*F%%rιPE"\YVfK/vՊNA{bQCq̙k Nj-+Ģ`Z²d4.!:)| ) >|YgI?J ]6)2KRy4ZZV&:Eet:Z': MT8<4ԶSt Rt:EEXTxSO&*q;:ޅBDY%<8,* j̦"ihX,"Wt"RJ3SS<,*RZ-(2uqDCCܫBJx)tVk)((Y &:MT$v++Zu7)(Y,uuռF=OWD$jEcQ%͵5sNCx<=Sh4:'*Y,5gNAx<STj~7T,Ռt׋NAKc1i@XTƈE%%H@4NCDD¢2Fz}qq]ZG/g㡐#:)A" Sо[%g~44^X BDHD/,*TUuW]* E JD"ŢаGt  P㏿i ܡNDB,*ox<"Wt  Rcm55'x̀Fc4ڬSсdRӊ&C!iEĢ&%%tWE}Q(.1E!Jx~&"v;9ZqXTҬht~Tc_ut̼AtJ&c1>HaQQ4*V#: )S;)vuebQI/&T*?GU%P]}q_/: Qf ^ѱz'~+M@g ǣQiz4b(Q"wI<,*i68O=%:VkcᇋNCWT&"L&I`ddǎd,*ilܸ|90'HjNg2UU]q4D\Q@{:)HƢ2A##۷ZtuE#b@**D!ʮX,E}`_矋NA2jhh͚_zzxg? I VcSZz!+: Ѩ':E nI5T4NtŢ2Jt7LW?0nٲbT$++? /*Td"D".Yr_D<D##^_TTS#:UbQ9;}|bqhHt*tVki PaFGFR)="XT / x<6.[&:KY_xWRqPYfD##|& dp׭{g W2l*.J pno"pү2lQ ہ^{AZFt*b猙 TZ^/: X+*HG%("m6s> 9&'DG!ROE?D4=?}QDT4QNKNA ##۷sv&T* wEexxӦ_:;ϻL@M,ffkn^@t"e+;2H1l6)(oJ ӳ~=eIfoj>b!~_G'E_ZtNAys׏{hڿH"Dt[Z.Hvd4fόR)(tݺuۢP+(Vkcy)2Kw8i_/*Ͳb=`Y": 2xwpmifSq1v4E2b;`)A{Ǒ3`p44NA/*d"NAbTWϚ%:2,:E3**&Od9_TT*JMޛb2UTL": 2}|":E3fd9_Tt:Bt J7bdC;c5#gRRd9St|Q닊jjZ5Dt1f vvbqhHte2NdRZCDt1z)we2/*2cʔŋEt1YT$`͢S?Wt(Oɓ=hL&Ͻ<鬫HBE_:V^O4)*)ҹs44^4`I5D!+&oÃ;vNl#w=mʓ7EEVZzg-5rih8(EhH!1EESp/yWT5_s44V-GVa>$lhT+*2y|1uNjNC՚DNY,$o㮿055'tM+H)x<HZDtg2J[ .: UA 5Ѷ~ɒ&ѩ W<S)XV":E++? 4b<j-+#:2͕ӧjVki13JJeBihXTI3x u eG,pnD^XؔW,X_*rh,-mnO?{4jVtDRRr!+:E0g͒VR:Jt(0O㎿zi_462? :UUӧK/F*:҅Eeg8D2#tNALҕ e|I-G-䜔|â2F]q`56q4' d"NC,`MM_6:j\[NCƢ2F*)SnǙ-L&I zyk,tVki)=tΙso؅hm]t `08|6tz8sfE"^oOD&^ɗ\u+RqjD̼C=|)(SXT&?3k  GOX4:2닊jjړNS.?swVun4Ut43/Yr<аt=NCTX>5@oρpdȵs~W*z25x Xuu Ƣ"H$twK+,7 CCmmS) Qa_*6RhvmuH{F)IQ닊կR:. # Alex 20091129: accept all test files as good echo "Accepting all eLyXer test files as good" echo "You should only do this if you have made a large change in all test files" echo " and you are sure that all files come out right!" # first from the test directory for oldfile in *-test.html; do newfile=${oldfile/"test"/"good"} mv -f "$oldfile" "$newfile" done # now the test file in subdir cd subdir for oldfile in *-test.html; do newfile=${oldfile/"test"/"good"} mv -f "$oldfile" "$newfile" done cd .. # and now for splitpart test files cd parts ./accept-all elyxer-1.2.5/forks/jras-elyxer/test/lists-1-6.lyx0000644000175000017500000001135412117061342021103 0ustar chennochenno#LyX 1.6.5 created this file. For more info see http://www.lyx.org/ \lyxformat 345 \begin_document \begin_header \textclass article \begin_preamble % eLyXer -- convert LyX source files to HTML output. % % Copyright (C) 2009-2010 Alex Fernández % % This program is free software: 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 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 % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . \end_preamble \use_default_options true \language spanish \inputencoding auto \font_roman default \font_sans default \font_typewriter default \font_default_family default \font_sc false \font_osf false \font_sf_scale 100 \font_tt_scale 100 \graphics default \paperfontsize default \spacing single \use_hyperref false \papersize default \use_geometry false \use_amsmath 1 \use_esint 1 \cite_engine basic \use_bibtopic false \paperorientation portrait \secnumdepth 3 \tocdepth 3 \paragraph_separation skip \defskip medskip \quotes_language english \papercolumns 1 \papersides 1 \paperpagestyle default \tracking_changes false \output_changes false \author "" \author "" \end_header \begin_body \begin_layout Title List Test \end_layout \begin_layout Standard This document was created with LyX 1.6.2rc2, a great text editor. It is used to test lists, descriptions and item lists. \end_layout \begin_layout Section List and Description \end_layout \begin_layout List \labelwidthstring 00.00.0000 Ut enim ad minim veniam, quis nostrud exercitation \end_layout \begin_layout List \labelwidthstring 00.00.0000 ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est \end_layout \begin_layout List \labelwidthstring 00.00.0000 laborum. \end_layout \begin_layout Description Duis aute irure dolor in reprehenderit in \end_layout \begin_layout Description voluptate velit esse cillum dolore eu fugiat nulla pariatur. \end_layout \begin_layout Section Itemize and Enumerate \end_layout \begin_layout Enumerate First enumerated, \end_layout \begin_layout Enumerate second enumerated. \end_layout \begin_layout Itemize First itemized, \end_layout \begin_layout Itemize second itemized. \end_layout \begin_layout Section Lists with Levels \end_layout \begin_layout Standard First a simple nested list. \end_layout \begin_layout Itemize Level one: \end_layout \begin_deeper \begin_layout Itemize level two first item, \end_layout \begin_layout Itemize level two second item. \end_layout \end_deeper \begin_layout Standard Now a more complex example. \end_layout \begin_layout Itemize First in first level: \end_layout \begin_deeper \begin_layout Itemize first in second level, \end_layout \begin_layout Itemize second in second level, \end_layout \end_deeper \begin_layout Itemize second in first level: \end_layout \begin_deeper \begin_layout Itemize now third on second level: \end_layout \begin_deeper \begin_layout Itemize third level 1, \end_layout \begin_layout Itemize third level 2. \end_layout \end_deeper \end_deeper \begin_layout Itemize back to third in first level. \end_layout \begin_layout Enumerate Now 1st in 1st level: \end_layout \begin_deeper \begin_layout Enumerate 1st on 2nd level: \end_layout \begin_deeper \begin_layout Enumerate 1st on 3rd level! \end_layout \begin_layout Enumerate 2nd on 3rd level. \end_layout \begin_layout Itemize And now mixing 3rd level itemized, \end_layout \begin_layout Itemize and another. \end_layout \end_deeper \begin_layout Enumerate back to 2nd on 2nd street, sorry, level, \end_layout \end_deeper \begin_layout Enumerate and back to 1st level: \end_layout \begin_deeper \begin_layout Standard Now with some non-list text. \end_layout \begin_layout Enumerate And an ordered list. \end_layout \begin_deeper \begin_layout Standard Just the nested text. \end_layout \begin_layout Standard Repeated twice. \end_layout \end_deeper \begin_layout Enumerate Second element in the ordered list. \end_layout \begin_layout Itemize For a still more difficult number: unordered now. \end_layout \begin_layout Subsection And now a new subsection. \end_layout \end_deeper \begin_layout Enumerate 3rd on 1st level. \end_layout \end_body \end_document elyxer-1.2.5/forks/jras-elyxer/test/formula.lyx0000644000175000017500000000303512117061342021106 0ustar chennochenno#LyX 2.0 created this file. For more info see http://www.lyx.org/ \lyxformat 413 \begin_document \begin_header \textclass article \use_default_options true \maintain_unincluded_children false \language english \language_package default \inputencoding auto \fontencoding global \font_roman default \font_sans default \font_typewriter default \font_default_family default \use_non_tex_fonts false \font_sc false \font_osf false \font_sf_scale 100 \font_tt_scale 100 \graphics default \default_output_format default \output_sync 0 \bibtex_command default \index_command default \paperfontsize default \use_hyperref false \papersize default \use_geometry false \use_amsmath 1 \use_esint 1 \use_mhchem 1 \use_mathdots 1 \cite_engine basic \use_bibtopic false \use_indices false \paperorientation portrait \suppress_date false \use_refstyle 1 \index Index \shortcut idx \color #008000 \end_index \secnumdepth 3 \tocdepth 3 \paragraph_separation indent \paragraph_indentation default \quotes_language english \papercolumns 1 \papersides 1 \paperpagestyle default \tracking_changes false \output_changes false \html_math_output 0 \html_css_as_file 0 \html_be_strict false \end_header \begin_body \begin_layout Title Formula Test \end_layout \begin_layout Standard Inline formula: \begin_inset Formula $a=b$ \end_inset . Display formula: \begin_inset Formula \[ b=a. \] \end_inset Numbered formula: \begin_inset Formula \begin{equation} c=c \end{equation} \end_inset \end_layout \begin_layout Standard No more, no less. \end_layout \end_body \end_document elyxer-1.2.5/forks/jras-elyxer/test/index-1-6-good.html0000644000175000017500000004452112117061342022134 0ustar chennochenno Index Test

Index Test

Part I. The Making

1 Explanations

This chapter contains a lot of explanations for terms, which you might want to look up later. Because better sooner than later, although later has been repeated twice. Actually, thrice now.
Do you not want to look any of them up right now? No problem. You will be able to do it later, in the index.
Now we will add two cites in one, just because [2, 3].
As we will see in 3↓, not everything is clear.
You could also look down on someone, but that is not nice.

1.1Magical type face changes in the world

Little more can be added, at least at this point.

1.2Color and colour

At this other point, however, more could be added, but won’t.

Unnumbered Section

They have a right to live too.
  • A list would be nice here.
  • Because it corrupts the next chapter’s beginning.

2 Nomenclature

We should explain what an index is. We can do that with the nomenclature. Normally we will want to mix index and nomenclature terms. But what happens if we actually do? We will know later, when we generate the file.

2.1 Reminder

We have to remind the reader that things will be remembered.

2.2 Remainder

Whatever remains should be explained here.

Part II. The Additions

3 Bulk

We actually need a lot more text in order for our index to have more terms; so we can find out if the links are working. Since they are anchors inside the page, they might otherwise just take us to the top of the page, and we would not like that.
Yes, it would be bad for us. But on the other hand too much text can hide errors. So not much more text is needed.
Thanks for reading us.

Unnumbered Part

Unnumbered Chapter

This extra chapter contains nothing of interest except for a couple of unnumbered parts (one actual part and one chapter).
List of Figures

Part III. Our Definition

4 The definition

A TOC is a Table Of Contents.

4.1 But I Already Knew That

You were lucky.

4.1.1 I Want My Money Back

There you have your 0€ back.

4.1.1.1 Completely Unfair Dude

Hey, I didn’t call you here.
A Paragraph For You
Totally uncalled for.
figure elyxer-svg.png
Figure 4.1 eLyXer logo

Unordered Section

Just to show that it works.
And now a list.
  1. First item.
  2. We will embed an ordered subsection here just to fake it.

    4.1.2 There We Go

  3. See if it’s in your TOC.
But There Is More
And nothing else.

A Appendix

An appendix here, an appendix there.

Index

able:

anchor:

error:

explained:

hand:

index: , , ,

later: , ,

link:

look:

down:

up: ,

page:

remembered:

sooner:

term:

terms:

text: , ,

thrice:

top of the page:

twice:

Nomenclature

generate An activity that requires a source and a destination, something like eLyXer does with files.
index A list of terms with a reference to where they occur.
nomenclature A list of common words with an explanation.

Bibliography

[1] WordReference.com: “definition of elixir”, accessed March 2009. http://www.wordreference.com/definition/elixir

[2] W3C: “HTML 4.01 Specification”, 24 December 1999. http://www.w3.org/TR/REC-html40/

[3] W3C: “HTML 4.01 Specification”, 24 December 1999. http://www.w3.org/TR/REC-html40/

elyxer-1.2.5/forks/jras-elyxer/test/test.css0000644000175000017500000000007112117061342020371 0ustar chennochenno/* * Test CSS */ div.Standard { background: #909090; } elyxer-1.2.5/forks/jras-elyxer/test/appendix-1-6-good.html0000644000175000017500000004234112117061342022633 0ustar chennochenno Appendix Test

Appendix Test

Alex Fernández (elyxer@gmail.com)

Part I. Of How Our Hero Came and Went

1 The Coming

Our hero came in. He was tired. He thought the world belonged to him.

1.1 The Meeting

Our hero met with Laurinda. She was smiling. But our hero was not amused. His whiskers were dripping wet, he was astonishingly thirsty, and the contradiction was killing him. “Give me some beer, woman!”, he ordered.

1.2 The Melting

Laurinda smiled again. “But Wenceslau, you don’t belong here.” What a stupid thing to say at that precise moment, our hero thought to himself. Only that it came out loud. At that precise moment he knew that the desired beer would not be forthcoming.
He turned to the bartender and tried to obtain a beer by the very old method of purchasing it. But being ignored was not one of Laurinda’s specialities.

2 The Going

It could not last. Laurinda’s hips were flapping, and she was hopping mad.

2.1 Our Hero’s Imagination

Our hero imagined her as a rabbit with long ears and a fine set of tusks. In a short time the image drifted to a walrus, and our hero could not help letting his sinister smile giving him away. Figure 2.1↓ shows a gross approximation of the rabbit-walrus.
figure rabbit-walrus.png
Figure 2.1 The rabbit-walrus.

2.2 Laurinda’s Anger

“Wasn’t it great”, said Laurinda. Actually she said it in the present tense, but our poor storytelling skills have changed that to a cheesy past. Don’t do this at home, kids. You want to be regarded for your authenticity, and misquoting isn’t going to help much.
Anyway, back to the story. Laurinda wanted to hit him in the head with a big ham that she kept just for occassions like this, and being a solid Hitchcock fan she was ready to cook the ham afterwards and serve the resulting stew to any policemen that might come by. She was also a huge Almodóvar fan, but she was unaware that in an early film the divine Pedro had copied the scene. Actually both directors had copied the idea from a short story by Roald Dahl, very much worth reading. Although it must be said that in this story it was a lamb leg, which hardly offers the consistency and stiffness necessary to kill a sturdy husband.
But who cares. Laurinda meanwhile had a funny appearance; if you want to see why please direct your eyes to figure 2.2↓.
figure laurindas-anger.png
Figure 2.2 Laurinda’s anger pictured in a mildly humorous tone.
And yet, how furious was really Laurinda, whom we may optionally refer to as Melinda from now on? Table 2.1↓ vainly attempts to quantify it.
Anger Time
1 2
Table 2.1 Laurinda’s anger as a function of time.
For the sake of Laurinda’s furiousness, here is figure 2.3↓ again.
figure laurindas-anger.png
Figure 2.3 Laurinda’s anger, again.
But how did Laurinda compute her anger? We cannot but speculate; here is a stupid suggestion in listing 2.1↓.
anger = time - 1
Algorithm 2.1 Laurinda computes her anger.
The result is in table 2.2↓, proving we were right all along. Also subtables a↓ and b↓ show anger and time, respectively.
Anger
1
(a) Only Anger.
Time
2
(b) Only Time.
Table 2.2 Laurinda’s anger quantified, divided in two.
Interested in that last table? Let us repeat it but without a label and with a table and a subtable a↓.
Censored
(a) The rabbit-walrus does an encore.
Anger Time
1 2
Table 2.3 One more time.

2.3 The Passing Away

Our hero was passing by the village. He had only stopped to say “Hi!” Again here our lousy skills have made us spoil the quote, but this time for the opposite reasons: everyone knows how to say “Hi!”, so we don’t need an actual quote. It is enough to report that the had stopped to say hi, even maybe qualifying it a bit to make do for the missing exclamation sign: he could have stopped to say a friendly hi. Getting all literary he could have stopped to say a longing hi, although this road leads to bizarreness. It could be cool though.
But anyway. Laurinda was so mad, so hopping mad that she called her friend, the Assassin. He was not in town at that precise moment, but that didn’t help our hero as he was just outside town killing people in a small barn. Just for practice.
Our hero left the village, but Laurinda cunningly annotated the MAC address of his laptop’s wifi card. The lack of networking knowledge on the part of our hero (who really couldn’t tell a SYN packet from an ACK) was to play an important part in the story — if he had known how to change the MAC address, which identified him with the precision of a surgeon’s scalpel, he would have been safe.
Let’s not even get into that last scalpel metaphor, shall we not? It leaks worse than the Titanic.

Part II. Of How Our Hero Went No More

3 The Killing

Our hero led a happy existence for a long time afterwards, randomly avoiding all points within connecting distance of a wifi network. It could not last.
Our hero went to the next village, found a friendly Moonrams cafe and connected to the net. Quickly the assassin (who knew the very people that run the internet, and who by this display of nerdiness no longer merits the starting capital letter) traced a bunch of IP packets coming from our hero’s MAC address. He deployed a team of murderous African bees, which as surely as a well-cared-for AK-47 reached our hero and killed him with three fast stings. Of course they died afterwards, being bees and all, so it was an astounding feat this training of wild African bees just for this one murder. Maybe the Assassin merits that capital letter after all.

3.1 The Passing Away

Our hero was undone. He was no more. He was, actually, an ex-hero. We shall narrate his wake soon.
  • But first a message from our kind sponsors. They want to present you the next section in this deeper inset.

    3.2 The Mourning

    Everyone cried in the ceremony. It was so sad that we need an image of this moment. You can find it in figure 3.1↓. Mental note: never pay the artist beforehand.
figure mourning.png
Figure 3.1 A crude approximation to our hero’s mourning.
And thusly everything happened.

4 The Mourning

We have already talked at length about the mourning, and under sponsorship no less, so no further details will be given here. Suffice to say that our hero was mourned. A lot.

A The Rebirth

Surprising everyone, our hero was about to make a comeback.

A.1 Coming Again

As it happened, our hero had never died; he had just faked his own death to find out his assassin. It was not difficult, what with the capital letter and all.

A.2 Two is Better than One

How to make another comeback? This is left as an exercise to the reader.

B Our Recommendation to Kids

Never trust killer bees. Or Assassins.

B.1 Killer Bees and Their Perils

A killer bee cannot be trained consistently, since it will die at the first sting. Better use killing wasps — or, even better, solve your differencies talking.
For the sake of your education, check figure B.1↓. It shows a bunch of killer bees, or something.
figure mourning.png
Figure B.1 A gathering of killer bees. Supposedly.

B.2 Assassins: Inherently Unreliable

Someone who kills people (even for business) is not someone you want to deal with. Watch “Fargo” by the Coen Brothers if you don’t believe me. And remember: a hero under the belt is a feather on the hat.
elyxer-1.2.5/forks/jras-elyxer/test/descriptions-1-5-good.html0000644000175000017500000000537312117061342023534 0ustar chennochenno Descriptions Tests

Descriptions Tests

First description.
Second description.
Third description which should hold all words but these.
Fourth description.
Fifth description with odd spaces.
Mixed font description.
Aneven more difficult description with change of font in the middle.
Animpossible description with intermixed changes of font and color.
A description which leads to fixed text in dif(fere)nt colors. And now some more.
ERT precedes this description, it should be kept.
ERT is the description  and not only the first word.
Word that leads a description and which appears in the Index.

Index

Word:

elyxer-1.2.5/forks/jras-elyxer/test/ert-good.html0000644000175000017500000000404112117061342021307 0ustar chennochenno ERT Test

ERT Test

This is a test for Evil Red Test (TeX code).
Pure TeX can contain formulas: Equation a = b. This activates the dorky math mode.
It can also contain arbitrary commands: $ http://elyxer.nongnu.org/ ○.
ERTs can be left open and be closed afterwards with text. This allows us to apply commands to arbitrary text: this text should be red, http://should.be.an.url/.
ERTs can also be inserted in formulas:
(unnumbered) a = b.
Curly brackets can be inserted escaping them: { like this }. Also in a formula: {h}. Escaped curly brackets should not be confused with regular TeX brackets: {}.
A rule in an ERT:
.
Other commands can be ignored: . TeX comments should also be ignored: but not text between comments.
elyxer-1.2.5/forks/jras-elyxer/test/bibtex-vancouver.bib0000644000175000017500000000115212117061342022642 0ustar chennochenno%% eLyXer: test BibTeX bibliography for vancouver style. %% Created on 20100529 by Alex Fernandez. @article{withvolume, Author = {J. Linkman}, Journal = {Just The Words}, Number = {3}, Pages = {1--300}, Publisher = {Grillomat Snack Bar, Paignton}, Title = {A Little Hors d'Oeuvres}, Volume = {300}, Year = {1969}, url = {http://www.ibras.dk/montypython/episode18.htm} } @article{withoutvolume, Author = {J. Linkman}, Journal = {Just The Words}, Publisher = {Grillomat Snack Bar, Paignton}, Title = {Our Main Course: Prawn Salad}, Year = {1969}, url = http://www.ibras.dk/montypython/episode18.htm } elyxer-1.2.5/forks/pages-elyxer/0000755000175000017500000000000012117071773016074 5ustar chennochennoelyxer-1.2.5/forks/pages-elyxer/math-unicode.html0000644000175000017500000011417012117067647021350 0ustar chennochenno eLyxer Math Showcase (Unicode edition)

figure elyxer.png eLyXer Math Showcase

Alex Fernández (elyxer@gmail.com)

1 Introduction

This document is intended as a showcase of the mathematical abilities of eLyXer; for more information be sure to visit the main page.

1.1 Versions

There are several versions of this page:
All of them are generated from the same .lyx source file; they should help you decide which rendering options suit you best.
Also available online is the eLyXer translation of the latest LyX’s detailed Math manual, which contains a lot more examples of LyX maths.

2 Typography

Math formulae use a lot of different symbols and fonts.

2.1 Greek Symbols

Greek symbols are very important in equations: φ, π, Ξ. eLyXer offers a complete set in both upper case: Γ…Ω and lower case: αω. Also the AMS italicized upper case: ΓΩ.

2.2 Math Symbols

eLyXer supports the whole set of math symbols in John D. Cook's list: ∃∂∇ ≥ . It can also render a few more:  ∝  × . You also get all symbols from Markus Kuhn's list: ⊙∐.

2.3 Other Symbols

There are other symbols like arrows:  ←  → , or geometrical shapes: , . eLyXer offers limited support for them. You might also want to use financial symbols in formulae: ¥€$.

2.4 Spacing

Equations look good when items are properly separated. The main separation is the Medium Mathematical Space: x = 3. Note: if you are viewing the non-Unicode version math.html of this page then you are in fact seeing midspaces, which are very similar but not exactly the same: (4)/(18) em for medium mathematical spaces versus (1)/(2) en, where 1 em = 2 en. Try out the Unicode version math-unicode.html — and viceversa. You can check out what version this page is in the page title.
The command \raisebox is useful to, surprisingly, raise a little box,
raisedoverloweredand back.
Like \mbox, it puts its content in a text box. It can also be used just for spacing:
BV.
There are other spacing commands: \hspace: a b, protected space: a b, and (at “block level”) \vspace: a b.
There should be 1 cm of vertical space above this paragraph.

2.5 Fonts

By default, letters denote variables and are taken from the \mathnormal font, which is italic, αx + αy = α(x + y), with the exception of upright capital Greek letters, G ≠ Γ.
Function names should be upright: sin(2π), log(x), tanδ.
Mathematical fonts used in equations include Roman (\mathrm), Sans Serif (\mathsf), Typewriter (\mathtt), Bold (\mathbf), SCRIPT (\mathscr), CALLIGRAPHIC (\mathcal), BLACKBOARD BOLD (\mathbb), and Fraktur (\mathfrak). For the latter, some single characters are translated to their Unicode equivalents: , 𝔽, 𝔉.
Regular text in a formula can be achieved via text font commands like \textrm: 5  to 10, via boxes like \mbox (prevents line breaks): 6  is more than 5, or the AMSmath \text macro (scales like math symbols) basesupersub. The content of an mbox is processed in LaTeX text mode. This allows text font commands, e.g. a switch to sans-serif-bold-italic, or the phonetic alphabet: sfbfit, tipa.
Units should be written upright, either with \mathrm or with macros from the units package, e.g. as simple unit, km, with magnitude, 57 km, with fractional unit, 200 kmh, or with a fraction before the units, 32 km, (7)/(16) s.

3 Numeration

Equations can be numbered, like (1↓)
(1) y = x
And also like (2↓).
(2) x = 3
Some equations can be numbered even if they don’t have a label.
(3) x = 2y
Notice that equation (2↑) comes after (1↑).

4 Simple Structures

Let’s now see a few of the simpler structures that eLyXer can output.

4.1 Fractions

A simple fraction:
(1)/(2).
Inlined: (2)/(3).
A big recursive fraction:
(1)/(1 + (1)/(1 + (1)/(1 + 2x)))
A nice fraction: 56. A non-diminishing fraction containing alignments:
(1)/(1 + (1)/(1 + x) × (1)/(1 + x)).
A similar concept is a binomial coefficient: (A + 1B). It can be prettily presented:
AB + 1.
A symbol can be stacked over another using \stackrel: xR → y. Anything can be stacked:
dx > 3limx,  headheels.

4.2 Limits

limx → ∞f(x) should appear as x → ∞ in italics, and «lim» in plain style. In display mode, a limit must appear below the main symbol:
limx → ∞f(x).
Limits are also used in sums and integrals:
i = 1x,  0f(x) dx
where the sum’s limits should appear below (i = 1) and above () the . The placement of the integral limits depends on the document class: LaTeX standard classes place them right to the . Limits are shown to the right in inline formulae: i = 1x and i = 1x.
The placing of limits can be configured with the \limits and \nolimits macros:
limx → ∞f(x),  i = 1x,  0f(x) dx

4.3 Roots

A square root: (3). A more complex root in a fraction:
(1)/(1 + (2)(1)/(1 + (2)) + ((1)/(2))).
eLyXer can also do higher-order roots: 3(x + y). A devilish case mixing everything we have seen so far:
(78((8)/(4)x) + i = 1x)/(s + 5(((78x + 45y) × (Ω))/(sin(x + 1)) + 38 km)).

5 Complex Structures

In this section we will explore arrays and related constructs.

5.1 Arrays

An inline array a b c d is always shown in the same line. In display mode, the array is shown on its own line:
12 2 3 4 × yx
Apart from that the appearance should be the same.

5.2 Brackets

Arrays are separated by variable-size brackets: a b c d a b c d a b c d a b c d ||| a b c d |||which might also differ on right and left a b c d or use the empty opening a b c d or closing: a b c d |||. There are also fixed-size big brackets, e.g. f.

5.3 Cases

Used to switch between several values.
y =  x i = 0,         x + 1  i < 3 
Cases may have more than two rows:
f(x) =  0  x < 0,         ∞  x = 0        0  x > 0 

5.4 Braces

Values can be underbraced or overbraced.
a − b = b + c + d + e.

6 Macros

Now it’s time for user-defined commands (sometimes called “macros”).
Definitions can be added as macros. Then they can be used in formulae: 1(2). They can accept default parameters. Again, useful in formulae: 4(5).
Other definitions from the preamble can be used: 3(4).
Definitions on the fly are also possible: 7(8), and used with different values: a(b).
elyxer-1.2.5/forks/pages-elyxer/index.html0000644000175000017500000002355612117071773020104 0ustar chennochenno eLyXer

figure elyxer.png eLyXer

elixir, n: a substance believed to cure all ills.
eLyXer (pronounced elixir) is a LyX to HTML converter. While there are a ton of such projects all over the web, eLyXer has a clear focus on flexibility and elegant output.
LyX is a wonderful text editor which produces beautiful PDF files. Internally it exports documents to LaTeX, and from there to PDF. Sadly there is not an equivalent “export to HTML” option… Until now! With eLyXer you can convert your master’s thesis, learned article, fascinating novel or love letter to a web page that you can then share, publish on the web or import into other text editors.
The user guide can be accessed online. The developer guide is recommended reading for people that want to contribute to the development, especially section 3. For the mathematically inclined: be sure to visit the Math Showcase.

Requirements

eLyXer is a standalone tool: it does not require that LyX is installed to run. It can convert documents generated with versions of LyX from 1.5.5 through 2.0 (and probably earlier versions). It requires Python 2.3.4, and should work with versions up to 2.6.1. It has been tested to run on Linux, Mac OS X and Windows.
Resource usage is minimum. Converting UserGuide.lyx (154 pages, about 40000 words) takes less than 15 seconds on my Asus EeePC 1000H, which sports an Intel Atom processor at 1.60 GHz. Memory usage is also quite frugal, remaining at about 35 MB even with in-memory processing.
The output requires XHTML, CSS2 and Unicode; any CSS2-compatible browser should do. Minimum browser versions for some popular programs are: Microsoft Internet Explorer 7, Mozilla Firefox 3, Safari 3 and Chrome 1.

Usage

eLyXer is a command line tool written in Python. Installation is done using the included installer; just type at the prompt as root:
# python install.py
or, on Windows:
> Python.exe install.py
Basic usage is as simple as writing at the command line prompt:
$ elyxer.py document.lyx page.html
or, on Windows:
> elyxer.py document.lyx page.html
where document.lyx is your LyX document, and page.html is the resulting HTML page. Write
$ elyxer.py --help
or see the user guide for details.

Downloads

You can download the latest version 1.2.4, created on 2013-01-11, as a zip file or as a tar.gz file. For older versions please refer to the project’s download area. See the change log for information about past versions.
eLyXer (including this page and all accompanying materials) is free software: 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. See the LICENSE file for details.
math2html (and math.css) is released without warranties or conditions of any kind under the terms of the Apache License, version 2.0.

Contact

You can contact the main developer at elyxer@gmail.com; he really likes getting challenging documents and making eLyXer work with them. Any document sample you send will be treated with the utmost confidentiality.
The author lingers around official LyX mailing lists and monitors for mentions of eLyXer. You can also join the low-volume mailing list, where announcements of new versions are always posted. Bugs can be reported at the Savannah page; features can be requested too. Feature requests that fit in will be added to the wish list.

Acknowledgments

This little project is my little contribution back to the wonderful LyX community, for all these years of fruitful use.
Thanks to Stevan White for encouraging me to publish the tool. Thanks also to John D. Cook, rikal, Bradley M. Bell, Markus Kuhn, Jens Nöckel, Günter Milde and LyX developers Georg Baum, Uwe Stöhr and Jürgen Spitzmüller for their wonderful lists of TeX commands and Unicode equivalents; to FileFormat.info for their complete tables of Unicode characters. More thanks go to Christian Ridderström for helping me out right at the start; to Ignacio García for relentless encouragement; to Abdelrazak Younes, Pavel Sanda, Günter Milde, Olivier Ripoll, José Matos, Iain Mac Donald, Uwe Stöhr for their interesting suggestions. Thanks to Uwe Stöhr, Hans Bezemer, Sara Teinturier, Vladimir Ermakov for their translations. Packagers Sven Hoexter (for Debian) and Uwe Stöhr (on Windows) have helped with their work to make it easy to try it out. Olivier Ripoll, Geremy Condra, Simon South, Jack Desert, John Boik, Yan Wong, Jose Ramón Álvarez Sánchez, Günter Milde, Pascal Francq, Marco R. Gazzetta have provided quite interesting patches. Davide P. Cervone has been extremely helpful and responsive about jsMath and MathJax integration, while Paul Hunter has also gone beyond the call of duty with his help integrating MathToWeb (which unfortunately has not been fruitful yet, due to my lack of skill and certainly not to his lack of interest).
Thanks to Nikos Alexandris, Joachim Kreimer-de Fries (Osnabryg), Richard Talley, Wolfgang Keller, Murray Eisenberg, Robert Orr, a Linux guy in Singapore, Anders Ekberg, Pavel Sanda, Steve Hastings, Sven Hoexter, Xie Chao, Uwe Stöhr, Jürgen Spitzmüller, Olivier Ripoll, Konrad Hofbauer, Eduardo Grosclaude, Ken, Jens Nöckel, Dr Eberhard W Lisse, William Crocker, Sara Teinturier, Hans Bezemer, Jack Desert, Hartmut Haase, Rainer Dorsch, Wolfgang Engelmann, Rodrigo Benenson, Stefano Franchi, Steve Litt, Paul Johnson, Yan Wong, Yaron Goland, Francis Girard, Rene de Zwart, Jose Ramón Álvarez Sánchez, Günter Milde, Axel Jacobs, Tiago Pedro Alves-Ferreira, Hoy Loper, Bob Alvarez, Tommaso Cucinotta for their testing and bug reporting.
A silent “thank you” goes to all those who downloaded the tool and silently tested it to their satisfaction (or were not bugged enough to write about it). Thanks to those who have criticized the tool for making eLyXer improve every day, if only to prove you wrong. And finally thanks to all those who have helped and yet I am now forgetting about them, for not hating me for it.
elyxer-1.2.5/forks/pages-elyxer/math.css0000644000175000017500000001116012117067660017536 0ustar chennochenno/* * math2html: convert LaTeX equations to HTML output. * * Copyright (C) 2009,2010 Alex Fernández * * Released under the terms of the `2-Clause BSD license'_, in short: * Copying and distribution of this file, with or without modification, * are permitted in any medium without royalty provided the copyright * notice and this notice are preserved. * This file is offered as-is, without any warranty. * * .. _2-Clause BSD license: http://www.spdx.org/licenses/BSD-2-Clause * * Based on eLyXer: convert LyX source files to HTML output. * http://elyxer.nongnu.org/ */ /* --end-- * CSS file for LaTeX formulas. */ /* Formulas */ .formula { text-align: center; font-family: "DejaVu Serif", serif; margin: 1.2em 0; } span.formula { white-space: nowrap; } div.formula { padding: 0.5ex; margin-left: auto; margin-right: auto; } /* Basic features */ a.eqnumber { display: inline-block; float: right; clear: right; font-weight: bold; } span.unknown { color: #800000; } span.ignored, span.arraydef { display: none; } .formula i { letter-spacing: 0.1ex; } /* Alignment */ .align-left, .align-l { text-align: left; } .align-right, .align-r { text-align: right; } .align-center, .align-c { text-align: center; } /* Structures */ span.overline, span.bar { text-decoration: overline; } .fraction, .fullfraction { display: inline-block; vertical-align: middle; text-align: center; } .fraction .fraction { font-size: 80%; line-height: 100%; } span.numerator { display: block; } span.denominator { display: block; padding: 0ex; border-top: thin solid; } sup.numerator, sup.unit { font-size: 70%; vertical-align: 80%; } sub.denominator, sub.unit { font-size: 70%; vertical-align: -20%; } span.sqrt { display: inline-block; vertical-align: middle; padding: 0.1ex; } sup.root { font-size: 70%; position: relative; left: 1.4ex; } span.radical { display: inline-block; padding: 0ex; font-size: 150%; vertical-align: top; } span.root { display: inline-block; border-top: thin solid; padding: 0ex; vertical-align: middle; } span.symbol { font-size: 125%; } span.bigsymbol { font-size: 150%; } span.largesymbol { font-size: 175%; } span.hugesymbol { font-size: 200%; } span.scripts { display: inline-table; vertical-align: middle; } .script { display: table-row; text-align: left; line-height: 150%; } span.limits { display: inline-table; vertical-align: middle; } .limit { display: table-row; line-height: 95%; } sup.limit, sub.limit { line-height: 150%; } span.symbolover { display: inline-block; text-align: center; position: relative; float: right; right: 100%; bottom: 0.5em; width: 0px; } span.withsymbol { display: inline-block; } span.symbolunder { display: inline-block; text-align: center; position: relative; float: right; right: 80%; top: 0.3em; width: 0px; } /* Environments */ span.array, span.bracketcases, span.binomial, span.environment { display: inline-table; text-align: center; border-collapse: collapse; margin: 0em; vertical-align: middle; } span.arrayrow, span.binomrow { display: table-row; padding: 0ex; border: 0ex; } span.arraycell, span.bracket, span.case, span.binomcell, span.environmentcell { display: table-cell; padding: 0ex 0.2ex; line-height: 99%; border: 0ex; } /* * CSS file for LaTeX formulas, extra stuff: * binomials, vertical braces, stackrel, fonts and colors. */ /* Inline binomials */ span.binom { display: inline-block; vertical-align: middle; text-align: center; font-size: 80%; } span.binomstack { display: block; padding: 0em; } /* Over- and underbraces */ span.overbrace { border-top: 2pt solid; } span.underbrace { border-bottom: 2pt solid; } /* Stackrel */ span.stackrel { display: inline-block; text-align: center; } span.upstackrel { display: block; padding: 0em; font-size: 80%; line-height: 64%; position: relative; top: 0.15em; } span.downstackrel { display: block; vertical-align: bottom; padding: 0em; } /* Fonts */ span.mathsf, span.textsf { font-style: normal; font-family: sans-serif; } span.mathrm, span.textrm { font-style: normal; font-family: serif; } span.text, span.textnormal { font-style: normal; } span.textipa { color: #008080; } span.fraktur { font-family: "Lucida Blackletter", eufm10, blackletter; } span.blackboard { font-family: Blackboard, msbm10, serif; } span.scriptfont { font-family: "Monotype Corsiva", "Apple Chancery", "URW Chancery L", cursive; font-style: italic; } /* Colors */ span.colorbox { display: inline-block; padding: 5px; } span.fbox { display: inline-block; border: thin solid black; padding: 2px; } span.boxed, span.framebox { display: inline-block; border: thin solid black; padding: 5px; } elyxer-1.2.5/forks/pages-elyxer/math-googlecharts.html0000644000175000017500000007254512117067647022414 0ustar chennochenno eLyxer Math Showcase (Google Charts edition)

figure elyxer.png eLyXer Math Showcase

Alex Fernández (elyxer@gmail.com)

1 Introduction

This document is intended as a showcase of the mathematical abilities of eLyXer; for more information be sure to visit the main page.

1.1 Versions

There are several versions of this page:
All of them are generated from the same .lyx source file; they should help you decide which rendering options suit you best.
Also available online is the eLyXer translation of the latest LyX’s detailed Math manual, which contains a lot more examples of LyX maths.

2 Typography

Math formulae use a lot of different symbols and fonts.

2.1 Greek Symbols

Greek symbols are very important in equations: \phi, \pi, \Xi. eLyXer offers a complete set in both upper case: \Gamma\ldots\Omega and lower case: \alpha\ldots\omega. Also the AMS italicized upper case: \varGamma\ldots\varOmega.

2.2 Math Symbols

eLyXer supports the whole set of math symbols in John D. Cook's list: \exists\partial\nabla\geq. It can also render a few more: \propto\times. You also get all symbols from Markus Kuhn's list: \bigodot\amalg.

2.3 Other Symbols

There are other symbols like arrows: \leftarrow\rightarrow, or geometrical shapes: \circ, \square. eLyXer offers limited support for them. You might also want to use financial symbols in formulae: \yen\euro\$.

2.4 Spacing

Equations look good when items are properly separated. The main separation is the Medium Mathematical Space: x=3. Note: if you are viewing the non-Unicode version math.html of this page then you are in fact seeing midspaces, which are very similar but not exactly the same: \frac{4}{18}\mathrm{em} for medium mathematical spaces versus \frac{1}{2}\mathrm{en}, where 1\mathrm{em}=2\mathrm{en}. Try out the Unicode version math-unicode.html — and viceversa. You can check out what version this page is in the page title.
The command \raisebox is useful to, surprisingly, raise a little box,

\raisebox{2mm}{raised}over\raisebox{-2mm}{lowered}\textrm{and back}.
Like \mbox, it puts its content in a text box. It can also be used just for spacing:
\raisebox{5mm}{}B^{V}.
There are other spacing commands: \hspace: a\hspace{4mm}b, protected space: a\ b, and (at “block level”) \vspace: a\vspace{1cm}b.
There should be 1 cm of vertical space above this paragraph.

2.5 Fonts

By default, letters denote variables and are taken from the \mathnormal font, which is italic, \alpha x+\alpha y=\alpha(x+y), with the exception of upright capital Greek letters, G\ne\Gamma.
Function names should be upright: \sin(2\pi),\log(x),\tan\delta.
Mathematical fonts used in equations include \mathrm{Roman} (\mathrm), \mathsf{Sans\: Serif} (\mathsf), \mathtt{Typewriter} (\mathtt), \mathbf{Bold} (\mathbf), \mathscr{SCRIPT} (\mathscr), \mathcal{CALLIGRAPHIC} (\mathcal), \mathbb{BLACKBOARD\: BOLD} (\mathbb), and \mathfrak{Fraktur} (\mathfrak). For the latter, some single characters are translated to their Unicode equivalents: \mathscr{F}, \mathbb{F}, \mathfrak{F}.
Regular text in a formula can be achieved via text font commands like \textrm: 5\:\textrm{to}\:10, via boxes like \mbox (prevents line breaks): 6\mbox{ is more than }5, or the AMSmath \text macro (scales like math symbols) \text{base}_{\text{sub}}^{\text{super}}. The content of an mbox is processed in LaTeX text mode. This allows text font commands, e.g. a switch to sans-serif-bold-italic, or the phonetic alphabet: \mbox{\textbf{\textsf{\textbf{\textit{sfbfit}}}}, \textipa{tipa}}.
Units should be written upright, either with \mathrm or with macros from the units package, e.g. as simple unit, \unit{km}, with magnitude, \unit[57]{km}, with fractional unit, \unitfrac[200]{km}{h}, or with a fraction before the units, \unit[\nicefrac{3}{2}]{km}, \unit[\frac{7}{16}]{s}.

3 Numeration

Equations can be numbered, like () And also like (↓). Some equations can be numbered even if they don’t have a label.
Notice that equation () comes after ().

4 Simple Structures

Let’s now see a few of the simpler structures that eLyXer can output.

4.1 Fractions

A simple fraction:

\frac{1}{2}.
Inlined: \frac{2}{3}.
A big recursive fraction:

\frac{1}{\left(1+\left(\frac{1}{1+\left(\frac{1}{1+2x}\lyxlock\right)}\lyxlock\right)\right)}\lyxlock
A nice fraction: \nicefrac{5}{6}. A non-diminishing fraction containing alignments:

\cfrac{1}{1+\left(\cfrac[l]{1}{1+x}\times\cfrac[r]{1}{1+x}\right)}.
A similar concept is a binomial coefficient: \binom{A+1}{B}. It can be prettily presented:

\dbinom{A}{B+1}.
A symbol can be stacked over another using \stackrel: x\stackrel{R}{\rightarrow}y. Anything can be stacked:

d\stackrel{x>3}{\lim}x,\quad\stackrel{\mathrm{head}}{\mathrm{heels}}.

4.2 Limits

\lim_{x\rightarrow\infty}f(x) should appear as x\rightarrow\infty in italics, and «lim» in plain style. In display mode, a limit must appear below the main symbol:

\lim_{x\rightarrow\infty}\lyxlock f(x).
Limits are also used in sums and integrals:

\sum_{i=1}^{\infty}x,\;\int_{0}^{\infty}f(x)\,\mathrm{d}x
where the sum’s limits should appear below (i=1) and above (\infty) the \sum. The placement of the integral limits depends on the document class: LaTeX standard classes place them right to the \int. Limits are shown to the right in inline formulae: \sum_{i=1}^{\infty}x and \intop_{i=1}^{\infty}x.
The placing of limits can be configured with the \limits and \nolimits macros:

\lim\nolimits _{x\rightarrow\infty}\lyxlock f(x),\;\sum\nolimits _{i=1}^{\infty}x,\;\int\limits _{0}^{\infty}f(x)\,\mathrm{d}x

4.3 Roots

A square root: \sqrt{3}. A more complex root in a fraction:

\frac{1}{\left(1+\sqrt{2}\left(\frac{1}{1+\sqrt{2}}\lyxlock\right)+\sqrt{\frac{1}{2}}\right)}\lyxlock.
eLyXer can also do higher-order roots: \sqrt[3]{x+y}. A devilish case mixing everything we have seen so far:

\frac{\sqrt[\nicefrac{7}{8}]{\frac{8}{4}x}+\sum_{i=1}^{\infty}x}{\sqrt[s+5]{\frac{(78x+45y)\times\sqrt{\Omega}}{\sin(x+1)}+\unit[38]{km}}}\lyxlock.

5 Complex Structures

In this section we will explore arrays and related constructs.

5.1 Arrays

An inline array \left[\begin{array}{cc}
a & b\\
c & d\end{array}\right] is always shown in the same line. In display mode, the array is shown on its own line:

\left[\begin{array}{lc}
12 & 2\\
3 & 4\times y^{x}\end{array}\right]
Apart from that the appearance should be the same.

5.2 Brackets

Arrays are separated by variable-size brackets: \left(\begin{array}{cc}
a & b\\
c & d\end{array}\right) \left[\begin{array}{cc}
a & b\\
c & d\end{array}\right] \left\{ \begin{array}{cc}
a & b\\
c & d\end{array}\right\} \left\langle \begin{array}{cc}
a & b\\
c & d\end{array}\right\rangle \left|\begin{array}{cc}
a & b\\
c & d\end{array}\right|which might also differ on right and left \left(\begin{array}{cc}
a & b\\
c & d\end{array}\right) or use the empty opening \left\{ \begin{array}{cc}
a & b\\
c & d\end{array}\right. or closing: \left.\begin{array}{cc}
a & b\\
c & d\end{array}\right|. There are also fixed-size big brackets, e.g. \bigl\langle f\bigr\rangle.

5.3 Cases

Used to switch between several values.

y=\begin{cases}
x & i=0,\\
x+1 & i<3\end{cases}
Cases may have more than two rows:

f(x)=\begin{cases}
0 & x<0,\\
\infty & x=0\\
0 & x>0\end{cases}

5.4 Braces

Values can be underbraced or overbraced.
\underbrace{a-b}=\overbrace{b+c+d+e}.

6 Macros

Now it’s time for user-defined commands (sometimes called “macros”).
Definitions can be added as macros. Then they can be used in formulae: \stupidroot 12. They can accept default parameters. Again, useful in formulae: \defaultroot.
Other definitions from the preamble can be used: \preambleroot{3}{4}.
Definitions on the fly are also possible: \newcommand{\ontheflyroot}[2]{\sqrt[#1]{#2}}\ontheflyroot{7}{8}, and used with different values: \ontheflyroot{a}{b}.
elyxer-1.2.5/forks/pages-elyxer/math-mathjax-local.html0000644000175000017500000005500112117067647022443 0ustar chennochenno eLyxer Math Showcase (MathJax local edition)

figure elyxer.png eLyXer Math Showcase

Alex Fernández (elyxer@gmail.com)

1 Introduction

This document is intended as a showcase of the mathematical abilities of eLyXer; for more information be sure to visit the main page.

1.1 Versions

There are several versions of this page:
All of them are generated from the same .lyx source file; they should help you decide which rendering options suit you best.
Also available online is the eLyXer translation of the latest LyX’s detailed Math manual, which contains a lot more examples of LyX maths.

2 Typography

Math formulae use a lot of different symbols and fonts.

2.1 Greek Symbols

Greek symbols are very important in equations: , , . eLyXer offers a complete set in both upper case: and lower case: . Also the AMS italicized upper case: .

2.2 Math Symbols

eLyXer supports the whole set of math symbols in John D. Cook's list: . It can also render a few more: . You also get all symbols from Markus Kuhn's list: .

2.3 Other Symbols

There are other symbols like arrows: , or geometrical shapes: , . eLyXer offers limited support for them. You might also want to use financial symbols in formulae: .

2.4 Spacing

Equations look good when items are properly separated. The main separation is the Medium Mathematical Space: . Note: if you are viewing the non-Unicode version math.html of this page then you are in fact seeing midspaces, which are very similar but not exactly the same: for medium mathematical spaces versus , where . Try out the Unicode version math-unicode.html — and viceversa. You can check out what version this page is in the page title.
The command \raisebox is useful to, surprisingly, raise a little box, Like \mbox, it puts its content in a text box. It can also be used just for spacing:
.
There are other spacing commands: \hspace: , protected space: , and (at “block level”) \vspace: .
There should be 1 cm of vertical space above this paragraph.

2.5 Fonts

By default, letters denote variables and are taken from the \mathnormal font, which is italic, , with the exception of upright capital Greek letters, .
Function names should be upright: .
Mathematical fonts used in equations include (\mathrm), (\mathsf), (\mathtt), (\mathbf), (\mathscr), (\mathcal), (\mathbb), and (\mathfrak). For the latter, some single characters are translated to their Unicode equivalents: , , .
Regular text in a formula can be achieved via text font commands like \textrm: , via boxes like \mbox (prevents line breaks): , or the AMSmath \text macro (scales like math symbols) . The content of an mbox is processed in LaTeX text mode. This allows text font commands, e.g. a switch to sans-serif-bold-italic, or the phonetic alphabet: .
Units should be written upright, either with \mathrm or with macros from the units package, e.g. as simple unit, , with magnitude, , with fractional unit, , or with a fraction before the units, , .

3 Numeration

Equations can be numbered, like () And also like (↓). Some equations can be numbered even if they don’t have a label.
Notice that equation () comes after ().

4 Simple Structures

Let’s now see a few of the simpler structures that eLyXer can output.

4.1 Fractions

A simple fraction: Inlined:
A big recursive fraction:
A nice fraction: . A non-diminishing fraction containing alignments:
A similar concept is a binomial coefficient: It can be prettily presented:
A symbol can be stacked over another using \stackrel: . Anything can be stacked:

4.2 Limits

should appear as in italics, and «lim» in plain style. In display mode, a limit must appear below the main symbol:
Limits are also used in sums and integrals: where the sum’s limits should appear below ( ) and above ( ) the . The placement of the integral limits depends on the document class: LaTeX standard classes place them right to the . Limits are shown to the right in inline formulae: and
The placing of limits can be configured with the \limits and \nolimits macros:

4.3 Roots

A square root: A more complex root in a fraction:
eLyXer can also do higher-order roots: . A devilish case mixing everything we have seen so far:

5 Complex Structures

In this section we will explore arrays and related constructs.

5.1 Arrays

An inline array is always shown in the same line. In display mode, the array is shown on its own line: Apart from that the appearance should be the same.

5.2 Brackets

Arrays are separated by variable-size brackets: which might also differ on right and left or use the empty opening or closing: . There are also fixed-size big brackets, e.g. .

5.3 Cases

Used to switch between several values.
Cases may have more than two rows:

5.4 Braces

Values can be underbraced or overbraced.
.

6 Macros

Now it’s time for user-defined commands (sometimes called “macros”).
Definitions can be added as macros. Then they can be used in formulae: . They can accept default parameters. Again, useful in formulae: .
Other definitions from the preamble can be used: .
Definitions on the fly are also possible: , and used with different values: .
elyxer-1.2.5/forks/pages-elyxer/userguide-frameset.html0000644000175000017500000000031412117067647022565 0ustar chennochenno eLyXer User Guide elyxer-1.2.5/forks/pages-elyxer/pipeline.png0000644000175000017500000001312712117067671020415 0ustar chennochennoPNG  IHDR%bKGD1 pHYsdd vpAga6IDATxyxT@LSZB E  "BP@@AAيd"aP-,E#V}_ET(ńr?~;3l7s2ޙy,w{3s=M4 DD0DZ*DCbR "RBDJE]h(YZP89}زh蚘%C%/سZP80yZX?DCbR "RBDJ1TH) )P!"*DCbR "RBDJ1TH) )P!"*DCO?U&F6kgMn?Oicl.?/<%^=uk`8S'`Wcͭ^'L~hʸ[iQgٳ4MVDE5kex~ׁ9s -Y[7&7ҀiӀɓDyˁ)S1c hgfk~n+VHm*࣏G6oN&Nyش ؾ(_qxvwr%::x֮F9x1_8sF@AС/y4- */oGu]uk-)SW^ʖ99!nV7޽#۷Sv,̜ $'fʷـ}jU ?(h*\8xP13Q?Yn,&?{{ ;XQhp˗i&n߲Z?2R-㸔)~YOk>`s5ĉءi:hE+д(:?k͜i;k+hښ5vku]M+UqoU+#umߢǏ/zVq ~L>}t4w}`NiSѢ_q;lm/;>~dqq I>x+W/Ja]`2ϯSKjTKYzhN8ZXNЯ,?upYE-*J'&Fag̐uJƎUW~rRݏ?J7ӟx-Z5zU}8 Ԫ0xu7lsn.в[]vm]u CBڷ7drE)op_Uu2\vZzʕٳY`ǧOȐܱccLӲ޶{IX׮xU`. |dM&ξ)p@*6ț.!\V ڥRc*[׼MVL I-TH) )P!"*DCbR "RBDJ1TH) )eig͚] '@׮F,*W]""RBDJ1TH) )P!"*DCbR "RBDJ1TH) )P!"*D%O}p*pѵ O] % ہKF-YP!,*e@&FOk@c*DCbR "RBDJ1TH) )P!"*DCbR "RBDJ1TH) )P!"L}7۷5DŽ @v60>iFow8p4Mθ׸ѵ$2Mܺ8-OӀQ$X7yHJ ~fΔ#:ScYYӦ]K2+ӄ?+_pPSO-u` 'GnGGGQQ{,ЭЦ 0oD:-M>p')/G/Lƌ22{,_gfh׮3fyy+VHŝ,՗I4 @n<>x><h0i^ uqԯS' D=oв%opܷ{??\ϗV[J P*ߖ11@^(0}l6-+^n /@Z/LRСе+@ll_B`y[s8qdg{>}%r2P;wMGҥZD}KYzhN{Vw},'O~[g,yi٨,LL3be\c~֭]I۶@.rfzՂc1PrE)op 9wsٵj`.}l;x^m/p=sc?#oeIwTϗݬ FׄxaR @zǎ;v]+"c1TPnxL'҃"RBDJ1TH) )P!"*DCbR "RBDJYrr~卮]jt (X2T7s|5'0j,* ȅ̇c*DCbR "RBDJ1TH) )P!"*DCbR "RBDJ1TH) )P!"*DCbR "RBDJ1TH) )P!"*DCbR "RBDJ1TH) )P!"*DCbR "RBDJ1TH) )P!"*D&iBd5 Cv6j/F&+P5 C] ,] ԩctmBOǎ?]0TH́|}{kzt‚5I`*~T;GH`k+@ҭpѵ]]]1TH%CZݺ>jt-c =x衢=BaA`Lkaс=bROYYF\6Rq^Sc}l eF=bR/52~ѝ7b 0rkk'.֔>|ӄJr!w[Z9&&P]|&T,1D?,Z+gtMu2 X7j ciBL^rs?5P=5+ק=xC%?4lHX 8vLxB#|/yaR%K榻x[9nk W5&f2tJd>0)ФU7CKEa6&|l&As̖t.̝+ǣ\Wȑ@>OQr$sDЯ0{6KjTהݟo%/X!KLG KeBox.w 9.A`/uU 'Bʔ}V_7 ܼ)/\̙#LT`bvm_oV2TBPժu@jmٺGq\w>sc.m rZM.mʮPgIר!Z&M_Er/;-t<8/gq#PLsk476L8*Un{ų=*!]y-]ɓe|c\;qs4ܼ 9bt9^&5UZs[ȶ[7|Ykfd_{ѝˁO>퓩/~`vM*6^Jz%6~IjGFEUIef9(1/OE2^gP``Na{7bb|^ ᓘ(c2`xg?(k;SҚ/eˀ?s ̮'5i"c;˷g^0p Ыs?(XgKhw|ԪY#鎼 /ȷܯ L ~`C)2g[#8*Tc2~} TWٻΊ}7Nu={iƹ+kԐVRi@Ԡ뛸[弩&9߼Y=bE`s:y1uℴcc / 98;+K S r;"B۶I𭷀+m``YMFRߗ1I7feʘ7ny~,9Yn.]ܟ"]SSsVvNO@ٱL2rW_ϟ.;έlDڵq?AΡ:a5jՀߖ>+J(~5}_)0{hHH@+V_.%EZG /"_ݟiu2b:i*ѣ[Ic RSeP ߷]Ҳ=RRB=v\<-|y[+ a|+]SSTJdOW r2ZgRSV[isn"Ǻ|]a΅ѳ,IB=9[HԬ)~A[yMi͟/MpoP[ѷ/p\vOZ._23]{灕of| =oRzYiϛ Vrn$-YL}L*[KS|FY -M9Bd=o ')J7Թ 8(ɞzO)Ba *v箨-\zOq=:dFII\箨-\zOF~=%&A:=ho{F4soByϛ |oG+;+/ؾ]Z+qq;TҶ;܍aV]y"IocݺorΘ! 2 k?׆ @VE?Pih6[&SR k/eIo'vr/=ȋprz:  {gʷ7XCƍ].e"R-I^kaz:-N/E7\eZ[MO& =;0&1|!hR!v&'y:kr "7‬&\~B_^"R{H) )P!"*DCbR "RBDJ1TH) )v@3%tEXtdate:create2009-11-19T00:47:59+01:00q%tEXtdate:modify2009-11-19T00:47:59+01:00uBtEXtsvg:base-urifile:///home/chenno/projects/elyxer/docs/pipeline.svgDIENDB`elyxer-1.2.5/forks/pages-elyxer/elyxer.png0000644000175000017500000010234312117067671020117 0ustar chennochennoPNG  IHDR_nbKGD X pHYsdd vpAgIDATx}w|iջdɽWt 5!$@H $! ͗PrC rS$Z l{%]q|Z gvfvvy9(Gr!q>r!ӅC9!-rC9[0r`90n#ra"G9øEs!qC}nv۷ottttttJRT… .\̜9s̙sᣍ~@x<x^{5oxcqM7X,xӦM6m_׿50}ӧ!b{o xgy Rp8l6f qؿBP(<3>8]N%X,:uԩSzAhrFٶT*J,^xOӟ{rÍ,}w}z5׈jZV B“W6&D|^>>[nݺu89C:rNQz^೟g?Y3f̘1Cl+Zbz„ &Lo߾}M0\`׾}k^X#ɖ͛7o<`֭[n=ݣCnpPYYYYYyG3> // @@"qF0N,8Q"ljjjjj:묳:ԟo9|#8|ÇE-3-8dIr'[5838Cw99hxㆍ6nn馛nr(#GGqA%fk׮]_$r =p8,Rm."JٳgϞ ̝;wܹms#q ̕ :eZ[[[[[E5믿?ݣCM{ pǎ;vH_/wp`0 ?NG^{}rxqD=BDI:Xexȗ9p,{99|Ks=sb3qx,ǀD2LAV@JR Dqat9ʋ0N5M ywySH$' )gKޠjI!O[t\. CP8}{6dlgȮ]v\r%\r n&nx'H|#W >H>^]۲USؽ{ݻ}s瀫ꪫ:ݣs7s4b2K:N$Ï;-r?9kNh}+_W\p\pV=CP0Ę%x<uH$8tFC ņXAWJljh :@5B<O8_AorDqŸ%@Νc$w$Dwwq{87Fc]+sk7F{--@0lLħFv`}60uqK$@ɖ?ªHėL9o B^/eL9L$B!Z~gNdr8> @3NMa8Csx``OwOwOg$"z[oN;ZZzz\.Z ==N{tp:=@Fcx"8F^Q6ɨ7v֖0aByy~>-mqca?Hr<"})/ 1/2T5fIY%H(X%>(~O\O||>ut w77w> KK+\n7f3{`Lz=i4)P4 `$8mOTV \yg6L~Lt==OvZ( H&c1"HzA{&@h j]PzBҳ8xqK 87567 bx" X,FN,Z4uje%0yrUUa!`Lǚ ? vdb_yE8)AP(J">RZ P(J$7onoVZaȑ~sp^PRRTK~]p՗_>e PPp~7FjTlEcјD>QYOvRbjG"776+WnDxW+_.ILZVI9[irU;zW;Z46 'Vضs"($ .; -) I.ٞ@cAUؒ?4ЬJ%/ZK rV՚@QQQ"~. kp2}D?ڵ֭;vtwC]qt"h(Iq̀Vk4׋9hb`65K/KEaґĵk| o܉ʀYKK`J2+٬k4@UJ%I0iD2IR<hFDbd2-Blk˾JR߫V[{7v`-+w Mm#=Շw:?=UW ɚ YNsDS?Z +*****F}-[}ZZfϮΊ8Rl7Xĉ'N*2l`<d a[`-0 9뮻ɌFcx}q @_Sgח ee!p۳\7L ,P"cbDUWs@_/ ^lTj5:0w~|艏1n .ᅣQvrªU{V\ӫ,,<'%>(G?oF<jl z!.nǭ.]|~`Ŋ+{/뮛>">}iʄ\t(&l b1zaA`fc'_G^O5F r*L:G'd2k׬YBbŋ/ 5W׿h<<ˆqK555555믽k/7ܱhX` ʉU JKm6,G(lB*4^N8>Ea7&eBPXeg"KPr 1z p:~߸Esc悂+>. Ri4aFfh4juxp  7pu3fU4X7FgR-;%%:ߏ 0޳g&薽 ^@ uPzQ]Uէ?կĉf*@کD'MM>D4_׬ M;= p$֖-U^-ȆrcȾcǮ]==d|Km%?yoV{ϣu T$a={zz)/z j.ۏYFlϦΙ3sfi)pyg]SYnX/jjk'LN22f/NG7H"Àӹe˻JtD.W_?V[,v;`6N8 bdkVrDˣ\nO3355TWrz0ɽ,y71A2fS}am:;r/TjupIf̸jihZ|$ |>_4JI+**(3;omBQPd JRT|xmׯXZl08aoX Z^PM'Es䕀^_RRUED' +ަ={#Gx}3f~jq4q'9̂-[P(;Z O8;4D<HdF__kDKx1*c,O-3W"ql4L|`EnXwyɫd/~fL&`Ui2Z`ܹ_sʹiuz2e9sn%R5{WI{er"^$x4tBu5%<6/PbyrT׮_xǀ/&`ڴ|#,Xz玖fS/[;?)N {kى!kabx9aq}^Ri zEŋ}}vZr\ٳYawtwG痉ٖ7})EE…WT+%l{͙S_L#~PU^~?js} ݗZ":m9sPM&EJpx}嗁w |O~~~&Ӌ7< }rc{IE",`0Ղ &y72y 4Kx|!ό+,r4|'m):o8nߗCbK/zdE""9[l;kP^p$J(ɃHھ]BtGmt>_Kˁ"b4y@/.N OmA&˟xڱcZ`˯XUNr(Ljlۓ8$E}rfiVUYcdKL\͈` DPUzad+Yg{WB޻>,ӱl#IRFE#;sY()"8УuFQoAo'R6n|MRY/׭{5 xϱd<hf]pF|8 ѱtق`¿ujbih9Sz2G% <ާ:(GG ue(*cKL@$r,Ejm6%#o|@XvÆtK~\_~2V/o6LNT__P^Eh2F"n|@w7 qΝPRl6W]OWy]x]۷*pHsݔ!~ 孒Iz1BE.)).XrI 's޼y^]N#"A```ݺ_WZ pnL)_p0$N2L&`(-$G}X\}}D|3:ٿ͋o*QZ*prǣ(?(c(vhj/;=&B7V:XR \哟Iʷ3oXq^:q\$HZNG=7(WoojsfΤ:]&fϟ:8%KN9碋(~1s:ɶ:8Hb8,RJdOq(0x,lv՘A {z$UJHuڱc: D"lS*5RY&wTE0u+O>  &ΙL@4j4g\6⓯#8xu0zx$⳥Y,6ĉ@__ooKKLFJZ{@?DJ"dpe/5])"_ VQU*P,>uۺW:/v8"rL-`ʔ"/o tz@omfssڵԸna3#͊%GXΝQ٪+|*+{!I[JdcN71=67wu9@⨱ >0P\&`0kkº:1vM;8 }tÆ'뮻ʩSPRGA_TE[{;vVfR`WXZ,WTdL@^y9>%HQ,ٹCCTvlLuȑ@xJ}|A&zTU}<]q7ڇ] t:E 3OZZIih:֖꫁l4~:lG͛Q|3^;}:pphLR\"Pb)Jںy3wȆ ںe &n"-[xܽGKZģUHz0 ,Ued߿mp={„f}T`Ҥ)Svؾ}ӦnԔ~ .¡u6ShTd2si%%?yf'L+*Uh#GF'AeZMha`vv (_HP 9(|?otf{'Ϝ}NMg>̚UZdɇ_ ;:$F{z3\X'Ϛum@OOwwK =5:75ҋ.jhniq(JS=? @'L&2Uj,8o}Kx&'PsswuIu. ?ȑ  Ob1)14xi!m `XZ֮4iR ~ ꫧwsΩpALώw㜹?1xqmן{48^ cpyٵkE;˓e5{zm_>{vx7F4 uu+Wگ~4665h~rP^^V\~UW}{O}kywݻWBA}m={eFhmݴTw<>wu.׶mk*̙W\h4_ԑZ(bH6p8`0dظnᦦXlz=LՁV/XCK|o[7( ÆqKk*;&M,(s'OِHbCC޽۷o$Jԏ:U9Ef;㌯|j L҆ ZظaPP@ѱe VӎÏ7MM}mFCJ%Gňh2i4dHIBlm=r$6n\k$@@]7PEQFwr 0"*c@8|HlRS Js$(Tc*BA6چ8xpa  (>@a2Io=ZOjz n _N⊥K*=>+(u*x]v٢E RWT9eݺ={ہUvlkBg/ r`T'*ahtwG"@oogg4J )V#"J}K];٬坂lwt(J%WTZsz.gO~̸!p8 ;iR)6*Ѩ̚E&a'\3mR #‹/Ry"A6,ʢqpR TW:$Q*EؔFѐhT"dp8"Jٽ.$SUuPX%'BqJ/BJ>kyT!Kz>kp0YBd8q2Gb1}I T )jMU~M&p/~v-,X|S~'9Bx{/֯߿or`۶ë=J= Jnj/ >}˴bm<( >cQ ۠ /F#"X 0&&I (DT 72`  Ӧ>0sf~>`it [>rٳu+wt $S\v ^r  â$>VJTRQx Wju:l|j5*P\\Zj0-/z{~'7o‚`PJ|,*"t:ry"Et[UU0sfYم<'G^w;;Kׯ`۟SdTV>JT&"e.tf~^O·onu}>RiB"~h4 //?_%O Iq9Z-NfJEq( `ggPTBmoomP0Iz1JˮJGU>E3"RaƬrQ6$ZhT!Z6*Idɮ7&O6nEEڿxزeffh)L&c1tn'U2.W_/I%.䱪S(P[A 55uuf30{y0s9yy驆,:4 v  B()``NP(ZjԪ 74Og9dopz W__0HHfQ*ɓb0 j5e )DR' j4B!z}RT0 E۾{vn3ibMCKO r+|n`׮ěBQ(x\F?Y 5p8 o>ݣz^x lFXLp:Is損#Fi11j+@Q%PIecf'AGGk/kϞ;)LǁŽlljȬ`#$*VD@8];+Wٹ! ?&BCL!" '@wwGG O*<;gXu# ,)-ٵkhT~[LLulZ-5~>^=kOKLH^CGuum<ҥ_DiHdω!H x, ~xnj_yDyG?NTUVĘ'N*{9ۉ8.m`v SQ B}0^dVFYfU!4I@t|1ft>J%_X$b$h&2"BoIYU%ekkK xd\^b֮]b 'On]ORʜ h}{$AS*ǶZ-ۻ曁 .hhE18M5͛z Wz/ єnFLMW%BRX鮻A1_oϼ 2g9A^?}{_g>N2PPihx|۶F/ ӠP'GIIi()"77{-7 o8_Z|=5xgd(ϴ_cyQ R8GDDŽ( ,9J0F/ -J3E]۶ TT?ϦOn_N-[6n<\Q*M&^n@'O;ڵ-_<ҥwTT8& Ru  2zaT#FBQ[ 8&ӝwm8Ip#m|9?TPhӦ/Y:Qj[,ƶ> .rZT@AAq^O*\2 dZVL74$Dj5BP@XrD^bjMl:y8}=tCN*ቜ`,KmBeN  1 /?"(/2EBDz=6 vSbfY;J'4~dR>|U5?[3i#M| ׿z۾ TTLzhӛZ2PXRTR̤*2b0k$PVr=_رM9i\Z{@2cbHm}4 %1zn*6@ l~Z-ep@磔.A|DtVB^[*P* I62%A":@A U|:y>؋G,AJeDT;R^^Yi0&"fhŠ{zC!੧x. `ƌ3v5(i<ġF"ΝnYg6^_Twliۿ{/} | /x ^OKӛ"}{熆~ʭ[FOp 7l>qr0sfU~W'+TORgSU3}_;+X*<>X2E! @jٴZ``/NA Ϫ4KDR"H$,WGIU%! RYF2I*'-(µIR '(*HU9ABVKN^f 8CG"dZhQZm;TxUJJJJt:!ɳ`pX=}` ??H4 SUV-\HFOzAC/WqJJ %Kv]:q2&5=Aw:OJ8p#'H9ƫ$g4vwl9BەJ 3v Y5|]  T;v]G6)RyS%d}t@߁~ʰ`FkJ԰La)T[tD*1r聁P$&"t"@n)$S&{dD+g"Z8KR%@2 QJ|&HZ"@ ǁPHHbaɯ;yOvZ$PPP\l0nEȚ9]]_>e׿/[v]"s$/m66;zJR&qn|+5J,LJu޽$9&hTyWZ5DPGT#;E|| .4?8`45YPA\6@s:[ZK.O T$N?-%>NPFi dcbgYH$u MXlLP, TD`*%^)%@X"#M.踉K"PNlMgN!$g65<Թ"^d԰FF =D+O06[^HIЉݻd@ƙ0N9]o߲ebɨ*,4)=YqzcDP=P*H9~(UrB*FC.KD\ɤqih &^1NǍPJJVoqϋֶm`4mJ 46D BdvldfG}3\ Ι^̦ `@`-Gְ75?2*hLiiyHHWI"epdmfŢVSj pLț6_tjuuT@mCCN'[K}xCDJll߿wߒ-[S>;v{G:$9KIy95xD%~PZJ, vMy  U?XBiDp?M ~` Q'87yR@IɊ5Ւ$w?p DJK'Oa;:LIUؤ!5IH/B;dKg@dnxTOPJ[(D&K<$Ad:/a; S|9U(JޟcmTsu{ PmڨڂA47*S٤!@b8X2: hnܺ4૯n닊J"zb(RJlTeW*dYY$Iңb0h BtV+ U|}]JUPl|,!21TJWTeAe $T.i`7D#g NR؊<:' OF5zhȟI2a0t;)R!NdddI ==ԎHH,ѵ81 ZFTTTWSYf*T_:;NXm>s>F/6;s {9QJeEi?>_El:sv Iy$}{AZVFD@Smy=*5m4(YU8B3DRdB!U~L{eRY"[H2I&@MGBa6j5Zttju^lStHZN @ns{~qr}1IQ6KK:;'M8_B~L0p^oX\Z({R?D8|!c$ IhҔiDj4 \bJ|lz'*K V*bNh繐j4JĞ)%dN6iJpߧ`;JR<^T*-XHE"4j%G^U<^T(L6L7?  Kw0r'?TN ."k(Dc̉L<*Hq r! JI׋WS y4AGKŒ+4%D5ĒIH_\.RWG,r> ddxhQTeh4_I It_89%'4X hnnj2щ%k}h ܩϓVKϪ5+k!YJPL$V9rxd5b` l3o߫>tSXC8sܹ4řc0h&'M*i&',J@ydp륪!΋E7GVeF"HB@(DK ;bT y(\QRIi?4e ӕRXI(TE%B(T%l\D}K:/pRɃT49#K-ORN|&B^τGi=%gyy: ($6*P3q$|f/1{;x<ce4z{C!a ;-_tnNDǑ~,DVS}EzstY#5e8`0M jmo~3mM4DE,Qqݥf|H#$=yGj"P(lOW5<`RNnl`c{ 'vԼSx< %FJ:* 9^-U*T9U*)5,sNUǤIV<1Ye@/%TL 8N0UU6""? b!I$+&>}rqv>n7IB"'$@~ޥrgiJ=?,#uNI`.h8(HBVL$nڲe?iij{A{* όVj3yDTa'"Y:X.GMڀj 91Q*8ZRAu:D(xVXLxh(Cի)BΓbjK( 񥄗}:eȽ,tDC#cI/l7,ҁD|Lrp _BN2A\4rUZlHU'aM7D\c(G/t0Z-9J+V<T?ko߼()۫iY$~ vǶL<Z#].%OkKi,FUV6iWRR^NKxs3RD~Ng2Q|"DJB^lė:AK|3R,R9P<]-Z2/oɍ bI&+v6-$@&}SCn4 FC2#9];S#֥*/{}Z2c-t:K*-2SJJHjiz.ZF#ߧRYPOkΛF7oӟ/{H/*yp]6 &KANxY,qcd#OSHǪn(DҺR MRﱔ4ӥ-1&]!ᴍ 382|}+)O/֠OH#pB`0śTzLCdBFB: VVr[ʽ{ ?*1Rl0)ҿ=SA94*>qƍ}G5i<ѨVϞ-p< /] ;2?F6}Pz< FKτ;zER9Fcc=WYᣉ@^ ەXiJ RQAuV$B^hqwma%2wX,)DJ-*H"Vyt:A:-Y ?$kbω`2鴣ߝFX(HA_*Rĉ{g~\, UEvVYF`XbɖpPА-ˏ̽ h,*@HRe44l@cYgu$NR%%FwK8ҥhqUe;bة {z߱Ty]rY~hVBD"ҏT@5ZKK?a2i4v `x8^x"7h!̈́ɬ*Ht A^ c|(%%[JE>EeE?6-z2`P#jJ-m h?};,'p(セ1ADJ$wcv`'zƩkEE9rQDRE!+`dqHX2eܦ'Ɨzq:Z-OZہ P6FdpE9M%H~@r=xkkI=NXHRtLldbjkt"XHt:=㱥UV⋀^WRRU iZNq(䁜)_X,`0PCFla6F٬5?cÇNNWT 8Dª7K^MqVU z<ҥZM9UUz=Ida*1:W`vq3K_8L,Yd[ @6Czf!L&S(D}*>'tY>__KS>pz}Qi #r"}uqhI$@Yu OMj6fA=#Դ2hB )3`t:b2YkV T`#'.u?vu:*uri~x8liiy ȑ;j?ni`@jj|>"&GU(Dd~ImP<+_>C*!& S(rr'L0hVj)m%T Xk# e`B$Y !¯JDx\Η$H&nBJKȴnk'ʺq#EV*IEDZ"nN;#o-*|Yu-553g<`AAUUmmm]v" |iJp̜Iq~ TRUbq>?vfsYىd:Dcxbd"DE#ܷ{`u̵׺\j5p?meeݟ[V+TB6S9<*+kjF`'_JEeL&Q .`Pt5yA4e #?ݝPq :T;x< eEu25TEy7:;>>K~逩^\>89^ӈZtS.X(r$d vvw[;.L៩~쟤7$<#ҚF"c~rHU{loip/⭷\py@II~P$ \w(Fs|BhQ9m#[N?%pn6{K^MX(m"AeZ/]fޟwzz#G={:;{$a`"O.V% @&' --@4g? I"|DO&MIJ4Z-`v;0}̙f3@yZ- d [J %pD,f`Lz}SbD 2)7olI뼬(H\B-/O9p}Q,B {Mk/l|G;kFAɳfz= ]xRm(,u Ӓ|, Jņiaȝ&%\nj0z0FJ|ttum~w={zG3oEN!ذa޶6`Φƞn"YU˩w DƍN:=$IPrȶakWGǪU R C]ڨ8|h^{hmA pV@yUUF#I^옪Ȼ54@iiYNTWqW6ljez^r: GU)lDK.tK! #s+WbKZJ or$TVJ3g8טWJ-zfauO&¨fKŵu31[$\t[jŋUr2Mq>paUƍ#ѨѨEcҥT';M,2"Bi@Ԯ4a18ON-Cj H؋ӯAD'I&KyJ|]]pÛ.<|1Ό<sΙ6M,N'rAAa`@$@iIg; С3hޠT*RACzzl )SiO)i0ş\1I0UU*[[Rw72k֜9V+x [JaljPȄjG/Re\6KHxS)%+B);tI$@aaQNG6Pv<^:b^΅PY2TDB I=l{$HV!co/ Xp3Ϥ N5b ++kC^07XRDtL 0 T*Rْ&i~JPg9HW==D4k;'}Wx߳ /GB08448ʕ?P*zDJJK' L^wwv]Kہbry:`DRՏX|(Ǜؾ}ŏ=xxg[,D%I~8MdDK|KcBSSOvZEH6B~BcF3 yq@N _4YF*5m#0WM{ >55f-Xp,h{JIq~vIdhhOnJN4&rg41F l?'vLؾRp* csZ~lLjp`I2z5Zb:FHx)vW(h$˜VӧSRYQ{"%wزԃ'o~SS#4={v ׬q+!:! $h4xU]8%C*u=g8Yt%Vs]7mS،$?燎gSXxH2~:_$^75Ӧ{ɈQ'M9Ng*~?tM 7߃RQEpO# YT:r x3e0Q eeTh2^.{.SJK]8Y@$y<=/'c„S`ɏl\:]& g̡C==\v;U>Ldqj2އBC`0(BBb]IrRK]/]‡"#E& Tdj?Y’K*1WnfIKIӦLvl>0 Q^zEԁO5TR6Gk>;2"yyBq )?!эFi [Z n1+--"p:} P=ɶ>jK,WIFMG7n|s{4A'qϞe˞zh?e@2I u:!4!B!S`8& 0k0ejjtK)*, k!AjuK|I=_x2jt9^hRh%KV˯xMM=*,0+l}m!./! FjbTﱨDɋt DE18HpX*@M 90Y\wnRR2G0.AKjk9UU?80m 7qo]K>%I|PyS&x?UEE',~2Q$EM6s}ܹf3tRh$7{RPas*f1 /y4!ǒW(CF**lGG{{8  PZZZRsAxzYVtd`s!Abbft*FÒ?1p- @f?X0 `ʔ9sK./} 0O@gmu[԰|NǮ]O>@4>bOϞ=[Tn`0$Rl&۞NG̑oյwxa p8j Z-{{)0yǎwZ[Lh:u:n*x6_i)l~ʿ-uwXhʶn| (-\**@.lp`a'ѦV+l6MExs?j2!†(H364f3UTh I˶! FEuk` #I1?JP(:S(W X Y/E=+=d2[cמyX!ipY4z=%ld0)BҜI^JmCM Hi(x}j-uƷDFC //۵cӟ.ՕI3/,-R*>J :;ID0 RRbO'W@2Ҁ]cǕ>1BM/(=^__ooWrĉWW"MD%U-v[N Vat:ZWU @M IDeeZ-e 9Mf .((,s!3Kiy*ytTl6Tde%|`9ϧ;%75F)Ӆ{q_bi sx {zIp)Kn2~憻,'Vqzڀ^OnشiMp]6Evzz]K'T0SG f:2h+us:6:\M/Jp0.6" c^{DeLd0gpDrbd㔼VJY(Jaƌ'._\q1j8t:nMoJJ,ڹsF cR'h@JEejJr D:A* )`D}9RbsS0`kJ7 dv«Jٹi;;wֲeb'W=\YcDTTSL⥑>nL5Rl媶j˥.0ֶn]Gw!G|3dDό|R*IsFIuum^Db2E"c;,5 iixTqb,) )t @TiqWS3a> [PqI"xSonO?hO1"&LX1kVs}qbD/h9_ⷿ ф}~~7mHu9epb{0v@8gO(vHe0Rɽr/S$U{Es Fܗ^\8*ǁΎzޔ {}}]] F#Kσ|U*N60y8^IՕ:rpR| k׶ڦ:lQ(Hh|o"[}餶՜k)nWH [Z_ճ{En/*ߗfR#![j`gg B􍊊*VGD\܀$3)$BAvSMƷd^+8oRT.'٪&L>s_1󥗞xxeo~s@{vgjN?tH&hh0lF#_[k6Fwi"R5f*tؘ'"3^  xrښɓ.eM]8Z2=eG "LUYq3ŨtZ-RR=.WkkOb˯_Lq#W\t)޾`}@7IsOtbdAA2V Px B9t|&<&'Y^_ R4J{mm]gV%[wo>/nQ '@[*Uy@E>_?XA5Vr2ߚ)S[s'wկ`zu#cHL,ÔN)MfsQ 64XNGHٛ+CdOZomm@oΝl")綱kjjoO=V)#b63?~:qF&N>7<M{hfwW2ifi^bV1K(((*R)CmDBZLzF<'u4'%{_s$$Bg dTP({|~>z{{zb1{)xG̹xɑ}B9T0NrԜ'? |snoӟ+W>? x\Llr3[U&XJ2 47Q̘QXt"ud:ommkh\\V*1r"L?gFVKe,&$T\Rmx6ML blSsG&*#mm@WlGRՍFϿ.70|p5ӧ;@MM^ތ_w+=6̘̙p!l19溧ԌFʵM$HӑK98,lU|J|RA Cx|wP)/Wn/g|S-N;2Zf.{Gᢋ x{vׁ޾tHNt"d)%nQlrhC%m.6HP\. *񉭀TRRY>n:͖=a.R5=9TrTz6eLp[Iv=~UZf+~Lp饟{g./brJGn طoښ'NL̙$2qlv;U:fJTwI)Hj3(:RsYpST^$/59mD?"dqw::(0zma ),|]o|yep,p̩;QfϾjή.@d$gV2mE"=kٜfj)_<D"dA M=l*g3$(*Zq7󟓄*-x<Ν/@0#ȽY" DŽ 4)=Y!!|>_j5OZ\KNQ;&8s'LF*() 8|xRJR(D01Ll{qg{(@To<IS*oOtົ;:q`ݺիC!P(.+_.kL&;9'lc NN8Fc+<46C7 |Nunsj@*{zdL|oD^/PJxߗ~f |0.ߟ{nM  RэghDQvh .30 }j8|]nu&K-^ÿ=3K_~:kɒS~$vK}+wZD׮Ofxx" u:t;L;9 )qR\EػKKqfH z$p=0gT6mk+` s3ޟUUyyӎ2\{p]7LD#UISc'/A᱈G S__(+>}޼3y763̆t[`vJ> hFF_0x@ t|ُmKv9poo/|xBӟ_߱gHd; $mmKEE60y) 0u*j)$9W!2<؎M|ݱx@8 45ZBlֶlf 8Hb[fJe,sM(..- jX BA8NQ\rq;8ߟH(`4Je~~c#־ PR<{p0pS6>H$(+7~/X._Dc%̟E|+?|T⬫;.7y y>nyݞdTFOq_ /]{^N`֎W_}=-[u\@;H&'NI"ˤksȶiJnJ%׃ *6@2pUUW +*IqZhh(('>6`"\ԧիW^F8^[Xs*omYg.Y|hzzdžիہw}^N nl8MFWxׁөD2]]5Œ)IDATOc#47a @(|G%Qֳ^VMޠј̀Ţ9$UVVk}PVf?tn|΁Kի6nܺu۶LG&cUyJJop%?ħ>$r_z閛/صOSJIc%%Βb٠x룏>M+V<r![E٬T{B…3ft7TTqƩq@sHA, @o]7I]6M0e PR2gYgQt_E99!->?d9Ç9!-rC9[0r`90n#ra"G9øEs!qC9!-rC9[0r&dk8%tEXtdate:create2009-08-31T01:36:31+02:00p+T%tEXtdate:modify2009-08-31T01:36:31+02:00@tEXtsvg:base-urifile:///home/chenno/projects/elyxer/docs/elyxer.svg|)IENDB`elyxer-1.2.5/forks/pages-elyxer/math-html.html0000644000175000017500000007715712117067647020703 0ustar chennochenno eLyxer Math Showcase (HTML edition)

figure elyxer.png eLyXer Math Showcase

Alex Fernández (elyxer@gmail.com)

1 Introduction

This document is intended as a showcase of the mathematical abilities of eLyXer; for more information be sure to visit the main page.

1.1 Versions

There are several versions of this page:
All of them are generated from the same .lyx source file; they should help you decide which rendering options suit you best.
Also available online is the eLyXer translation of the latest LyX’s detailed Math manual, which contains a lot more examples of LyX maths.

2 Typography

Math formulae use a lot of different symbols and fonts.

2.1 Greek Symbols

Greek symbols are very important in equations: φ, π, Ξ. eLyXer offers a complete set in both upper case: Γ…Ω and lower case: αω. Also the AMS italicized upper case: ΓΩ.

2.2 Math Symbols

eLyXer supports the whole set of math symbols in John D. Cook's list: ∃∂∇ ≥ . It can also render a few more:  ∝  × . You also get all symbols from Markus Kuhn's list: ⊙∐.

2.3 Other Symbols

There are other symbols like arrows:  ←  → , or geometrical shapes: , . eLyXer offers limited support for them. You might also want to use financial symbols in formulae: ¥€$.

2.4 Spacing

Equations look good when items are properly separated. The main separation is the Medium Mathematical Space: x = 3. Note: if you are viewing the non-Unicode version math.html of this page then you are in fact seeing midspaces, which are very similar but not exactly the same: (4)/(18) em for medium mathematical spaces versus (1)/(2) en, where 1 em = 2 en. Try out the Unicode version math-unicode.html — and viceversa. You can check out what version this page is in the page title.
The command \raisebox is useful to, surprisingly, raise a little box,
raisedoverloweredand back.
Like \mbox, it puts its content in a text box. It can also be used just for spacing:
BV.
There are other spacing commands: \hspace: a b, protected space: a b, and (at “block level”) \vspace: a b.
There should be 1 cm of vertical space above this paragraph.

2.5 Fonts

By default, letters denote variables and are taken from the \mathnormal font, which is italic, αx + αy = α(x + y), with the exception of upright capital Greek letters, G ≠ Γ.
Function names should be upright: sin(2π), log(x), tanδ.
Mathematical fonts used in equations include Roman (\mathrm), Sans Serif (\mathsf), Typewriter (\mathtt), Bold (\mathbf), SCRIPT (\mathscr), CALLIGRAPHIC (\mathcal), BLACKBOARD BOLD (\mathbb), and Fraktur (\mathfrak). For the latter, some single characters are translated to their Unicode equivalents: , 𝔽, 𝔉.
Regular text in a formula can be achieved via text font commands like \textrm: 5  to 10, via boxes like \mbox (prevents line breaks): 6  is more than 5, or the AMSmath \text macro (scales like math symbols) basesubsuper. The content of an mbox is processed in LaTeX text mode. This allows text font commands, e.g. a switch to sans-serif-bold-italic, or the phonetic alphabet: sfbfit, tipa.
Units should be written upright, either with \mathrm or with macros from the units package, e.g. as simple unit, km, with magnitude, 57 km, with fractional unit, 200 kmh, or with a fraction before the units, 32 km, (7)/(16) s.

3 Numeration

Equations can be numbered, like (1↓)
(1) y = x
And also like (2↓).
(2) x = 3
Some equations can be numbered even if they don’t have a label.
(3) x = 2y
Notice that equation (2↑) comes after (1↑).

4 Simple Structures

Let’s now see a few of the simpler structures that eLyXer can output.

4.1 Fractions

A simple fraction:
(1)/(2).
Inlined: (2)/(3).
A big recursive fraction:
(1)/((1 + ((1)/(1 + ((1)/(1 + 2x))))))
A nice fraction: 56. A non-diminishing fraction containing alignments:
(1)/(1 + ((1)/(1 + x) × (1)/(1 + x))).
A similar concept is a binomial coefficient: (A + 1B). It can be prettily presented:
(AB + 1).
A symbol can be stacked over another using \stackrel: xR → y. Anything can be stacked:
dx > 3limx,  headheels.

4.2 Limits

limx → ∞f(x) should appear as x → ∞ in italics, and «lim» in plain style. In display mode, a limit must appear below the main symbol:
limx → ∞f(x).
Limits are also used in sums and integrals:
i = 1x,  0f(x) dx
where the sum’s limits should appear below (i = 1) and above () the . The placement of the integral limits depends on the document class: LaTeX standard classes place them right to the . Limits are shown to the right in inline formulae: i = 1x and i = 1x.
The placing of limits can be configured with the \limits and \nolimits macros:
limx → ∞f(x),  i = 1x,  0f(x) dx

4.3 Roots

A square root: (3). A more complex root in a fraction:
(1)/((1 + (2)((1)/(1 + (2))) + ((1)/(2)))).
eLyXer can also do higher-order roots: 3(x + y). A devilish case mixing everything we have seen so far:
(78((8)/(4)x) + i = 1x)/(s + 5(((78x + 45y) × (Ω))/(sin(x + 1)) + 38 km)).

5 Complex Structures

In this section we will explore arrays and related constructs.

5.1 Arrays

An inline array [ a b c d ] is always shown in the same line. In display mode, the array is shown on its own line:
[ 12 2 3 4 × yx ]
Apart from that the appearance should be the same.

5.2 Brackets

Arrays are separated by variable-size brackets: ( a b c d ) [ a b c d ] { a b c d } a b c d | a b c d |which might also differ on right and left ( a b c d ) or use the empty opening { a b c d or closing: a b c d |. There are also fixed-size big brackets, e.g. f.

5.3 Cases

Used to switch between several values.
y =  x i = 0,         x + 1  i < 3 
Cases may have more than two rows:
f(x) =  0  x < 0,         ∞  x = 0        0  x > 0 

5.4 Braces

Values can be underbraced or overbraced.
a − b = b + c + d + e.

6 Macros

Now it’s time for user-defined commands (sometimes called “macros”).
Definitions can be added as macros. Then they can be used in formulae: 1(2). They can accept default parameters. Again, useful in formulae: 4(5).
Other definitions from the preamble can be used: 3(4).
Definitions on the fly are also possible: 7(8), and used with different values: a(b).
elyxer-1.2.5/forks/pages-elyxer/toc.css0000644000175000017500000000101412117067660017367 0ustar chennochenno/* * Styles for lyx TOC. */ body { font: small sans-serif; background: #f9f9f9; color: black; margin: 0; padding: 0; } #globalWrapper { font-size: 115%; margin: 5px 20px 5px 20px; padding: 0px; background: #ffffff; line-height: 1.5em; overflow: hidden; } a { text-decoration: none; color: #0030c0; background: none; } a:visited { color: #603090; } a:active { color: #ffa000; } a:hover { text-decoration: underline; } div.tocindent { padding: 0 0 0 2em; } div.toc { margin: 0.5em 0; font-size: 0.95em; } elyxer-1.2.5/forks/pages-elyxer/container.svg0000644000175000017500000003147612117067674020617 0ustar chennochenno image/svg+xml Container parser output contents LyX HTML elyxer-1.2.5/forks/pages-elyxer/math-mathjax.html0000644000175000017500000005456212117067647021366 0ustar chennochenno eLyxer Math Showcase (MathJax remote edition)

figure elyxer.png eLyXer Math Showcase

Alex Fernández (elyxer@gmail.com)

1 Introduction

This document is intended as a showcase of the mathematical abilities of eLyXer; for more information be sure to visit the main page.

1.1 Versions

There are several versions of this page:
All of them are generated from the same .lyx source file; they should help you decide which rendering options suit you best.
Also available online is the eLyXer translation of the latest LyX’s detailed Math manual, which contains a lot more examples of LyX maths.

2 Typography

Math formulae use a lot of different symbols and fonts.

2.1 Greek Symbols

Greek symbols are very important in equations: , , . eLyXer offers a complete set in both upper case: and lower case: . Also the AMS italicized upper case: .

2.2 Math Symbols

eLyXer supports the whole set of math symbols in John D. Cook's list: . It can also render a few more: . You also get all symbols from Markus Kuhn's list: .

2.3 Other Symbols

There are other symbols like arrows: , or geometrical shapes: , . eLyXer offers limited support for them. You might also want to use financial symbols in formulae: .

2.4 Spacing

Equations look good when items are properly separated. The main separation is the Medium Mathematical Space: . Note: if you are viewing the non-Unicode version math.html of this page then you are in fact seeing midspaces, which are very similar but not exactly the same: for medium mathematical spaces versus , where . Try out the Unicode version math-unicode.html — and viceversa. You can check out what version this page is in the page title.
The command \raisebox is useful to, surprisingly, raise a little box, Like \mbox, it puts its content in a text box. It can also be used just for spacing:
.
There are other spacing commands: \hspace: , protected space: , and (at “block level”) \vspace: .
There should be 1 cm of vertical space above this paragraph.

2.5 Fonts

By default, letters denote variables and are taken from the \mathnormal font, which is italic, , with the exception of upright capital Greek letters, .
Function names should be upright: .
Mathematical fonts used in equations include (\mathrm), (\mathsf), (\mathtt), (\mathbf), (\mathscr), (\mathcal), (\mathbb), and (\mathfrak). For the latter, some single characters are translated to their Unicode equivalents: , , .
Regular text in a formula can be achieved via text font commands like \textrm: , via boxes like \mbox (prevents line breaks): , or the AMSmath \text macro (scales like math symbols) . The content of an mbox is processed in LaTeX text mode. This allows text font commands, e.g. a switch to sans-serif-bold-italic, or the phonetic alphabet: .
Units should be written upright, either with \mathrm or with macros from the units package, e.g. as simple unit, , with magnitude, , with fractional unit, , or with a fraction before the units, , .

3 Numeration

Equations can be numbered, like () And also like (↓). Some equations can be numbered even if they don’t have a label.
Notice that equation () comes after ().

4 Simple Structures

Let’s now see a few of the simpler structures that eLyXer can output.

4.1 Fractions

A simple fraction: Inlined:
A big recursive fraction:
A nice fraction: . A non-diminishing fraction containing alignments:
A similar concept is a binomial coefficient: It can be prettily presented:
A symbol can be stacked over another using \stackrel: . Anything can be stacked:

4.2 Limits

should appear as in italics, and «lim» in plain style. In display mode, a limit must appear below the main symbol:
Limits are also used in sums and integrals: where the sum’s limits should appear below ( ) and above ( ) the . The placement of the integral limits depends on the document class: LaTeX standard classes place them right to the . Limits are shown to the right in inline formulae: and
The placing of limits can be configured with the \limits and \nolimits macros:

4.3 Roots

A square root: A more complex root in a fraction:
eLyXer can also do higher-order roots: . A devilish case mixing everything we have seen so far:

5 Complex Structures

In this section we will explore arrays and related constructs.

5.1 Arrays

An inline array is always shown in the same line. In display mode, the array is shown on its own line: Apart from that the appearance should be the same.

5.2 Brackets

Arrays are separated by variable-size brackets: which might also differ on right and left or use the empty opening or closing: . There are also fixed-size big brackets, e.g. .

5.3 Cases

Used to switch between several values.
Cases may have more than two rows:

5.4 Braces

Values can be underbraced or overbraced.
.

6 Macros

Now it’s time for user-defined commands (sometimes called “macros”).
Definitions can be added as macros. Then they can be used in formulae: . They can accept default parameters. Again, useful in formulae: .
Other definitions from the preamble can be used: .
Definitions on the fly are also possible: , and used with different values: .
elyxer-1.2.5/forks/pages-elyxer/parse tree.svg0000644000175000017500000005140612117067674020662 0ustar chennochenno image/svg+xml \begin_inset Graphics Text LatexCommand Inset label ref Image Reference Label InsetText elyxer-1.2.5/forks/pages-elyxer/lyx.css0000644000175000017500000003751612117067660017436 0ustar chennochenno/* * eLyXer -- convert LyX source files to HTML output. * * Copyright (C) 2009-2010 Alex Fernández * * This program is free software: 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 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 * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see http://www.gnu.org/licenses/. */ /* --end-- * Global CSS file for LyX documents. */ body { font: 90% sans-serif; background: #f9f9f9; color: black; margin: 0; padding: 0; } #globalWrapper { margin: 10px 5%; padding: 20px; background: #ffffff; line-height: 1.5em; } /* Basic styles */ a { text-decoration: none; background: none; } a:link { color: #0030c0; } a:visited { color: #603090; } a:active { color: #ffa000; } a:hover { text-decoration: underline; } h1 { margin-top: 1em; line-height: 1.5em; } h1.Part { text-align: center; } h1.Part- { text-align: center; } sup { font-size: 0.75em; line-height: 0.5em; vertical-align: text-top; } sub { font-size: 0.75em; line-height: 0.5em; vertical-align: text-bottom; } div.Standard { margin: 1em 0; } div.Unindented { margin: 0; } div.Indented { text-indent: 30pt; margin: 0; } div.Indented * { text-indent: 0pt; } p.dir { float: right; } p.printindex { font-size: 0.90em; } a.printindex { color: black; } table { display: inline-table; text-align: center; border-collapse: collapse; margin-top: 1em; margin-bottom: 1em; } tr.header { border-bottom: thin solid #c0c0c0; background: #ffffff; font-weight: bold; } td { padding: 1ex; border: thin solid #f0f0f0; } td div.Standard { margin: 0ex; padding: 0ex; } div.caption div.Standard, div.table div.Standard { margin: 0ex; padding: 0ex; } td.numeric { text-align: right; } td.empty { text-align: center; } div.right { text-align: right; } div.center { text-align: center; margin-left: auto; margin-right: auto; } p.biblio { } div.Paragraph, div.Paragraph- { font-weight: bold; font-size: 103%; } span.versalitas, span.noun { font-variant: small-caps; } span.sans { font-family: sans-serif; } span.code { font-family: monospace; } div.Plain { display: inline; width: auto; } h2 { line-height: 1.4em; } span.Description-entry { font-weight: bold; } span.List-entry { display: inline-block; width: 25%; vertical-align: text-top; } span.List-contents { display: inline-block; width: 75%; vertical-align: text-top; } div.Space { display: none; } span.appendix { display: none; } h1.biblio { } span.greyedout { color: #808080; } div.Description, div.List, li { margin: 1em 0; } li.nested { list-style-type: none; } span.Info { background: #f0f0f0; border: thin solid #c0c0c0; } pre { padding: 0em; margin: 0em; width: auto; font-family: monospace; line-height: 1.5em; } pre.LyX-Code { margin: 0.5em 3em; } a.Label { text-decoration: none; color: #000000; } span.phantom { color: #ffffff; } a.biblioentry { color: black; } span.menuitem { font-size: 105%; } span.normal { font-style: normal; } div.PlainVisible { width: auto; } div.indexgroup { margin-left: 2em; } span.strong { font-weight: bold; } /* Figures and Tables */ img.embedded { width: 100%; _width: auto; } div.float { margin-top: 1ex; margin-bottom: 1ex; text-align: center; } span.float { margin-top: 1ex; margin-bottom: 1ex; text-align: center; } div.figure { display: inline-block; text-align: left; padding: 1ex; margin-left: auto; margin-right: auto; border: thin solid #c0c0c0; } div.table { display: inline-block; text-align: left; padding: 1ex; margin-left: auto; margin-right: auto; border: thin solid #c0c0c0; } div.algorithm { display: inline-block; text-align: left; padding: 1ex; margin-left: auto; margin-right: auto; border: thin solid #c0c0c0; } div.caption { text-align: center; font-family: sans-serif; margin-left: auto; margin-right: auto; padding: 0.5ex; } img.figure { width: 100%; _width: auto; } div.multifigure { padding: 1ex; width: 100%; } div.multitable { display: inline-block; padding: 1ex; margin-left: auto; margin-right: auto; border: thin solid #c0c0c0; } div.multialgorithm { display: inline-block; padding: 1ex; margin-left: auto; margin-right: auto; border: thin solid #c0c0c0; } div.wrap-l, div.wrap-o, div.wrap-i { margin: 2ex; float: left; } div.wrap-r { margin: 2ex; float: right; } div.listing { display: inline-block; text-align: left; margin-left: auto; margin-right: auto; padding: 0.5ex; border: thin solid #c0c0c0; } span.number-left { float: left; background: #f0f0f0; width: 3em; text-align: right; margin-right: 1em; } span.number-right { float: right; background: #f0f0f0; width: 3em; text-align: right; margin-left: 1em; } /* Header */ h1.title { text-align: center; } h2.author { text-align: center; } h2.Date { text-align: center; } div.abstract { margin: 1em 3em; text-align: left; font-size: 0.95em; } p.abstract-message { text-align: center; font-weight: bold; } div.tocheader { margin: 1em 0; font-size: large; } a.toc { color: black; } div.tocindent { padding: 0 0 0 2em; } div.toc { margin: 0.5em 0; font-size: 0.95em; } div.fulltoc { padding: 1em; } div.warning { font-size: 120%; color:#cc0000; } div.Institute { text-align: center; } /* * Extras: colors, footnotes, boxes, spaces... */ /* Raw colors */ span.red { color: #c00000; } span.blue { color: #0000c0; } span.green { color: #00c000; } span.magenta { color: #c000c0; } span.cyan { color: #00c0c0; } span.yellow { color: #c0c000; } span.white { color: #ffffff; } /* Footnotes */ span.SupFootMarker { color: #0030c0; font-size: 0.75em; line-height: 0.5em; vertical-align: text-top; } span.AlignFootMarker { color: #0030c0; } div.EndFoot { margin: 0.2ex; background: #ffffff; padding: 0.5ex; font-size: small; font-weight: normal; line-height: 1.5em; text-align: left; } span.MarginFoot { float: right; clear: right; margin: 0.2ex; border: thin solid #c0c0c0; background: #ffffff; width: 30%; padding: 0.5ex; font-size: small; font-weight: normal; line-height: 1.5em; text-align: left; } span.HoverFoot { margin: 0.2ex; border: thin solid #c0c0c0; background: #ffffff; padding: 0.5ex; font-size: small; font-weight: normal; line-height: 1.5em; text-align: left; } span.FootOuter .HoverFoot { display: none; position: absolute; } span.FootOuter:hover .HoverFoot { display: inline; float: none; } span.Marginal { float: right; clear: right; margin: 0.2ex; border: thin solid #c0c0c0; background: #ffffff; width: 30%; padding: 0.5ex; font-size: small; font-weight: normal; line-height: 1.5em; text-align: left; } span.Note { display: none; } /* Boxes */ div.framed { outline-style: solid; } div.frameless { } div.Frameless { } div.Boxed { outline-width: thin; outline-style: solid; } div.Framed { outline-width: thin; outline-style: solid; line-height: 200%; } div.Doublebox { outline-style: double; } div.Shadowbox { outline-style: outset; } div.Shaded { outline-style: inset; } div.ovalbox { outline-style: groove; } div.Ovalbox { outline-style: ridge; } hr.line { display: inline-block; } /* Spaces */ span.hspace { display: inline-block; } span.vspace { display: inline-block; vertical-align: text-top; } span.hfill { display: inline-block; margin-left: auto; margin-right: auto; min-width: 20mm; background: #fff0f0; } div.defskip { display: block; height: 1em; } div.smallskip { display: block; height: 0.5em; } div.medskip { display: block; height: 1em; } div.bigskip { display: block; height: 2em; } div.vfill { display: block; height: 30em; } /* Sizes */ span.scriptstyle { font-size: 0.75em; } span.scriptscriptstyle { font-size: 0.60em; } /* Chunks */ div.chunk { width: auto; } span.chunkleft span.chunkright { font-style: normal; } span.chunkdecl { font-style: italic; padding: 0em 2em; } span.chunkref { font-style: italic; } /* Split Part Navigation */ div.splitheader { margin: 0em; padding: 0.1em; text-align: center; background: #f9f9f9; overflow: auto; } span.next { float: right; width: 30%; text-align: right; } span.up { display: inline-block; width: 30%; text-align: center; } span.prev { float: left; width: 30%; text-align: left; } hr.footer { margin-top: 2em; } div.footer { font-size: 0.90em; margin: 1em 0; } /* Change Tracking */ span.inserted { color: #0000ff; } span.deleted { color: #ff0000; text-decoration: line-through; } /* Google Charts */ img.chart { vertical-align: middle; } /* --end-- * CSS file for LaTeX formulas. */ /* Formulas */ .formula { text-align: center; font-family: "DejaVu Serif", serif; margin: 1.2em 0; } span.formula { white-space: nowrap; } div.formula { padding: 0.5ex; margin-left: auto; margin-right: auto; } /* Basic features */ a.eqnumber { display: inline-block; float: right; clear: right; font-weight: bold; } span.unknown { color: #800000; } span.ignored, span.arraydef { display: none; } .formula i { letter-spacing: 0.1ex; } /* Alignment */ .align-left, .align-l { text-align: left; } .align-right, .align-r { text-align: right; } .align-center, .align-c { text-align: center; } /* Structures */ span.overline, span.bar { text-decoration: overline; } .fraction, .fullfraction { display: inline-block; vertical-align: middle; text-align: center; } .fraction .fraction { font-size: 80%; line-height: 100%; } span.numerator { display: block; } span.denominator { display: block; padding: 0ex; border-top: thin solid; } sup.numerator, sup.unit { font-size: 70%; vertical-align: 80%; } sub.denominator, sub.unit { font-size: 70%; vertical-align: -20%; } span.sqrt { display: inline-block; vertical-align: middle; padding: 0.1ex; } sup.root { font-size: 70%; position: relative; left: 1.4ex; } span.radical { display: inline-block; padding: 0ex; font-size: 150%; vertical-align: top; } span.root { display: inline-block; border-top: thin solid; padding: 0ex; vertical-align: middle; } span.symbol { font-size: 125%; } span.bigsymbol { font-size: 150%; } span.largesymbol { font-size: 175%; } span.hugesymbol { font-size: 200%; } span.scripts { display: inline-table; vertical-align: middle; } .script { display: table-row; text-align: left; line-height: 150%; } span.limits { display: inline-table; vertical-align: middle; } .limit { display: table-row; line-height: 95%; } sup.limit, sub.limit { line-height: 150%; } span.symbolover { display: inline-block; text-align: center; position: relative; float: right; right: 100%; bottom: 0.5em; width: 0px; } span.withsymbol { display: inline-block; } span.symbolunder { display: inline-block; text-align: center; position: relative; float: right; right: 80%; top: 0.3em; width: 0px; } /* Environments */ span.array, span.bracketcases, span.binomial, span.environment { display: inline-table; text-align: center; border-collapse: collapse; margin: 0em; vertical-align: middle; } span.arrayrow, span.binomrow { display: table-row; padding: 0ex; border: 0ex; } span.arraycell, span.bracket, span.case, span.binomcell, span.environmentcell { display: table-cell; padding: 0ex 0.2ex; line-height: 99%; border: 0ex; } /* * CSS file for LaTeX formulas, extra stuff: * binomials, vertical braces, stackrel, fonts and colors. */ /* Inline binomials */ span.binom { display: inline-block; vertical-align: middle; text-align: center; font-size: 80%; } span.binomstack { display: block; padding: 0em; } /* Over- and underbraces */ span.overbrace { border-top: 2pt solid; } span.underbrace { border-bottom: 2pt solid; } /* Stackrel */ span.stackrel { display: inline-block; text-align: center; } span.upstackrel { display: block; padding: 0em; font-size: 80%; line-height: 64%; position: relative; top: 0.15em; } span.downstackrel { display: block; vertical-align: bottom; padding: 0em; } /* Fonts */ span.mathsf, span.textsf { font-style: normal; font-family: sans-serif; } span.mathrm, span.textrm { font-style: normal; font-family: serif; } span.text, span.textnormal { font-style: normal; } span.textipa { color: #008080; } span.fraktur { font-family: "Lucida Blackletter", eufm10, blackletter; } span.blackboard { font-family: Blackboard, msbm10, serif; } span.scriptfont { font-family: "Monotype Corsiva", "Apple Chancery", "URW Chancery L", cursive; font-style: italic; } /* Colors */ span.colorbox { display: inline-block; padding: 5px; } span.fbox { display: inline-block; border: thin solid black; padding: 2px; } span.boxed, span.framebox { display: inline-block; border: thin solid black; padding: 5px; } /* * Obsolete definitions, kept for backwards compatibility. */ /* Footnotes */ span.FootMarker { color: #0030c0; font-size: 0.75em; line-height: 0.5em; vertical-align: text-top; } span.Foot { margin: 0.2ex; border: thin solid #c0c0c0; background: #ffffff; padding: 0.5ex; font-size: small; font-weight: normal; line-height: 1.5em; text-align: left; } span.FootOuter .Foot { display: none; position: absolute; } span.FootOuter:hover .Foot { display: inline; float: none; } /* Dotted box */ span.dotted { border-top: thin dotted; } /* Obsolete aligned structures */ span.numerator-l { display: block; text-align: left; } span.numerator-r { display: block; text-align: right; } span.numeratorl { display: block; text-align: left; } span.numeratorr { display: block; text-align: right; } span.framebox- { display: inline-block; border: thin solid black; text-align: center; padding: 5px; } span.framebox-l { display: inline-block; border: thin solid black; text-align: left; padding: 5px; } span.framebox-r { display: inline-block; border: thin solid black; text-align: right; padding: 5px; } td.formula-l { text-align: left; padding: 0.2ex; border: 0ex; } td.formula-c { text-align: center; padding: 0.2ex; border: 0ex; } td.formula-r { text-align: right; padding: 0.2ex; border: 0ex; } /* Obsolete limits */ sub.bigsymbol { display: table-row; text-align: left; line-height: 150%; } sup.bigsymbol { display: table-row; text-align: left; line-height: 150%; } /* Obsolete cases */ table.cases { display: inline-block; text-align: center; border-collapse: collapse; margin: 0.2em; border-left: thin solid; vertical-align: middle; } table.cases tr td { padding-left: 1ex; padding-right: 1em; } /* Obsolete binomials */ span.fullbinom { display: inline-block; vertical-align: middle; text-align: center; } span.upbinom { display: block; padding: 0em; } span.downbinom { display: block; padding: 0em; } /* Obsolete environments */ table.formula { display: inline-block; text-align: center; border-collapse: collapse; margin: 0em; vertical-align: middle; } td.formula { padding: 0.2ex; border: 0ex; } table.environment { display: inline-block; text-align: right; margin: 0; vertical-align: middle; } table.environment tr td { padding: 0 1em; } /* * CSS section for print. */ @media print { body { font: 90% serif; background: #ffffff; color: black; margin: 0; padding: 0; } #globalWrapper { width: 100%; margin: 0px; padding: 0px; background: #ffffff; line-height: 1.5em; } span.FootOuter .Foot { display: block; position: relative; float: right; clear: right; margin: 0.2ex; border: thin solid #c0c0c0; background: #ffffff; width: 30%; padding: 0.5ex; font-size: small; font-weight: normal; line-height: 1.5em; text-align: left; } span.FootOuter .HoverFoot { display: block; position: relative; float: right; clear: right; margin: 0.2ex; border: thin solid #c0c0c0; background: #ffffff; width: 30%; padding: 0.5ex; font-size: small; font-weight: normal; line-height: 1.5em; text-align: left; } a:visited { color: #0030c0; } /* end of print CSS */ } elyxer-1.2.5/forks/pages-elyxer/pipeline.svg0000644000175000017500000002656712117067674020447 0ustar chennochenno image/svg+xml elyxer LyX file singleHTML file multipleHTML files elyxer --splitpart elyxer-1.2.5/forks/pages-elyxer/userguide-toc.html0000644000175000017500000001655512117067647021562 0ustar chennochenno Converted document
elyxer-1.2.5/forks/pages-elyxer/userguide.html0000644000175000017500000023450512117067647020774 0ustar chennochenno eLyXer User Guide

figure elyxer.png eLyXer User Guide

Alex Fernández (elyxer@gmail.com)

Table of Contents

1 The Basics

elixir, n: a substance believed to cure all ills[1].
eLyXer (pronounced elixir) is a LyX to HTML converter. While there are a ton of such projects all over the web, eLyXer has a clear focus on flexibility and elegant output.
eLyXer (including this guide and all accompanying materials) is licensed under the GPL version 3 or, at your option, any later version. See the LICENSE file for details.
Please visit the main page to find out about the latest developments.

1.1 System Requirements

eLyXer requires Python 2.4.x, and should work with versions up to 2.6.y; it will convert documents generated by LyX 1.5.x to 2.0. It has been tested on the most common operating systems: on Mac OS X, Linux and Windows, with and without CygWin.
Resource usage should be quite frugal; eLyXer runs quite happily on my 1st-gen Asus Eee, with its puny Celeron@570MHz and 512 MB of RAM. It should also be fast — the Eee can convert ~200 pages of LyX text in just over 50 seconds. Performance is fairly linear: 200 pages take 10 ×  as long as 20, so there are no scalability problems. Memory usage stays low even when processing large documents, and conversion can be done on the fly (with --lowmem) for even lower memory requirements.

1.2 Installation

This section looks at how to install eLyXer on your system, assuming that Python 2.4 to 2.6 is already there.

Download eLyXer

First you will need to fetch the official distribution file from the download area. Now, there is more than one way to install eLyXe, but all of them start by uncompressing the distributed file to a suitable directory. Just write at the command prompt:
$ tar -xzf elyxer-[version].tar.gz
Or for the .zip version:
$ unzip elyxer-[version].zip
A directory called elyxer should appear, where the main executable file elyxer.py resides.

Using the Installer

An installer is provided in the root directory, called install.py; it is the recommended way to install eLyXer. To run it just type in a console as root:
# python install.py
On Windows you can type (as a regular user):
> python.exe install.py
In any case, the script will install eLyXer as a Python script. Now you can check if it was installed successfully:
$ elyxer.py --help
A brief help text and the list of command line options should appear.
The installer will also copy existing translation files to your hard drive so that they can be used from within eLyXer for internationalization.

Prepackaged Versions

The easiest way to install eLyXer is if someone has prepackaged it for your system. Some Linux distributions include eLyXer: Debian squeeze and Ubuntu Lucid. Installation is done using apt-get or aptitude, for Debian as root:
# apt-get install elyxer
or, for Ubuntu:
$ sudo aptitude install elyxer
For both Debian and Ubuntu eLyXer needs to be run as "elyxer":
$ elyxer --help
On Windows, the alternate LyX installer includes eLyXer in the default installation. See 1.6↓ for LyX integration.

Manual Installation

If the installer did not work for you, you can manually install it as a module. On Linux go to the elyxer directory and type, as root:
# python setup.py install
On Windows just type:
> python.exe setup.py install
On Mac OS X you can use sudo to get the necessary permissions:
% sudo python setup.py install
Now you can run eLyXer as a Python script:
$ elyxer.py --help
The list of command line options should appear. You can also manually copy the file elyxer.py to a directory found in the execution path (for instance, /usr/bin on Linux or c:\windows\system32 on Windows).

1.3 Test Drive

Now you may want to try to convert the user guide:
$ elyxer.py --css lyx.css --title "eLyXer User Guide" docs/userguide.lyx docs/userguide2.html
It should generate a working web page identical to the one distributed:
$ diff docs/userguide.html docs/userguide2.html
The typical output will contain just the changed lines, which in this case should be only the header with the file creation date. An example is shown on listing 1↓.
7c7
< <meta name="create-date" content="2009-09-11"/>
---
> <meta name="create-date" content="2009-09-12"/>
Algorithm 1 Example of diff output for functionally identical HTML files.
If nothing else appears (i.e. both files are functionally equal) then everything is working fine. If you have bash installed, to test that everything really works fine you can just run the included tests:
$ ./run-tests
It will run a number of test and check the results, so you can see if everything is well. You also need to have installed the command-line tool diff to show differences between two files.

1.4 Usage

eLyXer is a standalone command line tool. It can be invoked from the command line as:
$ elyxer.py [options] [source file] [destination file]
If the source file is omitted then STDIN is used; likewise, if no destination file is specified eLyXer will output to STDOUT. This allows its use in pipes and other flexible configurations. Some examples:
$ elyxer.py file.lyx file.html
converts file.lyx to file.html. Debug messages are shown.
$ cat file.lyx | elyxer.py > file.html
converts file.lyx to file.html, as before. This time debug messages are not shown.
$ elyxer.py file.lyx | grep "<blockquote>" | wc
counts all blockquote paragraphs.
$ elyxer.py file.lyx | wget --no-check-certificate --spider -nv -F -i -
checks all external links in a document recursively. (Local links will appear as unresolved, but they can be ignored.)

1.5 Image Processing

eLyXer does not convert images directly; it uses the ImageMagick package, in particular the convert tool, to create PNG versions of the images embedded in the original LyX documents, and then it inserts links to those PNG images in the resulting HTML pages. If ImageMagick is not installed eLyXer will show an error message and will not try to convert further images.
HTML pages, unlike PDF documents, do not contain images in the document file; rather they contain pointers to image locations on disk. (Fortunately, LyX documents do not contain images either.) eLyXer will generate pages that point to the same locations as the original images, when they are PNG images, or to the converted versions otherwise. Image types like Encapsulated PostScript cannot be used directly from within pages.
Image location is fragile. All images should be placed in the same location (and with the same structure) as the original document; and they should all be referenced relatively to the current document. During conversion from within LyX image locations can be lost, since LyX does not do in-place conversion; instead, LyX copies the original file to a temporary directory, converts the file and then copies everything back to a directory ending in .LyXconv.

1.6 LyX Integration

If you used the eLyXer installer LyX will automatically detect it after reconfiguration. Just make sure that you are running LyX 1.6.5 or later, and click on Tools ▷ Reconfigure.
LyX should be able to detect if eLyXer was installed as a script, or even if it has been installed from a Linux distribution. In any case you can verify that it has been recognized by LyX by opening Tools ▷ Preferences…, going to External formats ▷ Converters, and finding the converter for “LyX -> HTML”. If eLyXer is there, it worked! Now you can convert your documents using View ▷ HTML. Otherwise try to reinstall eLyXer from scratch and then reconfigure LyX.

Installing as a Package or as a Module

Versions of the eLyXer installer prior to 1.2.0 tried to install eLyXer as a module, so it could be run using "python -m elyxer". This option is deprecated since a module called elyxer would collide with a Python package of the same name, and there are plans to install eLyXer as a proper Python package in the future (probably in the 1.3.0 time frame). In the interim eLyXer is installed only as a script called elyxer.py.
LyX (starting with versions 2.0.0 and 1.6.9) has been patched to recognize only the script and disregard the module.

2 Advanced Use

There are some advanced uses for eLyXer if you want to extract the most of it.

2.1 Command Line Options

eLyXer supports a few command line options:
--help: Show command line help.
--quiet: Be quiet and do not output messages (except errors). This way you can avoid the comforting “Parsing line 1000” messages. When STDIN or STDOUT are used (e.g. in a pipeline) --quiet is always enabled.

Advanced Options

--debug: Show debug messages. They may help a developer understand your problem.
--version: Show version number and date. Use to check which version you are actually running.
--lyxformat: Return the highest LyX version that eLyXer understands. This parameter is provided to help with lyx2lyx integration, so that this tool knows if it must convert the file to a lower LyX format.

Options to Control HTML output

--title "title": Change the title of the generated web page.
--css "new.css": Change default CSS. See section 2.2↓: CSS.
--embedcss "file.css": Embed the styles in file.css into the resulting HTML document. See section 2.2↓: CSS.
--html: Generate HTML 4.0 (instead of XHTML). The resulting pages should be easier to import from certain word processors. See section 2.6↓: HTML code.
--unicode: Restore full Unicode output. Right now switches midspaces to medium mathematical spaces. See also section 2.6↓: HTML code.
--iso885915: Generate a document using ISO-8859-1 encoding. Again, see section 2.6↓: HTML code.
--nofooter: Omit the footer message “Document generated by eLyXer” (shown at the bottom).

Options to Control image output

--directory "images_dir": Look for images in the directory specified.
--destdirectory "dest_dir": Converted images will end up into this directory.
--imageformat ".extension": Force the format implied by the extension (e.g. ".jpg" for JPEG) for output images. Use --imageformat "copy" to make images be copied over instead of converted.
--converter "program":Use the given program to convert images. Right now the supported converters are: imagemagick (default), inkscape and lyx itself. With --converter inkscape eLyXer picks Inkscape as the image converter (Inkscape uses some non-standard extensions so it might be needed to convert SVG images to PNG); with --converter lyx the new LyX option lyx -C is used. You can also supply your own converter command line, using $input and $output as variables (note the single quotes):
$ elyxer.py --converter ’lyx -C $input $output’ [source file] [destination file]
--noconvert: Use all images in their original location and do not convert anything. Useful when using images which do not convert well, such as SVG files.

Options to Control footnote output

--numberfoot: Number all footnotes using numbers: “[1]”, instead of the default “[A]”.
--symbolfoot: mark footnotes with symbols (*, **, †, ‡…).
--hoverfoot: show footnotes as hovering text. This is the default position.
--marginfoot: show footnotes with numbers instead of letters.
--endfoot: show footnotes at the end of the page.
--supfoot: use superscript for footnote markers. This is the default style.
--alignfoot: use aligned text for footnote markers, instead of superscript.
--footnotes "options": specify several footnotes options at the same time, separated with commas. Available options are: "number", "hover", "margin", "end". See section 2.9↓: Footnotes.

Advanced Options to Control HTML output

--splitpart "depth": Split the resulting webpage at the given depth. See section 2.5↓: Segmenting Pages.
--tocfor "original.html": Generate just a table of contents with links to the original HTML file. See section 2.4↓: TOC.
--target "frame": Add a target attribute to every link in the generated HTML, making all links point to the provided frame. Again, see section 2.4↓: TOC.
--notoclabels: Omit “Chapter”, “Part” and similar labels from the TOC; just output part numbers (and separate using a period). For instance, a chapter that without this option is labeled “Chapter 2: Advanced Use” in the TOC would now become “2. Advanced Use”, as on the PDF. Option adapted from the wish list: 3.2↓.
--lowmem: Activate a low memory mode which does not keep the whole document in memory: conversion is done on the fly. Keep in mind that some features as the TOC will be missing from the generated document.
--numberfoot:Label footnotes using numbers, instead of letters. Useful when bibliographical references are not numbered and therefore cannot be confused with footnotes.
--raw: Generate an HTML page without header or footer.
--mathjax remote: Use the excellent JavaScript library MathJax remotely to pretty-print mathematical equations. See section 2.8↓.
--mathjax "URL": Use the excellent JavaScript library MathJax at the given URL (usually a local URL is used). See also section 2.8↓.
--googlecharts: Use Google Charts to generate images for every formula. Again, see 2.8↓.
--simplemath: Do not generate fancy math structures such as multi-line Unicode brackets or stacked limits. This option is automatically activated when --html is selected; once more see section 2.8↓.
--template "file": Use an HTML template. The raw converted document will be placed where <!--$content--> appears in the template. Available variables: <!--$content-->, <!--$title-->, <!--$author-->, <!--$encoding-->, <!--$css-->, <!--$navigation-->, <!--$year-->, <!--$date-->, <!--$datetime-->, <!--$version-->, <!--$script-->, <!--$mathjax-->.
--copyright: Include a copyright notice at the bottom.

Deprecated Options

--toc: Generate just a table of contents. Use --tocfor instead.
--toctarget "original.html": Generate a table of contents with links to the original HTML file. Use --tocfor instead.
--nocopy: No effect since the copyright notice is now optional, maintained for backwards compatibility.
When an option accepts an argument it can be added after a space as --target "frame", or with an equals sign as in --target="frame". The quotes are optional and can be useful if your arguments include e.g. spaces.

Adding Options In LyX

To add one of these options so that it is used from within LyX, you have to modify the converter line. To this effect open Tools ▷ Preferences…, go to External formats ▷ Converters, find the converter for “LyX -> HTML” and edit the converter line. It should read something like this:
elyxer.py --directory $$r $$i $$o
If you want to generate pure HTML instead of XHTML, change the line to:
elyxer.py --html --directory $$r $$i $$o
And so on. Figure 1 shows what to do to add the --html option: after editing the line and adding the new option, click on “Modify” and then “Save” or “Apply” the changes. You should never remove the $$i $$o at the end, since it is what tells eLyXer where to find the input and output files.
figure converters.png
Figure 1 eLyXer converter in LyX 1.6.5.
LyX 1.6.5 supports a new “extra flag” line; however, at this moment it does not work with eLyXer.

2.2 CSS

HTML output, as generated, can fall short in certain situations. Some CSS wizardry can go a long way to customize eLyXer.
eLyXer tags most elements with the type so you can later modify them using a CSS. The default HTML header is similar to listing 2↓, so the default remote CSS file is used.
<head>
[...]
<link rel="stylesheet" href="http://elyxer.nongnu.org/lyx.css" type="text/css" media="all"/>
<title>Your title here</title>
</head>
Algorithm 2 CSS link automatically added to HTML
This sample CSS file is published on nongnu.org and distributed along with the scripts, docs/lyx.css. (You may have found that your document shows minor changes in its appearance with time — this is the reason. The main author regularly publishes a new, updated version of lyx.css on nongnu.org, and all documents using it automatically appear with the changes. Backwards compatibility is maintained as much as possible.)
To give your document a customized appearance (or for pages to be accessible offline) you probably will want to use your own CSS file; to use it first copy it to the directory where your document resides (e.g. renaming it to custom.css), and customize as needed. Then run elyxer.py with the following option:
$ elyxer.py --css=custom.css document.lyx page.html
This will make the generated page.html use your custom.css file. The ‘=’ sign between the constant ‘--css’ and the name of the CSS file is optional. More than one --css option can be added if you want several CSS files to be used in the header.
Sometimes the styles in a CSS are needed in the HTML document (for offline viewing, or to distribute as stand-alone pages). For these uses there is the option --embedcss: the styles contained in the CSS file passed as an argument will be embedded in the resulting HTML document. For instance:
$ elyxer.py --embedcss custom.css document.lyx page.html
This command generates a document page.html where the styles in custom.css are embedded. The CSS to embed must be a file, not a remote URL. Listing 3↓ shows the resulting HTML header for a test CSS with just one style, div.Standard. Note that the remote CSS is still added by default; to avoid it just add an option with an empty CSS file, --css="".
<head>
[...]
<head>
<link rel="stylesheet" href="http://elyxer.nongnu.org/lyx.css" type="text/css" media="all"/>
<style type="text/css">
<!--
/* Embedded CSS */
div.Standard {
  background: #909090;
}
-->
</style>
<title>Your title here</title>
</head>
Algorithm 3 CSS embedded into the HTML
As with the --css option, several --embedcss options can be added to embed more than one file.
The CSS file for eLyXer uses some CSS2 features for math structures (fractions, arrays). This makes the output incompatible with older browsers; it requires Microsoft Internet Explorer 7, Firefox 3, Safari 3 or Chrome 1. Check the Math Showcase to see if your browser can render eLyXer output correctly.

2.3 Title

By default the generated web pages have the title “Converted Document”. If a PDF title is found then it is used instead. The proper LyX title (a paragraph of type “Title” embedded in the text) will also be used if found. But when --lowmem is in use eLyXer does not try to get the proper title, since it may be found in the middle of the document or not be present at all; scanning for it would mean doing two passes, one to look for the title in all the document and another to output the web page, and --lowmem implies on-the-fly conversion to save memory.
You can change the title of the generated web page with the --title option:
$ elyxer.py --title "My Beautiful Document" document.lyx page.html

2.4 Table Of Contents

A table of contents (or TOC) can be generated for every converted LyX document. You can optionally also add a target frame to every link. The trick is to combine both options to generate a TOC that links to the original document on a different frame. For example, if the original page is called page.html and you generated it with this command:
$ elyxer.py document.lyx page.html
you can generate the TOC linking to this page, and at the same time point it to frame contents:
$ elyxer.py --tocfor page.html --target contents document.lyx page-toc.html
Then you can put it all together with a simple frameset generated manually. Just remember to place the original document in the frame called contents.
<html>
  <frameset cols="30%,70%">
    <frame name="toc" src="page-toc.html" />
    <frame name="contents" src="page.html" />
  </frameset>
</html>
Algorithm 4 An example frameset for TOC navegation
TOC generation accepts the same options as normal document conversion. For example, if you follow these instructions literally you will notice that the TOC has very wide margins and looks a bit weird; that is because it is using the default CSS. A special CSS file for TOC files is provided in docs/toc.css, so better results should be obtained with the --css option:
$ elyxer.py --tocfor page.html --css docs/toc.css --target contents document.lyx page-toc.html
With a little bit of practice you will be able to generate useful (and nice looking) TOC files. You can see an example for the user guide (if you are not already looking at it).

2.5 Segmenting Pages

Quite often you don’t want a huge monolithic page, but a set of linked pages. To do so you can use the --splitpart option, specifying the level at which eLyXer should split pages. For instance:
$ elyxer.py --splitpart 1 document.lyx output.html
will split document.lyx into pages at level 1, using output.html as the root page. Each page will get a number that starts with output and ends with .html, with a suffix that depends on the page — output-2.html will correspond to the second split part.
The level corresponding to 1 depends on the document class: books will be split at chapters, but articles will get a section per page. And so on with lower levels.

2.6 HTML Code

The HTML code generated is technically XHTML Transitional, version 1.0 [2], using UTF-8 encoding. Some programs have (in this day and age) trouble importing XHTML, notably some popular word processors. To work around this problem and provide more flexible output in general you can output HTML 4.0:
$ elyxer.py --html document.lyx page-to-import.html
Again, technically the code generated is HTML 4.01 Transitional [3] using UTF-8 encoding. Both versions should pass the W3C tests [4]. If your particular web page doesn’t pass the tests, then it is a bug and it will be treated as such.
The --html option also activates the --simplemath option; see section 2.8↓: Math for details.

Character Encodings

For better browser compatibility, medium mathematical spaces are substituted in the output with midspaces — improving the output for some popular browsers. If you want your mathematical spaces back, just use the --unicode option:
$ elyxer.py --unicode document.lyx page-to-import.html
Check out the Math Showcase with Unicode to see the results. In the future other non-Unicode substitutions might be used.
In case you want to use the ISO-8859-15 encoding in your generated document, you can add the --iso885915 option:
$ elyxer.py --iso885915 document.lyx page.html
This will make eLyXer output a document with all non-ASCII characters encoded as &nbsp;, &#x2005; and so on. This encoding is similar to ISO-8859-1, also called Latin-1, but including the Euro sign. The Math Showcase (ISO-8859-15 edition) has been generated using this option.
Both encoding options can be combined with --html at will.

2.7 Internationalization

eLyXer is distributed along with a few translation files. They are automatically regenerated every time make is run, and reside in the folder po/. Internationalization is done using GNU gettext, so every locale is identified by a two-letter code (such as “en” for English and “es” for Spanish). There are two kinds of files: the text .po file (which can be found in po/my.po for locale “my”), and the binary .mo file (found in po/my/elyxer.po).
For internationalization to work properly, Linux distributors should take all binary .mo files and place them in the directory corresponding to locale files, which we will call $localedir. As the Python gettext page explains, this is distribution-dependent: for example on Debian $localedir is /usr/share/locale, so for locale “es” the correct route would be
/usr/share/locale/es/LC_MESSAGES/elyxer.mo
Windows distributors on the other hand should place files in %PYTHONHOME%\share\locale, for example for locale “es” on a machine where Python is in C:\python:
C:\python\share\locale\es\LC_MESSAGES\elyxer.mo
To generate a new translation file (we will use “my” as an example locale here, corresponding to Burmese): you need to have the GNU gettext package installed. Then go to the directory where elyxer.pot resides:
$ cd src/conf
and generate a .po file for your locale:
$ msginit --output-file=my.po --locale=my
Then move the file to the po/ directory:
$ mv my.po ../../po/
and start translating it to Burmese! Once you are done run make from the root directory:
$ ./make
and it will generate the file po/my/elyxer.mo. Finally, place this file in
$localedir/my/LC_MESSAGES/elyxer.mo
and you are done.

2.8 Math

Math equations are an important part of what takes LyX apart from other editors, since it supports the full LaTeX feature set — that is, about everything under the sun. Unfortunately, math support is hard to get right. Many developers are focusing on MathML, but at the time of this writing (Q2 2010) support on some common browsers is still missing.
eLyXer follows its usual minimalistic approach and doesn’t try to be everything to everybody — instead, it supports out of the box a set of usual constructs (fraction, square root) and tries to simulate others (binomial, overbrace). See the Math showcase for yourself and learn what eLyXer supports and what not.
For more sophisticated math equations there are a couple of advanced features.

MathJax

The first option is to use MathJax, which is as simple as using the option --mathjax:
$ elyxer.py --mathjax remote math.lyx math-mathjax-remote.html
The remote argument tells MathJax to access the MathJax library remotely on the MathJax CDN. (You should always comply with their terms of service.) See the Math showcase (MathJax remote edition) to check the results.
In case you need to go outside the terms of service, or you want the content to be accessible offline, you can always use a local copy of MathJax. Just use the URL of the repository as an argument to the --mathjax option:
$ elyxer.py --mathjax MathJax/ math.lyx math-mathjax-local.html
This way eLyXer uses the given URL (in the example MathJax/) to load MathJax from and set it up. Although some code needs to be hosted on the same site as the pages, MathJax uses a feature called web-fonts which can be downloaded from a public server; this is quite easier to host. See the Math showcase (MathJax edition) to see how MathJax fares with eLyXer.
Something to note is that MathJax is a JavaScript library; all rendering is done client-side by the user’s browser. This has quite a few advantages:
  • Math processing on the server is quite light; equations are basically surrounded by a special tag and left in TeX form.
  • For developers: integration of these libraries is very easy. It took just a few days to integrate both libraries with eLyXer.
  • MathJax is improving all the time thanks to the efforts of Davide P. Cervone and the rest of the developer team; eLyXer and its users reap the benefits readily.
  • The client browser already knows its abilities, and can choose the rendering method it considers to be the best. MathJax can even choose between MathML and HTML+CSS at page rendering time, showing MathML on fancier browsers and simpler HTML where it is not available.
It also brings some disadvantages:
  • With the remote argument, JavaScript code resides at a remote server and your users will need online access to view the maths.
  • If MathJax is accessed locally you need to also host the code for MathJax. (Web fonts used in MathJax can at least be hosted elsewhere, so publishers do not need to also host the fonts package, but this hasn’t still been used in eLyXer.)
  • And of course it takes some time to render everything on the client, which can degrade the user experience on older machines.
Publishers should carefully consider pros and cons before deciding what to use.

Google Charts

Google Charts is an online service which generates images that contain charts and other stuff; it can also generate TeX formulas. eLyXer can use it using the option --googlecharts:
$ elyxer.py --googlecharts math.lyx math-googlecharts.html
There are some limitations to Google Charts: no macros, formulas cannot exceed 200 characters, and the supported command set is limited (commands in text mode, for instance, are out of bounds). Also, generated images can be hard to align vertically — by default they are middle-aligned, but some small characters or superscripted formulas can look weird. But this option can be a quick&dirty way of showing math for older or unsupported browsers.

Brackets and Limits

Fancy math structures are generated by default: arrays and binomials are surrounded by multi-line Unicode brackets, limits in display mode are stacked above / below the symbol, and so on. When the option --simplemath is used eLyXer avoids such structures and just outputs enlarged regular symbols. It is also included in the --html option.
Check out the Math showcase (HTML edition) to see the results.

2.9 Footnotes

Footnote generation is surprisingly hard to get right in an HTML document. eLyXer has a fairly complete set of command line options to customize how footnotes are generated. Here we will use the aggregated option --footnotes "options" which can be used to specify any combination, but they can be turned on independently using --…foot. For instance: --footnotes number,margin is equivalent to --numberfoot --marginfoot.

Markers

The footnote is attached to a point of the text (the referring text) which is usually marked by a bit of text. The default behavior for the marker is to use a superscript letter surrounded by square brackets, in blue: [A]. The text can be changed to aligned text with --footnotes align: [A], so markers are not mistaken with other superscript constructs such as exponents (like ea).
Markers can also be converted to numbers using --footnotes number: [1]. Or, they can be switched over to symbols using --footnotes symbol: *. Available symbols are rotated from this sequence: * ** † ‡ § §§ ¶ ¶¶ # ##. All options can be combined. For instance, symbol markers look best when shown aligned; --footnotes align,symbol will show aligned symbolic markers such as * or .

Position

Footnotes are supposed to appear at the foot of the page, but that is not always possible or practical in web pages. Huge pages make scrolling up and down quite uncomfortable, and remove the immediacy of having the note in the same page as the referring text.
There are a few alternatives: use the margin, show hovering text, or link to the note at the bottom of the page. eLyXer can use all three. --footnotes margin will place the notes at the margin, just as margin notes but with the addition of the footnote marker. While --footnotes hover will show hovering text when the mouse is placed on the marker; this is the default behavior. Note that hovering notes are converted into margin notes when printing.
When footnotes are shown at the end of the page with --footnotes end, footnote markers turn into links. The actual footnote at the end then contains a link back to the marker.
The most interesting part is that these three options can be combined at will: --footnotes margin,hover,end will show footnotes at the three possible locations. The most practical combination is probably --footnotes hover,end, which will show notes as hovering text and also at the end of the page. Note however that in this case notes will be printed twice (at the margin instead of hovering and at the end).

3 Work in Progress

As you can see eLyXer is a mature and tried package, but it has some rough edges.

3.1 Known Issues

The following issues (including bugs and missing features) are acknowledged. Some of them should be solved soon; others may take longer.
  1. On Mac OS X the output of a message with Unicode characters may cause an error. Workaround: run elyxer.py with the --quiet option.
  2. Some phonetic alphabet symbols are not well supported — if generated with LyX they only appear in a different color: [sample].
  3. Multi-column layouts are lost. This one is almost impossible to get right in CSS, so there are no plans to even try.
  4. Many BibTeX styles are missing. (They are quite trivial to add though.)
  5. ERT (bare TeX code) is ignored.
  6. Many AMS environments (like alignat, gather…) are not working or look strange — some non-AMS environments too.
  7. Images are never scaled above their nominal resolution. This is seldom needed if at all, so there are no plans to change it; if people really need the feature just let the author know so it can be added as an option.

3.2 Wish List

The following features have been requested by users; specific people are referenced by a couple of initials so they can recognize themselves while keeping some anonymity. (If you prefer that your initials do not to appear here at all just let me know.)
Queued features will be added at the next big release — the priority for each feature will be set by the number of users requesting it and date requested. Pending features need some assessment. Those marked as too complex have been evaluated as requiring too much work, but the decision might be reversed if there are enough people interested or a simple way to implement them is found. Once done, features are marked with the first release where they appear.
Feature Date Users Status
Understand \setcounter{section}{1} 2010-05-15 JB 1.1.0
Option to turn off title prefixes in TOC 2010-07-10 YG 1.1.0
Use BibLaTeX with eLyXer 2010-09-14 PJ, WE Pending
Render change tracking: "Show changes in output" 2010-09-18 YG 1.1.0
Option for footnotes at the margin 2010-09-21 A 1.1.0
Output SVG as <img> tags (20↓) 2010-09-22 YG Pending
EPUB output format (19↓) 2010-09-23 MJ, MG Too complex
Option for footnotes at the end of each section 2010-09-23 MJ 1.1.0
Add more controls for image conversion (21↓) 2010-10-02 WE 1.1.0
Support for format 401 (Insert Horizontal Line) 2010-10-06 US 1.1.2
Parse contents of ERTs 2010-10-06 US, JW 1.2.0
Correct scaling of tables with relative sizes (e.g. %col) 2010-10-09 US Pending
BibTeX: parse math formulas inside BibTeX files 2010-10-16 JA 1.1.1
BibTeX: display \url{} as an URL 2010-10-16 JA 1.1.1
Do not label bibliography items in comments 2010-10-21 JA Pending
Unit tests should warn if ImageMagick not installed 2010-10-24 JA Pending
Unit tests should run fine without PNG conversion tools 2010-10-30 JA Pending
Option --imageformat copy to avoid converting images 2010-11-12 JD 1.1.1
Option to embed the CSS in the HTML file22↓ 2010-11-23 GM, JA 1.1.1
Display sub- and superscript aligned vertically (as in integrals) 2010-11-23 GM 1.1.1
Use Unicode large characters for sums, integrals, matrices… 2010-12-07 GM 1.1.2
Do not number captions in code listings 2010-12-08 DC 1.2.0
Support brushes for SyntaxHighlighter 2010-12-10 DC Pending
Generate formula images using Google Charts 2011-01-07 ET 1.2.1
Output reference arrows as CSS pseudo-elements 2011-01-12 GM Pending
Include part names in --splitpart navigation header 2011-01-15 AJ 1.2.1
Merge options --toc and --toctarget into --tocfor 2010-01-17 JA 1.2.1
Make --splitpart and --tocfor work together 2010-01-17 JA, TP 1.2.1
Generate named references (equivalent to \nameref) 2011-01-19 TP 1.2.1
Do not generate entries when index or nomenclature are missing 2011-01-19 TP Queued
Do not output unknown commands in red except in --debug 2011-02-22 JA Queued
Output equations as images 2011-05-31 GK Pending
Parse modules for custom Flex CharStyles 2011-06-08 MG Pending
Convert several files with a single command 2011-06-01 PF Pending
Export slides as HTML5 presentation 2011-06-28 RK Pending
Add an option to remove navigation bars 2011-06-29 AH Pending
Support for External Material: PDF, Date 2011-10-22 MI Pending
Some features require further explanations.

EPUB output format

The EPUB management package calibre does not output valid EPUB documents when converted from eLyXer HTML files, at least according to the Threepress validator.
This is a complex feature request; calibre does minimal formatting in its EPUB conversion, so making it generate valid EPUB documents requires changing deeply how eLyXer outputs XHTML. Lots of help would be needed to get this working.
That said, EPUB readers are often much less strict than the official format and they readily accept eLyXer output. Just convert your LyX document to HTML using eLyXer, and then import the resulting HTML document into your EPUB reader. Let us know how it goes for you.

Output SVG as <img> tags

This feature would be most welcome from the part of the author. Unfortunately, Firefox alone from the major browsers refuses to render <img> tags correctly for SVG. According to bug #276431, this was fixed on 2010-09-08, so the next version should do the right thing; at that point this feature will be queued for inclusion.
You can check out how your browser does with SVG images with this SVG test page.

More controls for image conversion

eLyXer uses ImageMagick to convert images. Some images (in EPS format, for example) do have blank borders, or they come in varied sizes. It would be nice to remove blank borders and have some kind of unified resolution in the conversion, which would be passed to ImageMagick.
As of 1.1.0, the improvements include using ps:use-cropbox=true in ImageMagick for PostScript and EPS images. Unified resolution has not been added as it might collide with picture density, but suggestions are welcome.

CSS controls

Proposed by JRAS on the elyxer-users mailing list, the following is a direct quote of his message.
“[…]A mixed solution for CSS styles:
  1. The essential minimum css for math formatting (a compacted version of a math.css subset) included directly inside HTML head.
  2. Then a call to download the on-line full CSS, that can repeat the minimum already included math.css (from item 1) plus some other styles. The default can be changed by --css command line option.
  3. A new option (--addcss) to add another CSS defined by the user. For example, to only redefine some styles from the default, etc.
The styles should be included in that order (using the "cascading" property). Item 1 is fixed in every HTML file. Item 2 is always added and by default pointing to the eLyXer on-line css, but it can be changed by option --css to another url or file. Item 3 is optional and its url would be added after the other two items, only if the --addcss option was used in conversion.”
As of 1.1.1, an option --embedcss has been added which allows embedding one or more custom CSS files into the resulting HTML document. Also, --css can be repeated as many times as desired to use several CSS files.

3.3 Contact Information

If your problem does not appear in the above list, please let the author know; you can find him at elyxer@gmail.com. In the words of Rich Talley: “the tool’s author really likes getting challenging documents and making eLyXer work with them”. You can send your sample documents and we will try to make eLyXer convert them acceptably. Any documents sent will be treated with the utmost confidentiality.
You can also join the mailing list to discuss any information related to eLyXer. The author monitors the official LyX lists for mentions of eLyXer. Bugs can also be reported at the Savannah page.

3.4 Extending eLyXer

eLyXer should now support most LyX features; but sometimes it will ignore a command, sometimes it will signal it, and it might even refuse to work with certain documents. What can you do if eLyXer does not work with your LyX file? Worry not! Its flexible approach to processing allows anyone to write support for the missing commands.
eLyXer is written in Python so that it does not need to be compiled; its code is interpreted on the fly. See the accompanying developer guide to learn how to extend eLyXer for your own purposes. If you know how to program in Python it should not be difficult to support other LyX features. If you don’t your best bet is to ask the author.

4 FAQ

Q: What versions of LyX are supported?
A: The tool should work with all LyX versions from 1.5.5 to the latest and greatest. It has been tested on Linux, Mac OS X and Windows.
Q: There are indeed a ton of similar projects over the web. Why add another one?
A: The four tools supported by LyX (tex4ht, hevea, tth and latex2html) gave inferior results in 2009, and were quite inflexible. The author found the need for a good converter, while at the same time acknowledging the difficulty of the problem.
Q: Speaking of that: why build a LyX to HTML converter, instead of a more generic LaTeX to HTML converter?
A: The problem space is quite simplified, and therefore progress is much faster. To make it even easier eLyXer has historically centered on the subset of LyX functionality that is useful to most LyX users, leaving the rest for a later stage. Nowadays eLyXer aims to support the full LyX feature set.
Q: What can we expect from the tool in the future?
A: eLyXer should fulfill the needs of 99% of LyX users in the short term. It has also learned a couple of tricks of its own such as page segmenting. Eventually it could be distributed along with LyX as part of the standard installer.
Q: Why did you leave out my favorite feature <insert random LyX command here>?
A: In short, because nobody asked for it. Every feature which has been requested (either to me personally or to the list) has been tended to, unless it was too far out or I forgot about it. At this point of development every missing LyX feature will be considered a high priority item for the next version, if at all possible to implement.
Q: My document changed its appearance without my intervention. Was it black magic, elves or what?
A: It probably uses the online CSS file, which is regularly updated. See section 2.2↑ for details.
Q: Why use an online CSS, instead of placing the CSS file in the same directory as the converted file?
A: There were pros and cons. An online CSS resource allowed me to update it for everyone at the same time, but might make it more difficult for people without an internet connection; local CSS files are more flexible but can also be confusing to novice users. In the end the online solution was preferred, with the --css option as a fallback.
Q: My MathJax pages are not rendering correctly; equations are silently ignored.
A: Check that MathJax is installed on the same server as your pages; for security reasons the browser’s “same-origin” policy mandates that JavaScript can only be loaded from the same site as the original page. Also make sure that JavaScript is enabled on the browser.
Q: How can I disable hovering notes? Isn’t there a --nohover option?
A: It can be done using --footnotes margin. This will disable hovering text but keep footnotes in the margin.
Q: I found a bug, what should I do?
A: Just send it to the author at elyxer@gmail.com. You can also report it to the Savannah interface.

References

[1] WordReference.com: “definition of elixir”, accessed March 2009. http://www.wordreference.com/definition/elixir

[2] W3C: “XHTML™ 1.0 The Extensible HyperText Markup Language (Second Edition)”, revised 1 August 2002. http://www.w3.org/TR/xhtml1/

[3] W3C: “HTML 4.01 Specification”, 24 December 1999. http://www.w3.org/TR/REC-html40/

[4] W3C: “Markup Validation Service”, accessed March 2009. http://validator.w3.org/

elyxer-1.2.5/forks/pages-elyxer/math.html0000644000175000017500000011417412117067647017730 0ustar chennochenno eLyxer Math Showcase (non-Unicode edition)

figure elyxer.png eLyXer Math Showcase

Alex Fernández (elyxer@gmail.com)

1 Introduction

This document is intended as a showcase of the mathematical abilities of eLyXer; for more information be sure to visit the main page.

1.1 Versions

There are several versions of this page:
All of them are generated from the same .lyx source file; they should help you decide which rendering options suit you best.
Also available online is the eLyXer translation of the latest LyX’s detailed Math manual, which contains a lot more examples of LyX maths.

2 Typography

Math formulae use a lot of different symbols and fonts.

2.1 Greek Symbols

Greek symbols are very important in equations: φ, π, Ξ. eLyXer offers a complete set in both upper case: Γ…Ω and lower case: αω. Also the AMS italicized upper case: ΓΩ.

2.2 Math Symbols

eLyXer supports the whole set of math symbols in John D. Cook's list: ∃∂∇ ≥ . It can also render a few more:  ∝  × . You also get all symbols from Markus Kuhn's list: ⊙∐.

2.3 Other Symbols

There are other symbols like arrows:  ←  → , or geometrical shapes: , . eLyXer offers limited support for them. You might also want to use financial symbols in formulae: ¥€$.

2.4 Spacing

Equations look good when items are properly separated. The main separation is the Medium Mathematical Space: x = 3. Note: if you are viewing the non-Unicode version math.html of this page then you are in fact seeing midspaces, which are very similar but not exactly the same: (4)/(18) em for medium mathematical spaces versus (1)/(2) en, where 1 em = 2 en. Try out the Unicode version math-unicode.html — and viceversa. You can check out what version this page is in the page title.
The command \raisebox is useful to, surprisingly, raise a little box,
raisedoverloweredand back.
Like \mbox, it puts its content in a text box. It can also be used just for spacing:
BV.
There are other spacing commands: \hspace: a b, protected space: a b, and (at “block level”) \vspace: a b.
There should be 1 cm of vertical space above this paragraph.

2.5 Fonts

By default, letters denote variables and are taken from the \mathnormal font, which is italic, αx + αy = α(x + y), with the exception of upright capital Greek letters, G ≠ Γ.
Function names should be upright: sin(2π), log(x), tanδ.
Mathematical fonts used in equations include Roman (\mathrm), Sans Serif (\mathsf), Typewriter (\mathtt), Bold (\mathbf), SCRIPT (\mathscr), CALLIGRAPHIC (\mathcal), BLACKBOARD BOLD (\mathbb), and Fraktur (\mathfrak). For the latter, some single characters are translated to their Unicode equivalents: , 𝔽, 𝔉.
Regular text in a formula can be achieved via text font commands like \textrm: 5  to 10, via boxes like \mbox (prevents line breaks): 6  is more than 5, or the AMSmath \text macro (scales like math symbols) basesupersub. The content of an mbox is processed in LaTeX text mode. This allows text font commands, e.g. a switch to sans-serif-bold-italic, or the phonetic alphabet: sfbfit, tipa.
Units should be written upright, either with \mathrm or with macros from the units package, e.g. as simple unit, km, with magnitude, 57 km, with fractional unit, 200 kmh, or with a fraction before the units, 32 km, (7)/(16) s.

3 Numeration

Equations can be numbered, like (1↓)
(1) y = x
And also like (2↓).
(2) x = 3
Some equations can be numbered even if they don’t have a label.
(3) x = 2y
Notice that equation (2↑) comes after (1↑).

4 Simple Structures

Let’s now see a few of the simpler structures that eLyXer can output.

4.1 Fractions

A simple fraction:
(1)/(2).
Inlined: (2)/(3).
A big recursive fraction:
(1)/(1 + (1)/(1 + (1)/(1 + 2x)))
A nice fraction: 56. A non-diminishing fraction containing alignments:
(1)/(1 + (1)/(1 + x) × (1)/(1 + x)).
A similar concept is a binomial coefficient: (A + 1B). It can be prettily presented:
AB + 1.
A symbol can be stacked over another using \stackrel: xR → y. Anything can be stacked:
dx > 3limx,  headheels.

4.2 Limits

limx → ∞f(x) should appear as x → ∞ in italics, and «lim» in plain style. In display mode, a limit must appear below the main symbol:
limx → ∞f(x).
Limits are also used in sums and integrals:
i = 1x,  0f(x) dx
where the sum’s limits should appear below (i = 1) and above () the . The placement of the integral limits depends on the document class: LaTeX standard classes place them right to the . Limits are shown to the right in inline formulae: i = 1x and i = 1x.
The placing of limits can be configured with the \limits and \nolimits macros:
limx → ∞f(x),  i = 1x,  0f(x) dx

4.3 Roots

A square root: (3). A more complex root in a fraction:
(1)/(1 + (2)(1)/(1 + (2)) + ((1)/(2))).
eLyXer can also do higher-order roots: 3(x + y). A devilish case mixing everything we have seen so far:
(78((8)/(4)x) + i = 1x)/(s + 5(((78x + 45y) × (Ω))/(sin(x + 1)) + 38 km)).

5 Complex Structures

In this section we will explore arrays and related constructs.

5.1 Arrays

An inline array a b c d is always shown in the same line. In display mode, the array is shown on its own line:
12 2 3 4 × yx
Apart from that the appearance should be the same.

5.2 Brackets

Arrays are separated by variable-size brackets: a b c d a b c d a b c d a b c d ||| a b c d |||which might also differ on right and left a b c d or use the empty opening a b c d or closing: a b c d |||. There are also fixed-size big brackets, e.g. f.

5.3 Cases

Used to switch between several values.
y =  x i = 0,         x + 1  i < 3 
Cases may have more than two rows:
f(x) =  0  x < 0,         ∞  x = 0        0  x > 0 

5.4 Braces

Values can be underbraced or overbraced.
a − b = b + c + d + e.

6 Macros

Now it’s time for user-defined commands (sometimes called “macros”).
Definitions can be added as macros. Then they can be used in formulae: 1(2). They can accept default parameters. Again, useful in formulae: 4(5).
Other definitions from the preamble can be used: 3(4).
Definitions on the fly are also possible: 7(8), and used with different values: a(b).
elyxer-1.2.5/forks/pages-elyxer/converters.png0000644000175000017500000016106512117067671021007 0ustar chennochennoPNG  IHDR-F6|sRGB pHYs  tIME ,܆J IDATxwXSW7 ʒ=d8@-"ZD'.AQ@TsZAAT* ZJ+*Qd+1e>499ܛk8nߌ"@ $)Ti() B!BmxD!zt:FitSPrr@IB/`:iHt&5c20V69l`B!by؍Id+ޑ9+@h|vhp@_L xx!BKW (b\*L@lP$Ň$-w]z{b2j25MВE!W$UVP4Dq MJK#l6(t.Rs@,|S.(r|'5%ͭWo[O}SIQUUFvSz8C!$+{^~ؘ')қPv興e@ )lJh^Vh0e4q<`e/;PwrabIt@P]]o>Jz l6?!BIW^ڪ5k4Eߗd_#iDR/.2(.&A⫝̸Tڡ[E݀ZO`\H(1FMMYOQIɔH+*J}=|HMơB!$d髫9:*((H1#j"o*8t?s[dI.">>;m*Ax@0? (*3JTXT' %(KKAl˗'N(BmF VWW++ed Zmv ))#xfl\RnSt0X@]o&l`0]s!RSvVN^.OGG_ 5:ʏ\tDk&al6 l 0˜ؿҘR,iY\$| 4`Ё)li` ZW))ϞןSbujd@@ƅv_wmq*/@&yo^yWc FX‚͘m @؛,_ΐ]<~0rWĨ/jYзo^}7mN_3~\{#Y- C%& ^&<=nn⇟v}7uΓGӭA\3>E;PI>;Ξ<0NUUe3e8GÂwї~󡴞j5g9q]f16,v;}Aں΋WhiworLIqa/'WN!:ҷotLhP 1]I#㈈ KćqLQO>·W*I5>E:Ƥ]VNqQ2~fuq UǿҀ/D%];`7ONVw޻mXN;q*뗣/fb6X&U>~ӕ'"/>‚n*f9Q7níxÿ>wtu._:x9q]oء˒U ZsԹqw;{aUUeyiiC0R$IzV MJ`2Y,i< FC@H$y|>ɀO ,ćQbTP} \T&.+ @L< $1B%B.·~>QVZ zo ozsBX%f I/Jz!#+;zJ/_r—{JɰdX^=wK`|- Z;t ˭&JyL0S%+P?ݾ寧v-쵨2rnϒqB*7]@@2bH \> 4fH3S$> <6!.Sފ~&9Yl2@oOglWRUY.C>!yU9sv`bIg;z]Vzwޗ>v*eA~~O oݜOE6ו-O="={YG>O)Z;i`4> @@W"0Z~uUnzy©Qzt<,}Wbir6FD5#Dø0>guK5\l. g2AFFڍ QcH<!ԉQ[aw_p*qYoLcs+"<$ָN7e<&qҟ6x55STwk?VȣMT~]P3J%22SM~ޯw7]]KOO@ ZPM1՚ޡhM|G!#ʥߊGOKMh>~޾e:Т߀AO$Wߊuj]Oμu1WAK.]|j0b>_PPpG ɀʚÀ x~~PTen">\ƨvQQ^|>0 +J|n܊jCGY!Թhob¿ TًɞAf-&N_Z7&~WnG_ۼ6 8t&U&!UKΓ^Rs {6Q4VT&RdEkҙ4&0{q♫V }ɩc `>iio!лi*쾌!{FI TT@t:9eeo=J+疫iQ#"p \aV6AŃTsXf⿷LyW*h!#R:FQMGﲤXZOTKLiD?Hly9Jw*՚US2rb!I*WPRVQ3! V/&ٓ#++EtF "7555..ݻԈS>  r3_*Rh @4>j\Q^}#/MU#fTU ߦfW2m&͑0$测cD~ ׆(/{uTnv7== CZ_YY^TT]=ÇQSf\,)cCp0HLI.Rg6qW$RV8$sX & *+yx|kiCFXKcV$Wā r2z<S%M:A޹*1LUU Uӻ̇q#RRsRin}DKuIB$*_ fg=;6QZqa.VUcbffn#B!$ѳo>R/`J˪i?"}"J:ab*9G ƃZ8mWUU >`02,4B!ƚ2""jFSD٧R3?/  z]hh| PT}LB!hˆS>·AlIσgTUB!c*y @lu*h!B&6`\]xWB!jM!r]A\0B!PA#l&l6·!B>&&jB1> !B`|B!P0Bva!BB!Ƈ!BC!j'B!>0> !B]`|B!P0Bva!BB!Ƈ!BC!j'r,j |<!$D+ŇP }qϟǃBHb|Ix|3a!$h|&>^>B!j?xB!U V.·!B+f?ƇсGpy@h˒͘hIII$hcǎ+++:tHղ"o !BT3.S~ѢEwܩ=z3e``gB!>KLJ; (KKK+++{񪫫KKKɃByח,((pwwr労ٳlr;v۷͛={-֞:uʕ+K$I޽{Ϟ=YYY4r>>aaa111zzzu.\`_U̦E^xqҤI|G߾}{ҥ\.wݺu 6x jVjK֚{]F;yKz [n hjaÆm۶_¶mvǏ{zzzܹseee>>>ukĈΥ)((Pbii ֭kO `BuPm?<𫉳`hhH=544S.?\zpxƍ )))vvvL&sn]EEE]]nyJJʨQDKtrB}+gRQQׯ_SO߼y&r9rV|>_SS~99oN>Y{KHHHSBYk7o$yyy[[e˖%''sSN Xrenn&wﮥr#G7k?ϟsesssjP9B!fmֲ`7[[[ѧԕͰŋX,a WCBǎO<),d0={ׯKJJfΜ9f&/F6mZ~~rB}2>ew5Or& 111u<ٳg%M`X۷o߾}{tB!ɇK"B 6YB!ćk@}C!׮Qp> !B_si!2> B!$:e|·!BHćkl 8:k6 >lxiA$+>~Yt[<1_MH\LY@jjZ?S 1DwV!al0F$TkhhBQ$I۳X,Zy/͆zƟ|M[88P3$yqf;yƱ㧨qy?S7o;#!Mi軛3>ê:ݨzߝBCuf7:f3gو*}aO622b2:::zw^F4005.I.\0tP& fffp&ǎSEEeƍurrQrrr+++{!Z(%%ߝŒ7~Pzo{8~Po51^=jƟwn@zFfSq_9e/:9xKlmƟ<)M}wz<///kmTTw'Pf?ao!Ց01322݋ 88G}M&~~~۶m;wn\\\ɓ'PVVFUhJM Ǝv! <|RRٳE }N]o-t|%ZQ^]O)--VRաCkj㧼֯6_UUeE N:qwu8aZMxb:Ww'^s|>_VVf;.s8rxB"65>lW1?Iuu5x>77k׮wސKKKpppHOO"~G;;;nذ\]]w]BSCFFFGG_ݹsٳرc$Ih41TUY,ֿ)&=7\VT-\G[ @XMKSz@ѩ,Ԅqc]a9bԕ+< gۥ?6]kA޼yd2UUUwXﮑ?lKuq~;tut8͝d;OHF4>Ym τ ;wn=zXzy %%eԨQիW& j\sgO>uvv{{:#CTEEeŊbFkX]~Y?+C=6ddd@FV- EnĥLaI+inn^YyQN u䙡V1֫w'BUEWFk~s7kV2dLJ (Ϟ=2997om޼1;;ccc M4-\0,,,...""Dʂ.+T/yd?x*?67k4ng0_ii/v j4*Dk>vmH2vΧ$u7v /\#&2RSޤ}FW/~t(Fp+su[%WUVIIIɰlD}u$;>lٲe...AAAO>}޽{W^ |>ҤIgΜ),,$b=<}BdƇ*Zy8PкϟǃB_ !o!P%B!ډH0C!jC"a_!B/B!:;C!j'dyyʕ+ KAAA;m$Y,V  E!$?lũ'O޽۷oM^G;55522R>w$''.vCxB = v٘AΉ'455pWUUy8CELKh7Q4>Y2ᶙ022p8A'x7%%%VVVAAAz>3gάYm$I޽{Ϟ=YYY4rvyܹscff ݯ\"--={@6MF~j=}wJJƍ]]1fp!$y5B- ova 6l̘1&M211ϫmذaO]II wB 5q ~kO7XC?EM81###66 _u۶m{qrrΈ㏳g{۷RKKab`Æ JJJ%%%b/]ddd4p[8qB~|>p8]vœ!P-/yxڑh0:.my?OсNxx8F333[zuttիW222zMUSQQYbFR())))FS"_t:]CCCꩡavvU;wȑ#fffW^e2x6#B$xϞ=P!V<OMMMxbAA˭;QVV%kddd$$$)xQ***k7oԄ溺LNN͛EEE7ovttáAђDKߟVK.Q k؈vXVg1Ŀz|fKRSS9Ξ={VNKKr'~!x"$SVV1cƌ3Μ9ŋ''QFijj:::]ÇiiiVew-v999/_677?r䈘f]lYrrr\\?0wF[ϟ4iҙ3g `Xx26WWĨ(H1rHBfff\\~qqq;&Ii񻨫O>[n]fMzz:EYXXxzz֭vZ PRR-~˗!I 7mڴbŊw)**ڵ lBĉ,--O>] ___6mڴ|]]]www* [x)rppSY[[HCCR^^>((hՙzzzx26eeeeeeS##ZO>MI/>ʕ+]kŊϟwssrJhhh|||BBB݋_~hc `hh=~x<-j~혣%?Ň5;233Aaa#G,k݅7oi$)kbm߾=''秦nܸ j\Qݿk={_~ILL,X_~=sL<;3f:uJGFFNgϞZxcnjLƍ҄$ɟYOOOJJW^{{Ϛ5k6?~-5>./:uJKKKFF޾){(z]F]paСL&S__?22*Ν2d433ÇPXXnݺ#G 6Vs999}􁚨/UUaPfC3zk.734yT%$I>JJ}~+[.0> /4ߊ9޼y$B|oՑcƌVSS{yxxx b%Iрzs$d%%%ooo0a󝜜D/2RzIrwwOHHsqq\xmC|}}Ml2www__cǎEFFIKKS XjUVVV`޼ycƌ9t?-CJ\\eV :yyߘ Ld2e2^$&M8jh[*â qr !jF@II%Æ }Makkkggׂ}_~,[,۷o57ohBVVV-Κ5WX׻;&W^t-5eܫW)9=z0W>9>?* 0> EJJs!C Ƌ/z[yjͮ!jy’SF=}7/_ST\L=h\2H~|XJJ̙3 ֭[|& BFڵJ9&++;bĈʾ}6l ##!1?Od^~(-f9"/'?^_U*##oy􌲲i<16\Bć1k$g>,==}Сcƌ9{aÆ>ԺRHս}vklfxo/ymWɯR45554_%>Jt/vqViUQ#G\x g-L6MHl|؆ FyqwSSS z{{rR:uIf l(6j^EyYUէrF /үOQF)*2L[AE8hz%$/Ij*CӧOn 䔔.]Jy UhjħO9xcB9ٙoSS^*|$ɼ_>yWߗR;P .kbb"Zb_~Ν !m۶s988x{{gddcoBaxG'.M6FE֛޿ҥ$jݕ[zzz 4n?H%<v+B·5ջHԩI֖~UUUC ޽;R円٢[SW^55s޽ãGWi !j{3>L. MIUȺ$9>LZZzʔ)۷o… O>566o~5U555+yݼyh͎ssiVZ}.]j^/_쐐aIjj*ٳgOiii666MZHgXMyShѿyWW/{X,֨Q$''7~'OPM|m}:|5ު? $<ߝ;wO~gϞ.YDSSS^^vٲeqqq?ܹsE6Z'Mt̙B X,,J&&&&&&FEE@b#G6ԤO>[n]f @ Xhgk׮]bECC 1RSS###񒓓[k˗/i_|y-))){{{a—444Z EWxH·a|X& ݻn:;;r}}֭^ [x)rppռ p-((hՙzzzV2FLYYYYYYȨ)VXqy77+W'$$]*׏=:qD v Z*((DGG?Ki`` z۷.]rX;v,]tƌs̩7jredWW׳g߿?88<>>~ɒ%T'O14.jUnh̙r''gϞ0dȐ[$)J_rǢEEEE7nٳn5 ^xqҤI|Hj0<|&> `ٶ6Cq8=zPïF[ݻ7$$Ӄ_xd2SRRߢ?ޣGђ}QY]4[l2e/rԮGCoXXg-/cǎmzpRZu> X;a̛7oDG%%%^^^PZZhr{xx\|ȑ#$I.YDII&L0|''Z{IrwwOHHsqq/<P j5WH*2!"1!;;'@ `0'?x`ٍ0 ;}AƇ &pٸjF۵kW@@ʎ1}6lв|J!E^$?>,**$p+++)) 39!1YYYɑ${펶{666 CRa}0ɞ-h M5&?CEBR·IY[l+++EK>}ȈdPQ:uJKKKFF޾VWǎZlܸ*\z3$I~7!!!uBa|XI',)**rpp twwf֞{nzzp_ رc:㓑f͊6y٫Wf͚B6ah|&>^>>U]]y<ñڵ+Ҿ}?p?^4&r~ZTT=ztʔ)x!jc89ćkl ?OjIjjjΝ;r䈦իWL&Rݵ焭u嬬w),hf:}4?~ C!p>s`lda5&]YY͛76o蘝MTw9a+1Q&رc\ߟVK.5˗l6[4j055ٳn崴4FpY\]]cccl(YLPP|&/ :N,I'Mt̙B X,,RݵD6ҥKSkH"&&&&&&RWk9&}ٺu5kE,,,<==V^v+Zh~/_˦JLL|eTTr̙3+**._,YYYy1 !Z :N,}0aBfff5僂V^!oQkYZZ:[[KWWZWZK45|<$p8bZXbnnn$ILJ]O׏==l4?Btt<,T*SLxxٳUufccs a7n!#BKΡ3Ƈ5)^~}KFFF9 ׯ_Ϝ9S-//FFFvM'l>|(,,\lٕ+W\pg55AO0QoFOYOOOJJW^{N9~]5kikkm~q[[[j|D*%i4څ d2###ɓ'׺^gx.(L.]ҙ3glmmCk~m֚n_ⱲEjjZIMMgj!$ɕt$|N_[|Xky`$i(Mx>z۷o7mMCرcӦM'N3gNoܸaaa!Z҂D*ٹPC qF&l;]B4Y̤Iϝ;ϟo#>SG{)ÇqO[ܛ|EΎ?/_8-LJLמw^.]8$ICiJۻw},--֯_+ &RUUUoϟCTjٰakIIpP[*5zS={fhhxN> IDATϟ7=sL['M'B#ć 0}K 4mqoJJ+/jhjjH$a-+''4%⥤5Jx󠗗pڵk~zAAO?ToZqf-HR@4 wQCX2x$FCd1ͻ~z~~3gMkZ#J:|En~q֣EWR? 9tXmUU B;a3=!`Ǯ=xQHjpsGѺu97HL1ccc PXXnݺ#G߻wns99Z)ZHYRpk|}}œd1ڿ%j=a>Ĥ_5G],+/QE+Ç'~;t`B௿uFu_(=x0a;1\_gLoݙ>'C*׉pDRo1ϟsess#G$d%%%ooo0a󝜜D/2RzIjY"Fs8uuuժ###njcmmZWNE`Cbty6mDnjB#̇iqcG_ 11L UVVv'殷Z}}{_ #ϭq֣5FzMkMY){p)ûv҉>&C6*׉MS"iӴ-[{رȰ0P`` AV*..NeTgiiY7qF-QQQ;wtqqy?(:W,ѱxƌRRRx!J:HcDG$I?ǍEɢ]_yF{ CL4mxko צL\h|&> ^cW9ׯ_ٻlYWEӠX۷o߾Xj޼y% ͚5WX׻;&W^M"ftegg(wu}\·Po<{kKJ YYJo= j))oobމ' ɡs0:!C0/^V޿ٳg7Z\:|F7vOQRR} #--eb=A6`3;'N̽=o¨wOu5UmM`0:]n5aJ@ snt=:k.*X4j߾}6l<'q֩i.JRn񖓓6q@e`ӜYwMrhF-'˟MDØ#<6jD֍i zŎFWC#IʼnTecc3`<Iv{>`h9(** N_7qߝj+| ԷqCN1u|XFƨꚸzkt=:&33N?Bt++N97sF\>*!駟(-^~P0]e$]vu]JJĉx!P5 3dee&w9DØ0`BEGI*w($lnndIO<166.++!ʞݻk׮P33gϞս!!Dw>J|/^k-3W; U|Et^ jnVXmӳgZniicZe\]]w ;w.3F!I|c5qPy?vF h4h j%SJd޽RCURSSyBu:_I|X^aO[[t5'RK /_ WA_O߿޼*.]j˗/lvHH$55ٳn崴4 Np[\]]ccc[ AhެhMtD[S-//_rPWWwqq)((էg^|_zFj0zS[&,[n]f v@ Xhgk׮]b=4e˗/o\LѥcbbZZǭn/^Ó'O})))ӦMѣ_zG=׮]-QF}!jˏI? Ѧà{ƭ[3//o۶mѥmddєUH\paAAСC}}}@)+++++ 61ʊ+Ο?vʕ;~ѣG'N=l4cBttpY[[>}zРAӋ/>ʕ+JhgϞ*8qBSS3++KKKKXgĈ4޽{Ԥ׵k-Zt)d2={VQQ㰶8aA!𐶆6 j i`06o޼yfaɜ9s@d<(ޥK&O,;w>Hرc>>>)))K,ٲeKSNݻwٳ'++K__ӓF1p;vjkkm~q[[[j|dll|ɕ+W8p@tLR WΟ?C;wN>&O/ɓ'3V:3f._@dd}saǭGDDQin444~())QǏ?x`ذaݺuJ ݯ\"--={@6M3gάYm͚5yyy&&&@mǁ3DNH$>YֺKu=>~ٻt5DImM6ED(FQ)R(ݕJV7V*!k}vbZեtCQiYg6fyf93Ϝs/,..%Jzxxܺu޽{/vuu\+>>رc'O3f̝;w<<<ڰ:::QQQ˗/~v.Y\b]]]ϟ?rGlA͜93,,%[l\n"-ȈdSy֭[ǎ[n]o6{1ٳg/\}?~-vAƍ&M077z*6333޽o߾R{S!;k,aw<|X9""_YXX,ZNP(t:=<<\UUܼ}Z566ppp7[mIITYYYGG/cKbcc)S9r$33="(**z +ѩ㹒ltVXXaÆb=~A / ;;4F5kV9?apn]`AMMMnn՝;w&Ms߽{wڵ#,--^oB_|r\\ޔ)SˆWHV\ֶj}:{l@ׇI V{ Ї؟|ltttmm-ͮ /@ N&&&ӧOVYYܹswUSStڵ7n444܌]&}ƆG=!wsGxɌ3RSSKKKn``] 4SVV~W/_<==`W{qf_~B"&Om۶ׯ_z5<<_366p8w޽y&6t_UUU-GbUtuu_xq) 쎀@͇C\&a}X;b@L˗k׮MNN驩BRRR|PSSSTTjlltvv133KJJ.//?=z=5=y {;  Fhhhrr2J511z̙׮][xq/ZoeX΅x bqlddtСYfasWƍ TUUFؠɓ'Xr|+ 쎀̇ B?LuH^z؈]jii6gnnnmm+WO~ biiDR1ƍb[܊t 6qB3j * &ann>o<└.W?v mڴiā#x nVIIi˗/?w\IIIvv6J;w:w/^433J,--/^M|bY7n|N߹s'ϕy8Ab|YQF،?^[[Դx([tƍBCCO:"iooߺuk&&&ĨW!GGGsssccc---b^CӍgtAѢ]\\*++x>+V(}to6bkk_/YDIIٳ<[]a!bĊaÆϝ;7$$///{paq}&U y&B,׍%K8 A}T<D@Q>Wsss!1'0o_XXW_}kdX ήnذap24`>L, p~I~w`0*yyy'ND=IǝSOEEŋ'NPWWZ[[oݺfb.^9#H<A<|L&'$$% WUUYYY WpLѮofo~0z U\p'eddd=%.//f0X&*&L ۾}6^n;vS}||lrʼkG;KԉE0zXBfMMM===555mѣGvI 0B \~}VVVRR҃ >y$??̙3c!`]]Ç_~( OeeeOWMUva>L߯7__7o466nܸ1++L&S(ˆ ɓ'+VS3HJF---=~CadJJ}8gO%Ŵ4 !C566 CuItҥYfIII3&##+|eϳX-߶m_c#S̯z t՞0-0 )|%;vɓtNTTT@@ VZų͛7eBB•+W~jWW^0222..˗/vqq gΜynSP䈈]]ݨyhͅ?~WĂƘ1_ΘӧM{[!XI!:tPllo||H QYYܹs(wڅQ]v-11ƍ AAA<777B K쁾>ƆG=!w 88LdƌÇ700HNNfWH${{ӧOK Xhjnnhllhloh,Ql\? OϦprޠY\b'K9t7v&%4/.ۿ]83uu/ yӒ~{Zdmya+%k?\x7/? |"%%\<]MMMQQB,)))"""''|=z=V}5=ySd[[v/'2d*jbb".Mh46maa +biyvԂW,_tt.m'}3jB֭MgzJJ#6wdiiz ![v}^nW#LMfٜ?#.ӮΚ9C]MU&0А㏿_>R^^N|3HXNNN:::wqqR!KKK'''*ZPP0tPbqUWWO2/qss;|pGGM|qB ތd^t)..ݽ8vjjjzxxY p녳c|t=pvK~AT8x7g!$H.1MͯBZZS-M͆|kn2x7HDu0u )dCCCI$ҥK뵵vuԩ?SVV,&&fĉ[noĄN/Y/qtt477oiiJLL$n̯|^:nllWF޴itv pi244 +~W D:~YzEDaB쏑|={**[gGk#j=SR'8袅 <-]]|CJ\Kr<|'dddW[[YQQg)))GGiӦ >ٳg#{{,b_|֖1rH؄;/իW bmmZJ DL:K +q$-%XGUsW:aP(&Cã2J<9344P640$b5o4PäEng|o̙%%%/~ݻGvDK0ޞGτ0biVWj*+/YD,]FZZzw7`$Bk#˖~7b>D"1 Pfwtt`x#BDDڿdd̙{!C>''Ȉx$`0).KPZZzƭxĈcxڸðLp}أG}X011p8w鋷4iR_SSz%%b "3_m=ɓtcH$ȑ#a]SΠ ii)S%Po!,B&}X/(+9 IDATDWFS~)>>~$ WUUYYY Wp~}X__驡!))G '//wݿ_.6_!N֯_u!CL6p׮]K< IQQ_!w.<xb/^*//f0 L0!,,lVVVl6{ݺuFFF^^^رcn3#rʼOu3c]]̙3>SYY5}w*++Ottt8N]]]JJInn7|#' +.. 1I&ݻwK<kGSSSOOOMM sMIIIII m'oogee%%%=x𠨨'OϜ91=62ï_w}}sNmm7n` ,X`aa{Outt}off&))k.le'3}?l`ևu QRR200000iժU,߾}Ez Y |N:RVV6bww`aNϞ=3fDLII100 JJJ9vikkkl|%~8{-[C@~=$ HyyyZZZ˖-Cؤv;{AEEb&yYFL$--`kkWVV][eF##644eeeʮ\2&&L&X={ϯ^211?~|]XlllDDDssG}oߺ>Lv󁘈)''gС aCPtzxxB۷N!TRR"%%UVVcKbcc)S9r$33=EGGЪlVXXaÆb!w 6)|3_|r\\ޔ)S°˻?޽{ƌsA*s׮]X`g???UUU, >As0d  *((pvv/% ʵkoܸAR¸777c p[ڡC<ø((( \Daʌ3f̘QWWc``?;;;kii盙˓z g 6x!TSS7w#]Ff!ޗX܋9g_'ȅxڵktzjjSilltvv133KJJ.//%GX4QF<궶6xJ0];T*Ą+L&^d2W^/A>>Ç-,,dee31B\EE!RQQ644xzzb!fy,mw#W^566bⶴt{I [[[{ʕӧ8qḻ+**#,--T*"#fܸq77":bcccL=!B ތdfddϛ7OEE8%%˕SPDDDUUܹs333~o8])o9;;/{E)((X[[oܸѣGt:}Νؽk֬ٱcG^^^UU֭[sssdaBo޼;ыn[] S0uͨQmll---MMMyS9uTFFƟ)++m3qĭ[9:dܼ*111 ytqh4ZttM숷Cvr@77Z55%K?<Q.GL&gggÒ7l`hh(## noo_`Akkqzz:DRWW ޼ywܹtRϖևnR'h"B {f\Ѹ|Z%ݝ͌T<D@Q>Wssst:o0Oa޼ye^<1L/!;&,.߱n|ԷbA{{;ŋZ@̜9SRR/~ݻDpA.`}Xonٲ˻"81qI @"ߏ3gN_Kllݻ ?>~]&`3Y+aÆg~K.=1qI`bb"//pܹoaee5iҤ~D}A@,s0糳N:s挺g444zNIe2P%I$GgZ7sСϟO2eͫWp8Rl_;9bRSSjjj[NFG|m@LOO/++SSS۳gO8')v`). ,GM;ۡC᪪@??޵/ipǎ;wȑ#[XX(:1tަ&777e /I"Y":)5JӺ,\P]]244w hGp2 jjjrssܹ3i$<Ԑ02NEP _$tLqu8q"1w/i0_p႓ɓ'Om۶7n̟?{ԨQV@ϫrsر۶mstt`` T~ɏ$8wL55ON-ǯ}H3ϐrvv&^Ė|X,a mmmuVSSS``5kǀ0)̖&(MKƌںk} =NBט pxbE.ĕ+Ԁ"u֬/^\~KZgABSRRZ|ϝ;WRRMRΝ.:q ˹s…Νklllooy~[QQ ! ?ؼ>}#G?lm}!=?|N%)SGbj/A_w!*>>߮]8ڵkf͚JRBRk_;H4s)))ϟ?1bTooodz(3~*((m۶ӧGNMM+ȏ?޵KJZ`Llv&il| ͥ]C߼Y|{cO-]`X8^ rs}Xgxq#/_.^8f??pWK###o߾} ,rrrQQQQQQ/NP cs~==|mmB${￿XXo}}&MR3fKX>mzCS_[ɰlsahևs|*ZRRb W^=gK TƍS:{۷_ 2*;sۦYOlھ}gc#qQSiiIa:AD\&Xm,r;os"#??6ss/_jhh899s]Ҏ|^a\z\ZZיm'bc*HvttrWWU`jk[ӏ̘9ɓMii%y/k&?~rq-9w{nm=.7xa~e555RRR؎|^p8gϖ,_>ARRbSR NwÆ)#G`6^r5k.~ِV}V_}}R%˗O H˖M8w!AQ? $ٳ%99kIHn( 䒓ۗsNh\ySӥ.ϼIS:q?Hj /b@4 >nH,(}M\ujj!ĞD"[75d#^-;~'&UZZf4=*˷#`&?>KaF= l9{r-72~`nVR3W~[[Y=wdvݧHK+ٴi`f~eE|*`zn̙ѩ>}ݻwz葾~X~`PήVVjll'xύܹS[[ƍ! XXX޽;)) !B*~Dfjd={Fa0t@@m\\\YYq{:ydBimm Ϟ=e˖&kkD%%%|cu 90 jocvE$D"& &!!g|͔)S9hKr8R }X7F%''ߥ+++))EEEE=<Kf̘ZZZ:|p~F޽{XaÆ?/;;6[l)((زe  jz4ea` /5Af-,,Fggg33 #44499JC7ۙ3g7ݴiUaևEyyy)Vhhhfl=qwwWTTGYZZ:99QTLfFFyTTTSRRƎ hllD)++z{{1={,^6.--dݻNḊa}=bmmOb={:uTFFFrr,VsMFEGGTVV ڧ ڹs'QԩSC 1cԩS544~.$$$0pǏGFFr ? a@4 02uԉ'bO >\@y|tO2 H74N|y%qwwwww`7oḊX@X,Vkkkbb"qi|ɸAȯ#>ķ2ύM} .}:t(Bt `>L<ևIÐz%`LFt)TTT+255WRRQt z:CA&vԏxFץpԨQ"Ţ[$iȑ AXa%?sѣGKKK?СC;t)===)))ee={^ti֬YRRRcƌ@uvvihhHKKO2;Zl+-p8FFFgΜևZ#a/_e||cNJJ݂ÇG}D(>$ xIEEB9x(wd ϗaA,և 377ʕ+ӧO?qDZp8^jllܵkBEJoݺ5##XqssۺukVV֋/_ba„ aaa۷oFuyyyf7X,g1l62 CC}F?44D"-]^[[ͭGcQFHKK[ZZ677zIݻzux׮]gڵ f RpZ oogee%%%=x𠨨pQ=<{l'''8=M0&?~ e555\DOOO<}41koܸijxɌ3RSSKKKn``ǏTWW寭%mٲ`˖-ab?LX$]hl6+llltvv133KJJᮋR!2d*jbb֓'O޼y3m4555SSSl >88vӦM¬  aRև!HAp\yrS,Ǽǚ5k9KfaiiDR ʯq&yҥRwwb~ѼDJJJ`[Ώ?ŷp8...vvvQQQ3fػwo@@ _RIϞ=WD:u*###99YVV+iooߺui4ZttKee} ;wvQ &!!`?~<222??D C?$χ1UQQ:u*{ѱzÇ?{Aŋ(-ޫfcwwwwww챁10@&6`jmmMLL$.iiiQ`ЃAXa= ?vbZ&=w6p$2c999CP(;n/)&>L?֭KϾz>sfXa>>7+1ejjZ__4aDaAL&Y0¾srwT۸i E=D9r䀏~DabA, 9&--lل?ˍ32&%2lȑrέxvWSO\5~ 27w_Qy2}G,uAAfد-[*+LG6mp-//k|Pk.iUB˗O(-dkjN`>L, aZZÆ *,#vtt6B%'ێA2%"uΜ/jclڨQ/=j:ypR}iiIرӧk;Vrwv$GG 2wǎYX#;wuɓB^\*CNZ֏[^KHX8WB0 ð1&x7@^pǕ:ݷW 5,,ȑÇB4c ҼycBׯ?zڴiWW?{ԩݧafKqu.o-LiiIIIDkkǹs 7o @H0&:~Y; Fݽo,%?XcǍ'O'O(f q߳JVxGG;n`cǎOcʣG|H&𒊊 rAQ$___8%S0 <~Ν"#c7G,y4ÇƏW2E=<|E[ͭinnKL\RdvbǏOVfiRR/˫&() !:::߽ʢe„ aaa۷oFuyyyf7X,) ѣG6opS>L< aͳg۷oŋ+e**s^uvLL\XPyT n>7kvQPJJAJJ`۶m!c``qF777IIɔ$MMMM=x𠢢FJJaeeUYYYZZg ɓ'2dSDDDDLW^upp(**RWWϟ?~^^޸q$@0%螽=FrZ>~{IGG'*** `VG4P੺c%%%gΜIKK U\\\޽{GR80D / Ǜ6m FC{l'''8=M>LΝ;bGrիWǍ÷IHH`0222Ǐχs@Oqe$EHEEeԩ'NĞ::::::7>|gϺ-^xץqS33<qwwwww`7oḊB0X?WXDk`>L,ׇ a$^B}^'p8vvv2221lv{; 999CP(;ṅ0th4.>>>=}ߊ=p} SSz%% "/0F3QFEDD}GsC"F s}$8p`Ǐ?tPɓ'#@ vvv򊊊5D H$O?)//,''GԩSzzzRRR{v6ZZZG abaC]|ߖǎ;ydeee@@dd$q#Z[[t:ƍ>~Bݻw۷o߻wرcAAA/^,**8Sl<8~*+++ sB<X `~~i̘1]U ĂX#NNNW\>}'m`mmqG;wzzq׮][ٹps566;&L}j^n4`<|vvvwWرc'۹2 ABzK}}}7oiø8(^z)NinnΆ `>L,e>J".]Z__憍INNްaCHHHwԨQ666͚zzzjjj߿WPP۶mӧOG\~}VVVRR҃xΆ?~\]]~^ɓ'5OIIIII >GTWWwׯ_>U/͛7/==}ԩثiVV8Qa}ćad$5H.Lr8{6222쬨سgZ!eeϿ{իW&MO=}Mccƍd2Ba0߿Ƕ﫪:;;ML}ڵ7n444k`aC 1 <Yo׮]555+V]ֆu5.ìd*jbb O3gvttdgg_v @|xatQ^^^JjjjzxxYḻ+**#,--TjKKKߚ_Yf1bÆ =l\Z-:~#[:o…;n8,TͭN9 ޥ ۰L&3##|޼y***)))]~$Ҥ۴iPX0&`}]Y[[wkA.M:99aN?eee'nݺ׉Optt uqq֜9sH$%bȑ_:w &&&t:}ɒ%xyKKUbb/ Ys<,xtccn$hM6qY?+V:tg8Ḋ0OכTH_ AݛK8pF\_q GPGO?tosss{KKKEa޼y΂7c2}7@3+C?a@ֻ_%WQ!6%g,=11mP~3gJJJtY.:^~}ݣGv% yq+C/)CR>133322")9HGFF?~\NNnΜ9ݻw2FzD@ SSz%%OZ[s8mm;wZ&M"`tD"9rɓ'C_0~+C#?a 80 jocvjF`=A5AH$<]`>$ xIEEB9x w8s{ K8;߇#vw3n8))C.X޽{p?C1/ @L0!,,lXfF6n:###nh4x۷>2`… gΜY̙3>>>YYYZZZ&&&pR?C1 : $흙~ob?gjJiS )E$%D\"[B!ܯk$.Kv7ʒBW*eia40s>ϙs^sιЇ>yD---744|Q'(ŗPӦMݻA߿/zvx=***֬Ysq|QA> ϟ?rHP(l׮s9RNNn߾}7o\f… ?[r"bXǏ777g:UB_~i޼ŶmۄBçLSGurJ+}޽իH hkkӇxԨQ'O2{>?/;_("={v۶mNZ鴟P(ܽ{w@@ذaMF0􌌌,**"Ǐ|ӓ|ӦM+W0`1c!333=====ٳgӧOoժ ׭[?Qpp޽{<+W._|ƍƍ?.NBBݻw'M$^ı|%"ziyy[JJJ_5d) r[hiӦl)CJY(6믿^r⣤[TMFG,H֥K==QFp®].]vZ5ʼnTXXX^'$$+""68jԨpWW׃nܸR j۶իW\ѧOnPΐ'dgggggyٳgĉ_3?>eʔ͛73%FFFݺubII2iߐ{B]#c%+cR"*ίB‚Bph V6v諸3xQB|{mK6ݕ|wKB3x7dϗ G~ CȇȆx>ambC> - IDAT;B> @& d0@> @& à(ܧ1wjirBp¥QWoܿN +*(`ECu=e[Ч;a;6}it9grIn%40#݋ޤw1\OO_oZ|Vy9 P~v7χ+O<Zm/]6ڽw߬nѲG~C΀>?/YPH_];qКUwwDt(歔:'I.]ݾW- ݛ44f`CH PCb0|8\ 4\)goE)^~sEffm,̚~E`S'hkiׇMBD%R+NѤ3 ee#fhkkQI)u55I^XPҿzaШijhhkiIԄyKD͚}736 LDlk)tu&l6ysSS]? @6ND))͛QJjW)t9WDoB H?QͿz aբ!`gq[-uNPXPPe[0 B棼|En^+Ղ|@5]I&G4ŷkN3՝:555fY6d^n&M++/533u +.uaf*deLDq |>_4 wە.nˣ'9o~|I%1rm<E`ux$4fص`!? @6d0@> @6à1 C#@$9-"|+FF}°E6 03顾Cy)736vl)h+P6ilua2|la<4X 3."*ILLTQQٺu+b(00%ə3g*(^a77L,M6k׮]parr2 ɓ'Ϛ5 )S"##(#'''f7o|ɓ'l6-譥eѹsgӧϝ;|g̟??999""BagΜ9}t99}o~͚56m 566FsISȑ#׬Y\$Ǐ{xxss0􌌌,**"Ǐ|ӓ|ӦM+W0`1cVP|xʪ#ۗ3&\2tPכC@> @.]1!:TCCCill,IHH(++C[A|^ibbDٽ{wqsb0(E7 #QQQqQх vuҥ,Ե}utttTܑ#GFDDB$V ͡6pD06y%|˒bKŅ)|ĉ/^x-2ѭ[ׯ_pkP<_zJ-+0[[[cccs8" 3f\|9N0+&&FUU@/MN>K.<_@[F̥ɀ &0:~;w͛7mv޼ywF30Fm۶'qsh\|I:wܶm[qƍ'>zjj*aiiY?5@%~0$vO|=? 3nݺ~|c}rttbn   F;@7s4@|IzOC9}4vOc>F;@}c|4f;q/l|4f8 Cȇa2|l  ȇa SPH:vُ@W ђ}_hB!@ 60""n+|gȇa!ca\.aX_T^U}\"|>eINy3uwti߱{awPXZV&s|||U|:¾~W}|9DԻw;v|ߪ@&ċ񈏎4icr쭛77i¸}mg#urX_ŋJJɸjjj.^EE[ǎhR &p~=|c>K\b஝;m\K玖-zHJ7Jb|8\.z_5aK'.}{~7CD9s,leͺKֶQWo0Ŧc]EDsrzQ=cw&"Px~m:9 yp8sk[K {cu֛:Qbb}uT(/͛7ضm=ϟ?rHѐڵ 9۷o޽{/_R:~y.se*<tR===EEž}xhҤ蒥xmIeee"z9cǎr)kKx]SU;wȇAQZZjaRP^^TAA/8?l  wo˗.u޹wh+QL%9͓φ&c8y&ps'gL޾s}Jv7k=@Dbʫ3 ihΒݻ_^r7n(322?~KOOOWW1cx{{{yy/Z^׭[?|:!!!gϞyfrr)S藮[o߿=zԩS!B0'Oٳ_~yM;6ׯ߱c֭[+V^D!?~ԩx]]ѣG:'NyK]bŊOlK3O>Dm۶ RfͪHiz 0hԄ%~ZXXxK3ksEN2ѲZSC ȱ@ ;<߽><; $cǙJO8@_Ҥ9$,m۶oޣG##cOuEOO/22<8tP "ڸqWڷo?a„VlٲѣG|:۷oԩݻO:UPPPDķDvZkkk55 &I\K3g-[tSjUN:44t&&&Cъo gϞuۛmݺ˫ҍdΜ9dii٩Sk9rӒؼy3mٲԩS˥T/Dz;oȇAcExayy1D%f͌fYY ly گυ BsÇ2))}m[gc>2558c5E޽{>ZtiJJSQQQq)WVV;wnLLܹsEU)UYXXT5[f^XYY &*#oy]դk|⯥2oڊl߾[CbEGGϯ!Aff&hтyۢEONKr8˗/g̘1gRf J@|4f N{~M\%5E:--۷o ?JIIy̵H@"^zСg.//lUR7L>tuuH[MIx~<66Vb !|}}KJ!:::D2o_z'~-2l0浜Wjjr)kfU}e%^C> ;3?o;_L8::***=oJJJ~ekʒֶZSUk݇1I":mc=zۣNY(yyL`&L{gv;>>>Ǐg\(z{{{xx[U1<>cOے>,..f^zwRʥ&U}i%ozϗݛ=waI pℱ'g>]z5Gw4鵱YAnv:EI"=svb͙8''@_oaS4S_nTs"ݲ-:5|LӧW=0׶D9#G(((߿[nҥgb,Y]KKy;nܸ>} 8p׮]UM[PcKKKZ,^l֬Y޽СCU?Ml3l0`@aaa="""X,V_Mfkk0v5kH_zKoذaĉD4gΜ}I)TUJX>W 1׸ΠJS(]/* E45 wر{}9jNji5b_dUXe&U}KJx'iiqȇ41>p׮]# iX}P t-UUUؑ+++;OON27@=|@UӘ; lI333j&&&;6*hIzL,x0"<!bDnp\s0(F*F@ckaqģ0y%|.a Ә;a h0 gd0@> @F d0)($ P;w7ȇ+xvȇ4`xVt2"a2|l  #ȇaYZXgBayyBͦ% -\uF̤O8fff8!@;6UgȤɃyGΩo/]x0"262>'Ddhh6ɇ?øeyC~YD46[O^Dԥ[ofk[K {Μ0ӦcN;B?"G vqug]]BMLLx9%&øAc2x?"`?е <oɲU4"wh{͚6Nne^:Ґн&DTՈ?px҅ϟ>e]Q44f`w\.0h 15mi'0uVC8){"Ҳ#L5r 􈨤W+++KБE rt "3-ZE]M{V@}|ijhhkiI:Lz:`Ê[b$kjj¼PTPrي6ռͪ155e sۖ-ͱ? *99!8;9۰P0ly|e@-s9FUbV-IX# ÐFMjjbb?" +sqϦ|>?4lh|‚ܼ-ۂٖ8rߙYo],25hJ%OcGx5V0۱Ys33Snݨ4l9 8&Lvx( `~ﴥQrsl BD C> n9jkV-߹ʼ>}XUzOxz|Z(GzSS'1ofdh(p0:A}d¿***⟿ؾ3m`4 @"v0<_6eRii䩾9:CB$@KHE ^0o6@C|d`@dCaȇ4(Oc>F;Yȇ4L;w8&  d0@> @F d0@> @Fm)h  0hlːd0@> @6d0@> @6àKNyu[w G =ɋfy 5§1w|scff߹etaИguUUGn\XX4oɢRlldTPMo4lȇAm{pΝ6_bȲUӧNRVg獍>=礩1wF2ux>1#>M Ͽx9j1LWҷGp8D;wN]֬XZV cmku Sl:v?pإQD4gO+W3{gn" 7ݦې BK {cu֛:Ts>dYUo3g/ rؽ뎠Pfۃt{ڬdѸzxzt~j@#7/==¢x<-[_qdخ?u8hߖ/]x=s^+`7W|>%y0Dt,'twڻ SfpQLyuFtq󴶵vVU .LNne^:ҐнDQ;l:s򘦦ƂD ]ydx&D4g|:uDD1bocO@wD@_lq6D4h`cǙ){"$IWgObjLVUUfR?Cz(++gҬhGD%%<"ğ nޚ,wyPT2{֌-͉h萁{٨jݱkfào<2 ۵}T^^>{,CC}"jC򽙱qVfh0#C \pGwӑbSS&zO]CSS\QHSCC[K:m"~l6y&3>P?v>L̜1*à FAAqϯmzѹk7⟿la\IKD))T--MѸ,ph>T\\ԫS}F혷 >픈(_DJi+"lm!Ξ &-s+'77(8lYU5٨N:0hfϸKD2!=Nj{|wK/ la2|l  ȇa2|l  ȇa2|l  ȇ|'A!ah:hgG24a5^Ocrȇ|OBPwLȇa|4j j0 aO3R$[ZXgbbaG?}☙WuX>-ʇqhhDU2VͧOo־a~3|Z'&&ՠ/K\f'l0Ok[{m҅ף;.]ݾW- ݛ!鳡[~5&t,'twڻ=G1}]{..^bt%__g$vo޺Ы_ff=%)9Eww ;gdO'Nv6պ/S/\642ڥc之}tra.&!Rg/f>=?"R]$6lphƆy 8AD.]abpx9&_~}B###CCM6~ΝD ֽ{l,@,K(:aʰoi3M2ѲyۡD~dIf\ [0'"KF_PP"w`CDOKK?~\ .Z07gqmX݉Z|tG鳸~<`?е ~ɲU4) Ⱦ.XCw>Xdńct՗{:`,kˬ9 ߿=062{y<މ1]1?!{Ws[SeE?_Qzcwq˄}/Yz]rJ"jҤIll,DI2]]]PO? 0@W0"YCf^(*(?5q=pRUf?d͚Qn^))}DgݶnNx.1,,Zb5$lW[6D2z>Zy;n֭Z 8~9t1svr?WzcZҼ~<ش*J:_묊J"262z>;/?S]M{W׾P(7ogݻgee|r"bٟ>9NgsTfvvG[g?^JJnanFDl.m߲Ѧ};mFƻ¢3>ULaB+K7g+Q\$ӭ_"f5onZT׸ѫ6E++)s]O킄5D4ǩ.32559hҼ!G?y(+KG}z#Cb{#^_D헍:v&f~a+1'Ż5??^GG~g77hiiQVV>eff2@wŪ {ZԟL ‚ܼ$bѴmZx~9|u~()O@s^ccø+V2xH ?oQTTnEX Mܺ}gEnC9N &- VjoM#>G;gIUBCJ5+)qʪy#NOOW⡋t2n”ko ]DI'tϿ~lEvv]txR"RV6'1+0Q]]Ν;DݱcGl)/ 3|U*rUMM >sp8_=M4̧CM2s-4Ӷkμ99zF#*/ Ovve9f,Zk!aX\۶Ԩf~~.3nrh>_4Q*۱ HNN\ß=z45ۀ~{jg]9|[4lmerTEI6V_:KR]$6&ŲlJ_Owͺ #"gkWv`SVZ&//U$tee%-gs~?~Ɨ& NXXXpQF1M<߿C۶m –ReKcIrdff*z=KwyG>F7s_LAп_߃ǎUnɓg^z)p?vDYS^0wV=6[k;e9`OGiodd(~F__3gϟ<~D(._,iKK9Ts8Yqϳ*}KVw6t r]׈g[HqiYqȇAcgۃvm\ڬ˄ uؿ۴f}% e5r! ?}zR\ ;4IM2tT]]ݾZ8}׭@Ø?Na}gr:1{"V.a_~@@MuS:#]hدa~fթfjC7WWST{tXYdXudf!d0iBDNvF#8 ʐ d0@> @F d0@> @Fm)h  0hːd0@> @6daOcRJ> 7ZɇL! Laa|L  ȇa|L  ȇa|L<Ʈ zsYi{,r#K|U>,Qtl0F"7a|Laa|L  #VrrrFFN***_TP(rrrXmP|>?_(q&p/_{JT\f=fz_7[}@İ!ޓl6Yڟ>q̴nGK>glmm"0??.eկ$7/gL u͂ѣ01iԉ<ȵ`<]zJiڦ ]iiI]^ش^v]nޠӭ; ͬ7+L,þNiI^AL̡Wՠ6/ TǫGj[^PVҷׯ4򖔔9ғfЯ mܵsWwѲ˖,~򴨨XUUuѿ&F߻DYsm,#~?IDs|''"w99V-3,B\wt6;TU?4x Ocɱ2"b͞c`h\Zu҉_*:Ɍ~ğ͌vX_v%/^5mΦcߍ>$7'+'78ߺ}+mnj˱XU7nׇy{4x;6mXՑ/G{'meٚ:`Í+(puYOQA.\}ghJri=%"Pۡxild?)>o;?G$,.)ʒ46..#[zx!EEFD ԥ[Jr=;u~l!+:b?G_clY1u>ٻMǮ$(u[[@x֝[7475Ҍ}ucǎt]Zoaz&o߽2]ʥz+y2Ɩ/3knr%9^'驡~,C=*]hzo޿pIqA- ? -["/,?A|/Yz]1%706޳}Gx7/==~ͭMꪊvcb5uBNA&Jrgc=WVV:)sX}}r^]NO<3fpөO90/u 31i6uܹ ubhO'YTIDM5LM **߱X/LML dg֋]Inn޻wwxZKSÑ3=_ٳX-#D:)͖{"E s5 f]g ]|"336VsfM?{"s:M TTT(++|**M?FWWg'y ?^rT[r> B?9ØDoh`l@׻'&jT֦\  SR#f-^xZZZ*ihe%^VFj~^NUkjf{P XYY٫ז-275nk;ɹ0?ݻkjl\yŋ JŮ"ڱc޽qcffeOKy%JBPHl6[NrXe eB°# r**OtuHF\^^>{,{LIvN.5k8+34CG׮dҬُ^? rs%䔉>b~}YKa͌toݼnl2c.3sy99%l:w nZ(jSRQf滲24QV,vi)J_^A6@Wu8TRRTRR$(/%"uMuuIm eaK˻ux[_v%/^$8;;9y,[+ve<"%"UUU&Diy^X?ĩ36 ԩS״Iugy䝝ۖv#EijQJJj&DID%JJ=;|g-뢣}F>ۻ¢[ Y=_R( JDdٺձc{tWdfeE]ʲ]s%6--]NN"'=B&ǎf׹N6mTŦ逿P زe?j 31h2޽344\Ӷkμ99zFc-.wxto=}w%%l/M;+~|yYiNvfֻZv릫g,PVV/a(s g*q}z祢& rޥtrUՏ?O ñigץBE ?MRXu駣g( ߥQmDE5@еKAT_v%=  YaQ1h޼\A~nW0JJJLL?tM?zsyusqsVP^^~v'}]/ Œd&b/.7;37;SD H,^I\U@'2&g zVԗ{1Kף]Iڛן}˼y.OX(Z VvZR\T+雓U> yȨ"i's풛J|{c@mjx{ ;b{Qa~r"3gX+)7Vv>gw[;)|zw@ lم}oܧeEϟӀ.sK<7·2Ѩv@*^!D<8D.q,8%.q9ajKG!>x_p |2XF]|T #~ C|*z>^:a3gLqxD<">a|sp/Enl0""<q-oa %eW'x<@-vxWk#>:b 9c y<>G|p9pp0t>8\qsIDATN#yCyȇn'ɇG|@v>xD|~ .Lf'(x|"" .MD\gj3ݛ-5_LerNX[^nV"0Dy* image/svg+xml elyxer-1.2.5/forks/pages-elyxer/parse tree.png0000644000175000017500000002715512117067671020650 0ustar chennochennoPNG  IHDR|bKGD1 pHYsdd vpAgH-HIDATxytT>gXBdYBdY"b~Q[l%AAYde)* 7ܭV~T Uhay<;mrCf3's޹Nfy]=vDDD$(<# """ƒ8 """(<# """ƒ8 """(<# """ƒ8 """Tr"ΝΜq.ƒ؂@Ӧn$nۥQxڴq$/;<# """ƒ8 """(<# """ƒ8y$f֮q$Ĺs]  E p119@R%'ƌq"l!"""(<# """ƒb|./\_r""RuWt{?/Ӂ-c~""IA\ \M]*) 5[H8fM`=~ ԭ H<o۬p"'#HI㱯gd V>2 u L6oON45v,sCɓOK6liS`l^z0k,à ej|9~=PWb {ogxK,ee,`0YY@n1 .а!֬a?ΙMss  7+V|ݻ:zzzn//YL P׬]"!ψ؂dfNc {'V۽/*3goOO>q殻Q/:eKяSk~=>lLlc~0m[{Ɯ9co=k̢E%{ܒ$Mc5&7ט'4ȑ=T 1e'}VGԦWo`jMKRz WEU8}pм9aCv*hEYy e?ρ@>E=_ߞ6[KZ5Ο=_t4p-IJr~Yŋ..Θ1ԩ-DJ-f{\ .{ta)S&M_?^="-1'RJ^=`?OC,]V?#ɓ)/^w7w(D™:LJJK.]b-B9.erժe Y;Q@)6F ǁm}IIuvL o9s8ud,w䧟_m0)k޼۸8`ժ[б#k,;w8ebu4h^s|`@`JnϚ `t 'AZ恼<[|˰t)f5G۝??y'p%;N 7b{|P>kת٢,,\בABSYG{8Tσ 5[# """ƒ8 """(<#)w9-/JAQDĢ ׮|x;)ϟ'EˋHQ$nɞ,'XKr9!\>(\ylNOU]2ȡ Y`ξ)G.HQxvk\YA.z {7Ű,Pp \.%+Y32W@wڵ } };WUpW=ѥ lI6ud""*e iE/>n풉H Hxt9`>Q#JKS{(?~ o4i^ <0ED$Ty1BaVoivi1.Zp!p{ԅVDDGE9s4Ǟ1X!%qd"".ʉ<`6dgO?%krd""na2Zj  t !DD4"7tl~˖qHi))8HPC8~',‹s>}(K&""Kegsӧ.paf,""K%.K&֡`8t)""O}Dvr2p]\"{  A7ݺM},_4lvDDDJN!ܙ4T'u׹]2!a?7xࡇ[o10Ź]qF NP&"C= L2P6x1?o1"IJr$Ę1n@DBߏÇ.fZ`@^^ٞvx1J`>+ cH7<̙\qEdV9Ѳ=@L m[ɓ }iil|~C| g:C77\;eYS# DD yE ;ذY曁9bw)[:ZVZD(-ΟEo-::4á/PxS9G| g+Q6?,yR*\GěUQpվj٬O9z.G|^R229%u=#풉?C@b"o_ YUVH)ޡC~/gަOG1={reXS{%K?֭>}|ϟd?},ԩVy;&L;0`H״)M]2T]ǥ,UrrZ5k6ƾ>v,~h}^ܹ@˖@۶S 'z`PoR`,>ϟ.^FG>`_c,?8rQ͛u8 in? {/л7< \ӻ70t(in.0s&@B鵖r1u1پ=kw;w+ԭkLt1o13`1ԨarߥKƤdLJt`ʕ<-1gM7S1 Iεz1^},^\T:_rlnbc23}ok7̙/ƴicu?;zϟ?wms{{zŊlZc|ۿѥ1ݺ9<`V.,UO8sAKn,[foXΞ5fѢ>)R`V5o*޽Mr ~;|%~kز  <0x)keUI/_E֮ey׮8agv!C \lΪy$=[? f9w~sSxKv6wobbs~ZpU > ^lGip ,aٽۮyصMIV-PuǡuknH#Sk/Ə}h)oJ=⡇tl?/fG4cr`zV-OKc59?>k3ݛᣴ:*➓۾UzuVZqreoK@ǎmCm0>[ޏ[cڜ8@fEN'<{qP>_#9g |t_sre>pעE8xO%=I۶1@>ڵL.bHC+ux~{h̾ޢ?̂ևо}@VR :Wݺ55dQg@Nnk׎ꈖ}wPj5eb"'4׃Oᇁ=ESlほf9q>GyX_USM5}yHytY!`mQ#4-X8s&= S}Ϟ@zĉn]%].0jotq)1^7kHpTVHI]f kxή޻w{G#k0Uޏeɿ8NU\tqϩzu6ň;4Jĉ;Qk D޷akogF[D~y0XkX7ѣ甿%…DxR.\ """""">BA"[Z\LCVËb""$uEDD"p48_@8{`9q½DD$S q#燘HKڶu$Dz:;KRxPqqv35Nfu.H?ڷs$Dr%lFƾ} ˖q#8S D|<;TQ2"DD)r&!?!bph5 K'""@ᡜQC0lx1CDj*pۥ ,IOx,pPY!b>v,[<{gF3B!BDD)<+qԜ9v.H[hT ]x,]9RVx8rޗǿ8!Cs~Vr/RR씒,\Xp5m8UP U 6kgo?K'R6z:wt˖&\v /u|7e ϳy3k2lKx{q`l^=+Tj[,Lj#h()V9cg;I8%7DUl,?5:ux{Nq3в%/^ \= gу/.d? {/лN > |3k%*T`̙@n.MHX R"V1?g`m".sU{gn5hǏ}f&>UPebPIu^Yk$Ξewxx0KLyw$~U\׀~{>%1 !ESR֫!3s'?ش E}ع o֭< VOתo{ !mGMw/k4hypX[u]{<\8\wXc-:!$(ko$M4yR[MFoĴil:!".11Pb ~Kn~MNf߇\^o҄6t8~I{-$o{MX۶a oV%&#'eEkrY!#ϦNeSnNxu={|$n p>y[ǎ|{OK.]b E`9g&lW5V<&-ͮ10N޾gU2y2QCĨQ m<|8Uv ElտX 7on?~8`ժ=+y=%cAVx{߾[ovt48X͟[nG?ao[NσālX=G~Z!B>ڒ9m9f 32GViK'""CA*1c32]1cFNi""$(4`'d;!bLK'""N(:vtƒƍ,q Ç3D}p!#)Xq3;6ڵc3X@۶:H8Rxd&bP1f S\PF"ѣ!a.ppv];5.H !iS.Q1x0Deo""Cv6¦MvXZv|W)SxЬvM\g^"IN5 x#vBÆnXDSxr\fXfM3pВlcGDp{k5Х ays`Jv8 Lʚ'`{  G>lQ2_q!CZ2"~+ays7X1q"Я0e {ԇSYBkSW`Ю\kA#eD"JDh_ѧ0y2k""._f6l`'д)B׮y @jnXDc1nB"/p`^~K`3۶W34=4'X?.wzu]w p}w?VAn,LL cԯϪtqfbNޮG@oԭvD$2W.:i6)품}N""iUMqDADDDQxG5v)lwsa٬;{Frt(")v xaPԬ͵{l̇Nn{{ycu3f^cޘm1߯1]s1W_m̚5}+'sɘcjeȑϩkWC^YY;:߭u+a$$pߤIԮm̻s1}dLz`CD$(}kdhՊnYkpRx]US'6c}욊-[kK<h ƢeK)"AADʌ>o~<{7CŖ-\w9}K@Ŋ@F M\T)?K ʕ Z}Ծ='Ab6^ne-ZV[.;." "V hߞo/*mcl-8uk.`U ?Ӧ])ƒ5o[Vk*laش X8{ԱG}nG.&$D$l4hw۷]ַla'mۀ?,`NvIDBjDDSDDxGÆ\ `@HNWbvy(.TN0t(_``z}s͝fO?uٹO"R.M :v)c\Iwo`X` `E {* }ժf1Zo;Ձ~VCADʥc/֯jvZW1JYiтkX*NH`mEl,? v5U LZo՜9 Sp'W^aH-fÆ=<Э;ǚǁeˀÇKV1_P@c?ä-*US*Tm֍g~_'#m7aCkn.k@~#?'уn].WB0v9LN侔~}`Hn4i;)_~ɜd8 " ;w͛۷ժov>q8t(<W׮dIիCȈqj~bmOw}^{'#Nk``sW""t?L`.nۥ*wgz>1o9/>X9Pk0Y,_J%0t8gtTRVǎ'%W%?Q}o䓲;qaRDʝªU ?ys5Y`8^>kbc}٧b\^?ặbW~lо+Wr`^?8ؑrP>Q'dETo'` ">Jߘ1(< """eNADDDQxGDDDqDADDD<"jO_vIĉJd yzD$bt[nB$BDDDQxGDDDqDADDDQxGDDD ""aQ 5RD\x1킊HP8 """(<# """ƒ8 """(<# """ƒ8 """(<# """ƒ8 """g_ ^ޫ%tEXtdate:create2009-08-31T01:36:31+02:00p+T%tEXtdate:modify2009-08-31T01:36:31+02:00FtEXtsvg:base-urifile:///home/chenno/projects/elyxer/docs/parse%20tree.svgM^.IENDB`elyxer-1.2.5/forks/pages-elyxer/math-iso885915.html0000644000175000017500000011764212117067647021227 0ustar chennochenno eLyxer Math Showcase (ISO-8859-15 edition)

figure elyxer.png eLyXer Math Showcase

Alex Fernández (elyxer@gmail.com)

1 Introduction

This document is intended as a showcase of the mathematical abilities of eLyXer; for more information be sure to visit the main page.

1.1 Versions

There are several versions of this page:
All of them are generated from the same .lyx source file; they should help you decide which rendering options suit you best.
Also available online is the eLyXer translation of the latest LyX’s detailed Math manual, which contains a lot more examples of LyX maths.

2 Typography

Math formulae use a lot of different symbols and fonts.

2.1 Greek Symbols

Greek symbols are very important in equations: φ, π, Ξ. eLyXer offers a complete set in both upper case: Γ…Ω and lower case: αω. Also the AMS italicized upper case: ΓΩ.

2.2 Math Symbols

eLyXer supports the whole set of math symbols in John D. Cook's list: ∃∂∇ ≥ . It can also render a few more:  ∝  × . You also get all symbols from Markus Kuhn's list: ⊙∐.

2.3 Other Symbols

There are other symbols like arrows:  ←  → , or geometrical shapes: , . eLyXer offers limited support for them. You might also want to use financial symbols in formulae: ¥€$.

2.4 Spacing

Equations look good when items are properly separated. The main separation is the Medium Mathematical Space: x = 3. Note: if you are viewing the non-Unicode version math.html of this page then you are in fact seeing midspaces, which are very similar but not exactly the same: (4)/(18) em for medium mathematical spaces versus (1)/(2) en, where 1 em = 2 en. Try out the Unicode version math-unicode.html — and viceversa. You can check out what version this page is in the page title.
The command \raisebox is useful to, surprisingly, raise a little box,
raisedoverloweredand back.
Like \mbox, it puts its content in a text box. It can also be used just for spacing:
BV.
There are other spacing commands: \hspace: a b, protected space: a b, and (at “block level”) \vspace: a b.
There should be 1 cm of vertical space above this paragraph.

2.5 Fonts

By default, letters denote variables and are taken from the \mathnormal font, which is italic, αx + αy = α(x + y), with the exception of upright capital Greek letters, G ≠ Γ.
Function names should be upright: sin(2π), log(x), tanδ.
Mathematical fonts used in equations include Roman (\mathrm), Sans Serif (\mathsf), Typewriter (\mathtt), Bold (\mathbf), SCRIPT (\mathscr), CALLIGRAPHIC (\mathcal), BLACKBOARD BOLD (\mathbb), and Fraktur (\mathfrak). For the latter, some single characters are translated to their Unicode equivalents: , 𝔽, 𝔉.
Regular text in a formula can be achieved via text font commands like \textrm: 5  to 10, via boxes like \mbox (prevents line breaks): 6  is more than 5, or the AMSmath \text macro (scales like math symbols) basesupersub. The content of an mbox is processed in LaTeX text mode. This allows text font commands, e.g. a switch to sans-serif-bold-italic, or the phonetic alphabet: sfbfit, tipa.
Units should be written upright, either with \mathrm or with macros from the units package, e.g. as simple unit, km, with magnitude, 57 km, with fractional unit, 200 kmh, or with a fraction before the units, 32 km, (7)/(16) s.

3 Numeration

Equations can be numbered, like (1↓)
(1) y = x
And also like (2↓).
(2) x = 3
Some equations can be numbered even if they don’t have a label.
(3) x = 2y
Notice that equation (2↑) comes after (1↑).

4 Simple Structures

Let’s now see a few of the simpler structures that eLyXer can output.

4.1 Fractions

A simple fraction:
(1)/(2).
Inlined: (2)/(3).
A big recursive fraction:
(1)/(1 + (1)/(1 + (1)/(1 + 2x)))
A nice fraction: 56. A non-diminishing fraction containing alignments:
(1)/(1 + (1)/(1 + x) × (1)/(1 + x)).
A similar concept is a binomial coefficient: (A + 1B). It can be prettily presented:
AB + 1.
A symbol can be stacked over another using \stackrel: xR → y. Anything can be stacked:
dx > 3limx,  headheels.

4.2 Limits

limx → ∞f(x) should appear as x → ∞ in italics, and «lim» in plain style. In display mode, a limit must appear below the main symbol:
limx → ∞f(x).
Limits are also used in sums and integrals:
i = 1x,  0f(x) dx
where the sum’s limits should appear below (i = 1) and above () the . The placement of the integral limits depends on the document class: LaTeX standard classes place them right to the . Limits are shown to the right in inline formulae: i = 1x and i = 1x.
The placing of limits can be configured with the \limits and \nolimits macros:
limx → ∞f(x),  i = 1x,  0f(x) dx

4.3 Roots

A square root: (3). A more complex root in a fraction:
(1)/(1 + (2)(1)/(1 + (2)) + ((1)/(2))).
eLyXer can also do higher-order roots: 3(x + y). A devilish case mixing everything we have seen so far:
(78((8)/(4)x) + i = 1x)/(s + 5(((78x + 45y) × (Ω))/(sin(x + 1)) + 38 km)).

5 Complex Structures

In this section we will explore arrays and related constructs.

5.1 Arrays

An inline array a b c d is always shown in the same line. In display mode, the array is shown on its own line:
12 2 3 4 × yx
Apart from that the appearance should be the same.

5.2 Brackets

Arrays are separated by variable-size brackets: a b c d a b c d a b c d a b c d ||| a b c d |||which might also differ on right and left a b c d or use the empty opening a b c d or closing: a b c d |||. There are also fixed-size big brackets, e.g. f.

5.3 Cases

Used to switch between several values.
y =  x i = 0,         x + 1  i < 3 
Cases may have more than two rows:
f(x) =  0  x < 0,         ∞  x = 0        0  x > 0 

5.4 Braces

Values can be underbraced or overbraced.
a − b = b + c + d + e.

6 Macros

Now it’s time for user-defined commands (sometimes called “macros”).
Definitions can be added as macros. Then they can be used in formulae: 1(2). They can accept default parameters. Again, useful in formulae: 4(5).
Other definitions from the preamble can be used: 3(4).
Definitions on the fly are also possible: 7(8), and used with different values: a(b).
elyxer-1.2.5/forks/pages-elyxer/container.png0000644000175000017500000001225212117067671020570 0ustar chennochennoPNG  IHDRM7bKGD1 pHYsdd vpAgMIDATx{pTgcRx(⥌"ScVED!S(DZPGGUGĢ[ VBH(%9I!yn=N\o۞A$ TBhB oRe*Kv9b|HN7$HJ{IcH4$ծ4zt!+I9Mp@hB"*֮u]jZ3U@ ~gEhpriҽڕMl/) $ "48#l-[3}Wx&zFrs*裥_LikB1C5wGh"isg $]x1HݺJJnƏzO~+ خ]}WXؙА?>Ə,vtv2A &uh_; !C={|"4[:ᄺ]*-&3vh>wԪUcI4ywX#lw5)=fgK]$uT8o`{S'o|cO)epi6;߆ĩ>Lzqk}W\M= ֝;$Xawut啾I.&RUWK.]Iz~?<ɆDJζsgzQEh",\hw>㍔,l%ZeaذA: U@ҺrihUUq#oUs}YgH_iF\HKc$-B8!4 Mp@hB&8 4 Mp@hB&8 4]ʤqiӤ W_:Hڶ(m[[Gݻ>}뮳e+WJO?-M.JގOHғOJ/ { -W_o*76$k'XMmhTH۾=&OO[RLRwA˃ 3s6]U. R{zut.+(6kTTcǧ-$/Fx ^gVV8L:PiNi&ۥ_?k6TVJm/O=U ֭۫mϱmEE6FƷ]$i"֭?}| ä5k,4v | cbwpwX~4D\JKJvI/JG۲eˤ 7mJ۷ѩu_'téoդIf˗Śѣal̙ҵJ#UWKb6o(ٹ-ѡaSnf͒{wzϟx@c8q>&iFDm~1]8Du`_4=Mp@hB&8 4a{HWH-fmd {t%ֱ!4#wOΝ}޲{4 z1яΓ7GgFɾ+R O>P|)\R S6g8_o1i={^fϖyG:o:v]]]+u Di`&NRU_t LI1wAl"͝[wޢEv 6PX^4|tiWBClU4]wo~ZzT줓 >w@BPضM1\2iv$"RZR92.X~~ԭjEf8d;w٪J9SZBS] )"#bך5E}B)WQEh"ddH{K]QEh"< e\J*SNJGN4z*͈۹S:xiXߕ$}Wd98 4 Mp@hB4:'#åN={ڐY yӜ=ۺz9gO!/O;f|^4N^=q3y˖I&:#GZ SJf{ :t4`3ΨQaYgӏ>j{ާtusm^_n++m];)?_ζ+ӥRرCz Vwo7J!y-/;|eSEc6bbF6ôiȑRaKZK'`S5**ݻ]{tҁtemn~yyCp &hmNm+vΝ=XgeI$Ͷn<6fӧWƬMsۗ^;^|Q꫺IC$)HnX,vn=4JJ+.pz꫃} h:.:tV6]Ѷۨlg9vls}{LlG m`V5Ə[o j[n iR{ysdg7 k<ߵ  (-WAni rN䓥?_ןa{:0h)Y#I?w{GK6}7Opl̙wUb1i8i֬q7MIl7ǁ=%i;/YP`UU6]U%M.1B81 O榿FVVC?زe҄ 6pffx/:I|PwޢE-6˞=O-3w/bpBPyy펫_]snbFH5cϚe;MOj)$i;uq1c̙ҵJcO9Ŗ[XoTwfo }ne=gm.GݹsX/W]e{ݵ|UH&Ssuc־MBvv=\"׾d?mw r!K<9~}`X ;SI[gmVW[`\YcYSFfc'=pAg1ѦgͲ n,Ӿ$},+6ls}L)%B[QBFqp}J޷Uwvv*)/c>pxS@K#4 QY)[ fXFU"8)-[QEh3ΰ!2ʤ/) ;]*6c ߕ qU_*Z%]|ukֹs8? .Tzm] !z+ߧVڶo1o}w~Гk;7w5&ZFHug+С'軺޽~@K!4_H \R"eٷ⧃LS;w=<"-YbCIx~z;v0z8} Q{B3Vf϶a +q}>㩨H:s}WDy~I_~)uq95ylJMChFHv6ڵoו&O18B3b΢U͈;@&8 4 Mp@hB&8 4 M$=S}?BIen/wHҌҲe6YIO>rTQ!}4uY^.NX!=3jTfnt)i҂ҫ۶Gcx|:'TA1 ,ȦMCix[f~ƦkŤ)S; O7bh 4#.١J99-[lOĦeeRVV8L:P}7 D+22=^֭?}䑾9D܌!Mg87Ӻ}=_~YYv_\pPZTڵKz};'9ztÅ MA]xe]}ᥰЂ?=M*9sC w);۞O$ ,-_n?z4lX9͈9DKxf4pxM$[HŤ~|W(&^Ҟ= {&8 4 Mp@hB;$UT$}t+I_- .}:M I4dۈ߄&<̔{/5Kvׇc!C۶R.f.]|W`͈; W|W.!+@H)>D M bڵ]k$i,{wgjӧ4 A@I{.~n(\)'mۤwZ D\vaE?zzI  ͗_z^{h9h矯{?Ie@;)O:ɽݥݻ]vzK2e'҈vsA"G\D*)XĽ ۫|y.*>F i"-;vHJm= J?a|_}{)'րvhʔhK&Rܹ+]+rsϷYYڿ=wߕxCz eLyxer Developer Guide

figure elyxer.png eLyXer Developer Guide

Alex Fernández (elyxer@gmail.com)

1 The Basics

This document should help you get started if you want to understand how eLyXer works, and maybe extending its functionality. The package (including this guide and all accompanying materials) is licensed under the GPL version 3 or, at your option, any later version. See the LICENSE file for details. Also visit the main page to find out about the latest developments.
In this first section we will outline how eLyXer performs the basic tasks. Next section will be devoted to more arcane matters. The third section explains how to contribute to eLyXer, while the fourth one deals with future planned extensions. The fifth section includes things that will probably not be implemented. Finally there is a FAQ that contains answers to questions asked privately and on the lyx-devel list [7].

1.1 Getting eLyXer

If you are interested in eLyXer from a developer perspective the first thing to do is fetch the code. It is included in the standard distribution, so just navigate to the src/ folder and take a look at the .py Python code files.
For more serious use, or if your distribution did not carry the source code, or perhaps to get the latest copy of the code: you need to install the tool git, created by Linus Torvalds (of Linux fame) [8]. You will also need to have Python installed; versions at or above 2.4 should be fine [9]. The code is hosted in Savannah [1], a GNU project for hosting non-GNU projects. So first you have to fetch the code:
$ git clone git://git.sv.gnu.org/elyxer.git
You should see some output similar to this:
Initialized empty Git repository in /home/user/install/elyxer/.git/
remote: Counting objects: 528, done.
remote: Compressing objects: 100% (157/157), done.
remote: Total 528 (delta 371), reused 528 (delta 371)
Receiving objects: 100% (528/528), 150.00 KiB | 140 KiB/s, done.
Resolving deltas: 100% (371/371), done. 
Now enter the directory that git has created.
$ cd elyxer
Your first task is to create the main executable file:
$ ./make
The build system for eLyXer will compile it for you, and even run some basic tests. (We will see later on section 3.1↓ how this “compilation” is done.) Now you can try it out:
$ cd docs/
$ ../elyxer.py devguide.lyx devguide2.html
You have just created your first eLyXer page! The result is in devguide2.html; to view it in Firefox:
$ firefox-bin devguide2.html
If you want to debug eLyXer then it is better to run it from the source code folder, instead of the compiled version. For this you need to make just a small change, instead of elyxer.py run src/principal.py:
$ ../src/principal.py --debug devguide.lyx devguide2.html
and you will see the internal debug messages.
Note for Windows developers: on Windows eLyXer needs to be invoked using the Python executable, and of course changing the slashes to backward-slashes:
> Python ..\elyxer.py devguide.lyx devguide2.html
or for the source code version:
> Python ..\src\elyxer.py devguide.lyx devguide2.html
If you want to install the created version you just have to run the provided install script as root:
# ./install
Once eLyXer has been installed it can be invoked as any other Unix command:
$ elyxer.py devguide.lyx devguide3.html
In the rest of this section we will delve a little bit into how eLyXer works.

1.2Containers

The basic code artifact (or ‘class’ in Python talk) is the Container, located in the gen package (file src/gen/Container.py). Its responsibility is to take a bit of LyX code and generate working HTML code. This includes (with the aid of some helper classes): reading from file a few lines, converting it to HTML, and writing the lines back to a second file.
The following figure 1↓ shows how a Container works. Each type of Container should have a parser and an output, and a list of contents. The parser object receives LyX input and produces a list of contents that is stored in the Container. The output object then converts those contents to a portion of valid HTML code.
figure container.png
Figure 1 Container structure.
Two important class attributes of a Container are:
  • start: a string of text containing the LyX command that we are about to process;
  • and ending, which is used on some Containers to determine when to stop parsing.
A class called ContainerFactory has the responsibility of creating the appropriate containers, as the strings in their start attributes are found.
The basic method of a Container is:
  • process(): called after parsing the LyX text and before outputting the HTML result. Here the Container can alter its contents as needed, once everything has been read and before it is output.
Now we will see each subordinate class in detail.

1.3Parsers

The package parse contains almost all parsing code; it has been isolated on purpose so that LyX format changes can be tackled just by changing the code in that directory.
A Parser has two main methods: parseheader() and parse().
parseheader(): parses the first line and returns the contents as a list of words. This method is common for all Parsers. For example, for the command ’\\emph on’ the Parser will return a list [’\\emph’,’on’]. This list will end up in the Container as an attribute header.
parse(): parses all the remaining lines of the command. They will end up in the Container as an attribute contents. This method depends on the particular Parser employed.
Basic Parsers reside in the file parser.py. Among them are the following usual classes:
LoneCommand: parses a single line containing a LyX command.
BoundedParser: reads until it finds the ending. For each line found within, the BoundedParser will call the ContainerFactory to recursively parse its contents. The parser then returns everything found inside as a list.

1.4 Outputs

Common outputs reside in output.py. They have just one method:
gethtml(): processes the contents of a Container and returns a list with file lines. Carriage returns \n must be added manually at the desired points; eLyXer will just merge all lines and write them to file.
Outputs do not however inherit from a common class; all you need is an object with a method gethtml(self,container) that processes the Container’s contents (as a list attribute). An output can also use all attributes of a Container to do their job.

1.5 Tutorial: Adding Your Own Container

If you want to add your own Container to the processing you do not need to modify all these files. You just need to create your own source file that includes the Container, the Parser and the output (or reuse existing ones). Once it is added to the types in the ContainerFactory eLyXer will happily start matching it against LyX commands as they are parsed.
There are good examples of parsing commands in just one file in image.py and formula.py. But let us build our own container BibitemInset here. We want to parse the LyX command in listing 1↓. In the resulting HTML we will generate an anchor: a single tag <a name="mykey"> with fixed text "[ref]".
\begin_inset CommandInset bibitem
LatexCommand bibitem
key "mykey"
\end_inset
Algorithm 1 The LyX command to parse.
We will call the Container BibitemInset, and it will process precisely the inset that we have here. We will place the class in bibitem.py. So this file starts as shown in listing 2↓.
class BibitemInset(Container):
  "An inset containing a bibitem command"
  
  start = ’\\begin_inset CommandInset bibitem’
  ending = ’\\end_inset’
Algorithm 2 Class definition for BibitemInset.
We can use the parser for a bounded command with start and ending, BoundedParser. For the output we will generate a single HTML tag <a>, so the TagOutput() is appropriate. Finally we will set the breaklines attribute to False, so that the output shows the tag in the same line as the contents: <a …>[ref]</a>. Listing 3↓ shows the constructor.
  def __init__(self):
    self.parser = BoundedParser()
    self.output = TagOutput()
    self.tag = ’a’
    self.breaklines = False
Algorithm 3 Constructor for BibitemInset.
The BoundedParser will automatically parse the header and the contents. In the process() method we will discard the first line with the LatexCommand, and place the key from the second line as link destination. The class StringContainer holds string constants; in our case we will have to isolate the key by splitting the string around the double quote ", and then access the anchor with the same name. The contents will be set to the fixed string [ref]. The result is shown in listing 4↓.
  def process(self):
    #skip first line
    del self.contents[0]
    # parse second line: fixed string
    string = self.contents[0]
    # split around the "
    key = string.contents[0].split(’"’)[1]
    # make tag and contents
    self.tag = ’a name="’ + key + ’"’
    string.contents[0] = ’[ref] ’
Algorithm 4 Processing for BibitemInset.
And then we have to add the new class to the types parsed by the ContainerFactory; this has to be done outside the class definition. The complete file is shown in listing 5↓.
from parser import *
from output import *
from container import *
  
class BibitemInset(Container):
  "An inset containing a bibitem command"
  
  start = ’\\begin_inset CommandInset bibitem’
  ending = ’\\end_inset’
  
  def __init__(self):
    self.parser = BoundedParser()
    self.output = TagOutput()
    self.breaklines = False
  
  def process(self):
    #skip first line
    del self.contents[0]
    # parse second line: fixed string
    string = self.contents[0]
    # split around the "
    key = string.contents[0].split(’"’)[1]
    # make tag and contents
    self.tag = ’a name="’ + key + ’"’
    string.contents[0] = ’[ref] ’
  
ContainerFactory.types.append(BibitemInset)
Algorithm 5 Full listing for BibitemInset.
The end result of processing the command in listing 1↑ is a valid anchor:
<a name="mykey">[ref] </a>
The final touch is to make sure that the class is run, importing it in the file gen/factory.py, as shown in listing 6↓. This ensures that the ContainerFactory will know what to do when it finds an element that corresponds to the BibitemInset.

from structure import *
from bibitem import *
from container import *
Algorithm 6 Importing the BibitemInset from the factory file.
Now this Container is not too refined: the link text is fixed, and we need to do additional processing on the bibitem entry to show consecutive numbers. The approach is not very flexible either: e.g. anchor text is fixed. But in less than 20 lines we have parsed a new LyX command and have outputted valid, working XHTML code. The actual code is a bit different but follows the same principles; it can be found in src/bib/biblio.py: in the classes BiblioCite and BiblioEntry, and it processes bibliography entries and citations (with all our missing bits) in about 50 lines.

2 Advanced Features

This section tackles other, more complex features; all of them are included in current versions.

2.1 Parse Tree

On initialization of the ContainerFactory, a ParseTree is created to quickly pass each incoming LyX command to the appropriate containers, which are created on demand. For example, when the ContainerFactory finds a command:
\\emph on
it will create and initialize an EmphaticText object. The ParseTree works with words: it creates a tree where each keyword has its own node. At that node there may be a leaf, which is a Container class, and/or additional branches that point to other nodes. If the tree finds a Container leaf at the last node then it has found the right point; otherwise it must backtrack to the last node with a Container leaf.
Figure 2↓ shows a piece of the actual parse tree. You can see how if the string to parse is \begin_inset LatexCommand, at the node for the second keyword LatexCommand there is no leaf, just two more branches label and ref. In this case the ParseTree would backtrack to begin_inset, and choose the generic Inset.
figure parse tree.png
Figure 2 Portion of the parse tree.
Parsing is much faster this way, but there are disadvantages; for one, parsing can only be done using whole words and not prefixes. SGML tags (such as <lyxtabular>) pose particular problems: sometimes they may appear with attributes (as in <lyxtabular version="3">), and in this case the starting word is <lyxtabular without the trailing ’>’ character. So the parse tree removes any trailing ’>’, and the start string would be just <lyxtabular; this way both starting words <lyxtabular> and <lyxtabular are recognized.

2.2 Postprocessors

Some post-processing of the resulting HTML page can make the results look much better. The main stage in the postprocessing pipeline inserts a title “Bibliography” before the first bibliographical entry. But more can be added to alter the result. As eLyXer parses a LyX document it automatically numbers all chapters and sections. This is also done in the postprocessor.
The package post contains most postprocessing code, although some postprocessors are located in the classes of their containers for easy access.

2.3 Mathematical Formulae

Formulae in LyX are rendered beautifully into TeX and PDF documents. For HTML the conversion is not so simple. There are basically three options:
  • render the formula as an image (GIF or PNG), then import the image;
  • export a specific language called MathML
  • or render using a variety of Unicode characters, HTML and CSS wizardry [2].
eLyXer employs the third technique, with varied results. Basic fractions and square roots should be rendered fine, albeit at the moment there may be some issues pending. Complex fractions with several levels do not come out right. (But see subsection 2.4↓.)

2.4 MathML

There are two options in place to generate MathML, as suggested by Günther Milne and Abdelrazak Younes [4, 5]. Both rely on some JavaScript page manipulations, and they need to be hosted on the same server as the documents. MathJax is less mature but it has grown faster so it has become the preferred option.
To use this last option in your own pages you just have to add the --mathjax option:
$ elyxer.py --mathjax ./MathJax math.lyx math.html
You will notice that the --mathjax option requires an argument: the directory where MathJax resides. MathJax needs to live on your server; after downloading the package, deploy it to your server and give the installation directory as an argument to --mathjax.
In principle you might think of using some external installation of MathJax to avoid downloading it and serving it from your server, e.g. from Savannah:
$ elyxer.py --mathjax http://elyxer.nongnu.org/MathJax/ math.lyx math.html
This approach may not work on certain browsers for two reasons: JavaScript loaded from a different site may not work, and WebFonts are also subject to this same-origin policy. If you have made it work it would be great to hear about it.

2.5 Baskets

eLyXer supports a few distinct modes of operation. In each incarnation the tasks to do are quite different:
  • A pure filter: read from disk and write to disk each Container, keeping no context in memory.
  • In-memory processing: read a complete file, process it and write it all to disk.
  • TOC generation: output just a table of contents for a LyX document.
  • Split document generation: separates each chapter, section or subsection in a different file.
How can it do so many different tasks without changing a lot of code? The answer is in the file gen/basket.py. A Basket is an object that keeps Containers. Once a batch is ready, the Basket outputs them to disk or to some other Basket, but it may decide to just wait a little longer.
The basic Basket is the WriterBasket: it writes everything that it gets to disk immediately and then forgets about it. Some bits of state are kept around, like for example which biliography entries have been found so far, but the bulk of the memory is released.
Another more complex object is the TOCBasket: it checks if the Container is worthy to appear in a TOC, and otherwise just discards it. For chapters, sections and so on it converts them to TOC entries and outputs them to disk.
The MemoryBasket does most of its work in memory: it stores all Containers until they have all been read, then does some further processing on them and outputs an improved version of the document, at the cost of using quite more memory. This allows us for example to generate a list of figures or to set consecutive labels for bibliography entries (instead of just numbering them as they appear in the text).
The most complex kind of Basket is the SplittingBasket: it writes each document part to a separate file, choosing what parts to split depending on the configuration passed in the --splitpart option. By default it creates a TOC at the top of each page.

2.6 Hybrid Functions

Math processing is very configurable; most of it is based on configuration options found in src/conf/base.cfg. Parsing can be done using a few simple functions: commands (contained in [FormulaConfig.commands]) output some content and don’t have any parameters, while one-parameter functions (in [FormulaConfig.onefunctions]) take exactly one parameter and output an HTML tag. Thus, the definition for \bar is:
\bar:span class="bar"
Whenever eLyXer finds the command it parses a parameter, then outputs the tag <span class="bar"> surrounding the parameter. For instance: e.g. \bar{38} becomes <span class="bar">38</span> in the output. Decorating functions (in [FormulaConfig.decoratingfunctions]) place a symbol from in the definition above the parameter, and so on.
Such simple processing is not always enough; there is a generic mechanism for producing complex output from a number of parameters. They are called hybrid functions.
Each definition for a hybrid function contains: parser definition, output definition and a number of function tags. The parser definition tells eLyXer what to parse. Hybrid functions can have any number of optional parameters, denoted as [$p]; mandatory parameters are shown as {$p}. Each parameter consists of the symbol $ followed by a letter or number: $0, $p.
The output definition contains regular text, plus parameters and functions. Each function consists of the letter f plus a number, such as f0; and each is associated with a tagged HTML element. These function tags are the last part of the definition. Presently there can be as many as 10 function tags (from f0 to f9).
Let us see a simple example, equivalent to the above formula — a one-parameter, one-tag hybrid function:
\fun:[{$p},f0{$p},span class="fun"]
The only function tag f0 generates the HTML tag <span class="fun">. Whenever eLyXer finds \fun in a math formula, it will parse one parameter and put it into $p. Then it will generate f0{$p}, i.e. apply the tag <span class="fun">. Putting it all together: \fun{38} becomes <span class="fun">38</span>.
Parameters can be parsed as a literal, in which case eLyXer will take everything between the brackets without parsing it. Literal parameters can be used within a tag definition. A real life hybrid function with literal parameters:
\raisebox:[{$p!}{$1},f0{$1},span class="raisebox" style="vertical-align: $p;"]
In this case there are two mandatory parameters, the first one literal and the second one a regular TeX expression. The output is just one function tag, in this case using the first mandatory parameter. For instance, \raisebox{3cm}{5} would generate:
<span class="raisebox" style="vertical-align: 3cm;">5</span>
The parameter $p is parsed as 3cm, which is not parsed further.
Hybrid functions are easy to configure once you get the hang of it. Adding new TeX commands, even complex ones, becomes simply a matter of configuration.

3 Developing and Contributing

This chapter will show you how to further develop eLyXer and how to contribute your own code.

3.1 Distribution

You will notice that in the src/ folder there are several Python files, while in the main directory there is just a big one called elyxer.py. The reason is that before distributing the source code is coalesced and placed on the main directory, so that users can run it without worrying about libraries, directories and the such. (They need of course to have Python 2.5 installed.) And the weapon is a little Python script called coalesce.py that does the dirty job of parsing dependencies and inserting them into the main file. There is also a make Bash script that takes care of permissions and generates the documentation. Just type
$ ./make
at the prompt. This coalesces all code and configuration into elyxer.py. It is a primitive way perhaps to generate the “binary” (ok, not really a binary but a distributable Python file), but it works great.
The make script also runs all of the included tests to check that no functionality has been lost from one release to the next. These tests can also be run independently using the run-tests script:
$ ./run-tests
They are used to verify that no functionality is lost from one version to the next — although issues can certainly slip undetected if there is no test for them.
At the moment there is no way to do this packaging on non-Unix operating systems with a single script, e.g. a Windows .bat script. However the steps themselves are trivial.

3.2 Debugging

Code problems are quite difficult to debug using the full elyxer.py file. It is much better to use the uncoalesced version instead, since it is quite modular and neatly divided. To do so you just need to locate the file src/principal.py and run that instead of elyxer.py. For example, if you are in the docs/ directory and you want to convert math.lyx you can run eLyXer as:
$ ../src/principal.py math.lyx math.html
For extra debugging information you can activate the --debug option:
$ ../src/principal.py --debug math.lyx math.html
This will make any traces more meaningful and will let you follow the code much more easily.

3.3 Configuration

The make script does not just construct a single .py file from all sources; it is also used to extract the configuration in human-readable form and create a Python file which is then coalesced with all the rest. The original configuration file (the one you should modify) is called base.cfg, while the resulting Python file is called config.py.
The original configuration file uses this format:
[ContainerConfig.startendings]
\begin_deeper:\end_deeper
\begin_inset:\end_inset
\begin_layout:\end_layout
where each section header is enclosed in square brackets; it contains an object name and a section name. In the example above the object is called ContainerConfig, while the section is called startendings. Inside each section there are a number of key:value pairs separated by a colon; the key is used to reference the value in other Python code.
To create config.py go to the src/ folder and type:
$ ./exportconfig py
This will create all configuration objects to be used inside your Python code, where each section will become an object attribute containing a map. For instance, to access the first value above \end_deeper you would write in your Python code:
ContainerConfig.startendings[’\begin_deeper’]
Each section can contain as many values as needed.

3.4 License

eLyXer is published under the GPL, version 3 or later [3]. This basically means that you can modify the code and distribute the result as desired, as long as you publish your modifications under the same license. But consult a lawyer if you want an authoritative opinion.

3.5 Contributions

All contributions will be published under this same license, so if you send them this way you implicitly give your consent. An explicit license grant would be even better and may be required for larger contributions.
Please send any suggestions, patches, ideas and whatever else related to development to the mailing list. (Alternatively you may contact elyxer@gmail.com privately.) If you are willing to create a patch and submit it, you should patch against the proper sources in src/ and send it to the list. This will make everyone’s lives better than if you patch against elyxer.py.
The first external patches have started arriving during late 2009 and early 2010 (provided by Olivier Ripoll, Geremy Condra and Simon South). You can join in the fun!

4 Roadmap

You can see what user features are planned for the near feature in the wish list.
After the release of eLyXer 1.0, the goal is full LyX document support; any deviation from the output of LyX on e.g. PDF will be considered as bugs. (Keep in mind that some deviations arise in an inherent limitation in the design of eLyXer, and these will logically not be considered as bugs.)
For eLyXer 1.3.0 there are plans to convert it into a proper Python package so it can be installed using full source code (and not a coalesced script elyxer.py that contains everything). Also, once ERTs are parsed, eLyXer might be extended for 1.3.0 to translate generic LaTeX documents.
All this within the usual constraints: day job, family, etc.

5 Discarded Bits

Some features suggested for eLyXer have been discarded; they do not fit with the design of eLyXer or are too much effort for the proposed gains.

5.1 Spellchecking

LyX can use a spellchecker to verify the words used. However it is not interactive so you may forget to run it before generating a version. It is possible to integrate eLyXer with a spellchecker and verify the spelling before generating the HTML, but it is not clear that it can be done cleanly.

5.2 URL Checking

Another fun possibility is to make eLyXer check all the external URLs embedded in the document. However the Python facilities for URL checking are not very mature, at least with Python 2.5: some of them do not return errors, others throw complex exceptions that have to be parsed… It is far easier to just create the HTML page and use wget (or a similar tool) to recursively check all links in the page.

5.3 Use of lyx2lyx Framework

Abdelrazak Younes suggests using the lyx2lyx framework, which after all already knows about LyX formats [5]. It is an interesting suggestion, but one that for now does not fit well with the design of eLyXer: a standalone tool to convert between two formats, or as Kernighan and Plauger put it, a standalone filter [6]. Long-term maintenance might result a bit heavier with this approach though, especially if LyX changes to a different file format in the future.

6 FAQ

Q: I don’t like how your tool outputs my document, what can I do?
A: First make sure that you are using the proper CSS file, i.e. copy the existing docs/lyx.css file to your web page directory. Next try to customize the CSS file to your liking; it is a flexible approach that requires no code changes. Then try changing the code (and submitting the patch back).
Q: How is the code maintained?
A: It is kept in a git repository on Savannah. Patches in git format are welcome (but keep in mind that my knowledge of git is even shallower than my Python skills).
Q: I found a bug, what should I do?
A: Just report it to the Savannah interface, to the mailing list or directly to the main author.

Nomenclature

class A self-contained piece of code that hosts attributes (values) and methods (functions).
filter A type of program that reads from a file and writes to another file, keeping in memory only what is needed short term.
TOC Table of contents

References

[1] Free Software Foundation, Inc.: eLyXer summary. https://savannah.nongnu.org/projects/elyxer/

[2] S White: “Math in HTML with CSS”, accessed March 2009. http://www.zipcon.net/~swhite/docs/math/math.html

[3] R S Stallman et al: “GNU GENERAL PUBLIC LICENSE” version 3, 20070629. http://www.gnu.org/copyleft/gpl.html

[4] G Milde: “Re: eLyXer: LyX to HTML converter”, message to list lyx-devel, 20090309. http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg148627.html

[5] A Younes: “Re: eLyXer: LyX to HTML converter”, message to list lyx-devel, 20090309. http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg148634.html

[6] B W Kernighan, P J Plauger: “Software Tools”, ed. Addison-Wesley Professional 1976, p. 35.

[7] Various authors: “lyx-devel mailing list”, accessed November 2009. http://www.mail-archive.com/lyx-devel@lists.lyx.org/

[8] S Chacon: “Git — Download”, accessed November 2009. http://git-scm.com/download

[9] Python community: “Download Python”, accessed November 2009. http://www.python.org/download/

elyxer-1.2.5/forks/pages-elyxer/changelog.html0000644000175000017500000016447312117067647020735 0ustar chennochenno eLyXer changelog

figure elyxer.png eLyXer Changelog

This document lists all public versions, the date they were released on and the changes they contain. For more information about eLyXer visit the main page.
  • 1.2.4 (2013-01-11):
    • Implemented generic converters, and lyx -C as an image converter (thanks, Tommaso!).
    • Implemented command \today: Mar 10, 2013.
    • Added a Russian translation (thanks, Vladimir!).
    • Solved a bug when parsing a BibTeX entry with a trailing comma (thanks, Bob!).
    • BibTeX: correctly use booktitle instead of journal in an @inproceedings entry (thanks, Pascal!).
    • Expose language information as additional markup (using the lang attribute in HTML).
    • Fix by Guenter Milde for math2html under Python 3.0.
    • Convert em-dash only when surrounded by spaces (thanks, Robert).
    • Fix by José Ramón Álvarez Sánchez of problem in simultaneous use of hover and end options for footnotes (thanks, Tim!).
  • 1.2.3 (2011-08-31):
    • Changed the license for math2html from Apache v2 to FreeBSD 2-clause license, to better suit integration with DocUtils.
    • Removed a false positive error which appeared during the tests: “* No title in”.
    • Added most commands in Günter Milde’s excellent list of Unicode to LaTeX commands, except categories mathaccent, mathfence, mathradical, mathover and mathunder. Examples: \hash as  ⋕ , \smalltriangleleft as .
    • Deprecated option --jsmath, users are encouraged to use --mathjax instead.
    • Added argument --mathjax remote to access the MathJax CDN instead of hit a local copy. Changed the Math showcase to work remotely by default.
    • Solved Debian bug 639712: eLyXer didn’t accept Unicode characters in --title option, added test.
    • Solved Savannah bug 33961: eLyXer didn’t support sub- or superscript insets as used in LyX 2.0, added test.
    • Solved installation problem when $PATH contains a directory which does not exist; the eLyXer binary was created with the same name as said directory. Now install.py should just ignore the directory. (Thanks, Jack!)
  • 1.2.2 (2011-06-12):
    • Bug in description: when a (non-empty) ERT is the first element of a description, use it as first word and make it bold.
    • Proper support for \scriptstyle and \scriptscriptstyle: script, scriptscript.
    • Bug #33156: CSS specification as in --css=lyx.css was not working, solved now.
    • Support for \noindent and \centering in ERTs.
    • Ignore BibTeX entries which are not publication entries. Show a debug message for non-referenced entries.
    • Understand command \& in BibTeX files.
    • Bumped Lyx format supported (--lyxformat) to 413 (LyX 2.0.0).
    • Solved error when parsing display formulas generated with LyX 2.0: "Formula beginning \begin_inset Formula is unknown" (thanks, Pascal!). Added test case.
    • Added a bunch of new symbols, including \textsection §, \textemdash — or \v{z} ž (thanks again, Pascal!).
    • Changed output characters for English quotes, from Unicode “ and ‘ to HTML entities &ldquo; and &lsquo; (thanks, Marco!).
    • Make Flex styles in titles work (thanks, Tiago!).
    • Make custom Flex CharStyles work: generate HTML spans of the same class as the Flex type (thanks again, Marco!).
  • 1.2.1 (2011-03-07):
    • Wish list: support for formatted references (showing the part name and number) and named references (showing the part title, equivalent to \nameref).
    • Wish list: include part titles in --splitpart navigation header.
    • Changed literal for previous page in --splitpart: now it’s “Prev” instead of “Previous”.
    • Bug in --notoclabels: removed the “.” after the part number but before the title shown in the TOC. “5. How to Make Friends” is now “5 How to Make Friends” (thanks, José Ramón!).
    • Allow math2html to be invoked using parameters (like --debug).
    • Bugs in ERT parsing: brackets {} are not parsed correctly across different ERTs. The TeX parser was being thrown off by escaped brackets as in {\{\}}, added test. Comments are ignored now.
    • Solved conflict in CSS between .script (used to properly layout super- and subscripts) and span.script (used for the script-type \mathscr and \mathcal fonts). Changed the latter to span.scriptfont, forcing an incompatible but unavoidable change in the CSS.
    • Forced span.scriptfont to be shown as italic so it’s properly displayed on Firefox.
    • Wish list: new option --googlecharts adds support for formula images generated using Google Charts.
    • Wish list: merged options --toc and --toctarget into --tocfor.
    • Wish list: options --splitpart and --tocfor (previously --toc) now work together. Also: the separate TOC has a link to the main page.
    • Bug in --splitpart combined with --notoclabels: unnumbered parts displayed an ugly colon as in “Next : Section”, now removed (thanks, José Ramón!).
    • Modified the spacing in formulas so that words in the mathnormal font now appear separated, as a product of variables.
    • Do not show limit symbols such as or in a larger font than the rest for inline formulas.
    • Added support for \textcircled: w⃝.
  • 1.2.0 (2011-01-30):
    • Bumped LyX version support to 410.
    • Correctly create big brackets for environments with odd alignments such as matrix (thanks, Günther!).
    • Create and use big brackets for fractions and other structures, if needed.
    • Added option --simplemath to avoid fancy math structures: do not generate multi-line Unicode brackets or stacked limits.
    • eLyXer is now a proper Python package, instead of just a coalesced script elyxer.py containing everything. However only the script is installed right now.
    • Interpret TeXCode (previously known as Evil Red Text) as TeX commands and formulas.
    • Support for TeX commands \textvisiblespace, \AmS, \parbox, \tag, \rule, and more: , AmS.
    • Support for \Game: .
    • Changed the navigation header for --splitpart so that the left and right spans overflow (thanks, Axel!).
    • Bug in --notoclabels: labels such as “Figure” should be omitted in the TOC, but not in captions (thanks again, Axel!).
    • Bug in --splitpart: empty navigation links caused the header to look unbalanced, fixed now with a non-breaking space. Also, up link in the main page used to point to itself; now it’s an empty link (more thanks, Axel!).
    • Support for \limits and \nolimits: control if the last symbol should show limits above or below the symbol or not.
    • Bug in \vspace: add the vertical space after the command, not before; or at least try to.
    • Bug in \raisebox: parse and display the contents as text mode.
    • Wish list: do not number captions in code listings.
    • Do not install as a module (to run as python -m elyxer) but only as a script (to run as elyxer.py).
  • 1.1.2 (2010-12-23):
    • Wish list: display large Unicode symbols for sums and integrals in display mode.
    • Also in display mode, place limits for commands that take them above or below the symbol, instead of to the right.
    • Support for new Flex insets: Code, MenuItem, Noun, Strong; new Argument, Phantom and line (ruler) insets; new style \strikeout; new LaTeX commands \href, \newline.
    • BibTeX: apply a combining function only to the following character, not to the next word.
    • Added reference format for vpageref (“on page #”).
    • Improved math macro parsing: optional parameters, literal parameters, single-letter parameters, parameter defaults with operations.
    • Display math cases, full-sized binomials (\dbinom) and array brackets using Unicode bracket pieces.
    • Change all table-type elements in formulas to spans and do the formatting in the CSS, to generate valid XHTML.
    • Support graceful degradation of fractions and roots when the CSS is not present.
    • Adjusted roots to insert the root power inside the radical symbol.
    • Adjusted nice fractions (34) to improve their appearance.
    • Support for all upright Greek letters: μ, τ.
  • 1.1.1 (2010-12-13):
    • Wish list: understand \url{} in BibTeX files.
    • Wish list: parse math formulas in BibTeX files.
    • Improved support for dotless i and j as \imath and \jmath: ı, ȷ.
    • Solved bug when parsing a quoted string inside a BibTeX file containing a comma.
    • Added math environments equation* and matrix.
    • Do not break inline formulas at whitespace (thanks, José Ramón!).
    • Break up the CSS into pieces, and generate an independent math.css for use within math2html.py.
    • Ignore hyphens in option names, so e.g. --split-part is equivalent to --splitpart.
    • Changed --forceformat to --imageformat (kept the old option for backwards compatibility).
    • Wish list: added --imageformat "copy" to just copy images instead of converting them.
    • Wish list: added option --embedcss "file.css" to embed the CSS styles in file.css into the resulting HTML.
    • Wish list: more than one --css options can be added to use several CSS files.
    • Wish list: display sub- and superscript aligned vertically (as in integrals).
  • 1.1.0 (2010-11-23):
    • Wish list: understand \setcounter in the preamble to set the number of the first Chapter or Section.
    • Generate a new math2html.py file with an API to convert raw LaTeX code to HTML, and a command line utility.
    • Wish list: new option --notoclabels to omit part labels in the TOC.
    • Wish list: make “show changes in the output” work for change tracking.
    • Solve an existing issue with Description and List layouts: correct splitting of first words when intermixing styles.
    • Show decorations using Unicode combining characters, whenever possible.
    • Support for \dddot: o⃛ (with combining character) and \widehat: ^abc (with character on top).
    • Wish list: add several options for footnote generation (align markers instead of using superscript, place markers at the bottom of the page, use symbols for markers…). Also added a generic --footnotes option to aggregate them all.
    • Wish list: use ps:use-cropbox=true in ImageMagick for PostScript and EPS images.
    • Support for dotless i and j: ı, ȷ.
  • 1.0.4 (2010-10-29):
    • Solved bug #31342: detect appendices as they appear instead of looking at the containing layout.
    • Also reported in bug #31342: set part name to “Appendix A-Z” in the TOC for appendices, instead of showing them as regular chapters or sections.
    • Also reported in bug #31342: number parts and books using roman numerals, as in “Part I” or “Book IV”.
    • Fixed bug due to wrapped float placement not being mandatory anymore, despite what EmbeddedObjects.lyx says (thanks, Hans!).
    • Solved bug #31351: do not number (or add to the TOC) any document parts inside comments.
    • Also in bug #31351: the bibliography should be added to the TOC if so configured (and not inside a comment), and split into its own page with --splitpart.
    • Also in bug #31351: show the bibliography in regular size, not smaller than the main text as before.
    • Changed header from “Bibliography” to “References” for document classes other than book and report.
    • Solved bug #31414: bootstrap creation of conf/config.py.
    • Also in bug #31414: remodeled unit tests to try out Python 2.4 only if present, and to remove test files from previous runs.
    • Show the “Abstract” header only for the first Abstract layout (thanks, Yaron!).
    • Do not separate consecutive Abstract paragraphs, and display the abstract in slightly smaller font size.
    • Solved bug #31345: ignore preamble and comments in BibTeX files. Use string definitions (@string) in other entries.
    • Also in bug #31345: avoid endless loops for undesired characters in BibTeX entries.
    • Support for \fbox, \boxed, \framebox and \fcolorbox: fbox, boxed, framebox.
  • 1.0.3 (2010-10-15):
    • Do not hide errors when parsing child documents.
    • Correctly convert documents even when images are not found.
    • Do not center the content in figure or table floats by default.
    • Correctly convert child documents even when inserted in layouts.
    • Generate navigation bars for first page created with --splitpart.
    • Added wishlist to the user guide to keep track of requested features.
    • Solved bug #31243: spaces and comments in formulas (command definitions, empty formulas…).
    • Also reported in bug #31243: do not add numbering twice to child documents, and ignore child documents in comments.
    • Added support for \stackrel: xR → y (thanks, José Ramón!).
    • Added a lot of escaped characters to BibTeX parsing: \~n, \’{\i}… Also added a field note to all BibTeX styles.
    • Show all references (even those not cited) in the bibliography if configured to do so.
    • Understand relative sizes (e.g. 10col%) in spaces (thanks, Uwe!).
  • 1.0.2 (2010-09-20):
    • Updated MathJax to version 1.0.1 — no changes to eLyXer documents are necessary.
    • Added option --noconvert to use images in their original formats, and avoid converting images altogether.
    • Output <object> tags for SVG images. Size information is not used as it causes problems on Firefox.
    • BibTeX: include booktitle tag for the @incollection format.
    • BibTex: added a tag <span class="bibcites"> around all bibliographical cites, so they can be e.g. superscripted.
    • Show footnotes as hovering text instead of as marginal notes. Make the default footnote marker a bluish superscript letter in brackets:  [A]  [A] like this.
    • Updated --lyxformat to 398 (2.0alpha5); added warning if document version is bigger than that.
    • Support for \textless and \textgreater: <, >.
    • Added adjustments for better printing to default CSS.
    • Added languages “british” and “american” (which translate to plain English).
    • Avoid extracting indexes out of the containing layout if there is anything else in there (thanks, Amy!). This bug caused some content to be lost (e.g. child documents) if they were inside the same layout as e.g. an alphabetical index.
  • 1.0.1 (2010-09-01):
    • BibTeX: more robust parsing, specifically: correctly parse entries separated by commas. Support all TeX commands already available in math formulae.
    • Support for \textasciitilde: ~, \textasciicircum: ^ and a few other \text… symbols. Also, \textrm, \textsf and \textnormal should be working now in equations: a + roman + sans-serif + normal + b.
    • Improved support for custom horizontal and vertical spaces; absolute measures can now be used.
    • Support for sizes in table columns, figures and boxes.
    • Solved bug in --nofooter which required a dummy argument (thanks, Yan!).
    • Corrected box styling: <div class="Frameless"> is now indeed frameless, while <div class="Framed"> no longer has a double border.
    • Solved bug in text handling which separated consecutive centered lines with a space.
    • Basic support for LyX change tracking.
  • 1.0.0 (2010-07-21):
    • Replicate the navigation bar for --splitpart at the bottom of pages. Use translated strings for “Previous”, “Up” and “Next” links. Also added an explanatory text to the “up” link in the navigation bar, as in: “Up: Chapter 1”.
    • Added partial table of contents to pages generated with --splitpart.
    • Dependency cleanup between code modules.
    • Child documents of type “verbatim input” are now correctly converted on versions of Python built without universal newline support.
    • Include Index and Nomenclature in the Table of Contents.
    • When an Index, TOC, List of Figures… and the like is embedded in another layout, do not follow the style of the layout (thanks, Yaron!).
    • Solved a couple of XHTML validation errors: removed asterisks (*) in anchor names, avoid empty rows in arrays or case statements.
    • Make index entries work in Descriptions. Also, mixed styles should work again within Descriptions.
    • Group certain layouts together, such as Quote and Quotation.
    • Improved output for algorithms: do not run lines together, and do not separate other lines with double space.
    • List of algorithms does now correctly extract the text from the caption.
    • Increased line height for h2 in the main CSS (thanks, Wolfgang!).
    • Better color support in formulas: \color, \textcolor, \colorbox. blue, blue.
    • Formulas and formula labels are not colored by default.
    • Improved Index output: there is only one anchor for each entry, and entries are not shown in italics.
    • Allow hierarchical index entries, of the form “Main ! Secondary ! Final”.
  • 0.99 (2010-06-24):
    • Added --splitpart to online help (thanks, Sven!).
    • Restored compatibility with Python 2.4 (lost in 0.98 by mistake), added test to ensure it does not happen again.
    • BibTeX: improved template definitions for Vancouver style.
    • BibTeX: better parsing of braces (in templates) and quotes (in .bib files). Nested braces in templates are supported.
    • BibTeX: variable citing styles. Enclose cites in brackets instead of using superscripts.
    • BibTeX: export all BibTeX variables in bib-… spans.
    • BibTeX: limited author parsing, support for surname abbreviations as in style alpha.
    • BibTeX: use the file tag to show a link to the local file.
    • Added \oint and friends as a bigsymbol: x·dx.
    • Support for \officialeuro: .
    • Fix captions in lists of figures which use standard layouts (thanks, Hans!).
    • Added option --template to use an HTML template and substitute <!--$content-->, <!--$title-->
    • Added option --copyright to add a copyright notice at the bottom (no longer generated by default). Deprecated old option --nocopy.
    • Added support for including files as a code listing.
  • 0.98 (2010-05-13):
    • MathJax: workaround bug in MSIE, that causes it to fail to render anything.
    • Add a margin to LyX-Code. Also improve line break separation inside LyX-Code.
    • Coalesce Python code: use relative paths when importing (thanks, Jack!).
    • Experimental installation script.
    • Avoid postprocessing child documents twice (thanks, Rainer!).
    • Solved bug when loading images from child documents in subdirectories (thanks, Rainer!).
    • Solved bug in image scaling when only one dimension is set (thanks, Wolfgang!).
    • Corrected issue with one-liner \lstset (thanks again, Rainer!).
    • Improved lists of figures, tables and algorithms: use short title, better labeling of floats.
    • Solved weird bug in float numbering when a chapter has only one layout.
    • Added \diagup and \diagdown: , .
    • First public release of option --splitpart [level]: split resulting web page at the given level.
    • Support for macros, both in LyX macro inset and as \newcommand.
    • Added URLs to most BibTeX formats.
    • Added BibTeX style “vancouver” for articles (thanks, John!).
    • Added a footer detailing eLyXer version and conversion date; it can be turned off with --nofooter.
  • 0.43 (2010-04-10):
    • Many BibTeX improvements: new style abbrvnat, conditional formatting, look up types in lowercase, understand “--” as dash.
    • Added options for mathematical equations: --jsmath to use jsMath and --mathjax to use MathJax.
    • Added command help to loremipsumize.py so it can be used outside of eLyXer.
    • Include internationalization files in .zip file.
    • Solved bug in table parsing: separate different plain layouts (thanks, Sara!).
    • eLyXer compressed files now contain a single directory called elyxer-$VERSION, instead of just elyxer.
    • Added italicized uppercase Greek letters: ΓΩ. De-italicized regular uppercase Greek letters: ΓΩ.
  • 0.42 (2010-03-17):
    • Changed author everywhere to the real name, to avoid any copyleft uncertainties.
    • Remove hook in the main text ([D→]) from margin notes.
    • Do not crash when BibTeX files are not found, just show an error.
    • Added support for some IPA characters, including ħ. Better parsing of \textipa text.
    • Added option --numberfoot to label footnotes with numbers instead of letters.
    • Solved bug in assignment of default formatting to references (thanks, Hans!).
    • Added option --raw to output raw HTML without header or footer.
    • Added French and Dutch translations.
    • Solved indenting problem for lists: only the first line was being indented.
  • 0.41 (2010-02-11):
    • Select the translation based on document language.
    • Added em-dash — such as in this sentence, , \textup.
    • Added option --converter inkscape to use Inkscape as SVG converter.
    • Solved bug when numbering unordered unique parts such as Part* (thanks, Geremy!).
    • Show error instead of crashing when included document does not exist.
    • Support for all box styles. In CSS: switched to outline-style instead of border for boxes.
    • Support for vertical space insets.
    • Support for references inside paragraphs and formatted references.
    • Listings are now converted using <pre> tags, instead of <code>. They are also justified left.
    • Solved bug that prevented numbered listings to appear numbered (thanks, Sam!).
    • Support for generic Flex insets, incuding Flex CharStyle:MenuItem.
    • All &nbsp; entities are now generated as the Unicode U+00A0 character.
    • New option --iso885915 to generate a document with ISO-8859-15 encoding.
    • Support for Sam Liddicott’s Newfangle module for literate programming.
    • Updated the developer guide for potential contributors; added link from the main page.
    • Support for \underbrace and \overbrace (as bars and without sub/superscripts).
  • 0.40 (2010-01-19):
    • Faster (about 25%) BibTeX file parsing.
    • Show version number after a crash.
    • Imported Jens Nöckel’s contributed list of LaTeX to Unicode mappings: , and many more.
    • Added support for compressed documents (Document ▷ Compressed).
    • Added configurable alignment support for equation environments (thanks, Jens!). Multiple labels per formula are correctly processed.
    • Added a couple of note insets for Tufte document classes, appearing as side notes without a reference (thanks, Joachim!).
    • Support for escaped characters in BibTeX files, added German umlauts for starters.
    • Support for internationalization using GNU gettext files. Added Spanish and German translations in the po/ folder.
    • Support for verbatim includes.
  • 0.39 (2009-12-20):
    • Avoid oversized images on IE6.
    • Solved several crashes with the LyX documentation (thanks, Uwe!).
    • Created script to lorem-ipsumize texts, found in src/loremipsumize.py.
    • Solved some issues with BibTeX parsing; now it should work with most real-world files (thanks, Ken!). Also improved error reporting and implemented a new way of line-by-line parsing from file, activated with --lowmem.
    • Support for binomial coefficients: (AB). Ignore commands \leftroot, \uproot. Generic support for variable commands in math mode.
    • Support for omitted aligned brackets: right) (thanks, Jens!).
    • Solved bug with image conversion from directories (thanks, Olivier!).
  • 0.38 (2009-12-03):
    • Resized all logos in the documentation.
    • Solved bug in paragraph indentation that indented all formula spans and elements.
    • Solved a couple of bugs in image scaling: wraps with images, images in figures.
    • Solved bug in TOC generation: article-class documents had their TOC depth off-by-one.
    • Solved bug with listings inserted in documents using LyX 1.6, and improved their looks.
    • Slight font size reduction on Firefox, and huge reduction on some other proprietary browsers. Now global font size specification is done using percents.
    • New commands: \gtrless: , \complement: , \measuredangle: , \sphericalangle: , \nmid: , \circeq: , \lessgtr: , \nparallel: .
  • 0.37 (2009-11-30):
    • Further improvements in float manipulation: figures enclosing other figures have their own tweaked CSS class (thanks, Olivier).
    • PNG and JPEG images are not rescaled anymore, and never shown above their maximum size. Width and height are set using CSS properties.
    • TOC generation for unordered entries (like Section*) and entries inserted in other layouts. Max TOC depth and max numbering depth are honored. Also solved bug in tagging of unordered parts.
    • Implemented indented paragraphs when specified in the document.
    • Horizontal fill is now shown as a fixed-width space.
    • Simplified postprocessing code. Inclusion of child documents is now done inside a Standard layout.
    • Support for commands \varkappa: ϰ, \varnothing: , \mathring: , \backprime: , \notin: , \hfill: , \circledR: ®, \hslash: .
    • New option --splitpart to split the output in multiple pages, one page per part; needs more tweaking.
  • 0.36 (2009-11-19):
    • New in-memory processing of a document before file output, activated by default. It includes: TOC generation (TOC entries admit typefaces, colors, weights, spaces, short titles but restrict most other content), sequential numbering to bibliography entries, lists of floats (figures, tables, algorithms), correct labeling of references and use of the embedded title as HTML title.
    • New option --lowmem to do one-pass filtering only, to preserve memory (keeping the old behavior).
    • Updated the developer guide.
    • Change the postprocessing of equation labels so that only one anchor is used for the whole equation.
    • Added \mathscr and a few script fonts: hello. Added several characters for math script (\mathscr), fraktur (\mathfrak) and blackboard (\mathbb) fonts, and implemented the translation to Unicode chars: , 𝔉, 𝔽.
    • New math commands: \dfrac, implemented as \cfrac; \c for cedilla, already implemented as characters and now as decoration: ; thick space \; and quotes ": " "; \hspace for horizontal space and \vspace for vertical space; and a few size commands: \big, \Big, \bigg, \Bigg, \middle.
    • Added a parent attribute to every Container, for easier processing.
    • Image conversion and display: process width and height in an image if both are present; use % width of image within a float to scale the float; set max scaling of images to 100% with max-width CSS attribute. (Thanks, Olivier and Uwe.)
    • Subfloats are numbered (a), (b) (instead of x.ya, x.yb).
    • Convert all pathnames for image conversion using sys.getfilesystemencoding().
  • 0.35 (2009-11-05):
    • Added new characters: \checkmark , \blacklozenge , \nexists , \mathcircumflex ^.
    • Updated all documentation to LyX 1.6.
    • Solved CSS validation error in table.align (thanks, Olivier).
    • Solved XHTML validation error in greyed out note, removing useless divs.
    • Add a space after a fraction and before the units: 32 km, (7)/(16) s.
    • Corrected display of float within a float (thanks again, Olivier!).
    • Modified the meaning of --toc to be an on/off switch; the old behavior is now under --toctarget.
    • Changed the 2009-11-05 option --cutpart to --splitpart: new option to split the output file in parts. Not yet working correctly (for instance, links are not redirected).
    • eLyXer now understands and processes new Graphics options: width 50col%, height 50theight% and friends (thanks, Uwe).
    • PDF images are cropped before conversion to PNG (thanks, Uwe).
    • Included child documents can be inserted using firstline and lastline (as seen in EmbeddedObjects.lyx).
  • 0.34 (2009-10-28):
    • Support for child document inclusion (Insert ▷ File ▷ Child Document…).
    • Avoid generating images on different directories (relative paths starting with ../).
    • Added \maltese and financial symbols $, €, ¥.
    • Removed annoying message “Unexpected end of bracket” when parsing empty brackets.
    • Support for \raisebox.
    • Created new structure of Writers, preparing for document segmentation and TOC generation.
  • 0.33 (2009-10-19):
    • New TOC generation process based on an already-generated HTML document, not ready for prime time yet.
    • Adapted --help option so that it shows the executable file as invoked (elyxer.py, elyxer or whatever). Expanded online help from this command.
    • Support for new text commands \textsf, \texttt, \textit, \textbf, \textsl, \textsc.
    • Properly parse all text commands \text…, including \textipa.
    • Support for \cfrac. Now regular \frac shows embedded formulas smaller.
    • Do not number equations containing *, like in \begin{align*}. (Once more, thanks Uwe.)
    • Properly align equations for AMS align environment. Other environments are parsed but not necessarily honored.
    • Correctly distinguish \epsilon ϵ from \varepsilon ε.
    • Added TeX-to-Unicode mappings from Markus Kuhn.
    • Support for \unitfrac.
    • Added \dots: .
  • 0.32 (2009-10-05):
    • Fixed unit processing. Now units appear separated by a space after the number.
    • Repaired use of AlphaCommands. Decorations so defined in the configuration file appear again as a single symbol: .
    • Added option --lyxformat to return the highest LyX format that eLyXer understands. Should help when integrating with lyx2lyx.
    • Improved TOC (table of contents) generation. Modified option --toc to accept an URL, and documented it.
    • Added option --target to add a target frame to every link.
    • Corrected equation numbering error: now all \begin{equation}…\end{equation} formulae are numbered. (Thanks once more, Uwe.)
  • 0.31 (2009-09-27):
    • Modified image parsing code to remove dependency on Python 2.5, expurging os.SEEK_CUR.
    • Removed the ill-fated elyxerconv.py library file (but kept io/convert.py), see lyx-devel thread. Now the file elyxer.py itself can be installed as a library, and run as a module with python -m.; see also lyx-devel thread.
    • eLyXer was added to the Python Package Index (PyPI) starting with 0.30. Now it should be automatically registered for each release.
    • Updated documentation (user guide, README file) with details of distutils installation.
    • Modified single string Containers (StringContainer, Constant) so that they appear as empty Containers — should speed up postprocessing.
    • Solved bug when parsing BibTeX files with incorrect lines.
    • Modified postprocessing to correctly process lists within tables.
    • In the process refactored postprocessing completely: now instead of unconditional postprocessor stages, each stage can add a postprocessing hook. Should be faster — but is indeed a bit slower.
  • 0.30 (2009-09-13):
    • Removed most comments from the final distributed file elyxer.py.
    • Added distutils support for cross-platform distribution. The library elyxerconv is added to local Python libraries.
    • Added command line option --forceformat: force eLyXer to convert all images to the given output format.
    • Switched all options in command line help to quotes: --title <title> is now --title "title".
    • Solved bug reported by Uwe Stöhr when reading Windows BibTeX file generated by JabRef. Now eLyXer tries several encodings for each file, initially UTF-8 and Cp1252.
    • Another bug, also reported by Uwe Stöhr, in branch selection. Added test branches.lyx.
  • 0.29 (2009-09-08):
    • Preliminary support for BibTeX. Configurable output styles (albeit cumbersome and quite primitive).
    • Added new cite commands citep, citet, citealt; and reference command prettyref.
    • A couple of new math commands: \ldots, \qquad.
  • 0.28 (2009-09-05):
    • Various fixes related to Windows integration.
    • Documented integration with LyX in the user guide.
  • 0.27 (2009-06-17):
    • Units without the magnitude (the number) are working.
    • Complex roots now working, added to the math showcase.
    • Leave JPEG images untransformed instead of converting them to PNG (or at least transform them to JPEG). Read JPEG image sizes.
    • More flexible configuration options for lists of values.
    • Added --destdirectory option to convert images into.
    • Image conversion from a different directory (or even with absolute paths) should work now.
    • Changed the whole infrastructure for formulae parsing. More structured parsing should now be possible, e.g. square brackets are first-class citizens.
    • Implemented nice fractions: 78.
    • Redid basic typography: default font is now sans-serif, which looks better on your average browser. Formulae have a bit more space around.
    • Imported the complete symbol list from the unicodesymbols file in LyX.
  • 0.26 (2009-06-10):
    • Added a lot of new LaTeX commands, both for Unicode symbols and for math functions.
    • New mechanism to include new lists of “command:Unicode” equivalents.
    • New decoration command \overrightarrow, to show a long arrow above some text.
    • Solved bug: --directory option was not working. A new test for this option added.
  • 0.25 (2009-06-08):
    • Added new characters: German dash separator, a few arrows, horizontal ellipsis.
    • Automatic insertion of release date in the changelog upon version release.
    • New formula commands: phantom text (for spacing), mbox (literal text).
    • Solved two bugs in URLs: make FlexURLs point to the link in their contents, and do not show “mailto:” in email links.
    • Properly display Date layouts as <h2>.
    • Display a FATAL error (and terminate) when trying to read beyond the end of the document.
    • Cross-platform support for newlines. Besides the Unix \n, now supports Windows (\r\n) and Mac OS X (\r) newlines.
    • Support for \unit command, showing units for a magnitude.
    • New format for formulae (instead of $…$ or \[…\]): \command{…}.
  • 0.24 (2009-06-02):
    • Show sum and integral limits correctly in Konqueror, Safari and Chrome.
    • Also show roots and arrays correctly in those browsers. Larger radical symbol looks better.
    • Added Math Showcase to test on browsershots.org.
    • Substituted medium mathematical spaces with midspaces for better browser compatibility.
    • Added --unicode option to switch on full Unicode output; right now only re-adds medium mathematical spaces.
    • Included all Greek letters, upper and lower case; and common math symbols.
    • Make title from command line option prevail over PDF title.
    • Specified minimum browser versions in the user guide and in the requirements.
    • Documented option --directory (it existed already but was not in the docs).
    • Option --toc can generate a Table Of Contents. Not documented because it is only a start for bigger things.
    • Repaired configuration export to base.cfg: now all objects in config.py are automatically exported.
  • 0.23 (2009-05-24):
    • Corrected numbering and appearance of subfloats.
    • Plain layouts are not reflected in HTML output.
    • Unified table parsing, moved table starts to configuration file.
    • Use unicode output in debug and error messages.
    • Automated testing now shows unified diff, to show the file that doesn’t pass the tests.
    • Finally got UTF-8 output right (hopefully).
    • Display floats with tables properly aligned, and on a white background. Listings are working too.
    • Show warning when document is created with LyX 1.4.x.
    • Transform \newpage to an empty paragraph.
    • Standard layouts can be <div> or nothing at all, generating valid XHTML.
    • Added nomenclature commands for 1.5.x.
    • Got Index and nomenclature working again, added test file so they don’t break anymore.
  • 0.22 (2009-05-15):
    • Modified user guide to explain --html option.
    • Solved a few bugs manifested when exporting to HTML 4.0 with --html.
    • More configurable containers: quote types, barred text, boxes, info insets…
    • Added note on the main page about slow mirrors and latest versions.
    • Standard layouts can now be translated to <div> or to <span>, depending on the context.
    • Command endings can be deduced from starts in configuration file.
    • A bunch of new math symbols: nu, angle brackets.
    • Generalized big brackets of several types. Consolidated parameter parsing in formulas.
    • Equation numbering is working.
    • Unknown commands are shown in red: \unknown.
  • 0.21 (2009-05-11):
    • Command line option --html to export to HTML 4.0.
    • Container endings are now configurable from the main config file.
    • Styles can be mixed and matched at will (like typewriter bold in blue).
    • All constant strings (such as “Table of contents”) should now be configurable.
    • Added a few more colors: green, magenta, cyan, yellow, white (those two were yellow and white).
  • 0.20 (2009-05-09):
    • Command line option --version to show the current version number and date.
    • Release date is now automatically added to the configuration.
    • Preliminary support for inset boxes.
    • Support for numbered listings.
    • Added <meta> tag for Content-Type, to ease importing into word processors.
    • Automated version generation, taking version number and date from config, and updating current version in the main page.
  • 0.19 (2009-05-07):
    • More powerful configuration file manipulation: export to generic config and Python files.
    • Start lines for every parsed structure can now be configured in the global base.cfg file.
    • New Info types package and textclass.
    • New formula symbols: up and down arrows, long double arrows, Gamma and Upsilon, mu, backslash.
    • Show line number and current line for generic errors.
    • Listings and document abstracts are displayed properly.
  • 0.18 (2009-05-04):
    • Wrap floats are separated by a bit of space (two exes, actually) from the text.
    • Solved bug when running without any arguments.
    • Main executable file is now changed from elyxer to elyxer.py, to prevent problems on platforms that require the extension; main source file has changed from elyxer.py to principal.py, to avoid confusion.
    • Moved all parsing code to the new package parse, and configuration files to package conf.
    • All configuration is now read from (and written to) plain text files.
  • 0.17 (2009-04-27):
    • Alignment of table cells is now respected, both horizontally and vertically.
    • Wrap floats are actually floated left or right.
    • Correctly interpret symbols in formulae: !, ;,  ≤ ,  ≥ ,  ≠ ,   ∈ , , and a few spaces.
    • In formulae, \displaystyle and friends are ignored.
    • Square roots are again displayed correctly, and even better than before!
    • Cases are working (not perfect: with a bar instead of a bracket, but working).
  • 0.16 (2009-04-22):
    • Document date is shown centered.
    • Special rows in a longtable are properly ignored.
    • Multicolumn cells are properly interpreted.
    • Sums and integral limits are properly displayed with respect to the symbol: i = 1.
  • 0.15 (2009-04-19):
    • Info insets (containing shortcuts) are now interpreted and shown.
    • LyX-Code is interpreted as a <pre> tag.
    • Reorganized code into a few packages.
    • Line numbers are not shown for utility classes.
    • Floats (figures, tables and algorithms) are now numbered.
    • Float links point to the start of the table or figure, not to the caption.
  • 0.14 (2009-04-13):
    • Deeper layouts (of any kind, not just in lists) are now supported.
    • Appendices are numbered correctly (as A, B, C…).
    • Sections in deeper layouts are numbered correctly too.
    • Double dash does not catch Unix-style options: --css is not converted -- while the version with spaces is.
    • Corrected serious bug in formula parsing affecting inline arrays.
    • Arrays with vertical alignment are correctly parsed.
  • 0.13 (2009-04-12):
    • Lists are correctly displayed, instead of one list per item.
    • Lists can contain nested layouts.
    • List layouts (not to mistake with Enumerate or Itemize lists) are processed correctly.
    • Changelog moved to separate document.
    • Read image sizes correctly on big-endian architectures (e.g. Mac OS X on PowerPC).
    • Numeration of chapters, sections… is working.
    • Error messages now show the line where they happen.
  • 0.12 (2009-04-05):
    • Arrays are parsed correctly and displayed acceptably.
    • Numbers and units are correctly separated.
    • Text decorations (such as ) are shown in line.
    • Variables are italicized.
    • Notes and comments are not output at all, greyed-out notes are shown in grey.
    • LyX guides parse completely.
  • 0.11 (2009-03-27):
    • Arrays are at least well parsed (but still show wrong).
    • Integrals and sums appear as large characters.
    • Appendices are separated from the main document.
    • The bibliography appears separated with a title.
    • Floats appear centered on-screen.
  • 0.10 (2009-03-23):
    • Better handling of footnotes and margin notes: not overlapping and with a reference in the text.
    • Better parsing of first word in a Description.
    • Short titles are ignored.
    • Added a few font families for equations. Not that they display too well…
  • 0.9 (2009-03-21):
    • Better formula parsing (including line breaks). Supports a few math fonts.
    • Supports menu separator, text with bar, nomenclature and many more quote types.
    • Single configuration file general.py.
    • Layout of type Space is not shown.
    • Supports branches. Inactive branches are not shown.
    • New symbols: greek letters, shapes: bullet, right triangle.
    • Added support for new style (1.6.x) index entries.
    • From LyX documentation: UserGuide.lyx is now working (except for some math functions).
  • 0.8 (2009-03-20):
    • Can be run from other directories than the one with the document.
    • Tables have light grey separations. Table spacing is now better adjusted.
    • Descriptions appear with the first word in bold), but only within the first text style. Changing style in the middle of a word may distract the algorithm.
    • Added support for Lyx notes (not rendered in the HTML), margin notes, pretty quotes ‘’, weird spaces.
    • Added support for new style (1.6.x) hyperlinks, labels and references, TOC, index.
    • Uses PDF title if present.
    • From LyX documentation: Intro.lyx is now working.
  • 0.7 (2009-03-16):
    • Images referenced by absolute path are converted to relative PNGs.
    • Range of supported quotes is greater. Unknown quotes are now marked as errors but do not make the tool fail.
    • Default CSS is always on nongnu.org, it can be changed via command line option --css.
    • Reinstated layout classes for unknown types.
    • Updated documentation to include how to run on Windows.
    • Added meta generator tag to all pages.
    • Added option --title to change the default page title.
    • Phonetic symbols appear in dark cyan: [sample].
    • Lots of small fixes and improvements to correctly parse the official LyX guides (UserGuide.lyx, EmbeddedObjects.lyx and Math.lyx).
  • 0.6 (2009-03-15):
    • Added Flex URLs, Flex code.
    • Works with Python 2.3.5, but not yet Mac OS X terminal.
    • Alignment now works right (and center and left).
    • Modified license files to comply with Savannah policies.
    • Added index page and logo.
  • 0.5 (2009-03-14):
    • Inset parameters are all parsed correctly (including spaces in image paths).
    • Formulae and tables should work again (including complex formatting).
    • Modified to (mostly) run under Python 2.3.5 (Mac OS X Tiger).
    • Processes layouts ending in ‘*’ (like ‘Section*’).
    • Runtime options for help and to disable the copyright notice, debug, quietness.
    • Accepts scaling for images.
    • Nested lists working.
  • 0.4 (2009-03-12):
    • When images do not exist warns but does not fail.
    • Author and title containing tags are properly processed.
    • Slanted text translated to italics.
    • Title no longer necessary to have a working document.
    • ERT is ignored. Status line (open/collapsed) is ignored.
    • Supports footnotes, newlines, bibitem entries and citations.
    • Dev guide includes a Container tutorial.
  • 0.3 (2009-03-11): Now works with generic Insets.
  • 0.2 (2009-03-11): ImageMagick is not required anymore.
  • 0.1 (2009-03-10): first public version.
elyxer-1.2.5/elyxer.py0000755000175000017500000116206512117174753014245 0ustar chennochenno#! /usr/bin/env python # -*- coding: utf-8 -*- # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # --end-- # Alex 20090308 # eLyXer main script # http://www.nongnu.org/elyxer/ import sys import os.path import sys import codecs import sys class Trace(object): "A tracing class" debugmode = False quietmode = False showlinesmode = False prefix = None def debug(cls, message): "Show a debug message" if not Trace.debugmode or Trace.quietmode: return Trace.show(message, sys.stdout) def message(cls, message): "Show a trace message" if Trace.quietmode: return if Trace.prefix and Trace.showlinesmode: message = Trace.prefix + message Trace.show(message, sys.stdout) def error(cls, message): "Show an error message" message = '* ' + message if Trace.prefix and Trace.showlinesmode: message = Trace.prefix + message Trace.show(message, sys.stderr) def fatal(cls, message): "Show an error message and terminate" Trace.error('FATAL: ' + message) exit(-1) def show(cls, message, channel): "Show a message out of a channel" if sys.version_info < (3,0): message = message.encode('utf-8') channel.write(message + '\n') debug = classmethod(debug) message = classmethod(message) error = classmethod(error) fatal = classmethod(fatal) show = classmethod(show) class LineReader(object): "Reads a file line by line" def __init__(self, filename): if isinstance(filename, file): self.file = filename else: self.file = codecs.open(filename, 'rU', 'utf-8') self.linenumber = 1 self.lastline = None self.current = None self.mustread = True self.depleted = False try: self.readline() except UnicodeDecodeError: # try compressed file import gzip self.file = gzip.open(filename, 'rb') self.readline() def setstart(self, firstline): "Set the first line to read." for i in range(firstline): self.file.readline() self.linenumber = firstline def setend(self, lastline): "Set the last line to read." self.lastline = lastline def currentline(self): "Get the current line" if self.mustread: self.readline() return self.current def nextline(self): "Go to next line" if self.depleted: Trace.fatal('Read beyond file end') self.mustread = True def readline(self): "Read a line from elyxer.file" self.current = self.file.readline() if not isinstance(self.file, codecs.StreamReaderWriter): self.current = self.current.decode('utf-8') if len(self.current) == 0: self.depleted = True self.current = self.current.rstrip('\n\r') self.linenumber += 1 self.mustread = False Trace.prefix = 'Line ' + unicode(self.linenumber) + ': ' if self.linenumber % 1000 == 0: Trace.message('Parsing') def finished(self): "Find out if the file is finished" if self.lastline and self.linenumber == self.lastline: return True if self.mustread: self.readline() return self.depleted def close(self): self.file.close() class LineWriter(object): "Writes a file as a series of lists" file = False def __init__(self, filename): if isinstance(filename, file): self.file = filename self.filename = None else: self.filename = filename def write(self, strings): "Write a list of strings" for string in strings: if not isinstance(string, basestring): Trace.error('Not a string: ' + unicode(string) + ' in ' + unicode(strings)) return self.writestring(string) def writestring(self, string): "Write a string" if not self.file: self.file = codecs.open(self.filename, 'w', "utf-8") if self.file == sys.stdout and sys.version_info < (3,0): string = string.encode('utf-8') self.file.write(string) def writeline(self, line): "Write a line to file" self.writestring(line + '\n') def close(self): self.file.close() import os.path import sys class BibStylesConfig(object): "Configuration class from elyxer.config file" abbrvnat = { u'@article':u'$authors. $title. $journal,{ {$volume:}$pages,} $month $year.{ doi: $doi.}{ URL $url.}{ $note.}', u'cite':u'$surname($year)', u'default':u'$authors. $title. $publisher, $year.{ URL $url.}{ $note.}', } alpha = { u'@article':u'$authors. $title.{ $journal{, {$volume}{($number)}}{: $pages}{, $year}.}{ $url.}{ $filename.}{ $note.}', u'cite':u'$Sur$YY', u'default':u'$authors. $title.{ $journal,} $year.{ $url.}{ $filename.}{ $note.}', } authordate2 = { u'@article':u'$authors. $year. $title. $journal, $volume($number), $pages.{ URL $url.}{ $note.}', u'@book':u'$authors. $year. $title. $publisher.{ URL $url.}{ $note.}', u'cite':u'$surname, $year', u'default':u'$authors. $year. $title. $publisher.{ URL $url.}{ $note.}', } default = { u'@article':u'$authors: “$title”, $journal,{ pp. $pages,} $year.{ URL $url.}{ $note.}', u'@book':u'{$authors: }$title{ ($editor, ed.)}.{{ $publisher,} $year.}{ URL $url.}{ $note.}', u'@booklet':u'$authors: $title.{{ $publisher,} $year.}{ URL $url.}{ $note.}', u'@conference':u'$authors: “$title”, $journal,{ pp. $pages,} $year.{ URL $url.}{ $note.}', u'@inbook':u'$authors: $title.{{ $publisher,} $year.}{ URL $url.}{ $note.}', u'@incollection':u'$authors: $title{ in $booktitle{ ($editor, ed.)}}.{{ $publisher,} $year.}{ URL $url.}{ $note.}', u'@inproceedings':u'$authors: “$title”, $booktitle,{ pp. $pages,} $year.{ URL $url.}{ $note.}', u'@manual':u'$authors: $title.{{ $publisher,} $year.}{ URL $url.}{ $note.}', u'@mastersthesis':u'$authors: $title.{{ $publisher,} $year.}{ URL $url.}{ $note.}', u'@misc':u'$authors: $title.{{ $publisher,}{ $howpublished,} $year.}{ URL $url.}{ $note.}', u'@phdthesis':u'$authors: $title.{{ $publisher,} $year.}{ URL $url.}{ $note.}', u'@proceedings':u'$authors: “$title”, $journal,{ pp. $pages,} $year.{ URL $url.}{ $note.}', u'@techreport':u'$authors: $title, $year.{ URL $url.}{ $note.}', u'@unpublished':u'$authors: “$title”, $journal, $year.{ URL $url.}{ $note.}', u'cite':u'$index', u'default':u'$authors: $title.{{ $publisher,} $year.}{ URL $url.}{ $note.}', } defaulttags = { u'YY':u'??', u'authors':u'', u'surname':u'', } ieeetr = { u'@article':u'$authors, “$title”, $journal, vol. $volume, no. $number, pp. $pages, $year.{ URL $url.}{ $note.}', u'@book':u'$authors, $title. $publisher, $year.{ URL $url.}{ $note.}', u'cite':u'$index', u'default':u'$authors, “$title”. $year.{ URL $url.}{ $note.}', } plain = { u'@article':u'$authors. $title.{ $journal{, {$volume}{($number)}}{:$pages}{, $year}.}{ URL $url.}{ $note.}', u'@book':u'$authors. $title. $publisher,{ $month} $year.{ URL $url.}{ $note.}', u'@incollection':u'$authors. $title.{ In $booktitle {($editor, ed.)}.} $publisher,{ $month} $year.{ URL $url.}{ $note.}', u'@inproceedings':u'$authors. $title. { $booktitle{, {$volume}{($number)}}{:$pages}{, $year}.}{ URL $url.}{ $note.}', u'cite':u'$index', u'default':u'{$authors. }$title.{{ $publisher,} $year.}{ URL $url.}{ $note.}', } vancouver = { u'@article':u'$authors. $title. $journal, $year{;{$volume}{($number)}{:$pages}}.{ URL: $url.}{ $note.}', u'@book':u'$authors. $title. {$publisher, }$year.{ URL: $url.}{ $note.}', u'cite':u'$index', u'default':u'$authors. $title; {$publisher, }$year.{ $howpublished.}{ URL: $url.}{ $note.}', } class BibTeXConfig(object): "Configuration class from elyxer.config file" replaced = { u'--':u'—', u'..':u'.', } class ContainerConfig(object): "Configuration class from elyxer.config file" endings = { u'Align':u'\\end_layout', u'BarredText':u'\\bar', u'BoldText':u'\\series', u'Cell':u'':u'>', } html = { u'/>':u'>', } iso885915 = { u' ':u' ', u' ':u' ', u' ':u' ', } nonunicode = { u' ':u' ', } class FormulaConfig(object): "Configuration class from elyxer.config file" alphacommands = { u'\\AA':u'Å', u'\\AE':u'Æ', u'\\AmS':u'AmS', u'\\Angstroem':u'Å', u'\\DH':u'Ð', u'\\Koppa':u'Ϟ', u'\\L':u'Ł', u'\\Micro':u'µ', u'\\O':u'Ø', u'\\OE':u'Œ', u'\\Sampi':u'Ϡ', u'\\Stigma':u'Ϛ', u'\\TH':u'Þ', u'\\aa':u'å', u'\\ae':u'æ', u'\\alpha':u'α', u'\\beta':u'β', u'\\delta':u'δ', u'\\dh':u'ð', u'\\digamma':u'ϝ', u'\\epsilon':u'ϵ', u'\\eta':u'η', u'\\eth':u'ð', u'\\gamma':u'γ', u'\\i':u'ı', u'\\imath':u'ı', u'\\iota':u'ι', u'\\j':u'ȷ', u'\\jmath':u'ȷ', u'\\kappa':u'κ', u'\\koppa':u'ϟ', u'\\l':u'ł', u'\\lambda':u'λ', u'\\mu':u'μ', u'\\nu':u'ν', u'\\o':u'ø', u'\\oe':u'œ', u'\\omega':u'ω', u'\\phi':u'φ', u'\\pi':u'π', u'\\psi':u'ψ', u'\\rho':u'ρ', u'\\sampi':u'ϡ', u'\\sigma':u'σ', u'\\ss':u'ß', u'\\stigma':u'ϛ', u'\\tau':u'τ', u'\\tcohm':u'Ω', u'\\textcrh':u'ħ', u'\\th':u'þ', u'\\theta':u'θ', u'\\upsilon':u'υ', u'\\varDelta':u'∆', u'\\varGamma':u'Γ', u'\\varLambda':u'Λ', u'\\varOmega':u'Ω', u'\\varPhi':u'Φ', u'\\varPi':u'Π', u'\\varPsi':u'Ψ', u'\\varSigma':u'Σ', u'\\varTheta':u'Θ', u'\\varUpsilon':u'Υ', u'\\varXi':u'Ξ', u'\\varbeta':u'ϐ', u'\\varepsilon':u'ε', u'\\varkappa':u'ϰ', u'\\varphi':u'φ', u'\\varpi':u'ϖ', u'\\varrho':u'ϱ', u'\\varsigma':u'ς', u'\\vartheta':u'ϑ', u'\\xi':u'ξ', u'\\zeta':u'ζ', } array = { u'begin':u'\\begin', u'cellseparator':u'&', u'end':u'\\end', u'rowseparator':u'\\\\', } bigbrackets = { u'(':[u'⎛',u'⎜',u'⎝',], u')':[u'⎞',u'⎟',u'⎠',], u'[':[u'⎡',u'⎢',u'⎣',], u']':[u'⎤',u'⎥',u'⎦',], u'{':[u'⎧',u'⎪',u'⎨',u'⎩',], u'|':[u'|',], u'}':[u'⎫',u'⎪',u'⎬',u'⎭',], u'∥':[u'∥',], } bigsymbols = { u'∑':[u'⎲',u'⎳',], u'∫':[u'⌠',u'⌡',], } bracketcommands = { u'\\left':u'span class="symbol"', u'\\left.':u'', u'\\middle':u'span class="symbol"', u'\\right':u'span class="symbol"', u'\\right.':u'', } combiningfunctions = { u'\\"':u'̈', u'\\\'':u'́', u'\\^':u'̂', u'\\`':u'̀', u'\\acute':u'́', u'\\bar':u'̄', u'\\breve':u'̆', u'\\c':u'̧', u'\\check':u'̌', u'\\dddot':u'⃛', u'\\ddot':u'̈', u'\\dot':u'̇', u'\\grave':u'̀', u'\\hat':u'̂', u'\\mathring':u'̊', u'\\overleftarrow':u'⃖', u'\\overrightarrow':u'⃗', u'\\r':u'̊', u'\\s':u'̩', u'\\textcircled':u'⃝', u'\\textsubring':u'̥', u'\\tilde':u'̃', u'\\v':u'̌', u'\\vec':u'⃗', u'\\~':u'̃', } commands = { u'\\ ':u' ', u'\\!':u'', u'\\#':u'#', u'\\$':u'$', u'\\%':u'%', u'\\&':u'&', u'\\,':u' ', u'\\:':u' ', u'\\;':u' ', u'\\AC':u'∿', u'\\APLcomment':u'⍝', u'\\APLdownarrowbox':u'⍗', u'\\APLinput':u'⍞', u'\\APLinv':u'⌹', u'\\APLleftarrowbox':u'⍇', u'\\APLlog':u'⍟', u'\\APLrightarrowbox':u'⍈', u'\\APLuparrowbox':u'⍐', u'\\Box':u'□', u'\\Bumpeq':u'≎', u'\\CIRCLE':u'●', u'\\Cap':u'⋒', u'\\CapitalDifferentialD':u'ⅅ', u'\\CheckedBox':u'☑', u'\\Circle':u'○', u'\\Coloneqq':u'⩴', u'\\ComplexI':u'ⅈ', u'\\ComplexJ':u'ⅉ', u'\\Corresponds':u'≙', u'\\Cup':u'⋓', u'\\Delta':u'Δ', u'\\Diamond':u'◇', u'\\Diamondblack':u'◆', u'\\Diamonddot':u'⟐', u'\\DifferentialD':u'ⅆ', u'\\Downarrow':u'⇓', u'\\EUR':u'€', u'\\Euler':u'ℇ', u'\\ExponetialE':u'ⅇ', u'\\Finv':u'Ⅎ', u'\\Game':u'⅁', u'\\Gamma':u'Γ', u'\\Im':u'ℑ', u'\\Join':u'⨝', u'\\LEFTCIRCLE':u'◖', u'\\LEFTcircle':u'◐', u'\\LHD':u'◀', u'\\Lambda':u'Λ', u'\\Lbag':u'⟅', u'\\Leftarrow':u'⇐', u'\\Lleftarrow':u'⇚', u'\\Longleftarrow':u'⟸', u'\\Longleftrightarrow':u'⟺', u'\\Longrightarrow':u'⟹', u'\\Lparen':u'⦅', u'\\Lsh':u'↰', u'\\Mapsfrom':u'⇐|', u'\\Mapsto':u'|⇒', u'\\Omega':u'Ω', u'\\P':u'¶', u'\\Phi':u'Φ', u'\\Pi':u'Π', u'\\Pr':u'Pr', u'\\Psi':u'Ψ', u'\\Qoppa':u'Ϙ', u'\\RHD':u'▶', u'\\RIGHTCIRCLE':u'◗', u'\\RIGHTcircle':u'◑', u'\\Rbag':u'⟆', u'\\Re':u'ℜ', u'\\Rparen':u'⦆', u'\\Rrightarrow':u'⇛', u'\\Rsh':u'↱', u'\\S':u'§', u'\\Sigma':u'Σ', u'\\Square':u'☐', u'\\Subset':u'⋐', u'\\Sun':u'☉', u'\\Supset':u'⋑', u'\\Theta':u'Θ', u'\\Uparrow':u'⇑', u'\\Updownarrow':u'⇕', u'\\Upsilon':u'Υ', u'\\Vdash':u'⊩', u'\\Vert':u'∥', u'\\Vvdash':u'⊪', u'\\XBox':u'☒', u'\\Xi':u'Ξ', u'\\Yup':u'⅄', u'\\\\':u'
', u'\\_':u'_', u'\\aleph':u'ℵ', u'\\amalg':u'∐', u'\\anchor':u'⚓', u'\\angle':u'∠', u'\\aquarius':u'♒', u'\\arccos':u'arccos', u'\\arcsin':u'arcsin', u'\\arctan':u'arctan', u'\\arg':u'arg', u'\\aries':u'♈', u'\\arrowbullet':u'➢', u'\\ast':u'∗', u'\\asymp':u'≍', u'\\backepsilon':u'∍', u'\\backprime':u'‵', u'\\backsimeq':u'⋍', u'\\backslash':u'\\', u'\\ballotx':u'✗', u'\\barwedge':u'⊼', u'\\because':u'∵', u'\\beth':u'ℶ', u'\\between':u'≬', u'\\bigcap':u'∩', u'\\bigcirc':u'○', u'\\bigcup':u'∪', u'\\bigodot':u'⊙', u'\\bigoplus':u'⊕', u'\\bigotimes':u'⊗', u'\\bigsqcup':u'⊔', u'\\bigstar':u'★', u'\\bigtriangledown':u'▽', u'\\bigtriangleup':u'△', u'\\biguplus':u'⊎', u'\\bigvee':u'∨', u'\\bigwedge':u'∧', u'\\biohazard':u'☣', u'\\blacklozenge':u'⧫', u'\\blacksmiley':u'☻', u'\\blacksquare':u'■', u'\\blacktriangle':u'▲', u'\\blacktriangledown':u'▼', u'\\blacktriangleleft':u'◂', u'\\blacktriangleright':u'▶', u'\\blacktriangleup':u'▴', u'\\bot':u'⊥', u'\\bowtie':u'⋈', u'\\box':u'▫', u'\\boxast':u'⧆', u'\\boxbar':u'◫', u'\\boxbox':u'⧈', u'\\boxbslash':u'⧅', u'\\boxcircle':u'⧇', u'\\boxdot':u'⊡', u'\\boxminus':u'⊟', u'\\boxplus':u'⊞', u'\\boxslash':u'⧄', u'\\boxtimes':u'⊠', u'\\bullet':u'•', u'\\bumpeq':u'≏', u'\\cancer':u'♋', u'\\cap':u'∩', u'\\capricornus':u'♑', u'\\cat':u'⁀', u'\\cdot':u'⋅', u'\\cdots':u'⋯', u'\\cent':u'¢', u'\\centerdot':u'∙', u'\\checkmark':u'✓', u'\\chi':u'χ', u'\\circ':u'○', u'\\circeq':u'≗', u'\\circlearrowleft':u'↺', u'\\circlearrowright':u'↻', u'\\circledR':u'®', u'\\circledast':u'⊛', u'\\circledbslash':u'⦸', u'\\circledcirc':u'⊚', u'\\circleddash':u'⊝', u'\\circledgtr':u'⧁', u'\\circledless':u'⧀', u'\\clubsuit':u'♣', u'\\coloneqq':u'≔', u'\\complement':u'∁', u'\\cong':u'≅', u'\\coprod':u'∐', u'\\copyright':u'©', u'\\cos':u'cos', u'\\cosh':u'cosh', u'\\cot':u'cot', u'\\coth':u'coth', u'\\csc':u'csc', u'\\cup':u'∪', u'\\curlyvee':u'⋎', u'\\curlywedge':u'⋏', u'\\curvearrowleft':u'↶', u'\\curvearrowright':u'↷', u'\\dag':u'†', u'\\dagger':u'†', u'\\daleth':u'ℸ', u'\\dashleftarrow':u'⇠', u'\\dashv':u'⊣', u'\\ddag':u'‡', u'\\ddagger':u'‡', u'\\ddots':u'⋱', u'\\deg':u'deg', u'\\det':u'det', u'\\diagdown':u'╲', u'\\diagup':u'╱', u'\\diameter':u'⌀', u'\\diamond':u'◇', u'\\diamondsuit':u'♦', u'\\dim':u'dim', u'\\div':u'÷', u'\\divideontimes':u'⋇', u'\\dotdiv':u'∸', u'\\doteq':u'≐', u'\\doteqdot':u'≑', u'\\dotplus':u'∔', u'\\dots':u'…', u'\\doublebarwedge':u'⌆', u'\\downarrow':u'↓', u'\\downdownarrows':u'⇊', u'\\downharpoonleft':u'⇃', u'\\downharpoonright':u'⇂', u'\\dsub':u'⩤', u'\\earth':u'♁', u'\\eighthnote':u'♪', u'\\ell':u'ℓ', u'\\emptyset':u'∅', u'\\eqcirc':u'≖', u'\\eqcolon':u'≕', u'\\eqsim':u'≂', u'\\euro':u'€', u'\\exists':u'∃', u'\\exp':u'exp', u'\\fallingdotseq':u'≒', u'\\fcmp':u'⨾', u'\\female':u'♀', u'\\flat':u'♭', u'\\forall':u'∀', u'\\fourth':u'⁗', u'\\frown':u'⌢', u'\\frownie':u'☹', u'\\gcd':u'gcd', u'\\gemini':u'♊', u'\\geq)':u'≥', u'\\geqq':u'≧', u'\\geqslant':u'≥', u'\\gets':u'←', u'\\gg':u'≫', u'\\ggg':u'⋙', u'\\gimel':u'ℷ', u'\\gneqq':u'≩', u'\\gnsim':u'⋧', u'\\gtrdot':u'⋗', u'\\gtreqless':u'⋚', u'\\gtreqqless':u'⪌', u'\\gtrless':u'≷', u'\\gtrsim':u'≳', u'\\guillemotleft':u'«', u'\\guillemotright':u'»', u'\\hbar':u'ℏ', u'\\heartsuit':u'♥', u'\\hfill':u' ', u'\\hom':u'hom', u'\\hookleftarrow':u'↩', u'\\hookrightarrow':u'↪', u'\\hslash':u'ℏ', u'\\idotsint':u'∫⋯∫', u'\\iiint':u'', u'\\iint':u'', u'\\imath':u'ı', u'\\inf':u'inf', u'\\infty':u'∞', u'\\intercal':u'⊺', u'\\interleave':u'⫴', u'\\invamp':u'⅋', u'\\invneg':u'⌐', u'\\jmath':u'ȷ', u'\\jupiter':u'♃', u'\\ker':u'ker', u'\\land':u'∧', u'\\landupint':u'', u'\\lang':u'⟪', u'\\langle':u'⟨', u'\\lblot':u'⦉', u'\\lbrace':u'{', u'\\lbrace)':u'{', u'\\lbrack':u'[', u'\\lceil':u'⌈', u'\\ldots':u'…', u'\\leadsto':u'⇝', u'\\leftarrow)':u'←', u'\\leftarrowtail':u'↢', u'\\leftarrowtobar':u'⇤', u'\\leftharpoondown':u'↽', u'\\leftharpoonup':u'↼', u'\\leftleftarrows':u'⇇', u'\\leftleftharpoons':u'⥢', u'\\leftmoon':u'☾', u'\\leftrightarrow':u'↔', u'\\leftrightarrows':u'⇆', u'\\leftrightharpoons':u'⇋', u'\\leftthreetimes':u'⋋', u'\\leo':u'♌', u'\\leq)':u'≤', u'\\leqq':u'≦', u'\\leqslant':u'≤', u'\\lessdot':u'⋖', u'\\lesseqgtr':u'⋛', u'\\lesseqqgtr':u'⪋', u'\\lessgtr':u'≶', u'\\lesssim':u'≲', u'\\lfloor':u'⌊', u'\\lg':u'lg', u'\\lgroup':u'⟮', u'\\lhd':u'⊲', u'\\libra':u'♎', u'\\lightning':u'↯', u'\\limg':u'⦇', u'\\liminf':u'liminf', u'\\limsup':u'limsup', u'\\ll':u'≪', u'\\llbracket':u'⟦', u'\\llcorner':u'⌞', u'\\lll':u'⋘', u'\\ln':u'ln', u'\\lneqq':u'≨', u'\\lnot':u'¬', u'\\lnsim':u'⋦', u'\\log':u'log', u'\\longleftarrow':u'⟵', u'\\longleftrightarrow':u'⟷', u'\\longmapsto':u'⟼', u'\\longrightarrow':u'⟶', u'\\looparrowleft':u'↫', u'\\looparrowright':u'↬', u'\\lor':u'∨', u'\\lozenge':u'◊', u'\\lrcorner':u'⌟', u'\\ltimes':u'⋉', u'\\lyxlock':u'', u'\\male':u'♂', u'\\maltese':u'✠', u'\\mapsfrom':u'↤', u'\\mapsto':u'↦', u'\\mathcircumflex':u'^', u'\\max':u'max', u'\\measuredangle':u'∡', u'\\medbullet':u'⚫', u'\\medcirc':u'⚪', u'\\mercury':u'☿', u'\\mho':u'℧', u'\\mid':u'∣', u'\\min':u'min', u'\\models':u'⊨', u'\\mp':u'∓', u'\\multimap':u'⊸', u'\\nLeftarrow':u'⇍', u'\\nLeftrightarrow':u'⇎', u'\\nRightarrow':u'⇏', u'\\nVDash':u'⊯', u'\\nabla':u'∇', u'\\napprox':u'≉', u'\\natural':u'♮', u'\\ncong':u'≇', u'\\nearrow':u'↗', u'\\neg':u'¬', u'\\neg)':u'¬', u'\\neptune':u'♆', u'\\nequiv':u'≢', u'\\newline':u'
', u'\\nexists':u'∄', u'\\ngeqslant':u'≱', u'\\ngtr':u'≯', u'\\ngtrless':u'≹', u'\\ni':u'∋', u'\\ni)':u'∋', u'\\nleftarrow':u'↚', u'\\nleftrightarrow':u'↮', u'\\nleqslant':u'≰', u'\\nless':u'≮', u'\\nlessgtr':u'≸', u'\\nmid':u'∤', u'\\nolimits':u'', u'\\nonumber':u'', u'\\not':u'¬', u'\\not<':u'≮', u'\\not=':u'≠', u'\\not>':u'≯', u'\\notbackslash':u'⍀', u'\\notin':u'∉', u'\\notni':u'∌', u'\\notslash':u'⌿', u'\\nparallel':u'∦', u'\\nprec':u'⊀', u'\\nrightarrow':u'↛', u'\\nsim':u'≁', u'\\nsimeq':u'≄', u'\\nsqsubset':u'⊏̸', u'\\nsubseteq':u'⊈', u'\\nsucc':u'⊁', u'\\nsucccurlyeq':u'⋡', u'\\nsupset':u'⊅', u'\\nsupseteq':u'⊉', u'\\ntriangleleft':u'⋪', u'\\ntrianglelefteq':u'⋬', u'\\ntriangleright':u'⋫', u'\\ntrianglerighteq':u'⋭', u'\\nvDash':u'⊭', u'\\nvdash':u'⊬', u'\\nwarrow':u'↖', u'\\odot':u'⊙', u'\\officialeuro':u'€', u'\\oiiint':u'', u'\\oiint':u'', u'\\oint':u'', u'\\ointclockwise':u'', u'\\ointctrclockwise':u'', u'\\ominus':u'⊖', u'\\oplus':u'⊕', u'\\oslash':u'⊘', u'\\otimes':u'⊗', u'\\owns':u'∋', u'\\parallel':u'∥', u'\\partial':u'∂', u'\\pencil':u'✎', u'\\perp':u'⊥', u'\\pisces':u'♓', u'\\pitchfork':u'⋔', u'\\pluto':u'♇', u'\\pm':u'±', u'\\pointer':u'➪', u'\\pointright':u'☞', u'\\pounds':u'£', u'\\prec':u'≺', u'\\preccurlyeq':u'≼', u'\\preceq':u'≼', u'\\precsim':u'≾', u'\\prime':u'′', u'\\prompto':u'∝', u'\\qoppa':u'ϙ', u'\\qquad':u' ', u'\\quad':u' ', u'\\quarternote':u'♩', u'\\radiation':u'☢', u'\\rang':u'⟫', u'\\rangle':u'⟩', u'\\rblot':u'⦊', u'\\rbrace':u'}', u'\\rbrace)':u'}', u'\\rbrack':u']', u'\\rceil':u'⌉', u'\\recycle':u'♻', u'\\rfloor':u'⌋', u'\\rgroup':u'⟯', u'\\rhd':u'⊳', u'\\rightangle':u'∟', u'\\rightarrow)':u'→', u'\\rightarrowtail':u'↣', u'\\rightarrowtobar':u'⇥', u'\\rightharpoondown':u'⇁', u'\\rightharpoonup':u'⇀', u'\\rightharpooondown':u'⇁', u'\\rightharpooonup':u'⇀', u'\\rightleftarrows':u'⇄', u'\\rightleftharpoons':u'⇌', u'\\rightmoon':u'☽', u'\\rightrightarrows':u'⇉', u'\\rightrightharpoons':u'⥤', u'\\rightthreetimes':u'⋌', u'\\rimg':u'⦈', u'\\risingdotseq':u'≓', u'\\rrbracket':u'⟧', u'\\rsub':u'⩥', u'\\rtimes':u'⋊', u'\\sagittarius':u'♐', u'\\saturn':u'♄', u'\\scorpio':u'♏', u'\\searrow':u'↘', u'\\sec':u'sec', u'\\second':u'″', u'\\setminus':u'∖', u'\\sharp':u'♯', u'\\simeq':u'≃', u'\\sin':u'sin', u'\\sinh':u'sinh', u'\\sixteenthnote':u'♬', u'\\skull':u'☠', u'\\slash':u'∕', u'\\smallsetminus':u'∖', u'\\smalltriangledown':u'▿', u'\\smalltriangleleft':u'◃', u'\\smalltriangleright':u'▹', u'\\smalltriangleup':u'▵', u'\\smile':u'⌣', u'\\smiley':u'☺', u'\\spadesuit':u'♠', u'\\spddot':u'¨', u'\\sphat':u'', u'\\sphericalangle':u'∢', u'\\spot':u'⦁', u'\\sptilde':u'~', u'\\sqcap':u'⊓', u'\\sqcup':u'⊔', u'\\sqsubset':u'⊏', u'\\sqsubseteq':u'⊑', u'\\sqsupset':u'⊐', u'\\sqsupseteq':u'⊒', u'\\square':u'□', u'\\sslash':u'⫽', u'\\star':u'⋆', u'\\steaming':u'☕', u'\\subseteqq':u'⫅', u'\\subsetneqq':u'⫋', u'\\succ':u'≻', u'\\succcurlyeq':u'≽', u'\\succeq':u'≽', u'\\succnsim':u'⋩', u'\\succsim':u'≿', u'\\sun':u'☼', u'\\sup':u'sup', u'\\supseteqq':u'⫆', u'\\supsetneqq':u'⫌', u'\\surd':u'√', u'\\swarrow':u'↙', u'\\swords':u'⚔', u'\\talloblong':u'⫾', u'\\tan':u'tan', u'\\tanh':u'tanh', u'\\taurus':u'♉', u'\\textasciicircum':u'^', u'\\textasciitilde':u'~', u'\\textbackslash':u'\\', u'\\textcopyright':u'©\'', u'\\textdegree':u'°', u'\\textellipsis':u'…', u'\\textemdash':u'—', u'\\textendash':u'—', u'\\texteuro':u'€', u'\\textgreater':u'>', u'\\textless':u'<', u'\\textordfeminine':u'ª', u'\\textordmasculine':u'º', u'\\textquotedblleft':u'“', u'\\textquotedblright':u'”', u'\\textquoteright':u'’', u'\\textregistered':u'®', u'\\textrightarrow':u'→', u'\\textsection':u'§', u'\\texttrademark':u'™', u'\\texttwosuperior':u'²', u'\\textvisiblespace':u' ', u'\\therefore':u'∴', u'\\third':u'‴', u'\\top':u'⊤', u'\\triangle':u'△', u'\\triangleleft':u'⊲', u'\\trianglelefteq':u'⊴', u'\\triangleq':u'≜', u'\\triangleright':u'▷', u'\\trianglerighteq':u'⊵', u'\\twoheadleftarrow':u'↞', u'\\twoheadrightarrow':u'↠', u'\\twonotes':u'♫', u'\\udot':u'⊍', u'\\ulcorner':u'⌜', u'\\unlhd':u'⊴', u'\\unrhd':u'⊵', u'\\unrhl':u'⊵', u'\\uparrow':u'↑', u'\\updownarrow':u'↕', u'\\upharpoonleft':u'↿', u'\\upharpoonright':u'↾', u'\\uplus':u'⊎', u'\\upuparrows':u'⇈', u'\\uranus':u'♅', u'\\urcorner':u'⌝', u'\\vDash':u'⊨', u'\\varclubsuit':u'♧', u'\\vardiamondsuit':u'♦', u'\\varheartsuit':u'♥', u'\\varnothing':u'∅', u'\\varspadesuit':u'♤', u'\\vdash':u'⊢', u'\\vdots':u'⋮', u'\\vee':u'∨', u'\\vee)':u'∨', u'\\veebar':u'⊻', u'\\vert':u'∣', u'\\virgo':u'♍', u'\\warning':u'⚠', u'\\wasylozenge':u'⌑', u'\\wedge':u'∧', u'\\wedge)':u'∧', u'\\wp':u'℘', u'\\wr':u'≀', u'\\yen':u'¥', u'\\yinyang':u'☯', u'\\{':u'{', u'\\|':u'∥', u'\\}':u'}', } decoratedcommand = { } decoratingfunctions = { u'\\overleftarrow':u'⟵', u'\\overrightarrow':u'⟶', u'\\widehat':u'^', } endings = { u'bracket':u'}', u'complex':u'\\]', u'endafter':u'}', u'endbefore':u'\\end{', u'squarebracket':u']', } environments = { u'align':[u'r',u'l',], u'eqnarray':[u'r',u'c',u'l',], u'gathered':[u'l',u'l',], } fontfunctions = { u'\\boldsymbol':u'b', u'\\mathbb':u'span class="blackboard"', u'\\mathbb{A}':u'𝔸', u'\\mathbb{B}':u'𝔹', u'\\mathbb{C}':u'ℂ', u'\\mathbb{D}':u'𝔻', u'\\mathbb{E}':u'𝔼', u'\\mathbb{F}':u'𝔽', u'\\mathbb{G}':u'𝔾', u'\\mathbb{H}':u'ℍ', u'\\mathbb{J}':u'𝕁', u'\\mathbb{K}':u'𝕂', u'\\mathbb{L}':u'𝕃', u'\\mathbb{N}':u'ℕ', u'\\mathbb{O}':u'𝕆', u'\\mathbb{P}':u'ℙ', u'\\mathbb{Q}':u'ℚ', u'\\mathbb{R}':u'ℝ', u'\\mathbb{S}':u'𝕊', u'\\mathbb{T}':u'𝕋', u'\\mathbb{W}':u'𝕎', u'\\mathbb{Z}':u'ℤ', u'\\mathbf':u'b', u'\\mathcal':u'span class="scriptfont"', u'\\mathcal{B}':u'ℬ', u'\\mathcal{E}':u'ℰ', u'\\mathcal{F}':u'ℱ', u'\\mathcal{H}':u'ℋ', u'\\mathcal{I}':u'ℐ', u'\\mathcal{L}':u'ℒ', u'\\mathcal{M}':u'ℳ', u'\\mathcal{R}':u'ℛ', u'\\mathfrak':u'span class="fraktur"', u'\\mathfrak{C}':u'ℭ', u'\\mathfrak{F}':u'𝔉', u'\\mathfrak{H}':u'ℌ', u'\\mathfrak{I}':u'ℑ', u'\\mathfrak{R}':u'ℜ', u'\\mathfrak{Z}':u'ℨ', u'\\mathit':u'i', u'\\mathring{A}':u'Å', u'\\mathring{U}':u'Ů', u'\\mathring{a}':u'å', u'\\mathring{u}':u'ů', u'\\mathring{w}':u'ẘ', u'\\mathring{y}':u'ẙ', u'\\mathrm':u'span class="mathrm"', u'\\mathscr':u'span class="scriptfont"', u'\\mathscr{B}':u'ℬ', u'\\mathscr{E}':u'ℰ', u'\\mathscr{F}':u'ℱ', u'\\mathscr{H}':u'ℋ', u'\\mathscr{I}':u'ℐ', u'\\mathscr{L}':u'ℒ', u'\\mathscr{M}':u'ℳ', u'\\mathscr{R}':u'ℛ', u'\\mathsf':u'span class="mathsf"', u'\\mathtt':u'tt', } hybridfunctions = { u'\\addcontentsline':[u'{$p!}{$q!}{$r!}',u'f0{}',u'ignored',], u'\\addtocontents':[u'{$p!}{$q!}',u'f0{}',u'ignored',], u'\\backmatter':[u'',u'f0{}',u'ignored',], u'\\binom':[u'{$1}{$2}',u'f2{(}f0{f1{$1}f1{$2}}f2{)}',u'span class="binom"',u'span class="binomstack"',u'span class="bigsymbol"',], u'\\boxed':[u'{$1}',u'f0{$1}',u'span class="boxed"',], u'\\cfrac':[u'[$p!]{$1}{$2}',u'f0{f3{(}f1{$1}f3{)/(}f2{$2}f3{)}}',u'span class="fullfraction"',u'span class="numerator align-$p"',u'span class="denominator"',u'span class="ignored"',], u'\\color':[u'{$p!}{$1}',u'f0{$1}',u'span style="color: $p;"',], u'\\colorbox':[u'{$p!}{$1}',u'f0{$1}',u'span class="colorbox" style="background: $p;"',], u'\\dbinom':[u'{$1}{$2}',u'(f0{f1{f2{$1}}f1{f2{ }}f1{f2{$2}}})',u'span class="binomial"',u'span class="binomrow"',u'span class="binomcell"',], u'\\dfrac':[u'{$1}{$2}',u'f0{f3{(}f1{$1}f3{)/(}f2{$2}f3{)}}',u'span class="fullfraction"',u'span class="numerator"',u'span class="denominator"',u'span class="ignored"',], u'\\displaystyle':[u'{$1}',u'f0{$1}',u'span class="displaystyle"',], u'\\fancyfoot':[u'[$p!]{$q!}',u'f0{}',u'ignored',], u'\\fancyhead':[u'[$p!]{$q!}',u'f0{}',u'ignored',], u'\\fbox':[u'{$1}',u'f0{$1}',u'span class="fbox"',], u'\\fboxrule':[u'{$p!}',u'f0{}',u'ignored',], u'\\fboxsep':[u'{$p!}',u'f0{}',u'ignored',], u'\\fcolorbox':[u'{$p!}{$q!}{$1}',u'f0{$1}',u'span class="boxed" style="border-color: $p; background: $q;"',], u'\\frac':[u'{$1}{$2}',u'f0{f3{(}f1{$1}f3{)/(}f2{$2}f3{)}}',u'span class="fraction"',u'span class="numerator"',u'span class="denominator"',u'span class="ignored"',], u'\\framebox':[u'[$p!][$q!]{$1}',u'f0{$1}',u'span class="framebox align-$q" style="width: $p;"',], u'\\frontmatter':[u'',u'f0{}',u'ignored',], u'\\href':[u'[$o]{$u!}{$t!}',u'f0{$t}',u'a href="$u"',], u'\\hspace':[u'{$p!}',u'f0{ }',u'span class="hspace" style="width: $p;"',], u'\\leftroot':[u'{$p!}',u'f0{ }',u'span class="leftroot" style="width: $p;px"',], u'\\mainmatter':[u'',u'f0{}',u'ignored',], u'\\markboth':[u'{$p!}{$q!}',u'f0{}',u'ignored',], u'\\markright':[u'{$p!}',u'f0{}',u'ignored',], u'\\nicefrac':[u'{$1}{$2}',u'f0{f1{$1}⁄f2{$2}}',u'span class="fraction"',u'sup class="numerator"',u'sub class="denominator"',u'span class="ignored"',], u'\\parbox':[u'[$p!]{$w!}{$1}',u'f0{1}',u'div class="Boxed" style="width: $w;"',], u'\\raisebox':[u'{$p!}{$1}',u'f0{$1.font}',u'span class="raisebox" style="vertical-align: $p;"',], u'\\renewenvironment':[u'{$1!}{$2!}{$3!}',u'',], u'\\rule':[u'[$v!]{$w!}{$h!}',u'f0/',u'hr class="line" style="width: $w; height: $h;"',], u'\\scriptscriptstyle':[u'{$1}',u'f0{$1}',u'span class="scriptscriptstyle"',], u'\\scriptstyle':[u'{$1}',u'f0{$1}',u'span class="scriptstyle"',], u'\\sqrt':[u'[$0]{$1}',u'f0{f1{$0}f2{√}f4{(}f3{$1}f4{)}}',u'span class="sqrt"',u'sup class="root"',u'span class="radical"',u'span class="root"',u'span class="ignored"',], u'\\stackrel':[u'{$1}{$2}',u'f0{f1{$1}f2{$2}}',u'span class="stackrel"',u'span class="upstackrel"',u'span class="downstackrel"',], u'\\tbinom':[u'{$1}{$2}',u'(f0{f1{f2{$1}}f1{f2{ }}f1{f2{$2}}})',u'span class="binomial"',u'span class="binomrow"',u'span class="binomcell"',], u'\\textcolor':[u'{$p!}{$1}',u'f0{$1}',u'span style="color: $p;"',], u'\\textstyle':[u'{$1}',u'f0{$1}',u'span class="textstyle"',], u'\\thispagestyle':[u'{$p!}',u'f0{}',u'ignored',], u'\\unit':[u'[$0]{$1}',u'$0f0{$1.font}',u'span class="unit"',], u'\\unitfrac':[u'[$0]{$1}{$2}',u'$0f0{f1{$1.font}⁄f2{$2.font}}',u'span class="fraction"',u'sup class="unit"',u'sub class="unit"',], u'\\uproot':[u'{$p!}',u'f0{ }',u'span class="uproot" style="width: $p;px"',], u'\\url':[u'{$u!}',u'f0{$u}',u'a href="$u"',], u'\\vspace':[u'{$p!}',u'f0{ }',u'span class="vspace" style="height: $p;"',], } hybridsizes = { u'\\binom':u'$1+$2', u'\\cfrac':u'$1+$2', u'\\dbinom':u'$1+$2+1', u'\\dfrac':u'$1+$2', u'\\frac':u'$1+$2', u'\\tbinom':u'$1+$2+1', } labelfunctions = { u'\\label':u'a name="#"', } limitcommands = { u'\\biginterleave':u'⫼', u'\\bigsqcap':u'⨅', u'\\fint':u'⨏', u'\\iiiint':u'⨌', u'\\int':u'∫', u'\\intop':u'∫', u'\\lim':u'lim', u'\\prod':u'∏', u'\\smallint':u'∫', u'\\sqint':u'⨖', u'\\sum':u'∑', u'\\varointclockwise':u'∲', u'\\varprod':u'⨉', u'\\zcmp':u'⨟', u'\\zhide':u'⧹', u'\\zpipe':u'⨠', u'\\zproject':u'⨡', } misccommands = { u'\\limits':u'LimitPreviousCommand', u'\\newcommand':u'MacroDefinition', u'\\renewcommand':u'MacroDefinition', u'\\setcounter':u'SetCounterFunction', u'\\tag':u'FormulaTag', u'\\tag*':u'FormulaTag', u'\\today':u'TodayCommand', } modified = { u'\n':u'', u' ':u'', u'$':u'', u'&':u' ', u'\'':u'’', u'+':u' + ', u',':u', ', u'-':u' − ', u'/':u' ⁄ ', u'<':u' < ', u'=':u' = ', u'>':u' > ', u'@':u'', u'~':u'', } onefunctions = { u'\\Big':u'span class="bigsymbol"', u'\\Bigg':u'span class="hugesymbol"', u'\\bar':u'span class="bar"', u'\\begin{array}':u'span class="arraydef"', u'\\big':u'span class="symbol"', u'\\bigg':u'span class="largesymbol"', u'\\bigl':u'span class="bigsymbol"', u'\\bigr':u'span class="bigsymbol"', u'\\centering':u'span class="align-center"', u'\\ensuremath':u'span class="ensuremath"', u'\\hphantom':u'span class="phantom"', u'\\noindent':u'span class="noindent"', u'\\overbrace':u'span class="overbrace"', u'\\overline':u'span class="overline"', u'\\phantom':u'span class="phantom"', u'\\underbrace':u'span class="underbrace"', u'\\underline':u'u', u'\\vphantom':u'span class="phantom"', } spacedcommands = { u'\\Bot':u'⫫', u'\\Doteq':u'≑', u'\\DownArrowBar':u'⤓', u'\\DownLeftTeeVector':u'⥞', u'\\DownLeftVectorBar':u'⥖', u'\\DownRightTeeVector':u'⥟', u'\\DownRightVectorBar':u'⥗', u'\\Equal':u'⩵', u'\\LeftArrowBar':u'⇤', u'\\LeftDownTeeVector':u'⥡', u'\\LeftDownVectorBar':u'⥙', u'\\LeftTeeVector':u'⥚', u'\\LeftTriangleBar':u'⧏', u'\\LeftUpTeeVector':u'⥠', u'\\LeftUpVectorBar':u'⥘', u'\\LeftVectorBar':u'⥒', u'\\Leftrightarrow':u'⇔', u'\\Longmapsfrom':u'⟽', u'\\Longmapsto':u'⟾', u'\\MapsDown':u'↧', u'\\MapsUp':u'↥', u'\\Nearrow':u'⇗', u'\\NestedGreaterGreater':u'⪢', u'\\NestedLessLess':u'⪡', u'\\NotGreaterLess':u'≹', u'\\NotGreaterTilde':u'≵', u'\\NotLessTilde':u'≴', u'\\Nwarrow':u'⇖', u'\\Proportion':u'∷', u'\\RightArrowBar':u'⇥', u'\\RightDownTeeVector':u'⥝', u'\\RightDownVectorBar':u'⥕', u'\\RightTeeVector':u'⥛', u'\\RightTriangleBar':u'⧐', u'\\RightUpTeeVector':u'⥜', u'\\RightUpVectorBar':u'⥔', u'\\RightVectorBar':u'⥓', u'\\Rightarrow':u'⇒', u'\\Same':u'⩶', u'\\Searrow':u'⇘', u'\\Swarrow':u'⇙', u'\\Top':u'⫪', u'\\UpArrowBar':u'⤒', u'\\VDash':u'⊫', u'\\approx':u'≈', u'\\approxeq':u'≊', u'\\backsim':u'∽', u'\\barin':u'⋶', u'\\barleftharpoon':u'⥫', u'\\barrightharpoon':u'⥭', u'\\bij':u'⤖', u'\\coloneq':u'≔', u'\\corresponds':u'≙', u'\\curlyeqprec':u'⋞', u'\\curlyeqsucc':u'⋟', u'\\dashrightarrow':u'⇢', u'\\dlsh':u'↲', u'\\downdownharpoons':u'⥥', u'\\downuparrows':u'⇵', u'\\downupharpoons':u'⥯', u'\\drsh':u'↳', u'\\eqslantgtr':u'⪖', u'\\eqslantless':u'⪕', u'\\equiv':u'≡', u'\\ffun':u'⇻', u'\\finj':u'⤕', u'\\ge':u'≥', u'\\geq':u'≥', u'\\ggcurly':u'⪼', u'\\gnapprox':u'⪊', u'\\gneq':u'⪈', u'\\gtrapprox':u'⪆', u'\\hash':u'⋕', u'\\iddots':u'⋰', u'\\implies':u' ⇒ ', u'\\in':u'∈', u'\\le':u'≤', u'\\leftarrow':u'←', u'\\leftarrowtriangle':u'⇽', u'\\leftbarharpoon':u'⥪', u'\\leftrightarrowtriangle':u'⇿', u'\\leftrightharpoon':u'⥊', u'\\leftrightharpoondown':u'⥐', u'\\leftrightharpoonup':u'⥎', u'\\leftrightsquigarrow':u'↭', u'\\leftslice':u'⪦', u'\\leftsquigarrow':u'⇜', u'\\leftupdownharpoon':u'⥑', u'\\leq':u'≤', u'\\lessapprox':u'⪅', u'\\llcurly':u'⪻', u'\\lnapprox':u'⪉', u'\\lneq':u'⪇', u'\\longmapsfrom':u'⟻', u'\\multimapboth':u'⧟', u'\\multimapdotbothA':u'⊶', u'\\multimapdotbothB':u'⊷', u'\\multimapinv':u'⟜', u'\\nVdash':u'⊮', u'\\ne':u'≠', u'\\neq':u'≠', u'\\ngeq':u'≱', u'\\nleq':u'≰', u'\\nni':u'∌', u'\\not\\in':u'∉', u'\\notasymp':u'≭', u'\\npreceq':u'⋠', u'\\nsqsubseteq':u'⋢', u'\\nsqsupseteq':u'⋣', u'\\nsubset':u'⊄', u'\\nsucceq':u'⋡', u'\\pfun':u'⇸', u'\\pinj':u'⤔', u'\\precapprox':u'⪷', u'\\preceqq':u'⪳', u'\\precnapprox':u'⪹', u'\\precnsim':u'⋨', u'\\propto':u'∝', u'\\psur':u'⤀', u'\\rightarrow':u'→', u'\\rightarrowtriangle':u'⇾', u'\\rightbarharpoon':u'⥬', u'\\rightleftharpoon':u'⥋', u'\\rightslice':u'⪧', u'\\rightsquigarrow':u'⇝', u'\\rightupdownharpoon':u'⥏', u'\\sim':u'~', u'\\strictfi':u'⥼', u'\\strictif':u'⥽', u'\\subset':u'⊂', u'\\subseteq':u'⊆', u'\\subsetneq':u'⊊', u'\\succapprox':u'⪸', u'\\succeqq':u'⪴', u'\\succnapprox':u'⪺', u'\\supset':u'⊃', u'\\supseteq':u'⊇', u'\\supsetneq':u'⊋', u'\\times':u'×', u'\\to':u'→', u'\\updownarrows':u'⇅', u'\\updownharpoons':u'⥮', u'\\upupharpoons':u'⥣', u'\\vartriangleleft':u'⊲', u'\\vartriangleright':u'⊳', } starts = { u'beginafter':u'}', u'beginbefore':u'\\begin{', u'bracket':u'{', u'command':u'\\', u'comment':u'%', u'complex':u'\\[', u'simple':u'$', u'squarebracket':u'[', u'unnumbered':u'*', } symbolfunctions = { u'^':u'sup', u'_':u'sub', } textfunctions = { u'\\mbox':u'span class="mbox"', u'\\text':u'span class="text"', u'\\textbf':u'b', u'\\textipa':u'span class="textipa"', u'\\textit':u'i', u'\\textnormal':u'span class="textnormal"', u'\\textrm':u'span class="textrm"', u'\\textsc':u'span class="versalitas"', u'\\textsf':u'span class="textsf"', u'\\textsl':u'i', u'\\texttt':u'tt', u'\\textup':u'span class="normal"', } unmodified = { u'characters':[u'.',u'*',u'€',u'(',u')',u'[',u']',u':',u'·',u'!',u';',u'|',u'§',u'"',], } urls = { u'googlecharts':u'http://chart.googleapis.com/chart?cht=tx&chl=', } class GeneralConfig(object): "Configuration class from elyxer.config file" version = { u'date':u'2013-03-10', u'lyxformat':u'413', u'number':u'1.2.5', } class HeaderConfig(object): "Configuration class from elyxer.config file" parameters = { u'beginpreamble':u'\\begin_preamble', u'branch':u'\\branch', u'documentclass':u'\\textclass', u'endbranch':u'\\end_branch', u'endpreamble':u'\\end_preamble', u'language':u'\\language', u'lstset':u'\\lstset', u'outputchanges':u'\\output_changes', u'paragraphseparation':u'\\paragraph_separation', u'pdftitle':u'\\pdf_title', u'secnumdepth':u'\\secnumdepth', u'tocdepth':u'\\tocdepth', } styles = { u'article':[u'article',u'aastex',u'aapaper',u'acmsiggraph',u'sigplanconf',u'achemso',u'amsart',u'apa',u'arab-article',u'armenian-article',u'article-beamer',u'chess',u'dtk',u'elsarticle',u'heb-article',u'IEEEtran',u'iopart',u'kluwer',u'scrarticle-beamer',u'scrartcl',u'extarticle',u'paper',u'mwart',u'revtex4',u'spie',u'svglobal3',u'ltugboat',u'agu-dtd',u'jgrga',u'agums',u'entcs',u'egs',u'ijmpc',u'ijmpd',u'singlecol-new',u'doublecol-new',u'isprs',u'tarticle',u'jsarticle',u'jarticle',u'jss',u'literate-article',u'siamltex',u'cl2emult',u'llncs',u'svglobal',u'svjog',u'svprobth',], u'book':[u'book',u'amsbook',u'scrbook',u'extbook',u'tufte-book',u'report',u'extreport',u'scrreprt',u'memoir',u'tbook',u'jsbook',u'jbook',u'mwbk',u'svmono',u'svmult',u'treport',u'jreport',u'mwrep',], } class ImageConfig(object): "Configuration class from elyxer.config file" converters = { u'imagemagick':u'convert[ -density $scale][ -define $format:use-cropbox=true] "$input" "$output"', u'inkscape':u'inkscape "$input" --export-png="$output"', u'lyx':u'lyx -C "$input" "$output"', } cropboxformats = { u'.eps':u'ps', u'.pdf':u'pdf', u'.ps':u'ps', } formats = { u'default':u'.png', u'vector':[u'.svg',u'.eps',], } class LayoutConfig(object): "Configuration class from elyxer.config file" groupable = { u'allowed':[u'StringContainer',u'Constant',u'TaggedText',u'Align',u'TextFamily',u'EmphaticText',u'VersalitasText',u'BarredText',u'SizeText',u'ColorText',u'LangLine',u'Formula',], } class NewfangleConfig(object): "Configuration class from elyxer.config file" constants = { u'chunkref':u'chunkref{', u'endcommand':u'}', u'endmark':u'>', u'startcommand':u'\\', u'startmark':u'=<', } class NumberingConfig(object): "Configuration class from elyxer.config file" layouts = { u'ordered':[u'Chapter',u'Section',u'Subsection',u'Subsubsection',u'Paragraph',], u'roman':[u'Part',u'Book',], } sequence = { u'symbols':[u'*',u'**',u'†',u'‡',u'§',u'§§',u'¶',u'¶¶',u'#',u'##',], } class StyleConfig(object): "Configuration class from elyxer.config file" hspaces = { u'\\enskip{}':u' ', u'\\hfill{}':u' ', u'\\hspace*{\\fill}':u' ', u'\\hspace*{}':u'', u'\\hspace{}':u' ', u'\\negthinspace{}':u'', u'\\qquad{}':u'  ', u'\\quad{}':u' ', u'\\space{}':u' ', u'\\thinspace{}':u' ', u'~':u' ', } quotes = { u'ald':u'»', u'als':u'›', u'ard':u'«', u'ars':u'‹', u'eld':u'“', u'els':u'‘', u'erd':u'”', u'ers':u'’', u'fld':u'«', u'fls':u'‹', u'frd':u'»', u'frs':u'›', u'gld':u'„', u'gls':u'‚', u'grd':u'“', u'grs':u'‘', u'pld':u'„', u'pls':u'‚', u'prd':u'”', u'prs':u'’', u'sld':u'”', u'srd':u'”', } referenceformats = { u'eqref':u'(@↕)', u'formatted':u'¶↕', u'nameref':u'$↕', u'pageref':u'#↕', u'ref':u'@↕', u'vpageref':u'on-page#↕', u'vref':u'@on-page#↕', } size = { u'ignoredtexts':[u'col',u'text',u'line',u'page',u'theight',u'pheight',], } vspaces = { u'bigskip':u'
', u'defskip':u'
', u'medskip':u'
', u'smallskip':u'
', u'vfill':u'
', } class TOCConfig(object): "Configuration class from elyxer.config file" extractplain = { u'allowed':[u'StringContainer',u'Constant',u'TaggedText',u'Align',u'TextFamily',u'EmphaticText',u'VersalitasText',u'BarredText',u'SizeText',u'ColorText',u'LangLine',u'Formula',], u'cloned':[u'',], u'extracted':[u'',], } extracttitle = { u'allowed':[u'StringContainer',u'Constant',u'Space',], u'cloned':[u'TextFamily',u'EmphaticText',u'VersalitasText',u'BarredText',u'SizeText',u'ColorText',u'LangLine',u'Formula',], u'extracted':[u'PlainLayout',u'TaggedText',u'Align',u'Caption',u'StandardLayout',u'FlexInset',], } class TagConfig(object): "Configuration class from elyxer.config file" barred = { u'under':u'u', } family = { u'sans':u'span class="sans"', u'typewriter':u'tt', } flex = { u'CharStyle:Code':u'span class="code"', u'CharStyle:MenuItem':u'span class="menuitem"', u'Code':u'span class="code"', u'MenuItem':u'span class="menuitem"', u'Noun':u'span class="noun"', u'Strong':u'span class="strong"', } group = { u'layouts':[u'Quotation',u'Quote',], } layouts = { u'Center':u'div', u'Chapter':u'h?', u'Date':u'h2', u'Paragraph':u'div', u'Part':u'h1', u'Quotation':u'blockquote', u'Quote':u'blockquote', u'Section':u'h?', u'Subsection':u'h?', u'Subsubsection':u'h?', } listitems = { u'Enumerate':u'ol', u'Itemize':u'ul', } notes = { u'Comment':u'', u'Greyedout':u'span class="greyedout"', u'Note':u'', } script = { u'subscript':u'sub', u'superscript':u'sup', } shaped = { u'italic':u'i', u'slanted':u'i', u'smallcaps':u'span class="versalitas"', } class TranslationConfig(object): "Configuration class from elyxer.config file" constants = { u'Appendix':u'Appendix', u'Book':u'Book', u'Chapter':u'Chapter', u'Paragraph':u'Paragraph', u'Part':u'Part', u'Section':u'Section', u'Subsection':u'Subsection', u'Subsubsection':u'Subsubsection', u'abstract':u'Abstract', u'bibliography':u'Bibliography', u'figure':u'figure', u'float-algorithm':u'Algorithm ', u'float-figure':u'Figure ', u'float-listing':u'Listing ', u'float-table':u'Table ', u'float-tableau':u'Tableau ', u'footnotes':u'Footnotes', u'generated-by':u'Document generated by ', u'generated-on':u' on ', u'index':u'Index', u'jsmath-enable':u'Please enable JavaScript on your browser.', u'jsmath-requires':u' requires JavaScript to correctly process the mathematics on this page. ', u'jsmath-warning':u'Warning: ', u'list-algorithm':u'List of Algorithms', u'list-figure':u'List of Figures', u'list-table':u'List of Tables', u'list-tableau':u'List of Tableaux', u'main-page':u'Main page', u'next':u'Next', u'nomenclature':u'Nomenclature', u'on-page':u' on page ', u'prev':u'Prev', u'references':u'References', u'toc':u'Table of Contents', u'toc-for':u'Contents for ', u'up':u'Up', } languages = { u'american':u'en', u'british':u'en', u'deutsch':u'de', u'dutch':u'nl', u'english':u'en', u'french':u'fr', u'ngerman':u'de', u'russian':u'ru', u'spanish':u'es', } class CommandLineParser(object): "A parser for runtime options" def __init__(self, options): self.options = options def parseoptions(self, args): "Parse command line options" if len(args) == 0: return None while len(args) > 0 and args[0].startswith('--'): key, value = self.readoption(args) if not key: return 'Option ' + value + ' not recognized' if not value: return 'Option ' + key + ' needs a value' setattr(self.options, key, value) return None def readoption(self, args): "Read the key and value for an option" arg = args[0][2:] del args[0] if '=' in arg: key = self.readequalskey(arg, args) else: key = arg.replace('-', '') if not hasattr(self.options, key): return None, key current = getattr(self.options, key) if isinstance(current, bool): return key, True # read value if len(args) == 0: return key, None if args[0].startswith('"'): initial = args[0] del args[0] return key, self.readquoted(args, initial) value = args[0].decode('utf-8') del args[0] if isinstance(current, list): current.append(value) return key, current return key, value def readquoted(self, args, initial): "Read a value between quotes" Trace.error('Oops') value = initial[1:] while len(args) > 0 and not args[0].endswith('"') and not args[0].startswith('--'): Trace.error('Appending ' + args[0]) value += ' ' + args[0] del args[0] if len(args) == 0 or args[0].startswith('--'): return None value += ' ' + args[0:-1] return value def readequalskey(self, arg, args): "Read a key using equals" split = arg.split('=', 1) key = split[0] value = split[1] args.insert(0, value) return key class Options(object): "A set of runtime options" instance = None location = None nocopy = False copyright = False debug = False quiet = False version = False hardversion = False versiondate = False html = False help = False showlines = True unicode = False iso885915 = False css = [] title = None directory = None destdirectory = None toc = False toctarget = '' tocfor = None forceformat = None lyxformat = False target = None splitpart = None memory = True lowmem = False nobib = False converter = 'imagemagick' raw = False jsmath = None mathjax = None nofooter = False simplemath = False template = None noconvert = False notoclabels = False letterfoot = True numberfoot = False symbolfoot = False hoverfoot = True marginfoot = False endfoot = False supfoot = True alignfoot = False footnotes = None imageformat = None copyimages = False googlecharts = False embedcss = [] branches = dict() def parseoptions(self, args): "Parse command line options" Options.location = args[0] del args[0] parser = CommandLineParser(Options) result = parser.parseoptions(args) if result: Trace.error(result) self.usage() self.processoptions() def processoptions(self): "Process all options parsed." if Options.help: self.usage() if Options.version: self.showversion() if Options.hardversion: self.showhardversion() if Options.versiondate: self.showversiondate() if Options.lyxformat: self.showlyxformat() if Options.splitpart: try: Options.splitpart = int(Options.splitpart) if Options.splitpart <= 0: Trace.error('--splitpart requires a number bigger than zero') self.usage() except: Trace.error('--splitpart needs a numeric argument, not ' + Options.splitpart) self.usage() if Options.lowmem or Options.toc or Options.tocfor: Options.memory = False self.parsefootnotes() if Options.forceformat and not Options.imageformat: Options.imageformat = Options.forceformat if Options.imageformat == 'copy': Options.copyimages = True if Options.css == []: Options.css = ['http://elyxer.nongnu.org/lyx.css'] if Options.html: Options.simplemath = True if Options.toc and not Options.tocfor: Trace.error('Option --toc is deprecated; use --tocfor "page" instead') Options.tocfor = Options.toctarget if Options.nocopy: Trace.error('Option --nocopy is deprecated; it is no longer needed') if Options.jsmath: Trace.error('Option --jsmath is deprecated; use --mathjax instead') # set in Trace if necessary for param in dir(Trace): if param.endswith('mode'): setattr(Trace, param, getattr(self, param[:-4])) def usage(self): "Show correct usage" Trace.error('Usage: ' + os.path.basename(Options.location) + ' [options] [filein] [fileout]') Trace.error('Convert LyX input file "filein" to HTML file "fileout".') Trace.error('If filein (or fileout) is not given use standard input (or output).') Trace.error('Main program of the eLyXer package (http://elyxer.nongnu.org/).') self.showoptions() def parsefootnotes(self): "Parse footnotes options." if not Options.footnotes: return Options.marginfoot = False Options.letterfoot = False Options.hoverfoot = False options = Options.footnotes.split(',') for option in options: footoption = option + 'foot' if hasattr(Options, footoption): setattr(Options, footoption, True) else: Trace.error('Unknown footnotes option: ' + option) if not Options.endfoot and not Options.marginfoot and not Options.hoverfoot: Options.hoverfoot = True if not Options.numberfoot and not Options.symbolfoot: Options.letterfoot = True def showoptions(self): "Show all possible options" Trace.error(' Common options:') Trace.error(' --help: show this online help') Trace.error(' --quiet: disables all runtime messages') Trace.error('') Trace.error(' Advanced options:') Trace.error(' --debug: enable debugging messages (for developers)') Trace.error(' --version: show version number and release date') Trace.error(' --lyxformat: return the highest LyX version supported') Trace.error(' Options for HTML output:') Trace.error(' --title "title": set the generated page title') Trace.error(' --css "file.css": use a custom CSS file') Trace.error(' --embedcss "file.css": embed styles from a CSS file into the output') Trace.error(' --html: output HTML 4.0 instead of the default XHTML') Trace.error(' --unicode: full Unicode output') Trace.error(' --iso885915: output a document with ISO-8859-15 encoding') Trace.error(' --nofooter: remove the footer "generated by eLyXer"') Trace.error(' --simplemath: do not generate fancy math constructions') Trace.error(' Options for image output:') Trace.error(' --directory "img_dir": look for images in the specified directory') Trace.error(' --destdirectory "dest": put converted images into this directory') Trace.error(' --imageformat ".ext": image output format, or "copy" to copy images') Trace.error(' --noconvert: do not convert images, use in original locations') Trace.error(' --converter "inkscape": use an alternative program to convert images') Trace.error(' Options for footnote display:') Trace.error(' --numberfoot: mark footnotes with numbers instead of letters') Trace.error(' --symbolfoot: mark footnotes with symbols (*, **...)') Trace.error(' --hoverfoot: show footnotes as hovering text (default)') Trace.error(' --marginfoot: show footnotes on the page margin') Trace.error(' --endfoot: show footnotes at the end of the page') Trace.error(' --supfoot: use superscript for footnote markers (default)') Trace.error(' --alignfoot: use aligned text for footnote markers') Trace.error(' --footnotes "options": specify several comma-separated footnotes options') Trace.error(' Available options are: "number", "symbol", "hover", "margin", "end",') Trace.error(' "sup", "align"') Trace.error(' Advanced output options:') Trace.error(' --splitpart "depth": split the resulting webpage at the given depth') Trace.error(' --tocfor "page": generate a TOC that points to the given page') Trace.error(' --target "frame": make all links point to the given frame') Trace.error(' --notoclabels: omit the part labels in the TOC, such as Chapter') Trace.error(' --lowmem: do the conversion on the fly (conserve memory)') Trace.error(' --raw: generate HTML without header or footer.') Trace.error(' --mathjax remote: use MathJax remotely to display equations') Trace.error(' --mathjax "URL": use MathJax from the given URL to display equations') Trace.error(' --googlecharts: use Google Charts to generate formula images') Trace.error(' --template "file": use a template, put everything in ') Trace.error(' --copyright: add a copyright notice at the bottom') Trace.error(' Deprecated options:') Trace.error(' --toc: (deprecated) create a table of contents') Trace.error(' --toctarget "page": (deprecated) generate a TOC for the given page') Trace.error(' --nocopy: (deprecated) maintained for backwards compatibility') Trace.error(' --jsmath "URL": use jsMath from the given URL to display equations') sys.exit() def showversion(self): "Return the current eLyXer version string" string = 'eLyXer version ' + GeneralConfig.version['number'] string += ' (' + GeneralConfig.version['date'] + ')' Trace.error(string) sys.exit() def showhardversion(self): "Return just the version string" Trace.message(GeneralConfig.version['number']) sys.exit() def showversiondate(self): "Return just the version dte" Trace.message(GeneralConfig.version['date']) sys.exit() def showlyxformat(self): "Return just the lyxformat parameter" Trace.message(GeneralConfig.version['lyxformat']) sys.exit() class BranchOptions(object): "A set of options for a branch" def __init__(self, name): self.name = name self.options = {'color':'#ffffff'} def set(self, key, value): "Set a branch option" if not key.startswith(ContainerConfig.string['startcommand']): Trace.error('Invalid branch option ' + key) return key = key.replace(ContainerConfig.string['startcommand'], '') self.options[key] = value def isselected(self): "Return if the branch is selected" if not 'selected' in self.options: return False return self.options['selected'] == '1' def __unicode__(self): "String representation" return 'options for ' + self.name + ': ' + unicode(self.options) import gettext class DocumentParameters(object): "Global parameters for the document." pdftitle = None indentstandard = False tocdepth = 10 startinglevel = 0 maxdepth = 10 language = None bibliography = None outputchanges = False displaymode = False class Translator(object): "Reads the configuration file and tries to find a translation." "Otherwise falls back to the messages in the config file." instance = None def translate(cls, key): "Get the translated message for a key." return cls.instance.getmessage(key) translate = classmethod(translate) def __init__(self): self.translation = None self.first = True def findtranslation(self): "Find the translation for the document language." self.langcodes = None if not DocumentParameters.language: Trace.error('No language in document') return if not DocumentParameters.language in TranslationConfig.languages: Trace.error('Unknown language ' + DocumentParameters.language) return if TranslationConfig.languages[DocumentParameters.language] == 'en': return langcodes = [TranslationConfig.languages[DocumentParameters.language]] try: self.translation = gettext.translation('elyxer', None, langcodes) except IOError: Trace.error('No translation for ' + unicode(langcodes)) def getmessage(self, key): "Get the translated message for the given key." if self.first: self.findtranslation() self.first = False message = self.getuntranslated(key) if not self.translation: return message try: message = self.translation.ugettext(message) except IOError: pass return message def getuntranslated(self, key): "Get the untranslated message." if not key in TranslationConfig.constants: Trace.error('Cannot translate ' + key) return key return TranslationConfig.constants[key] Translator.instance = Translator() class NumberCounter(object): "A counter for numbers (by default)." "The type can be changed to return letters, roman numbers..." name = None value = None mode = None master = None letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' symbols = NumberingConfig.sequence['symbols'] romannumerals = [ ('M', 1000), ('CM', 900), ('D', 500), ('CD', 400), ('C', 100), ('XC', 90), ('L', 50), ('XL', 40), ('X', 10), ('IX', 9), ('V', 5), ('IV', 4), ('I', 1) ] def __init__(self, name): "Give a name to the counter." self.name = name def setmode(self, mode): "Set the counter mode. Can be changed at runtime." self.mode = mode return self def init(self, value): "Set an initial value." self.value = value def gettext(self): "Get the next value as a text string." return unicode(self.value) def getletter(self): "Get the next value as a letter." return self.getsequence(self.letters) def getsymbol(self): "Get the next value as a symbol." return self.getsequence(self.symbols) def getsequence(self, sequence): "Get the next value from elyxer.a sequence." return sequence[(self.value - 1) % len(sequence)] def getroman(self): "Get the next value as a roman number." result = '' number = self.value for numeral, value in self.romannumerals: if number >= value: result += numeral * (number / value) number = number % value return result def getvalue(self): "Get the current value as configured in the current mode." if not self.mode or self.mode in ['text', '1']: return self.gettext() if self.mode == 'A': return self.getletter() if self.mode == 'a': return self.getletter().lower() if self.mode == 'I': return self.getroman() if self.mode == '*': return self.getsymbol() Trace.error('Unknown counter mode ' + self.mode) return self.gettext() def getnext(self): "Increase the current value and get the next value as configured." if not self.value: self.value = 0 self.value += 1 return self.getvalue() def reset(self): "Reset the counter." self.value = 0 def __unicode__(self): "Return a printable representation." result = 'Counter ' + self.name if self.mode: result += ' in mode ' + self.mode return result class DependentCounter(NumberCounter): "A counter which depends on another one (the master)." def setmaster(self, master): "Set the master counter." self.master = master self.last = self.master.getvalue() return self def getnext(self): "Increase or, if the master counter has changed, restart." if self.last != self.master.getvalue(): self.reset() value = NumberCounter.getnext(self) self.last = self.master.getvalue() return value def getvalue(self): "Get the value of the combined counter: master.dependent." return self.master.getvalue() + '.' + NumberCounter.getvalue(self) class NumberGenerator(object): "A number generator for unique sequences and hierarchical structures. Used in:" " * ordered part numbers: Chapter 3, Section 5.3." " * unique part numbers: Footnote 15, Bibliography cite [15]." " * chaptered part numbers: Figure 3.15, Equation (8.3)." " * unique roman part numbers: Part I, Book IV." chaptered = None generator = None romanlayouts = [x.lower() for x in NumberingConfig.layouts['roman']] orderedlayouts = [x.lower() for x in NumberingConfig.layouts['ordered']] counters = dict() appendix = None def deasterisk(self, type): "Remove the possible asterisk in a layout type." return type.replace('*', '') def isunique(self, type): "Find out if the layout type corresponds to a unique part." return self.isroman(type) def isroman(self, type): "Find out if the layout type should have roman numeration." return self.deasterisk(type).lower() in self.romanlayouts def isinordered(self, type): "Find out if the layout type corresponds to an (un)ordered part." return self.deasterisk(type).lower() in self.orderedlayouts def isnumbered(self, type): "Find out if the type for a layout corresponds to a numbered layout." if '*' in type: return False if self.isroman(type): return True if not self.isinordered(type): return False if self.getlevel(type) > DocumentParameters.maxdepth: return False return True def isunordered(self, type): "Find out if the type contains an asterisk, basically." return '*' in type def getlevel(self, type): "Get the level that corresponds to a layout type." if self.isunique(type): return 0 if not self.isinordered(type): Trace.error('Unknown layout type ' + type) return 0 type = self.deasterisk(type).lower() level = self.orderedlayouts.index(type) + 1 return level - DocumentParameters.startinglevel def getparttype(self, type): "Obtain the type for the part: without the asterisk, " "and switched to Appendix if necessary." if NumberGenerator.appendix and self.getlevel(type) == 1: return 'Appendix' return self.deasterisk(type) def generate(self, type): "Generate a number for a layout type." "Unique part types such as Part or Book generate roman numbers: Part I." "Ordered part types return dot-separated tuples: Chapter 5, Subsection 2.3.5." "Everything else generates unique numbers: Bibliography [1]." "Each invocation results in a new number." return self.getcounter(type).getnext() def getcounter(self, type): "Get the counter for the given type." type = type.lower() if not type in self.counters: self.counters[type] = self.create(type) return self.counters[type] def create(self, type): "Create a counter for the given type." if self.isnumbered(type) and self.getlevel(type) > 1: index = self.orderedlayouts.index(type) above = self.orderedlayouts[index - 1] master = self.getcounter(above) return self.createdependent(type, master) counter = NumberCounter(type) if self.isroman(type): counter.setmode('I') return counter def getdependentcounter(self, type, master): "Get (or create) a counter of the given type that depends on another." if not type in self.counters or not self.counters[type].master: self.counters[type] = self.createdependent(type, master) return self.counters[type] def createdependent(self, type, master): "Create a dependent counter given the master." return DependentCounter(type).setmaster(master) def startappendix(self): "Start appendices here." firsttype = self.orderedlayouts[DocumentParameters.startinglevel] counter = self.getcounter(firsttype) counter.setmode('A').reset() NumberGenerator.appendix = True class ChapteredGenerator(NumberGenerator): "Generate chaptered numbers, as in Chapter.Number." "Used in equations, figures: Equation (5.3), figure 8.15." def generate(self, type): "Generate a number which goes with first-level numbers (chapters). " "For the article classes a unique number is generated." if DocumentParameters.startinglevel > 0: return NumberGenerator.generator.generate(type) chapter = self.getcounter('Chapter') return self.getdependentcounter(type, chapter).getnext() NumberGenerator.chaptered = ChapteredGenerator() NumberGenerator.generator = NumberGenerator() class Parser(object): "A generic parser" def __init__(self): self.begin = 0 self.parameters = dict() def parseheader(self, reader): "Parse the header" header = reader.currentline().split() reader.nextline() self.begin = reader.linenumber return header def parseparameter(self, reader): "Parse a parameter" if reader.currentline().strip().startswith('<'): key, value = self.parsexml(reader) self.parameters[key] = value return split = reader.currentline().strip().split(' ', 1) reader.nextline() if len(split) == 0: return key = split[0] if len(split) == 1: self.parameters[key] = True return if not '"' in split[1]: self.parameters[key] = split[1].strip() return doublesplit = split[1].split('"') self.parameters[key] = doublesplit[1] def parsexml(self, reader): "Parse a parameter in xml form: " strip = reader.currentline().strip() reader.nextline() if not strip.endswith('>'): Trace.error('XML parameter ' + strip + ' should be <...>') split = strip[1:-1].split() if len(split) == 0: Trace.error('Empty XML parameter <>') return None, None key = split[0] del split[0] if len(split) == 0: return key, dict() attrs = dict() for attr in split: if not '=' in attr: Trace.error('Erroneous attribute for ' + key + ': ' + attr) attr += '="0"' parts = attr.split('=') attrkey = parts[0] value = parts[1].split('"')[1] attrs[attrkey] = value return key, attrs def parseending(self, reader, process): "Parse until the current ending is found" if not self.ending: Trace.error('No ending for ' + unicode(self)) return while not reader.currentline().startswith(self.ending): process() def parsecontainer(self, reader, contents): container = self.factory.createcontainer(reader) if container: container.parent = self.parent contents.append(container) def __unicode__(self): "Return a description" return self.__class__.__name__ + ' (' + unicode(self.begin) + ')' class LoneCommand(Parser): "A parser for just one command line" def parse(self,reader): "Read nothing" return [] class TextParser(Parser): "A parser for a command and a bit of text" stack = [] def __init__(self, container): Parser.__init__(self) self.ending = None if container.__class__.__name__ in ContainerConfig.endings: self.ending = ContainerConfig.endings[container.__class__.__name__] self.endings = [] def parse(self, reader): "Parse lines as long as they are text" TextParser.stack.append(self.ending) self.endings = TextParser.stack + [ContainerConfig.endings['Layout'], ContainerConfig.endings['Inset'], self.ending] contents = [] while not self.isending(reader): self.parsecontainer(reader, contents) return contents def isending(self, reader): "Check if text is ending" current = reader.currentline().split() if len(current) == 0: return False if current[0] in self.endings: if current[0] in TextParser.stack: TextParser.stack.remove(current[0]) else: TextParser.stack = [] return True return False class ExcludingParser(Parser): "A parser that excludes the final line" def parse(self, reader): "Parse everything up to (and excluding) the final line" contents = [] self.parseending(reader, lambda: self.parsecontainer(reader, contents)) return contents class BoundedParser(ExcludingParser): "A parser bound by a final line" def parse(self, reader): "Parse everything, including the final line" contents = ExcludingParser.parse(self, reader) # skip last line reader.nextline() return contents class BoundedDummy(Parser): "A bound parser that ignores everything" def parse(self, reader): "Parse the contents of the container" self.parseending(reader, lambda: reader.nextline()) # skip last line reader.nextline() return [] class StringParser(Parser): "Parses just a string" def parseheader(self, reader): "Do nothing, just take note" self.begin = reader.linenumber + 1 return [] def parse(self, reader): "Parse a single line" contents = reader.currentline() reader.nextline() return contents class InsetParser(BoundedParser): "Parses a LyX inset" def parse(self, reader): "Parse inset parameters into a dictionary" startcommand = ContainerConfig.string['startcommand'] while reader.currentline() != '' and not reader.currentline().startswith(startcommand): self.parseparameter(reader) return BoundedParser.parse(self, reader) class ContainerOutput(object): "The generic HTML output for a container." def gethtml(self, container): "Show an error." Trace.error('gethtml() not implemented for ' + unicode(self)) def isempty(self): "Decide if the output is empty: by default, not empty." return False class EmptyOutput(ContainerOutput): def gethtml(self, container): "Return empty HTML code." return [] def isempty(self): "This output is particularly empty." return True class FixedOutput(ContainerOutput): "Fixed output" def gethtml(self, container): "Return constant HTML code" return container.html class ContentsOutput(ContainerOutput): "Outputs the contents converted to HTML" def gethtml(self, container): "Return the HTML code" html = [] if container.contents == None: return html for element in container.contents: if not hasattr(element, 'gethtml'): Trace.error('No html in ' + element.__class__.__name__ + ': ' + unicode(element)) return html html += element.gethtml() return html class TaggedOutput(ContentsOutput): "Outputs an HTML tag surrounding the contents." tag = None breaklines = False empty = False def settag(self, tag, breaklines=False, empty=False): "Set the value for the tag and other attributes." self.tag = tag if breaklines: self.breaklines = breaklines if empty: self.empty = empty return self def setbreaklines(self, breaklines): "Set the value for breaklines." self.breaklines = breaklines return self def gethtml(self, container): "Return the HTML code." if self.empty: return [self.selfclosing(container)] html = [self.open(container)] html += ContentsOutput.gethtml(self, container) html.append(self.close(container)) return html def open(self, container): "Get opening line." if not self.checktag(): return '' open = '<' + self.tag + '>' if self.breaklines: return open + '\n' return open def close(self, container): "Get closing line." if not self.checktag(): return '' close = '' if self.breaklines: return '\n' + close + '\n' return close def selfclosing(self, container): "Get self-closing line." if not self.checktag(): return '' selfclosing = '<' + self.tag + '/>' if self.breaklines: return selfclosing + '\n' return selfclosing def checktag(self): "Check that the tag is valid." if not self.tag: Trace.error('No tag in ' + unicode(container)) return False if self.tag == '': return False return True class FilteredOutput(ContentsOutput): "Returns the output in the contents, but filtered:" "some strings are replaced by others." def __init__(self): "Initialize the filters." self.filters = [] def addfilter(self, original, replacement): "Add a new filter: replace the original by the replacement." self.filters.append((original, replacement)) def gethtml(self, container): "Return the HTML code" result = [] html = ContentsOutput.gethtml(self, container) for line in html: result.append(self.filter(line)) return result def filter(self, line): "Filter a single line with all available filters." for original, replacement in self.filters: if original in line: line = line.replace(original, replacement) return line class StringOutput(ContainerOutput): "Returns a bare string as output" def gethtml(self, container): "Return a bare string" return [container.string] class Cloner(object): "An object used to clone other objects." def clone(cls, original): "Return an exact copy of an object." "The original object must have an empty constructor." return cls.create(original.__class__) def create(cls, type): "Create an object of a given class." clone = type.__new__(type) clone.__init__() return clone clone = classmethod(clone) create = classmethod(create) class ContainerExtractor(object): "A class to extract certain containers." def __init__(self, config): "The config parameter is a map containing three lists: allowed, copied and extracted." "Each of the three is a list of class names for containers." "Allowed containers are included as is into the result." "Cloned containers are cloned and placed into the result." "Extracted containers are looked into." "All other containers are silently ignored." self.allowed = config['allowed'] self.cloned = config['cloned'] self.extracted = config['extracted'] def extract(self, container): "Extract a group of selected containers from elyxer.a container." list = [] locate = lambda c: c.__class__.__name__ in self.allowed + self.cloned recursive = lambda c: c.__class__.__name__ in self.extracted process = lambda c: self.process(c, list) container.recursivesearch(locate, recursive, process) return list def process(self, container, list): "Add allowed containers, clone cloned containers and add the clone." name = container.__class__.__name__ if name in self.allowed: list.append(container) elif name in self.cloned: list.append(self.safeclone(container)) else: Trace.error('Unknown container class ' + name) def safeclone(self, container): "Return a new container with contents only in a safe list, recursively." clone = Cloner.clone(container) clone.output = container.output clone.contents = self.extract(container) return clone class Globable(object): """A bit of text which can be globbed (lumped together in bits). Methods current(), skipcurrent(), checkfor() and isout() have to be implemented by subclasses.""" leavepending = False def __init__(self): self.endinglist = EndingList() def checkbytemark(self): "Check for a Unicode byte mark and skip it." if self.finished(): return if ord(self.current()) == 0xfeff: self.skipcurrent() def isout(self): "Find out if we are out of the position yet." Trace.error('Unimplemented isout()') return True def current(self): "Return the current character." Trace.error('Unimplemented current()') return '' def checkfor(self, string): "Check for the given string in the current position." Trace.error('Unimplemented checkfor()') return False def finished(self): "Find out if the current text has finished." if self.isout(): if not self.leavepending: self.endinglist.checkpending() return True return self.endinglist.checkin(self) def skipcurrent(self): "Return the current character and skip it." Trace.error('Unimplemented skipcurrent()') return '' def glob(self, currentcheck): "Glob a bit of text that satisfies a check on the current char." glob = '' while not self.finished() and currentcheck(): glob += self.skipcurrent() return glob def globalpha(self): "Glob a bit of alpha text" return self.glob(lambda: self.current().isalpha()) def globnumber(self): "Glob a row of digits." return self.glob(lambda: self.current().isdigit()) def isidentifier(self): "Return if the current character is alphanumeric or _." if self.current().isalnum() or self.current() == '_': return True return False def globidentifier(self): "Glob alphanumeric and _ symbols." return self.glob(self.isidentifier) def isvalue(self): "Return if the current character is a value character:" "not a bracket or a space." if self.current().isspace(): return False if self.current() in '{}()': return False return True def globvalue(self): "Glob a value: any symbols but brackets." return self.glob(self.isvalue) def skipspace(self): "Skip all whitespace at current position." return self.glob(lambda: self.current().isspace()) def globincluding(self, magicchar): "Glob a bit of text up to (including) the magic char." glob = self.glob(lambda: self.current() != magicchar) + magicchar self.skip(magicchar) return glob def globexcluding(self, excluded): "Glob a bit of text up until (excluding) any excluded character." return self.glob(lambda: self.current() not in excluded) def pushending(self, ending, optional = False): "Push a new ending to the bottom" self.endinglist.add(ending, optional) def popending(self, expected = None): "Pop the ending found at the current position" if self.isout() and self.leavepending: return expected ending = self.endinglist.pop(self) if expected and expected != ending: Trace.error('Expected ending ' + expected + ', got ' + ending) self.skip(ending) return ending def nextending(self): "Return the next ending in the queue." nextending = self.endinglist.findending(self) if not nextending: return None return nextending.ending class EndingList(object): "A list of position endings" def __init__(self): self.endings = [] def add(self, ending, optional = False): "Add a new ending to the list" self.endings.append(PositionEnding(ending, optional)) def pickpending(self, pos): "Pick any pending endings from a parse position." self.endings += pos.endinglist.endings def checkin(self, pos): "Search for an ending" if self.findending(pos): return True return False def pop(self, pos): "Remove the ending at the current position" if pos.isout(): Trace.error('No ending out of bounds') return '' ending = self.findending(pos) if not ending: Trace.error('No ending at ' + pos.current()) return '' for each in reversed(self.endings): self.endings.remove(each) if each == ending: return each.ending elif not each.optional: Trace.error('Removed non-optional ending ' + each) Trace.error('No endings left') return '' def findending(self, pos): "Find the ending at the current position" if len(self.endings) == 0: return None for index, ending in enumerate(reversed(self.endings)): if ending.checkin(pos): return ending if not ending.optional: return None return None def checkpending(self): "Check if there are any pending endings" if len(self.endings) != 0: Trace.error('Pending ' + unicode(self) + ' left open') def __unicode__(self): "Printable representation" string = 'endings [' for ending in self.endings: string += unicode(ending) + ',' if len(self.endings) > 0: string = string[:-1] return string + ']' class PositionEnding(object): "An ending for a parsing position" def __init__(self, ending, optional): self.ending = ending self.optional = optional def checkin(self, pos): "Check for the ending" return pos.checkfor(self.ending) def __unicode__(self): "Printable representation" string = 'Ending ' + self.ending if self.optional: string += ' (optional)' return string class Position(Globable): """A position in a text to parse. Including those in Globable, functions to implement by subclasses are: skip(), identifier(), extract(), isout() and current().""" def __init__(self): Globable.__init__(self) def skip(self, string): "Skip a string" Trace.error('Unimplemented skip()') def identifier(self): "Return an identifier for the current position." Trace.error('Unimplemented identifier()') return 'Error' def extract(self, length): "Extract the next string of the given length, or None if not enough text," "without advancing the parse position." Trace.error('Unimplemented extract()') return None def checkfor(self, string): "Check for a string at the given position." return string == self.extract(len(string)) def checkforlower(self, string): "Check for a string in lower case." extracted = self.extract(len(string)) if not extracted: return False return string.lower() == self.extract(len(string)).lower() def skipcurrent(self): "Return the current character and skip it." current = self.current() self.skip(current) return current def next(self): "Advance the position and return the next character." self.skipcurrent() return self.current() def checkskip(self, string): "Check for a string at the given position; if there, skip it" if not self.checkfor(string): return False self.skip(string) return True def error(self, message): "Show an error message and the position identifier." Trace.error(message + ': ' + self.identifier()) class TextPosition(Position): "A parse position based on a raw text." def __init__(self, text): "Create the position from elyxer.some text." Position.__init__(self) self.pos = 0 self.text = text self.checkbytemark() def skip(self, string): "Skip a string of characters." self.pos += len(string) def identifier(self): "Return a sample of the remaining text." length = 30 if self.pos + length > len(self.text): length = len(self.text) - self.pos return '*' + self.text[self.pos:self.pos + length] + '*' def isout(self): "Find out if we are out of the text yet." return self.pos >= len(self.text) def current(self): "Return the current character, assuming we are not out." return self.text[self.pos] def extract(self, length): "Extract the next string of the given length, or None if not enough text." if self.pos + length > len(self.text): return None return self.text[self.pos : self.pos + length] class FilePosition(Position): "A parse position based on an underlying file." def __init__(self, filename): "Create the position from a file." Position.__init__(self) self.reader = LineReader(filename) self.pos = 0 self.checkbytemark() def skip(self, string): "Skip a string of characters." length = len(string) while self.pos + length > len(self.reader.currentline()): length -= len(self.reader.currentline()) - self.pos + 1 self.nextline() self.pos += length def currentline(self): "Get the current line of the underlying file." return self.reader.currentline() def nextline(self): "Go to the next line." self.reader.nextline() self.pos = 0 def linenumber(self): "Return the line number of the file." return self.reader.linenumber + 1 def identifier(self): "Return the current line and line number in the file." before = self.reader.currentline()[:self.pos - 1] after = self.reader.currentline()[self.pos:] return 'line ' + unicode(self.getlinenumber()) + ': ' + before + '*' + after def isout(self): "Find out if we are out of the text yet." if self.pos > len(self.reader.currentline()): if self.pos > len(self.reader.currentline()) + 1: Trace.error('Out of the line ' + self.reader.currentline() + ': ' + unicode(self.pos)) self.nextline() return self.reader.finished() def current(self): "Return the current character, assuming we are not out." if self.pos == len(self.reader.currentline()): return '\n' if self.pos > len(self.reader.currentline()): Trace.error('Out of the line ' + self.reader.currentline() + ': ' + unicode(self.pos)) return '*' return self.reader.currentline()[self.pos] def extract(self, length): "Extract the next string of the given length, or None if not enough text." if self.pos + length > len(self.reader.currentline()): return None return self.reader.currentline()[self.pos : self.pos + length] class Container(object): "A container for text and objects in a lyx file" partkey = None parent = None begin = None def __init__(self): self.contents = list() def process(self): "Process contents" pass def gethtml(self): "Get the resulting HTML" html = self.output.gethtml(self) if isinstance(html, basestring): Trace.error('Raw string ' + html) html = [html] return self.escapeall(html) def escapeall(self, lines): "Escape all lines in an array according to the output options." result = [] for line in lines: if Options.html: line = self.escape(line, EscapeConfig.html) if Options.iso885915: line = self.escape(line, EscapeConfig.iso885915) line = self.escapeentities(line) elif not Options.unicode: line = self.escape(line, EscapeConfig.nonunicode) result.append(line) return result def escape(self, line, replacements = EscapeConfig.entities): "Escape a line with replacements from elyxer.a map" pieces = replacements.keys() # do them in order pieces.sort() for piece in pieces: if piece in line: line = line.replace(piece, replacements[piece]) return line def escapeentities(self, line): "Escape all Unicode characters to HTML entities." result = '' pos = TextPosition(line) while not pos.finished(): if ord(pos.current()) > 128: codepoint = hex(ord(pos.current())) if codepoint == '0xd835': codepoint = hex(ord(pos.next()) + 0xf800) result += '&#' + codepoint[1:] + ';' else: result += pos.current() pos.skipcurrent() return result def searchall(self, type): "Search for all embedded containers of a given type" list = [] self.searchprocess(type, lambda container: list.append(container)) return list def searchremove(self, type): "Search for all containers of a type and remove them" list = self.searchall(type) for container in list: container.parent.contents.remove(container) return list def searchprocess(self, type, process): "Search for elements of a given type and process them" self.locateprocess(lambda container: isinstance(container, type), process) def locateprocess(self, locate, process): "Search for all embedded containers and process them" for container in self.contents: container.locateprocess(locate, process) if locate(container): process(container) def recursivesearch(self, locate, recursive, process): "Perform a recursive search in the container." for container in self.contents: if recursive(container): container.recursivesearch(locate, recursive, process) if locate(container): process(container) def extracttext(self): "Extract all text from elyxer.allowed containers." result = '' constants = ContainerExtractor(ContainerConfig.extracttext).extract(self) for constant in constants: result += constant.string return result def group(self, index, group, isingroup): "Group some adjoining elements into a group" if index >= len(self.contents): return if hasattr(self.contents[index], 'grouped'): return while index < len(self.contents) and isingroup(self.contents[index]): self.contents[index].grouped = True group.contents.append(self.contents[index]) self.contents.pop(index) self.contents.insert(index, group) def remove(self, index): "Remove a container but leave its contents" container = self.contents[index] self.contents.pop(index) while len(container.contents) > 0: self.contents.insert(index, container.contents.pop()) def tree(self, level = 0): "Show in a tree" Trace.debug(" " * level + unicode(self)) for container in self.contents: container.tree(level + 1) def getparameter(self, name): "Get the value of a parameter, if present." if not name in self.parameters: return None return self.parameters[name] def getparameterlist(self, name): "Get the value of a comma-separated parameter as a list." paramtext = self.getparameter(name) if not paramtext: return [] return paramtext.split(',') def hasemptyoutput(self): "Check if the parent's output is empty." current = self.parent while current: if current.output.isempty(): return True current = current.parent return False def __unicode__(self): "Get a description" if not self.begin: return self.__class__.__name__ return self.__class__.__name__ + '@' + unicode(self.begin) class BlackBox(Container): "A container that does not output anything" def __init__(self): self.parser = LoneCommand() self.output = EmptyOutput() self.contents = [] class LyXFormat(BlackBox): "Read the lyxformat command" def process(self): "Show warning if version < 276" version = int(self.header[1]) if version < 276: Trace.error('Warning: unsupported old format version ' + str(version)) if version > int(GeneralConfig.version['lyxformat']): Trace.error('Warning: unsupported new format version ' + str(version)) class StringContainer(Container): "A container for a single string" parsed = None def __init__(self): self.parser = StringParser() self.output = StringOutput() self.string = '' def process(self): "Replace special chars from elyxer.the contents." if self.parsed: self.string = self.replacespecial(self.parsed) self.parsed = None def replacespecial(self, line): "Replace all special chars from elyxer.a line" replaced = self.escape(line, EscapeConfig.entities) replaced = self.changeline(replaced) if ContainerConfig.string['startcommand'] in replaced and len(replaced) > 1: # unprocessed commands if self.begin: message = 'Unknown command at ' + unicode(self.begin) + ': ' else: message = 'Unknown command: ' Trace.error(message + replaced.strip()) return replaced def changeline(self, line): line = self.escape(line, EscapeConfig.chars) if not ContainerConfig.string['startcommand'] in line: return line line = self.escape(line, EscapeConfig.commands) return line def extracttext(self): "Return all text." return self.string def __unicode__(self): "Return a printable representation." result = 'StringContainer' if self.begin: result += '@' + unicode(self.begin) ellipsis = '...' if len(self.string.strip()) <= 15: ellipsis = '' return result + ' (' + self.string.strip()[:15] + ellipsis + ')' class Constant(StringContainer): "A constant string" def __init__(self, text): self.contents = [] self.string = text self.output = StringOutput() def __unicode__(self): return 'Constant: ' + self.string class TaggedText(Container): "Text inside a tag" output = None def __init__(self): self.parser = TextParser(self) self.output = TaggedOutput() def complete(self, contents, tag, breaklines=False): "Complete the tagged text and return it" self.contents = contents self.output.tag = tag self.output.breaklines = breaklines return self def constant(self, text, tag, breaklines=False): "Complete the tagged text with a constant" constant = Constant(text) return self.complete([constant], tag, breaklines) def __unicode__(self): "Return a printable representation." if not hasattr(self.output, 'tag'): return 'Emtpy tagged text' if not self.output.tag: return 'Tagged ' return 'Tagged <' + self.output.tag + '>' class ContainerSize(object): "The size of a container." width = None height = None maxwidth = None maxheight = None scale = None def set(self, width = None, height = None): "Set the proper size with width and height." self.setvalue('width', width) self.setvalue('height', height) return self def setmax(self, maxwidth = None, maxheight = None): "Set max width and/or height." self.setvalue('maxwidth', maxwidth) self.setvalue('maxheight', maxheight) return self def readparameters(self, container): "Read some size parameters off a container." self.setparameter(container, 'width') self.setparameter(container, 'height') self.setparameter(container, 'scale') self.checkvalidheight(container) return self def setparameter(self, container, name): "Read a size parameter off a container, and set it if present." value = container.getparameter(name) self.setvalue(name, value) def setvalue(self, name, value): "Set the value of a parameter name, only if it's valid." value = self.processparameter(value) if value: setattr(self, name, value) def checkvalidheight(self, container): "Check if the height parameter is valid; otherwise erase it." heightspecial = container.getparameter('height_special') if self.height and self.extractnumber(self.height) == '1' and heightspecial == 'totalheight': self.height = None def processparameter(self, value): "Do the full processing on a parameter." if not value: return None if self.extractnumber(value) == '0': return None for ignored in StyleConfig.size['ignoredtexts']: if ignored in value: value = value.replace(ignored, '') return value def extractnumber(self, text): "Extract the first number in the given text." result = '' decimal = False for char in text: if char.isdigit(): result += char elif char == '.' and not decimal: result += char decimal = True else: return result return result def checkimage(self, width, height): "Check image dimensions, set them if possible." if width: self.maxwidth = unicode(width) + 'px' if self.scale and not self.width: self.width = self.scalevalue(width) if height: self.maxheight = unicode(height) + 'px' if self.scale and not self.height: self.height = self.scalevalue(height) if self.width and not self.height: self.height = 'auto' if self.height and not self.width: self.width = 'auto' def scalevalue(self, value): "Scale the value according to the image scale and return it as unicode." scaled = value * int(self.scale) / 100 return unicode(int(scaled)) + 'px' def removepercentwidth(self): "Remove percent width if present, to set it at the figure level." if not self.width: return None if not '%' in self.width: return None width = self.width self.width = None if self.height == 'auto': self.height = None return width def addstyle(self, container): "Add the proper style attribute to the output tag." if not isinstance(container.output, TaggedOutput): Trace.error('No tag to add style, in ' + unicode(container)) if not self.width and not self.height and not self.maxwidth and not self.maxheight: # nothing to see here; move along return tag = ' style="' tag += self.styleparameter('width') tag += self.styleparameter('maxwidth') tag += self.styleparameter('height') tag += self.styleparameter('maxheight') if tag[-1] == ' ': tag = tag[:-1] tag += '"' container.output.tag += tag def styleparameter(self, name): "Get the style for a single parameter." value = getattr(self, name) if value: return name.replace('max', 'max-') + ': ' + value + '; ' return '' class QuoteContainer(Container): "A container for a pretty quote" def __init__(self): self.parser = BoundedParser() self.output = FixedOutput() def process(self): "Process contents" self.type = self.header[2] if not self.type in StyleConfig.quotes: Trace.error('Quote type ' + self.type + ' not found') self.html = ['"'] return self.html = [StyleConfig.quotes[self.type]] class LyXLine(Container): "A Lyx line" def __init__(self): self.parser = LoneCommand() self.output = FixedOutput() def process(self): self.html = ['
'] class EmphaticText(TaggedText): "Text with emphatic mode" def process(self): self.output.tag = 'i' class ShapedText(TaggedText): "Text shaped (italic, slanted)" def process(self): self.type = self.header[1] if not self.type in TagConfig.shaped: Trace.error('Unrecognized shape ' + self.header[1]) self.output.tag = 'span' return self.output.tag = TagConfig.shaped[self.type] class VersalitasText(TaggedText): "Text in versalitas" def process(self): self.output.tag = 'span class="versalitas"' class ColorText(TaggedText): "Colored text" def process(self): self.color = self.header[1] self.output.tag = 'span class="' + self.color + '"' class SizeText(TaggedText): "Sized text" def process(self): self.size = self.header[1] self.output.tag = 'span class="' + self.size + '"' class BoldText(TaggedText): "Bold text" def process(self): self.output.tag = 'b' class TextFamily(TaggedText): "A bit of text from elyxer.a different family" def process(self): "Parse the type of family" self.type = self.header[1] if not self.type in TagConfig.family: Trace.error('Unrecognized family ' + type) self.output.tag = 'span' return self.output.tag = TagConfig.family[self.type] class Hfill(TaggedText): "Horizontall fill" def process(self): self.output.tag = 'span class="hfill"' class BarredText(TaggedText): "Text with a bar somewhere" def process(self): "Parse the type of bar" self.type = self.header[1] if not self.type in TagConfig.barred: Trace.error('Unknown bar type ' + self.type) self.output.tag = 'span' return self.output.tag = TagConfig.barred[self.type] class LangLine(TaggedText): "A line with language information" def process(self): "Only generate a span with lang info when the language is recognized." lang = self.header[1] if not lang in TranslationConfig.languages: self.output = ContentsOutput() return isolang = TranslationConfig.languages[lang] self.output = TaggedOutput().settag('span lang="' + isolang + '"', False) class InsetLength(BlackBox): "A length measure inside an inset." def process(self): self.length = self.header[1] class Space(Container): "A space of several types" def __init__(self): self.parser = InsetParser() self.output = FixedOutput() def process(self): self.type = self.header[2] if self.type not in StyleConfig.hspaces: Trace.error('Unknown space type ' + self.type) self.html = [' '] return self.html = [StyleConfig.hspaces[self.type]] length = self.getlength() if not length: return self.output = TaggedOutput().settag('span class="hspace"', False) ContainerSize().set(length).addstyle(self) def getlength(self): "Get the space length from elyxer.the contents or parameters." if len(self.contents) == 0 or not isinstance(self.contents[0], InsetLength): return None return self.contents[0].length class VerticalSpace(Container): "An inset that contains a vertical space." def __init__(self): self.parser = InsetParser() self.output = FixedOutput() def process(self): "Set the correct tag" self.type = self.header[2] if self.type not in StyleConfig.vspaces: self.output = TaggedOutput().settag('div class="vspace" style="height: ' + self.type + ';"', True) return self.html = [StyleConfig.vspaces[self.type]] class Align(Container): "Bit of aligned text" def __init__(self): self.parser = ExcludingParser() self.output = TaggedOutput().setbreaklines(True) def process(self): self.output.tag = 'div class="' + self.header[1] + '"' class Newline(Container): "A newline" def __init__(self): self.parser = LoneCommand() self.output = FixedOutput() def process(self): "Process contents" self.html = ['
\n'] class NewPage(Newline): "A new page" def process(self): "Process contents" self.html = ['


\n

\n'] class Separator(Container): "A separator string which is not extracted by extracttext()." def __init__(self, constant): self.output = FixedOutput() self.contents = [] self.html = [constant] class StrikeOut(TaggedText): "Striken out text." def process(self): "Set the output tag to strike." self.output.tag = 'strike' class StartAppendix(BlackBox): "Mark to start an appendix here." "From this point on, all chapters become appendices." def process(self): "Activate the special numbering scheme for appendices, using letters." NumberGenerator.generator.startappendix() class Link(Container): "A link to another part of the document" anchor = None url = None type = None page = None target = None destination = None title = None def __init__(self): "Initialize the link, add target if configured." self.contents = [] self.parser = InsetParser() self.output = LinkOutput() if Options.target: self.target = Options.target def complete(self, text, anchor = None, url = None, type = None, title = None): "Complete the link." self.contents = [Constant(text)] if anchor: self.anchor = anchor if url: self.url = url if type: self.type = type if title: self.title = title return self def computedestination(self): "Use the destination link to fill in the destination URL." if not self.destination: return self.url = '' if self.destination.anchor: self.url = '#' + self.destination.anchor if self.destination.page: self.url = self.destination.page + self.url def setmutualdestination(self, destination): "Set another link as destination, and set its destination to this one." self.destination = destination destination.destination = self def __unicode__(self): "Return a printable representation." result = 'Link' if self.anchor: result += ' #' + self.anchor if self.url: result += ' to ' + self.url return result class URL(Link): "A clickable URL" def process(self): "Read URL from elyxer.parameters" target = self.escape(self.getparameter('target')) self.url = target type = self.getparameter('type') if type: self.url = self.escape(type) + target name = self.getparameter('name') if not name: name = target self.contents = [Constant(name)] class FlexURL(URL): "A flexible URL" def process(self): "Read URL from elyxer.contents" self.url = self.extracttext() class LinkOutput(ContainerOutput): "A link pointing to some destination" "Or an anchor (destination)" def gethtml(self, link): "Get the HTML code for the link" type = link.__class__.__name__ if link.type: type = link.type tag = 'a class="' + type + '"' if link.anchor: tag += ' name="' + link.anchor + '"' if link.destination: link.computedestination() if link.url: tag += ' href="' + link.url + '"' if link.target: tag += ' target="' + link.target + '"' if link.title: tag += ' title="' + link.title + '"' return TaggedOutput().settag(tag).gethtml(link) class Postprocessor(object): "Postprocess a container keeping some context" stages = [] def __init__(self): self.stages = StageDict(Postprocessor.stages, self) self.current = None self.last = None def postprocess(self, next): "Postprocess a container and its contents." self.postrecursive(self.current) result = self.postcurrent(next) self.last = self.current self.current = next return result def postrecursive(self, container): "Postprocess the container contents recursively" if not hasattr(container, 'contents'): return if len(container.contents) == 0: return if hasattr(container, 'postprocess'): if not container.postprocess: return postprocessor = Postprocessor() contents = [] for element in container.contents: post = postprocessor.postprocess(element) if post: contents.append(post) # two rounds to empty the pipeline for i in range(2): post = postprocessor.postprocess(None) if post: contents.append(post) container.contents = contents def postcurrent(self, next): "Postprocess the current element taking into account next and last." stage = self.stages.getstage(self.current) if not stage: return self.current return stage.postprocess(self.last, self.current, next) class StageDict(object): "A dictionary of stages corresponding to classes" def __init__(self, classes, postprocessor): "Instantiate an element from elyxer.each class and store as a dictionary" instances = self.instantiate(classes, postprocessor) self.stagedict = dict([(x.processedclass, x) for x in instances]) def instantiate(self, classes, postprocessor): "Instantiate an element from elyxer.each class" stages = [x.__new__(x) for x in classes] for element in stages: element.__init__() element.postprocessor = postprocessor return stages def getstage(self, element): "Get the stage for a given element, if the type is in the dict" if not element.__class__ in self.stagedict: return None return self.stagedict[element.__class__] class Label(Link): "A label to be referenced" names = dict() lastlayout = None def __init__(self): Link.__init__(self) self.lastnumbered = None def process(self): "Process a label container." key = self.getparameter('name') self.create(' ', key) self.lastnumbered = Label.lastlayout def create(self, text, key, type = 'Label'): "Create the label for a given key." self.key = key self.complete(text, anchor = key, type = type) Label.names[key] = self if key in Reference.references: for reference in Reference.references[key]: reference.destination = self return self def findpartkey(self): "Get the part key for the latest numbered container seen." numbered = self.numbered(self) if numbered and numbered.partkey: return numbered.partkey return '' def numbered(self, container): "Get the numbered container for the label." if container.partkey: return container if not container.parent: if self.lastnumbered: return self.lastnumbered return None return self.numbered(container.parent) def __unicode__(self): "Return a printable representation." if not hasattr(self, 'key'): return 'Unnamed label' return 'Label ' + self.key class Reference(Link): "A reference to a label." references = dict() key = 'none' def process(self): "Read the reference and set the arrow." self.key = self.getparameter('reference') if self.key in Label.names: self.direction = u'↑' label = Label.names[self.key] else: self.direction = u'↓' label = Label().complete(' ', self.key, 'preref') self.destination = label self.formatcontents() if not self.key in Reference.references: Reference.references[self.key] = [] Reference.references[self.key].append(self) def formatcontents(self): "Format the reference contents." formatkey = self.getparameter('LatexCommand') if not formatkey: formatkey = 'ref' self.formatted = u'↕' if formatkey in StyleConfig.referenceformats: self.formatted = StyleConfig.referenceformats[formatkey] else: Trace.error('Unknown reference format ' + formatkey) self.replace(u'↕', self.direction) self.replace('#', '1') self.replace('on-page', Translator.translate('on-page')) partkey = self.destination.findpartkey() # only if partkey and partkey.number are not null, send partkey.number self.replace('@', partkey and partkey.number) self.replace(u'¶', partkey and partkey.tocentry) if not '$' in self.formatted or not partkey or not partkey.titlecontents: # there is a $ left, but it should go away on preprocessing self.contents = [Constant(self.formatted)] return pieces = self.formatted.split('$') self.contents = [Constant(pieces[0])] for piece in pieces[1:]: self.contents += partkey.titlecontents self.contents.append(Constant(piece)) def replace(self, key, value): "Replace a key in the format template with a value." if not key in self.formatted: return if not value: value = '' self.formatted = self.formatted.replace(key, value) def __unicode__(self): "Return a printable representation." return 'Reference ' + self.key class HeaderParser(Parser): "Parses the LyX header" def parse(self, reader): "Parse header parameters into a dictionary, return the preamble." contents = [] self.parseending(reader, lambda: self.parseline(reader, contents)) # skip last line reader.nextline() return contents def parseline(self, reader, contents): "Parse a single line as a parameter or as a start" line = reader.currentline() if line.startswith(HeaderConfig.parameters['branch']): self.parsebranch(reader) return elif line.startswith(HeaderConfig.parameters['lstset']): LstParser().parselstset(reader) return elif line.startswith(HeaderConfig.parameters['beginpreamble']): contents.append(self.factory.createcontainer(reader)) return # no match self.parseparameter(reader) def parsebranch(self, reader): "Parse all branch definitions." branch = reader.currentline().split()[1] reader.nextline() subparser = HeaderParser().complete(HeaderConfig.parameters['endbranch']) subparser.parse(reader) options = BranchOptions(branch) for key in subparser.parameters: options.set(key, subparser.parameters[key]) Options.branches[branch] = options def complete(self, ending): "Complete the parser with the given ending." self.ending = ending return self class PreambleParser(Parser): "A parser for the LyX preamble." preamble = [] def parse(self, reader): "Parse the full preamble with all statements." self.ending = HeaderConfig.parameters['endpreamble'] self.parseending(reader, lambda: self.parsepreambleline(reader)) return [] def parsepreambleline(self, reader): "Parse a single preamble line." PreambleParser.preamble.append(reader.currentline()) reader.nextline() class LstParser(object): "Parse global and local lstparams." globalparams = dict() def parselstset(self, reader): "Parse a declaration of lstparams in lstset." paramtext = self.extractlstset(reader) if not '{' in paramtext: Trace.error('Missing opening bracket in lstset: ' + paramtext) return lefttext = paramtext.split('{')[1] croppedtext = lefttext[:-1] LstParser.globalparams = self.parselstparams(croppedtext) def extractlstset(self, reader): "Extract the global lstset parameters." paramtext = '' while not reader.finished(): paramtext += reader.currentline() reader.nextline() if paramtext.endswith('}'): return paramtext Trace.error('Could not find end of \\lstset settings; aborting') def parsecontainer(self, container): "Parse some lstparams from elyxer.a container." container.lstparams = LstParser.globalparams.copy() paramlist = container.getparameterlist('lstparams') container.lstparams.update(self.parselstparams(paramlist)) def parselstparams(self, paramlist): "Process a number of lstparams from elyxer.a list." paramdict = dict() for param in paramlist: if not '=' in param: if len(param.strip()) > 0: Trace.error('Invalid listing parameter ' + param) else: key, value = param.split('=', 1) paramdict[key] = value return paramdict import datetime import os import codecs class BulkFile(object): "A file to treat in bulk" encodings = ['utf-8','Cp1252'] def __init__(self, filename): self.filename = filename self.temp = self.filename + '.temp' def readall(self): "Read the whole file" for encoding in BulkFile.encodings: try: return self.readcodec(encoding) except UnicodeDecodeError: pass Trace.error('No suitable encoding for ' + self.filename) return [] def readcodec(self, encoding): "Read the whole file with the given encoding" filein = codecs.open(self.filename, 'rU', encoding) lines = filein.readlines() result = [] for line in lines: result.append(line.strip('\r\n') + '\n') filein.close() return result def getfiles(self): "Get reader and writer for a file name" reader = LineReader(self.filename) writer = LineWriter(self.temp) return reader, writer def swaptemp(self): "Swap the temp file for the original" os.chmod(self.temp, os.stat(self.filename).st_mode) os.rename(self.temp, self.filename) def __unicode__(self): "Get the unicode representation" return 'file ' + self.filename class HTMLTemplate(object): "A template for HTML generation." current = None def getheader(self): "Get the header (before content) of the template." return [] def convertheader(self): "Convert the header and all variables." return self.convert(self.getheader()) def convertfooter(self): "Convert the footer and all variables." return self.convert(self.getfooter()) def convert(self, html): "Convert a bit of HTML replacing all variables." varmap = VariableMap() for index, line in enumerate(html): if '\n'] def getfooter(self): "Get the raw footer." return ['\n\n'] class FileTemplate(HTMLTemplate): "A template read from elyxer.a file." divider = '' def read(self): "Read the file, separate header and footer." self.header = [] lines = [] for line in self.templatelines(): if FileTemplate.divider == line: self.header = lines lines = [] else: lines.append(line) if self.header == []: Trace.error('No ' + FileTemplate.divider + ' in template') self.header = lines lines = [] self.footer = lines return self def templatelines(self): "Read all lines in the template, separate content into its own line." template = BulkFile(Options.template).readall() for line in template: if not FileTemplate.divider in line: yield line else: split = line.split(FileTemplate.divider) for part in split[:-1]: yield part yield FileTemplate.divider yield split[-1] def getheader(self): "Return the header (before content)." return self.header def getfooter(self): "Return the footer (after the content)." return self.footer class DefaultTemplate(HTMLTemplate): "The default HTML template when not configured." def getheader(self): "Get the default header (before content)." html = [] if not Options.html: html.append(u'"?>\n') html.append(u'\n') html.append(u'\n') else: html.append(u'\n') html.append(u'\n') html.append(u'\n') html.append(u'\n') html.append(u'\n') html.append(u'\n') html += self.getcss() html.append(u'<!--$title-->\n') if Options.jsmath: html.append(u'\n') html.append(u'\n') if Options.mathjax: if Options.mathjax == 'remote': html.append(u'\n') else: html.append(u'\n') html.append('\n') html.append('\n') html.append('
\n') if Options.jsmath or Options.mathjax: if Options.mathjax: html.append(u'\n') html.append(u'\n') return html def getcss(self): "Get the CSS headers, both linked and embedded." html = [] for cssdoc in Options.css: if cssdoc != '': html.append(u'\n') for cssfile in Options.embedcss: html.append(u'\n') return html def getfooter(self): "Get the default footer (after content)." html = [] html.append('\n') footer = self.createfooter() if len(footer) > 0: html.append('\n') html += footer html.append('
\n') html.append('\n') html.append('\n') return html def createfooter(self): "Create the footer proper." html = [] if Options.copyright: html.append('\n') if Options.nofooter: return html html.append('\n') return html class VariableMap(object): "A map with all replacement variables." def __init__(self): self.variables = dict() self.variables['title'] = DocumentTitle().getvalue() self.variables['author'] = DocumentAuthor().getvalue() self.variables['version'] = GeneralConfig.version['number'] + ' (' \ + GeneralConfig.version['date'] + ')' self.variables['year'] = unicode(datetime.date.today().year) self.variables['date'] = datetime.date.today().isoformat() self.variables['datetime'] = datetime.datetime.now().isoformat() self.variables['css'] = Options.css[0] if Options.iso885915: self.variables['encoding'] = 'ISO-8859-1' else: self.variables['encoding'] = 'UTF-8' if Options.jsmath: self.variables['jsmath'] = Options.jsmath if Options.mathjax: self.variables['mathjax'] = Options.mathjax def replace(self, line): "Replace all variables in a line." result = '' pos = TextPosition(line) while not pos.finished(): if pos.checkskip(''): Trace.error('Weird template format in ' + line) return value class DocumentTitle(object): "The title of the whole document." title = None def getvalue(self): "Return the correct title from elyxer.the option or the PDF title." if Options.title: return Options.title if DocumentTitle.title: return DocumentTitle.title if DocumentParameters.pdftitle: return DocumentParameters.pdftitle return 'Converted document' class DocumentAuthor(object): "The author of the document." author = '' def appendauthor(cls, authorline): "Append a line with author information." cls.author += authorline appendauthor = classmethod(appendauthor) def getvalue(self): "Get the document author." return DocumentAuthor.author class HeaderOutput(ContainerOutput): "Returns the HTML headers" def gethtml(self, container): "Return a constant header" return HTMLTemplate.get().convertheader() class FooterOutput(ContentsOutput): "Return the HTML code for the footer" def gethtml(self, container): "Footer HTML" contents = ContentsOutput.gethtml(self, container) return contents + HTMLTemplate.get().convertfooter() class InsetText(Container): "An inset of text in a lyx file" def __init__(self): self.parser = BoundedParser() self.output = ContentsOutput() class Inset(Container): "A generic inset in a LyX document" def __init__(self): self.contents = list() self.parser = InsetParser() self.output = TaggedOutput().setbreaklines(True) def process(self): self.type = self.header[1] self.output.tag = 'span class="' + self.type + '"' def __unicode__(self): return 'Inset of type ' + self.type class NewlineInset(Newline): "A newline or line break in an inset" def __init__(self): self.parser = InsetParser() self.output = FixedOutput() class NewPageInset(NewPage): "A new page command." def __init__(self): self.parser = InsetParser() self.output = FixedOutput() class Branch(Container): "A branch within a LyX document" def __init__(self): self.parser = InsetParser() self.output = TaggedOutput().settag('span class="branch"', True) def process(self): "Disable inactive branches" self.branch = self.header[2] if not self.isactive(): Trace.debug('Branch ' + self.branch + ' not active') self.output = EmptyOutput() def isactive(self): "Check if the branch is active" if not self.branch in Options.branches: Trace.error('Invalid branch ' + self.branch) return True branch = Options.branches[self.branch] return branch.isselected() class ShortTitle(Container): "A short title to display (always hidden)" def __init__(self): self.parser = InsetParser() self.output = EmptyOutput() class FlexInset(Container): "A flexible inset, generic version." def __init__(self): self.parser = InsetParser() self.output = TaggedOutput().settag('span', False) def process(self): "Set the correct flex tag." self.type = self.header[2] if self.type in TagConfig.flex: self.output.settag(TagConfig.flex[self.type], False) else: self.output.settag('span class="' + self.type + '"', False) class InfoInset(Container): "A LyX Info inset" def __init__(self): self.parser = InsetParser() self.output = TaggedOutput().settag('span class="Info"', False) def process(self): "Set the shortcut as text" self.type = self.getparameter('type') self.contents = [Constant(self.getparameter('arg'))] class BoxInset(Container): "A box inset" def __init__(self): self.parser = InsetParser() self.output = TaggedOutput().settag('div', True) def process(self): "Set the correct tag" self.type = self.header[2] self.output.settag('div class="' + self.type + '"', True) ContainerSize().readparameters(self).addstyle(self) class PhantomText(Container): "A line of invisible text (white over white)." def __init__(self): self.parser = InsetParser() self.output = TaggedOutput().settag('span class="phantom"', False) class LineInset(LyXLine): "A LaTeX ruler, but parsed as an inset." def __init__(self): self.parser = InsetParser() self.output = FixedOutput() class Caption(Container): "A caption for a figure or a table" def __init__(self): self.parser = InsetParser() self.output = TaggedOutput().settag('div class="caption"', True) def create(self, message): "Create a caption with a given message." self.contents = [Constant(message)] return self class ScriptInset(Container): "Sub- or super-script in an inset." def __init__(self): self.parser = InsetParser() self.output = TaggedOutput().settag('span', False) def process(self): "Set the correct script tag." self.type = self.header[2] if not self.type in TagConfig.script: Trace.error('Unknown script type ' + self.type) return self.output.settag(TagConfig.script[self.type], False) class PartKey(object): "A key to identify a given document part (chapter, section...)." partkey = None tocentry = None anchortext = None number = None filename = None titlecontents = None header = False def __init__(self): self.level = 0 def createindex(self, partkey): "Create a part key for an index page." self.partkey = partkey self.tocentry = partkey self.filename = partkey return self def createfloat(self, float): "Create a part key for a float." self.number = NumberGenerator.chaptered.generate(float.type) self.partkey = Translator.translate('float-' + float.type) + self.number if Options.notoclabels: self.tocentry = self.number else: self.tocentry = self.partkey self.readtitle(float) return self def createsubfloat(self, number): "Create the part key for a subfloat." self.partkey = '(' + number + ')' self.number = number return self def createformula(self, number): "Create the part key for a formula." self.number = number self.partkey = 'formula-' + number self.tocentry = '(' + number + ')' return self def createheader(self, headorfooter): "Create the part key for a header or footer." self.partkey = headorfooter self.tocentry = None self.header = True return self def createanchor(self, partkey): "Create an anchor for the page." self.partkey = partkey self.tocentry = partkey self.header = True return self def createmain(self): "Create the part key for the main page." self.partkey = '' self.tocentry = DocumentTitle().getvalue() return self def addtoclabel(self, container): "Create the label for the TOC, and add it to the container." labeltext = '' if self.anchortext: labeltext = self.anchortext container.contents.insert(0, Separator(u' ')) label = Label().create(labeltext, self.partkey, type='toc') container.contents.insert(0, label) def readtitle(self, container): "Read the title of the TOC entry." shorttitles = container.searchall(ShortTitle) if len(shorttitles) > 0: self.titlecontents = [] for shorttitle in shorttitles: self.titlecontents += shorttitle.contents return extractor = ContainerExtractor(TOCConfig.extracttitle) captions = container.searchall(Caption) if len(captions) == 1: self.titlecontents = extractor.extract(captions[0]) return self.titlecontents = extractor.extract(container) def __unicode__(self): "Return a printable representation." return 'Part key for ' + self.partkey class LayoutPartKey(PartKey): "The part key for a layout." generator = NumberGenerator() def create(self, layout): "Set the layout for which we are creating the part key." self.processtype(layout.type) self.readtitle(layout) return self def processtype(self, type): "Process the layout type." self.level = self.generator.getlevel(type) self.number = self.generator.generate(type) anchortype = self.getanchortype(type) self.partkey = 'toc-' + anchortype + '-' + self.number self.tocentry = self.gettocentry(type) self.filename = self.getfilename(type) if self.generator.isnumbered(type): if not self.tocentry: self.tocentry = '' else: self.tocentry += ' ' self.tocentry += self.number self.anchortext = self.getanchortext(type) def getanchortype(self, type): "Get the type for the anchor." parttype = self.generator.getparttype(type) if self.generator.isunordered(type): parttype += '-' return parttype def gettocentry(self, type): "Get the entry for the TOC: Chapter, Section..." if Options.notoclabels: return '' return Translator.translate(self.generator.getparttype(type)) def addtotocentry(self, text): "Add some text to the tocentry; create if None." if not self.tocentry: self.tocentry = '' self.tocentry += text def getanchortext(self, type): "Get the text for the anchor given to a layout type." if self.generator.isunique(type): return self.tocentry + '.' return self.number def getfilename(self, type): "Get the filename to be used if splitpart is active." if self.level == Options.splitpart and self.generator.isnumbered(type): return self.number if self.level <= Options.splitpart: return self.partkey.replace('toc-', '') return None def needspartkey(self, layout): "Find out if a layout needs a part key." if self.generator.isunique(layout.type): return True return self.generator.isinordered(layout.type) def __unicode__(self): "Get a printable representation." return 'Part key for layout ' + self.tocentry class PartKeyGenerator(object): "Number a layout with the relevant attributes." partkeyed = [] layoutpartkey = LayoutPartKey() def forlayout(cls, layout): "Get the part key for a layout." if layout.hasemptyoutput(): return None if not cls.layoutpartkey.needspartkey(layout): return None Label.lastlayout = layout cls.partkeyed.append(layout) return LayoutPartKey().create(layout) def forindex(cls, index): "Get the part key for an index or nomenclature." if index.hasemptyoutput(): return None cls.partkeyed.append(index) return PartKey().createindex(index.name) forlayout = classmethod(forlayout) forindex = classmethod(forindex) import unicodedata import urllib class FormulaParser(Parser): "Parses a formula" def parseheader(self, reader): "See if the formula is inlined" self.begin = reader.linenumber + 1 type = self.parsetype(reader) if not type: reader.nextline() type = self.parsetype(reader) if not type: Trace.error('Unknown formula type in ' + reader.currentline().strip()) return ['unknown'] return [type] def parsetype(self, reader): "Get the formula type from the first line." if reader.currentline().find(FormulaConfig.starts['simple']) >= 0: return 'inline' if reader.currentline().find(FormulaConfig.starts['complex']) >= 0: return 'block' if reader.currentline().find(FormulaConfig.starts['unnumbered']) >= 0: return 'block' if reader.currentline().find(FormulaConfig.starts['beginbefore']) >= 0: return 'numbered' return None def parse(self, reader): "Parse the formula until the end" formula = self.parseformula(reader) while not reader.currentline().startswith(self.ending): stripped = reader.currentline().strip() if len(stripped) > 0: Trace.error('Unparsed formula line ' + stripped) reader.nextline() reader.nextline() return formula def parseformula(self, reader): "Parse the formula contents" simple = FormulaConfig.starts['simple'] if simple in reader.currentline(): rest = reader.currentline().split(simple, 1)[1] if simple in rest: # formula is $...$ return self.parsesingleliner(reader, simple, simple) # formula is multiline $...$ return self.parsemultiliner(reader, simple, simple) if FormulaConfig.starts['complex'] in reader.currentline(): # formula of the form \[...\] return self.parsemultiliner(reader, FormulaConfig.starts['complex'], FormulaConfig.endings['complex']) beginbefore = FormulaConfig.starts['beginbefore'] beginafter = FormulaConfig.starts['beginafter'] if beginbefore in reader.currentline(): if reader.currentline().strip().endswith(beginafter): current = reader.currentline().strip() endsplit = current.split(beginbefore)[1].split(beginafter) startpiece = beginbefore + endsplit[0] + beginafter endbefore = FormulaConfig.endings['endbefore'] endafter = FormulaConfig.endings['endafter'] endpiece = endbefore + endsplit[0] + endafter return startpiece + self.parsemultiliner(reader, startpiece, endpiece) + endpiece Trace.error('Missing ' + beginafter + ' in ' + reader.currentline()) return '' begincommand = FormulaConfig.starts['command'] beginbracket = FormulaConfig.starts['bracket'] if begincommand in reader.currentline() and beginbracket in reader.currentline(): endbracket = FormulaConfig.endings['bracket'] return self.parsemultiliner(reader, beginbracket, endbracket) Trace.error('Formula beginning ' + reader.currentline() + ' is unknown') return '' def parsesingleliner(self, reader, start, ending): "Parse a formula in one line" line = reader.currentline().strip() if not start in line: Trace.error('Line ' + line + ' does not contain formula start ' + start) return '' if not line.endswith(ending): Trace.error('Formula ' + line + ' does not end with ' + ending) return '' index = line.index(start) rest = line[index + len(start):-len(ending)] reader.nextline() return rest def parsemultiliner(self, reader, start, ending): "Parse a formula in multiple lines" formula = '' line = reader.currentline() if not start in line: Trace.error('Line ' + line.strip() + ' does not contain formula start ' + start) return '' index = line.index(start) line = line[index + len(start):].strip() while not line.endswith(ending): formula += line + '\n' reader.nextline() line = reader.currentline() formula += line[:-len(ending)] reader.nextline() return formula class MacroParser(FormulaParser): "A parser for a formula macro." def parseheader(self, reader): "See if the formula is inlined" self.begin = reader.linenumber + 1 return ['inline'] def parse(self, reader): "Parse the formula until the end" formula = self.parsemultiliner(reader, self.parent.start, self.ending) reader.nextline() return formula class FormulaBit(Container): "A bit of a formula" type = None size = 1 original = '' def __init__(self): "The formula bit type can be 'alpha', 'number', 'font'." self.contents = [] self.output = ContentsOutput() def setfactory(self, factory): "Set the internal formula factory." self.factory = factory return self def add(self, bit): "Add any kind of formula bit already processed" self.contents.append(bit) self.original += bit.original bit.parent = self def skiporiginal(self, string, pos): "Skip a string and add it to the original formula" self.original += string if not pos.checkskip(string): Trace.error('String ' + string + ' not at ' + pos.identifier()) def computesize(self): "Compute the size of the bit as the max of the sizes of all contents." if len(self.contents) == 0: return 1 self.size = max([element.size for element in self.contents]) return self.size def clone(self): "Return a copy of itself." return self.factory.parseformula(self.original) def __unicode__(self): "Get a string representation" return self.__class__.__name__ + ' read in ' + self.original class TaggedBit(FormulaBit): "A tagged string in a formula" def constant(self, constant, tag): "Set the constant and the tag" self.output = TaggedOutput().settag(tag) self.add(FormulaConstant(constant)) return self def complete(self, contents, tag, breaklines = False): "Set the constant and the tag" self.contents = contents self.output = TaggedOutput().settag(tag, breaklines) return self def selfcomplete(self, tag): "Set the self-closing tag, no contents (as in
)." self.output = TaggedOutput().settag(tag, empty = True) return self class FormulaConstant(Constant): "A constant string in a formula" def __init__(self, string): "Set the constant string" Constant.__init__(self, string) self.original = string self.size = 1 self.type = None def computesize(self): "Compute the size of the constant: always 1." return self.size def clone(self): "Return a copy of itself." return FormulaConstant(self.original) def __unicode__(self): "Return a printable representation." return 'Formula constant: ' + self.string class RawText(FormulaBit): "A bit of text inside a formula" def detect(self, pos): "Detect a bit of raw text" return pos.current().isalpha() def parsebit(self, pos): "Parse alphabetic text" alpha = pos.globalpha() self.add(FormulaConstant(alpha)) self.type = 'alpha' class FormulaSymbol(FormulaBit): "A symbol inside a formula" modified = FormulaConfig.modified unmodified = FormulaConfig.unmodified['characters'] def detect(self, pos): "Detect a symbol" if pos.current() in FormulaSymbol.unmodified: return True if pos.current() in FormulaSymbol.modified: return True return False def parsebit(self, pos): "Parse the symbol" if pos.current() in FormulaSymbol.unmodified: self.addsymbol(pos.current(), pos) return if pos.current() in FormulaSymbol.modified: self.addsymbol(FormulaSymbol.modified[pos.current()], pos) return Trace.error('Symbol ' + pos.current() + ' not found') def addsymbol(self, symbol, pos): "Add a symbol" self.skiporiginal(pos.current(), pos) self.contents.append(FormulaConstant(symbol)) class FormulaNumber(FormulaBit): "A string of digits in a formula" def detect(self, pos): "Detect a digit" return pos.current().isdigit() def parsebit(self, pos): "Parse a bunch of digits" digits = pos.glob(lambda: pos.current().isdigit()) self.add(FormulaConstant(digits)) self.type = 'number' class Comment(FormulaBit): "A LaTeX comment: % to the end of the line." start = FormulaConfig.starts['comment'] def detect(self, pos): "Detect the %." return pos.current() == self.start def parsebit(self, pos): "Parse to the end of the line." self.original += pos.globincluding('\n') class WhiteSpace(FormulaBit): "Some white space inside a formula." def detect(self, pos): "Detect the white space." return pos.current().isspace() def parsebit(self, pos): "Parse all whitespace." self.original += pos.skipspace() def __unicode__(self): "Return a printable representation." return 'Whitespace: *' + self.original + '*' class Bracket(FormulaBit): "A {} bracket inside a formula" start = FormulaConfig.starts['bracket'] ending = FormulaConfig.endings['bracket'] def __init__(self): "Create a (possibly literal) new bracket" FormulaBit.__init__(self) self.inner = None def detect(self, pos): "Detect the start of a bracket" return pos.checkfor(self.start) def parsebit(self, pos): "Parse the bracket" self.parsecomplete(pos, self.innerformula) return self def parsetext(self, pos): "Parse a text bracket" self.parsecomplete(pos, self.innertext) return self def parseliteral(self, pos): "Parse a literal bracket" self.parsecomplete(pos, self.innerliteral) return self def parsecomplete(self, pos, innerparser): "Parse the start and end marks" if not pos.checkfor(self.start): Trace.error('Bracket should start with ' + self.start + ' at ' + pos.identifier()) return None self.skiporiginal(self.start, pos) pos.pushending(self.ending) innerparser(pos) self.original += pos.popending(self.ending) self.computesize() def innerformula(self, pos): "Parse a whole formula inside the bracket" while not pos.finished(): self.add(self.factory.parseany(pos)) def innertext(self, pos): "Parse some text inside the bracket, following textual rules." specialchars = FormulaConfig.symbolfunctions.keys() specialchars.append(FormulaConfig.starts['command']) specialchars.append(FormulaConfig.starts['bracket']) specialchars.append(Comment.start) while not pos.finished(): if pos.current() in specialchars: self.add(self.factory.parseany(pos)) if pos.checkskip(' '): self.original += ' ' else: self.add(FormulaConstant(pos.skipcurrent())) def innerliteral(self, pos): "Parse a literal inside the bracket, which does not generate HTML." self.literal = '' while not pos.finished() and not pos.current() == self.ending: if pos.current() == self.start: self.parseliteral(pos) else: self.literal += pos.skipcurrent() self.original += self.literal class SquareBracket(Bracket): "A [] bracket inside a formula" start = FormulaConfig.starts['squarebracket'] ending = FormulaConfig.endings['squarebracket'] def clone(self): "Return a new square bracket with the same contents." bracket = SquareBracket() bracket.contents = self.contents return bracket class MathsProcessor(object): "A processor for a maths construction inside the FormulaProcessor." def process(self, contents, index): "Process an element inside a formula." Trace.error('Unimplemented process() in ' + unicode(self)) def __unicode__(self): "Return a printable description." return 'Maths processor ' + self.__class__.__name__ class FormulaProcessor(object): "A processor specifically for formulas." processors = [] def process(self, bit): "Process the contents of every formula bit, recursively." self.processcontents(bit) self.processinsides(bit) self.traversewhole(bit) def processcontents(self, bit): "Process the contents of a formula bit." if not isinstance(bit, FormulaBit): return bit.process() for element in bit.contents: self.processcontents(element) def processinsides(self, bit): "Process the insides (limits, brackets) in a formula bit." if not isinstance(bit, FormulaBit): return for index, element in enumerate(bit.contents): for processor in self.processors: processor.process(bit.contents, index) # continue with recursive processing self.processinsides(element) def traversewhole(self, formula): "Traverse over the contents to alter variables and space units." last = None for bit, contents in self.traverse(formula): if bit.type == 'alpha': self.italicize(bit, contents) elif bit.type == 'font' and last and last.type == 'number': bit.contents.insert(0, FormulaConstant(u' ')) last = bit def traverse(self, bit): "Traverse a formula and yield a flattened structure of (bit, list) pairs." for element in bit.contents: if hasattr(element, 'type') and element.type: yield (element, bit.contents) elif isinstance(element, FormulaBit): for pair in self.traverse(element): yield pair def italicize(self, bit, contents): "Italicize the given bit of text." index = contents.index(bit) contents[index] = TaggedBit().complete([bit], 'i') class Formula(Container): "A LaTeX formula" def __init__(self): self.parser = FormulaParser() self.output = TaggedOutput().settag('span class="formula"') def process(self): "Convert the formula to tags" if self.header[0] == 'inline': DocumentParameters.displaymode = False else: DocumentParameters.displaymode = True self.output.settag('div class="formula"', True) if Options.jsmath: self.jsmath() elif Options.mathjax: self.mathjax() elif Options.googlecharts: self.googlecharts() else: self.classic() def jsmath(self): "Make the contents for jsMath." if self.header[0] != 'inline': self.output = TaggedOutput().settag('div class="math"') else: self.output = TaggedOutput().settag('span class="math"') self.contents = [Constant(self.parsed)] def mathjax(self): "Make the contents for MathJax." self.output.tag = 'span class="MathJax_Preview"' tag = 'script type="math/tex' if self.header[0] != 'inline': tag += ';mode=display' self.contents = [TaggedText().constant(self.parsed, tag + '"', True)] def googlecharts(self): "Make the contents using Google Charts http://code.google.com/apis/chart/." url = FormulaConfig.urls['googlecharts'] + urllib.quote_plus(self.parsed) img = '' + self.parsed + '' self.contents = [Constant(img)] def classic(self): "Make the contents using classic output generation with XHTML and CSS." whole = FormulaFactory().parseformula(self.parsed) FormulaProcessor().process(whole) whole.parent = self self.contents = [whole] def parse(self, pos): "Parse using a parse position instead of self.parser." if pos.checkskip('$$'): self.parsedollarblock(pos) elif pos.checkskip('$'): self.parsedollarinline(pos) elif pos.checkskip('\\('): self.parseinlineto(pos, '\\)') elif pos.checkskip('\\['): self.parseblockto(pos, '\\]') else: pos.error('Unparseable formula') self.process() return self def parsedollarinline(self, pos): "Parse a $...$ formula." self.header = ['inline'] self.parsedollar(pos) def parsedollarblock(self, pos): "Parse a $$...$$ formula." self.header = ['block'] self.parsedollar(pos) if not pos.checkskip('$'): pos.error('Formula should be $$...$$, but last $ is missing.') def parsedollar(self, pos): "Parse to the next $." pos.pushending('$') self.parsed = pos.globexcluding('$') pos.popending('$') def parseinlineto(self, pos, limit): "Parse a \\(...\\) formula." self.header = ['inline'] self.parseupto(pos, limit) def parseblockto(self, pos, limit): "Parse a \\[...\\] formula." self.header = ['block'] self.parseupto(pos, limit) def parseupto(self, pos, limit): "Parse a formula that ends with the given command." pos.pushending(limit) self.parsed = pos.glob(lambda: True) pos.popending(limit) def __unicode__(self): "Return a printable representation." if self.partkey and self.partkey.number: return 'Formula (' + self.partkey.number + ')' return 'Unnumbered formula' class WholeFormula(FormulaBit): "Parse a whole formula" def detect(self, pos): "Not outside the formula is enough." return not pos.finished() def parsebit(self, pos): "Parse with any formula bit" while not pos.finished(): self.add(self.factory.parseany(pos)) class FormulaFactory(object): "Construct bits of formula" # bit types will be appended later types = [FormulaSymbol, RawText, FormulaNumber, Bracket, Comment, WhiteSpace] skippedtypes = [Comment, WhiteSpace] defining = False def __init__(self): "Initialize the map of instances." self.instances = dict() def detecttype(self, type, pos): "Detect a bit of a given type." if pos.finished(): return False return self.instance(type).detect(pos) def instance(self, type): "Get an instance of the given type." if not type in self.instances or not self.instances[type]: self.instances[type] = self.create(type) return self.instances[type] def create(self, type): "Create a new formula bit of the given type." return Cloner.create(type).setfactory(self) def clearskipped(self, pos): "Clear any skipped types." while not pos.finished(): if not self.skipany(pos): return return def skipany(self, pos): "Skip any skipped types." for type in self.skippedtypes: if self.instance(type).detect(pos): return self.parsetype(type, pos) return None def parseany(self, pos): "Parse any formula bit at the current location." for type in self.types + self.skippedtypes: if self.detecttype(type, pos): return self.parsetype(type, pos) Trace.error('Unrecognized formula at ' + pos.identifier()) return FormulaConstant(pos.skipcurrent()) def parsetype(self, type, pos): "Parse the given type and return it." bit = self.instance(type) self.instances[type] = None returnedbit = bit.parsebit(pos) if returnedbit: return returnedbit.setfactory(self) return bit def parseformula(self, formula): "Parse a string of text that contains a whole formula." pos = TextPosition(formula) whole = self.create(WholeFormula) if whole.detect(pos): whole.parsebit(pos) return whole # no formula found if not pos.finished(): Trace.error('Unknown formula at: ' + pos.identifier()) whole.add(TaggedBit().constant(formula, 'span class="unknown"')) return whole class FormulaCommand(FormulaBit): "A LaTeX command inside a formula" types = [] start = FormulaConfig.starts['command'] commandmap = None def detect(self, pos): "Find the current command." return pos.checkfor(FormulaCommand.start) def parsebit(self, pos): "Parse the command." command = self.extractcommand(pos) bit = self.parsewithcommand(command, pos) if bit: return bit if command.startswith('\\up') or command.startswith('\\Up'): upgreek = self.parseupgreek(command, pos) if upgreek: return upgreek if not self.factory.defining: Trace.error('Unknown command ' + command) self.output = TaggedOutput().settag('span class="unknown"') self.add(FormulaConstant(command)) return None def parsewithcommand(self, command, pos): "Parse the command type once we have the command." for type in FormulaCommand.types: if command in type.commandmap: return self.parsecommandtype(command, type, pos) return None def parsecommandtype(self, command, type, pos): "Parse a given command type." bit = self.factory.create(type) bit.setcommand(command) returned = bit.parsebit(pos) if returned: return returned return bit def extractcommand(self, pos): "Extract the command from elyxer.the current position." if not pos.checkskip(FormulaCommand.start): pos.error('Missing command start ' + FormulaCommand.start) return if pos.finished(): return self.emptycommand(pos) if pos.current().isalpha(): # alpha command command = FormulaCommand.start + pos.globalpha() # skip mark of short command pos.checkskip('*') return command # symbol command return FormulaCommand.start + pos.skipcurrent() def emptycommand(self, pos): """Check for an empty command: look for command disguised as ending. Special case against '{ \{ \} }' situation.""" command = '' if not pos.isout(): ending = pos.nextending() if ending and pos.checkskip(ending): command = ending return FormulaCommand.start + command def parseupgreek(self, command, pos): "Parse the Greek \\up command.." if len(command) < 4: return None if command.startswith('\\up'): upcommand = '\\' + command[3:] elif pos.checkskip('\\Up'): upcommand = '\\' + command[3:4].upper() + command[4:] else: Trace.error('Impossible upgreek command: ' + command) return upgreek = self.parsewithcommand(upcommand, pos) if upgreek: upgreek.type = 'font' return upgreek class CommandBit(FormulaCommand): "A formula bit that includes a command" def setcommand(self, command): "Set the command in the bit" self.command = command if self.commandmap: self.original += command self.translated = self.commandmap[self.command] def parseparameter(self, pos): "Parse a parameter at the current position" self.factory.clearskipped(pos) if pos.finished(): return None parameter = self.factory.parseany(pos) self.add(parameter) return parameter def parsesquare(self, pos): "Parse a square bracket" self.factory.clearskipped(pos) if not self.factory.detecttype(SquareBracket, pos): return None bracket = self.factory.parsetype(SquareBracket, pos) self.add(bracket) return bracket def parseliteral(self, pos): "Parse a literal bracket." self.factory.clearskipped(pos) if not self.factory.detecttype(Bracket, pos): if not pos.isvalue(): Trace.error('No literal parameter found at: ' + pos.identifier()) return None return pos.globvalue() bracket = Bracket().setfactory(self.factory) self.add(bracket.parseliteral(pos)) return bracket.literal def parsesquareliteral(self, pos): "Parse a square bracket literally." self.factory.clearskipped(pos) if not self.factory.detecttype(SquareBracket, pos): return None bracket = SquareBracket().setfactory(self.factory) self.add(bracket.parseliteral(pos)) return bracket.literal def parsetext(self, pos): "Parse a text parameter." self.factory.clearskipped(pos) if not self.factory.detecttype(Bracket, pos): Trace.error('No text parameter for ' + self.command) return None bracket = Bracket().setfactory(self.factory).parsetext(pos) self.add(bracket) return bracket class EmptyCommand(CommandBit): "An empty command (without parameters)" commandmap = FormulaConfig.commands def parsebit(self, pos): "Parse a command without parameters" self.contents = [FormulaConstant(self.translated)] class SpacedCommand(CommandBit): "An empty command which should have math spacing in formulas." commandmap = FormulaConfig.spacedcommands def parsebit(self, pos): "Place as contents the command translated and spaced." self.contents = [FormulaConstant(u' ' + self.translated + u' ')] class AlphaCommand(EmptyCommand): "A command without paramters whose result is alphabetical" commandmap = FormulaConfig.alphacommands def parsebit(self, pos): "Parse the command and set type to alpha" EmptyCommand.parsebit(self, pos) self.type = 'alpha' class OneParamFunction(CommandBit): "A function of one parameter" commandmap = FormulaConfig.onefunctions simplified = False def parsebit(self, pos): "Parse a function with one parameter" self.output = TaggedOutput().settag(self.translated) self.parseparameter(pos) self.simplifyifpossible() def simplifyifpossible(self): "Try to simplify to a single character." if self.original in self.commandmap: self.output = FixedOutput() self.html = [self.commandmap[self.original]] self.simplified = True class SymbolFunction(CommandBit): "Find a function which is represented by a symbol (like _ or ^)" commandmap = FormulaConfig.symbolfunctions def detect(self, pos): "Find the symbol" return pos.current() in SymbolFunction.commandmap def parsebit(self, pos): "Parse the symbol" self.setcommand(pos.current()) pos.skip(self.command) self.output = TaggedOutput().settag(self.translated) self.parseparameter(pos) class TextFunction(CommandBit): "A function where parameters are read as text." commandmap = FormulaConfig.textfunctions def parsebit(self, pos): "Parse a text parameter" self.output = TaggedOutput().settag(self.translated) self.parsetext(pos) def process(self): "Set the type to font" self.type = 'font' class LabelFunction(CommandBit): "A function that acts as a label" commandmap = FormulaConfig.labelfunctions def parsebit(self, pos): "Parse a literal parameter" self.key = self.parseliteral(pos) def process(self): "Add an anchor with the label contents." self.type = 'font' self.label = Label().create(' ', self.key, type = 'eqnumber') self.contents = [self.label] # store as a Label so we know it's been seen Label.names[self.key] = self.label class FontFunction(OneParamFunction): "A function of one parameter that changes the font" commandmap = FormulaConfig.fontfunctions def process(self): "Simplify if possible using a single character." self.type = 'font' self.simplifyifpossible() FormulaFactory.types += [FormulaCommand, SymbolFunction] FormulaCommand.types = [ AlphaCommand, EmptyCommand, OneParamFunction, FontFunction, LabelFunction, TextFunction, SpacedCommand, ] class BigSymbol(object): "A big symbol generator." symbols = FormulaConfig.bigsymbols def __init__(self, symbol): "Create the big symbol." self.symbol = symbol def getpieces(self): "Get an array with all pieces." if not self.symbol in self.symbols: return [self.symbol] if self.smalllimit(): return [self.symbol] return self.symbols[self.symbol] def smalllimit(self): "Decide if the limit should be a small, one-line symbol." if not DocumentParameters.displaymode: return True if len(self.symbols[self.symbol]) == 1: return True return Options.simplemath class BigBracket(BigSymbol): "A big bracket generator." def __init__(self, size, bracket, alignment='l'): "Set the size and symbol for the bracket." self.size = size self.original = bracket self.alignment = alignment self.pieces = None if bracket in FormulaConfig.bigbrackets: self.pieces = FormulaConfig.bigbrackets[bracket] def getpiece(self, index): "Return the nth piece for the bracket." function = getattr(self, 'getpiece' + unicode(len(self.pieces))) return function(index) def getpiece1(self, index): "Return the only piece for a single-piece bracket." return self.pieces[0] def getpiece3(self, index): "Get the nth piece for a 3-piece bracket: parenthesis or square bracket." if index == 0: return self.pieces[0] if index == self.size - 1: return self.pieces[-1] return self.pieces[1] def getpiece4(self, index): "Get the nth piece for a 4-piece bracket: curly bracket." if index == 0: return self.pieces[0] if index == self.size - 1: return self.pieces[3] if index == (self.size - 1)/2: return self.pieces[2] return self.pieces[1] def getcell(self, index): "Get the bracket piece as an array cell." piece = self.getpiece(index) span = 'span class="bracket align-' + self.alignment + '"' return TaggedBit().constant(piece, span) def getcontents(self): "Get the bracket as an array or as a single bracket." if self.size == 1 or not self.pieces: return self.getsinglebracket() rows = [] for index in range(self.size): cell = self.getcell(index) rows.append(TaggedBit().complete([cell], 'span class="arrayrow"')) return [TaggedBit().complete(rows, 'span class="array"')] def getsinglebracket(self): "Return the bracket as a single sign." if self.original == '.': return [TaggedBit().constant('', 'span class="emptydot"')] return [TaggedBit().constant(self.original, 'span class="symbol"')] class FormulaEquation(CommandBit): "A simple numbered equation." piece = 'equation' def parsebit(self, pos): "Parse the array" self.output = ContentsOutput() self.add(self.factory.parsetype(WholeFormula, pos)) class FormulaCell(FormulaCommand): "An array cell inside a row" def setalignment(self, alignment): self.alignment = alignment self.output = TaggedOutput().settag('span class="arraycell align-' + alignment +'"', True) return self def parsebit(self, pos): self.factory.clearskipped(pos) if pos.finished(): return self.add(self.factory.parsetype(WholeFormula, pos)) class FormulaRow(FormulaCommand): "An array row inside an array" cellseparator = FormulaConfig.array['cellseparator'] def setalignments(self, alignments): self.alignments = alignments self.output = TaggedOutput().settag('span class="arrayrow"', True) return self def parsebit(self, pos): "Parse a whole row" index = 0 pos.pushending(self.cellseparator, optional=True) while not pos.finished(): cell = self.createcell(index) cell.parsebit(pos) self.add(cell) index += 1 pos.checkskip(self.cellseparator) if len(self.contents) == 0: self.output = EmptyOutput() def createcell(self, index): "Create the cell that corresponds to the given index." alignment = self.alignments[index % len(self.alignments)] return self.factory.create(FormulaCell).setalignment(alignment) class MultiRowFormula(CommandBit): "A formula with multiple rows." def parserows(self, pos): "Parse all rows, finish when no more row ends" self.rows = [] first = True for row in self.iteraterows(pos): if first: first = False else: # intersparse empty rows self.addempty() row.parsebit(pos) self.addrow(row) self.size = len(self.rows) def iteraterows(self, pos): "Iterate over all rows, end when no more row ends" rowseparator = FormulaConfig.array['rowseparator'] while True: pos.pushending(rowseparator, True) row = self.factory.create(FormulaRow) yield row.setalignments(self.alignments) if pos.checkfor(rowseparator): self.original += pos.popending(rowseparator) else: return def addempty(self): "Add an empty row." row = self.factory.create(FormulaRow).setalignments(self.alignments) for index, originalcell in enumerate(self.rows[-1].contents): cell = row.createcell(index) cell.add(FormulaConstant(u' ')) row.add(cell) self.addrow(row) def addrow(self, row): "Add a row to the contents and to the list of rows." self.rows.append(row) self.add(row) class FormulaArray(MultiRowFormula): "An array within a formula" piece = 'array' def parsebit(self, pos): "Parse the array" self.output = TaggedOutput().settag('span class="array"', False) self.parsealignments(pos) self.parserows(pos) def parsealignments(self, pos): "Parse the different alignments" # vertical self.valign = 'c' literal = self.parsesquareliteral(pos) if literal: self.valign = literal # horizontal literal = self.parseliteral(pos) self.alignments = [] for l in literal: self.alignments.append(l) class FormulaMatrix(MultiRowFormula): "A matrix (array with center alignment)." piece = 'matrix' def parsebit(self, pos): "Parse the matrix, set alignments to 'c'." self.output = TaggedOutput().settag('span class="array"', False) self.valign = 'c' self.alignments = ['c'] self.parserows(pos) class FormulaCases(MultiRowFormula): "A cases statement" piece = 'cases' def parsebit(self, pos): "Parse the cases" self.output = ContentsOutput() self.alignments = ['l', 'l'] self.parserows(pos) for row in self.contents: for cell in row.contents: cell.output.settag('span class="case align-l"', True) cell.contents.append(FormulaConstant(u' ')) array = TaggedBit().complete(self.contents, 'span class="bracketcases"', True) brace = BigBracket(len(self.contents), '{', 'l') self.contents = brace.getcontents() + [array] class EquationEnvironment(MultiRowFormula): "A \\begin{}...\\end equation environment with rows and cells." def parsebit(self, pos): "Parse the whole environment." self.output = TaggedOutput().settag('span class="environment"', False) environment = self.piece.replace('*', '') if environment in FormulaConfig.environments: self.alignments = FormulaConfig.environments[environment] else: Trace.error('Unknown equation environment ' + self.piece) self.alignments = ['l'] self.parserows(pos) class BeginCommand(CommandBit): "A \\begin{}...\end command and what it entails (array, cases, aligned)" commandmap = {FormulaConfig.array['begin']:''} types = [FormulaEquation, FormulaArray, FormulaCases, FormulaMatrix] def parsebit(self, pos): "Parse the begin command" command = self.parseliteral(pos) bit = self.findbit(command) ending = FormulaConfig.array['end'] + '{' + command + '}' pos.pushending(ending) bit.parsebit(pos) self.add(bit) self.original += pos.popending(ending) self.size = bit.size def findbit(self, piece): "Find the command bit corresponding to the \\begin{piece}" for type in BeginCommand.types: if piece.replace('*', '') == type.piece: return self.factory.create(type) bit = self.factory.create(EquationEnvironment) bit.piece = piece return bit FormulaCommand.types += [BeginCommand] import datetime class CombiningFunction(OneParamFunction): commandmap = FormulaConfig.combiningfunctions def parsebit(self, pos): "Parse a combining function." self.type = 'alpha' combining = self.translated parameter = self.parsesingleparameter(pos) if not parameter: Trace.error('Empty parameter for combining function ' + self.command) elif len(parameter.extracttext()) != 1: Trace.error('Applying combining function ' + self.command + ' to invalid string "' + parameter.extracttext() + '"') self.contents.append(Constant(combining)) def parsesingleparameter(self, pos): "Parse a parameter, or a single letter." self.factory.clearskipped(pos) if pos.finished(): Trace.error('Error while parsing single parameter at ' + pos.identifier()) return None if self.factory.detecttype(Bracket, pos) \ or self.factory.detecttype(FormulaCommand, pos): return self.parseparameter(pos) letter = FormulaConstant(pos.skipcurrent()) self.add(letter) return letter class DecoratingFunction(OneParamFunction): "A function that decorates some bit of text" commandmap = FormulaConfig.decoratingfunctions def parsebit(self, pos): "Parse a decorating function" self.type = 'alpha' symbol = self.translated self.symbol = TaggedBit().constant(symbol, 'span class="symbolover"') self.parameter = self.parseparameter(pos) self.output = TaggedOutput().settag('span class="withsymbol"') self.contents.insert(0, self.symbol) self.parameter.output = TaggedOutput().settag('span class="undersymbol"') self.simplifyifpossible() class LimitCommand(EmptyCommand): "A command which accepts limits above and below, in display mode." commandmap = FormulaConfig.limitcommands def parsebit(self, pos): "Parse a limit command." pieces = BigSymbol(self.translated).getpieces() self.output = TaggedOutput().settag('span class="limits"') for piece in pieces: self.contents.append(TaggedBit().constant(piece, 'span class="limit"')) class LimitPreviousCommand(LimitCommand): "A command to limit the previous command." commandmap = None def parsebit(self, pos): "Do nothing." self.output = TaggedOutput().settag('span class="limits"') self.factory.clearskipped(pos) def __unicode__(self): "Return a printable representation." return 'Limit previous command' class LimitsProcessor(MathsProcessor): "A processor for limits inside an element." def process(self, contents, index): "Process the limits for an element." if Options.simplemath: return if self.checklimits(contents, index): self.modifylimits(contents, index) if self.checkscript(contents, index) and self.checkscript(contents, index + 1): self.modifyscripts(contents, index) def checklimits(self, contents, index): "Check if the current position has a limits command." if not DocumentParameters.displaymode: return False if self.checkcommand(contents, index + 1, LimitPreviousCommand): self.limitsahead(contents, index) return False if not isinstance(contents[index], LimitCommand): return False return self.checkscript(contents, index + 1) def limitsahead(self, contents, index): "Limit the current element based on the next." contents[index + 1].add(contents[index].clone()) contents[index].output = EmptyOutput() def modifylimits(self, contents, index): "Modify a limits commands so that the limits appear above and below." limited = contents[index] subscript = self.getlimit(contents, index + 1) limited.contents.append(subscript) if self.checkscript(contents, index + 1): superscript = self.getlimit(contents, index + 1) else: superscript = TaggedBit().constant(u' ', 'sup class="limit"') limited.contents.insert(0, superscript) def getlimit(self, contents, index): "Get the limit for a limits command." limit = self.getscript(contents, index) limit.output.tag = limit.output.tag.replace('script', 'limit') return limit def modifyscripts(self, contents, index): "Modify the super- and subscript to appear vertically aligned." subscript = self.getscript(contents, index) # subscript removed so instead of index + 1 we get index again superscript = self.getscript(contents, index) scripts = TaggedBit().complete([superscript, subscript], 'span class="scripts"') contents.insert(index, scripts) def checkscript(self, contents, index): "Check if the current element is a sub- or superscript." return self.checkcommand(contents, index, SymbolFunction) def checkcommand(self, contents, index, type): "Check for the given type as the current element." if len(contents) <= index: return False return isinstance(contents[index], type) def getscript(self, contents, index): "Get the sub- or superscript." bit = contents[index] bit.output.tag += ' class="script"' del contents[index] return bit class BracketCommand(OneParamFunction): "A command which defines a bracket." commandmap = FormulaConfig.bracketcommands def parsebit(self, pos): "Parse the bracket." OneParamFunction.parsebit(self, pos) def create(self, direction, character): "Create the bracket for the given character." self.original = character self.command = '\\' + direction self.contents = [FormulaConstant(character)] return self class BracketProcessor(MathsProcessor): "A processor for bracket commands." def process(self, contents, index): "Convert the bracket using Unicode pieces, if possible." if Options.simplemath: return if self.checkleft(contents, index): return self.processleft(contents, index) def processleft(self, contents, index): "Process a left bracket." rightindex = self.findright(contents, index + 1) if not rightindex: return size = self.findmax(contents, index, rightindex) self.resize(contents[index], size) self.resize(contents[rightindex], size) def checkleft(self, contents, index): "Check if the command at the given index is left." return self.checkdirection(contents[index], '\\left') def checkright(self, contents, index): "Check if the command at the given index is right." return self.checkdirection(contents[index], '\\right') def checkdirection(self, bit, command): "Check if the given bit is the desired bracket command." if not isinstance(bit, BracketCommand): return False return bit.command == command def findright(self, contents, index): "Find the right bracket starting at the given index, or 0." depth = 1 while index < len(contents): if self.checkleft(contents, index): depth += 1 if self.checkright(contents, index): depth -= 1 if depth == 0: return index index += 1 return None def findmax(self, contents, leftindex, rightindex): "Find the max size of the contents between the two given indices." sliced = contents[leftindex:rightindex] return max([element.size for element in sliced]) def resize(self, command, size): "Resize a bracket command to the given size." character = command.extracttext() alignment = command.command.replace('\\', '') bracket = BigBracket(size, character, alignment) command.output = ContentsOutput() command.contents = bracket.getcontents() class TodayCommand(EmptyCommand): "Shows today's date." commandmap = None def parsebit(self, pos): "Parse a command without parameters" self.output = FixedOutput() self.html = [datetime.date.today().strftime('%b %d, %Y')] FormulaCommand.types += [ DecoratingFunction, CombiningFunction, LimitCommand, BracketCommand, ] FormulaProcessor.processors += [ LimitsProcessor(), BracketProcessor(), ] class ParameterDefinition(object): "The definition of a parameter in a hybrid function." "[] parameters are optional, {} parameters are mandatory." "Each parameter has a one-character name, like {$1} or {$p}." "A parameter that ends in ! like {$p!} is a literal." "Example: [$1]{$p!} reads an optional parameter $1 and a literal mandatory parameter p." parambrackets = [('[', ']'), ('{', '}')] def __init__(self): self.name = None self.literal = False self.optional = False self.value = None self.literalvalue = None def parse(self, pos): "Parse a parameter definition: [$0], {$x}, {$1!}..." for (opening, closing) in ParameterDefinition.parambrackets: if pos.checkskip(opening): if opening == '[': self.optional = True if not pos.checkskip('$'): Trace.error('Wrong parameter name, did you mean $' + pos.current() + '?') return None self.name = pos.skipcurrent() if pos.checkskip('!'): self.literal = True if not pos.checkskip(closing): Trace.error('Wrong parameter closing ' + pos.skipcurrent()) return None return self Trace.error('Wrong character in parameter template: ' + pos.skipcurrent()) return None def read(self, pos, function): "Read the parameter itself using the definition." if self.literal: if self.optional: self.literalvalue = function.parsesquareliteral(pos) else: self.literalvalue = function.parseliteral(pos) if self.literalvalue: self.value = FormulaConstant(self.literalvalue) elif self.optional: self.value = function.parsesquare(pos) else: self.value = function.parseparameter(pos) def __unicode__(self): "Return a printable representation." result = 'param ' + self.name if self.value: result += ': ' + unicode(self.value) else: result += ' (empty)' return result class ParameterFunction(CommandBit): "A function with a variable number of parameters defined in a template." "The parameters are defined as a parameter definition." def readparams(self, readtemplate, pos): "Read the params according to the template." self.params = dict() for paramdef in self.paramdefs(readtemplate): paramdef.read(pos, self) self.params['$' + paramdef.name] = paramdef def paramdefs(self, readtemplate): "Read each param definition in the template" pos = TextPosition(readtemplate) while not pos.finished(): paramdef = ParameterDefinition().parse(pos) if paramdef: yield paramdef def getparam(self, name): "Get a parameter as parsed." if not name in self.params: return None return self.params[name] def getvalue(self, name): "Get the value of a parameter." return self.getparam(name).value def getliteralvalue(self, name): "Get the literal value of a parameter." param = self.getparam(name) if not param or not param.literalvalue: return None return param.literalvalue class HybridFunction(ParameterFunction): """ A parameter function where the output is also defined using a template. The template can use a number of functions; each function has an associated tag. Example: [f0{$1},span class="fbox"] defines a function f0 which corresponds to a span of class fbox, yielding $1. Literal parameters can be used in tags definitions: [f0{$1},span style="color: $p;"] yields $1, where $p is a literal parameter. Sizes can be specified in hybridsizes, e.g. adding parameter sizes. By default the resulting size is the max of all arguments. Sizes are used to generate the right parameters. A function followed by a single / is output as a self-closing XHTML tag: [f0/,hr] will generate
. """ commandmap = FormulaConfig.hybridfunctions def parsebit(self, pos): "Parse a function with [] and {} parameters" readtemplate = self.translated[0] writetemplate = self.translated[1] self.readparams(readtemplate, pos) self.contents = self.writeparams(writetemplate) self.computehybridsize() def writeparams(self, writetemplate): "Write all params according to the template" return self.writepos(TextPosition(writetemplate)) def writepos(self, pos): "Write all params as read in the parse position." result = [] while not pos.finished(): if pos.checkskip('$'): param = self.writeparam(pos) if param: result.append(param) elif pos.checkskip('f'): function = self.writefunction(pos) if function: function.type = None result.append(function) elif pos.checkskip('('): result.append(self.writebracket('left', '(')) elif pos.checkskip(')'): result.append(self.writebracket('right', ')')) else: result.append(FormulaConstant(pos.skipcurrent())) return result def writeparam(self, pos): "Write a single param of the form $0, $x..." name = '$' + pos.skipcurrent() if not name in self.params: Trace.error('Unknown parameter ' + name) return None if not self.params[name]: return None if pos.checkskip('.'): self.params[name].value.type = pos.globalpha() return self.params[name].value def writefunction(self, pos): "Write a single function f0,...,fn." tag = self.readtag(pos) if not tag: return None if pos.checkskip('/'): # self-closing XHTML tag, such as
return TaggedBit().selfcomplete(tag) if not pos.checkskip('{'): Trace.error('Function should be defined in {}') return None pos.pushending('}') contents = self.writepos(pos) pos.popending() if len(contents) == 0: return None return TaggedBit().complete(contents, tag) def readtag(self, pos): "Get the tag corresponding to the given index. Does parameter substitution." if not pos.current().isdigit(): Trace.error('Function should be f0,...,f9: f' + pos.current()) return None index = int(pos.skipcurrent()) if 2 + index > len(self.translated): Trace.error('Function f' + unicode(index) + ' is not defined') return None tag = self.translated[2 + index] if not '$' in tag: return tag for variable in self.params: if variable in tag: param = self.params[variable] if not param.literal: Trace.error('Parameters in tag ' + tag + ' should be literal: {' + variable + '!}') continue if param.literalvalue: value = param.literalvalue else: value = '' tag = tag.replace(variable, value) return tag def writebracket(self, direction, character): "Return a new bracket looking at the given direction." return self.factory.create(BracketCommand).create(direction, character) def computehybridsize(self): "Compute the size of the hybrid function." if not self.command in HybridSize.configsizes: self.computesize() return self.size = HybridSize().getsize(self) # set the size in all elements at first level for element in self.contents: element.size = self.size class HybridSize(object): "The size associated with a hybrid function." configsizes = FormulaConfig.hybridsizes def getsize(self, function): "Read the size for a function and parse it." sizestring = self.configsizes[function.command] for name in function.params: if name in sizestring: size = function.params[name].value.computesize() sizestring = sizestring.replace(name, unicode(size)) if '$' in sizestring: Trace.error('Unconverted variable in hybrid size: ' + sizestring) return 1 return eval(sizestring) FormulaCommand.types += [HybridFunction] class MacroDefinition(CommandBit): "A function that defines a new command (a macro)." macros = dict() def parsebit(self, pos): "Parse the function that defines the macro." self.output = EmptyOutput() self.parameternumber = 0 self.defaults = [] self.factory.defining = True self.parseparameters(pos) self.factory.defining = False Trace.debug('New command ' + self.newcommand + ' (' + \ unicode(self.parameternumber) + ' parameters)') self.macros[self.newcommand] = self def parseparameters(self, pos): "Parse all optional parameters (number of parameters, default values)" "and the mandatory definition." self.newcommand = self.parsenewcommand(pos) # parse number of parameters literal = self.parsesquareliteral(pos) if literal: self.parameternumber = int(literal) # parse all default values bracket = self.parsesquare(pos) while bracket: self.defaults.append(bracket) bracket = self.parsesquare(pos) # parse mandatory definition self.definition = self.parseparameter(pos) def parsenewcommand(self, pos): "Parse the name of the new command." self.factory.clearskipped(pos) if self.factory.detecttype(Bracket, pos): return self.parseliteral(pos) if self.factory.detecttype(FormulaCommand, pos): return self.factory.create(FormulaCommand).extractcommand(pos) Trace.error('Unknown formula bit in defining function at ' + pos.identifier()) return 'unknown' def instantiate(self): "Return an instance of the macro." return self.definition.clone() class MacroParameter(FormulaBit): "A parameter from elyxer.a macro." def detect(self, pos): "Find a macro parameter: #n." return pos.checkfor('#') def parsebit(self, pos): "Parse the parameter: #n." if not pos.checkskip('#'): Trace.error('Missing parameter start #.') return self.number = int(pos.skipcurrent()) self.original = '#' + unicode(self.number) self.contents = [TaggedBit().constant('#' + unicode(self.number), 'span class="unknown"')] class MacroFunction(CommandBit): "A function that was defined using a macro." commandmap = MacroDefinition.macros def parsebit(self, pos): "Parse a number of input parameters." self.output = FilteredOutput() self.values = [] macro = self.translated self.parseparameters(pos, macro) self.completemacro(macro) def parseparameters(self, pos, macro): "Parse as many parameters as are needed." self.parseoptional(pos, list(macro.defaults)) self.parsemandatory(pos, macro.parameternumber - len(macro.defaults)) if len(self.values) < macro.parameternumber: Trace.error('Missing parameters in macro ' + unicode(self)) def parseoptional(self, pos, defaults): "Parse optional parameters." optional = [] while self.factory.detecttype(SquareBracket, pos): optional.append(self.parsesquare(pos)) if len(optional) > len(defaults): break for value in optional: default = defaults.pop() if len(value.contents) > 0: self.values.append(value) else: self.values.append(default) self.values += defaults def parsemandatory(self, pos, number): "Parse a number of mandatory parameters." for index in range(number): parameter = self.parsemacroparameter(pos, number - index) if not parameter: return self.values.append(parameter) def parsemacroparameter(self, pos, remaining): "Parse a macro parameter. Could be a bracket or a single letter." "If there are just two values remaining and there is a running number," "parse as two separater numbers." self.factory.clearskipped(pos) if pos.finished(): return None if self.factory.detecttype(FormulaNumber, pos): return self.parsenumbers(pos, remaining) return self.parseparameter(pos) def parsenumbers(self, pos, remaining): "Parse the remaining parameters as a running number." "For example, 12 would be {1}{2}." number = self.factory.parsetype(FormulaNumber, pos) if not len(number.original) == remaining: return number for digit in number.original: value = self.factory.create(FormulaNumber) value.add(FormulaConstant(digit)) value.type = number self.values.append(value) return None def completemacro(self, macro): "Complete the macro with the parameters read." self.contents = [macro.instantiate()] replaced = [False] * len(self.values) for parameter in self.searchall(MacroParameter): index = parameter.number - 1 if index >= len(self.values): Trace.error('Macro parameter index out of bounds: ' + unicode(index)) return replaced[index] = True parameter.contents = [self.values[index].clone()] for index in range(len(self.values)): if not replaced[index]: self.addfilter(index, self.values[index]) def addfilter(self, index, value): "Add a filter for the given parameter number and parameter value." original = '#' + unicode(index + 1) value = ''.join(self.values[0].gethtml()) self.output.addfilter(original, value) class FormulaMacro(Formula): "A math macro defined in an inset." def __init__(self): self.parser = MacroParser() self.output = EmptyOutput() def __unicode__(self): "Return a printable representation." return 'Math macro' FormulaFactory.types += [ MacroParameter ] FormulaCommand.types += [ MacroFunction, ] class SideNote(Container): "A side note that appears at the right." def __init__(self): self.parser = InsetParser() self.output = TaggedOutput() def process(self): "Enclose everything in a marginal span." self.output.settag('span class="Marginal"', True) class FootnoteMarker(Container): "A marker for a footnote." def __init__(self): "Set the correct span class." self.contents = [] span = 'span class="SupFootMarker"' if Options.alignfoot: span = 'span class="AlignFootMarker"' self.output = TaggedOutput().settag(span, False) mode = 'A' if Options.numberfoot: mode = '1' if Options.symbolfoot: mode = '*' NumberGenerator.generator.getcounter('Footnote').setmode(mode) def create(self): "Create the marker for a footnote." self.order = NumberGenerator.generator.generate('Footnote') if Options.endfoot: self.link = Link().complete(self.getmark(), 'footmarker-' + self.order) self.createcontents() return self def createanchor(self, marker): "Create the anchor for a footnote. Adds a link for end footnotes." self.order = marker.order if Options.endfoot: self.link = Link().complete(self.getmark(), 'footnote-' + self.order) self.link.setmutualdestination(marker.link) self.createcontents() return self def createlabel(self, marker): "Create the label for a footnote. Used in hoverfoot and marginfoot." self.order = marker.order self.contents = [Constant(self.getmark())] space = Constant(u' ') self.contents = [space] + self.contents + [space] return self def createcontents(self): "Create the contents of the marker." if Options.endfoot: self.contents = [self.link] else: self.contents = [Constant(self.getmark())] space = Constant(u' ') self.contents = [space] + self.contents + [space] def getmark(self): "Get the mark to be displayed in the marker based on the order." if Options.symbolfoot: return self.order else: return '[' + self.order + ']' class Footnote(Container): "A footnote to the main text." def __init__(self): self.parser = InsetParser() self.output = TaggedOutput().settag('span class="FootOuter"', False) def process(self): "Add a counter for the footnote." "Can be numeric or a letter depending on runtime options." marker = FootnoteMarker().create() anchor = FootnoteMarker().createanchor(marker) label = FootnoteMarker().createlabel(marker) notecontents = list(self.contents) self.contents = [marker] if Options.hoverfoot: self.contents.append(self.createnote([label] + notecontents, 'span class="HoverFoot"')) if Options.marginfoot: self.contents.append(self.createnote([label] + notecontents, 'span class="MarginFoot"')) if Options.endfoot: EndFootnotes.footnotes.append(self.createnote([anchor] + notecontents, 'div class="EndFoot"')) def createnote(self, contents, tag): "Create a note with the given contents and HTML tag." return TaggedText().complete(contents, tag, False) class EndFootnotes(Container): "The collection of footnotes at the document end." footnotes = [] def __init__(self): "Generate all footnotes and a proper header for them all." self.output = ContentsOutput() header = TaggedText().constant(Translator.translate('footnotes'), 'h1 class="index"') self.contents = [header] + self.footnotes class Note(Container): "A LyX note of several types" def __init__(self): self.parser = InsetParser() self.output = EmptyOutput() def process(self): "Hide note and comment, dim greyed out" self.type = self.header[2] if TagConfig.notes[self.type] == '': return self.output = TaggedOutput().settag(TagConfig.notes[self.type], True) class LyXHeader(Container): "Reads the header, outputs the HTML header" def __init__(self): self.contents = [] self.parser = HeaderParser() self.output = HeaderOutput() self.parameters = dict() self.partkey = PartKey().createheader('header') def process(self): "Find pdf title" DocumentParameters.pdftitle = self.getheaderparameter('pdftitle') documentclass = self.getheaderparameter('documentclass') if documentclass in HeaderConfig.styles['article']: DocumentParameters.startinglevel = 1 if documentclass in HeaderConfig.styles['book']: DocumentParameters.bibliography = 'bibliography' else: DocumentParameters.bibliography = 'references' if self.getheaderparameter('paragraphseparation') == 'indent': DocumentParameters.indentstandard = True DocumentParameters.tocdepth = self.getlevel('tocdepth') DocumentParameters.maxdepth = self.getlevel('secnumdepth') DocumentParameters.language = self.getheaderparameter('language') if self.getheaderparameter('outputchanges') == 'true': DocumentParameters.outputchanges = True return self def getheaderparameter(self, configparam): "Get a parameter configured in HeaderConfig." key = HeaderConfig.parameters[configparam] if not key in self.parameters: return None return self.parameters[key] def getlevel(self, configparam): "Get a level read as a parameter from elyxer.HeaderConfig." paramvalue = self.getheaderparameter(configparam) if not paramvalue: return 0 value = int(paramvalue) if DocumentParameters.startinglevel == 1: return value return value + 1 class LyXPreamble(Container): "The preamble at the beginning of a LyX file. Parsed for macros." def __init__(self): self.parser = PreambleParser() self.output = EmptyOutput() self.factory = FormulaFactory() def process(self): "Parse the LyX preamble, if needed." if len(PreambleParser.preamble) == 0: return pos = TextPosition('\n'.join(PreambleParser.preamble)) while not pos.finished(): if self.detectfunction(pos): self.parsefunction(pos) else: pos.globincluding('\n') PreambleParser.preamble = [] def detectfunction(self, pos): "Detect a macro definition or a preamble function." for function in FormulaConfig.misccommands: if pos.checkfor(function): return True return False def parsefunction(self, pos): "Parse a single command." self.factory.parsetype(FormulaCommand, pos) class LyXFooter(Container): "Reads the footer, outputs the HTML footer" def __init__(self): self.contents = [] self.parser = BoundedDummy() self.output = FooterOutput() self.partkey = PartKey().createheader('footer') def process(self): "Include any footnotes at the end." if EndFootnotes.footnotes: endnotes = EndFootnotes() self.contents = [endnotes] class Layout(Container): "A layout (block of text) inside a lyx file" type = 'none' def __init__(self): "Initialize the layout." self.contents = [] self.parser = BoundedParser() self.output = TaggedOutput().setbreaklines(True) def process(self): "Get the type and numerate if necessary." self.type = self.header[1] if self.type in TagConfig.layouts: self.output.tag = TagConfig.layouts[self.type] + ' class="' + self.type + '"' elif self.type.replace('*', '') in TagConfig.layouts: self.output.tag = TagConfig.layouts[self.type.replace('*', '')] self.output.tag += ' class="' + self.type.replace('*', '-') + '"' else: self.output.tag = 'div class="' + self.type + '"' self.numerate() def numerate(self): "Numerate if necessary." partkey = PartKeyGenerator.forlayout(self) if partkey: self.partkey = partkey self.output.tag = self.output.tag.replace('?', unicode(partkey.level)) def __unicode__(self): "Return a printable representation." if self.partkey: return 'Layout ' + self.type + ' #' + unicode(self.partkey.partkey) return 'Layout of type ' + self.type class StandardLayout(Layout): "A standard layout -- can be a true div or nothing at all" indentation = False def process(self): self.type = 'standard' self.output = ContentsOutput() def complete(self, contents): "Set the contents and return it." self.process() self.contents = contents return self class Title(Layout): "The title of the whole document" def process(self): self.type = 'title' self.output.tag = 'h1 class="title"' title = self.extracttext() DocumentTitle.title = title Trace.message('Title: ' + title) class Author(Layout): "The document author" def process(self): self.type = 'author' self.output.tag = 'h2 class="author"' author = self.extracttext() Trace.debug('Author: ' + author) DocumentAuthor.appendauthor(author) class Abstract(Layout): "A paper abstract" done = False def process(self): self.type = 'abstract' self.output.tag = 'div class="abstract"' if Abstract.done: return message = Translator.translate('abstract') tagged = TaggedText().constant(message, 'p class="abstract-message"', True) self.contents.insert(0, tagged) Abstract.done = True class FirstWorder(Layout): "A layout where the first word is extracted" def extractfirstword(self): "Extract the first word as a list" return self.extractfromcontents(self.contents) def extractfromcontents(self, contents): "Extract the first word in contents." firstcontents = [] while len(contents) > 0: if self.isfirstword(contents[0]): firstcontents.append(contents[0]) del contents[0] return firstcontents if self.spaceincontainer(contents[0]): extracted = self.extractfromcontainer(contents[0]) firstcontents.append(extracted) return firstcontents firstcontents.append(contents[0]) del contents[0] return firstcontents def extractfromcontainer(self, container): "Extract the first word from a container cloning it including its output." if isinstance(container, StringContainer): return self.extractfromstring(container) result = Cloner.clone(container) result.output = container.output result.contents = self.extractfromcontents(container.contents) return result def extractfromstring(self, container): "Extract the first word from elyxer.a string container." if not ' ' in container.string: Trace.error('No space in string ' + container.string) return container split = container.string.split(' ', 1) container.string = split[1] return Constant(split[0]) def spaceincontainer(self, container): "Find out if the container contains a space somewhere." return ' ' in container.extracttext() def isfirstword(self, container): "Find out if the container is valid as a first word." if not isinstance(container, FirstWord): return False return not container.isempty() class FirstWord(Container): "A container which is in itself a first word, unless it's empty." "Should be inherited by other containers, e.g. ERT." def isempty(self): "Find out if the first word is empty." Trace.error('Unimplemented isempty()') return True class Description(FirstWorder): "A description layout" def process(self): "Set the first word to bold" self.type = 'Description' self.output.tag = 'div class="Description"' firstword = self.extractfirstword() if not firstword: return tag = 'span class="Description-entry"' self.contents.insert(0, TaggedText().complete(firstword, tag)) self.contents.insert(1, Constant(u' ')) class List(FirstWorder): "A list layout" def process(self): "Set the first word to bold" self.type = 'List' self.output.tag = 'div class="List"' firstword = self.extractfirstword() if not firstword: return first = TaggedText().complete(firstword, 'span class="List-entry"') second = TaggedText().complete(self.contents, 'span class="List-contents"') self.contents = [first, second] class PlainLayout(Layout): "A plain layout" def process(self): "Output just as contents." self.output = ContentsOutput() self.type = 'Plain' def makevisible(self): "Make the layout visible, output as tagged text." self.output = TaggedOutput().settag('div class="PlainVisible"', True) class LyXCode(Layout): "A bit of LyX-Code." def process(self): "Output as pre." self.output.tag = 'pre class="LyX-Code"' for newline in self.searchall(Newline): index = newline.parent.contents.index(newline) newline.parent.contents[index] = Constant('\n') class PostLayout(object): "Numerate an indexed layout" processedclass = Layout def postprocess(self, last, layout, next): "Group layouts and/or number them." if layout.type in TagConfig.group['layouts']: return self.group(last, layout) if layout.partkey: self.number(layout) return layout def group(self, last, layout): "Group two layouts if they are the same type." if not self.isgroupable(layout) or not self.isgroupable(last) or last.type != layout.type: return layout layout.contents = last.contents + [Constant('
\n')] + layout.contents last.contents = [] last.output = EmptyOutput() return layout def isgroupable(self, container): "Check that the container can be grouped." if not isinstance(container, Layout): return False for element in container.contents: if not element.__class__.__name__ in LayoutConfig.groupable['allowed']: return False return True def number(self, layout): "Generate a number and place it before the text" layout.partkey.addtoclabel(layout) class PostStandard(object): "Convert any standard spans in root to divs" processedclass = StandardLayout def postprocess(self, last, standard, next): "Switch to div, and clear if empty." type = 'Standard' if self.isempty(standard): standard.output = EmptyOutput() return standard if DocumentParameters.indentstandard: if isinstance(last, StandardLayout): type = 'Indented' else: type = 'Unindented' standard.output = TaggedOutput().settag('div class="' + type + '"', True) return standard def isempty(self, standard): "Find out if the standard layout is empty." for element in standard.contents: if not element.output.isempty(): return False return True class PostPlainLayout(PostLayout): "Numerate a plain layout" processedclass = PlainLayout def postprocess(self, last, plain, next): "Group plain layouts." if not self.istext(last) or not self.istext(plain): return plain plain.makevisible() return self.group(last, plain) def istext(self, container): "Find out if the container is only text." if not isinstance(container, PlainLayout): return False extractor = ContainerExtractor(TOCConfig.extractplain) text = extractor.extract(container) return (len(text) > 0) class PostLyXCode(object): "Coalesce contiguous LyX-Code layouts." processedclass = LyXCode def postprocess(self, last, lyxcode, next): "Coalesce if last was also LyXCode" if not isinstance(last, LyXCode): return lyxcode if hasattr(last, 'first'): lyxcode.first = last.first else: lyxcode.first = last toappend = lyxcode.first.contents toappend.append(Constant('\n')) toappend += lyxcode.contents lyxcode.output = EmptyOutput() return lyxcode Postprocessor.stages += [ PostLayout, PostStandard, PostLyXCode, PostPlainLayout ] class BiblioCitation(Container): "A complete bibliography citation (possibly with many cites)." citations = dict() def __init__(self): self.parser = InsetParser() self.output = TaggedOutput().settag('span class="bibcites"') self.contents = [] def process(self): "Process the complete citation and all cites within." self.contents = [Constant('[')] keys = self.getparameterlist('key') for key in keys: self.contents += [BiblioCite().create(key), Constant(', ')] if len(keys) > 0: # remove trailing , self.contents.pop() self.contents.append(Constant(']')) class BiblioCite(Link): "Cite of a bibliography entry" cites = dict() def create(self, key): "Create the cite to the given key." self.key = key number = NumberGenerator.generator.generate('bibliocite') ref = BiblioReference().create(key, number) self.complete(number, 'cite-' + number, type='bibliocite') self.setmutualdestination(ref) if not key in BiblioCite.cites: BiblioCite.cites[key] = [] BiblioCite.cites[key].append(self) return self class Bibliography(Container): "A bibliography layout containing an entry" def __init__(self): self.parser = BoundedParser() self.output = TaggedOutput().settag('p class="biblio"', True) class BiblioHeader(Container): "The header of the bibliography." def __init__(self): "Create the header for the bibliography section." self.type = 'biblio' self.output = ContentsOutput() self.name = Translator.translate(DocumentParameters.bibliography) self.contents = [TaggedText().constant(self.name, 'h1 class="biblio"', True)] def addtotoc(self, parent): "Add the bibliography header to the TOC." self.parent = parent self.partkey = PartKeyGenerator.forindex(self) if not self.partkey: return self.partkey.addtoclabel(self) while parent: parent.partkey = self.partkey parent = parent.parent class PostBiblio(object): "Insert a Bibliography legend before the first item" processedclass = Bibliography def postprocess(self, last, element, next): "If we have the first bibliography insert a tag" if isinstance(last, Bibliography) or Options.nobib: return element layout = StandardLayout() header = BiblioHeader() header.addtotoc(layout) layout.complete([header, element]) return layout Postprocessor.stages += [PostBiblio] class BiblioReference(Link): "A reference to a bibliographical entry." references = dict() def create(self, key, number): "Create the reference with the given key and number." self.key = key self.complete(number, 'biblio-' + number, type='biblioentry') if not key in BiblioReference.references: BiblioReference.references[key] = [] BiblioReference.references[key].append(self) return self class BiblioEntry(Container): "A bibliography entry" entries = dict() def __init__(self): self.parser = InsetParser() self.output = TaggedOutput().settag('span class="entry"') self.contents = [] def process(self): "Process the cites for the entry's key" self.citeref = [Constant(NumberGenerator.generator.generate('biblioentry'))] self.processcites(self.getparameter('key')) def processcites(self, key): "Get all the cites of the entry" self.key = key if not key in BiblioReference.references: self.contents.append(Constant('[-] ')) return self.contents = [Constant('[')] for ref in BiblioReference.references[key]: self.contents.append(ref) self.contents.append(Constant(',')) self.contents.pop(-1) self.contents.append(Constant('] ')) class Processor(object): "Process a container and its contents." prestages = [] skipfiltered = ['LyXHeader', 'LyXFooter', 'Title', 'Author', 'TableOfContents'] def __init__(self, filtering): "Set filtering mode (to skip postprocessing)." "With filtering on, the classes in skipfiltered are not processed at all." self.filtering = filtering self.postprocessor = Postprocessor() def process(self, container): "Do the whole processing on a container." if self.filtering and container.__class__.__name__ in self.skipfiltered: return None container = self.preprocess(container) self.processcontainer(container) if not container: # do not postprocess empty containers from elyxer.here return container return self.postprocess(container) def preprocess(self, root): "Preprocess a root container with all prestages." if not root: return None for stage in self.prestages: root = stage.preprocess(root) if not root: return None return root def processcontainer(self, container): "Process a container and its contents, recursively." if not container: return for element in container.contents: self.processcontainer(element) container.process() def postprocess(self, container): "Postprocess a container, unless filtering is on." if self.filtering: return container return self.postprocessor.postprocess(container) class ListInset(Container): "An inset with a list, normally made of links." def __init__(self): self.parser = InsetParser() self.output = ContentsOutput() def sortdictionary(self, dictionary): "Sort all entries in the dictionary" keys = dictionary.keys() # sort by name keys.sort() return keys sortdictionary = classmethod(sortdictionary) class ListOf(ListInset): "A list of entities (figures, tables, algorithms)" def process(self): "Parse the header and get the type" self.type = self.header[2] text = Translator.translate('list-' + self.type) self.contents = [TaggedText().constant(text, 'div class="tocheader"', True)] class TableOfContents(ListInset): "Table of contents" def process(self): "Parse the header and get the type" self.create(Translator.translate('toc')) def create(self, heading): "Create a table of contents with the given heading text." self.output = TaggedOutput().settag('div class="fulltoc"', True) self.contents = [TaggedText().constant(heading, 'div class="tocheader"', True)] return self def add(self, entry): "Add a new entry to the TOC." if entry: self.contents.append(entry) class IndexReference(Link): "A reference to an entry in the alphabetical index." name = 'none' def process(self): "Put entry in index" name = self.getparameter('name') if name: self.name = name.strip() else: self.name = self.extracttext() IndexEntry.get(self.name).addref(self) def __unicode__(self): "Return a printable representation." return 'Reference to ' + self.name class IndexHeader(Link): "The header line for an index entry. Keeps all arrows." keyescapes = {'!':'', '|':'-', ' ':'-', '--':'-', ',':'', '\\':'', '@':'_', u'°':''} def create(self, names): "Create the header for the given index entry." self.output = TaggedOutput().settag('p class="printindex"', True) self.name = names[-1] keys = [self.escape(part, self.keyescapes) for part in names] self.key = '-'.join(keys) self.anchor = Link().complete('', 'index-' + self.key, None, 'printindex') self.contents = [self.anchor, Constant(self.name + ': ')] self.arrows = [] return self def addref(self, reference): "Create an arrow pointing to a reference." reference.index = unicode(len(self.arrows)) reference.destination = self.anchor reference.complete(u'↓', 'entry-' + self.key + '-' + reference.index) arrow = Link().complete(u'↑', type = 'IndexArrow') arrow.destination = reference if len(self.arrows) > 0: self.contents.append(Constant(u', ')) self.arrows.append(arrow) self.contents.append(arrow) def __unicode__(self): "Return a printable representation." return 'Index header for ' + self.name class IndexGroup(Container): "A group of entries in the alphabetical index, for an entry." root = None def create(self): "Create an index group." self.entries = dict() self.output = EmptyOutput() return self def findentry(self, names): "Find the entry with the given names." if self == IndexGroup.root: self.output = ContentsOutput() else: self.output = TaggedOutput().settag('div class="indexgroup"', True) lastname = names[-1] if not lastname in self.entries: self.entries[lastname] = IndexEntry().create(names) return self.entries[lastname] def sort(self): "Sort all entries in the group." for key in ListInset.sortdictionary(self.entries): entry = self.entries[key] entry.group.sort() self.contents.append(entry) def __unicode__(self): "Return a printable representation." return 'Index group' IndexGroup.root = IndexGroup().create() class IndexEntry(Container): "An entry in the alphabetical index." "When an index entry is of the form 'part1 ! part2 ...', " "a hierarchical structure in the form of an IndexGroup is constructed." "An index entry contains a mandatory header, and an optional group." def create(self, names): "Create an index entry with the given name." self.output = ContentsOutput() self.header = IndexHeader().create(names) self.group = IndexGroup().create() self.contents = [self.header, self.group] return self def addref(self, reference): "Add a reference to the entry." self.header.addref(reference) def get(cls, name): "Get the index entry for the given name." group = IndexGroup.root parts = IndexEntry.splitname(name) readparts = [] for part in parts: readparts.append(part) entry = group.findentry(readparts) group = entry.group return entry def splitname(cls, name): "Split a name in parts divided by !." return [part.strip() for part in name.split('!')] def __unicode__(self): "Return a printable representation." return 'Index entry for ' + self.header.name get = classmethod(get) splitname = classmethod(splitname) class PrintIndex(ListInset): "Command to print an index" def process(self): "Create the alphabetic index" self.name = Translator.translate('index') self.partkey = PartKeyGenerator.forindex(self) if not self.partkey: return self.contents = [TaggedText().constant(self.name, 'h1 class="index"')] self.partkey.addtoclabel(self) IndexGroup.root.sort() self.contents.append(IndexGroup.root) class NomenclatureEntry(Link): "An entry of LyX nomenclature" entries = dict() def process(self): "Put entry in index" symbol = self.getparameter('symbol') description = self.getparameter('description') key = symbol.replace(' ', '-').lower() if key in NomenclatureEntry.entries: Trace.error('Duplicated nomenclature entry ' + key) self.complete(u'↓', 'noment-' + key) entry = Link().complete(u'↑', 'nom-' + key) entry.symbol = symbol entry.description = description self.setmutualdestination(entry) NomenclatureEntry.entries[key] = entry class PrintNomenclature(ListInset): "Print all nomenclature entries" def process(self): "Create the nomenclature." self.name = Translator.translate('nomenclature') self.partkey = PartKeyGenerator.forindex(self) if not self.partkey: return self.contents = [TaggedText().constant(self.name, 'h1 class="nomenclature"')] self.partkey.addtoclabel(self) for key in self.sortdictionary(NomenclatureEntry.entries): entry = NomenclatureEntry.entries[key] contents = [entry, Constant(entry.symbol + u' ' + entry.description)] text = TaggedText().complete(contents, 'div class="Nomenclated"', True) self.contents.append(text) class PreListInset(object): "Preprocess any container that contains a list inset." def preprocess(self, container): "Preprocess a container, extract any list inset and return it." listinsets = container.searchall(ListInset) if len(listinsets) == 0: return container if len(container.contents) > 1: return container return listinsets[0] Processor.prestages += [PreListInset()] class TableParser(BoundedParser): "Parse the whole table" headers = ContainerConfig.table['headers'] def __init__(self): BoundedParser.__init__(self) self.columns = list() def parseheader(self, reader): "Parse table headers" reader.nextline() while self.startswithheader(reader): self.parseparameter(reader) return [] def startswithheader(self, reader): "Check if the current line starts with a header line" for start in TableParser.headers: if reader.currentline().strip().startswith(start): return True return False class TablePartParser(BoundedParser): "Parse a table part (row or cell)" def parseheader(self, reader): "Parse the header" tablekey, parameters = self.parsexml(reader) self.parameters = parameters return list() class ColumnParser(LoneCommand): "Parse column properties" def parseheader(self, reader): "Parse the column definition" key, parameters = self.parsexml(reader) self.parameters = parameters return [] class Table(Container): "A lyx table" def __init__(self): self.parser = TableParser() self.output = TaggedOutput().settag('table', True) self.columns = [] def process(self): "Set the columns on every row" index = 0 while index < len(self.contents): element = self.contents[index] if isinstance(element, Column): self.columns.append(element) del self.contents[index] elif isinstance(element, BlackBox): del self.contents[index] elif isinstance(element, Row): element.setcolumns(self.columns) index += 1 else: Trace.error('Unknown element type ' + element.__class__.__name__ + ' in table: ' + unicode(element.contents[0])) index += 1 class Row(Container): "A row in a table" def __init__(self): self.parser = TablePartParser() self.output = TaggedOutput().settag('tr', True) self.columns = list() def setcolumns(self, columns): "Process alignments for every column" if len(columns) != len(self.contents): Trace.error('Columns: ' + unicode(len(columns)) + ', cells: ' + unicode(len(self.contents))) return for index, cell in enumerate(self.contents): columns[index].set(cell) class Column(Container): "A column definition in a table" def __init__(self): self.parser = ColumnParser() self.output = EmptyOutput() def process(self): "Read size parameters if present." self.size = ContainerSize().readparameters(self) def set(self, cell): "Set alignments in the corresponding cell" alignment = self.getparameter('alignment') if alignment == 'block': alignment = 'justify' cell.setattribute('align', alignment) valignment = self.getparameter('valignment') cell.setattribute('valign', valignment) self.size.addstyle(cell) class Cell(Container): "A cell in a table" def __init__(self): self.parser = TablePartParser() self.output = TaggedOutput().settag('td', True) def setmulticolumn(self, span): "Set the cell as multicolumn" self.setattribute('colspan', span) def setattribute(self, attribute, value): "Set a cell attribute in the tag" self.output.tag += ' ' + attribute + '="' + unicode(value) + '"' class PostTable(object): "Postprocess a table" processedclass = Table def postprocess(self, last, table, next): "Postprocess a table: long table, multicolumn rows" self.longtable(table) for row in table.contents: index = 0 while index < len(row.contents): self.checkforplain(row, index) self.checkmulticolumn(row, index) index += 1 return table def longtable(self, table): "Postprocess a long table, removing unwanted rows" features = table.getparameter('features') if not features: return if not 'islongtable' in features: return if features['islongtable'] != 'true': return if self.hasrow(table, 'endfirsthead'): self.removerows(table, 'endhead') if self.hasrow(table, 'endlastfoot'): self.removerows(table, 'endfoot') def hasrow(self, table, attrname): "Find out if the table has a row of first heads" for row in table.contents: if row.getparameter(attrname): return True return False def removerows(self, table, attrname): "Remove the head rows, since the table has first head rows." for row in table.contents: if row.getparameter(attrname): row.output = EmptyOutput() def checkforplain(self, row, index): "Make plain layouts visible if necessary." cell = row.contents[index] plainlayouts = cell.searchall(PlainLayout) if len(plainlayouts) <= 1: return for plain in plainlayouts: plain.makevisible() def checkmulticolumn(self, row, index): "Process a multicolumn attribute" cell = row.contents[index] mc = cell.getparameter('multicolumn') if not mc: return if mc != '1': Trace.error('Unprocessed multicolumn=' + unicode(multicolumn) + ' cell ' + unicode(cell)) return total = 1 index += 1 while self.checkbounds(row, index): del row.contents[index] total += 1 cell.setmulticolumn(total) def checkbounds(self, row, index): "Check if the index is within bounds for the row" if index >= len(row.contents): return False mc = row.contents[index].getparameter('multicolumn') if mc != '2': return False return True Postprocessor.stages.append(PostTable) import struct import sys import os import shutil import os import os.path import codecs class Path(object): "Represents a generic path" def exists(self): "Check if the file exists" return os.path.exists(self.path) def open(self): "Open the file as readonly binary" return codecs.open(self.path, 'rb') def getmtime(self): "Return last modification time" return os.path.getmtime(self.path) def hasexts(self, exts): "Check if the file has one of the given extensions." for ext in exts: if self.hasext(ext): return True return False def hasext(self, ext): "Check if the file has the given extension" return self.getext() == ext def getext(self): "Get the current extension of the file." base, ext = os.path.splitext(self.path) return ext def __unicode__(self): "Return a unicode string representation" return self.path def __eq__(self, path): "Compare to another path" if not hasattr(path, 'path'): return False return self.path == path.path class InputPath(Path): "Represents an input file" def __init__(self, url): "Create the input path based on url" self.url = url self.path = url if not os.path.isabs(url): self.path = os.path.join(Options.directory, url) class OutputPath(Path): "Represents an output file" def __init__(self, inputpath): "Create the output path based on an input path" self.url = inputpath.url if os.path.isabs(self.url): self.url = os.path.basename(self.url) self.path = os.path.join(Options.destdirectory, self.url) def changeext(self, ext): "Change extension to the given one" base, oldext = os.path.splitext(self.path) self.path = base + ext base, oldext = os.path.splitext(self.url) self.url = base + ext def exists(self): "Check if the file exists" return os.path.exists(self.path) def createdirs(self): "Create any intermediate directories that don't exist" dir = os.path.dirname(self.path) if len(dir) > 0 and not os.path.exists(dir): os.makedirs(dir) def removebackdirs(self): "Remove any occurrences of ../ (or ..\ on Windows)" self.path = os.path.normpath(self.path) backdir = '..' + os.path.sep while self.path.startswith(backdir): self.path = self.path[len(backdir):] while self.url.startswith('../'): self.url = self.url[len('../'):] class Image(Container): "An embedded image" defaultformat = ImageConfig.formats['default'] size = None copy = None def __init__(self): self.parser = InsetParser() self.output = TaggedOutput() self.type = 'embedded' def process(self): "Place the url, convert the image if necessary." self.origin = InputPath(self.getparameter('filename')) self.destination = self.getdestination(self.origin) self.size = ContainerSize().readparameters(self) if self.origin.exists(): ImageConverter.instance.convert(self) else: Trace.error('Image ' + unicode(self.origin) + ' not found') self.setsize() self.settag() def getdestination(self, origin): "Convert origin path to destination path." "Changes extension of destination to output image format." destination = OutputPath(origin) if Options.noconvert: return destination self.convertformat(destination) destination.removebackdirs() return destination def convertformat(self, destination): "Convert the format of the destination image." if Options.copyimages: return imageformat = '.jpg' forcedest = Image.defaultformat if Options.imageformat: imageformat = Options.imageformat forcedest = Options.imageformat if not destination.hasext(imageformat): destination.changeext(forcedest) def setsize(self): "Set the size attributes width and height." width, height = ImageFile(self.destination).getdimensions() self.size.checkimage(width, height) def scalevalue(self, value): "Scale the value according to the image scale and return it as unicode." scaled = value * int(self.size.scale) / 100 return unicode(int(scaled)) + 'px' def settag(self): "Set the output tag for the image." tag = 'img class="' + self.type + '"' if self.origin.exists(): url = self.destination.url else: url = self.origin.url alt = Translator.translate('figure') + ' ' + url tag += ' src="' + url + '" alt="' + alt + '"' emptytag = True if self.destination.hasext('.svg'): self.contents = [Constant(alt)] tag = 'object class="' + self.type + '" data="' + url + '"' emptytag = False self.output.settag(tag, True, empty=emptytag) self.size.addstyle(self) class ImageConverter(object): "A converter from elyxer.one image file to another." vectorformats = ImageConfig.formats['vector'] cropboxformats = ImageConfig.cropboxformats active = True instance = None def convert(self, image): "Convert an image to PNG" if not ImageConverter.active or Options.noconvert: return if image.origin.path == image.destination.path: return if image.destination.exists(): if image.origin.getmtime() <= image.destination.getmtime(): # file has not changed; do not convert return image.destination.createdirs() if Options.copyimages: Trace.debug('Copying ' + image.origin.path + ' to ' + image.destination.path) shutil.copy2(image.origin.path, image.destination.path) return converter, command = self.buildcommand(image) try: Trace.debug(converter + ' command: "' + command + '"') result = os.system(command.encode(sys.getfilesystemencoding())) if result != 0: Trace.error(converter + ' not installed; images will not be processed') ImageConverter.active = False return Trace.message('Converted ' + unicode(image.origin) + ' to ' + unicode(image.destination)) except OSError, exception: Trace.error('Error while converting image ' + unicode(image.origin) + ': ' + unicode(exception)) def buildcommand(self, image): "Build the command to convert the image." if Options.converter in ImageConfig.converters: command = ImageConfig.converters[Options.converter] else: command = Options.converter; params = self.getparams(image) for param in params: command = command.replace('$' + param, unicode(params[param])) # remove unwanted options while '[' in command and ']' in command: command = self.removeparam(command) return Options.converter, command def removeparam(self, command): "Remove an unwanted param." if command.index('[') > command.index(']'): Trace.error('Converter command should be [...$...]: ' + command) exit() before = command[:command.index('[')] after = command[command.index(']') + 1:] between = command[command.index('[') + 1:command.index(']')] if '$' in between: return before + after return before + between + after def getparams(self, image): "Get the parameters for ImageMagick conversion" params = dict() params['input'] = image.origin params['output'] = image.destination if image.origin.hasexts(self.vectorformats): scale = 100 if image.size.scale: scale = image.size.scale # descale image.size.scale = None params['scale'] = scale if image.origin.getext() in self.cropboxformats: params['format'] = self.cropboxformats[image.origin.getext()] return params ImageConverter.instance = ImageConverter() class ImageFile(object): "A file corresponding to an image (JPG or PNG)" dimensions = dict() def __init__(self, path): "Create the file based on its path" self.path = path def getdimensions(self): "Get the dimensions of a JPG or PNG image" if not self.path.exists(): return None, None if unicode(self.path) in ImageFile.dimensions: return ImageFile.dimensions[unicode(self.path)] dimensions = (None, None) if self.path.hasext('.png'): dimensions = self.getpngdimensions() elif self.path.hasext('.jpg'): dimensions = self.getjpgdimensions() elif self.path.hasext('.svg'): dimensions = self.getsvgdimensions() ImageFile.dimensions[unicode(self.path)] = dimensions return dimensions def getpngdimensions(self): "Get the dimensions of a PNG image" pngfile = self.path.open() pngfile.seek(16) width = self.readlong(pngfile) height = self.readlong(pngfile) pngfile.close() return (width, height) def getjpgdimensions(self): "Get the dimensions of a JPEG image" jpgfile = self.path.open() start = self.readword(jpgfile) if start != int('ffd8', 16): Trace.error(unicode(self.path) + ' not a JPEG file') return (None, None) self.skipheaders(jpgfile, ['ffc0', 'ffc2']) self.seek(jpgfile, 3) height = self.readword(jpgfile) width = self.readword(jpgfile) jpgfile.close() return (width, height) def getsvgdimensions(self): "Get the dimensions of a SVG image." return (None, None) def skipheaders(self, file, hexvalues): "Skip JPEG headers until one of the parameter headers is found" headervalues = [int(value, 16) for value in hexvalues] header = self.readword(file) safetycounter = 0 while header not in headervalues and safetycounter < 30: length = self.readword(file) if length == 0: Trace.error('End of file ' + file.name) return self.seek(file, length - 2) header = self.readword(file) safetycounter += 1 def readlong(self, file): "Read a long (32-bit) value from elyxer.file" return self.readformat(file, '>L', 4) def readword(self, file): "Read a 16-bit value from elyxer.file" return self.readformat(file, '>H', 2) def readformat(self, file, format, bytes): "Read any format from elyxer.file" read = file.read(bytes) if read == '' or len(read) < bytes: Trace.error('EOF reached') return 0 tuple = struct.unpack(format, read) return tuple[0] def seek(self, file, bytes): "Seek forward, just by reading the given number of bytes" file.read(bytes) class ListItem(Container): "An element in a list" type = 'none' def __init__(self): "Create a list item." self.parser = BoundedParser() self.output = ContentsOutput() def process(self): "Set the correct type and contents." self.type = self.header[1] tag = TaggedText().complete(self.contents, 'li', True) self.contents = [tag] def __unicode__(self): return self.type + ' item @ ' + unicode(self.begin) class DeeperList(Container): "A nested list" def __init__(self): "Create a nested list element." self.parser = BoundedParser() self.output = ContentsOutput() self.contents = [] def process(self): "Create the deeper list" if len(self.contents) == 0: Trace.error('Empty deeper list') return def __unicode__(self): result = 'deeper list @ ' + unicode(self.begin) + ': [' for element in self.contents: result += unicode(element) + ', ' return result[:-2] + ']' class PendingList(object): "A pending list" def __init__(self): self.contents = [] self.type = None def additem(self, item): "Add a list item" self.contents += item.contents if not self.type: self.type = item.type def adddeeper(self, deeper): "Add a deeper list item" if self.empty(): self.insertfake() self.contents[-1].contents += deeper.contents def generate(self): "Get the resulting list" if not self.type: tag = 'ul' else: tag = TagConfig.listitems[self.type] text = TaggedText().complete(self.contents, tag, True) self.__init__() return text def isduewithitem(self, item): "Decide whether the pending list must be generated before the given item" if not self.type: return False if self.type != item.type: return True return False def isduewithnext(self, next): "Applies only if the list is finished with next item." if not next: return True if not isinstance(next, ListItem) and not isinstance(next, DeeperList): return True return False def empty(self): return len(self.contents) == 0 def insertfake(self): "Insert a fake item" item = TaggedText().constant('', 'li class="nested"', True) self.contents = [item] self.type = 'Itemize' def __unicode__(self): result = 'pending ' + unicode(self.type) + ': [' for element in self.contents: result += unicode(element) + ', ' if len(self.contents) > 0: result = result[:-2] return result + ']' class PostListItem(object): "Postprocess a list item" processedclass = ListItem def postprocess(self, last, item, next): "Add the item to pending and return an empty item" if not hasattr(self.postprocessor, 'list'): self.postprocessor.list = PendingList() self.postprocessor.list.additem(item) if self.postprocessor.list.isduewithnext(next): return self.postprocessor.list.generate() if isinstance(next, ListItem) and self.postprocessor.list.isduewithitem(next): return self.postprocessor.list.generate() return BlackBox() class PostDeeperList(object): "Postprocess a deeper list" processedclass = DeeperList def postprocess(self, last, deeper, next): "Append to the list in the postprocessor" if not hasattr(self.postprocessor, 'list'): self.postprocessor.list = PendingList() self.postprocessor.list.adddeeper(deeper) if self.postprocessor.list.isduewithnext(next): return self.postprocessor.list.generate() return BlackBox() Postprocessor.stages += [PostListItem, PostDeeperList] class Float(Container): "A floating inset" type = 'none' def __init__(self): self.parser = InsetParser() self.output = TaggedOutput().settag('div class="float"', True) def process(self): "Get the float type." self.type = self.header[2] self.processnumber() self.processfloats() self.processtags() def isparent(self): "Find out whether the float is the parent float or is contained in another float." current = self.parent while current: if isinstance(current, Float): return False current = current.parent return True def processnumber(self): "Number a float if it isn't numbered." if not self.isparent(): # do nothing; parent will take care of numbering return self.partkey = PartKey().createfloat(self) def processtags(self): "Process the HTML tags." tagged = self.embed() self.applywideningtag(tagged) def embed(self): "Embed the whole contents in a div." embeddedtag = self.getembeddedtag() tagged = TaggedText().complete(self.contents, embeddedtag, True) self.contents = [tagged] return tagged def processfloats(self): "Process all floats contained inside." floats = self.searchall(Float) counter = NumberCounter('subfloat').setmode('a') for subfloat in floats: subfloat.output.tag = subfloat.output.tag.replace('div', 'span') subfloat.partkey = PartKey().createsubfloat(counter.getnext()) def getembeddedtag(self): "Get the tag for the embedded object." floats = self.searchall(Float) if len(floats) > 0: return 'div class="multi' + self.type + '"' return 'div class="' + self.type + '"' def applywideningtag(self, container): "Apply the tag to set float width, if present." images = self.searchall(Image) if len(images) != 1: return '' image = images[0] if not image.size: return width = image.size.removepercentwidth() if not width: return image.type = 'figure' ContainerSize().setmax(width).addstyle(container) image.settag() def searchinside(self, type): "Search for a given type in the contents" return self.searchincontents(self.contents, type) def searchincontents(self, contents, type): "Search in the given contents for the required type." list = [] for element in contents: list += self.searchinelement(element, type) return list def searchinelement(self, element, type): "Search for a given type outside floats" if isinstance(element, Float): return [] if isinstance(element, type): return [element] return self.searchincontents(element.contents, type) def __unicode__(self): "Return a printable representation" return 'Floating inset of type ' + self.type class Wrap(Float): "A wrapped (floating) float" def processtags(self): "Add the widening tag to the parent tag." self.embed() placement = self.getparameter('placement') if not placement: placement = 'o' self.output.tag = 'div class="wrap-' + placement + '"' self.applywideningtag(self) class Listing(Container): "A code listing" processor = None def __init__(self): self.parser = InsetParser() self.output = TaggedOutput().settag('div class="listing"', True) self.numbered = None def process(self): "Remove all layouts" self.counter = 0 self.type = 'listing' self.processparams() if Listing.processor: Listing.processor.preprocess(self) for container in self.extractcontents(): if container: self.contents.append(container) if 'caption' in self.lstparams: text = self.lstparams['caption'][1:-1] self.contents.insert(0, Caption().create(text)) if Listing.processor: Listing.processor.postprocess(self) def extractcontents(self): "Extract all contents one container at a time." oldcontents = self.contents self.contents = [] inpre = [] for container in oldcontents: if self.iscaption(container): yield self.completepre(inpre) inpre = [] yield container else: inpre += self.extract(container) yield self.completepre(inpre) def processparams(self): "Process listing parameteres." LstParser().parsecontainer(self) if 'numbers' in self.lstparams: self.numbered = self.lstparams['numbers'] def iscaption(self, container): "Find out if the container has a caption (which should not be in
)."
    return (len(container.searchall(Caption)) > 0)

  def completepre(self, listinpre):
    "Complete the 
 tag with whatever has already been added."
    if len(listinpre) == 0:
      return None
    return TaggedText().complete(listinpre, 'pre class="listing"', False)

  def extract(self, container):
    "Extract the container's contents and return them"
    if isinstance(container, StringContainer):
      return self.modifystring(container)
    if isinstance(container, StandardLayout):
      return self.modifylayout(container)
    if isinstance(container, PlainLayout):
      return self.modifylayout(container)
    Trace.error('Unexpected container ' + container.__class__.__name__ +
        ' in listing')
    container.tree()
    return []

  def modifystring(self, string):
    "Modify a listing string"
    if string.string == '':
      string.string = u'​'
    return self.modifycontainer(string)

  def modifylayout(self, layout):
    "Modify a standard layout"
    if len(layout.contents) == 0:
      layout.contents = [Constant(u'​')]
    return self.modifycontainer(layout)

  def modifycontainer(self, container):
    "Modify a listing container"
    contents = [container, Constant('\n')]
    if self.numbered:
      self.counter += 1
      tag = 'span class="number-' + self.numbered + '"'
      contents.insert(0, TaggedText().constant(unicode(self.counter), tag))
    return contents

class FloatNumber(Container):
  "Holds the number for a float in the caption."

  def __init__(self):
    self.output = ContentsOutput()

  def create(self, float):
    "Create the float number."
    self.contents = [Constant(float.partkey.partkey)]
    return self

class PostFloat(object):
  "Postprocess a float: number it and move the label"

  processedclass = Float

  def postprocess(self, last, float, next):
    "Move the label to the top and number the caption"
    number = FloatNumber().create(float)
    for caption in float.searchinside(Caption):
      self.postlabels(float, caption)
      caption.contents = [number, Separator(u' ')] + caption.contents
    return float

  def postlabels(self, float, caption):
    "Search for labels and move them to the top"
    labels = caption.searchremove(Label)
    if len(labels) == 0 and float.partkey.tocentry:
      labels = [Label().create(' ', float.partkey.partkey.replace(' ', '-'))]
    float.contents = labels + float.contents

class PostWrap(PostFloat):
  "For a wrap: exactly like a float"

  processedclass = Wrap

Postprocessor.stages += [PostFloat, PostWrap]



class IncludeInset(Container):
  "A child document included within another."

  # the converter factory will be set in converter.py
  converterfactory = None
  filename = None

  def __init__(self):
    self.parser = InsetParser()
    self.output = ContentsOutput()

  def process(self):
    "Include the provided child document"
    self.filename = os.path.join(Options.directory, self.getparameter('filename'))
    Trace.debug('Child document: ' + self.filename)
    LstParser().parsecontainer(self)
    command = self.getparameter('LatexCommand')
    if command == 'verbatiminput':
      self.readverbatim()
      return
    elif command == 'lstinputlisting':
      self.readlisting()
      return
    self.processinclude()

  def processinclude(self):
    "Process a regular include: standard child document."
    self.contents = []
    olddir = Options.directory
    newdir = os.path.dirname(self.getparameter('filename'))
    if newdir != '':
      Trace.debug('Child dir: ' + newdir)
      Options.directory = os.path.join(Options.directory, newdir)
    try:
      self.convertinclude()
    finally:
      Options.directory = olddir

  def convertinclude(self):
    "Convert an included document."
    try:
      converter = IncludeInset.converterfactory.create(self)
    except:
      Trace.error('Could not read ' + self.filename + ', please check that the file exists and has read permissions.')
      return
    if self.hasemptyoutput():
      return
    converter.convert()
    self.contents = converter.getcontents()

  def readverbatim(self):
    "Read a verbatim document."
    self.contents = [TaggedText().complete(self.readcontents(), 'pre', True)]

  def readlisting(self):
    "Read a document as a listing."
    listing = Listing()
    listing.contents = self.readcontents()
    listing.parameters = self.parameters
    listing.process()
    self.contents = [listing]

  def readcontents(self):
    "Read the contents of a complete file."
    contents = list()
    lines = BulkFile(self.filename).readall()
    for line in lines:
      contents.append(Constant(line))
    return contents

  def __unicode__(self):
    "Return a printable description."
    if not self.filename:
      return 'Included unnamed file'
    return 'Included "' + self.filename + '"'






class ChangeInserted(Container):
  "A change which consists of an insertion."

  def __init__(self):
    self.parser = TextParser(self)
    if DocumentParameters.outputchanges:
      self.output = TaggedOutput().settag('span class="inserted"')
    else:
      self.output = ContentsOutput()

class ChangeDeleted(TaggedText):
  "A change which consists of a deletion."

  def __init__(self):
    self.parser = TextParser(self)
    if DocumentParameters.outputchanges:
      self.output = TaggedOutput().settag('span class="deleted"')
    else:
      self.output = EmptyOutput()












class ERT(FirstWord):
  "Evil Red Text: embedded TeX code."
  "Considered as a first word for descriptions."

  def __init__(self):
    self.parser = InsetParser()
    self.output = ContentsOutput()

  def process(self):
    "Process all TeX code, formulas, commands."
    text = ''
    separator = ''
    for container in self.contents:
      text += separator + container.extracttext()
      separator = '\n'
    pos = TextPosition(text)
    pos.leavepending = True
    code = TeXCode()
    code.parse(pos)
    self.contents = [code]

  def isempty(self):
    "Find out if the ERT is empty or not."
    if len(self.contents) == 0:
      return True
    if len(self.contents) > 1:
      Trace.error('Unknown ERT length 2')
      return False
    texcode = self.contents[0]
    return len(texcode.contents) == 0

class TeXCode(Container):
  "A parser and processor for TeX code."

  texseparators = ['{', '\\', '}', '$', '%']
  replaced = BibTeXConfig.replaced
  factory = FormulaFactory()
  endinglist = EndingList()

  def __init__(self):
    self.contents = []
    self.output = ContentsOutput()

  def parse(self, pos):
    "Parse some TeX code."
    self.parserecursive(pos)
    if pos.leavepending:
      self.endinglist.pickpending(pos)

  def findlaststring(self):
    "Find the last string in the contents."
    if len(self.contents) == 0:
      return None
    string = self.contents[-1]
    if not isinstance(string, StringContainer):
      return None
    return string

  def add(self, piece):
    "Add a new piece to the tag."
    if isinstance(piece, basestring):
      self.addtext(piece)
    else:
      self.contents.append(piece)

  def addtext(self, piece):
    "Add a text string to the tag."
    last = self.findlaststring()
    if last:
      last.string += piece
      return
    self.contents.append(Constant(piece))

  def parserecursive(self, pos):
    "Parse brackets or quotes recursively."
    while not pos.finished():
      self.parsetext(pos)
      if pos.finished():
        return
      elif pos.checkfor('{'):
        self.parseopenbracket(pos)
      elif pos.checkfor('}'):
        self.parseclosebracket(pos)
      elif pos.checkfor('\\'):
        self.parseescaped(pos)
      elif pos.checkfor('$'):
        self.parseformula(pos)
      elif pos.checkfor('%'):
        self.parsecomment(pos)
      else:
        pos.error('Unexpected character ' + pos.current())
        pos.skipcurrent()

  def parsetext(self, pos):
    "Parse a bit of text, excluding separators and compressing spaces."
    text = self.parsecompressingspace(pos)
    if text == '':
      return
    for key in self.replaced:
      if key in text:
        text = text.replace(key, self.replaced[key])
    self.add(text)

  def parsecompressingspace(self, pos):
    "Parse some text excluding value separators and compressing spaces."
    parsed = ''
    while not pos.finished():
      parsed += pos.glob(lambda: self.excludespaces(pos))
      if not pos.finished() and pos.current().isspace():
        parsed += ' '
        pos.skipspace()
      else:
        return parsed
    return parsed

  def excludespaces(self, pos):
    "Exclude value separators and spaces."
    current = pos.current()
    if current in self.texseparators:
      return False
    if current.isspace():
      return False
    return True

  def parseescaped(self, pos):
    "Parse an escaped string \\*."
    if pos.checkfor('\\(') or pos.checkfor('\\['):
      # start of formula commands
      self.parseformula(pos)
      return
    if not self.factory.detecttype(FormulaCommand, pos):
      pos.error('Not an escape sequence')
      return
    self.add(self.factory.parsetype(FormulaCommand, pos))

  def parseopenbracket(self, pos):
    "Parse a { bracket."
    if not pos.checkskip('{'):
      pos.error('Missing opening { bracket')
      return
    pos.pushending('}')
    self.parserecursive(pos)
    pos.popending('}')

  def parseclosebracket(self, pos):
    "Parse a } bracket."
    ending = self.endinglist.findending(pos)
    if not ending:
      Trace.error('Unexpected closing } bracket')
    else:
      self.endinglist.pop(pos)
    if not pos.checkskip('}'):
      pos.error('Missing closing } bracket')
      return

  def parseformula(self, pos):
    "Parse a whole formula."
    formula = Formula().parse(pos)
    self.add(formula)

  def parsecomment(self, pos):
    "Parse a TeX comment: % to the end of the line."
    pos.globexcluding('\n')

  def __unicode__(self):
    "Return a printable representation."
    return 'TeX code: ' + self.extracttext()



class BibTagParser(object):
  "A parser for BibTeX tags."

  nameseparators = ['{', '=', '"', '#']

  def __init__(self):
    self.key = None
    tags = BibStylesConfig.defaulttags
    self.tags = dict((x, BibTag().constant(tags[x])) for x in tags)

  def parse(self, pos):
    "Parse the entry between {}."
    self.type = pos.globexcluding(self.nameseparators).strip()
    if not pos.checkskip('{'):
      pos.error('Entry should start with {')
      return
    pos.pushending('}')
    self.parsetags(pos)
    pos.popending('}')
    pos.skipspace()

  def parsetags(self, pos):
    "Parse all tags in the entry."
    pos.skipspace()
    while not pos.finished():
      if pos.checkskip('{'):
        pos.error('Unmatched {')
        return
      pos.pushending(',', True)
      self.parsetag(pos)
      if pos.checkfor(','):
        pos.popending(',')
  
  def parsetag(self, pos):
    "Parse a single tag."
    (key, value) = self.getkeyvalue(pos)
    if not key:
      return
    if not value:
      self.key = key
      return
    name = key.lower()
    self.tags[name] = value
    if hasattr(self, 'dissect' + name):
      dissector = getattr(self, 'dissect' + name)
      dissector(value.extracttext())
    if not pos.finished():
      remainder = pos.globexcluding(',')
      pos.error('Ignored ' + remainder + ' before comma')

  def getkeyvalue(self, pos):
    "Parse a string of the form key=value."
    piece = pos.globexcluding(self.nameseparators).strip()
    if pos.finished():
      return (piece, None)
    if not pos.checkskip('='):
      pos.error('Undesired character in tag name ' + piece)
      pos.skipcurrent()
      return (piece, None)
    key = piece.lower()
    pos.skipspace()
    value = self.parsevalue(pos)
    return (key, value)

  def parsevalue(self, pos):
    "Parse the value for a tag."
    tag = BibTag()
    pos.skipspace()
    if pos.checkfor(','):
      pos.error('Unexpected ,')
      return tag.error()
    tag.parse(pos)
    return tag

  def dissectauthor(self, authortag):
    "Dissect the author tag into pieces."
    authorsplit = authortag.split(' and ')
    if len(authorsplit) == 0:
      return
    authorlist = []
    for authorname in authorsplit:
      author = BibAuthor().parse(authorname)
      authorlist.append(author)
    initials = ''
    authors = ''
    if len(authorlist) == 1:
      initials = authorlist[0].surname[0:3]
      authors = unicode(authorlist[0])
    else:
      for author in authorlist:
        initials += author.surname[0:1]
        authors += unicode(author) + ', '
      authors = authors[:-2]
    self.tags['surname'] = BibTag().constant(authorlist[0].surname)
    self.tags['Sur'] = BibTag().constant(initials)
    self.tags['authors'] = BibTag().constant(authors)

  def dissectyear(self, yeartag):
    "Dissect the year tag into pieces, looking for 4 digits in a row."
    pos = TextPosition(yeartag)
    while not pos.finished():
      if pos.current().isdigit():
        number = pos.globnumber()
        if len(number) == 4:
          self.tags['YY'] = BibTag().constant(number[2:])
          return
      else:
        pos.skipcurrent()

  def dissectfile(self, filetag):
    "Extract the filename from elyxer.the file tag as ':filename:FORMAT'."
    if not filetag.startswith(':'):
      return
    bits = filetag.split(':')
    if len(bits) != 3:
      return
    self.tags['filename'] = BibTag().constant(bits[1])
    self.tags['format'] = BibTag().constant(bits[2])

  def gettag(self, key):
    "Get the tag for a given key."
    if not key in self.tags:
      return None
    return self.tags[key]

  def gettagtext(self, key):
    "Get the tag for a key as raw text."
    return self.gettag(key).extracttext()

class BibTag(Container):
  "A tag in a BibTeX file."

  valueseparators = ['{', '"', '#', '}']
  stringdefs = dict()

  def __init__(self):
    self.contents = []
    self.output = ContentsOutput()

  def constant(self, text):
    "Initialize for a single constant."
    self.contents = [Constant(text)]
    return self

  def error(self):
    "To use when parsing resulted in an error."
    return self.constant('')

  def parse(self, pos):
    "Parse brackets or quotes at the first level."
    while not pos.finished():
      self.parsetext(pos)
      if pos.finished():
        return
      elif pos.checkfor('{'):
        self.parsebracket(pos)
      elif pos.checkfor('"'):
        self.parsequoted(pos)
      elif pos.checkfor('#'):
        self.parsehash(pos)
      else:
        pos.error('Unexpected character ' + pos.current())
        pos.skipcurrent()

  def parsetext(self, pos):
    "Parse a bit of text, try to substitute strings with string defs."
    text = pos.globexcluding(self.valueseparators)
    key = text.strip()
    if key == '':
      return
    if key in self.stringdefs:
      self.add(self.stringdefs[key])
      return
    self.add(Constant(key))

  def add(self, piece):
    "Add a new piece to the tag."
    self.contents.append(piece)

  def parsetex(self, pos):
    "Parse some TeX code."
    tex = TeXCode()
    tex.parse(pos)
    self.add(tex)

  def parsebracket(self, pos):
    "Parse a {} bracket"
    if not pos.checkskip('{'):
      pos.error('Missing opening { in bracket')
      return
    pos.pushending('}')
    self.parsetex(pos)
    pos.popending('}')

  def parsequoted(self, pos):
    "Parse a piece of quoted text"
    if not pos.checkskip('"'):
      pos.error('Missing opening " in quote')
      return
    pos.pushending('"')
    self.parsetex(pos)
    pos.popending('"')
    pos.skipspace()

  def parsehash(self, pos):
    "Parse a hash mark #."
    if not pos.checkskip('#'):
      pos.error('Missing # in hash')
      return

  def __unicode__(self):
    "Return a printable representation."
    return 'BibTag: ' + self.extracttext()

class BibAuthor(object):
  "A BibTeX individual author."

  def __init__(self):
    self.surname = ''
    self.firstnames = []

  def parse(self, tag):
    "Parse an individual author tag."
    if ',' in tag:
      self.parsecomma(tag)
    else:
      self.parsewithoutcomma(tag)
    return self

  def parsecomma(self, tag):
    "Parse an author with a comma: Python, M."
    bits = tag.split(',')
    if len(bits) > 2:
      Trace.error('Too many commas in ' + tag)
    self.surname = bits[0].strip()
    self.parsefirstnames(bits[1].strip())

  def parsewithoutcomma(self, tag):
    "Parse an author without a comma: M. Python."
    bits = tag.rsplit(None, 1)
    if len(bits) == 0:
      Trace.error('Empty author')
      ppp()
      return
    self.surname = bits[-1].strip()
    if len(bits) == 1:
      return
    self.parsefirstnames(bits[0].strip())

  def parsefirstnames(self, firstnames):
    "Parse the first name."
    for firstname in firstnames.split():
      self.firstnames.append(firstname)

  def getinitial(self):
    "Get the main initial for the author."
    if len(self.surname) == 0:
      return ''
    return self.surname[0].toupper()

  def __unicode__(self):
    "Return a printable representation."
    result = ''
    for firstname in self.firstnames:
      result += firstname + ' '
    return result + self.surname



class BibTeX(Container):
  "Show a BibTeX bibliography and all referenced entries"

  def __init__(self):
    self.parser = InsetParser()
    self.output = ContentsOutput()

  def process(self):
    "Read all bibtex files and process them."
    self.entries = []
    self.contents = [self.createheader()]
    bibliography = Translator.translate('bibliography')
    files = self.getparameterlist('bibfiles')
    showall = False
    if self.getparameter('btprint') == 'btPrintAll':
      showall = True
    for file in files:
      bibfile = BibFile(file, showall)
      bibfile.parse()
      self.entries += bibfile.entries
      Trace.message('Parsed ' + unicode(bibfile))
    self.entries.sort(key = unicode)
    self.applystyle()

  def createheader(self):
    "Create the header for the bibliography."
    header = BiblioHeader()
    if 'bibtotoc' in self.getparameterlist('options'):
      header.addtotoc(self)
    return header

  def applystyle(self):
    "Read the style and apply it to all entries"
    style = self.readstyle()
    for entry in self.entries:
      entry.template = style['default']
      entry.citetemplate = style['cite']
      type = entry.type.lower()
      if type in style:
        entry.template = style[type]
      entry.process()
      self.contents.append(entry)

  def readstyle(self):
    "Read the style from elyxer.the bibliography options"
    for option in self.getparameterlist('options'):
      if hasattr(BibStylesConfig, option):
        return getattr(BibStylesConfig, option)
    return BibStylesConfig.default

class BibFile(object):
  "A BibTeX file"

  def __init__(self, filename, showall):
    "Create the BibTeX file"
    self.filename = filename + '.bib'
    self.showall = showall
    self.added = 0
    self.ignored = 0
    self.entries = []

  def parse(self):
    "Parse the BibTeX file and extract all entries."
    try:
      self.parsefile()
    except IOError:
      Trace.error('Error reading ' + self.filename + '; make sure the file exists and can be read.')

  def parsefile(self):
    "Parse the whole file."
    bibpath = InputPath(self.filename)
    if Options.lowmem:
      pos = FilePosition(bibpath.path)
    else:
      bulkfile = BulkFile(bibpath.path)
      text = ''.join(bulkfile.readall())
      pos = TextPosition(text)
    while not pos.finished():
      pos.skipspace()
      if pos.checkskip(','):
        pos.skipspace()
      self.parseentry(pos)

  def parseentry(self, pos):
    "Parse a single entry"
    for entry in BibEntry.instances:
      if entry.detect(pos):
        newentry = Cloner.clone(entry)
        newentry.parse(pos)
        if not newentry.isvisible():
          return
        if self.showall or newentry.isreferenced():
          self.entries.append(newentry)
          self.added += 1
        else:
          Trace.debug('Ignored entry ' + unicode(newentry))
          self.ignored += 1
        return
    # Skip the whole line since it's a comment outside an entry
    pos.globincluding('\n').strip()

  def __unicode__(self):
    "String representation"
    string = self.filename + ': ' + unicode(self.added) + ' entries added, '
    string += unicode(self.ignored) + ' entries ignored'
    return string

class BibEntry(Container):
  "An entry in a BibTeX file"

  instances = []

  def detect(self, pos):
    "Throw an error."
    Trace.error('Tried to detect() in ' + unicode(self))

  def parse(self, pos):
    "Throw an error."
    Trace.error('Tried to parse() in ' + unicode(self))

  def isvisible(self):
    "Return if the entry should be visible. Throws an error."
    Trace.error('Function isvisible() not implemented for ' + unicode(self))

  def isreferenced(self):
    "Return if the entry is referenced. Throws an error."
    Trace.error('Function isreferenced() not implemented for ' + unicode(self))

  def __unicode__(self):
    "Return a string representation"
    return 'BibTeX entry ' + self.__class__.__name__

class CommentEntry(BibEntry):
  "A simple comment."

  def detect(self, pos):
    "Detect the special entry"
    return pos.checkfor('%')

  def parse(self, pos):
    "Parse all consecutive comment lines."
    while pos.checkfor('%'):
      pos.globincluding('\n')

  def isvisible(self):
    "A comment entry is never visible."
    return False

  def __unicode__(self):
    "Return a string representation"
    return 'Comment'

class SpecialEntry(BibEntry):
  "A special entry"

  types = ['@preamble', '@comment']

  def __init__(self):
    self.contents = []
    self.output = EmptyOutput()

  def detect(self, pos):
    "Detect the special entry"
    for type in self.types:
      if pos.checkforlower(type):
        return True
    return False

  def parse(self, pos):
    "Parse and ignore."
    self.type = 'special'
    pos.globincluding('{')
    pos.pushending('}')
    while not pos.finished():
      if pos.checkfor('{'):
        self.parse(pos)
      else:
        pos.skipcurrent()
    pos.popending()

  def isvisible(self):
    "A special entry is never visible."
    return False

  def __unicode__(self):
    "Return a string representation"
    return self.type

class StringEntry(SpecialEntry):
  "A string definition. The definition can later be used in other entries."

  parser = BibTagParser()
  start = '@string'
  key = None

  def detect(self, pos):
    "Detect the string definition."
    return pos.checkforlower(self.start)

  def parse(self, pos):
    "Parse a single tag, which will define a string."
    self.type = self.start
    if not self.checkstart(pos):
      return
    pos.skipspace()
    if not pos.checkskip('{'):
      Trace.error('Missing opening { in ' + unicode(self))
      pos.globincluding('\n')
      return
    pos.pushending('}')
    (self.key, value) = self.parser.getkeyvalue(pos)
    BibTag.stringdefs[self.key] = value
    pos.popending('}')

  def checkstart(self, pos):
    "Check that the entry starts with @string."
    if not pos.checkskip('@'):
      Trace.error('Missing @ from elyxer.string definition')
      return False
    name = '@' + pos.globalpha()
    if not name.lower() == self.start.lower():
      Trace.error('Invalid start @' + name +', missing ' + self.start + ' from elyxer.' + unicode(self))
      pos.globincluding('\n')
      return False
    return True

  def __unicode__(self):
    "Return a printable representation."
    result = 'string definition'
    if self.key:
      result += ' for ' + self.key
    return result


BibEntry.instances += [CommentEntry(), SpecialEntry(), StringEntry()]






class PubEntry(BibEntry):
  "A publication entry"

  def __init__(self):
    self.output = TaggedOutput().settag('p class="biblio"', True)

  def detect(self, pos):
    "Detect a publication entry."
    return pos.checkfor('@')

  def parse(self, pos):
    "Parse the publication entry."
    self.parser = BibTagParser()
    self.parser.parse(pos)
    self.type = self.parser.type

  def isvisible(self):
    "A publication entry is always visible."
    return True

  def isreferenced(self):
    "Check if the entry is referenced."
    if not self.parser.key:
      return False
    return self.parser.key in BiblioReference.references

  def process(self):
    "Process the entry."
    self.index = NumberGenerator.generator.generate('pubentry')
    self.parser.tags['index'] = Constant(self.index)
    biblio = BiblioEntry()
    biblio.citeref = self.createref()
    biblio.processcites(self.parser.key)
    self.contents = [biblio, Constant(' ')]
    self.contents += self.entrycontents()

  def entrycontents(self):
    "Get the contents of the entry."
    return self.translatetemplate(self.template)

  def createref(self):
    "Create the reference to cite."
    return self.translatetemplate(self.citetemplate)

  def translatetemplate(self, template):
    "Translate a complete template into a list of contents."
    pos = TextPosition(template)
    part = BibPart(self.parser.tags).parse(pos)
    for variable in part.searchall(BibVariable):
      if variable.empty():
        Trace.error('Error parsing BibTeX template for ' + unicode(self) + ': '
            + unicode(variable) + ' is empty')
    return [part]

  def __unicode__(self):
    "Return a string representation"
    string = ''
    if 'author' in self.parser.tags:
      string += self.parser.gettagtext('author') + ': '
    if 'title' in self.parser.tags:
      string += '"' + self.parser.gettagtext('title') + '"'
    return string

class BibPart(Container):
  "A part of a BibTeX template."

  def __init__(self, tags):
    self.output = ContentsOutput()
    self.contents = []
    self.tags = tags
    self.quotes = 0

  def parse(self, pos):
    "Parse a part of a template, return a list of contents."
    while not pos.finished():
      self.add(self.parsepiece(pos))
    return self

  def parsepiece(self, pos):
    "Get the next piece of the template, return if it was empty."
    if pos.checkfor('{'):
      return self.parsebraces(pos)
    elif pos.checkfor('$'):
      return self.parsevariable(pos)
    result = ''
    while not pos.finished() and not pos.current() in '{$':
      if pos.current() == '"':
        self.quotes += 1
      result += pos.skipcurrent()
    return Constant(result)

  def parsebraces(self, pos):
    "Parse a pair of curly braces {}."
    if not pos.checkskip('{'):
      Trace.error('Missing { in braces.')
      return None
    pos.pushending('}')
    part = BibPart(self.tags).parse(pos)
    pos.popending('}')
    empty = part.emptyvariables()
    if empty:
      return None
    return part

  def parsevariable(self, pos):
    "Parse a variable $name."
    var = BibVariable(self.tags).parse(pos)
    if self.quotes % 2 == 1:
      # odd number of quotes; don't add spans in an attribute
      var.removetag()
    return var

  def emptyvariables(self):
    "Find out if there are only empty variables in the part."
    for variable in self.searchall(BibVariable):
      if not variable.empty():
        return False
    return True

  def add(self, piece):
    "Add a new piece to the current part."
    if not piece:
      return
    if self.redundantdot(piece):
      # remove extra dot
      piece.string = piece.string[1:]
    self.contents.append(piece)
    piece.parent = self

  def redundantdot(self, piece):
    "Find out if there is a redundant dot in the next piece."
    if not isinstance(piece, Constant):
      return False
    if not piece.string.startswith('.'):
      return False
    if len(self.contents) == 0:
      return False
    if not isinstance(self.contents[-1], BibVariable):
      return False
    if not self.contents[-1].extracttext().endswith('.'):
      return False
    return True

class BibVariable(Container):
  "A variable in a BibTeX template."
  
  def __init__(self, tags):
    self.output = TaggedOutput()
    self.contents = []
    self.tags = tags

  def parse(self, pos):
    "Parse the variable name."
    if not pos.checkskip('$'):
      Trace.error('Missing $ in variable name.')
      return self
    self.key = pos.globalpha()
    self.output.tag = 'span class="bib-' + self.key + '"'
    self.processtags()
    return self

  def processtags(self):
    "Find the tag with the appropriate key in the list of tags."
    if not self.key in self.tags:
      return
    result = self.tags[self.key]
    self.contents = [result]

  def empty(self):
    "Find out if the variable is empty."
    if not self.contents:
      return True
    if self.extracttext() == '':
      return True
    return False

  def removetag(self):
    "Remove the output tag and leave just the contents."
    self.output = ContentsOutput()

  def __unicode__(self):
    "Return a printable representation."
    result = 'variable ' + self.key
    if not self.empty():
      result += ':' + self.extracttext()
    return result

BibEntry.instances += [PubEntry()]






class NewfangledChunk(Layout):
  "A chunk of literate programming."

  names = dict()
  firsttime = True

  def process(self):
    "Process the literate chunk."
    self.output.tag = 'div class="chunk"'
    self.type = 'chunk'
    text = self.extracttext()
    parts = text.split(',')
    if len(parts) < 1:
      Trace.error('Not enough parameters in ' + text)
      return
    self.name = parts[0]
    self.number = self.order()
    self.createlinks()
    self.contents = [self.left, self.declaration(), self.right]
    ChunkProcessor.lastchunk = self

  def order(self):
    "Create the order number for the chunk."
    return NumberGenerator.generator.generate('chunk')

  def createlinks(self):
    "Create back and forward links."
    self.leftlink = Link().complete(self.number, 'chunk:' + self.number, type='chunk')
    self.left = TaggedText().complete([self.leftlink], 'span class="chunkleft"', False)
    self.right = TaggedText().constant('', 'span class="chunkright"', False)
    if not self.name in NewfangledChunk.names:
      NewfangledChunk.names[self.name] = []
    else:
      last = NewfangledChunk.names[self.name][-1]
      forwardlink = Link().complete(self.number + u'→', 'chunkback:' + last.number, type='chunk')
      backlink = Link().complete(u'←' + last.number + u' ', 'chunkforward:' + self.number, type='chunk')
      forwardlink.setmutualdestination(backlink)
      last.right.contents.append(forwardlink)
      self.right.contents.append(backlink)
    NewfangledChunk.names[self.name].append(self)
    self.origin = self.createorigin()
    if self.name in NewfangledChunkRef.references:
      for ref in NewfangledChunkRef.references[self.name]:
        self.linkorigin(ref.origin)

  def createorigin(self):
    "Create a link that points to the chunks' origin."
    link = Link()
    self.linkorigin(link)
    return link

  def linkorigin(self, link):
    "Create a link to the origin."
    start = NewfangledChunk.names[self.name][0]
    link.complete(start.number, type='chunk')
    link.destination = start.leftlink
    link.computedestination()

  def declaration(self):
    "Get the chunk declaration."
    contents = []
    text = u'⟨' + self.name + '[' + unicode(len(NewfangledChunk.names[self.name])) + '] '
    contents.append(Constant(text))
    contents.append(self.origin)
    text = ''
    if NewfangledChunk.firsttime:
      Listing.processor = ChunkProcessor()
      NewfangledChunk.firsttime = False
    text += u'⟩'
    if len(NewfangledChunk.names[self.name]) > 1:
      text += '+'
    text += u'≡'
    contents.append(Constant(text))
    return TaggedText().complete(contents, 'span class="chunkdecl"', True)

class ChunkProcessor(object):
  "A processor for listings that belong to chunks."

  lastchunk = None
  counters = dict()
  endcommand = '}'
  chunkref = 'chunkref'

  def preprocess(self, listing):
    "Preprocess a listing: set the starting counter."
    if not ChunkProcessor.lastchunk:
      return
    name = ChunkProcessor.lastchunk.name
    if not name in ChunkProcessor.counters:
      ChunkProcessor.counters[name] = 0
    listing.counter = ChunkProcessor.counters[name]
    for command, container, index in self.commandsinlisting(listing):
      chunkref = self.getchunkref(command)
      if chunkref:
        self.insertchunkref(chunkref, container, index)

  def commandsinlisting(self, listing):
    "Find all newfangle commands in a listing."
    for container in listing.contents:
      for index in range(len(container.contents) - 2):
        if self.findinelement(container, index):
          third = container.contents[index + 2].string
          end = third.index(NewfangleConfig.constants['endmark'])
          command = third[:end]
          lenstart = len(NewfangleConfig.constants['startmark'])
          container.contents[index].string = container.contents[index].string[:-lenstart]
          del container.contents[index + 1]
          container.contents[index + 1].string = third[end + len(NewfangleConfig.constants['endmark']):]
          yield command, container, index

  def findinelement(self, container, index):
    "Find a newfangle command in an element."
    for i in range(2):
      if not isinstance(container.contents[index + i], StringContainer):
        return False
    first = container.contents[index].string
    second = container.contents[index + 1].string
    third = container.contents[index + 2].string
    if not first.endswith(NewfangleConfig.constants['startmark']):
      return False
    if second != NewfangleConfig.constants['startcommand']:
      return False
    if not NewfangleConfig.constants['endmark'] in third:
      return False
    return True

  def getchunkref(self, command):
    "Get the contents of a chunkref command, if present."
    if not command.startswith(NewfangleConfig.constants['chunkref']):
      return None
    if not NewfangleConfig.constants['endcommand'] in command:
      return None
    start = len(NewfangleConfig.constants['chunkref'])
    end = command.index(NewfangleConfig.constants['endcommand'])
    return command[start:end]

  def insertchunkref(self, ref, container, index):
    "Insert a chunkref after the given index at the given container."
    chunkref = NewfangledChunkRef().complete(ref)
    container.contents.insert(index + 1, chunkref)

  def postprocess(self, listing):
    "Postprocess a listing: store the ending counter for next chunk."
    if not ChunkProcessor.lastchunk:
      return
    ChunkProcessor.counters[ChunkProcessor.lastchunk.name] = listing.counter

class NewfangledChunkRef(Inset):
  "A reference to a chunk."

  references = dict()

  def process(self):
    "Show the reference."
    self.output.tag = 'span class="chunkref"'
    self.ref = self.extracttext()
    self.addbits()

  def complete(self, ref):
    "Complete the reference to the given string."
    self.output = ContentsOutput()
    self.ref = ref
    self.contents = [Constant(self.ref)]
    self.addbits()
    return self

  def addbits(self):
    "Add the bits to the reference."
    if not self.ref in NewfangledChunkRef.references:
      NewfangledChunkRef.references[self.ref] = []
    NewfangledChunkRef.references[self.ref].append(self)
    if self.ref in NewfangledChunk.names:
      start = NewfangledChunk.names[self.ref][0]
      self.origin = start.createorigin()
    else:
      self.origin = Link()
    self.contents.insert(0, Constant(u'⟨'))
    self.contents.append(Constant(' '))
    self.contents.append(self.origin)
    self.contents.append(Constant(u'⟩'))

  def __unicode__(self):
    "Return a printable representation."
    return 'Reference to chunk ' + self.ref






class SetCounterFunction(CommandBit):
  "A function which is used in the preamble to set a counter."

  def parsebit(self, pos):
    "Parse a function with [] and {} parameters."
    counter = self.parseliteral(pos)
    value = self.parseliteral(pos)
    try:
      self.setcounter(counter, int(value))
    except:
      Trace.error('Counter ' + counter + ' cannot be set to ' + value)

  def setcounter(self, counter, value):
    "Set a global counter."
    Trace.debug('Setting counter ' + unicode(counter) + ' to ' + unicode(value))
    NumberGenerator.generator.getcounter(counter).init(value)

class FormulaTag(CommandBit):
  "A \\tag command."

  def parsebit(self, pos):
    "Parse the tag and apply it."
    self.output = EmptyOutput()
    self.tag = self.parseliteral(pos)

class MiscCommand(CommandBit):
  "A generic command which maps to a command class."

  commandmap = FormulaConfig.misccommands

  def parsebit(self, pos):
    "Find the right command to parse and parse it."
    commandtype = globals()[self.translated]
    return self.parsecommandtype(self.translated, commandtype, pos)

FormulaCommand.types += [MiscCommand]



class ContainerFactory(object):
  "Creates containers depending on the first line"

  def __init__(self):
    "Read table that convert start lines to containers"
    types = dict()
    for start, typename in ContainerConfig.starts.iteritems():
      types[start] = globals()[typename]
    self.tree = ParseTree(types)

  def createcontainer(self, reader):
    "Parse a single container."
    #Trace.debug('processing "' + reader.currentline().strip() + '"')
    if reader.currentline() == '':
      reader.nextline()
      return None
    container = Cloner.create(self.tree.find(reader))
    container.start = reader.currentline().strip()
    self.parse(container, reader)
    return container

  def parse(self, container, reader):
    "Parse a container"
    parser = container.parser
    parser.parent = container
    parser.ending = self.getending(container)
    parser.factory = self
    container.header = parser.parseheader(reader)
    container.begin = parser.begin
    self.parsecontents(container, reader)
    container.parameters = parser.parameters
    container.parser = None

  def parsecontents(self, container, reader):
    "Parse the contents of a container."
    contents = container.parser.parse(reader)
    if isinstance(contents, basestring):
      # read a string, set as parsed
      container.parsed = contents
      container.contents = []
    else:
      container.contents = contents

  def getending(self, container):
    "Get the ending for a container"
    split = container.start.split()
    if len(split) == 0:
      return None
    start = split[0]
    if start in ContainerConfig.startendings:
      return ContainerConfig.startendings[start]
    classname = container.__class__.__name__
    if classname in ContainerConfig.endings:
      return ContainerConfig.endings[classname]
    if hasattr(container, 'ending'):
      Trace.error('Pending ending in ' + container.__class__.__name__)
      return container.ending
    return None

class ParseTree(object):
  "A parsing tree"

  default = '~~default~~'

  def __init__(self, types):
    "Create the parse tree"
    self.root = dict()
    for start, type in types.iteritems():
      self.addstart(type, start)

  def addstart(self, type, start):
    "Add a start piece to the tree"
    tree = self.root
    for piece in start.split():
      if not piece in tree:
        tree[piece] = dict()
      tree = tree[piece]
    if ParseTree.default in tree:
      Trace.error('Start ' + start + ' duplicated')
    tree[ParseTree.default] = type

  def find(self, reader):
    "Find the current sentence in the tree"
    branches = self.matchline(reader.currentline())
    while not ParseTree.default in branches[-1]:
      branches.pop()
    last = branches[-1]
    return last[ParseTree.default]

  def matchline(self, line):
    "Match a given line against the tree, as deep as possible."
    branches = [self.root]
    for piece in line.split(' '):
      current = branches[-1]
      piece = piece.rstrip('>')
      if piece in current:
        branches.append(current[piece])
      else:
        return branches
    return branches







class TOCEntry(Container):
  "A container for a TOC entry."

  def __init__(self):
    Container.__init__(self)
    self.branches = []

  def create(self, container):
    "Create the TOC entry for a container, consisting of a single link."
    if container.partkey.header:
      return self.header(container)
    self.contents = [self.createlink(container)]
    self.output = TaggedOutput().settag('div class="toc"', True)
    self.partkey = container.partkey
    return self

  def header(self, container):
    "Create a TOC entry for header and footer (0 depth)."
    self.partkey = container.partkey
    self.output = EmptyOutput()
    return self

  def createlink(self, container):
    "Create the link that will make the whole TOC entry."
    labels = container.searchall(Label)
    link = Link()
    if self.isanchor(labels):
      link.url = '#' + container.partkey.partkey
      if Options.tocfor:
        link.url = Options.tocfor + link.url
    else:
      label = labels[0]
      link.destination = label
    if container.partkey.tocentry:
      link.complete(container.partkey.tocentry)
    if container.partkey.titlecontents:
      if Options.notoclabels:
        separator = u' '
      else:
        separator = u': '
      if container.partkey.tocentry:
        link.contents.append(Constant(separator))
      link.contents += container.partkey.titlecontents
    return link

  def isanchor(self, labels):
    "Decide if the link is an anchor based on a set of labels."
    if len(labels) == 0:
      return True
    if not Options.tocfor:
      return False
    if Options.splitpart:
      return False
    return True

  def __unicode__(self):
    "Return a printable representation."
    if not self.partkey.tocentry:
      return 'Unnamed TOC entry'
    return 'TOC entry: ' + self.partkey.tocentry

class Indenter(object):
  "Manages and writes indentation for the TOC."

  def __init__(self):
    self.depth = 0

  def getindent(self, depth):
    indent = ''
    if depth > self.depth:
      indent = self.openindent(depth - self.depth)
    elif depth < self.depth:
      indent = self.closeindent(self.depth - depth)
    self.depth = depth
    return Constant(indent)

  def openindent(self, times):
    "Open the indenting div a few times."
    indent = ''
    for i in range(times):
      indent += '
\n' return indent def closeindent(self, times): "Close the indenting div a few times." indent = '' for i in range(times): indent += '
\n' return indent class IndentedEntry(Container): "An entry with an indentation." def __init__(self): self.output = ContentsOutput() def create(self, indent, entry): "Create the indented entry." self.entry = entry self.contents = [indent, entry] return self def __unicode__(self): "Return a printable documentation." return 'Indented ' + unicode(self.entry) class TOCTree(object): "A tree that contains the full TOC." def __init__(self): self.tree = [] self.branches = [] def store(self, entry): "Place the entry in a tree of entries." while len(self.tree) < entry.partkey.level: self.tree.append(None) if len(self.tree) > entry.partkey.level: self.tree = self.tree[:entry.partkey.level] stem = self.findstem() if len(self.tree) == 0: self.branches.append(entry) self.tree.append(entry) if stem: entry.stem = stem stem.branches.append(entry) def findstem(self): "Find the stem where our next element will be inserted." for element in reversed(self.tree): if element: return element return None class TOCConverter(object): "A converter from elyxer.containers to TOC entries." cache = dict() tree = TOCTree() def __init__(self): self.indenter = Indenter() def convertindented(self, container): "Convert a container into an indented TOC entry." entry = self.convert(container) if not entry: return None return self.indent(entry) def indent(self, entry): "Indent a TOC entry." indent = self.indenter.getindent(entry.partkey.level) return IndentedEntry().create(indent, entry) def convert(self, container): "Convert a container to a TOC entry." if not container.partkey: return None if container.partkey.partkey in self.cache: return TOCConverter.cache[container.partkey.partkey] if container.partkey.level > DocumentParameters.tocdepth: return None entry = TOCEntry().create(container) TOCConverter.cache[container.partkey.partkey] = entry TOCConverter.tree.store(entry) return entry class Basket(object): "A basket to place a set of containers. Can write them, store them..." def setwriter(self, writer): self.writer = writer return self class WriterBasket(Basket): "A writer of containers. Just writes them out to a writer." def write(self, container): "Write a container to the line writer." self.writer.write(container.gethtml()) def finish(self): "Mark as finished." self.writer.close() class KeeperBasket(Basket): "Keeps all containers stored." def __init__(self): self.contents = [] def write(self, container): "Keep the container." self.contents.append(container) def finish(self): "Finish the basket by flushing to disk." self.flush() def flush(self): "Flush the contents to the writer." for container in self.contents: self.writer.write(container.gethtml()) self.writer.close() class TOCBasket(Basket): "A basket to place the TOC of a document." def __init__(self): self.converter = TOCConverter() def setwriter(self, writer): Basket.setwriter(self, writer) Options.nocopy = True self.writer.write(LyXHeader().gethtml()) return self def write(self, container): "Write the table of contents for a container." entry = self.converter.convertindented(container) if entry: self.writer.write(entry.gethtml()) def finish(self): "Mark as finished." self.writer.write(LyXFooter().gethtml()) self.writer.close() class IntegralProcessor(object): "A processor for an integral document." def __init__(self): "Create the processor for the integral contents." self.storage = [] def locate(self, container): "Locate only containers of the processed type." return isinstance(container, self.processedtype) def store(self, container): "Store a new container." self.storage.append(container) def process(self): "Process the whole storage." for container in self.storage: self.processeach(container) class IntegralTOC(IntegralProcessor): "A processor for an integral TOC." processedtype = TableOfContents tocentries = [] def processeach(self, toc): "Fill in a Table of Contents." converter = TOCConverter() for container in PartKeyGenerator.partkeyed: toc.add(converter.convertindented(container)) # finish off with the footer to align indents toc.add(converter.convertindented(LyXFooter())) def writetotoc(self, entries, toc): "Write some entries to the TOC." for entry in entries: toc.contents.append(entry) class IntegralBiblioEntry(IntegralProcessor): "A processor for an integral bibliography entry." processedtype = BiblioEntry def processeach(self, entry): "Process each entry." number = NumberGenerator.generator.generate('integralbib') link = Link().complete('cite', 'biblio-' + number, type='biblioentry') link.contents = entry.citeref entry.contents = [Constant('['), link, Constant('] ')] if entry.key in BiblioCite.cites: for cite in BiblioCite.cites[entry.key]: cite.contents = entry.citeref cite.anchor = 'cite-' + number cite.destination = link class IntegralFloat(IntegralProcessor): "Store all floats in the document by type." processedtype = Float bytype = dict() def processeach(self, float): "Store each float by type." if not float.type in IntegralFloat.bytype: IntegralFloat.bytype[float.type] = [] IntegralFloat.bytype[float.type].append(float) class IntegralListOf(IntegralProcessor): "A processor for an integral list of floats." processedtype = ListOf def processeach(self, listof): "Fill in a list of floats." listof.output = TaggedOutput().settag('div class="fulltoc"', True) if not listof.type in IntegralFloat.bytype: Trace.message('No floats of type ' + listof.type) return for float in IntegralFloat.bytype[listof.type]: entry = self.processfloat(float) if entry: listof.contents.append(entry) def processfloat(self, float): "Get an entry for the list of floats." if not float.isparent(): return None return TOCEntry().create(float) class IntegralReference(IntegralProcessor): "A processor for a reference to a label." processedtype = Reference def processeach(self, reference): "Extract the text of the original label." reference.formatcontents() class MemoryBasket(KeeperBasket): "A basket which stores everything in memory, processes it and writes it." def __init__(self): "Create all processors in one go." KeeperBasket.__init__(self) self.processors = [ IntegralTOC(), IntegralBiblioEntry(), IntegralFloat(), IntegralListOf(), IntegralReference(), ] def finish(self): "Process everything which cannot be done in one pass and write to disk." self.process() self.flush() def process(self): "Process everything with the integral processors." self.searchintegral() for processor in self.processors: processor.process() def searchintegral(self): "Search for all containers for all integral processors." for container in self.contents: # container.tree() if self.integrallocate(container): self.integralstore(container) container.locateprocess(self.integrallocate, self.integralstore) def integrallocate(self, container): "Locate all integrals." for processor in self.processors: if processor.locate(container): return True return False def integralstore(self, container): "Store a container in one or more processors." for processor in self.processors: if processor.locate(container): processor.store(container) class SplitPartLink(IntegralProcessor): "A link processor for multi-page output." processedtype = Link def processeach(self, link): "Process each link and add the current page." link.page = self.page class NavigationLink(Container): "A link in the navigation header." def __init__(self, name): "Create the link for a given name (prev, next...)." self.name = name self.link = Link().complete(u' ', name, type=name) self.output = TaggedOutput().settag('span class="' + name + '"') self.contents = [self.link] def complete(self, container, after = False): "Complete the navigation link with destination container." "The 'after' parameter decides if the link goes after the part title." if not container.partkey: Trace.error('No part key for link name ' + unicode(container)) return self.link.contents = [Constant(Translator.translate(self.name))] partname = self.getpartname(container) separator = Constant(u' ') if after: self.contents = partname + [separator, self.link] else: self.contents = [self.link, separator] + partname def getpartname(self, container): "Get the part name for a container, title optional." partname = [Constant(container.partkey.tocentry)] if not container.partkey.titlecontents: return partname if Options.notoclabels: return container.partkey.titlecontents return partname + [Constant(': ')] + container.partkey.titlecontents def setdestination(self, destination): "Set the destination for this link." self.link.destination = destination def setmutualdestination(self, destination): "Set the destination for this link, and vice versa." self.link.setmutualdestination(destination.link) class UpAnchor(Link): "An anchor to the top of the page for the up links." def create(self, container): "Create the up anchor based on the first container." if not container.partkey: Trace.error('No part key for ' + unicode(container)) return None self.createliteral(container.partkey.tocentry) self.partkey.titlecontents = container.partkey.titlecontents return self def createmain(self): "Create the up anchor for the main page." return self.createliteral(Translator.translate('main-page')) def createliteral(self, literal): "Create the up anchor based on a literal string." self.complete('', '') self.output = EmptyOutput() self.partkey = PartKey().createanchor(literal) return self class SplitPartNavigation(object): "Used to create the navigation links for a new split page." def __init__(self): self.upanchors = [] self.lastcontainer = None self.nextlink = None self.lastnavigation = None def writefirstheader(self, basket): "Write the first header to the basket." anchor = self.createmainanchor() basket.write(anchor) basket.write(self.createnavigation(anchor)) def writeheader(self, basket, container): "Write the header to the basket." basket.write(LyXHeader()) basket.write(self.currentupanchor(container)) basket.write(self.createnavigation(container)) def writefooter(self, basket): "Write the footer to the basket." if self.lastnavigation: basket.write(self.lastnavigation) basket.write(LyXFooter()) def createnavigation(self, container): "Create the navigation bar with all links." prevlink = NavigationLink('prev') uplink = NavigationLink('up') if self.nextlink: prevlink.complete(self.lastcontainer) self.nextlink.complete(container, after=True) prevlink.setmutualdestination(self.nextlink) uplink.complete(self.getupdestination(container)) uplink.setdestination(self.getupdestination(container)) self.nextlink = NavigationLink('next') contents = [prevlink, Constant('\n'), uplink, Constant('\n'), self.nextlink] header = TaggedText().complete(contents, 'div class="splitheader"', True) self.lastcontainer = container self.lastnavigation = header return header def currentupanchor(self, container): "Update the internal list of up anchors, and return the current one." level = self.getlevel(container) while len(self.upanchors) > level: del self.upanchors[-1] while len(self.upanchors) < level: self.upanchors.append(self.upanchors[-1]) upanchor = UpAnchor().create(container) self.upanchors.append(upanchor) return upanchor def createmainanchor(self): "Create the up anchor to the main page." mainanchor = UpAnchor().createmain() self.upanchors.append(mainanchor) return mainanchor def getupdestination(self, container): "Get the name of the up page." level = self.getlevel(container) if len(self.upanchors) < level: uppage = self.upanchors[-1] else: uppage = self.upanchors[level - 1] return uppage def getlevel(self, container): "Get the level of the container." if not container.partkey: return 1 else: return container.partkey.level + 1 class SplitFileBasket(MemoryBasket): "A memory basket which contains a part split into a file, possibly with a TOC." def __init__(self): MemoryBasket.__init__(self) self.entrycount = 0 self.root = None self.converter = TOCConverter() def write(self, container): "Keep track of numbered layouts." MemoryBasket.write(self, container) if not container.partkey: return if container.partkey.header: return entry = self.converter.convert(container) if not entry: return self.entrycount += 1 self.root = entry def addtoc(self): "Add the table of contents if necessary." if self.entrycount != 1: return if self.root.branches == []: return text = Translator.translate('toc-for') + self.root.partkey.tocentry toc = TableOfContents().create(text) self.addbranches(self.root, toc) toc.add(self.converter.convertindented(LyXFooter())) self.write(toc) def addbranches(self, entry, toc): "Add an entry and all of its branches to the table of contents." for branch in entry.branches: toc.add(self.converter.indent(branch)) self.addbranches(branch, toc) class SplitPartBasket(Basket): "A basket used to split the output in different files." baskets = [] def setwriter(self, writer): if not hasattr(writer, 'filename') or not writer.filename: Trace.error('Cannot use standard output for split output; ' + 'please supply an output filename.') exit() self.writer = writer self.filename = writer.filename self.converter = TOCConverter() self.basket = MemoryBasket() self.basket.page = writer.filename return self def write(self, container): "Write a container, possibly splitting the file." self.basket.write(container) def splitbaskets(self): "Process the whole basket and create all baskets for split part pages." self.basket.process() basket = self.firstbasket() navigation = SplitPartNavigation() for container in self.basket.contents: if self.mustsplit(container): filename = self.getfilename(container) Trace.debug('New page ' + filename) basket.addtoc() navigation.writefooter(basket) basket = self.addbasket(filename) navigation.writeheader(basket, container) basket.write(container) if self.afterheader(container): navigation.writefirstheader(basket) self.mainanchor = navigation.upanchors[0] for basket in self.baskets: basket.process() def finish(self): "Process the whole basket, split into page baskets and flush all of them." self.splitbaskets() for basket in self.baskets: basket.flush() def afterheader(self, container): "Find out if this is the header on the file." return isinstance(container, LyXHeader) def firstbasket(self): "Create the first basket." return self.addbasket(self.filename, self.writer) def addbasket(self, filename, writer = None): "Add a new basket." if not writer: writer = LineWriter(filename) basket = SplitFileBasket() basket.setwriter(writer) self.baskets.append(basket) # set the page name everywhere basket.page = filename splitpartlink = SplitPartLink() splitpartlink.page = os.path.basename(basket.page) basket.processors = [splitpartlink] return basket def mustsplit(self, container): "Find out if the oputput file has to be split at this entry." if not container.partkey: return False if not container.partkey.filename: return False return True def getfilename(self, container): "Get the new file name for a given container." partname = container.partkey.filename basename = self.filename if Options.tocfor: basename = Options.tocfor base, extension = os.path.splitext(basename) return base + '-' + partname + extension class SplitTOCBasket(SplitPartBasket): "A basket which contains the TOC for a split part document." def finish(self): "Process the whole basket, split into page baskets and flush all of them." self.splitbaskets() tocbasket = TOCBasket().setwriter(self.writer) self.mainanchor.partkey = PartKey().createmain() tocbasket.write(self.mainanchor) for container in self.basket.contents: tocbasket.write(container) tocbasket.finish() class PostFormula(object): "Postprocess a formula" processedclass = Formula def postprocess(self, last, formula, next): "Postprocess any formulae" if Options.jsmath or Options.mathjax: return formula self.postnumbering(formula) return formula def postnumbering(self, formula): "Check if it's a numbered equation, insert number." if formula.header[0] != 'numbered': return functions = formula.searchremove(LabelFunction) if len(functions) == 0: label = self.createlabel(formula) elif len(functions) == 1: label = self.createlabel(formula, functions[0]) if len(functions) <= 1: label.parent = formula formula.contents.insert(0, label) return for function in functions: label = self.createlabel(formula, function) row = self.searchrow(function) label.parent = row row.contents.insert(0, label) def createlabel(self, formula, function = None): "Create a new label for a formula." "Add a label to a formula." tag = self.createtag(formula) partkey = PartKey().createformula(tag) if not formula.partkey: formula.partkey = partkey if not function: label = Label() label.create(partkey.tocentry + ' ', 'eq-' + tag, type="eqnumber") else: label = function.label label.complete(partkey.tocentry + ' ') return label def createtag(self, formula): "Create the label tag." tags = formula.searchall(FormulaTag) if len(tags) == 0: return NumberGenerator.chaptered.generate('formula') if len(tags) > 1: Trace.error('More than one tag in formula: ' + unicode(formula)) return tags[0].tag def searchrow(self, function): "Search for the row that contains the label function." if isinstance(function.parent, Formula) or isinstance(function.parent, FormulaRow): return function.parent return self.searchrow(function.parent) Postprocessor.stages.append(PostFormula) class eLyXerConverter(object): "Converter for a document in a lyx file. Places all output in a given basket." def __init__(self): self.filtering = False def setio(self, ioparser): "Set the InOutParser" self.reader = ioparser.getreader() self.basket = self.getbasket() self.basket.setwriter(ioparser.getwriter()) return self def getbasket(self): "Get the appropriate basket for the current options." if Options.tocfor: if Options.splitpart: return SplitTOCBasket() return TOCBasket() if Options.splitpart: return SplitPartBasket() if Options.memory: return MemoryBasket() return WriterBasket() def embed(self, reader): "Embed the results from elyxer.a reader into a memory basket." "Header and footer are ignored. Useful for embedding one document inside another." self.filtering = True self.reader = reader self.basket = MemoryBasket() return self def convert(self): "Perform the conversion for the document" try: self.processcontents() except (Exception): version = '[eLyXer version ' + GeneralConfig.version['number'] version += ' (' + GeneralConfig.version['date'] + ') in ' version += Options.location + '] ' Trace.error(version) Trace.error('Conversion failed at ' + self.reader.currentline()) raise def processcontents(self): "Parse the contents and write it by containers" factory = ContainerFactory() processor = Processor(self.filtering) while not self.reader.finished(): container = factory.createcontainer(self.reader) result = processor.process(container) self.writecontainer(result) result = processor.postprocess(None) self.writecontainer(result) if not self.filtering: self.basket.finish() def writecontainer(self, container): "Write each container to the correct basket." if not container: return includes = container.searchremove(IncludeInset) self.basket.write(container) # recursive processing for IncludeInset for include in includes: for element in include.contents: self.basket.write(element) def getcontents(self): "Return the contents of the basket." return self.basket.contents def __unicode__(self): "Printable representation." string = 'Converter with filtering ' + unicode(self.filtering) string += ' and basket ' + unicode(self.basket) return string class InOutParser(object): "Parse in and out arguments" def __init__(self): self.filein = sys.stdin self.fileout = sys.stdout def parse(self, args): "Parse command line arguments" self.filein = sys.stdin self.fileout = sys.stdout if len(args) < 2: Trace.quietmode = True if len(args) > 0: self.filein = args[0] del args[0] self.readdir(self.filein, 'directory') else: Options.directory = '.' if len(args) > 0: self.fileout = args[0] del args[0] self.readdir(self.fileout, 'destdirectory') else: Options.destdirectory = '.' if len(args) > 0: raise Exception('Unused arguments: ' + unicode(args)) return self def getreader(self): "Get the resulting reader." return LineReader(self.filein) def getwriter(self): "Get the resulting writer." return LineWriter(self.fileout) def readdir(self, filename, diroption): "Read the current directory if needed" if getattr(Options, diroption) != None: return setattr(Options, diroption, os.path.dirname(filename)) if getattr(Options, diroption) == '': setattr(Options, diroption, '.') class NullWriter(object): "A writer that goes nowhere." def write(self, list): "Do nothing." pass class ConverterFactory(object): "Create a converter fit for converting a filename and embedding the result." def create(self, container): "Create a converter for a given container, with filename" " and possibly other parameters." fullname = os.path.join(Options.directory, container.filename) reader = LineReader(container.filename) if 'firstline' in container.lstparams: reader.setstart(int(container.lstparams['firstline'])) if 'lastline' in container.lstparams: reader.setend(int(container.lstparams['lastline'])) return eLyXerConverter().embed(reader) IncludeInset.converterfactory = ConverterFactory() def convertdoc(args): "Read a whole document from the command line and write it." Options().parseoptions(args) ioparser = InOutParser().parse(args) converter = eLyXerConverter().setio(ioparser) converter.convert() def main(): "Main function, called if invoked from the command line" convertdoc(list(sys.argv)) if __name__ == '__main__': main() elyxer-1.2.5/test/0000755000175000017500000000000012117174531013316 5ustar chennochennoelyxer-1.2.5/test/index-1-6-lowmem-good.html0000644000175000017500000003177512074107030020045 0ustar chennochenno Index Test

Index Test

Table of Contents

Part I. The Making

1 Explanations

This chapter contains a lot of explanations for terms, which you might want to look up later. Because better sooner than later, although later has been repeated twice. Actually, thrice now.
Do you not want to look any of them up right now? No problem. You will be able to do it later, in the index.
Now we will add two cites in one, just because [1, 2].
As we will see in , not everything is clear.
You could also look down on someone, but that is not nice.

1.1Magical type face changes in the world

Little more can be added, at least at this point.

1.2Color and colour

At this other point, however, more could be added, but won’t.

Unnumbered Section

They have a right to live too.
  • A list would be nice here.
  • Because it corrupts the next chapter’s beginning.

2 Nomenclature

We should explain what an index is. We can do that with the nomenclature. Normally we will want to mix index and nomenclature terms. But what happens if we actually do? We will know later, when we generate the file.

2.1 Reminder

We have to remind the reader that things will be remembered.

2.2 Remainder

Whatever remains should be explained here.

Part II. The Additions

3 Bulk

We actually need a lot more text in order for our index to have more terms; so we can find out if the links are working. Since they are anchors inside the page, they might otherwise just take us to the top of the page, and we would not like that.
Yes, it would be bad for us. But on the other hand too much text can hide errors. So not much more text is needed.
Thanks for reading us.

Unnumbered Part

Unnumbered Chapter

This extra chapter contains nothing of interest except for a couple of unnumbered parts (one actual part and one chapter).
Table of Contents
List of Figures

Part III. Our Definition

4 The definition

A TOC is a Table Of Contents.

4.1 But I Already Knew That

You were lucky.

4.1.1 I Want My Money Back

There you have your 0€ back.

4.1.1.1 Completely Unfair Dude

Hey, I didn’t call you here.
A Paragraph For You
Totally uncalled for.
figure elyxer-svg.png
Figure 4.1 eLyXer logo

Unordered Section

Just to show that it works.
And now a list.
  1. First item.
  2. We will embed an ordered subsection here just to fake it.

    4.1.2 There We Go

  3. See if it’s in your TOC.
But There Is More
And nothing else.

A Appendix

An appendix here, an appendix there.

Index

able:

anchor:

error:

explained:

hand:

index: , , ,

later: , ,

link:

look:

down:

up: ,

page:

remembered:

sooner:

term:

terms:

text: , ,

thrice:

top of the page:

twice:

Nomenclature

generate An activity that requires a source and a destination, something like eLyXer does with files.
index A list of terms with a reference to where they occur.
nomenclature A list of common words with an explanation.

Bibliography

[-] WordReference.com: “definition of elixir”, accessed March 2009. http://www.wordreference.com/definition/elixir

[1] W3C: “HTML 4.01 Specification”, 24 December 1999. http://www.w3.org/TR/REC-html40/

[2] W3C: “HTML 4.01 Specification”, 24 December 1999. http://www.w3.org/TR/REC-html40/

elyxer-1.2.5/test/decorations-1-6.lyx0000644000175000017500000003227412074107030016667 0ustar chennochenno#LyX 1.6.7 created this file. For more info see http://www.lyx.org/ \lyxformat 345 \begin_document \begin_header \textclass scrbook \begin_preamble % eLyXer -- convert LyX source files to HTML output. % % Copyright (C) 2009-2010 Alex Fernández % % This program is free software: 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 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 % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % DO NOT ALTER THIS PREAMBLE!!! % % This preamble is designed to ensure that the User's Guide prints % out as advertised. If you mess with this preamble, % parts of the User's Guide may not print out as expected. If you % have problems LaTeXing this file, please contact % the documentation team % email: lyx-docs@lists.lyx.org \usepackage{ifpdf} % part of the hyperref bundle \ifpdf % if pdflatex is used % set fonts for nicer pdf view \IfFileExists{lmodern.sty}{\usepackage{lmodern}}{} \fi % end if pdflatex is used % for correct jump positions whe clicking on a link to a float \usepackage[figure]{hypcap} % the pages of the TOC is numbered roman % and a pdf-bookmark for the TOC is added \let\myTOC\tableofcontents \renewcommand{\tableofcontents}{% \frontmatter \pdfbookmark[1]{\contentsname}{} \myTOC \mainmatter } % redefine the \LyX macro for PDF bookmarks \def\LyX{\texorpdfstring{% L\kern-.1667em\lower.25em\hbox{Y}\kern-.125emX\@} {LyX}} % define a short command for \textvisiblespace \newcommand{\spce}{\textvisiblespace} % macro for italic page numbers in the index \newcommand{\IndexDef}[1]{\textit{#1}} % redefine the greyed out note \end_preamble \options intoc,bibtotoc,idxtotoc,BCOR7mm,tablecaptionabove \use_default_options false \language english \inputencoding auto \font_roman default \font_sans default \font_typewriter default \font_default_family default \font_sc false \font_osf false \font_sf_scale 100 \font_tt_scale 100 \graphics default \paperfontsize 12 \spacing single \use_hyperref true \pdf_title "Decorations Test" \pdf_author "Alex Fernández" \pdf_subject "Taken from Guía de Usuario de Lyx, Ignacio García" \pdf_keywords "LyX" \pdf_bookmarks true \pdf_bookmarksnumbered true \pdf_bookmarksopen false \pdf_bookmarksopenlevel 1 \pdf_breaklinks false \pdf_pdfborder false \pdf_colorlinks true \pdf_backref false \pdf_pdfusetitle false \pdf_quoted_options "linkcolor=black, citecolor=black, urlcolor=blue, filecolor=blue,pdfpagelayout=OneColumn, pdfnewwindow=true,pdfstartview=XYZ, plainpages=false, pdfpagelabels,pdftex" \papersize default \use_geometry false \use_amsmath 1 \use_esint 0 \cite_engine basic \use_bibtopic false \paperorientation portrait \secnumdepth 3 \tocdepth 3 \paragraph_separation skip \defskip medskip \quotes_language english \papercolumns 1 \papersides 2 \paperpagestyle default \tracking_changes false \output_changes false \author "" \author "" \end_header \begin_body \begin_layout Title Decorations Test \end_layout \begin_layout Chapter Decorations \end_layout \begin_layout Standard A few examples taken from the Spanish Lyx User's Guide. \end_layout \begin_layout Standard An accent that looks like a hat: \begin_inset Formula $\hat{a}$ \end_inset , done using \series bold \backslash hat \begin_inset ERT status open \begin_layout Plain Layout \backslash spce \end_layout \end_inset a \series default within an equation. The following table shows commands to make decorations. \end_layout \begin_layout Standard \begin_inset Float table wide false sideways false status open \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout Decorations and commands. \end_layout \end_inset \end_layout \begin_layout Plain Layout \align center \begin_inset VSpace defskip \end_inset \begin_inset Tabular \begin_inset Text \begin_layout Plain Layout Name \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Command \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Sample \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout circumflex \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \series bold \backslash hat \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \begin_inset Formula $\hat{a}$ \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout grave \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \series bold \backslash grave \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \begin_inset Formula $\grave{m}$ \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout acute \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \series bold \backslash acute \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \begin_inset Formula $\acute{A}$ \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout diaeresis \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \series bold \backslash ddot \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \begin_inset Formula $\ddot{B}$ \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout tilde \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \series bold \backslash tilde \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \begin_inset Formula $\tilde{N}$ \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout dot \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \series bold \backslash dot \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \begin_inset Formula $\dot{L}$ \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout triple dot \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \series bold \backslash dddot \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \begin_inset Formula $\dddot{o}$ \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout breve \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \series bold \backslash breve \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \begin_inset Formula $\breve{g}$ \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout caron \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \series bold \backslash check \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \begin_inset Formula $\check{s}$ \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout bar \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \series bold \backslash bar \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \begin_inset Formula $\bar{l}$ \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout vector \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \series bold \backslash vec \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \begin_inset Formula $\vec{m}$ \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout long vector \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \series bold \backslash overrightarrow \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \begin_inset Formula $\overrightarrow{ABC}$ \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout wide hat \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \series bold \backslash widehat \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \begin_inset Formula $\widehat{house}$ \end_inset \end_layout \end_inset \end_inset \end_layout \end_inset \end_layout \begin_layout Standard Decorations should also appear correctly in unit names: \begin_inset Formula $100\mathrm{a\tilde{n}os}$ \end_inset and in superscripts: \begin_inset Formula $40^{100\mathrm{a\tilde{n}os}}$ \end_inset . \end_layout \begin_layout Standard That's all folks! \end_layout \end_body \end_document elyxer-1.2.5/test/decorations-1-6-good.html0000644000175000017500000001106312074107030017736 0ustar chennochenno Decorations Test

Decorations Test

1 Decorations

A few examples taken from the Spanish Lyx User’s Guide.
An accent that looks like a hat: , done using \hat a within an equation. The following table shows commands to make decorations.
Table 1.1 Decorations and commands.
Name Command Sample
circumflex \hat
grave \grave
acute \acute
diaeresis \ddot
tilde \tilde
dot \dot
triple dot \dddot o⃛
breve \breve
caron \check
bar \bar l
vector \vec m⃗
long vector \overrightarrow ABC
wide hat \widehat ^house
Decorations should also appear correctly in unit names: 100 años and in superscripts: 40100 años.
That’s all folks!
elyxer-1.2.5/test/math-1-6.lyx0000644000175000017500000005114112074107030015300 0ustar chennochenno#LyX 1.6.7 created this file. For more info see http://www.lyx.org/ \lyxformat 345 \begin_document \begin_header \textclass scrartcl \begin_preamble % eLyXer -- convert LyX source files to HTML output. % % Copyright (C) 2009-2010 Alex Fernández % % This program is free software: 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 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 % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % DO NOT ALTER THIS PREAMBLE!!! % % This preamble is designed to ensure that the User's Guide prints % out as advertised. If you mess with this preamble, % parts of the User's Guide may not print out as expected. If you % have problems LaTeXing this file, please contact % the documentation team % email: lyx-docs@lists.lyx.org \usepackage{ifpdf} % part of the hyperref bundle \ifpdf % if pdflatex is used % set fonts for nicer pdf view \IfFileExists{lmodern.sty}{\usepackage{lmodern}}{} \fi % end if pdflatex is used % for correct jump positions whe clicking on a link to a float \usepackage[figure]{hypcap} % the pages of the TOC is numbered roman % and a pdf-bookmark for the TOC is added \let\myTOC\tableofcontents \renewcommand{\tableofcontents}{% \frontmatter \pdfbookmark[1]{\contentsname}{} \myTOC \mainmatter } % redefine the \LyX macro for PDF bookmarks \def\LyX{\texorpdfstring{% L\kern-.1667em\lower.25em\hbox{Y}\kern-.125emX\@} {LyX}} % define a short command for \textvisiblespace \newcommand{\spce}{\textvisiblespace} % macro for italic page numbers in the index % test macro with a lot of spaces (bug #31243) \newcommand % Renewing a command with spaces and comments { \IndexDef } [1] { \textit {#1} } % test macro with two arguments \newcommand{\preambleroot}[2]{\sqrt[#1]{#2}} % redefine the greyed out note \usepackage{mathrsfs} \usepackage{upgreek} \end_preamble \options intoc,bibtotoc,idxtotoc,BCOR7mm,tablecaptionabove \use_default_options false \language english \inputencoding auto \font_roman default \font_sans default \font_typewriter default \font_default_family default \font_sc false \font_osf false \font_sf_scale 100 \font_tt_scale 100 \graphics default \paperfontsize 12 \spacing single \use_hyperref true \pdf_title "Math Test" \pdf_author "Alex Fernández" \pdf_subject "Taken from Guía de Usuario de Lyx, Ignacio García" \pdf_keywords "LyX" \pdf_bookmarks true \pdf_bookmarksnumbered true \pdf_bookmarksopen false \pdf_bookmarksopenlevel 1 \pdf_breaklinks false \pdf_pdfborder false \pdf_colorlinks true \pdf_backref false \pdf_pdfusetitle false \pdf_quoted_options "linkcolor=black, citecolor=black, urlcolor=blue, filecolor=blue,pdfpagelayout=OneColumn, pdfnewwindow=true,pdfstartview=XYZ, plainpages=false, pdfpagelabels,pdftex" \papersize default \use_geometry false \use_amsmath 1 \use_esint 0 \cite_engine basic \use_bibtopic false \paperorientation portrait \secnumdepth 3 \tocdepth 3 \paragraph_separation indent \defskip medskip \quotes_language english \papercolumns 1 \papersides 2 \paperpagestyle default \tracking_changes false \output_changes false \author "" \author "" \end_header \begin_body \begin_layout Title Math Test \end_layout \begin_layout Section Limits \end_layout \begin_layout Standard A limit: \begin_inset Formula \[ \lim_{x\rightarrow\infty}\lyxlock f(x),\] \end_inset which should appear as \begin_inset Formula $x\rightarrow\infty$ \end_inset in italics, and \begin_inset Quotes fld \end_inset lim \begin_inset Quotes frd \end_inset in plain style. Inlined: \begin_inset Formula $\lim_{x\rightarrow\infty}\lyxlock f(x)$ \end_inset . \end_layout \begin_layout Standard And why not, a sum: \begin_inset Formula \[ \sum_{i=1}^{\infty}a_{i},\] \end_inset where the sum's limits should appear below ( \begin_inset Formula $i=1$ \end_inset ) and above ( \begin_inset Formula $\infty$ \end_inset ) the \begin_inset Formula $\sum$ \end_inset but to the right. Inlined: \begin_inset Formula $\sum_{i=1}^{\infty}a_{i}.$ \end_inset Integral: \begin_inset Formula $\intop_{x=a}^{\infty}x\,\text{d}x.$ \end_inset Display mode: \begin_inset Formula \[ \intop_{x=a}^{\infty}x\,\text{d}x.\] \end_inset \end_layout \begin_layout Standard We can also integrate without limits: \begin_inset Formula $\int A\,\text{d}x$ \end_inset . \end_layout \begin_layout Standard A sum inside another element (red color): \end_layout \begin_layout Standard \begin_inset Formula \[ \textcolor{red}{\sum_{i=1}^{\infty}a_{i}}.\] \end_inset \end_layout \begin_layout Standard The placing of limits can be cofigured with the \family typewriter \backslash limits \family default and \family typewriter \backslash nolimits \family default macros: \begin_inset Formula \[ \lim\nolimits _{x\rightarrow\infty}\lyxlock f(x),\;\sum\nolimits _{i=1}^{\infty}x,\;\int\limits _{0}^{\infty}f(x)\,\mathrm{d}x\] \end_inset \end_layout \begin_layout Subsection Super- and Subscript \end_layout \begin_layout Standard When any element has both super- and subscript, they should appear like inlined limits, one above the other: \begin_inset Formula $a_{4}^{3}$ \end_inset . Also before an element: \begin_inset Formula $_{2}^{3}\text{He}$ \end_inset . In display mode: \end_layout \begin_layout Standard \begin_inset Formula \[ \sum_{i,j}a_{j}^{i}+\sum_{i,j}a_{i}^{j}=\sum_{i}a_{i}^{i},\] \end_inset \begin_inset Formula \[ _{1}^{2}\text{H}+{}_{1}^{2}\text{H}\rightarrow{}_{2}^{3}\text{He}+{}_{0}^{1}\text{n}.\] \end_inset \end_layout \begin_layout Section Numeration \end_layout \begin_layout Standard Equations can be numbered, like \begin_inset CommandInset ref LatexCommand ref reference "eq:first" \end_inset . \end_layout \begin_layout Standard \begin_inset Formula \begin{equation} y=x\label{eq:first}\end{equation} \end_inset \end_layout \begin_layout Standard And also like \begin_inset CommandInset ref LatexCommand ref reference "eq:second" \end_inset . \end_layout \begin_layout Standard \begin_inset Formula \begin{equation} x=3\label{eq:second}\end{equation} \end_inset \end_layout \begin_layout Standard Notice that eq. \begin_inset CommandInset ref LatexCommand ref reference "eq:second" \end_inset comes after eq. \begin_inset CommandInset ref LatexCommand ref reference "eq:first" \end_inset . \end_layout \begin_layout Standard Some equations can also be numbered, even if they don't have a label. \end_layout \begin_layout Standard \begin_inset Formula \begin{equation} x=2y\end{equation} \end_inset \end_layout \begin_layout Standard Other equations that contain * should not numbered, but perhaps aligned: \end_layout \begin_layout Standard \begin_inset Formula \begin{align*} left & & right\end{align*} \end_inset \end_layout \begin_layout Standard Some environments allow for multiple labels: \begin_inset Formula \begin{eqnarray} a & = & b\times c\label{eq:third}\\ c\times d\times e & = & i.\label{eq:fourth}\end{eqnarray} \end_inset \end_layout \begin_layout Standard Now a random environment: \begin_inset Formula $\begin{gathered}x\end{gathered} y$ \end_inset . \end_layout \begin_layout Section Brackets \end_layout \begin_layout Standard An array: \begin_inset Formula \[ \left[\begin{array}{lc} 12 & 2\\ 3 & 4\times y^{x}\end{array}\right]\] \end_inset And an inline array \begin_inset Formula $\left[\begin{array}[t]{cc} a & b\\ c & dio\end{array}\right]$ \end_inset . \end_layout \begin_layout Standard Arrays are separated by variable-size brackets: \begin_inset Formula $\left(\begin{array}{cc} a & b\\ c & d\end{array}\right)$ \end_inset \begin_inset Formula $\left[\begin{array}{cc} a & b\\ c & d\end{array}\right]$ \end_inset \begin_inset Formula $\left\{ \begin{array}{cc} a & b\\ c & d\end{array}\right\} $ \end_inset \begin_inset Formula $\left\langle \begin{array}{cc} a & b\\ c & d\end{array}\right\rangle $ \end_inset \begin_inset Formula $\left|\begin{array}{cc} a & b\\ c & d\end{array}\right|$ \end_inset which might also differ on right and left \begin_inset Formula $\left(\begin{array}{cc} a & b\\ c & d\end{array}\right)$ \end_inset or use the empty opening \begin_inset Formula $\left\{ \begin{array}{cc} a & b\\ c & d\end{array}\right.$ \end_inset or closing: \begin_inset Formula $\left.\begin{array}{cc} a & b\\ c & d\end{array}\right|$ \end_inset . There are also fixed-size big brackets: \begin_inset Formula $\left(a\right)$ \end_inset \begin_inset Formula $\left[b\right]$ \end_inset \begin_inset Formula $\left\{ c\right\} $ \end_inset \begin_inset Formula $\left\langle d\right\rangle $ \end_inset \begin_inset Formula $\left|e\right|$ \end_inset \begin_inset Formula $\bigl\langle f\bigr\rangle$ \end_inset . \end_layout \begin_layout Standard Aligned brackets can be present: \begin_inset Formula $\left(toText\right)$ \end_inset . One of them may be omitted: \begin_inset Formula $\left.toText\right)$ \end_inset . \end_layout \begin_layout Standard Aligned brackets can be applied to complex items: \begin_inset Formula \[ s\times\left(1+\left(\begin{array}{cc} a_{11} & a_{21}\\ a_{12} & a_{22}\end{array}\right)\times\left(\begin{array}{cc} 1 & -1\\ -1 & -1\end{array}\right)+\left\Vert \begin{array}{ccc} 1 & -1 & 0\\ -1 & 1 & 0\\ 0 & 0 & r\end{array}\right\Vert \right).\] \end_inset \end_layout \begin_layout Standard Math brackets should not be mistaken for TeX brackets: \begin_inset Formula $\frac{\mathcal{F}\left\{ s(x)\right\} }{2}$ \end_inset . \end_layout \begin_layout Section Fraction \end_layout \begin_layout Standard A big recursive fraction: \begin_inset Formula \[ \frac{1}{\left(1+\left(\frac{1}{1+\left(\frac{1}{1+2x}\lyxlock\right)}\lyxlock\right)\right)}\lyxlock\] \end_inset \end_layout \begin_layout Standard A nice fraction: \begin_inset Formula $\nicefrac{5}{6}$ \end_inset . \end_layout \begin_layout Standard A non-diminishing fraction containing alignments: \begin_inset Formula \[ \cfrac{1}{1+\left(\cfrac[l]{1}{1+x}\times\cfrac[r]{1}{1+x}\right)}.\] \end_inset \end_layout \begin_layout Standard A similar concept is a binomial coefficient: \begin_inset Formula $\binom{A+1}{B}.$ \end_inset It can be prettily presented: \begin_inset Formula \[ \dbinom{A}{B+1}.\] \end_inset \end_layout \begin_layout Standard A symbol can be stacked over another using \family typewriter \backslash stackrel \family default : \begin_inset Formula $x\stackrel{R}{\rightarrow}y$ \end_inset . Anything can be stacked: \begin_inset Formula $\stackrel{head}{heels}$ \end_inset . \end_layout \begin_layout Section Roots \end_layout \begin_layout Standard A square root: \begin_inset Formula $\sqrt{3}.$ \end_inset A root in a fraction: \begin_inset Formula $\sqrt{\frac{(78x+45y)\times\sqrt{Height}}{\sin(x+1)}+5}.$ \end_inset \end_layout \begin_layout Standard A more complex square root in a fraction: \begin_inset Formula \[ \frac{1}{\left(1+\sqrt{2}\left(\frac{1}{1+\sqrt{2}}\lyxlock\right)+\sqrt{\frac{1}{2}}\right)}\lyxlock.\] \end_inset \end_layout \begin_layout Standard Higher order roots: \begin_inset Formula $\sqrt[3]{x+y}$ \end_inset , \begin_inset Formula $\sqrt[x+1]{Weight}$ \end_inset . In a fraction: \begin_inset Formula \[ \frac{\sqrt[\nicefrac{7}{8}]{\frac{8}{4}x}}{\sqrt[s+5]{\frac{(78x+45y)\times\sqrt{Height}}{\sin(x+1)}+5}}\lyxlock.\] \end_inset \end_layout \begin_layout Section Decorations \end_layout \begin_layout Subsection Cases \end_layout \begin_layout Standard Used to switch several values. \end_layout \begin_layout Standard \begin_inset Formula \[ y=\begin{cases} x & i=0,\\ x+1 & i<3\end{cases}\] \end_inset \end_layout \begin_layout Standard Cases may have more than two rows: \end_layout \begin_layout Standard \begin_inset Formula \[ f(x)=\begin{cases} 0 & x<0,\\ \infty & x=0,\\ 0 & x>0\end{cases}\] \end_inset \end_layout \begin_layout Subsection Braces \end_layout \begin_layout Standard Values can be underbraced or overbraced. \begin_inset Formula \[ \underbrace{a-b}=\overbrace{c+d+e}+f.\] \end_inset \end_layout \begin_layout Standard Underbraces and overbraces can contain text. \begin_inset Formula \[ \overbrace{a-b}^{over}=\underbrace{c+\overbrace{d+e}^{over}+f}_{under}+g.\] \end_inset They can also be inlined: \begin_inset Formula $\overbrace{a+b}^{over}$ \end_inset . \end_layout \begin_layout Section Spacing \end_layout \begin_layout Standard The command \family typewriter \backslash raisebox \family default is useful to, surprisingly, raise a little box, \begin_inset Formula \[ \raisebox{2mm}{raised}over\raisebox{-2mm}{lowered}\textrm{ and back}.\] \end_inset Like \family typewriter \backslash mbox \family default , it puts its content in a text box. It can also be used just for spacing: \begin_inset Newline newline \end_inset \begin_inset Formula $\raisebox{5mm}{}B^{V}$ \end_inset . \end_layout \begin_layout Standard There are other spacing commands: \family typewriter \backslash hspace \family default \begin_inset Formula $a\hspace{4mm}b$ \end_inset , protected space \begin_inset Formula $a\ b$ \end_inset , and at \begin_inset Quotes eld \end_inset block level \begin_inset Quotes erd \end_inset \family typewriter \backslash vspace \family default : \begin_inset Formula $a\vspace{1cm}b$ \end_inset . \end_layout \begin_layout Standard There should be 1 \begin_inset space ~ \end_inset cm of vertical space above this paragraph. \end_layout \begin_layout Section Fonts \end_layout \begin_layout Standard This section tests font support. \end_layout \begin_layout Subsection Variables and Functions \end_layout \begin_layout Standard By default, letters denote variables and are taken from the \family typewriter \backslash mathnormal \family default font, which is italic: \begin_inset Formula $\alpha x+\alpha y=\alpha(x+y)$ \end_inset , with the exception of upright capital Greek letters, \begin_inset Formula $G\ne\Gamma$ \end_inset . Letters run together represent different variables: \begin_inset Formula $abcd=a\times b\times c\times d$ \end_inset . \end_layout \begin_layout Standard There has been some trouble over some commands like Greek letters; some of them should be italicized, as in: \begin_inset Formula $\mu$ \end_inset or \begin_inset Formula $\AA$ \end_inset . Others should not, as in \begin_inset Formula $\Omega$ \end_inset . Upright Greek letters are also available: \begin_inset Formula $\upmu\neq\mu$ \end_inset . An example from the LyX math guide: \begin_inset Formula \[ \uppi^{+}\to\upmu^{+}+\upnu_{\upmu}.\] \end_inset \end_layout \begin_layout Standard Functions names should be upright: \begin_inset Formula $\sin(2\pi),\log(x),\tan\delta$ \end_inset . \end_layout \begin_layout Subsection Mathematical Fonts \end_layout \begin_layout Standard Mathematical fonts used in equations include \begin_inset Formula $\mathrm{Roman}$ \end_inset ( \family typewriter \backslash mathrm \family default ), \begin_inset Formula $\mathsf{Sans\: Serif}$ \end_inset ( \family typewriter \backslash mathsf \family default ), \begin_inset Formula $\mathtt{Typewriter}$ \end_inset ( \family typewriter \backslash mathtt \family default ), \begin_inset Formula $\mathbf{Bold}$ \end_inset ( \family typewriter \backslash mathbf \family default ), \begin_inset Formula $\mathscr{SCRIPT}$ \end_inset ( \family typewriter \backslash mathscr \family default ), \begin_inset Formula $\mathcal{CALLIGRAPHIC}$ \end_inset ( \family typewriter \backslash mathcal \family default ), \begin_inset Formula $\mathbb{BLACKBOARD\: BOLD}$ \end_inset ( \family typewriter \noun on \backslash \noun default mathbb \family default ), and \begin_inset Formula $\mathfrak{Fraktur}$ \end_inset ( \family typewriter \backslash mathfrak \family default ). For the latter, some single characters are translated to their Unicode equivalents: \begin_inset Formula $\mathscr{F}$ \end_inset , \begin_inset Formula $\mathbb{F}$ \end_inset , \begin_inset Formula $\mathfrak{F}$ \end_inset . \end_layout \begin_layout Standard Regular text in a formula can be achieved via text font commands like \family typewriter \backslash textrm \family default : \begin_inset Formula $5\:\textrm{to}\:10$ \end_inset , via boxes like \backslash mbox (prevents line breaks): \begin_inset Formula $6\mbox{ is more than }5$ \end_inset , or the AMSmath \family typewriter \backslash text \family default macro (scales like math symbols) \begin_inset Formula $\text{base}_{\text{sub}}^{\text{super}}$ \end_inset . The content of an mbox is processed in LaTeX text mode. This allows text font commands, e.g. a switch to \family sans \series bold \shape italic sans-serif-bold-italic \family default \series default \shape default , or the phonetic alphabet: \begin_inset Formula $\mbox{\textbf{\textsf{\textbf{\textit{sfbfit}}}}, \textipa{tipa}}$ \end_inset . \end_layout \begin_layout Subsection Units \end_layout \begin_layout Standard Units should be written upright, either with \family typewriter \backslash mathrm \family default or with macros from the \family typewriter units \family default package, e.g. as simple unit, \begin_inset Formula $\unit{km}$ \end_inset , with magnitude, \begin_inset Formula $\unit[57]{km}$ \end_inset , with fractional unit, \begin_inset Formula $\unitfrac[200]{km}{h}$ \end_inset , or with a fraction before the units, \begin_inset Formula $\unit[\nicefrac{3}{2}]{km}$ \end_inset , \begin_inset Formula $\unit[\frac{7}{16}]{s}$ \end_inset . \end_layout \begin_layout Subsection Sizes \end_layout \begin_layout Standard Sizes can be specified in formulas: \begin_inset Formula ${\displaystyle \text{display}},{\textstyle \text{text}},{\scriptstyle \text{script}},{\scriptscriptstyle \text{scriptscript}}$ \end_inset . \end_layout \begin_layout Section Colors and Boxes \end_layout \begin_layout Standard A colored box: \begin_inset Formula $\colorbox{red}{aaa}$ \end_inset . \end_layout \begin_layout Standard A framed box: \begin_inset Formula $\framebox[2cm][c]{box}$ \end_inset . It can be aligned left: \begin_inset Formula $\framebox[2cm][l]{box}$ \end_inset or right: \begin_inset Formula $\framebox[2cm][r]{box}$ \end_inset . \end_layout \begin_layout Section Macros \end_layout \begin_layout Standard Definitions can be added as macros \begin_inset FormulaMacro \renewcommand{\stupidroot}[2]{\sqrt[#1]{#2}} {\sqrt[#1]{#2}} \end_inset . Then they can be used in formulae: \begin_inset Formula $\stupidroot{}{12}+\stupidroot 12$ \end_inset . \end_layout \begin_layout Standard Macro definitions can accept default parameters \begin_inset FormulaMacro \renewcommand{\defaultroot}[2][4][5]{\sqrt[#1]{#2}} {#1\sqrt{#2}} \end_inset . Again, useful in formulae: \begin_inset Formula $\defaultroot$ \end_inset . Default parameters can then be overriden: \begin_inset Formula $\defaultroot[][y]+\defaultroot[x]$ \end_inset . \end_layout \begin_layout Standard Other definitions from the preamble can be used: \begin_inset Formula $\preambleroot{3}{4}$ \end_inset . \end_layout \begin_layout Standard Definitions on the fly are also possible: \begin_inset Formula $\newcommand{\ontheflyroot}[2]{\sqrt[#1]{#2}}\ontheflyroot{7}{8}$ \end_inset , and used with different values: \begin_inset Formula $\ontheflyroot{a}{b}$ \end_inset . \end_layout \begin_layout Standard Macros may contain a literal parameter \begin_inset FormulaMacro \renewcommand{\colort}[1]{\colorbox{#1}{t}} {\colorbox{#1}{t}} \end_inset . It should parse correctly: \begin_inset Formula $\colort{red}$ \end_inset . \end_layout \begin_layout Standard A macro with four parameters from the LyX detailed math guide \begin_inset FormulaMacro \renewcommand{\qG}[4][1,\,2]{#2_{#1}=-\frac{#3}{2}\pm\sqrt{\frac{#3^{2}}{4}-#4}} \end_inset . Now in use: \begin_inset Formula $1+\qG x{(1-x)}5-B$ \end_inset . \end_layout \begin_layout Section Pathological Cases \end_layout \begin_layout Standard Empty equations have been known to fail: \begin_inset Formula $ $ \end_inset . \end_layout \begin_layout Standard An equation with an mbox containing a comment: \begin_inset Formula $\mbox{text %comment more}$ \end_inset , and a comment inside textrm: \begin_inset Formula $\textrm{text %comment more}$ \end_inset . Finally, a comment at the end of a text function: \begin_inset Formula $\mbox{only text%comment }$ \end_inset . \end_layout \begin_layout Section Bye-bye \end_layout \begin_layout Standard That's all folks! \end_layout \end_body \end_document elyxer-1.2.5/test/appendix-1-6.lyx0000644000175000017500000005244412074107030016166 0ustar chennochenno#LyX 1.6.5 created this file. For more info see http://www.lyx.org/ \lyxformat 345 \begin_document \begin_header \textclass scrbook \begin_preamble % eLyXer -- convert LyX source files to HTML output. % % Copyright (C) 2009-2010 Alex Fernández % % This program is free software: 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 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 % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % DO NOT ALTER THIS PREAMBLE!!! % % This preamble is designed to ensure that the User's Guide prints % out as advertised. If you mess with this preamble, % parts of the User's Guide may not print out as expected. If you % have problems LaTeXing this file, please contact % the documentation team % email: lyx-docs@lists.lyx.org \usepackage{ifpdf} % part of the hyperref bundle \ifpdf % if pdflatex is used % set fonts for nicer pdf view \IfFileExists{lmodern.sty}{\usepackage{lmodern}}{} \fi % end if pdflatex is used % for correct jump positions whe clicking on a link to a float \usepackage[figure]{hypcap} % the pages of the TOC is numbered roman % and a pdf-bookmark for the TOC is added \let\myTOC\tableofcontents \renewcommand{\tableofcontents}{% \frontmatter \pdfbookmark[1]{\contentsname}{} \myTOC \mainmatter } % redefine the \LyX macro for PDF bookmarks \def\LyX{\texorpdfstring{% L\kern-.1667em\lower.25em\hbox{Y}\kern-.125emX\@} {LyX}} % define a short command for \textvisiblespace \newcommand{\spce}{\textvisiblespace} % macro for italic page numbers in the index \newcommand{\IndexDef}[1]{\textit{#1}} % redefine the greyed out note \end_preamble \options intoc,bibtotoc,idxtotoc,BCOR7mm,tablecaptionabove \use_default_options false \language english \inputencoding auto \font_roman default \font_sans default \font_typewriter default \font_default_family default \font_sc false \font_osf false \font_sf_scale 100 \font_tt_scale 100 \graphics default \paperfontsize 12 \spacing single \use_hyperref true \pdf_title "Appendix Test" \pdf_author "Alex Fernández" \pdf_subject "Containing Numeration and Other Appendixy things" \pdf_keywords "LyX eLyXer" \pdf_bookmarks true \pdf_bookmarksnumbered true \pdf_bookmarksopen false \pdf_bookmarksopenlevel 1 \pdf_breaklinks false \pdf_pdfborder false \pdf_colorlinks true \pdf_backref false \pdf_pdfusetitle false \pdf_quoted_options "linkcolor=black, citecolor=black, urlcolor=blue, filecolor=blue,pdfpagelayout=OneColumn, pdfnewwindow=true,pdfstartview=XYZ, plainpages=false, pdfpagelabels,pdftex" \papersize default \use_geometry false \use_amsmath 1 \use_esint 0 \cite_engine basic \use_bibtopic false \paperorientation portrait \secnumdepth 3 \tocdepth 3 \paragraph_separation skip \defskip medskip \quotes_language english \papercolumns 1 \papersides 2 \paperpagestyle default \tracking_changes false \output_changes false \author "" \author "" \end_header \begin_body \begin_layout Title Appendix Test \end_layout \begin_layout Author Alex Fernández (elyxer@gmail.com) \end_layout \begin_layout Standard \begin_inset CommandInset toc LatexCommand tableofcontents \end_inset \end_layout \begin_layout Standard \begin_inset FloatList figure \end_inset \end_layout \begin_layout Standard \begin_inset FloatList table \end_inset \end_layout \begin_layout Part Of How Our Hero Came and Went \end_layout \begin_layout Chapter The Coming \end_layout \begin_layout Standard Our hero came in. He was tired. He thought the world belonged to him. \end_layout \begin_layout Section The Meeting \end_layout \begin_layout Standard Our hero met with Laurinda. She was smiling. But our hero was not amused. His whiskers were dripping wet, he was astonishingly thirsty, and the contradic tion was killing him. \begin_inset Quotes eld \end_inset Give me some beer, woman! \begin_inset Quotes erd \end_inset , he ordered. \end_layout \begin_layout Section The Melting \end_layout \begin_layout Standard Laurinda smiled again. \begin_inset Quotes eld \end_inset But Wenceslau, you don't belong here. \begin_inset Quotes erd \end_inset What a stupid thing to say at that precise moment, our hero thought to himself. Only that it came out loud. At that precise moment he knew that the desired beer would not be forthcoming. \end_layout \begin_layout Standard He turned to the bartender and tried to obtain a beer by the very old method of purchasing it. But being ignored was not one of Laurinda's specialities. \end_layout \begin_layout Chapter The Going \end_layout \begin_layout Standard It could not last. Laurinda's hips were flapping, and she was hopping mad. \end_layout \begin_layout Section Our Hero's Imagination \end_layout \begin_layout Standard Our hero imagined her as a rabbit with long ears and a fine set of tusks. In a short time the image drifted to a walrus, and our hero could not help letting his sinister smile giving him away. Figure \begin_inset CommandInset ref LatexCommand ref reference "fig:rabbit-walrus" \end_inset shows a gross approximation of the rabbit-walrus. \end_layout \begin_layout Standard \begin_inset Float figure wide false sideways false status open \begin_layout Plain Layout \align center \begin_inset Graphics filename rabbit-walrus.svg \end_inset \end_layout \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout \begin_inset CommandInset label LatexCommand label name "fig:rabbit-walrus" \end_inset The rabbit-walrus. \end_layout \end_inset \end_layout \begin_layout Plain Layout \end_layout \end_inset \end_layout \begin_layout Section Laurinda's Anger \end_layout \begin_layout Standard \begin_inset Quotes eld \end_inset Wasn't it great \begin_inset Quotes erd \end_inset , said Laurinda. Actually she said it in the present tense, but our poor storytelling skills have changed that to a cheesy past. Don't do this at home, kids. You want to be regarded for your authenticity, and misquoting isn't going to help much. \end_layout \begin_layout Standard Anyway, back to the story. Laurinda wanted to hit him in the head with a big ham that she kept just for occassions like this, and being a solid Hitchcock fan she was ready to cook the ham afterwards and serve the resulting stew to any policemen that might come by. She was also a huge Almodóvar fan, but she was unaware that in an early film the divine Pedro had copied the scene. Actually both directors had copied the idea from a short story by Roald Dahl, very much worth reading. Although it must be said that in this story it was a lamb leg, which hardly offers the consistency and stiffness necessary to kill a sturdy husband. \end_layout \begin_layout Standard But who cares. Laurinda meanwhile had a funny appearance; if you want to see why please direct your eyes to figure \begin_inset CommandInset ref LatexCommand ref reference "fig:anger" \end_inset . \end_layout \begin_layout Standard \begin_inset Float figure wide false sideways false status open \begin_layout Plain Layout \align center \begin_inset Graphics filename laurindas-anger.svg \end_inset \end_layout \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout \begin_inset CommandInset label LatexCommand label name "fig:anger" \end_inset Laurinda's anger pictured in a mildly humorous tone. \end_layout \end_inset \end_layout \end_inset \end_layout \begin_layout Standard And yet, how furious was really Laurinda, whom we may optionally refer to as Melinda from now on? Table \begin_inset CommandInset ref LatexCommand ref reference "tab:anger-time" \end_inset vainly attempts to quantify it. \end_layout \begin_layout Standard \begin_inset Float table wide false sideways false status open \begin_layout Plain Layout \align center \begin_inset Tabular \begin_inset Text \begin_layout Plain Layout Anger \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Time \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 1 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 2 \end_layout \end_inset \end_inset \end_layout \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout \begin_inset CommandInset label LatexCommand label name "tab:anger-time" \end_inset Laurinda's anger as a function of time. \end_layout \end_inset \end_layout \end_inset \end_layout \begin_layout Standard For the sake of Laurinda's furiousness, here is figure \begin_inset CommandInset ref LatexCommand ref reference "fig:anger-again" \end_inset again. \end_layout \begin_layout Standard \begin_inset Float figure wide false sideways false status open \begin_layout Plain Layout \align center \begin_inset Graphics filename laurindas-anger.svg \end_inset \end_layout \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout \begin_inset CommandInset label LatexCommand label name "fig:anger-again" \end_inset Laurinda's anger, again. \end_layout \end_inset \end_layout \end_inset \end_layout \begin_layout Standard But how did Laurinda compute her anger? We cannot but speculate; here is a stupid suggestion in listing \begin_inset CommandInset ref LatexCommand ref reference "alg:computation" \end_inset . \end_layout \begin_layout Standard \begin_inset Float algorithm wide false sideways false status open \begin_layout Plain Layout anger = time - 1 \end_layout \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout \begin_inset CommandInset label LatexCommand label name "alg:computation" \end_inset Laurinda computes her anger. \end_layout \end_inset \end_layout \begin_layout Plain Layout \end_layout \end_inset \end_layout \begin_layout Standard The result is in table \begin_inset CommandInset ref LatexCommand ref reference "tab:anger-time-again" \end_inset , proving we were right all along. Also subtables \begin_inset CommandInset ref LatexCommand ref reference "tab:Only-Anger" \end_inset and \begin_inset CommandInset ref LatexCommand ref reference "tab:Only-Time" \end_inset show anger and time, respectively. \end_layout \begin_layout Standard \begin_inset Float table wide false sideways false status open \begin_layout Plain Layout \align center \begin_inset Float table wide false sideways false status open \begin_layout Plain Layout \align center \begin_inset Tabular \begin_inset Text \begin_layout Plain Layout Anger \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 1 \end_layout \end_inset \end_inset \end_layout \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout \begin_inset CommandInset label LatexCommand label name "tab:Only-Anger" \end_inset Only Anger. \end_layout \end_inset \end_layout \end_inset \begin_inset Float table wide false sideways false status open \begin_layout Plain Layout \align center \begin_inset Tabular \begin_inset Text \begin_layout Plain Layout Time \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 2 \end_layout \end_inset \end_inset \begin_inset Caption \begin_layout Plain Layout \begin_inset CommandInset label LatexCommand label name "tab:Only-Time" \end_inset Only Time. \end_layout \end_inset \end_layout \end_inset \end_layout \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout \begin_inset CommandInset label LatexCommand label name "tab:anger-time-again" \end_inset Laurinda's anger quantified, divided in two. \end_layout \end_inset \end_layout \end_inset \end_layout \begin_layout Standard Interested in that last table? Let us repeat it but without a label and with a table and a subtable \begin_inset CommandInset ref LatexCommand ref reference "tab:rabbit-walrus-encore" \end_inset . \end_layout \begin_layout Standard \begin_inset Float table wide false sideways false status open \begin_layout Plain Layout \align center \begin_inset Float table wide false sideways false status open \begin_layout Plain Layout Censored \end_layout \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout \begin_inset CommandInset label LatexCommand label name "tab:rabbit-walrus-encore" \end_inset The rabbit-walrus does an encore. \end_layout \end_inset \end_layout \begin_layout Plain Layout \end_layout \end_inset \begin_inset Tabular \begin_inset Text \begin_layout Plain Layout Anger \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Time \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 1 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 2 \end_layout \end_inset \end_inset \end_layout \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout One more time. \end_layout \end_inset \end_layout \end_inset \end_layout \begin_layout Section The Passing Away \end_layout \begin_layout Standard Our hero was passing by the village. He had only stopped to say \begin_inset Quotes eld \end_inset Hi! \begin_inset Quotes erd \end_inset Again here our lousy skills have made us spoil the quote, but this time for the opposite reasons: everyone knows how to say \begin_inset Quotes eld \end_inset Hi! \begin_inset Quotes erd \end_inset , so we don't need an actual quote. It is enough to report that the had stopped to say hi, even maybe qualifying it a bit to make do for the missing exclamation sign: he could have stopped to say a friendly hi. Getting all literary he could have stopped to say a longing hi, although this road leads to bizarreness. It could be cool though. \end_layout \begin_layout Standard But anyway. Laurinda was so mad, so hopping mad that she called her friend, the Assassin. He was not in town at that precise moment, but that didn't help our hero as he was just outside town killing people in a small barn. Just for practice. \end_layout \begin_layout Standard Our hero left the village, but Laurinda cunningly annotated the MAC address of his laptop's wifi card. The lack of networking knowledge on the part of our hero (who really couldn't tell a SYN packet from an ACK) was to play an important part in the story -- if he had known how to change the MAC address, which identified him with the precision of a surgeon's scalpel, he would have been safe. \end_layout \begin_layout Standard Let's not even get into that last scalpel metaphor, shall we not? It leaks worse than the Titanic. \end_layout \begin_layout Part Of How Our Hero Went No More \end_layout \begin_layout Chapter The Killing \end_layout \begin_layout Standard Our hero led a happy existence for a long time afterwards, randomly avoiding all points within connecting distance of a wifi network. It could not last. \end_layout \begin_layout Standard Our hero went to the next village, found a friendly Moonrams cafe and connected to the net. Quickly the assassin (who knew the very people that run the internet, and who by this display of nerdiness no longer merits the starting capital letter) traced a bunch of IP packets coming from our hero's MAC address. He deployed a team of murderous African bees, which as surely as a well-cared-f or AK-47 reached our hero and killed him with three fast stings. Of course they died afterwards, being bees and all, so it was an astounding feat this training of wild African bees just for this one murder. Maybe the Assassin merits that capital letter after all. \end_layout \begin_layout Section The Passing Away \end_layout \begin_layout Standard Our hero was undone. He was no more. He was, actually, an ex-hero. We shall narrate his wake soon. \end_layout \begin_layout Itemize But first a message from our kind sponsors. They want to present you the next section in this deeper inset. \end_layout \begin_deeper \begin_layout Section The Mourning \end_layout \begin_layout Standard Everyone cried in the ceremony. It was so sad that we need an image of this moment. You can find it in figure \begin_inset CommandInset ref LatexCommand ref reference "fig:mourning" \end_inset . \begin_inset Note Greyedout status open \begin_layout Plain Layout Mental note: never pay the artist beforehand. \end_layout \end_inset \end_layout \end_deeper \begin_layout Standard \begin_inset Float figure wide false sideways false status open \begin_layout Plain Layout \align center \begin_inset Graphics filename mourning.svg \end_inset \end_layout \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout \begin_inset CommandInset label LatexCommand label name "fig:mourning" \end_inset A crude approximation to our hero's mourning. \end_layout \end_inset \end_layout \end_inset \end_layout \begin_layout Standard And thusly everything happened. \end_layout \begin_layout Chapter The Mourning \end_layout \begin_layout Standard We have already talked at length about the mourning, and under sponsorship no less, so no further details will be given here. Suffice to say that our hero was mourned. A lot. \end_layout \begin_layout Chapter \start_of_appendix The Rebirth \end_layout \begin_layout Standard Surprising everyone, our hero was about to make a comeback. \end_layout \begin_layout Section Coming Again \end_layout \begin_layout Standard As it happened, our hero had never died; he had just faked his own death to find out his assassin. It was not difficult, what with the capital letter and all. \end_layout \begin_layout Section Two is Better than One \end_layout \begin_layout Standard How to make another comeback? This is left as an exercise to the reader. \end_layout \begin_layout Chapter Our Recommendation to Kids \end_layout \begin_layout Standard Never trust killer bees. Or Assassins. \end_layout \begin_layout Section Killer Bees and Their Perils \end_layout \begin_layout Standard A killer bee cannot be trained consistently, since it will die at the first sting. Better use killing wasps -- or, even better, solve your differencies talking. \end_layout \begin_layout Standard For the sake of your education, check figure \begin_inset CommandInset ref LatexCommand ref reference "fig:killer-bees" \end_inset . It shows a bunch of killer bees, or something. \end_layout \begin_layout Standard \begin_inset Float figure wide false sideways false status open \begin_layout Plain Layout \align center \begin_inset Graphics filename mourning.svg \end_inset \end_layout \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout \begin_inset CommandInset label LatexCommand label name "fig:killer-bees" \end_inset A gathering of killer bees. Supposedly. \end_layout \end_inset \end_layout \end_inset \end_layout \begin_layout Section Assassins: Inherently Unreliable \end_layout \begin_layout Standard Someone who kills people (even for business) is not someone you want to deal with. Watch \begin_inset Quotes eld \end_inset Fargo \begin_inset Quotes erd \end_inset by the Coen Brothers if you don't believe me. And remember: a hero under the belt is a feather on the hat. \end_layout \end_body \end_document elyxer-1.2.5/test/change.lyx0000644000175000017500000000426212074107030015275 0ustar chennochenno#LyX 1.6.7 created this file. For more info see http://www.lyx.org/ \lyxformat 345 \begin_document \begin_header \textclass article \use_default_options true \language english \inputencoding auto \font_roman default \font_sans default \font_typewriter default \font_default_family default \font_sc false \font_osf false \font_sf_scale 100 \font_tt_scale 100 \graphics default \paperfontsize default \use_hyperref false \papersize default \use_geometry false \use_amsmath 1 \use_esint 1 \cite_engine basic \use_bibtopic false \paperorientation portrait \secnumdepth 3 \tocdepth 3 \paragraph_separation indent \defskip medskip \quotes_language english \papercolumns 1 \papersides 1 \paperpagestyle default \tracking_changes true \output_changes true \author "chenno,,," \end_header \begin_body \begin_layout Title Change Test \end_layout \begin_layout List \labelwidthstring 00.00.0000 \change_inserted 0 1283108483 Prisoner: \change_unchanged Well... I'd just like to say, m'lud, I've got a family... a wife and six kids... and I ho \change_deleted 0 1283108130 o \change_unchanged pe very much you don't have to take away my freedom... because... well, because m'lud freedom is a state much prized within the rea \change_inserted 0 1283108101 l \change_unchanged m of civilized society. It is a bond wherewith the savage man may charm the outward hatchments of his soul, and soothe the troubled brea \change_inserted 0 1283108102 s \change_unchanged t into a magnitude of quiet. It is most precious as a blessed balm, the saviour of princes, the harbinger of happiness, yea, the very stuff and pith of all we hold most dear. What frees the prisoner in his lonely cell, chained within the bondage of rude walls, far from the owl of Theb \change_deleted 0 1283108105 b \change_unchanged es? What fires and stirs the woodcock in his springe or wakes the drowsy apricot betides? What goddess doth the storm toss'd mariner offer her most tempestuous prayers to? Freedom! Freedom! Freedom! \change_inserted 0 1283108446 \end_layout \begin_layout List \labelwidthstring 00.00.0000 \change_inserted 0 1283108472 Judge: It's only a bloody parking offence. \change_unchanged \end_layout \end_body \end_document elyxer-1.2.5/test/elyxer-svg.svg0000644000175000017500000015524512074107030016150 0ustar chennochenno image/svg+xml elyxer-1.2.5/test/appendix-1-6-toc-good.html0000644000175000017500000000675512074107030020033 0ustar chennochenno Converted document elyxer-1.2.5/test/figures-good.html0000644000175000017500000002556612074107030016604 0ustar chennochenno Figures Test

Figures Test

1 Floats

First, figure 1↓.
figure random.png
Figure 1 A random image
Next, figure 2↓.
figure lyx credits.png
(a) Random image A
figure lyx credits.png
(b) Random image B
Figure 2 Two random images
And last, 3↓.
figure random.png
(a) Random image A
figure random.png
(b) Random image B
figure random.png
(c) Random image C
Figure 3 Three random images
That’s all, folks.

2 Wraps

Now with wraps.
figure random.png
Figure 4 A wrapped image.
This image should wrap around the text. The text should be fairly complete and cover several paragraphs, but we might not get so much text. After all typing just because tends to bore the readers, who bear the grunt of the gruntwork of reading the resulting text.
figure random.png
Figure 5 Exterior wrapped image.
The next wrapping image should be smaller, and has default (outer) placement. Again, a lot of text would be required so the image fits around the text; the wrapped image will probably fall on some other page in the PDF, anyway.

3 Algorithms and Listings

We can also add a listing.
This listing appears here courtesy of the fine Ministry of Silly Walks.
And appear here it does alright.
And also a listing inside a float.
This listing appears here courtesy of the fine Ministry of Silly Walks.
And appear here it does alright.
Algorithm 1 An algorithm.
Another algorithm for the sake of it.
\my_first_tex_command
it does not work at all!
\end_command
Algorithm 2 Another algorithm, embedded.
Now the same text outside the algorithm.
\my_first_tex_command
it does not work at all!
\end_command
And an algorithm without caption.
\my_first_tex_command
it should work this time!
\end_command
Now a numbered listing.
1This listing has been numbered.
2Each line has its own number.
A numbered listing with a caption.
1This listing has a caption.
First caption which should not be numbered.
2It should not be numbered.
3These lines, on the other hand, should.
This second caption should not be numbered either.
As soon as we can get to it: a LyX-Code.
This is LyX-Code.
Code-LyX it’s not.
My heart will explode,
My tongue’s in a knot.
Another algorithm, this time without styling.
Who shall declare this good, that ill
When good and ill so intertwine
But to fulfil the vast design of an omniscient will.
When seeming again but turns to loss
When earthly treasure proves but dross
And what seems lost but turns again
To high eternal gain.
Algorithm 4 A poem by Dame Irene Stoat.
And many other things.

4 Boxes (Minipages)

We can insert a box here:
Well I, I think that, er, nobody who has gone abroad should be allowed back in the country. I mean, er, blimey, blimey if they’re not keen enough to stay here when they’re ’ere, why should we allow them back, er, at the tax-payers’ expense? I mean, be fair, I mean, I don’t eat squirrels do I? I mean well perhaps I do one or two but there’s no law against that, is there? It’s a free country. I mean if I want to eat a squirrel now and again, that’s me own business, innit? I mean, I’m no racialist. I, oh, oh...
A decorated centered box:
CONFUSE-A-CAT LIMITED
INCORPORATING
AMAZE-A-VOLE LTD
STUN-A-STOAT LTD
PUZZLE-A-PUMA LTD
STARTLE-A-THOMPSON’S GAZELLE LTD
BEWILDEREBEEST INC
DISTRACT-A-BEE
And a double-decorated box with a certain width:
Goodnight. Ding-ding-ding-ding-ding, five, four, three, two, one… Goodnight. Ding-ding-ding-ding-ding, five, four, three, two, one…
Five, four, three, two, one, zero!
It was fine doing that.
elyxer-1.2.5/test/with images-1-5-html-good.html0000644000175000017500000000326612074107030020574 0ustar chennochenno Images Tests

Images Tests

figure elyxer-svg.png First image: regular path.
figure elyxer-svg.png Second image: convoluted path.
figure docs/elyxer.png Third image: from another directory.
figure mini-elyxer.jpg Fourth image: from a JPEG file.
figure square.png Fifth image: from a PNG file.
elyxer-1.2.5/test/figures.lyx0000644000175000017500000003333212074107030015514 0ustar chennochenno#LyX 1.6.7 created this file. For more info see http://www.lyx.org/ \lyxformat 345 \begin_document \begin_header \textclass scrartcl \begin_preamble % eLyXer -- convert LyX source files to HTML output. % % Copyright (C) 2009-2010 Alex Fernández % % This program is free software: 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 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 % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . \end_preamble \use_default_options false \language english \inputencoding auto \font_roman default \font_sans default \font_typewriter default \font_default_family default \font_sc false \font_osf false \font_sf_scale 100 \font_tt_scale 100 \graphics default \paperfontsize default \spacing single \use_hyperref false \papersize default \use_geometry false \use_amsmath 1 \use_esint 1 \cite_engine basic \use_bibtopic false \paperorientation portrait \secnumdepth 3 \tocdepth 3 \paragraph_separation skip \defskip medskip \quotes_language english \papercolumns 1 \papersides 1 \paperpagestyle default \tracking_changes false \output_changes false \author "" \author "" \end_header \begin_body \begin_layout Title Figures Test \end_layout \begin_layout Standard \begin_inset FloatList figure \end_inset \end_layout \begin_layout Standard \begin_inset FloatList algorithm \end_inset \end_layout \begin_layout Section Floats \end_layout \begin_layout Standard First, figure \begin_inset CommandInset ref LatexCommand ref reference "fig:A-random-image" \end_inset . \end_layout \begin_layout Standard \begin_inset Float figure wide false sideways false status open \begin_layout Plain Layout \align center \begin_inset Graphics filename random.png width 50col% \end_inset \end_layout \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout \begin_inset CommandInset label LatexCommand label name "fig:A-random-image" \end_inset A random image \end_layout \end_inset \end_layout \begin_layout Plain Layout \end_layout \end_inset \end_layout \begin_layout Standard Next, figure \begin_inset CommandInset ref LatexCommand ref reference "fig:Two-random-images." \end_inset . \end_layout \begin_layout Standard \begin_inset Float figure wide false sideways false status open \begin_layout Plain Layout \begin_inset Float figure wide false sideways false status open \begin_layout Plain Layout \align center \begin_inset Graphics filename lyx credits.png width 50col% \end_inset \end_layout \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout Random image A \end_layout \end_inset \end_layout \end_inset \begin_inset Float figure wide false sideways false status open \begin_layout Plain Layout \align center \begin_inset Graphics filename lyx credits.png width 50col% \end_inset \end_layout \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout Random image B \end_layout \end_inset \end_layout \end_inset \begin_inset Caption \begin_layout Plain Layout \begin_inset CommandInset label LatexCommand label name "fig:Two-random-images." \end_inset Two random images \end_layout \end_inset \end_layout \end_inset \end_layout \begin_layout Standard And last, \begin_inset CommandInset ref LatexCommand ref reference "fig:Three-random-images" \end_inset . \end_layout \begin_layout Standard \begin_inset Float figure wide false sideways false status open \begin_layout Plain Layout \begin_inset Float figure wide false sideways false status open \begin_layout Plain Layout \align center \begin_inset Graphics filename random.png width 30col% \end_inset \end_layout \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout Random image A \end_layout \end_inset \end_layout \end_inset \begin_inset Float figure wide false sideways false status open \begin_layout Plain Layout \align center \begin_inset Graphics filename random.png width 30col% \end_inset \end_layout \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout Random image B \end_layout \end_inset \end_layout \end_inset \begin_inset Float figure wide false sideways false status open \begin_layout Plain Layout \align center \begin_inset Graphics filename random.png width 30col% \end_inset \end_layout \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout Random image C \end_layout \end_inset \end_layout \end_inset \end_layout \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout \begin_inset CommandInset label LatexCommand label name "fig:Three-random-images" \end_inset Three random images \end_layout \end_inset \end_layout \end_inset \end_layout \begin_layout Standard That's all, folks. \end_layout \begin_layout Section Wraps \end_layout \begin_layout Standard Now with wraps. \end_layout \begin_layout Standard \begin_inset Wrap figure lines 0 placement l overhang 0in width "50col%" status open \begin_layout Plain Layout \end_layout \begin_layout Plain Layout \align center \begin_inset Graphics filename random.png width 50col% \end_inset \end_layout \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout A wrapped image. \end_layout \end_inset \end_layout \end_inset \end_layout \begin_layout Standard This image should wrap around the text. The text should be fairly complete and cover several paragraphs, but we might not get so much text. After all typing just because tends to bore the readers, who bear the grunt of the gruntwork of reading the resulting text. \end_layout \begin_layout Standard \begin_inset Wrap figure lines 0 placement o overhang 0in width "4cm" status open \begin_layout Plain Layout \align center \begin_inset Graphics filename random.png width 4cm \end_inset \end_layout \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout Exterior wrapped image. \end_layout \end_inset \end_layout \end_inset \end_layout \begin_layout Standard The next wrapping image should be smaller, and has default (outer) placement. Again, a lot of text would be required so the image fits around the text; the wrapped image will probably fall on some other page in the PDF, anyway. \end_layout \begin_layout Section Algorithms and Listings \end_layout \begin_layout Standard We can also add a listing. \end_layout \begin_layout Standard \begin_inset listings inline false status open \begin_layout Plain Layout This listing appears here courtesy of the fine Ministry of Silly Walks. \end_layout \begin_layout Plain Layout And appear here it does alright. \end_layout \end_inset \end_layout \begin_layout Standard And also a listing inside a float. \end_layout \begin_layout Standard \begin_inset Float algorithm wide false sideways false status open \begin_layout Plain Layout \begin_inset listings inline false status open \begin_layout Plain Layout This listing appears here courtesy of the fine Ministry of Silly Walks. \end_layout \begin_layout Plain Layout And appear here it does alright. \end_layout \end_inset \end_layout \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout An algorithm. \end_layout \end_inset \end_layout \begin_layout Plain Layout \end_layout \end_inset \end_layout \begin_layout Standard Another algorithm for the sake of it. \end_layout \begin_layout Standard \begin_inset Float algorithm wide false sideways false status open \begin_layout Quotation \family typewriter \backslash my_first_tex_command \end_layout \begin_layout Quotation \family typewriter it does not work at all! \end_layout \begin_layout Quotation \family typewriter \backslash end_command \end_layout \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout Another algorithm, embedded. \end_layout \end_inset \end_layout \end_inset \end_layout \begin_layout Standard Now the same text outside the algorithm. \end_layout \begin_layout Quotation \family typewriter \backslash my_first_tex_command \end_layout \begin_layout Quotation \family typewriter it does not work at all! \end_layout \begin_layout Quotation \family typewriter \backslash end_command \end_layout \begin_layout Standard And an algorithm without caption. \end_layout \begin_layout Standard \begin_inset Float algorithm wide false sideways false status open \begin_layout Quotation \family typewriter \backslash my_first_tex_command \end_layout \begin_layout Quotation \family typewriter it should work this time! \end_layout \begin_layout Quotation \family typewriter \backslash end_command \end_layout \end_inset \end_layout \begin_layout Standard Now a numbered listing. \end_layout \begin_layout Standard \begin_inset listings lstparams "numbers=left,stepnumber=1" inline false status open \begin_layout Plain Layout This listing has been numbered. \end_layout \begin_layout Plain Layout Each line has its own number. \end_layout \end_inset \end_layout \begin_layout Standard A numbered listing with a caption. \end_layout \begin_layout Standard \begin_inset listings lstparams "numbers=left,stepnumber=1" inline false status open \begin_layout Plain Layout This listing has a caption. \end_layout \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout First caption which should not be numbered. \end_layout \end_inset \end_layout \begin_layout Plain Layout It should not be numbered. \end_layout \begin_layout Plain Layout These lines, on the other hand, should. \end_layout \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout This second caption should not be numbered either. \end_layout \end_inset \end_layout \end_inset \end_layout \begin_layout Standard As soon as we can get to it: a LyX-Code. \end_layout \begin_layout LyX-Code This is LyX-Code. \end_layout \begin_layout LyX-Code Code-LyX it's not. \end_layout \begin_layout LyX-Code My heart will explode, \end_layout \begin_layout LyX-Code My tongue's in a knot. \end_layout \begin_layout Standard Another algorithm, this time without styling. \end_layout \begin_layout Quote \begin_inset Float algorithm wide false sideways false status open \begin_layout Plain Layout Who shall declare this good, that ill \end_layout \begin_layout Plain Layout When good and ill so intertwine \end_layout \begin_layout Plain Layout But to fulfil the vast design of an omniscient will. \end_layout \begin_layout Plain Layout When seeming again but turns to loss \end_layout \begin_layout Plain Layout When earthly treasure proves but dross \end_layout \begin_layout Plain Layout And what seems lost but turns again \end_layout \begin_layout Plain Layout To high eternal gain. \end_layout \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout A poem by Dame Irene Stoat. \end_layout \end_inset \end_layout \end_inset \end_layout \begin_layout Standard And many other things. \end_layout \begin_layout Section Boxes (Minipages) \end_layout \begin_layout Standard We can insert a box here: \end_layout \begin_layout Standard \begin_inset Box Frameless position "t" hor_pos "c" has_inner_box 1 inner_pos "t" use_parbox 0 width "100col%" special "none" height "1in" height_special "totalheight" status open \begin_layout Plain Layout \noindent Well I, I think that, er, nobody who has gone abroad should be allowed back in the country. I mean, er, blimey, blimey if they're not keen enough to stay here when they're 'ere, why should we allow them back, er, at the tax-payers' expense? I mean, be fair, I mean, I don't eat squirrels do I? I mean well perhaps I do one or two but there's no law against that, is there? It's a free country. I mean if I want to eat a squirrel now and again, that's me own business, innit? I mean, I'm no racialist. I, oh, oh... \end_layout \end_inset \end_layout \begin_layout Standard A decorated centered box: \end_layout \begin_layout Standard \begin_inset Box Boxed position "t" hor_pos "c" has_inner_box 1 inner_pos "t" use_parbox 0 width "100col%" special "none" height "1in" height_special "totalheight" status open \begin_layout Plain Layout \noindent \align center CONFUSE-A-CAT LIMITED \end_layout \begin_layout Plain Layout \noindent \align center INCORPORATING \end_layout \begin_layout Plain Layout \noindent \align center AMAZE-A-VOLE LTD \end_layout \begin_layout Plain Layout \noindent \align center STUN-A-STOAT LTD \end_layout \begin_layout Plain Layout \noindent \align center PUZZLE-A-PUMA LTD \end_layout \begin_layout Plain Layout \noindent \align center STARTLE-A-THOMPSON'S GAZELLE LTD \end_layout \begin_layout Plain Layout \noindent \align center BEWILDEREBEEST INC \end_layout \begin_layout Plain Layout \noindent \align center DISTRACT-A-BEE \end_layout \end_inset \end_layout \begin_layout Standard And a double-decorated box with a certain width: \end_layout \begin_layout Standard \begin_inset Box Doublebox position "t" hor_pos "c" has_inner_box 1 inner_pos "t" use_parbox 0 width "60col%" special "none" height "1in" height_special "totalheight" status open \begin_layout Plain Layout Goodnight. Ding-ding-ding-ding-ding, five, four, three, two, one\SpecialChar \ldots{} Goodnight. Ding-ding-ding-ding-ding, five, four, three, two, one\SpecialChar \ldots{} \end_layout \begin_layout Plain Layout Five, four, three, two, one, zero! \end_layout \end_inset \end_layout \begin_layout Standard It was fine doing that. \end_layout \end_body \end_document elyxer-1.2.5/test/plain-text.txt0000644000175000017500000000017212074107030016134 0ustar chennochennoPlain text document. To be included verbatim in a LyX document. Do not modify unless you want to test something. elyxer-1.2.5/test/toc-book-good.html0000644000175000017500000000727112074107030016646 0ustar chennochenno Book TOC Test

Book TOC Test

List of Figures

Part I. Our Definition

1 The definition

A TOC is a Table Of Contents.

1.1 But I Already Knew That

You were lucky.

I Want My Money Back

There you have your 0€ back.

Completely Unfair Dude

Hey, I didn’t call you here.
A Paragraph For You
Totally uncalled for.
figure elyxer-svg.png
Figure 1.1 eLyXer logo

Unordered Section

Just to show that it works.
And now a list.
  1. First item.
  2. We will embed an ordered subsection here just to fake it.

    There We Go

  3. See if it’s in your TOC.
But There Is More
And nothing else.

A Appendix

An appendix here, an appendix there.
elyxer-1.2.5/test/bibtex-alpha.bib0000644000175000017500000000132212074107030016322 0ustar chennochenno%% eLyXer: test BibTeX bibliography for alpha style. %% Created on 20100601 by Alex Fernandez. @article{alphavolume, Author = {E. Praline and B. Brooky}, Title = {The population explosion}, Number = {1}, Pages = {2--4}, Journal = {Just The Words}, Publisher = {Brooky \& Sons}, Volume = {1}, Year = {1969}, url = {http://www.ibras.dk/montypython/episode18.htm} } @article{alphabasic, Author = {B. Bishop and W. Belpit}, Journal = {Just The Words}, Publisher = {Grillomat Snack Bar, Paignton}, Title = {Your legs are so swollen}, Year = {1969}, file = :bibtex-good.html:HTML, url = http://www.ibras.dk/montypython/episode18.htm, note = {Found on \url{http://www.ibras.dk/montypython/episode18.htm}.} } elyxer-1.2.5/test/file-1-6.lyx0000644000175000017500000000634312074107030015272 0ustar chennochenno#LyX 1.6.7 created this file. For more info see http://www.lyx.org/ \lyxformat 345 \begin_document \begin_header \textclass article \begin_preamble % eLyXer -- convert LyX source files to HTML output. % % Copyright (C) 2009-2010 Alex Fernández % % This program is free software: 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 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 % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . \end_preamble \use_default_options true \language english \inputencoding auto \font_roman default \font_sans default \font_typewriter default \font_default_family default \font_sc false \font_osf false \font_sf_scale 100 \font_tt_scale 100 \graphics default \paperfontsize default \spacing single \use_hyperref false \papersize default \use_geometry false \use_amsmath 1 \use_esint 1 \cite_engine basic \use_bibtopic false \paperorientation portrait \secnumdepth 3 \tocdepth 3 \paragraph_separation skip \defskip medskip \quotes_language english \papercolumns 1 \papersides 1 \paperpagestyle default \tracking_changes false \output_changes false \author "" \author "" \end_header \begin_body \begin_layout Title File Test \end_layout \begin_layout Author Created by Alex Fernández \end_layout \begin_layout Standard This document was created with LyX 1.6.2rc2, a great text editor. \end_layout \begin_layout Part The only part \end_layout \begin_layout Section The First Section \end_layout \begin_layout Standard With some text. \begin_inset Note Greyedout status open \begin_layout Plain Layout And a greyed out note. \end_layout \end_inset \end_layout \begin_layout Section* Another Section (Not Numbered) \end_layout \begin_layout Standard With some more text. \begin_inset Note Note status open \begin_layout Plain Layout And a note which should not appear at all. \end_layout \end_inset \begin_inset Note Comment status open \begin_layout Plain Layout Actually, two notes which should not appear. \end_layout \end_inset \end_layout \begin_layout Standard Now we include a different document. \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand include filename "helloworld.lyx" \end_inset \end_layout \begin_layout Standard And now a verbatim include. \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand verbatiminput filename "plain-text.txt" \end_inset \end_layout \begin_layout Standard \begin_inset Note Comment status open \begin_layout Plain Layout An include which should not appear since it's inside a comment. \begin_inset CommandInset include LatexCommand include filename "helloworld.lyx" \end_inset \end_layout \end_inset \end_layout \begin_layout Standard \begin_inset CommandInset index_print LatexCommand printindex \end_inset \end_layout \end_body \end_document elyxer-1.2.5/test/image-scaling.lyx0000644000175000017500000000642612074107030016554 0ustar chennochenno#LyX 1.6.5 created this file. For more info see http://www.lyx.org/ \lyxformat 345 \begin_document \begin_header \textclass article \begin_preamble % eLyXer -- convert LyX source files to HTML output. % % Copyright (C) 2009-2010 Alex Fernández % % This program is free software: 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 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 % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . \end_preamble \use_default_options false \language english \inputencoding auto \font_roman default \font_sans default \font_typewriter default \font_default_family default \font_sc false \font_osf false \font_sf_scale 100 \font_tt_scale 100 \graphics default \paperfontsize default \spacing single \use_hyperref false \papersize default \use_geometry false \use_amsmath 1 \use_esint 1 \cite_engine basic \use_bibtopic false \paperorientation portrait \secnumdepth 3 \tocdepth 3 \paragraph_separation skip \defskip medskip \quotes_language english \papercolumns 1 \papersides 1 \paperpagestyle default \tracking_changes false \output_changes false \author "" \author "" \end_header \begin_body \begin_layout Title Image Scaling Tests \end_layout \begin_layout Section Scale \end_layout \begin_layout Standard \begin_inset Graphics filename elyxer.png \end_inset PNG unscaled. \end_layout \begin_layout Standard \begin_inset Graphics filename elyxer.png lyxscale 50 scale 50 \end_inset PNG scaled 50%. \end_layout \begin_layout Standard \begin_inset Graphics filename elyxer-eps.eps \end_inset Unscaled EPS. \end_layout \begin_layout Standard \begin_inset Graphics filename elyxer-eps.eps scale 50 \end_inset EPS scaled 50%. \end_layout \begin_layout Section Exploring Width \end_layout \begin_layout Standard \begin_inset Graphics filename elyxer.png lyxscale 50 width 50col% \end_inset 50% column width. \end_layout \begin_layout Standard \begin_inset Graphics filename elyxer.png lyxscale 50 width 5cm \end_inset 5cm wide. \end_layout \begin_layout Standard \begin_inset Graphics filename elyxer.png lyxscale 50 width 50line% \end_inset 50% line width. \end_layout \begin_layout Standard \begin_inset Graphics filename elyxer.png lyxscale 50 width 5mm \end_inset 5mm wide. \end_layout \begin_layout Section Exploring Height \end_layout \begin_layout Standard \begin_inset Graphics filename elyxer.png lyxscale 50 height 50col% \end_inset 50% column height. \end_layout \begin_layout Standard \begin_inset Graphics filename elyxer.png lyxscale 50 height 5cm \end_inset 5cm high. \end_layout \begin_layout Standard \begin_inset Graphics filename elyxer.png lyxscale 50 height 50page% \end_inset 50% page height. \end_layout \begin_layout Standard \begin_inset Graphics filename elyxer.png lyxscale 50 height 5mm \end_inset 5 mm high. \end_layout \end_body \end_document elyxer-1.2.5/test/references-good.html0000644000175000017500000000460512074107030017250 0ustar chennochenno References Test

References Test

Alex Fernández (elyxer@gmail.com)

1 First Chapter

This first chapter contains the reference: 2↓, contained in chapter: 2↓.

1.1 Sectioned

This section contains a reference in brackets: (2↓). It should be on page: 1↓, and so be: 2 on page 1↓.
Adding a pretty reference: Chapter 2↓. Now a named reference: Second Chapter↓.

2 Second Chapter

This second chapter contains the label .

2.1 URIs

elyxer-1.2.5/test/spacing-good.html0000644000175000017500000000724012074107030016551 0ustar chennochenno Spacing Test

Spacing Test

1 Paragraph

As our world turns more complex, paragraph spacing tends to be more and more important.
Some people would say that paragraph spacing is the first and foremost issue in our modern culture. Perhaps they can be said to be exaggerating, but not by much.

2 Issues in Horizontal Spacing

Some new issues arise every day. Today we would like to explore horizontal fill.
Cheese available
Red Leicester no
Tilsit no
Cheese available
Camembert runny
Cheddar no
These tables should be separated by equal horizontal spacing. Can it be done? It should.

2.1 Horizontal Space

The horizontal space is inserted using Insert ▷ Format ▷ Horizontal space. The result is as follows: a b c d e  f.
Custom spaces can also be used: 01cm1in.

2.2 Half Spaces

As reported by Uwe Stöhr: 22 m, 3.53 €. It is correctly converted to a thin space.

3 Issues in Vertical Spacing

Vertical spacing can also be added. Let us now separate a few sentences with it.
J. Losey
L. Anderson
S. Kubrick
P.P. Pasolini
O. Welles
The Late B. Forbes
elyxer-1.2.5/test/descriptions-1-5.lyx0000644000175000017500000000663512074107030017064 0ustar chennochenno#LyX 1.5.7 created this file. For more info see http://www.lyx.org/ \lyxformat 276 \begin_document \begin_header \textclass article \begin_preamble % eLyXer -- convert LyX source files to HTML output. % % Copyright (C) 2009-2010 Alex Fernández % % This program is free software: 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 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 % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . \end_preamble \language english \inputencoding auto \font_roman default \font_sans default \font_typewriter default \font_default_family default \font_sc false \font_osf false \font_sf_scale 100 \font_tt_scale 100 \graphics default \paperfontsize default \spacing single \papersize default \use_geometry false \use_amsmath 1 \use_esint 1 \cite_engine basic \use_bibtopic false \paperorientation portrait \secnumdepth 3 \tocdepth 3 \paragraph_separation indent \defskip medskip \quotes_language english \papercolumns 1 \papersides 1 \paperpagestyle default \tracking_changes false \output_changes false \author "" \author "" \end_header \begin_body \begin_layout Title Descriptions Tests \end_layout \begin_layout Description First description. \end_layout \begin_layout Description Second\InsetSpace ~ description. \end_layout \begin_layout Description Third\InsetSpace ~ description\InsetSpace ~ which\InsetSpace ~ should\InsetSpace ~ hold\InsetSpace ~ all\InsetSpace ~ words but these. \end_layout \begin_layout Description Fourth description. \end_layout \begin_layout Description Fifth\InsetSpace \space{} description\InsetSpace \thinspace{} with odd spaces. \end_layout \begin_layout Description \family typewriter Mixed \family default font description. \end_layout \begin_layout Description \family typewriter An even \family default more difficult description with change of font in the middle. \end_layout \begin_layout Description \family typewriter A \color red n \family default i \color inherit mpossible description with intermixed changes of font and color. \end_layout \begin_layout Description A description which leads to \family typewriter fixed \color blue text \color red in \color inherit \color green dif \family default (fere) \family typewriter nt \color inherit \color magenta colors \family default \color inherit . And now \family typewriter \series bold some \series default more \family default . \end_layout \begin_layout Description \begin_inset ERT status open \begin_layout Standard \end_layout \end_inset ERT precedes this description, it should be kept. \end_layout \begin_layout Description \begin_inset ERT status open \begin_layout Standard ERT is the description \end_layout \end_inset and not only the first word. \end_layout \begin_layout Description \begin_inset LatexCommand index name "Word" \end_inset Word that leads a description and which appears in the Index. \end_layout \begin_layout Description \begin_inset LatexCommand printindex \end_inset \end_layout \end_body \end_document elyxer-1.2.5/test/footnotes-1-6-hover-end-good.html0000644000175000017500000001637312117063046021350 0ustar chennochenno Footnotes Tests

Footnotes Tests

1 This is just some random section text used to insert some footnotes.[1] [1] And this is one of those footnotes. And this is a margin note, also tested here.

Lorem ipsum dolor sit amet, consectetur adipisicing[2] [2] adipisicing elit[3] [3] elit, sed do eiusmod eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa [4] [4] culpa qui officia [5] [5] officia deserunt mollit anim id est laborum.
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum[6] [6] laborum, laborum.
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do tempor incididunt ut [7] [7] ut labore[8] [8] labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis Duis aute irure dolor in reprehenderit in voluptate velit[9] [9] velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id id est laborum.

Nomenclature

eiusmod eiusmod indeed

References

Index

ullamco:

Footnotes

[1]And this is one of those footnotes.
[2]adipisicing
[3]elit
[4]culpa
[5]officia
[6]laborum, laborum
[7]ut
[8]labore
[9]velit
elyxer-1.2.5/test/helloworld-embedcss-good.html0000644000175000017500000000201512074107030021056 0ustar chennochenno Converted document
Hello world
elyxer-1.2.5/test/compressed.lyx0000644000175000017500000000174112074107030016213 0ustar chennochennoUn6}W X`HgmmQ 6FTl[c=,'NѴ/g9s&t:a#I"pNT y@Qe2%Lef3v`$[TXW@g+^+̭l*6K9lxޓpAIDŎIZ.P$m$'rl& ֭S2лa8tH#[dgmzc];QQ !Fo?Qk\Ԫ E a򓔚\mCʓ->a'45+$Md|G/UM.#َd5G z';#.C-@ޑ{0nI{d)UO७S HDQZӊ\4(a5}ϯn4y/tt3C?rZ+@#2'Lh@_fx2? o.f3҈F~2vv1 q$u+y.69}OTGF%G躺 &YH%lr֦I; [ɟF`.s.Dò!5¬fb-AFM٢&,м; B[Ʃ=BTJ/$B#h}q /f:{?*[ Iu36ŧ^}'y|ܔ}&ClͶYԉcUtډ  ,TeV+ݯ*ZO)4T[P(KT9@?ær)xNUw?/YZZT>蜟>Y@N~Eꖲ"K-ڧĸyC؞/۽E}Jtn+9t݋e*\P_,=}pMaᏒ1+Iܢ W~lVNYIPl1hlRR۬s셿(G7=Yelyxer-1.2.5/test/toc-book-notoclabels-good.html0000644000175000017500000000714312074107030021147 0ustar chennochenno Book TOC Test

Book TOC Test

List of Figures

I. Our Definition

1 The definition

A TOC is a Table Of Contents.

1.1 But I Already Knew That

You were lucky.

I Want My Money Back

There you have your 0€ back.

Completely Unfair Dude

Hey, I didn’t call you here.
A Paragraph For You
Totally uncalled for.
figure elyxer-svg.png
Figure 1.1 eLyXer logo

Unordered Section

Just to show that it works.
And now a list.
  1. First item.
  2. We will embed an ordered subsection here just to fake it.

    There We Go

  3. See if it’s in your TOC.
But There Is More
And nothing else.

A Appendix

An appendix here, an appendix there.
elyxer-1.2.5/test/helloworld.lyx0000644000175000017500000000321312074107030016216 0ustar chennochenno#LyX 1.6.5 created this file. For more info see http://www.lyx.org/ \lyxformat 345 \begin_document \begin_header \textclass article \begin_preamble % eLyXer -- convert LyX source files to HTML output. % % Copyright (C) 2009-2010 Alex Fernández % % This program is free software: 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 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 % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . \end_preamble \use_default_options false \language spanish \inputencoding auto \font_roman default \font_sans default \font_typewriter default \font_default_family default \font_sc false \font_osf false \font_sf_scale 100 \font_tt_scale 100 \graphics default \paperfontsize default \spacing single \use_hyperref false \papersize default \use_geometry false \use_amsmath 1 \use_esint 1 \cite_engine basic \use_bibtopic false \paperorientation portrait \secnumdepth 3 \tocdepth 3 \paragraph_separation skip \defskip medskip \quotes_language english \papercolumns 1 \papersides 1 \paperpagestyle default \tracking_changes false \output_changes false \author "" \author "" \end_header \begin_body \begin_layout Standard Hello world \end_layout \end_body \end_document elyxer-1.2.5/test/lyx credits.png0000644000175000017500000005011412074107030016247 0ustar chennochennoPNG  IHDRjU pHYs+ IDATxit׵(khfog `%{o $ 49w; %h؎ $FBh`D7w﷾"nI87X]~Tw5vԽ%ڵבVթSuNϞ7* ZTPAE*>TPA} *PATPч *TPAE*S ۊtΈ3.&cV*0Cl+l8?'X|t1K?R? *L&??'tƗ~ڣ;ީ3E<3glh{4y\x~+֤-SJ~^g{߽?]l`vw>tʿ:.xto83/fAHC#hh{ t:>V(jʿ!4[zg݌ *P8h:>\Lr$/99ϬާZ$%iy} >B0U}ڵC=+J\O)%pD EBs'Σ^^ƣtJ}^$jCgYeiM3H40%3f1p˞JpfYzo߉7fyE=BoP.^ꖁ"n֖-2>8w8z1bT)T![t*>ײw~^yoj3\!IOgċ_Jnry+ #QCz*S*C&XxsS!yf_a'I췘o\VrވUG޺X6f~W[9tJ_hpY{a<9tۏTO-FK-Yo+/vR<Zz@>:HL2 gYeÿzv~7>vx~̲tgd[e*A$D5x>,ֶT;|XĭZy+/""h/֟yk=f_zaݧwZyW~Q=+/ڶ%^T_;y6KK썗vjqN.y}k1/\yvi-|,.$xϥ_2bg߸Bp`ޚbl-D {[Rqo^?Q}Q~(Sۖ%r˳v`yb^m_xwRz7ƹwcxTHUjرySץy+ѨrJ7ˢn&=/qwg ~BeްT-`T[xZj忧/l%?7r7?4s/?u>O/<3#'7}1;,~2vT>Q *C |8yC>UP$ݦO˫ś_ O;'1N@ Űuëřg6!<EH!x&a q^!3ts_G)Y<٥ `$2$ a&9H;("zp&G#p~H1fGlhQk=udg4Gp5zC†8)xU4\-W0˼`8{ڵZ9OG tJ(b]l:I0n/2!)x1*Q7hS@}xZNr҅O#Ɇ6$SX$o/zHѨ&8h Iyrܤy􈣉$Lq#I3UC 󔘍4E ;HSxׇ],l>2 b ATxJ`˖ @\z71/r-[6_E>aƼ$h4w}]SD4L=L@\pЄX5}\ފG6u88_Mތ3hSm]oȺk=(^6hRw2[lazhASxO]F^5h82 b4&fcd8}h,q>pܑ&vܵPݦ`^e.<8pT1E>w9l^fcLaRC,()#4$Fwp/'SHTJ@ M2l 6 `@D95RRM΄c H) '30ֵ)w%aݵ/NF3BЀc@UqpX(@Te<D;EQZS֎/2 ۱ IicХveQ( jP%" "˚Aʷ)rE4| ( Ӡ%:+e4ĺkN+E6PX`>^ `HFi7:P@C(+׏d ef8>ϋRf/I- l6‹h0Gc]{WRXqJ^SVfbλb 34(ƱEa$3MVJ~Ѐ>de(6@ },l&Z$hj >] ͭGĢhp(P4}žyrꓡi+f_i@k 6"rG4SV.U2=1 CC! Ynj|^P9gp{IbCz1ay^E-b 2K U*&s2Պeh g:@)e&%o)pMD854xڎu>x( 4T-?AQ1GBD+buN7:9?b( (8R@AC M#QbqP3X欍 / J 8`|a88\XьBKi ԝD|yAcа$H ҭ:#kJ Qb)|X$,eeAL6By>M.{r_F)?4,cļ`]Gs8~(4#tGĺ*Mt78},[KnRuq+ *6 + "вZ$R&oTxDppc@\_XPč8߆r$(k(.FF\dfܥPRp%40h %- v9Afǻx[8.@p6@O$/˜L)žUናeMi8Iۍ8Q)r=NeJbxRH$ưy@Cd}Ȍ8L]h+OX堅JfPDRL2 þLԈ^[M㾁& /'2ЦYwy:\Xc7o R`(:*@ PH@~D1%m&^ `_ 7Q{Nzڦm7teOS}/T}Pm  k910/ʼn0J!hPҲy)is X~"ӳ[6~ yӲisfȦC6]>d\9o ??1ڧQ&7ޣX3sxLJ^LHF#J uѲxk|XƲ,z' 7TQ>=γ)tU:d޴l ak#]}py3̈́E۶eHhڅیs!3r/o5beQ9H_uQFM֕kvvGKh_+o c3RzPlB㐔n6DB^;ʭB͕cp4BB` 1,4^UqlQR=VU0署$ƭXyl1YTg4]?b"c`_`ouo=PۖcR'Gm;Y>l_ K xIZu+nNch`{`5xTND,2? [wЦ{59j"``և}tsӽ՟_Y9x~yvo,'r_Њ 3{QaYe= 5j .kYd4#}#AC[42o(#I<Ūbs)AőUt* Kte p,+CIT_G*ʣY1t-MMSQT%ݩAk|"/~K?LAvEBB@`$u7CS@ MQN5nz*õfoԷɆIή˄K yh.sN% ^:E0NbpsQxyrGC,Jmmg11Fݠ MQ@3컹+>̖HQ@ϛcŁVqOMQ@K|](C"fAOA|_l_%̷~NWʛEE^GhD.sX"!J! cNuR"! Kd}VEst:#TXp1 s686b'I3%LťNfS>N5! Jwsօ>[t/Ϻu[{sDN℁cAS |fW*T]+qW>Da`y߈qG-m]+5Uz_o؏]ܲef a$Usu%ÑbdP^#eUl2ϋg3q}?xvRha.qHJaQN]{A2'(@3!uJ]qOdXC؊:7}x֌% lXYpeci)wجm&@aNqmq^Fcq2'P,F>plk(,x$)l&ьuX(2~pAl-HU{8#?`.H͂pb/"e̪>Xw၇ꩋ\jd9M asc_<<vfDxx>-(FF#QZZRmX䖖kZWN>wtߵy-#׈k_.UDQo_ekf="o?V B᱀?ؖfna^Dn hbjeVra ڿbZC_iT,sFfrߢ3*l(e1~#"wW@վiY˛ׄ_14jg,d(sAj;{RZju%C㶞:;$ZJWui+٨ XWk(h~!bh>8__?__?_ߔ6 vn7G=RNS M1m))m))|}ܖ*{#)T???V"u(Qo,&o&DnEg׭;*]u]0mik-k-PPcKiӦPmׯo[8m|3%;qt`j$4ñqHrIƧ#Դ6m5elk6KP@ĂI>\0vlF!+C,Ou\7g_cMlI1zj!sO^}~?zy $I׷5$??.m| lsi__o__o_y_ߡogTܡi]'F[e 2,.)TRF4ESMImwމ\T[wRGD 98vQ==nf?~R;YS~Sy`HR[E$5>&$\]BeϲNeU[X<ֺ՟\ɲ) pv޼E#џ2~wd~dnz_TIFå5"mT*hTS@ӌ`)iV˺{+5 ̋Y:MX XI*h>d#Rpq?o(jVlo峨PDҞIcKarTIZmWQ05?tz1rRKWׯH-ڊV\(xPaDBH-[Ͳ}ft_c.YD}ƹkCkFQUT[BmJ07׭ Wkv<1&1+Z}79Hыf .a/,2W4~.Z{1A*i4C4CqAjCt ҪAW)]pfRES C3LܶSuɯԝ04^vI^Yj.s=Y6LQ٦vf)Y26ZXa#Ev0O?_]2NmJǹ/6^y}5lo'|u_{^:_:vj>~qC IDATzd# mĔX 83 Mi@.#F7j^d{Blݧ7[7n OjuKB@vOѝ=U?pUt%bFos\E~@+[M*]U4 mF]znj*ӹ]VҗrOwzTG#^8gө>lGDq ǹ7#-[6l6:EB0},QVp` [}`zYw{R߷<鉇L[FO6\Qvmٲgf~%Jm:Yv;ˌ fvdڢi{ 9:x[s Mى*U}?Mi.Σ_R{# 杀亓xhMc{:X!ZJz}6lB:#mGK?R#}{8 EP UBxDXW"f^QҸcI %*S`EZ>Kq-8Lhwdh  cCBROe*D X}4Xdg6O4,J.`l㨬pYJ %T&*EO>"`18Sm%(:H%ZA:UJnXwbqHAkPd 8lVwxd*vimqhVzCL,  cYB*FTǺ뗔ZJ.d#d} CFkMiQ#D It"aBp DP+f-BT+֠a`C4A&),SOk^4XH[5,"q^fhe= M!JpsIt=e<ی,8VQa_ALf?h!ow'l(itLyRiKO$W;wu>||W/J^h WHbٖ!-G*ͫu==Ѝ%%C) uO204͌yKeY'o|UACNZsA?kAD(m_>uIlbvNyP  $d}q#wL65v?~]8Պq[hF.^e0~=%N3vq#!]Fl&e\Դf"4|vl?yxG}4/__|wmw>.7Q,Bznwˬ+l;y{-Ea(T^ͽRaThOtݢ7^ ۗU (p:%?00B EYΥkKK;WxPr3ީ&OT d Geȼh1_' @r6 -NzDZ059hn>=%Y%/etoDQXSV)bce.#4cBO2տx|;CS&}qwϗpY[B^v&ĸ~vzuϠXY~£2wW]]u]U !u]iHh{6=#0P5qpDE4WZyl涨򾞾" YdE)՜TB6uZXYv,{ƹDylK(J3lkie22nhF`Ќzٴ0_֛;L/zN4MQ4CӔigcrϓ'Y9w0 0^ֵvmFzw9y 0_Ad-kݏ_ 5wF]{66`;sv6$>~oXΦ! ~Al %Yem6>knli罨kiN94/cyFhFSNi ti(W錍ɭvm9&MPhO \M2\ Y[Ω8w[ZD__o|r|FBM:ۥ+Ru˪ΩeU@s $tCi_PBD@@ d86gCio9ӹqPtU `QZ_a@@e4ڏƥꎗU4rw#hJw^|{!#hfP̠WN@[ Cu5^9FI[9Xۚk!'Q""w-a!'` qG> lUjmJ.K>^^CAMyNv#͏v}YwgOwgO{]lYd2n43#SζܸRtM+8+n&Q DEh o,x8^fŭ#EfG/6@;"yڢ%p|Kc=Hvæy }Ͳ+>>⡹^wr eyt5Pb3 ,x׍n 9:a/^fǥ7I5 5.#5ΕQBJBwҢKsuEEQJK6TܹSa';IfұG.Vޏ%`!S㥉YeC 4hm9SHvh $z?x^ ͐c BKO-" /k#Skm+M;aӁN5ft梟c;ݟA>f,,EGT3aIϷ5MٯZ.6ۘmѥ hj*59_~@;=qXBxH7&pә=g9j56IB#-gJcG]KQRy&o8SCi:pݓںVzA{U)+!05{" 6pm-8o!6JHSCPa>7vq݇(;Ccf&xG6dhi&c?Z"< \`T*X>kEDlz߯5F q'7?~Qu ~mݒZ%}YRDΑĥj7Ǧ9 EQn*iT)m-@vY<㒲~w_ G# FOȪx G*ʦGsОp8-oz;:@g]v 5:j^vΐ5#6zyTfL%O- ݴVnGʓ>\>66q;ե-[6tw=ɁA3ܓV&RD5'6Wɜ_\3HO8&7SqA5g$C}&ӵZ5h/k6>;j>ֱ=阷,A B$<%;/- QFeu*䬜:>d7wG|y-\6CXxXf2Hޖ8l"V aC94=ԇSdXp4(㆓S I|)=k4T-`9HNbP(V=Czp!dC(V `)lh΃Yeca2dWXц`9 Oh){91b4ޞ1ZOy8 =CO'k.LM-hf\ˌ/}ERG[j,3yw8c{HƾnCtp6hfPCwQ|zQ.͏65Z$j;i͡A3 -$$<8m zJ4siJ DQ hg臜* YE6. CQ?M=^zoero>^iS4\pLjn1HU!#/*GmJ)}3B@k<-i=0v䛥'eI,%h*KAFhOln9.xĬ5^>9 INR)V.2V4h\lp^xȲ Je|_|׹YLb؎ z%oͺ/LS๖5~|s {l5{*[عh&ũށG|.`O )y<ߜ/5Ex , nC^(&)?En<7[w`:[ؑ}l5f<LP3~cBFƅo5 \×j4oܕe2e- z&Ðk 6?F:͸Hzks`;Y_\k;Zhb)ȰeX Ko2gX]%K'kaiE "g@D0E bȆ?@@Ěړ%ҍRY7W; EN]AV379lf##88.Rs{䵮G]EoEQuE?~ϫ3̠(Arg_CK->NK_Cwvv~pB;QyiP~Qyg_ogwn3m6CS̝놬]B)i9143(\;Eu睙nS4E/\UNSMW@ڊĝv)S]D=v^y`{WwO8p y3kūww=~0럿Fn;Ys_;fj ]Rg"\ވȫ&93u{{z_Q m+448 mzF1a{{z{zˢ35Mm6괹u=]†]eh ַtHٸ{gN jwm ҴڋCO;;g y tSڍ.IF(e/ЇH3<044N8iEp"9gwh&z8430hf")mnKS@፥ Bk=0$E4ﷴ*"R 7Ή[ͩt~( KuJQf',jCyEQ׺զF!`i[ Tr N[f rRC]7޴ڔ{8kzM#Q Kzk%g "1(!\DHϦ  }`[KǁA*-sj D$-1mђ Pdr!HM3 2+ ;,{Wem9y>)0$ĖylK BrGn8Y;,˰l.*rA;-;qfW']r~ R@;jaXh'ӇuyϧE_h~ICr 3oUuiyWs޺uKl>B#`8}9ErVl^cz.񸩌W|>rhћ}Q:rXj2"œHSV,5Fi-,KSi^"tNjYj"b#1>>?F8L+ө5 Mhܸ)+qXeNԯY['+X¶KҒMQÝ=BDoܷW*/(ӛJ,8OSM6hSW̦(x[H>yl3mg^Z"XshWAlAXqї'kXniyBvұʇ`ʌ )$tIDATWy0s!2cfH5;˺7[ a7 @ֵoEψ ߳+l[I3r wqβ8b x Ɲvm΍!mYz- wߊzb# h)-H؊tVJ:kxˌ~BfI(HUy]sjLP2n|^"VFiMQ\v]ɖ-\6\)-X_~ﳅBn 5r.-r-ҲP!FSm9_2Pun ^O[M\CߗnٲsfO-SGԩ.7dFMd'g4C|i)CiQN*zBqcP+>P,vDF2'O*g\ G ƒng5.h&41y[o:B}X+'bÀI[+l͋GsOMMYq g zCы S>L>вaB)0;NgK\!`1/2E%,ss?Aeco4Nf,aQv1,%E}4hQ ]t&MS'ϋMeNbuc.R-ϋexR VhKM4-U,Jo #M(؊e, 8,,ʠ*$A!Ԕ}CR>Rl,;dͨV]rsS~8a;+ 5Kʫ OdrY.Ak4_t| KWƋ6&ˌAC()#%XI$+sh^x;HX4VNA f^^vhpHJ4̞ 1D)p5[RޕS ,v-D˸u/)~!g[Dp4S]$1QQhVAO h5o尯XmJE~Fpp.ɫq3/hr&ob~&m"ZdAA{q4hb3ЈNL$F^2^̛h۬Wow)3V^>кM:^E}Lj}^TgmC8Op|devh̋7*oG}xh p xS9xּ7:M yBBаS><-@[o8vh2A4BËi1W1/D7`=Qr[ ATGnxʖ- G44qL} ƼGՠ 32 Nw>~ N6/| ЖFΤ#wv|^Ђz݇ Sy qe憀C_wR^#/eDɗ}VlxNl zY {S/O}xzħ~`ȩɼxS#/tzY)ͼƦ*Uhj˼xˢzYxzjm<G@31FòJuUP{;4>.5mkOz?u(UP,h|4~ < PRT7먠 * *PAT *CTPч *PPu+*DQE͗,:L( ((F3m:M3*PA7bucԵK]<|x}W+w鍤h3Ѻ *0|׵ŧQ/7ԇ *> -84M=i|eY:jXU h╽"C&ފ>Q.̋ *Lp LE]Rч *LxAa-gR2pIZT i͞lY7z~0Y"YA>TP'Ľ&쌹/ۇV  Bː騢STt0*ݏϗ?p `vF0;#xm;!d j\hA}oPA 'O(6EKsV 跚ļQ{aOY3?|1{ K~q'QU*PA"XZy?X9J\xÑ8[6~ժ a{w/0rN ~f+ТʼԆ"*KoYN㶎g̝}7|V_*PA R@y/` 'D ]Pϫ9+ZYZϾw=W 4pcqPU* D72l_l[E۷>{}Vx%xq`هz90`g7[T0h}~#%g.ә\{9;e:*PAO xUчkW}eS_k}}b~8>)xSLL?aT aR^w`]6Ge3b(ϵ+U ʁa}~>3[5^pߏG~34а9v5T *(e](Ja}||X K4Ey5g{=H:;uB>TPA o cßk+\{s>TPA9gq>VTP58>TPAʼ #hU *Ȁ* * #;@} ?#IENDB`elyxer-1.2.5/test/version2.0.lyx0000644000175000017500000000333712074107030015757 0ustar chennochenno#LyX 2.0 created this file. For more info see http://www.lyx.org/ \lyxformat 413 \begin_document \begin_header \textclass scrbook \use_default_options true \maintain_unincluded_children false \language english \language_package default \inputencoding auto \fontencoding global \font_roman default \font_sans default \font_typewriter default \font_default_family default \use_non_tex_fonts false \font_sc false \font_osf false \font_sf_scale 100 \font_tt_scale 100 \graphics default \default_output_format default \output_sync 0 \bibtex_command default \index_command default \paperfontsize default \spacing single \use_hyperref false \papersize default \use_geometry false \use_amsmath 1 \use_esint 1 \use_mhchem 1 \use_mathdots 1 \cite_engine basic \use_bibtopic false \use_indices false \paperorientation portrait \suppress_date false \use_refstyle 0 \index Index \shortcut idx \color #008000 \end_index \secnumdepth 2 \tocdepth 2 \paragraph_separation indent \paragraph_indentation default \quotes_language english \papercolumns 1 \papersides 1 \paperpagestyle default \tracking_changes false \output_changes false \html_math_output 0 \html_css_as_file 0 \html_be_strict false \end_header \begin_body \begin_layout Title Version 2.0 Test \end_layout \begin_layout Standard Some random document for preliminary 2.0 tests. \end_layout \begin_layout Standard \begin_inset CommandInset href LatexCommand href name "Savannah bug 33961" target "https://savannah.nongnu.org/bugs/index.php?33961" \end_inset : Apparently \begin_inset script superscript \begin_layout Plain Layout super \end_layout \end_inset and \begin_inset script subscript \begin_layout Plain Layout subscript \end_layout \end_inset fails. \end_layout \end_body \end_document elyxer-1.2.5/test/with images-1-5-good.html0000644000175000017500000000345512074107030017632 0ustar chennochenno Images Tests

Images Tests

figure elyxer-svg.png First image: regular path.
figure elyxer-svg.png Second image: convoluted path.
figure docs/elyxer.png Third image: from another directory.
figure mini-elyxer.jpg Fourth image: from a JPEG file.
figure square.png Fifth image: from a PNG file.
elyxer-1.2.5/test/mini-elyxer.jpg0000644000175000017500000000304712074107030016256 0ustar chennochennoJFIFddC  !"$"$C2:"0!1A"Q2aRr#Bq'1A!"Qa2 ?죬jɣ 'UўIO@d/~#xCuO_L3M:!5;{{ 5,$}t3,%H)?s~ԋ8$3ΐ?XZ,T5U"OC bF˜9UJs;lz-OC)l$vtvu-5Jv;4UFG`A zquԣ#]`=u:B|^5ixbS~Jʇ ({}18|QSKQfE.뜖Wf0z7\,* DK/y{ Qk멧j(dsPsǼnq c;k]iN,cgl@K`W r"|DheIϗV$*n{|+3IJdD_EEqN6`,4OJr} :ݩ;ܷ.ਹ9U'.rA>ge>{:+_Ը.s!op|~&*6m^+3eɗļov%edvoQi@d+'9}`k<#BB7lJNdU5uSҼBHA7zC2:b\.skK45*ŠWKHV+Ĝ04_WTΪ4;$\/MNzι]]wGU|8?o};:Y8$֑>QDu5B㶧yQDJZ@![vN''2jh@ZoomǸ6Ҿ% u Ӿ,&$q%}smtTI(7=陼VǸܨiW[y7@븐ay = W&\7d۶J)9OW J?kZ-;j[픩MNU$Ē}$l5*4 u4j>:4hCF$@jth elyxer-1.2.5/test/setcounter.lyx0000644000175000017500000000613012074107030016237 0ustar chennochenno#LyX 1.6.7 created this file. For more info see http://www.lyx.org/ \lyxformat 345 \begin_document \begin_header \textclass book \begin_preamble % eLyXer -- convert LyX source files to HTML output. % % Copyright (C) 2009-2010 Alex Fernández % % This program is free software: 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 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 % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . \setcounter{part}{2} \setcounter{chapter}{3} \setcounter{figure}{4} \setcounter{section}{1} \setcounter{subsection}{5} \end_preamble \use_default_options false \language english \inputencoding auto \font_roman default \font_sans default \font_typewriter default \font_default_family default \font_sc false \font_osf false \font_sf_scale 100 \font_tt_scale 100 \graphics default \paperfontsize default \spacing single \use_hyperref false \papersize default \use_geometry false \use_amsmath 1 \use_esint 1 \cite_engine basic \use_bibtopic false \paperorientation portrait \secnumdepth 2 \tocdepth 2 \paragraph_separation skip \defskip medskip \quotes_language english \papercolumns 1 \papersides 1 \paperpagestyle default \tracking_changes false \output_changes false \author "" \author "" \end_header \begin_body \begin_layout Title Setcounter Test \end_layout \begin_layout Standard \begin_inset CommandInset toc LatexCommand tableofcontents \end_inset \end_layout \begin_layout Standard \begin_inset FloatList figure \end_inset \end_layout \begin_layout Part Third Part \end_layout \begin_layout Chapter Chapter Four \end_layout \begin_layout Standard This is the fourth chapter, even if it comes out first. \end_layout \begin_layout Standard \begin_inset Float figure wide false sideways false status open \begin_layout Plain Layout \noindent \align center \begin_inset Graphics filename random.png scale 50 \end_inset \end_layout \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout Figure 4.1 it is. \end_layout \end_inset \end_layout \begin_layout Plain Layout \end_layout \end_inset \end_layout \begin_layout Section Section Four Point One \end_layout \begin_layout Standard This is the section 4.1, even if sections were bumped to 2. \end_layout \begin_layout Subsection Subsection 4.1.1 \end_layout \begin_layout Standard Ignoring the subsection \family typewriter \backslash setcounter \family default statement in the preamble. \end_layout \begin_layout Section Section Four Point Two \end_layout \begin_layout Standard Section 4.2 comes next. \end_layout \begin_layout Chapter Chapter Five \end_layout \begin_layout Standard The last one. \end_layout \end_body \end_document elyxer-1.2.5/test/formula-good.html0000644000175000017500000000222712074107030016572 0ustar chennochenno Formula Test

Formula Test

Inline formula: a = b. Display formula:
b = a.
Numbered formula:
(1) c = c
No more, no less.
elyxer-1.2.5/test/parts/0000755000175000017500000000000012117174767014462 5ustar chennochennoelyxer-1.2.5/test/parts/index-1-6-part-good-Section--2.html0000644000175000017500000000446112074107030022452 0ustar chennochenno Article TOC Test

Unordered Section

Just to show that it works.
And now a list.
  1. First item.
  2. We will embed an ordered subsection here just to fake it.

    There We Go

  3. See if it’s in your TOC.
But There Is More
And nothing else.
Contents for Section
elyxer-1.2.5/test/parts/index-1-6-part-good-3.html0000644000175000017500000000646612074107030021003 0ustar chennochenno Index Test
 Part II: The Additions Up Part II: The Additions Part: Unnumbered Part 

3 Bulk

We actually need a lot more text in order for our index to have more terms; so we can find out if the links are working. Since they are anchors inside the page, they might otherwise just take us to the top of the page, and we would not like that.
Yes, it would be bad for us. But on the other hand too much text can hide errors. So not much more text is needed.
Thanks for reading us.
 Part II: The Additions Up Part II: The Additions Part: Unnumbered Part 
elyxer-1.2.5/test/parts/index-1-6-part-good-Part-II.html0000644000175000017500000000365612074107030022044 0ustar chennochenno Index Test
 Chapter 2: Nomenclature Up Main page Chapter 3: Bulk, or what used to be bulk text 

Part II. The Additions

 Chapter 2: Nomenclature Up Main page Chapter 3: Bulk, or what used to be bulk text 
elyxer-1.2.5/test/parts/index-1-6-part-good-2.html0000644000175000017500000000615112074107030020771 0ustar chennochenno Index Test
 Chapter 1: Explanations Up Part I: The Making Part II: The Additions 

2 Nomenclature

We should explain what an index is. We can do that with the nomenclature. Normally we will want to mix index and nomenclature terms. But what happens if we actually do? We will know later, when we generate the file.

2.1 Reminder

We have to remind the reader that things will be remembered.

2.2 Remainder

Whatever remains should be explained here.
 Chapter 1: Explanations Up Part I: The Making Part II: The Additions 
elyxer-1.2.5/test/parts/index-1-6-part-good-Part-I.html0000644000175000017500000000537012074107030021726 0ustar chennochenno Index Test
 Main page Up Main page Chapter 1: Explanations 

Part I. The Making

 Main page Up Main page Chapter 1: Explanations 
elyxer-1.2.5/test/parts/index-1-6-part-good-A.html0000644000175000017500000000333112074107030021005 0ustar chennochenno Index Test
 Chapter 4: The definition Up Part III: Our Definition Index 

A Appendix

An appendix here, an appendix there.
 Chapter 4: The definition Up Part III: Our Definition Index 
elyxer-1.2.5/test/parts/index-1-6-part-good-Part-III.html0000644000175000017500000000545412074107030022153 0ustar chennochenno Index Test
 Chapter: Unnumbered Chapter Up Main page Chapter 4: The definition 

Part III. Our Definition

 Chapter: Unnumbered Chapter Up Main page Chapter 4: The definition 
elyxer-1.2.5/test/parts/index-1-6-part-good-Part--I.html0000644000175000017500000000366512074107030022010 0ustar chennochenno Index Test
 Chapter 3: Bulk, or what used to be bulk text Up Main page Chapter: Unnumbered Chapter 

Unnumbered Part

Contents for Part
 Chapter 3: Bulk, or what used to be bulk text Up Main page Chapter: Unnumbered Chapter 
elyxer-1.2.5/test/parts/index-1-6-part-good-1.html0000644000175000017500000001065512074107030020774 0ustar chennochenno Index Test
 Part I: The Making Up Part I: The Making Chapter 2: Nomenclature 

1 Explanations

This chapter contains a lot of explanations for terms, which you might want to look up later. Because better sooner than later, although later has been repeated twice. Actually, thrice now.
Do you not want to look any of them up right now? No problem. You will be able to do it later, in the index.
Now we will add two cites in one, just because [2, 3].
As we will see in 3↓, not everything is clear.
You could also look down on someone, but that is not nice.

1.1Magical type face changes in the world

Little more can be added, at least at this point.

1.2Color and colour

At this other point, however, more could be added, but won’t.

Unnumbered Section

They have a right to live too.
  • A list would be nice here.
  • Because it corrupts the next chapter’s beginning.
 Part I: The Making Up Part I: The Making Chapter 2: Nomenclature 
elyxer-1.2.5/test/parts/index-1-6-part-good-Nomenclature.html0000644000175000017500000000427712074107030023273 0ustar chennochenno Index Test
 Index Up Main page Bibliography 

Nomenclature

generate An activity that requires a source and a destination, something like eLyXer does with files.
index A list of terms with a reference to where they occur.
nomenclature A list of common words with an explanation.
 Index Up Main page Bibliography 
elyxer-1.2.5/test/parts/index-1-6-frameset.html0000644000175000017500000000025012074107030020536 0ustar chennochenno elyxer-1.2.5/test/parts/index-1-6-part-good-Bibliography.html0000644000175000017500000000373612074107030023251 0ustar chennochenno Index Test
 Nomenclature Up Main page

Bibliography

[1] WordReference.com: “definition of elixir”, accessed March 2009. http://www.wordreference.com/definition/elixir

[2] W3C: “HTML 4.01 Specification”, 24 December 1999. http://www.w3.org/TR/REC-html40/

[3] W3C: “HTML 4.01 Specification”, 24 December 1999. http://www.w3.org/TR/REC-html40/

elyxer-1.2.5/test/parts/index-1-6-toc-good.html0000644000175000017500000001056112074107030020451 0ustar chennochenno Index Test elyxer-1.2.5/test/parts/index-1-6-part-good-5.html0000644000175000017500000000413312074107030020772 0ustar chennochenno Article TOC Test

5 But I Already Knew That

You were lucky.

I Want My Money Back

There you have your 0€ back.

Completely Unfair Dude

Hey, I didn’t call you here.
A Paragraph For You
Totally uncalled for.
elyxer-1.2.5/test/parts/index-1-6-toc-test.html0000644000175000017500000001056112117174767020523 0ustar chennochenno Index Test elyxer-1.2.5/test/parts/elyxer-svg.png0000644000175000017500000010235112074107030017254 0ustar chennochennoPNG  IHDR_nbKGD X pHYsdd vpAgIDATx}w|iջdɽWt 5!$@H $! ͗PrC rS$Z l{%]q|Z gvfvvy9(Gr!q>r!ӅC9!-rC9[0r`90n#ra"G9øEs!qC}nv۷ottttttJRT… .\̜9s̙sᣍ~@x<x^{5oxcqM7X,xӦM6m_׿50}ӧ!b{o xgy Rp8l6f qؿBP(<3>8]N%X,:uԩSzAhrFٶT*J,^xOӟ{rÍ,}w}z5׈jZV B“W6&D|^>>[nݺu89C:rNQz^೟g?Y3f̘1Cl+Zbz„ &Lo߾}M0\`׾}k^X#ɖ͛7o<`֭[n=ݣCnpPYYYYYyG3> // @@"qF0N,8Q"ljjjjj:묳:ԟo9|#8|ÇE-3-8dIr'[5838Cw99hxㆍ6nn馛nr(#GGqA%fk׮]_$r =p8,Rm."JٳgϞ ̝;wܹms#q ̕ :eZ[[[[[E5믿?ݣCM{ pǎ;vH_/wp`0 ?NG^{}rxqD=BDI:Xexȗ9p,{99|Ks=sb3qx,ǀD2LAV@JR Dqat9ʋ0N5M ywySH$' )gKޠjI!O[t\. CP8}{6dlgȮ]v\r%\r n&nx'H|#W >H>^]۲USؽ{ݻ}s瀫ꪫ:ݣs7s4b2K:N$Ï;-r?9kNh}+_W\p\pV=CP0Ę%x<uH$8tFC ņXAWJljh :@5B<O8_AorDqŸ%@Νc$w$Dwwq{87Fc]+sk7F{--@0lLħFv`}60uqK$@ɖ?ªHėL9o B^/eL9L$B!Z~gNdr8> @3NMa8Csx``OwOwOg$"z[oN;ZZzz\.Z ==N{tp:=@Fcx"8F^Q6ɨ7v֖0aByy~>-mqca?Hr<"})/ 1/2T5fIY%H(X%>(~O\O||>ut w77w> KK+\n7f3{`Lz=i4)P4 `$8mOTV \yg6L~Lt==OvZ( H&c1"HzA{&@h j]PzBҳ8xqK 87567 bx" X,FN,Z4uje%0yrUUa!`Lǚ ? vdb_yE8)AP(J">RZ P(J$7onoVZaȑ~sp^PRRTK~]p՗_>e PPp~7FjTlEcјD>QYOvRbjG"776+WnDxW+_.ILZVI9[irU;zW;Z46 'Vضs"($ .; -) I.ٞ@cAUؒ?4ЬJ%/ZK rV՚@QQQ"~. kp2}D?ڵ֭;vtwC]qt"h(Iq̀Vk4׋9hb`65K/KEaґĵk| o܉ʀYKK`J2+٬k4@UJ%I0iD2IR<hFDbd2-Blk˾JR߫V[{7v`-+w Mm#=Շw:?=UW ɚ YNsDS?Z +*****F}-[}ZZfϮΊ8Rl7Xĉ'N*2l`<d a[`-0 9뮻ɌFcx}q @_Sgח ee!p۳\7L ,P"cbDUWs@_/ ^lTj5:0w~|艏1n .ᅣQvrªU{V\ӫ,,<'%>(G?oF<jl z!.nǭ.]|~`Ŋ+{/뮛>">}iʄ\t(&l b1zaA`fc'_G^O5F r*L:G'd2k׬YBbŋ/ 5W׿h<<ˆqK555555믽k/7ܱhX` ʉU JKm6,G(lB*4^N8>Ea7&eBPXeg"KPr 1z p:~߸Esc悂+>. Ri4aFfh4juxp  7pu3fU4X7FgR-;%%:ߏ 0޳g&薽 ^@ uPzQ]Uէ?կĉf*@کD'MM>D4_׬ M;= p$֖-U^-ȆrcȾcǮ]==d|Km%?yoV{ϣu T$a={zz)/z j.ۏYFlϦΙ3sfi)pyg]SYnX/jjk'LN22f/NG7H"Àӹe˻JtD.W_?V[,v;`6N8 bdkVrDˣ\nO3355TWrz0ɽ,y71A2fS}am:;r/TjupIf̸jihZ|$ |>_4JI+**(3;omBQPd JRT|xmׯXZl08aoX Z^PM'Es䕀^_RRUED' +ަ={#Gx}3f~jq4q'9̂-[P(;Z O8;4D<HdF__kDKx1*c,O-3W"ql4L|`EnXwyɫd/~fL&`Ui2Z`ܹ_sʹiuz2e9sn%R5{WI{er"^$x4tBu5%<6/PbyrT׮_xǀ/&`ڴ|#,Xz玖fS/[;?)N {kى!kabx9aq}^Ri zEŋ}}vZr\ٳYawtwG痉ٖ7})EE…WT+%l{͙S_L#~PU^~?js} ݗZ":m9sPM&EJpx}嗁w |O~~~&Ӌ7< }rc{IE",`0Ղ &y72y 4Kx|!ό+,r4|'m):o8nߗCbK/zdE""9[l;kP^p$J(ɃHھ]BtGmt>_Kˁ"b4y@/.N OmA&˟xڱcZ`˯XUNr(Ljlۓ8$E}rfiVUYcdKL\͈` DPUzad+Yg{WB޻>,ӱl#IRFE#;sY()"8УuFQoAo'R6n|MRY/׭{5 xϱd<hf]pF|8 ѱtق`¿ujbih9Sz2G% <ާ:(GG ue(*cKL@$r,Ejm6%#o|@XvÆtK~\_~2V/o6LNT__P^Eh2F"n|@w7 qΝPRl6W]OWy]x]۷*pHsݔ!~ 孒Iz1BE.)).XrI 's޼y^]N#"A```ݺ_WZ pnL)_p0$N2L&`(-$G}X\}}D|3:ٿ͋o*QZ*prǣ(?(c(vhj/;=&B7V:XR \哟Iʷ3oXq^:q\$HZNG=7(WoojsfΤ:]&fϟ:8%KN9碋(~1s:ɶ:8Hb8,RJdOq(0x,lv՘A {z$UJHuڱc: D"lS*5RY&wTE0u+O>  &ΙL@4j4g\6⓯#8xu0zx$⳥Y,6ĉ@__ooKKLFJZ{@?DJ"dpe/5])"_ VQU*P,>uۺW:/v8"rL-`ʔ"/o tz@omfssڵԸna3#͊%GXΝQ٪+|*+{!I[JdcN71=67wu9@⨱ >0P\&`0kkº:1vM;8 }tÆ'뮻ʩSPRGA_TE[{;vVfR`WXZ,WTdL@^y9>%HQ,ٹCCTvlLuȑ@xJ}|A&zTU}<]q7ڇ] t:E 3OZZIih:֖꫁l4~:lG͛Q|3^;}:pphLR\"Pb)Jںy3wȆ ںe &n"-[xܽGKZģUHz0 ,Ued߿mp={„f}T`Ҥ)Svؾ}ӦnԔ~ .¡u6ShTd2si%%?yf'L+*Uh#GF'AeZMha`vv (_HP 9(|?otf{'Ϝ}NMg>̚UZdɇ_ ;:$F{z3\X'Ϛum@OOwwK =5:75ҋ.jhniq(JS=? @'L&2Uj,8o}Kx&'PsswuIu. ?ȑ  Ob1)14xi!m `XZ֮4iR ~ ꫧwsΩpALώw㜹?1xqmן{48^ cpyٵkE;˓e5{zm_>{vx7F4 uu+Wگ~4665h~rP^^V\~UW}{O}kywݻWBA}m={eFhmݴTw<>wu.׶mk*̙W\h4_ԑZ(bH6p8`0dظnᦦXlz=LՁV/XCK|o[7( ÆqKk*;&M,(s'OِHbCC޽۷o$Jԏ:U9Ef;㌯|j L҆ ZظaPP@ѱe VӎÏ7MM}mFCJ%Gňh2i4dHIBlm=r$6n\k$@@]7PEQFwr 0"*c@8|HlRS Js$(Tc*BA6چ8xpa  (>@a2Io=ZOjz n _N⊥K*=>+(u*x]v٢E RWT9eݺ={ہUvlkBg/ r`T'*ahtwG"@oogg4J )V#"J}K];٬坂lwt(J%WTZsz.gO~̸!p8 ;iR)6*Ѩ̚E&a'\3mR #‹/Ry"A6,ʢqpR TW:$Q*EؔFѐhT"dp8"Jٽ.$SUuPX%'BqJ/BJ>kyT!Kz>kp0YBd8q2Gb1}I T )jMU~M&p/~v-,X|S~'9Bx{/֯߿or`۶ë=J= Jnj/ >}˴bm<( >cQ ۠ /F#"X 0&&I (DT 72`  Ӧ>0sf~>`it [>rٳu+wt $S\v ^r  â$>VJTRQx Wju:l|j5*P\\Zj0-/z{~'7o‚`PJ|,*"t:ry"Et[UU0sfYم<'G^w;;Kׯ`۟SdTV>JT&"e.tf~^O·onu}>RiB"~h4 //?_%O Iq9Z-NfJEq( `ggPTBmoomP0Iz1JˮJGU>E3"RaƬrQ6$ZhT!Z6*Idɮ7&O6nEEڿxزeffh)L&c1tn'U2.W_/I%.䱪S(P[A 55uuf30{y0s9yy驆,:4 v  B()``NP(ZjԪ 74Og9dopz W__0HHfQ*ɓb0 j5e )DR' j4B!z}RT0 E۾{vn3ibMCKO r+|n`׮ěBQ(x\F?Y 5p8 o>ݣz^x lFXLp:Is損#Fi11j+@Q%PIecf'AGGk/kϞ;)LǁŽlljȬ`#$*VD@8];+Wٹ! ?&BCL!" '@wwGG O*<;gXu# ,)-ٵkhT~[LLulZ-5~>^=kOKLH^CGuum<ҥ_DiHdω!H x, ~xnj_yDyG?NTUVĘ'N*{9ۉ8.m`v SQ B}0^dVFYfU!4I@t|1ft>J%_X$b$h&2"BoIYU%ekkK xd\^b֮]b 'On]ORʜ h}{$AS*ǶZ-ۻ曁 .hhE18M5͛z Wz/ єnFLMW%BRX鮻A1_oϼ 2g9A^?}{_g>N2PPihx|۶F/ ӠP'GIIi()"77{-7 o8_Z|=5xgd(ϴ_cyQ R8GDDŽ( ,9J0F/ -J3E]۶ TT?ϦOn_N-[6n<\Q*M&^n@'O;ڵ-_<ҥwTT8& Ru  2zaT#FBQ[ 8&ӝwm8Ip#m|9?TPhӦ/Y:Qj[,ƶ> .rZT@AAq^O*\2 dZVL74$Dj5BP@XrD^bjMl:y8}=tCN*ቜ`,KmBeN  1 /?"(/2EBDz=6 vSbfY;J'4~dR>|U5?[3i#M| ׿z۾ TTLzhӛZ2PXRTR̤*2b0k$PVr=_رM9i\Z{@2cbHm}4 %1zn*6@ l~Z-ep@磔.A|DtVB^[*P* I62%A":@A U|:y>؋G,AJeDT;R^^Yi0&"fhŠ{zC!੧x. `ƌ3v5(i<ġF"ΝnYg6^_Twliۿ{/} | /x ^OKӛ"}{熆~ʭ[FOp 7l>qr0sfU~W'+TORgSU3}_;+X*<>X2E! @jٴZ``/NA Ϫ4KDR"H$,WGIU%! RYF2I*'-(µIR '(*HU9ABVKN^f 8CG"dZhQZm;TxUJJJJt:!ɳ`pX=}` ??H4 SUV-\HFOzAC/WqJJ %Kv]:q2&5=Aw:OJ8p#'H9ƫ$g4vwl9BەJ 3v Y5|]  T;v]G6)RyS%d}t@߁~ʰ`FkJ԰La)T[tD*1r聁P$&"t"@n)$S&{dD+g"Z8KR%@2 QJ|&HZ"@ ǁPHHbaɯ;yOvZ$PPP\l0nEȚ9]]_>e׿/[v]"s$/m66;zJR&qn|+5J,LJu޽$9&hTyWZ5DPGT#;E|| .4?8`45YPA\6@s:[ZK.O T$N?-%>NPFi dcbgYH$u MXlLP, TD`*%^)%@X"#M.踉K"PNlMgN!$g65<Թ"^d԰FF =D+O06[^HIЉݻd@ƙ0N9]o߲ebɨ*,4)=YqzcDP=P*H9~(UrB*FC.KD\ɤqih &^1NǍPJJVoqϋֶm`4mJ 46D BdvldfG}3\ Ι^̦ `@`-Gְ75?2*hLiiyHHWI"epdmfŢVSj pLț6_tjuuT@mCCN'[K}xCDJll߿wߒ-[S>;v{G:$9KIy95xD%~PZJ, vMy  U?XBiDp?M ~` Q'87yR@IɊ5Ւ$w?p DJK'Oa;:LIUؤ!5IH/B;dKg@dnxTOPJ[(D&K<$Ad:/a; S|9U(JޟcmTsu{ PmڨڂA47*S٤!@b8X2: hnܺ4૯n닊J"zb(RJlTeW*dYY$Iңb0h BtV+ U|}]JUPl|,!21TJWTeAe $T.i`7D#g NR؊<:' OF5zhȟI2a0t;)R!NdddI ==ԎHH,ѵ81 ZFTTTWSYf*T_:;NXm>s>F/6;s {9QJeEi?>_El:sv Iy$}{AZVFD@Smy=*5m4(YU8B3DRdB!U~L{eRY"[H2I&@MGBa6j5Zttju^lStHZN @ns{~qr}1IQ6KK:;'M8_B~L0p^oX\Z({R?D8|!c$ IhҔiDj4 \bJ|lz'*K V*bNh繐j4JĞ)%dN6iJpߧ`;JR<^T*-XHE"4j%G^U<^T(L6L7?  Kw0r'?TN ."k(Dc̉L<*Hq r! JI׋WS y4AGKŒ+4%D5ĒIH_\.RWG,r> ddxhQTeh4_I It_89%'4X hnnj2щ%k}h ܩϓVKϪ5+k!YJPL$V9rxd5b` l3o߫>tSXC8sܹ4řc0h&'M*i&',J@ydp륪!΋E7GVeF"HB@(DK ;bT y(\QRIi?4e ӕRXI(TE%B(T%l\D}K:/pRɃT49#K-ORN|&B^τGi=%gyy: ($6*P3q$|f/1{;x<ce4z{C!a ;-_tnNDǑ~,DVS}EzstY#5e8`0M jmo~3mM4DE,Qqݥf|H#$=yGj"P(lOW5<`RNnl`c{ 'vԼSx< %FJ:* 9^-U*T9U*)5,sNUǤIV<1Ye@/%TL 8N0UU6""? b!I$+&>}rqv>n7IB"'$@~ޥrgiJ=?,#uNI`.h8(HBVL$nڲe?iij{A{* όVj3yDTa'"Y:X.GMڀj 91Q*8ZRAu:D(xVXLxh(Cի)BΓbjK( 񥄗}:eȽ,tDC#cI/l7,ҁD|Lrp _BN2A\4rUZlHU'aM7D\c(G/t0Z-9J+V<T?ko߼()۫iY$~ vǶL<Z#].%OkKi,FUV6iWRR^NKxs3RD~Ng2Q|"DJB^lė:AK|3R,R9P<]-Z2/oɍ bI&+v6-$@&}SCn4 FC2#9];S#֥*/{}Z2c-t:K*-2SJJHjiz.ZF#ߧRYPOkΛF7oӟ/{H/*yp]6 &KANxY,qcd#OSHǪn(DҺR MRﱔ4ӥ-1&]!ᴍ 382|}+)O/֠OH#pB`0śTzLCdBFB: VVr[ʽ{ ?*1Rl0)ҿ=SA94*>qƍ}G5i<ѨVϞ-p< /] ;2?F6}Pz< FKτ;zER9Fcc=WYᣉ@^ ەXiJ RQAuV$B^hqwma%2wX,)DJ-*H"Vyt:A:-Y ?$kbω`2鴣ߝFX(HA_*Rĉ{g~\, UEvVYF`XbɖpPА-ˏ̽ h,*@HRe44l@cYgu$NR%%FwK8ҥhqUe;bة {z߱Ty]rY~hVBD"ҏT@5ZKK?a2i4v `x8^x"7h!̈́ɬ*Ht A^ c|(%%[JE>EeE?6-z2`P#jJ-m h?};,'p(セ1ADJ$wcv`'zƩkEE9rQDRE!+`dqHX2eܦ'Ɨzq:Z-OZہ P6FdpE9M%H~@r=xkkI=NXHRtLldbjkt"XHt:=㱥UV⋀^WRRU iZNq(䁜)_X,`0PCFla6F٬5?cÇNNWT 8Dª7K^MqVU z<ҥZM9UUz=Ida*1:W`vq3K_8L,Yd[ @6Czf!L&S(D}*>'tY>__KS>pz}Qi #r"}uqhI$@Yu OMj6fA=#Դ2hB )3`t:b2YkV T`#'.u?vu:*uri~x8liiy ȑ;j?ni`@jj|>"&GU(Dd~ImP<+_>C*!& S(rr'L0hVj)m%T Xk# e`B$Y !¯JDx\Η$H&nBJKȴnk'ʺq#EV*IEDZ"nN;#o-*|Yu-553g<`AAUUmmm]v" |iJp̜Iq~ TRUbq>?vfsYىd:Dcxbd"DE#ܷ{`u̵׺\j5p?meeݟ[V+TB6S9<*+kjF`'_JEeL&Q .`Pt5yA4e #?ݝPq :T;x< eEu25TEy7:;>>K~逩^\>89^ӈZtS.X(r$d vvw[;.L៩~쟤7$<#ҚF"c~rHU{loip/⭷\py@II~P$ \w(Fs|BhQ9m#[N?%pn6{K^MX(m"AeZ/]fޟwzz#G={:;{$a`"O.V% @&' --@4g? I"|DO&MIJ4Z-`v;0}̙f3@yZ- d [J %pD,f`Lz}SbD 2)7olI뼬(H\B-/O9p}Q,B {Mk/l|G;kFAɳfz= ]xRm(,u Ӓ|, Jņiaȝ&%\nj0z0FJ|ttum~w={zG3oEN!ذa޶6`Φƞn"YU˩w DƍN:=$IPrȶakWGǪU R C]ڨ8|h^{hmA pV@yUUF#I^옪Ȼ54@iiYNTWqW6ljez^r: GU)lDK.tK! #s+WbKZJ or$TVJ3g8טWJ-zfauO&¨fKŵu31[$\t[jŋUr2Mq>paUƍ#ѨѨEcҥT';M,2"Bi@Ԯ4a18ON-Cj H؋ӯAD'I&KyJ|]]pÛ.<|1Ό<sΙ6M,N'rAAa`@$@iIg; С3hޠT*RACzzl )SiO)i0ş\1I0UU*[[Rw72k֜9V+x [JaljPȄjG/Re\6KHxS)%+B);tI$@aaQNG6Pv<^:b^΅PY2TDB I=l{$HV!co/ Xp3Ϥ N5b ++kC^07XRDtL 0 T*Rْ&i~JPg9HW==D4k;'}Wx߳ /GB08448ʕ?P*zDJJK' L^wwv]Kہbry:`DRՏX|(Ǜؾ}ŏ=xxg[,D%I~8MdDK|KcBSSOvZEH6B~BcF3 yq@N _4YF*5m#0WM{ >55f-Xp,h{JIq~vIdhhOnJN4&rg41F l?'vLؾRp* csZ~lLjp`I2z5Zb:FHx)vW(h$˜VӧSRYQ{"%wزԃ'o~SS#4={v ׬q+!:! $h4xU]8%C*u=g8Yt%Vs]7mS،$?燎gSXxH2~:_$^75Ӧ{ɈQ'M9Ng*~?tM 7߃RQEpO# YT:r x3e0Q eeTh2^.{.SJK]8Y@$y<=/'c„S`ɏl\:]& g̡C==\v;U>Ldqj2އBC`0(BBb]IrRK]/]‡"#E& Tdj?Y’K*1WnfIKIӦLvl>0 Q^zEԁO5TR6Gk>;2"yyBq )?!эFi [Z n1+--"p:} P=ɶ>jK,WIFMG7n|s{4A'qϞe˞zh?e@2I u:!4!B!S`8& 0k0ejjtK)*, k!AjuK|I=_x2jt9^hRh%KV˯xMM=*,0+l}m!./! FjbTﱨDɋt DE18HpX*@M 90Y\wnRR2G0.AKjk9UU?80m 7qo]K>%I|PyS&x?UEE',~2Q$EM6s}ܹf3tRh$7{RPas*f1 /y4!ǒW(CF**lGG{{8  PZZZRsAxzYVtd`s!Abbft*FÒ?1p- @f?X0 `ʔ9sK./} 0O@gmu[԰|NǮ]O>@4>bOϞ=[Tn`0$Rl&۞NG̑oյwxa p8j Z-{{)0yǎwZ[Lh:u:n*x6_i)l~ʿ-uwXhʶn| (-\**@.lp`a'ѦV+l6MExs?j2!†(H364f3UTh I˶! FEuk` #I1?JP(:S(W X Y/E=+=d2[cמyX!ipY4z=%ld0)BҜI^JmCM Hi(x}j-uƷDFC //۵cӟ.ՕI3/,-R*>J :;ID0 RRbO'W@2Ҁ]cǕ>1BM/(=^__ooWrĉWW"MD%U-v[N Vat:ZWU @M IDeeZ-e 9Mf .((,s!3Kiy*ytTl6Tde%|`9ϧ;%75F)Ӆ{q_bi sx {zIp)Kn2~憻,'Vqzڀ^OnشiMp]6Evzz]K'T0SG f:2h+us:6:\M/Jp0.6" c^{DeLd0gpDrbd㔼VJY(Jaƌ'._\q1j8t:nMoJJ,ڹsF cR'h@JEejJr D:A* )`D}9RbsS0`kJ7 dv«Jٹi;;wֲeb'W=\YcDTTSL⥑>nL5Rl媶j˥.0ֶn]Gw!G|3dDό|R*IsFIuum^Db2E"c;,5 iixTqb,) )t @TiqWS3a> [PqI"xSonO?hO1"&LX1kVs}qbD/h9_ⷿ ф}~~7mHu9epb{0v@8gO(vHe0Rɽr/S$U{Es Fܗ^\8*ǁΎzޔ {}}]] F#Kσ|U*N60y8^IՕ:rpR| k׶ڦ:lQ(Hh|o"[}餶՜k)nWH [Z_ճ{En/*ߗfR#![j`gg B􍊊*VGD\܀$3)$BAvSMƷd^+8oRT.'٪&L>s_1󥗞xxeo~s@{vgjN?tH&hh0lF#_[k6Fwi"R5f*tؘ'"3^  xrښɓ.eM]8Z2=eG "LUYq3ŨtZ-RR=.WkkOb˯_Lq#W\t)޾`}@7IsOtbdAA2V Px B9t|&<&'Y^_ R4J{mm]gV%[wo>/nQ '@[*Uy@E>_?XA5Vr2ߚ)S[s'wկ`zu#cHL,ÔN)MfsQ 64XNGHٛ+CdOZomm@oΝl")綱kjjoO=V)#b63?~:qF&N>7<M{hfwW2ifi^bV1K(((*R)CmDBZLzF<'u4'%{_s$$Bg dTP({|~>z{{zb1{)xG̹xɑ}B9T0NrԜ'? |snoӟ+W>? x\Llr3[U&XJ2 47Q̘QXt"ud:ommkh\\V*1r"L?gFVKe,&$T\Rmx6ML blSsG&*#mm@WlGRՍFϿ.70|p5ӧ;@MM^ތ_w+=6̘̙p!l19溧ԌFʵM$HӑK98,lU|J|RA Cx|wP)/Wn/g|S-N;2Zf.{Gᢋ x{vׁ޾tHNt"d)%nQlrhC%m.6HP\. *񉭀TRRY>n:͖=a.R5=9TrTz6eLp[Iv=~UZf+~Lp饟{g./brJGn طoښ'NL̙$2qlv;U:fJTwI)Hj3(:RsYpST^$/59mD?"dqw::(0zma ),|]o|yep,p̩;QfϾjή.@d$gV2mE"=kٜfj)_<D"dA M=l*g3$(*Zq7󟓄*-x<Ν/@0#ȽY" DŽ 4)=Y!!|>_j5OZ\KNQ;&8s'LF*() 8|xRJR(D01Ll{qg{(@To<IS*oOtົ;:q`ݺիC!P(.+_.kL&;9'lc NN8Fc+<46C7 |Nunsj@*{zdL|oD^/PJxߗ~f |0.ߟ{nM  RэghDQvh .30 }j8|]nu&K-^ÿ=3K_~:kɒS~$vK}+wZD׮Ofxx" u:t;L;9 )qR\EػKKqfH z$p=0gT6mk+` s3ޟUUyyӎ2\{p]7LD#UISc'/A᱈G S__(+>}޼3y763̆t[`vJ> hFF_0x@ t|ُmKv9poo/|xBӟ_߱gHd; $mmKEE60y) 0u*j)$9W!2<؎M|ݱx@8 45ZBlֶlf 8Hb[fJe,sM(..- jX BA8NQ\rq;8ߟH(`4Je~~c#־ PR<{p0pS6>H$(+7~/X._Dc%̟E|+?|T⬫;.7y y>nyݞdTFOq_ /]{^N`֎W_}=-[u\@;H&'NI"ˤksȶiJnJ%׃ *6@2pUUW +*IqZhh(('>6`"\ԧիW^F8^[Xs*omYg.Y|hzzdžիہw}^N nl8MFWxׁөD2]]5Œ)IDATOc#47a @(|G%Qֳ^VMޠј̀Ţ9$UVVk}PVf?tn|΁Kի6nܺu۶LG&cUyJJop%?ħ>$r_z閛/صOSJIc%%Βb٠x룏>M+V<r![E٬T{B…3ft7TTqƩq@sHA, @o]7I]6M0e PR2gYgQt_E99!->?d9Ç9!-rC9[0r`90n#ra"G9øEs!qC9!-rC9[0r&dk8%tEXtdate:create2010-01-22T02:44:07+01:00ZrUk%tEXtdate:modify2010-01-22T02:44:07+01:00+/FtEXtsvg:base-urifile:///home/chenno/projects/elyxer/test/./elyxer-svg.svgV#IENDB`elyxer-1.2.5/test/parts/accept-all0000755000175000017500000000221212074107030016367 0ustar chennochenno#!/bin/bash # eLyXer -- convert LyX source files to HTML output. # # Copyright (C) 2009 Alex Fernández # # This program is free software: 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 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 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # Alex 20100419: accept all splitpart test files as good echo "Accepting all eLyXer splitpart test files as good" echo "You should only do this if you have made a large change in all test files" echo " and you are sure that all files come out right!" # do it only for splitpart test files for oldfile in *test*.html; do newfile=${oldfile/"test"/"good"} mv -f "$oldfile" "$newfile" done elyxer-1.2.5/test/parts/index-1-6-part-good-Index.html0000644000175000017500000001247512074107030021705 0ustar chennochenno Index Test
 Appendix A: Appendix Up Main page Nomenclature 

Index

able:

anchor:

error:

explained:

hand:

index: , , ,

later: , ,

link:

look:

down:

up: ,

page:

remembered:

sooner:

term:

terms:

text: , ,

thrice:

top of the page:

twice:

 Appendix A: Appendix Up Main page Nomenclature 
elyxer-1.2.5/test/parts/index-1-6-part-good-4.html0000644000175000017500000000636712074107030021004 0ustar chennochenno Index Test
 Part III: Our Definition Up Part III: Our Definition Appendix A: Appendix 

4 The definition

A TOC is a Table Of Contents.

4.1 But I Already Knew That

You were lucky.

4.1.1 I Want My Money Back

There you have your 0€ back.

4.1.1.1 Completely Unfair Dude

Hey, I didn’t call you here.
A Paragraph For You
Totally uncalled for.
figure elyxer-svg.png
Figure 4.1 eLyXer logo

Unordered Section

Just to show that it works.
And now a list.
  1. First item.
  2. We will embed an ordered subsection here just to fake it.

    4.1.2 There We Go

  3. See if it’s in your TOC.
But There Is More
And nothing else.
 Part III: Our Definition Up Part III: Our Definition Appendix A: Appendix 
elyxer-1.2.5/test/parts/index-1-6-part-good.html0000644000175000017500000001127212074107030020632 0ustar chennochenno Index Test elyxer-1.2.5/test/parts/index-1-6-part-good-Chapter--1.html0000644000175000017500000001260512074107030022432 0ustar chennochenno Index Test elyxer-1.2.5/test/template.html0000644000175000017500000000076612074107030016020 0ustar chennochenno <!--$title-->

(C)

elyxer-1.2.5/test/languages-good.html0000644000175000017500000000171412074107030017073 0ustar chennochenno Converted document
This is some English text.
Esto es texto en español.
elyxer-1.2.5/test/file-1-6-good.html0000644000175000017500000000345012074107030016344 0ustar chennochenno File Test

File Test

Created by Alex Fernández

This document was created with LyX 1.6.2rc2, a great text editor.

Part I. The only part

1 The First Section

With some text. And a greyed out note.

Another Section (Not Numbered)

With some more text.
Now we include a different document.
Hello world
And now a verbatim include.
Plain text document.
  To be included verbatim in a LyX document.

Do not modify unless you want to test something.


Index

elyxer-1.2.5/test/toc-book.lyx0000644000175000017500000001031012074107030015554 0ustar chennochenno#LyX 1.6.7 created this file. For more info see http://www.lyx.org/ \lyxformat 345 \begin_document \begin_header \textclass book \begin_preamble % eLyXer -- convert LyX source files to HTML output. % % Copyright (C) 2009-2010 Alex Fernández % % This program is free software: 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 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 % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . \end_preamble \use_default_options false \language english \inputencoding auto \font_roman default \font_sans default \font_typewriter default \font_default_family default \font_sc false \font_osf false \font_sf_scale 100 \font_tt_scale 100 \graphics default \paperfontsize default \spacing single \use_hyperref false \papersize default \use_geometry false \use_amsmath 1 \use_esint 1 \cite_engine basic \use_bibtopic false \paperorientation portrait \secnumdepth 1 \tocdepth 2 \paragraph_separation skip \defskip medskip \quotes_language english \papercolumns 1 \papersides 1 \paperpagestyle default \tracking_changes false \output_changes false \author "" \author "" \end_header \begin_body \begin_layout Title Book TOC Test \end_layout \begin_layout Standard \begin_inset CommandInset toc LatexCommand tableofcontents \end_inset \end_layout \begin_layout Standard \begin_inset FloatList figure \end_inset \end_layout \begin_layout Part Our Definition \end_layout \begin_layout Chapter The definition \end_layout \begin_layout Standard A TOC is a Table Of Contents. \end_layout \begin_layout Standard \begin_inset Note Comment status open \begin_layout Section Hidden Section \end_layout \begin_layout Plain Layout This section should be hidden from mortals, and from the TOC. \end_layout \end_inset \end_layout \begin_layout Section But I Already Knew That \end_layout \begin_layout Standard You were lucky. \end_layout \begin_layout Subsection I Want My Money Back \end_layout \begin_layout Standard There you have your 0€ back. \end_layout \begin_layout Subsubsection Completely Unfair Dude \end_layout \begin_layout Standard Hey, I didn't call you here. \end_layout \begin_layout Paragraph A Paragraph For You \end_layout \begin_layout Standard Totally uncalled for. \end_layout \begin_layout Standard \begin_inset Float figure wide false sideways false status open \begin_layout Plain Layout \noindent \align center \begin_inset Graphics filename elyxer-svg.svg \end_inset \end_layout \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout eLyXer logo \end_layout \end_inset \end_layout \begin_layout Plain Layout \end_layout \end_inset \end_layout \begin_layout Section* Unordered Section \end_layout \begin_layout Standard Just to show that it works. \end_layout \begin_layout Standard And now a list. \end_layout \begin_layout Enumerate First item. \end_layout \begin_layout Enumerate We will embed an ordered subsection here just to fake it. \end_layout \begin_deeper \begin_layout Subsection There We Go \end_layout \end_deeper \begin_layout Enumerate See if it's in your TOC. \end_layout \begin_layout Paragraph But There Is More \end_layout \begin_layout Standard And nothing else. \end_layout \begin_layout Standard \begin_inset Note Comment status open \begin_layout Plain Layout \begin_inset CommandInset index_print LatexCommand printindex \end_inset \end_layout \end_inset \end_layout \begin_layout Chapter \start_of_appendix Appendix \end_layout \begin_layout Standard An appendix here, an appendix there. \end_layout \begin_layout Standard \begin_inset Note Comment status open \begin_layout Plain Layout \begin_inset CommandInset bibtex LatexCommand bibtex bibfiles "bibtex-plain" options "bibtotoc,plain" \end_inset \end_layout \end_inset \end_layout \end_body \end_document elyxer-1.2.5/test/rabbit-walrus.svg0000644000175000017500000002462712074107030016620 0ustar chennochenno image/svg+xml elyxer-1.2.5/test/math-1-6-good.html0000644000175000017500000013070412074107030016361 0ustar chennochenno Math Test

Math Test

1 Limits

A limit:
limx → ∞f(x), 
which should appear as x → ∞ in italics, and «lim» in plain style. Inlined: limx → ∞f(x).
And why not, a sum:
i = 1ai, 
where the sum’s limits should appear below (i = 1) and above () the but to the right. Inlined: i = 1ai. Integral: x = ax dx. Display mode:
x = ax dx.
We can also integrate without limits: A dx.
A sum inside another element (red color):
i = 1ai.
The placing of limits can be cofigured with the \limits and \nolimits macros:
limx → ∞f(x),  i = 1x,  0f(x) dx

1.1 Super- and Subscript

When any element has both super- and subscript, they should appear like inlined limits, one above the other: a34. Also before an element: 32 He. In display mode:
i, jaij + i, jaji = iaii, 
21 H + 21 H → 32 He + 10 n.

2 Numeration

Equations can be numbered, like 1↓.
(1) y = x
And also like 2↓.
(2) x = 3
Notice that eq. 2↑ comes after eq. 1↑.
Some equations can also be numbered, even if they don’t have a label.
(3) x = 2y
Other equations that contain * should not numbered, but perhaps aligned:
left right
Some environments allow for multiple labels:
(4) a  =  b × c (5) c × d × e  =  i.
Now a random environment: x y.

3 Brackets

An array:
12 2 3 4 × yx
And an inline array a b c dio .
Arrays are separated by variable-size brackets: a b c d a b c d a b c d a b c d ||| a b c d |||which might also differ on right and left a b c d or use the empty opening a b c d or closing: a b c d |||. There are also fixed-size big brackets: (a) [b] {c} d |e| f.
Aligned brackets can be present: (toText). One of them may be omitted: toText).
Aligned brackets can be applied to complex items:
s × 1 +  a11 a21 a12 a22  ×  1  − 1  − 1  − 1  +  1  − 1 0  − 1 1 0 0 0 r .
Math brackets should not be mistaken for TeX brackets: ({s(x)})/(2).

4 Fraction

A big recursive fraction:
(1)/(1 + (1)/(1 + (1)/(1 + 2x)))
A nice fraction: 56.
A non-diminishing fraction containing alignments:
(1)/(1 + (1)/(1 + x) × (1)/(1 + x)).
A similar concept is a binomial coefficient: (A + 1B). It can be prettily presented:
AB + 1.
A symbol can be stacked over another using \stackrel: xR → y. Anything can be stacked: headheels.

5 Roots

A square root: (3). A root in a fraction: (((78x + 45y) × (Height))/(sin(x + 1)) + 5).
A more complex square root in a fraction:
(1)/(1 + (2)(1)/(1 + (2)) + ((1)/(2))).
Higher order roots: 3(x + y), x + 1(Weight). In a fraction:
(78((8)/(4)x))/(s + 5(((78x + 45y) × (Height))/(sin(x + 1)) + 5)).

6 Decorations

6.1 Cases

Used to switch several values.
y =  x i = 0,         x + 1  i < 3 
Cases may have more than two rows:
f(x) =  0  x < 0,         ∞  x = 0,         0  x > 0 

6.2 Braces

Values can be underbraced or overbraced.
a − b = c + d + e + f.
Underbraces and overbraces can contain text.
a − bover = c + d + eover + funder + g.
They can also be inlined: a + bover.

7 Spacing

The command \raisebox is useful to, surprisingly, raise a little box,
raisedoverlowered and back.
Like \mbox, it puts its content in a text box. It can also be used just for spacing:
BV.
There are other spacing commands: \hspace a b, protected space a b, and at “block level” \vspace: a b.
There should be 1 cm of vertical space above this paragraph.

8 Fonts

This section tests font support.

8.1 Variables and Functions

By default, letters denote variables and are taken from the \mathnormal font, which is italic: αx + αy = α(x + y), with the exception of upright capital Greek letters, G ≠ Γ. Letters run together represent different variables: abcd = a × b × c × d.
There has been some trouble over some commands like Greek letters; some of them should be italicized, as in: μ or Å. Others should not, as in Ω. Upright Greek letters are also available: μ ≠ μ. An example from the LyX math guide:
π +  → μ +  + νμ.
Functions names should be upright: sin(2π), log(x), tanδ.

8.2 Mathematical Fonts

Mathematical fonts used in equations include Roman (\mathrm), Sans Serif (\mathsf), Typewriter (\mathtt), Bold (\mathbf), SCRIPT (\mathscr), CALLIGRAPHIC (\mathcal), BLACKBOARD BOLD (\mathbb), and Fraktur (\mathfrak). For the latter, some single characters are translated to their Unicode equivalents: , 𝔽, 𝔉.
Regular text in a formula can be achieved via text font commands like \textrm: 5  to 10, via boxes like \mbox (prevents line breaks): 6  is more than 5, or the AMSmath \text macro (scales like math symbols) basesupersub. The content of an mbox is processed in LaTeX text mode. This allows text font commands, e.g. a switch to sans-serif-bold-italic, or the phonetic alphabet: sfbfit, tipa.

8.3 Units

Units should be written upright, either with \mathrm or with macros from the units package, e.g. as simple unit, km, with magnitude, 57 km, with fractional unit, 200 kmh, or with a fraction before the units, 32 km, (7)/(16) s.

8.4 Sizes

Sizes can be specified in formulas: display, text, script, scriptscript.

9 Colors and Boxes

A colored box: aaa.
A framed box: box. It can be aligned left: box or right: box.

10 Macros

Definitions can be added as macros. Then they can be used in formulae: (12) + 1(2).
Macro definitions can accept default parameters. Again, useful in formulae: 4(5). Default parameters can then be overriden: 5(y) + x(4).
Other definitions from the preamble can be used: 3(4).
Definitions on the fly are also possible: 7(8), and used with different values: a(b).
Macros may contain a literal parameter. It should parse correctly: t.
A macro with four parameters from the LyX detailed math guide. Now in use: 1 + x1,  2 =  − ((1 − x))/(2)±(((1 − x)2)/(4) − 5) − B.

11 Pathological Cases

Empty equations have been known to fail: .
An equation with an mbox containing a comment: text more, and a comment inside textrm: text more. Finally, a comment at the end of a text function: only text.

12 Bye-bye

That’s all folks!
elyxer-1.2.5/test/abstract-good.html0000644000175000017500000000217412074107030016731 0ustar chennochenno Abstract Test

Abstract Test

Abstract

This document is a test of the abstract capabilities of LyX.
When exported in LyX, this abstract should be shown contiguous.
Apart from the abstract, not much more yet.
elyxer-1.2.5/test/setcounter-good.html0000644000175000017500000000600512074107030017316 0ustar chennochenno Setcounter Test

Setcounter Test

Part III. Third Part

4 Chapter Four

This is the fourth chapter, even if it comes out first.
figure random.png
Figure 4.1 Figure 4.1 it is.

4.1 Section Four Point One

This is the section 4.1, even if sections were bumped to 2.

4.1.1 Subsection 4.1.1

Ignoring the subsection \setcounter statement in the preamble.

4.2 Section Four Point Two

Section 4.2 comes next.

5 Chapter Five

The last one.
elyxer-1.2.5/test/subdir/0000755000175000017500000000000012117174766014620 5ustar chennochennoelyxer-1.2.5/test/subdir/appendix-1-6.lyx0000644000175000017500000005244412117174766017500 0ustar chennochenno#LyX 1.6.5 created this file. For more info see http://www.lyx.org/ \lyxformat 345 \begin_document \begin_header \textclass scrbook \begin_preamble % eLyXer -- convert LyX source files to HTML output. % % Copyright (C) 2009-2010 Alex Fernández % % This program is free software: 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 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 % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % DO NOT ALTER THIS PREAMBLE!!! % % This preamble is designed to ensure that the User's Guide prints % out as advertised. If you mess with this preamble, % parts of the User's Guide may not print out as expected. If you % have problems LaTeXing this file, please contact % the documentation team % email: lyx-docs@lists.lyx.org \usepackage{ifpdf} % part of the hyperref bundle \ifpdf % if pdflatex is used % set fonts for nicer pdf view \IfFileExists{lmodern.sty}{\usepackage{lmodern}}{} \fi % end if pdflatex is used % for correct jump positions whe clicking on a link to a float \usepackage[figure]{hypcap} % the pages of the TOC is numbered roman % and a pdf-bookmark for the TOC is added \let\myTOC\tableofcontents \renewcommand{\tableofcontents}{% \frontmatter \pdfbookmark[1]{\contentsname}{} \myTOC \mainmatter } % redefine the \LyX macro for PDF bookmarks \def\LyX{\texorpdfstring{% L\kern-.1667em\lower.25em\hbox{Y}\kern-.125emX\@} {LyX}} % define a short command for \textvisiblespace \newcommand{\spce}{\textvisiblespace} % macro for italic page numbers in the index \newcommand{\IndexDef}[1]{\textit{#1}} % redefine the greyed out note \end_preamble \options intoc,bibtotoc,idxtotoc,BCOR7mm,tablecaptionabove \use_default_options false \language english \inputencoding auto \font_roman default \font_sans default \font_typewriter default \font_default_family default \font_sc false \font_osf false \font_sf_scale 100 \font_tt_scale 100 \graphics default \paperfontsize 12 \spacing single \use_hyperref true \pdf_title "Appendix Test" \pdf_author "Alex Fernández" \pdf_subject "Containing Numeration and Other Appendixy things" \pdf_keywords "LyX eLyXer" \pdf_bookmarks true \pdf_bookmarksnumbered true \pdf_bookmarksopen false \pdf_bookmarksopenlevel 1 \pdf_breaklinks false \pdf_pdfborder false \pdf_colorlinks true \pdf_backref false \pdf_pdfusetitle false \pdf_quoted_options "linkcolor=black, citecolor=black, urlcolor=blue, filecolor=blue,pdfpagelayout=OneColumn, pdfnewwindow=true,pdfstartview=XYZ, plainpages=false, pdfpagelabels,pdftex" \papersize default \use_geometry false \use_amsmath 1 \use_esint 0 \cite_engine basic \use_bibtopic false \paperorientation portrait \secnumdepth 3 \tocdepth 3 \paragraph_separation skip \defskip medskip \quotes_language english \papercolumns 1 \papersides 2 \paperpagestyle default \tracking_changes false \output_changes false \author "" \author "" \end_header \begin_body \begin_layout Title Appendix Test \end_layout \begin_layout Author Alex Fernández (elyxer@gmail.com) \end_layout \begin_layout Standard \begin_inset CommandInset toc LatexCommand tableofcontents \end_inset \end_layout \begin_layout Standard \begin_inset FloatList figure \end_inset \end_layout \begin_layout Standard \begin_inset FloatList table \end_inset \end_layout \begin_layout Part Of How Our Hero Came and Went \end_layout \begin_layout Chapter The Coming \end_layout \begin_layout Standard Our hero came in. He was tired. He thought the world belonged to him. \end_layout \begin_layout Section The Meeting \end_layout \begin_layout Standard Our hero met with Laurinda. She was smiling. But our hero was not amused. His whiskers were dripping wet, he was astonishingly thirsty, and the contradic tion was killing him. \begin_inset Quotes eld \end_inset Give me some beer, woman! \begin_inset Quotes erd \end_inset , he ordered. \end_layout \begin_layout Section The Melting \end_layout \begin_layout Standard Laurinda smiled again. \begin_inset Quotes eld \end_inset But Wenceslau, you don't belong here. \begin_inset Quotes erd \end_inset What a stupid thing to say at that precise moment, our hero thought to himself. Only that it came out loud. At that precise moment he knew that the desired beer would not be forthcoming. \end_layout \begin_layout Standard He turned to the bartender and tried to obtain a beer by the very old method of purchasing it. But being ignored was not one of Laurinda's specialities. \end_layout \begin_layout Chapter The Going \end_layout \begin_layout Standard It could not last. Laurinda's hips were flapping, and she was hopping mad. \end_layout \begin_layout Section Our Hero's Imagination \end_layout \begin_layout Standard Our hero imagined her as a rabbit with long ears and a fine set of tusks. In a short time the image drifted to a walrus, and our hero could not help letting his sinister smile giving him away. Figure \begin_inset CommandInset ref LatexCommand ref reference "fig:rabbit-walrus" \end_inset shows a gross approximation of the rabbit-walrus. \end_layout \begin_layout Standard \begin_inset Float figure wide false sideways false status open \begin_layout Plain Layout \align center \begin_inset Graphics filename rabbit-walrus.svg \end_inset \end_layout \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout \begin_inset CommandInset label LatexCommand label name "fig:rabbit-walrus" \end_inset The rabbit-walrus. \end_layout \end_inset \end_layout \begin_layout Plain Layout \end_layout \end_inset \end_layout \begin_layout Section Laurinda's Anger \end_layout \begin_layout Standard \begin_inset Quotes eld \end_inset Wasn't it great \begin_inset Quotes erd \end_inset , said Laurinda. Actually she said it in the present tense, but our poor storytelling skills have changed that to a cheesy past. Don't do this at home, kids. You want to be regarded for your authenticity, and misquoting isn't going to help much. \end_layout \begin_layout Standard Anyway, back to the story. Laurinda wanted to hit him in the head with a big ham that she kept just for occassions like this, and being a solid Hitchcock fan she was ready to cook the ham afterwards and serve the resulting stew to any policemen that might come by. She was also a huge Almodóvar fan, but she was unaware that in an early film the divine Pedro had copied the scene. Actually both directors had copied the idea from a short story by Roald Dahl, very much worth reading. Although it must be said that in this story it was a lamb leg, which hardly offers the consistency and stiffness necessary to kill a sturdy husband. \end_layout \begin_layout Standard But who cares. Laurinda meanwhile had a funny appearance; if you want to see why please direct your eyes to figure \begin_inset CommandInset ref LatexCommand ref reference "fig:anger" \end_inset . \end_layout \begin_layout Standard \begin_inset Float figure wide false sideways false status open \begin_layout Plain Layout \align center \begin_inset Graphics filename laurindas-anger.svg \end_inset \end_layout \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout \begin_inset CommandInset label LatexCommand label name "fig:anger" \end_inset Laurinda's anger pictured in a mildly humorous tone. \end_layout \end_inset \end_layout \end_inset \end_layout \begin_layout Standard And yet, how furious was really Laurinda, whom we may optionally refer to as Melinda from now on? Table \begin_inset CommandInset ref LatexCommand ref reference "tab:anger-time" \end_inset vainly attempts to quantify it. \end_layout \begin_layout Standard \begin_inset Float table wide false sideways false status open \begin_layout Plain Layout \align center \begin_inset Tabular \begin_inset Text \begin_layout Plain Layout Anger \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Time \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 1 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 2 \end_layout \end_inset \end_inset \end_layout \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout \begin_inset CommandInset label LatexCommand label name "tab:anger-time" \end_inset Laurinda's anger as a function of time. \end_layout \end_inset \end_layout \end_inset \end_layout \begin_layout Standard For the sake of Laurinda's furiousness, here is figure \begin_inset CommandInset ref LatexCommand ref reference "fig:anger-again" \end_inset again. \end_layout \begin_layout Standard \begin_inset Float figure wide false sideways false status open \begin_layout Plain Layout \align center \begin_inset Graphics filename laurindas-anger.svg \end_inset \end_layout \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout \begin_inset CommandInset label LatexCommand label name "fig:anger-again" \end_inset Laurinda's anger, again. \end_layout \end_inset \end_layout \end_inset \end_layout \begin_layout Standard But how did Laurinda compute her anger? We cannot but speculate; here is a stupid suggestion in listing \begin_inset CommandInset ref LatexCommand ref reference "alg:computation" \end_inset . \end_layout \begin_layout Standard \begin_inset Float algorithm wide false sideways false status open \begin_layout Plain Layout anger = time - 1 \end_layout \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout \begin_inset CommandInset label LatexCommand label name "alg:computation" \end_inset Laurinda computes her anger. \end_layout \end_inset \end_layout \begin_layout Plain Layout \end_layout \end_inset \end_layout \begin_layout Standard The result is in table \begin_inset CommandInset ref LatexCommand ref reference "tab:anger-time-again" \end_inset , proving we were right all along. Also subtables \begin_inset CommandInset ref LatexCommand ref reference "tab:Only-Anger" \end_inset and \begin_inset CommandInset ref LatexCommand ref reference "tab:Only-Time" \end_inset show anger and time, respectively. \end_layout \begin_layout Standard \begin_inset Float table wide false sideways false status open \begin_layout Plain Layout \align center \begin_inset Float table wide false sideways false status open \begin_layout Plain Layout \align center \begin_inset Tabular \begin_inset Text \begin_layout Plain Layout Anger \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 1 \end_layout \end_inset \end_inset \end_layout \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout \begin_inset CommandInset label LatexCommand label name "tab:Only-Anger" \end_inset Only Anger. \end_layout \end_inset \end_layout \end_inset \begin_inset Float table wide false sideways false status open \begin_layout Plain Layout \align center \begin_inset Tabular \begin_inset Text \begin_layout Plain Layout Time \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 2 \end_layout \end_inset \end_inset \begin_inset Caption \begin_layout Plain Layout \begin_inset CommandInset label LatexCommand label name "tab:Only-Time" \end_inset Only Time. \end_layout \end_inset \end_layout \end_inset \end_layout \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout \begin_inset CommandInset label LatexCommand label name "tab:anger-time-again" \end_inset Laurinda's anger quantified, divided in two. \end_layout \end_inset \end_layout \end_inset \end_layout \begin_layout Standard Interested in that last table? Let us repeat it but without a label and with a table and a subtable \begin_inset CommandInset ref LatexCommand ref reference "tab:rabbit-walrus-encore" \end_inset . \end_layout \begin_layout Standard \begin_inset Float table wide false sideways false status open \begin_layout Plain Layout \align center \begin_inset Float table wide false sideways false status open \begin_layout Plain Layout Censored \end_layout \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout \begin_inset CommandInset label LatexCommand label name "tab:rabbit-walrus-encore" \end_inset The rabbit-walrus does an encore. \end_layout \end_inset \end_layout \begin_layout Plain Layout \end_layout \end_inset \begin_inset Tabular \begin_inset Text \begin_layout Plain Layout Anger \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Time \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 1 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 2 \end_layout \end_inset \end_inset \end_layout \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout One more time. \end_layout \end_inset \end_layout \end_inset \end_layout \begin_layout Section The Passing Away \end_layout \begin_layout Standard Our hero was passing by the village. He had only stopped to say \begin_inset Quotes eld \end_inset Hi! \begin_inset Quotes erd \end_inset Again here our lousy skills have made us spoil the quote, but this time for the opposite reasons: everyone knows how to say \begin_inset Quotes eld \end_inset Hi! \begin_inset Quotes erd \end_inset , so we don't need an actual quote. It is enough to report that the had stopped to say hi, even maybe qualifying it a bit to make do for the missing exclamation sign: he could have stopped to say a friendly hi. Getting all literary he could have stopped to say a longing hi, although this road leads to bizarreness. It could be cool though. \end_layout \begin_layout Standard But anyway. Laurinda was so mad, so hopping mad that she called her friend, the Assassin. He was not in town at that precise moment, but that didn't help our hero as he was just outside town killing people in a small barn. Just for practice. \end_layout \begin_layout Standard Our hero left the village, but Laurinda cunningly annotated the MAC address of his laptop's wifi card. The lack of networking knowledge on the part of our hero (who really couldn't tell a SYN packet from an ACK) was to play an important part in the story -- if he had known how to change the MAC address, which identified him with the precision of a surgeon's scalpel, he would have been safe. \end_layout \begin_layout Standard Let's not even get into that last scalpel metaphor, shall we not? It leaks worse than the Titanic. \end_layout \begin_layout Part Of How Our Hero Went No More \end_layout \begin_layout Chapter The Killing \end_layout \begin_layout Standard Our hero led a happy existence for a long time afterwards, randomly avoiding all points within connecting distance of a wifi network. It could not last. \end_layout \begin_layout Standard Our hero went to the next village, found a friendly Moonrams cafe and connected to the net. Quickly the assassin (who knew the very people that run the internet, and who by this display of nerdiness no longer merits the starting capital letter) traced a bunch of IP packets coming from our hero's MAC address. He deployed a team of murderous African bees, which as surely as a well-cared-f or AK-47 reached our hero and killed him with three fast stings. Of course they died afterwards, being bees and all, so it was an astounding feat this training of wild African bees just for this one murder. Maybe the Assassin merits that capital letter after all. \end_layout \begin_layout Section The Passing Away \end_layout \begin_layout Standard Our hero was undone. He was no more. He was, actually, an ex-hero. We shall narrate his wake soon. \end_layout \begin_layout Itemize But first a message from our kind sponsors. They want to present you the next section in this deeper inset. \end_layout \begin_deeper \begin_layout Section The Mourning \end_layout \begin_layout Standard Everyone cried in the ceremony. It was so sad that we need an image of this moment. You can find it in figure \begin_inset CommandInset ref LatexCommand ref reference "fig:mourning" \end_inset . \begin_inset Note Greyedout status open \begin_layout Plain Layout Mental note: never pay the artist beforehand. \end_layout \end_inset \end_layout \end_deeper \begin_layout Standard \begin_inset Float figure wide false sideways false status open \begin_layout Plain Layout \align center \begin_inset Graphics filename mourning.svg \end_inset \end_layout \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout \begin_inset CommandInset label LatexCommand label name "fig:mourning" \end_inset A crude approximation to our hero's mourning. \end_layout \end_inset \end_layout \end_inset \end_layout \begin_layout Standard And thusly everything happened. \end_layout \begin_layout Chapter The Mourning \end_layout \begin_layout Standard We have already talked at length about the mourning, and under sponsorship no less, so no further details will be given here. Suffice to say that our hero was mourned. A lot. \end_layout \begin_layout Chapter \start_of_appendix The Rebirth \end_layout \begin_layout Standard Surprising everyone, our hero was about to make a comeback. \end_layout \begin_layout Section Coming Again \end_layout \begin_layout Standard As it happened, our hero had never died; he had just faked his own death to find out his assassin. It was not difficult, what with the capital letter and all. \end_layout \begin_layout Section Two is Better than One \end_layout \begin_layout Standard How to make another comeback? This is left as an exercise to the reader. \end_layout \begin_layout Chapter Our Recommendation to Kids \end_layout \begin_layout Standard Never trust killer bees. Or Assassins. \end_layout \begin_layout Section Killer Bees and Their Perils \end_layout \begin_layout Standard A killer bee cannot be trained consistently, since it will die at the first sting. Better use killing wasps -- or, even better, solve your differencies talking. \end_layout \begin_layout Standard For the sake of your education, check figure \begin_inset CommandInset ref LatexCommand ref reference "fig:killer-bees" \end_inset . It shows a bunch of killer bees, or something. \end_layout \begin_layout Standard \begin_inset Float figure wide false sideways false status open \begin_layout Plain Layout \align center \begin_inset Graphics filename mourning.svg \end_inset \end_layout \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout \begin_inset CommandInset label LatexCommand label name "fig:killer-bees" \end_inset A gathering of killer bees. Supposedly. \end_layout \end_inset \end_layout \end_inset \end_layout \begin_layout Section Assassins: Inherently Unreliable \end_layout \begin_layout Standard Someone who kills people (even for business) is not someone you want to deal with. Watch \begin_inset Quotes eld \end_inset Fargo \begin_inset Quotes erd \end_inset by the Coen Brothers if you don't believe me. And remember: a hero under the belt is a feather on the hat. \end_layout \end_body \end_document elyxer-1.2.5/test/subdir/mini-elyxer.jpg0000644000175000017500000000304712074107030017546 0ustar chennochennoJFIFddC  !"$"$C2:"0!1A"Q2aRr#Bq&1A!"Qa2 ?죬Jɣ*'b4gFn*dd#YgK߈mS%7LΈMF&Mf%I_]4*F D R vg)b2WHmahRUWH5= * dK.pW=)>*ڼj{UH[ޤ=,rIPgPvgRӣTyo:,IEPiatdxv @ǮG]4pbk#SJU S[|WHhV/%<픡  GqNAyu4mI R^ep6cWzCڕ\D?y{ Qk멧j(dsPsǼnV8i54[['dU1} %X+e9ai]`42CqitYYUl?jUU=UP%2"/8]uKl)XAЙ~ھ prޡ ?sRr$q]?׺)㢵K02'WʷrbnڨOz5*S?˦Z^<{ Kɐ1[9bVVGl E B2pXz'Fh[U%@ oӧ6ZZꚺi^Gn!$ _!]}nEJvb+d%$+Nrv@|j8k~D$U|OUO\SOSRN!=T-{dqWaHPcr$ d䞴_x j()KP(+~!XO!֦ EoO{o]+RPY[O1);ɜbGQW:ΆEH$kjbC~I#>n웊[ʆujh)ؘq*J l`xɵW:;M6풊NSR,<p yWVף[WTkLң~\DVޭ:RCNh;gwW *3j}ږe*S,rI$1$rI'[]b ×{ZG1А:4hғ4Ѣelyxer-1.2.5/test/subdir/mourning.png0000644000175000017500000003177012117174766017174 0ustar chennochennoPNG  IHDR[$NQgAMA asRGB cHRMz&u0`:pQ<bKGD X pHYsdd2IDATxg\Tw9ӇA,4 `5{^Sl٘n4c{; D.Sv+,|\ g/9s'  xpE                        zr~§"\' Pn/(j_tMe/9M<\Unu=nRpE'|Qo--mΗIH{ḳuS4ƞS8\ ~T}Þ!X[kmZvM_YIZIڰϴ?xMl hz׶4~pS}TP?p~wؙmgC -z4R_R >-TJ*83́{EXcMɣg7v+3qH&InoO::yXUݗ:pY389\j5꘦OaH J`rz(K6=ޣp&qWG~0?C`؁g\|)kGܡ\9u'),g0epx8M?q޳ז[`~zzz̕W >X9}WڰmGl/utp{XG}$y`~ZJiul(mPS3cv58p&8OҞS]{ݳGNY^KKS[~s7+`~ԡ;>+T-HX/guhy&ߪ0)1-f,5(9[ׅ>5%Vrl_&~;'9}/oUQ{Yn֏k9<ԬWox}QlUVq8북#,1ːƸ]cHf&]Y]Sg~cwmUYEI7uoqV1~,˅2v^iko yj ėeSU26Ų?vrcwj:.1I"Kn ?DTKU)2f_MM'Ɣ=J٣^dh/ a3 `Wp~Oה $Ssjcc6Vo{ǕqkeŽ]. eNJeۤyu]ͱ?W?v(w=쭲m#{eA{ O|VV(r\|,f΂7}nƄPj#~8~BCS62<⃈>][oxs/Ϧ/ҧ(Uk\3a?i^]hW?vDUBŖ1j[~{J՗e[[FQiT4rqs4 ctF}Zy^ؑoQW<~ߐ}a<:PXvϭn-n0?vER+Ttjwlφu_1jg,cݯY,?kAǏRc;ҺȆ+c{K}wYqn:hXG gϞ=7a~N>zk.SM[ZCuU!$d2Q7h]t/'e9+ g!' ,}'|c3ULgtS[j q{蟰-o{EQ%]S{պɻhd@ɲe2Ύ>7U-mdUl$_}IMdm눽M/5ɩ`;cy|v= E>y;A2lφ6N?:sTYUx/[yqz8QIM6v1vklu>$e]Lc|b&I]lـ-`~{|LJyI^fKe͚ڷVz=Q̹OvJx4.k9n%zQ=(HD͒W>z8JQ]]|E|I|I\+WtԴ o^[-WQ ,0_31XI7,M 0ZI7NE(C<.#JLֹ͆Q-u~dFuA?Z'_FԫMol{žX.swjl=|㔉},SCā}˻wouذyGm9<7_7'o 1k@=V|Kb=w:/`0_6G%>`-6sSW<#,]\=P=F=RBp$S5h_I &0?0?`=wmi?Q;د,'hu RcRwW(܉?='}^UЧuB g-wZQ_enyP&uE|ȧG-0ųa"F_`lBaN&]#$?$Q~@r?yO|nkQm9&]hh2RuMwFQWԿ_H]cE'2^xb,=I7Ifǂ(v|h1cEE|uh5oԌZұ:lvLW۟x(TSfKe Vojؤu,7pn`x2BhA"Tɣx6lAp+Ap'Kǟ=;]]GQTgJ9ٗ]wu%/ +7ni/j|&Ǜ~Nf9߬.ٛS1XÆ &ոq#p3 a~Y~TRS.ي96Hmԍo~2`PqDbI|f̈́S5)Pd,2nɋbY¦ k}6Ivbßv+Jm{hC2Ky_k<3,r[covMWgQVR'՟\wZnzr酊YS^6f+a->bO |wOͤbQg[{~!nqٺ6ϴ:7&D\^`~g v 0?@0?@0?@0?@0?@0?@0?@0?@0?@0?@0?@@LƪyAیY7.߫pZo-jNh^=sy9' @à2x~05mL}_} 21#k'Q3fS?p</# [׼{~x$L38iWnUK1`~Pɀe%R;f3K;}4!ӑ+R/^/7:i="C_:gvJ}$~a~~C_U3{CVRC8+۔phVLu\Ԓm;>6`_0?NbDZ=9| zi[+b.X]mޡ_7_E]0?<VYn g༨iQN7j)C81: `~Xi\;|x;92\\ Y0/7sm3u>v&0m|f5<@eM[lUV[SC]W?i׆}IK -Kث)ByGE` x`jyfU[k e*׶ۯ팢n8gJ9ٗ-N\%`fAM_̏øuvۓJ[ [IZ&eu .909S\gI0uTjPW-Տ^QWua~Zc i)6!$BU뻵-` 3qhaOy~&|altK "{;M7Q-p @ƪyAݓwؼB` CjS۵nV6 8 <˛{ I4s_,ӂqۇHUT[8,2ʏJW<[-uc~O s%cȧ!SiY(њcK[c;pST mY<^:jJhs@}T^`~\cgKi~%>Car~9H߼gw2.8׎ Na~\Eƙ ΈӷfJY 8OmaZMmj7=WM63WkY]mmK-qjxeօZ5G4 ʢdž_#7WISv~4܆Tg]k똉Api++k.?+TsAsK W;lөuU×Ϡ~~`0?.ma½n~ 6UO6g24r|HnrLm+_QEFN~@V]sӟS$c 8bqnbKMEt8lS=R 5K[4c{H%+!N8 ,fw}nneѳN-G}l0?.O?)`c[~#$Bg֎ ׋:'DhIɍzSA} RcRw>}[5՛Ԩ{[iLy&u<:I&ƥpuGi۸u{ED~ᗹji5ǦռQ3]xs3=w3uspQ/ߛ+B֋%W-I^ccJҨ?W?.rڝ}>Z[ty }JJ]%J70$qh"i2tԓgGA'ts{&p2QN]DC4(oysِ!2x%kü{+hXwpm>g_76`a~ACB"}u},IS,~/6tŝl,d<_՝~ȫTo[yY-&ps$m%[]e2g>sXrWpBܫޑTQ8 68sʁk[n4N0?Nhأ,oS8n,Jqk=+[ tOޠpTZ^Zyr~#Ϲj/^&fUf$LO~.:řa~JG#>pBK]L&2us8ry` q~啹 Tw7LWR䭡nq6"wZRW8lyrCYa~AfA2T0?E#t2QG8n$^}sRp*|gs' tyTo nځ<6v}S\̧rs->oMCkiMf%7_#1^X&)`7l:O~1e7Z7ܠK.όAe\(6Q8@z]65;=xNy^oK]pS :,m[Zo}}Cq5lx?GImS o D˰Q?WIu6VP8Ab7!'~E7 [u ji۵ N-r'V*rdS:,j;m#ۮF 9 ,X.h^UoUsНLc'~EsBӊ6E/Se+`[*gHZw±a~FR*~H[IWm㞓>/6zH}tAe68͇6Khd6[gi3B]0?`##r;4Cui[m;CRz pflu0X/O]0?`#6K+P)򔟳ARnoPNƇy;|ֈ±a~ꮚ䝔v}n gN|wY8C6[++̓çO .嬕+)^?bQ-r*tvCMu3ڱp uc-;z%uɔX}M7|lz0M6ʩ[4{QW86XWXf!-R{|rgޝ;)5J~nqle V?' 7GVhWbٌ/6NN?'svyD٭~?V&䋻~O]QF{3_mf?s9u#1h+ԪVo/ A0?`E勪ݛI]ԋ31Զm͒? n g+҅~4xt8\@Mvr!-N^]k}u}pz+241ƎPWr+hHj%gV}YY3Ϸvfͱ<&|nyE V>@m'uˣݐDB+()R'' F4P?YO;~ 60?`u﷌n6ѹ͑(PWSU&(w8F5IEKXc0Oqqn-a~{ĉc_v׬nyznW=xXW/ޛhԔ6~[Rw.H)F5褚fx65)E4rY+#6֗B NK ឯ t _1,NZ&%E]8Anjvo[/ -0?Mn}&9^n_}?7sso֊mtWPH ٺg6gz2nS' dN?}!i7Z@z]61,oO7w<1Q (YVlOc_UekEp, buRM2;jnݢ~-BCBSjQ`~/MK{uյOgo=p-S/gT]}jAUE4ieXO"w=I@wsw{OM|=zm,mgHe*kDؤyvwZ.?̏U~ͧwg#J[nkv]6 H U p@_Qޘن7M150n gzb_w"U6n >Bԃ2~e';zpCCC]t?q&f(Sy}>mFa~Uw?=!yQ~H18) 9<G. g\(:! eSHTn|?>{}a~ڹǒyڍfZ&F]ueawbuzSk"p`ys,0;+F ʷŸBܨm#6&ěᓊ$Wnp/љr^9/'׻ߙw'N)u83?(+U`eOJ*..k6D%Nͼp!5&uu8'_2 }d?9r2ũ҂Rʽr%lܒ̩Y+~YU9b ҸY rvKnݹ]:lDž'a]Q %"l%̊ROÇI8YqRJsعm,oqS[r5. u؂KO9_| wEGPW-8Ez-*[pS]/Hm!$-tsC6'ͼ›{D` N>?wju]+AqdWs&0:G'ePWNsY~'Qu9FQ] nSYɤ`]N;?+6Vr{UQWu9HVKu< uV rǥkP'mΏlll5u< z=uX YenodeO]GF S+|~dzޓݠcjb#H][1 x8fweRWu9}orӱaWkX'Q<"-';cI4s_gBO uXKO)YBoG>KcAmO]gq/p +\n~,Vy4-x\Ԩ 8ɺg.S)[*N' 31֭=oONv*2)q ;Hp1]6п1-`-?BHtM)JRdc?s%Ιc_i҉xƻsy .>g2=s~TB*  M] тDv'xaGttsSua~QiT%rkI׿!d2~:2ųa-r->9 ǁEfYTKq]q]55cjT5kjT{kNi7u]RMo{j}SC7ZB's-.O!#9%~I&(y}mg?j/{7KyoVt&""4^ !|<ߵF6w7;E ˿Py2$aiNz@iLDDTn -g˰ -Hg #ɶMWt*W{h9F aU6 7MҙXPydptj8/;dmDDD¡q{4V:K5K %nODT};tsFH = DDDB%t3Ԓ޸5_'J8K֎ҙhX+tZ)0ԼisDDDavz x0J:K[2zd rnϟ;/L4otɿjd @ ?Le^p牊ڥ3ЄC} 7{,Dt`X`8(_Բ-P 3K`5;HΕDTi΂n'`؝w6 A}CBUC?zf6p:СbojnG;N: Qcc07{eҙJIa _UWϷzhr_ T?Mj@)ߕ{ Rm5# 3*,@G7SB4cs6F:ZՆUBp]lL4*>jP(.t}YpUܭ@Jg}>71@JgcB4#Q:T /ok_-% #'|=d( X͈[2lKg!sDo~H6Zh$3Ė$ QQ2Ns&3j9`2]!}X EXǟ#^kS5pZ\wtjo }פg PY5]>rHt v|8[Hg~,TBC7 kzs(|R];Smq`|1>ugԲC)12s38j,TzeN Y 1S_/h|]}BrtF/9N: _;WHg^,TB~w#D7Eyh6`mkbΠtB%t92 /PP<U6+*' cOR}XQϐBV8eHg!9M|՝6>eeqvW{گUvB =inrxtB% JgV&`xYՉ s-zP -!lx;NBVCYxc}w@+P8;w R(tqeF21HaY(߹ Kg ?BݸQ: UNSr1`%{(EN#=)45%-@祳{TBZʬt:L8!I%0~PYr/ogIgqW'.}pD:KxP ?_[`cR *Ӹa,t83 7Qr:'!XTؒJg[ B(c2S:KP3M\9bF7 P{$jGppKg *UC[&ےA;tF/ٵPGkptaRuަ& Ty3jE9xYv^zg#n2JձP sF?WTv1,BU9t3(% F3wBёKJg*U~qtg4sC2rIg-ϋXTMjȭ x0J: E"So4 X=.*qyL g@2;[5+lK$aJr?s(ʜ;Q M@ݣIgBY?o;˾o?OsFW8iPW[Ջś@׌ k@nF,Od$\BW86ܭYIx op,3WHgBfp(Vs#Tҁ۷2ө)ܣF:M56N 驔t 6ĥKZ( }2($P^{t ܠt9,Tj6~~ a6x1U'.A ;y !t!!r{FKg! F:_`tZוFKz>(hL:*5+vEH[-!L-6E: JͲ58`,?"/(xt0ND $g4oB/AB.1tR3KgB%rWvIgQZGr0;3= DfϮ[(A ȱz*vt*B] )ƽxJ 3cY/t*eoKg\>~ tj,XDV|ey'P\) D:!Ԭe'$*2 g9F$ NoXtRkH:CxP/ڻ3Ptƾ_:wm;R_ɿOn'%#[!TQf0'%#+%Xğu>OS:tsƤ3@)Ð^,TeO3oP: MPYMM;,DMXT#*T! j:"3sujġ^zYƴ-TaNY6/@}AJma ),Jny PeDTEG]G[&niCBt}=l2/.j{THL8g#EƷaW3QPp jt" m> hdZ Jz!|DeX4-(}0M{u3QeV%jet& *$Em.g=,DՉ )wA d+%,= .P^n0\Zx}ju?2T$wr TQ}s-A家\*z-m9S:QuaBE '3SaGJ"1{} sRH?udrBTXPӧJG('È$oC*P)WJaNJg DՁ ttr2x\:@UEZˀD4*TZ&]6n$檔g%?7D'e"My@nL=;tr(@6qKPK8o1)p샋*ocPxsORaIy9o_ ː[}>1]: Q8WU™.u뀉 xaoz*h-Wd8DtX,Th T1*W{{n[nذaÆ 3JR ;^m$::*4C3TB6;00*yW^y]wu]~駟~D2}*&jWoXdbB3w ?Нwywu}>O|~:J=df8cccc \U6\Г… MWM3# /JM;s]u]`ڵk׮^MQAtM7t _~_\A~iTtpNTJɴ;/THWWWWWԯcǎ;vL'J:r׿g?~~o'~mvm3y ;7.h/qQir 0Wej͛7o޼_}ϟ# = N}ȫnoWя~عsΝ;gqJپj?<((X4#3HP&}%\r%GRS}<0:kW9899/ٳgϞ=GJahƍ7nY*ụ3 3= ER:9->^x^8nnXf͚5ktBN_4Ms&[[eMoyqa9ԆjWvU1>DGMPH*}LW&[5yys56o޼yfs9s . .8} C2>PU0vBlڴiӦMm۶mvڵk0{ٳ6ںڣVm}sBhl}_Fw?+%L 65-]LiWR۶ hײe뮻..&x^믿/}K_QVd2}ZLS:[ Dá"wIW(|O@a.Kz{vr]z饗^zd˗/_|b27x7_/͛(q4{0)أBSz3WRuus@<>+&J^^ ȶ,jl,jɺ@Qmmi]X: Ч)Զ)3VxɿV ^ *~ ·YmL* L |{mI9%/PbBG`,* zߓJ+Pw@:_l`hQ* d+̌^Y3)XQ^MY(< / ;-/H`7*ɴDD<>%H :Om)Y}tdPO֌B'ywr2E "㷉3E I5,Th3?.(rǸ" MܴC:QԹͣU̝hXt DB,?VOJ'!F-X4)tߕ{ ,뤈`BӤQ!.@T,Thts *4MjtVIg r4)[X&z~ww?OʥP ^eIJ`v&y 6_4$SsyQ`b}B]-0?g#_,WR~}}~(ŶОUm._-85ߧz7XM=*R3o0 Nw7'f{DJ@X4 s%o xu^ nWuN NZ3W*w)qwԔDnQRvhY O.u+P^n}9dކ݋+o:۽oFWv,G8uzo(DSBN%44߽r%8[\׺"r6NJX=kwGb> [@N8bhY4܇2?]Zvx3w.ĶsnQ-U9I@vZp/yx w9%{# vI6H%{gZU.{sV^o ^I) n {zʷ'-80үd;njwH(WPjt}T锝:xGRkے7uJ͏8\R0|y+b 5LXK s?صK0g7YC?iF'C=E]oeS9Kg)I{tU: Qm`B7LΥ"{UZr1{ :hh=v|.P9E 4oV ¥SLP=R% sy?nt=5>$m*q ԝ=g/7(6PH  JPZ7?Hjρxɐxa ͸34[MpbBQ gK~OVU( 5yۀ}b*Crg2WPD攷 j Tg *Ew];U Q+pS ur :sO>)`oHDT}T(2?X=ulSɫJ0]xq3s@Oó۳z0zb"bnr|/Xz5ڏ=_Dt(P$W;] D 6b.ɭЌ#(QY3 =2/* {73i8G"%0o>ϗNs(3y%h翸g!ZDD4S,T(RQgkI8x5%@U@aDT;XP OU)֩[բKUF:]:U3*)* 7].ll^!PHq-2uPsUF~PhPPP@)IaSo.Ņ3Z`;DTXP$1k0=/rj.nArz)Y.vOtI jB" a^} da]ҍ};t "f,T(:K:W_eN0Ftk^0Ԧmh&"פS5_FV ݘjdݹaP^svUΑN391Uru}yt "F,Tezi&lSJ:[s(oO0RMDU դ 9 x+sCx!?S+2jT)5*ݘCW9˽A< $v\Z:4|W7:r\I7jBG?6NCDՄ զӼ?+CLQx`鮧}]ҭ:W:U*TEz5A o3ct]ph‹ $u9S={s 9ct{s=5)P,T'I+A]p)^/s1[uv6F^(XPmQ4fFY#f;3.HH?( )֑&,;;LߐKOBs&L.î0nLGDBjggst"/ɺۋK0Vk՛4;-&bB3> @Cө[u;[s\gZ|SJ!jBj>3 Z6D[sXm~X" )jKp?)}Y?7߯;cbzNADՄ F_)Cn}^?SSQ5aB5E6S/xNWˊ  Jx,T(7!LkNKq &_݉KSQ5aB5EEW:co0omc"NvP'ݪGm4WP)3g qI뮆khn&jY "ʠJI:$#:?_yi L4DT "𫑢$B {ee)*?]rX 0Yaa4nVK jBjJ on伕rNADՀ զzESX]*nǩwP%aB5IDN19cj1_\ni/ U  MK6%brj0ʹewK*ʣ};;]'Œ $u>ONq\_5'ҭ=:oDf,T6݂TtC>^.ڣ\[NDTXPMRB*COp-ҭ:b DF,T6y[qt>C59 ?l<ǼNADaBjN)^~.n r?ۘt " #*T-P\~-nNN |2P~N:  IO:šORAzt+g~t " *T3M!0a y6nn>_: Ijup:_:š١]_3v[9sjUα!aB5)x2hNq(5l:q9v$ʙ zU)D&,T&MX̑N1AE?Xe,0m|Wӧ[: I>7I`\c/>b,nL(""*TeH3+EJz;} ֦9CD/BjӨBոl>]:3#i}ܬ3BJP!*#DM ]vT}zLҭ:md": *DeOv֦O4Q)(XPmN1||OqtN=F&>`hN Iz)\+Y qt " 3*Tսs_rnsߔ*g݈NADaBjS\7+U/ sS6N]E~+jjD_`蒻s6 $4; !ׂe$t'c.׊Q!#`BW.|@ݢߨz*{6rW0;>vy;h#cB5xrS=iآs/ ڧU`QWY vjӺwJ!jBjҾxr3^o1! zкv{Z $8eqȇ 4}rS?^) ߘn<>%vvc<$q7fɳD4,Ty+b4'K%y}ŀTC[g ijrORY/ɓݕuj%dٱҭ'ZBjUFـJԷ>I-F`ĥ[\)3}@o0Ʀ2g^O9tPHЮ)cio\c|J3Kb-{PI+_DTKXP$h*2ecgtVNZjS O%w$ΐn%"* j]x8vVjzQ²c8F NDTXP$2\7e,R nYx4t3?bܓDDՏ E^J]ҭ:DSxqȦXj}D}Z(2X|ISiK)bVtPhP^\ԟN,SSnʼnb'Ar@U>DT^,T(TzCPleKn@][ggڛҭ (`BѰGQA.gܙNQE?]ܑ|=?5K7 ERV+ݦ♿IbgMY6H'(`BM#Kχy tJhݩ`^K'(`B0>Q,sntcJ< Njޯ:SQPHQO'y3/hͱBt`ا$w[թ^0cFN"&B~fρZ9Fk|a򇩳տ˒bXPfTX7/ӗPbwltSXPܩ?i /zJ4SvD= PVy>>tJ"*-zt6hnL3•_~ ̟%.ӡ_7SQPHQ'MI~D:uñ_w tD%,T(Rԃ*;ǍeSg$jD>U@A*#-U @c*N6U:̯oߘFID,T(ZWkɿ2)ZVoǏ+u `jo65gB"Eu}|طZ~^Z:]>6[S:Q%8I sq`:KN_1[˩`tJ |#h԰԰t"" """ -:QhP!""bBDDDBB  """ -*DDDZ,T(XQhP!""bBDDDBB  """ ̖*IENDB`elyxer-1.2.5/test/subdir/laurindas-anger.png0000644000175000017500000005356012074107030020371 0ustar chennochennoPNG  IHDR[,ƽbKGD X pHYsdd vpAg[3=VIDATxwxe53d2B*TE .Vl(k]um]VײX J^BL1<_I<3w]{e C䮪> """DDDD¢BDDDŢBDDDŢBDDDŢBDDDŢBDDDŢBDDDŢBDDDŢBDDDŢBDDDŢBDDDŢBDDDŢBDDDŢBDDDŢBDDDŢBDDDŢBDDDŢBDDDŢBDDDŢBDDDŢBDDDŢBDDDŢBDDDŢBDDDŢBDDDŢBDDDŢBDDDŢBDDDŢBDDDŢBDDDŢBDDDz.!h ƄPAKHXTdjsշm_8J]?p=+[ni[Q-0LW6cMh@sioh@7T4P?b\T h @sJsN2U @1]x:^_ `li4Ӑ:I֧ph| VKfS4nP5A}oޯ J(BB!7|N 3I@1W)'1P{t>s2MҫNɵ[~e_-p]N.FepUe4kuoR/} k[e@m|@>s9i< ^fI$ON*:×OdLJMc-avudM2~R fwбsò-ـ{Wc֮mc ༰WuZ]dd<諓s7ƛ/L_f1P!y!350]>;ش иzwֹa`Tfڧ-umaMZ4  #LӠ92D,*QTkهm;=0̵NʞXZ5$.*=|J`))H5ZK?hl]4b4GW+KұI{\4N _#UHo6E$7u@w,pNuщe7t/="mIܓ!}S9_[?zh6?+26dѤgG],*|6 (g9A$'o&%]RF>({*QaQߑ~W4~8 ;-)ɢSEw43XPQ^k`?_8($:Qdرh>exi':fV-~&;P} A ~P9 w| [NCDx^u'?/FoZx)GTn{Q#: EC벁]>wuUE"8T\*={ʌ;qZTDE%ι6|cDԗ,e-#wwpRѩJ gDf*^x3]"TDǢ炯*@"PIGa@Oݿhns.}Mt*08)4{r;0Ŝ]'}P=bѩ(ޱ9ݎD SHeG쩛>~]t*W,*qΤβ NAD)dh2'j֖-_XT\ܼNjNADrZtœi s f[&^h4:h4CmZ^ojVk4*JkRZmt` >xGCC ;SZa+Pь07(:*]c~7>}Ltht: 0>!!+ 0o_mff rK訯_;s ~[t=涛üE +X_ح^|BO&NuCbb^0`QG=p}r' hogi?\.}n"OY4`M|B@VC~ڇ_ i}Aoi?ρ $%`ҤgA!R5sKSw_xpIISF3j[Dt8z^ξRuNw;U^̘wE՚3nPZ:efsJJiT4wͰ,B \B(%zϑRaF`ǖ7oT#~RSt:)5O%- n X22  S!_z hmYZtsRK8SqK'e7W3`۹遏u=ykڗ@leKtJN/eA!,I~pMM[N}MWO@w=pA tY;QQJ h\9Ȭl(JQY,Ç(:My[kO?6|\3x2m4mp, Nw׼E"LkHixGoMT423û$o ;;#,KB92j4@ Dxϗ YYD5rr'oN=D}<]XT"oh7h XiDZ\zhH#/6IIᢓۏ߯_x1kPJZsrƍT*&cKҵΓmE%JR ʜgkҧN#^M#B&/b}͊T(srΩh=\z텅Ү.4Ҷx1;֬ѣ刖PIGaۖD)x,V&9-@/9ȟ);ڀׯ_budEF)7RAde Maax͖t.ɅcJC{e_l'$s؛gsd`T*Zd Ɵ{w}] 777778;0 /////>3bedj `>Ff#.)=b6 FyLFG]ʊ^~2YEKR;j,oyW( %wlݺu֭Yf͚#(̙3gΜ TUUUUU|<%"p@/)҈grrA<9@]{UW*>:p4nO쮓?_ / =vr\y͛'TT6$B-8˹in,MN.(4Ic>[l_r n޳SA±kf @'Yt ~ 4U[lٲeSҔ4 w))-JEya92ËcSveD!>&=`i郢Q($fDemjZ3%2 r#톑K e˖-[fKR4Ht DQڹ ̐!Cّƍ7np\p"OISbnѤmi>{] __:ꨣ.\p$[攔;u3~(Q}ESyFt>%3wsV|̙3g`ĉ'NnnX|+&bk̈́t iG:V,Yd{{zq|Q^x^lڴiӦ םt(nU9+:EQĺXKN,(`I($jJNLNNNNN?@i$sQq΋kk#qn믿v]>?Zn߳>(kePӆr !3ŢS>/*!nJ|Dtj_KKâE-ZD_uOFVP( 9{"H/ѾO*(jvHz{6nܸqc뛑FHWz24h|߿UtǢQ9b*]TLz{'ƞ;uY]b5&vP?i:ut8 =_iu^^.@:e&S =+l}M9o<-?CtŢǼ5@ZH( .,5Ѻ Hy㺯o~֑[E2;*hkkHW7DP{$EW'D{ 3Wl{v;>Mk!ŵ$Z'sgq8?%:[Bq\y}v{k+Y\45<8M95EG](ص)E%ʂjwxV{NC`" ;nU۔=#?tS$eX)E%ʜIul)1n@8o ;"AZ" h ];'Jkm~Gt =i><GZb%<=>_0˖UVVWnw /FT(9e)eS(JuͣEȑ}!zW 4447][_l ?[JOʀztpv`,*Q uK}%:TjNД~b ǎ`0<һ".:74tŋw,+*+U%=RAsj][EP.([:Oc4t"nmÊյ'|"Gw46\Qz畺G*z\"''%S(J85B94l7lZX]Mv\]p8Νv{xퟓ gSQ^Iikko(/Ք#CDP.(qVn[ʡ'$dgN H޽uu VssKK?ʕᑔji YvKE > B!J^~a4&%NI -tB%)+kmmmzwܺu 2JHϓFXTE%J<5U":r$$ (:E4HSHK_H/`Od֬ٞrû**9#rEjm偄5S(Jnw{;:W<,:iFcr2`2%%':M_4 |Rޞ*VYYStNDln nmʤB%^cb"MX:cQ0[Z׋N!_:ɔX99)D;vr:G4 :R~|ҢjiHz?Œ`J)E%TwbLhVRrqᥡ H#(vu:b#-F{ 42}%H)86N<,*|78>mBh  %piooiiiQr#M UUK}EHWUYw/y E%4ٹRt zO|ۼ9foI#*.! 47GB#+i['; ^yLۓ#$`h9ږǪDIQ=`|?}pqkkҶg>|^tnVεhs~l¹񄋏aSd,*ݡzJ6ByXT"ĶeOnirKHHO2Dt͛#siawy*HW|>8u# nRt~z)naKN#?FŒDI:/ev/|$.4bArxѹtGm$.ݾgcO-!ƢEb7-@ݢSɟ^o6NArX#RYgXTiꯪC uPg6v'_^Oml%uFc0XSPwElo3GcfeͨT~ڤFyXT v@c7r+Yt*ju^Ҩ8ZZ-"{GT))Cܼm4a -Vt bQُ_4]7VuNw;,BR`39N6nB`0W[(:r%dkL}wOSk4r4kUDjo߰At 1{@t i} ޴^:fVN;@4bJڎBP(_~FA-s[G$Ѻ/%V -XhMh^.TYjWXxGCæM]EudMn"lqʍ(m^(:Tjh4N~lv{U myϏB⦨~x@ų\|?tS>Bt B51Qt;> ׯ_/:$?|)/nJ]{_g6ٹRtt-:Ԑ!ii))J%) ZSj >4 "Mq;=Ct16ilmN::lvF~MKKM0»L&Vb |zzڳ4AKzz4E7}'+^siO0,7mzj\ ''!,pQ*p:m]DQC.c;ovʪz hnvw'trl69\t:VքXfHOrs32Դ4 ''###HOOIʮ`8iѭ6|7ώ--v;PQ>&O͵XxeٞK]߅  >䣏:GFbͻv@Vbׯ6t@`~,6ii )sJtv٢"Z=hN|":IEm٣GNup~ <o@KK[[kTp8#IRX @AAvvNNx$0#_":Il٢"r܋mz@hA(?tT$**Z9E(77/p=Gtkhٚ;߮Zq㟽`j4JJ C 06,vҤQƌ,>5NgKS(#G*:rRmбz_FFS>MNg2tpnڵ9`]08c=η"b;-]oQ.wDVNWxeKKew߉u'vؘ1O~wZm'};+*ˁG7綾)S.{y&S^#\PDQ|á{XP-n17#8`"`.ϙ54ih--~ޮ NuӧqĄ |wNMH_}u>.x^zQtʾr?y0tqST$G+:slŵJsSL {<44RV&:r%N.L%:E싻4 @%TqY%nӦ_s^z3gˬY_,: 4U;~xKE/`0Tڪ@mo<荺rV>"~mQoONAr{J+5לwssNChlw>Of~755{Nwp.WkkEeX9y\)G]J*$)`6o~ms:c'nK.f>㌳"eݺ͛7mN;m9s7XH о;}30kSLu,o {%׿/ȭΞ}ϘqPHw#=y/\whjڲEt n] h4;[TR 0!:u_^}5>%]q_}50k'}bҥ?zM7= ~xDe.ώfd^Pz'n FCPwTV~=P_uN{k-DEuz֬[offkmq.(` ~V0?t'n=wB;_t>v( }<(:#>wEcm`SdiH2Vxu:D=hn+mJrEr֚5k—|!QH]?c'&_Nt io*WӋ xTE.;3}@h4ѩ^/#+ͻwG{4ޤb)Ogqۛ?D>tp9E# DpѩzӦM>x{~d2Fѩ`<7Iw8--w~TGOJr[mD Q4 yX ʯ@NC,$E)Sƌ;xGy1 991j$REoE?أ*S]hd)*xھ/xJv1g'A kvzH9 :m9h?S@nnfffT?jՓUD?أ}p XߋN[ -6SMh tڔ.CZ2ҎIE%%;O? ԯ_~Sv{}i 2hbn喬Sį)*ɛDI|$ct@VCӭ2k%"я粲; 1L0qT^M9Z& /Kx&S?ݑXq+nsޟ7.DI:zG#l 3=Tǩ~T=g6&wy}ۜY J_/S 1OKRץ\vXf+:E"<6kˡP_S5k5$1)17*WEž}D:8o[%$LfsOf֔_iN4̷)}ܜ4)WaN {U): 5 Pk#f'e^ӢmIS?O99S>5!bho[^ErM01_T\woD1ɹ`i ~z7y,;̛E?2R`Ѣ~y`̘aÆ93r#MY,fsFTҶ>V SbڛtG{L|)WnDїgϤ1juBƉ9WE? = f<+lPE{o~P+l|b;|D!`^) R>UH:/8/'Yjb״iq/˅^|qX5Qgzxd7?'*ШN\hCMz4EERj 9kȰ(Z:*F %տDg\Dz5{of|i:V|bO0k_:7fϸ6]$"I;i5=SU( AC:d_k~XW&-Ŕ5) 9sׁ?SNzNLvGjkV;_[ڝ@j^j^j^}`ennFFf&p}\suҥEvwHAysonFZFNE=%ڒD II!xLt +AMt 9Ӹ^Zwd_y2ey eg0u[@sJKKO+,c.gom%lͻJ:3zҶd]aqQ̆1;WNEqfKJ?\QR.@0"Vz'x4ph3½\K= !yY,dz\ͼ&/7|,_V Z1ضw{嶽@ˁ{bC0p9.Nyg;ܴ~V!IT}Dk;l*>g[)oBisɛ2:;fPMQvJ0gkjLgww;;ꁊJGE5а!ذh屖++W+9!iFJǕX%MO{Q#:􉵙&`{siHw#*R󔁀 (:Ew] !'Yg] on/D `DɈ%Q`ʾ5CndD+?qF j5>ivY(Z;6^*FD]`)Bt _QMG'Ft4_~ky-| SNA:5tؗl"RˎjDFcڰ3Db~%6SMhi(RmO%:QP5 ON\X -SXTQ*H}zu3yCkfVe":hLKl4~%%Yt~Hq=~J2lz+{U ]:iHtSҹSXTIf 卡'4)D/:ɑ+ӿER2Ϻ0_UߋNCv7o*_,:QtMmEM^)@XT`L ,~0i<5*NAefC(BK[բSЁDwN:Bt -Oml<)HAKz!A$e |0@s~-i<5+NA]ך2)G_0-eE TAިJ6LZt)=T^-: QtMES(ٲ=mt ,*]d [ޤD$'*6EƜ SUzcnFt "ڐlNA¢ED& /~cD펽6)HNnȨgvoYV, 'mHt :n2R.+Z/:*)HNT>E iuESD$hk\F)@XTX20]t )[NADrv%:J7i T urE yAT@֓ƓieErΚjv>;iNgEb-[N.6Ԗ$:J/T@isr`聢QW.oSt MS(Op{C&)@XT"@ >>gˆ WNDQS=ޏ۳NA¢!Z%eR Ё$W: A?ld4DotN<^=P}t ,*d?v )h Uɟyo@5)Ƅ^Kt ,lɮ':UGlI1LW@EǾpw֔O(:Nx.)SЁDXVNAGy` K=xi+uk9At QѬ<&_ϢXT"Q^ZHt ҏN
QiH 3*/"vxVԝ+:I8겗+i/:uFR2(Iq}U>Yb>¦'a4#*,m{R#[I4u@x ũP( vFP:D I;عKfi~}z24Yt::ԓgMV,:I_TB@it9B4DbIGw4mŢ.\o$NCufsynJR+w; ibicNqS`*?ܘc<#:VVׯ"+ݣb/N43DH1OΙ6$]t "ypRs:x(:Q NCbH),H,imNNK0 Ȏ⋊$dp1DR>OkJV4Dby[ {GGU_rD/[1STv5T4Zt)yp-x5SľD7qt RԨtZ Κ-: ~Z<(̝شM)bӾLꬒ9ЁNQ'}̡>8G`]!n"&_SĮSsERNCsEEY=t/aJ{kuNA$ޫ):E v[O~Ht:+*XJ Lt*n7E9 .)bOƒ f:O>@t:-*# e0Qt:ŘHtyibO [NBt ꪘ/*jVewCeTt 1:Mt "z-(:EvZJN#: uU^o zҚL!ᷜr ySOh*9j kW : O5ꓸFʍ[tء~J2l'29]tꮸ+*ic/`vSN%: >ŠH,ulT穪Uܕk_K8i<SPwmQdÓ@/Ȧ-\(ovD KRZ@7OLStR5kқ^u{PO}Qj/8Dýe9Y-:U {+=C |bDPdA"QZ(4#̀aR6|ѩj ,dNCŢmIly,@dުg]#\DHH.4^熾t⭀b-&: ڼTɏ< dxYt#h[(:W|E9+} 煍o`@1$$fw̽(oH٤K9Sn> }{q]Dv]5}mYPJ% *8}?-H*sT5~):QlѸ io>0[rRE? $ JT7ٳ(uG7@ݢSOᑔ̝" u~[݀;a 9mAp-BwLuf-`|(7#SZ;#_.cTD?JEEd*w=87֏TBDD Zӓb@3@t* wDcQLӪ Z  ?nۛuF{wSh,*2l}%@0mɾwГS=]s&l)H427(9G;Q@=NS;Ct3'dX*:Ƣ"s*$xB;D<ѹKf؃Ŗ3N3!ON{){l<~DD$ܞc:ݫw ׼Q@GfgCT'f.y?w.2&"Ƣ<&_@/l[r j9iy ֞!:zHuxi$qm âo@{eu?mv6}$8umipE?tGGoC-g^"" b\ۇjuwo?ι¶,>P1%ɟ$irѣXj Appendix Test

Appendix Test

Alex Fernández (elyxer@gmail.com)

Part I. Of How Our Hero Came and Went

1 The Coming

Our hero came in. He was tired. He thought the world belonged to him.

1.1 The Meeting

Our hero met with Laurinda. She was smiling. But our hero was not amused. His whiskers were dripping wet, he was astonishingly thirsty, and the contradiction was killing him. “Give me some beer, woman!”, he ordered.

1.2 The Melting

Laurinda smiled again. “But Wenceslau, you don’t belong here.” What a stupid thing to say at that precise moment, our hero thought to himself. Only that it came out loud. At that precise moment he knew that the desired beer would not be forthcoming.
He turned to the bartender and tried to obtain a beer by the very old method of purchasing it. But being ignored was not one of Laurinda’s specialities.

2 The Going

It could not last. Laurinda’s hips were flapping, and she was hopping mad.

2.1 Our Hero’s Imagination

Our hero imagined her as a rabbit with long ears and a fine set of tusks. In a short time the image drifted to a walrus, and our hero could not help letting his sinister smile giving him away. Figure 2.1↓ shows a gross approximation of the rabbit-walrus.
figure rabbit-walrus.png
Figure 2.1 The rabbit-walrus.

2.2 Laurinda’s Anger

“Wasn’t it great”, said Laurinda. Actually she said it in the present tense, but our poor storytelling skills have changed that to a cheesy past. Don’t do this at home, kids. You want to be regarded for your authenticity, and misquoting isn’t going to help much.
Anyway, back to the story. Laurinda wanted to hit him in the head with a big ham that she kept just for occassions like this, and being a solid Hitchcock fan she was ready to cook the ham afterwards and serve the resulting stew to any policemen that might come by. She was also a huge Almodóvar fan, but she was unaware that in an early film the divine Pedro had copied the scene. Actually both directors had copied the idea from a short story by Roald Dahl, very much worth reading. Although it must be said that in this story it was a lamb leg, which hardly offers the consistency and stiffness necessary to kill a sturdy husband.
But who cares. Laurinda meanwhile had a funny appearance; if you want to see why please direct your eyes to figure 2.2↓.
figure laurindas-anger.png
Figure 2.2 Laurinda’s anger pictured in a mildly humorous tone.
And yet, how furious was really Laurinda, whom we may optionally refer to as Melinda from now on? Table 2.1↓ vainly attempts to quantify it.
Anger Time
1 2
Table 2.1 Laurinda’s anger as a function of time.
For the sake of Laurinda’s furiousness, here is figure 2.3↓ again.
figure laurindas-anger.png
Figure 2.3 Laurinda’s anger, again.
But how did Laurinda compute her anger? We cannot but speculate; here is a stupid suggestion in listing 2.1↓.
anger = time - 1
Algorithm 2.1 Laurinda computes her anger.
The result is in table 2.2↓, proving we were right all along. Also subtables a↓ and b↓ show anger and time, respectively.
Anger
1
(a) Only Anger.
Time
2
(b) Only Time.
Table 2.2 Laurinda’s anger quantified, divided in two.
Interested in that last table? Let us repeat it but without a label and with a table and a subtable a↓.
Censored
(a) The rabbit-walrus does an encore.
Anger Time
1 2
Table 2.3 One more time.

2.3 The Passing Away

Our hero was passing by the village. He had only stopped to say “Hi!” Again here our lousy skills have made us spoil the quote, but this time for the opposite reasons: everyone knows how to say “Hi!”, so we don’t need an actual quote. It is enough to report that the had stopped to say hi, even maybe qualifying it a bit to make do for the missing exclamation sign: he could have stopped to say a friendly hi. Getting all literary he could have stopped to say a longing hi, although this road leads to bizarreness. It could be cool though.
But anyway. Laurinda was so mad, so hopping mad that she called her friend, the Assassin. He was not in town at that precise moment, but that didn’t help our hero as he was just outside town killing people in a small barn. Just for practice.
Our hero left the village, but Laurinda cunningly annotated the MAC address of his laptop’s wifi card. The lack of networking knowledge on the part of our hero (who really couldn’t tell a SYN packet from an ACK) was to play an important part in the story — if he had known how to change the MAC address, which identified him with the precision of a surgeon’s scalpel, he would have been safe.
Let’s not even get into that last scalpel metaphor, shall we not? It leaks worse than the Titanic.

Part II. Of How Our Hero Went No More

3 The Killing

Our hero led a happy existence for a long time afterwards, randomly avoiding all points within connecting distance of a wifi network. It could not last.
Our hero went to the next village, found a friendly Moonrams cafe and connected to the net. Quickly the assassin (who knew the very people that run the internet, and who by this display of nerdiness no longer merits the starting capital letter) traced a bunch of IP packets coming from our hero’s MAC address. He deployed a team of murderous African bees, which as surely as a well-cared-for AK-47 reached our hero and killed him with three fast stings. Of course they died afterwards, being bees and all, so it was an astounding feat this training of wild African bees just for this one murder. Maybe the Assassin merits that capital letter after all.

3.1 The Passing Away

Our hero was undone. He was no more. He was, actually, an ex-hero. We shall narrate his wake soon.
  • But first a message from our kind sponsors. They want to present you the next section in this deeper inset.

    3.2 The Mourning

    Everyone cried in the ceremony. It was so sad that we need an image of this moment. You can find it in figure 3.1↓. Mental note: never pay the artist beforehand.
figure mourning.png
Figure 3.1 A crude approximation to our hero’s mourning.
And thusly everything happened.

4 The Mourning

We have already talked at length about the mourning, and under sponsorship no less, so no further details will be given here. Suffice to say that our hero was mourned. A lot.

A The Rebirth

Surprising everyone, our hero was about to make a comeback.

A.1 Coming Again

As it happened, our hero had never died; he had just faked his own death to find out his assassin. It was not difficult, what with the capital letter and all.

A.2 Two is Better than One

How to make another comeback? This is left as an exercise to the reader.

B Our Recommendation to Kids

Never trust killer bees. Or Assassins.

B.1 Killer Bees and Their Perils

A killer bee cannot be trained consistently, since it will die at the first sting. Better use killing wasps — or, even better, solve your differencies talking.
For the sake of your education, check figure B.1↓. It shows a bunch of killer bees, or something.
figure mourning.png
Figure B.1 A gathering of killer bees. Supposedly.

B.2 Assassins: Inherently Unreliable

Someone who kills people (even for business) is not someone you want to deal with. Watch “Fargo” by the Coen Brothers if you don’t believe me. And remember: a hero under the belt is a feather on the hat.
elyxer-1.2.5/test/subdir/image-directory-good.html0000644000175000017500000000261312074107030021500 0ustar chennochenno Image Directory Test

Image Directory Test

1 Directory

Just images that have to be taken from another directory.
figure mourning.png
Figure 1.1 An image from another directory
Nothing else.
elyxer-1.2.5/test/helloworld-good.html0000644000175000017500000000152512074107030017300 0ustar chennochenno Converted document
Hello world
elyxer-1.2.5/test/branches-1-5-good.html0000644000175000017500000000230012074107030017202 0ustar chennochenno Document with branches

Document with branches

First some stupid text.
Now some intermediately stupid text.
In this second branch, reddish, we have to be more careful: it is active.
Finally some terminally stupid text.
elyxer-1.2.5/test/elyxer.png0000644000175000017500000005353412074107030015336 0ustar chennochennoPNG  IHDRooUB#bKGD X pHYs229 vpAgoowV9IDATx]w|TU~d{)(bZQϺkòXbE*DC {$3Ii7Bј~prry# B!ߌC4DixC4D@C! h7DC44>@ 4CFo殚j.p[m!`#-w[6 G#ˑSVOY=e5S/YɲO_1b:VtXk̘1cƌRT*VRT*e׮]vZ >>>>>x~!,_8&N8qD *****5 D"?=z>P/h zǟz8r{ DDDDDDX,o{<>_9 '''''8q4h@ ;h9h9h˛H$HNNNNN;]@ ?qP!,4fo١١r6`N3]tw?`h4 `[d[d[=vxwzwzw78|#6oOxe#F#RQp<ȳ [}%ҾK.; iH ۰4͸7!MH7o2_|-5 aUªU}4D[l}PT폶?(JV%>4Zm0Lh4QQKW,] _2~%12' QӿԿԿgL3g}}7B!ҩ~`ۨ\g%hjpq }r"iy'9TZJ=  bW`H"zɀwCj 8N hmmmGrΟ?bO<1w.T*R)vwv(zg K E7n]E1by~E 37]r~9A<ǰ2qln a))рFCPV*e2@*E"@"6C!z~x|ƓNRdX}bzb ,d?^O^{wPH"NF#7iccccc#k= ;G… rlN}C ?xPPPQA* z8͙7xQ-ND9+k༅cǦ:Ւn&mNZ]]^/f\TyM*^Obr(~eY Dj5Nt\fl|?YW~7O?Vk2]|1\yr⧋c<\4h:Ne1^z1EOmjS/Ow逷"<<HJpESn2FZpP0~[_Os_/q$&hTDhJ v19Lln6].`Cyd2L|nV-M.彔G{>(,\.8w05 tΖΖΖ% MMM﹟Т|Q([;@S$ 71CpYcLM22 n^PxAD&Jn8@2LrT"22 *o( \@~8S_UXƘ흝Ν=;39 Jd `~\ V4O=3Qs)ç f=:YǛ^lTlH82 H&^>} 33>h tv+Wv{sG>SSCj5P_v>l6MMNպaQ_)xcJZZl^t[#GmjEGp86fnv:|}Gt`S0?!~bGS%U+pl_xL>` &~.]ƻ?~̯WeKg{ 8qĈ$p -- hdd2׬)/6mǪ*וfl4ছnxk/|+`xv.Uߨc|7.g\B`0tWNX6X ;]]CL dZ-o`]mm]]]=y36_ --}DD$%~;h_$"twx<Og'q4r\|n<dH&"q\ @IB"Yl$#ǿ$/^P=zqKҷ;˻gw|y@S>h(ٙLv_<103fL.wTRU(4_ fFFPddtu< 0O.^{wz=t4 rqI]ꀻz/ |H.W(z8D;?ؾyё,ZɞǣԤ$DPJS۩qԹ3n Xoo޼u~Q4`q)sUcg/ֿsW~7g\T;wǟ??^{#xuىwF#-55&F/gf۾/ r_N"!%ـf xmݚ_] |G c:$=E"XVGG[=3ǍKL/_b^a&z2Vr90|xvTj^OFx{{{ȫȫȫnGIO2fȺalwjÕ[wk5H2;-0(Hr@u2P2Y \z JNVNynyop; XgG 0%->>"&zqU^NFv`kkĤT>$-66666،c/frᇅ\QttB”)@cc]ݾ0$UT)S&NLI (d2\"bc'Lc"PrM5%SN:wXP-pco x'U @4eQeJ &sf_H$k5bLPxG~pҝ8 0kDi/YG? N, efqnwy/Q{H~+9ӑĶYc"`**ہHMMIXs%$IT=hW WTX,@[":(eggfFE;gNVZmDČyqqqwfQ^y JV "v; 7ƙyZtǀD8_y-L.rl@ŵt;pݚwzc5%+Cg LB) ~8WTcwVvLu=rJHIIJ2ȍB2۸q&pqk "oҩSw製{7nx믾zX@!JNȑ PN_X~a'8]J?~O&j[7/M@dwX.qwI䂬,@ ɔp;,X.W(tjklʥ_~AuW40D 2LFp8N'cV23s;1؇dXX~_~z=ߟݙq6f"'f2xG4||FTP 9r̘/F6o^7Rr?՗ir90nܘ1ĉӦx#Ph#vM5yd`هf^Wm-xի|תRQ5@`cQ@,VfF H*=ߟI4koJ4m{}!x-p> п[I$D"` sl""(fsfYWvh#bc)8Y*<7 *:?p8غ8ѣX.|Ѣ_ήzdbijF#dfNBȠ0`.70МCs+)<|AG6:W= BKu)obBjJby" _oB4[|9P^jx| X^P-pXˬltѠKXm|1LR d}=9#?4>;z.\_"#L/]y#G"fddddJ Y/nn7%CaaUFAS&%Q\h4:]r20v 7p\[ n޷rɳz`? ZTP8@;\@cb@TbNAL`z_-X?A7x Yhbw4WlCrYŢ8qD൵f̘'\!6**&f82j|%YA!WsΚ ڵgOCp *wggeÆeeLq}>d;uuWQTU55lTEԈ &&"Bt]Eonno~iF@"9|xV r1tz#5m_].eĆY29_p7wŀd dB׮>wtP*gl6Բ1\4q〒G z~[o4 x۽8p;csW\`Q<'dfϞ1#=wH{q،:cƜ9W]EBsCUU'R˅H.w:-h޹&54Pi 생<hn޹3?XS.m2PV$ X'7^`ܲ WeL ; O(y<tkoqDLWV Çj5ZHk|N#FDG-KQ r~⒒fs9w.)ij[wU*F *8Wd$Lmm--SAtՕ6[UUe%uW_ h4]]?Lr䏷5km˓:53C]7^ww2*DIӠ)ujT 2//ч,[ \pIYY=lWK/KC懛3/1b؛n⃡m\TT] 46ju[[E`2jjvj~oX+4ǻ9G)R0xi<s]]d zOitk߰f`N~" ewO΂LT8K.6-'5*=]V`׮~z]h޽{O' 'L&̤$`sY4ee  fͪU6))EE}DGH$~5ˁWIN+|uN`Ҫ$f_ 55.THu0n]wK]¦9oxf5[|Ë}Ad\3gȑTsEN~?57UU@kkssu5hZBTTC\C` #T_j|yÀq~?tV+Z_OŎbb\& !HHH8, 4-u_ x"w,)ٷԙ3P z C!Bpr% B4664t^(XMH2Z?ϋ~So2~S. 6~5bM* Θ1|8T֭۽ؿc8)V[^k1¤*11WUF?DDTՀTVSJE%2/"kQUUR83f<^z) щx@|>@|QQ&J\[qt<ZZ~x:%TǹyXdl Qpa>H`aennjjt40vlVV\1*GԴldM=|2ՉUd  (_$Zv:<srlMԻ^v Iq10lP] DEq\I x tMRJN'tΛ@ >u*l21q@^@gft{Z,|3+TWW]M~;:D"@h B#+> hKr{|~4OF#|X hL&SXL~_ ^4x/`O@lbL~::g897m6*z^/NK}/̚ */+FP;:SXQ('$"ѢEH$ Ç+w,t6"z/qd\ ЯJ$`@uuECNU*Zi@e35'=/ @uT`~ - CǿR)dgjPkQ_b}py$>J$--@]]y߿wwP5.DJ[ jH@BBrFtuuvrp #Gtuͭ@Uնm? XEEǓ}EϧR4PV\)Q?dQ(Jr@ssS46׻\a#G@aTj:oiid4ry|#-}O/[9H~S3eJQ w=S^U.#'(/C\"F *}ob_8@j%hDp晓&EEj5P^^Zjɩ.`TBA|񱱀˕8mphcLfvvzd{^qEXؗ|+zQ.F?>* ;6"89s/j`V Lt) ik=tO#}/.`\i"7^|Zɧ+7~|,ߣq\̀]+o6?]6dX (2܁%~? @tJu-lȝV'Pc'|f!㨜a[Wf#\~j"ӔHx7˻VMRrs) 3,Dt_IY-'n~f[5yH NAի1cƏٱ1"/h$ ۷gB|u`펈 u*8/ 2_McW}~_=p#Pfo>J.*)[q^dc,L1&Mf2sw^|q#1hā\.CkuY/z` Qhb!p8~?~XSdgtNGJ$M"/{/ua CCm֦O$d q|Tټ(s0' x'|@||sX  b1lt\DR. 8!qH72D՗Dٹ޲JecC@dΝ}gMI &$DF ^18 #)*DBvLG`xDױi<jZ,55N'b </3;""2B w3cIk55UUޟE G L0eJTR)=' cA+O^*!I$`~zmz|?`C !?i,UW$)+DLы({oD"X495"0a;:VX;edn ! ɯ l$ Q"@+BJr*Un.M0z=EL&J).ՒJr⸈~aPh`h)dvk}xm>D Y+J'1 :\g TTHH =c{Dck65Q~]g QгZ'fd:BA{.Y$Ih~p/':6եMvq wa~F$A p-vs;ę;@"!%:v{c흝@KKGGm-‰l\\(DQRYYIo6Pl~.l6 xų΀x'64#,fLwbV ËfBT8~^oC"(q:8x 0Y9do=l/{Pt9a緙Q?3ً*4=gv˂ `~`{>nks78$0&$,ʢ^v$$Ѣ7N4=/l}8tS 8z\mH'w87&Sx";U*:?QI=R&s80a+0"3C?o_FEX2TVQ", w?Pw1C~4&z򿣖dz=?bmKV<&J3ˇ #~d>HvV c{HNPPP(^zcư&e6=44X;(CojɪU_Ouwɖ&[#lǮ]˖GΘqq*dfW_iE$="HERv4:?xbNg6E,&0uߙw h4d,?*;䋆4>fdde8=30?.f"',f#Nhhx$ *sN0n~RU2|D\pƻFOV }gy? WP iiU*[$N#0&]/.N$ۛ~cbpbJMl ZZ] d^ :;$YR"6 hyp3 d{8Є3}od\N:ݯ+ eeNOnH26q@#1#BAl%̘##kX;U*|t:99. de~?V+dl쭻.!d1?';LFYDCUiH}i =Cޒ)n3ݤtwuD@fGc vj'defRC B.g~!'d%&"fD>T_ Ԕ}VKGS l^uqW."h8UϮ\^/M}CqqXR)f34/BY93GCw^B/!!1Q)"d^LE:;m62c~Ch8^nj"2wFC`,E0Cpl9^4.fŖYc-b<8,hto?'~'߉_] ^fb|?t`rsr9 `T%H30ٞkX\Nt:]9X&(L.I/ ^IѨP\tS';1VDZtM*b6}>hm¯㙒BYIZmb=`9@#n'`bi51CzzFZMaYn6|| 6*$ٰogllR~ E=ct8b w8f2cTo@xЙ&GR 'rJkx,wkR{?r1%Cf&~@v<|x.)Dkoh-pdnt`DN98wRHd2Q=T* k0Qz=Eh[hlcYuuѣC6#F4667^&QhXl2=ʧDdTEd8DB:r90i鑑ZM]e ee.<4$$l$IHj}>͍t&S\+1! ~4a(r9mTTmlVШ43+#& )|GtֈjC?p_?ގNg{;=Q2o9Z'&55k48wP6/Om=K$uͳz (*kJݤ9:jL6v,F(~=7SV h4JRy*;G]6e. .S"4>x8JSS0(+VG]ݔ)@\e p<8̉ @?\5jXرm6^jkkm%rD2,e 118qL 㩩!H- _v;c@j)bXn~8]%$ ̘3*?1(\S(F2$'bRШBfkJr.DBMaDwuɋy6)I$lJko{uOKZ(4\Px+{ҾT}ftyVžoDb@3Br@甌*:+Q֓EE^Vu-#eK3Y#V*К :PݴDHx҈%$$'+dJn7q.T #\lp@xH/utI$mmb~G0ҘcbJRILF#M& .FŮtf"FݽQ$'ވq7DdXզBARƒEAMMd%Zh,V.ܓHU*"QM _ɢ}7Vg.*>#I&n45@ E+K_[*o*IS"2ضqv;ppCC~>a; @zp` '&ΞVF#%9LvefssL xP*1c8`5"rI ef*SyL\8"s0$~aL'޿K1͓jm@$ ! 5777SDZH{@.'?*Y@lkki#,ML pIDD]p h>E\+)nyw]pB]"WS򙕊&ر$k {nu:~y~$&5 !spy'Fq(M*=c6}T *$rj5 eeUU6yy?gNGrz_2Dd -  j_5)թJ&#u|s\?ڀ7oہ#Gn>S]d6t:l8!R)P&"jqŊ'eT*{>Ѳ Sib"qt Yߙ̂%Zd2h ~pIc>K?b"bۻpj#sT6[m- x^9f;lf l(p@̟G]D!kh4ضFC)V+|8.vo֋^U>PT-z?G=VTT[i`> ̛,N'{_a/B`RKnjjt/P0d2xoÇɟÇk4q9 %L@,oITS(hUHDaU(XǷ.Jan3fώFw_l2^dI\py\`2.WW qj֪Tr9q:4*h H}RW (܍ ?"2v CrB!|d15: X.0PDQa~@99HEQ͋(L+Mܕz?PܵiǷx9S.K?\';\ 2Ɣpa /PNvs [>hU0. t C c|9PTT]}@ `QW*)l82;rnDW(! [tI̊H3l&鄡e rR r9֚J)41?~ Şln7In4D%L?;W'(?wr)Z`ϲwnz>p j1Ht ѐhLJ"-lP<[Afw(ݽR)W*ccI٦`&"=eqœ}/P>(BPg8ŕJ5f̘1aB@}ZRTVj5՛4E҄e(}{^"1Ng\PV6}ƍG3>;1;PZzE5hH):Z&ƌ9Lp8:;YKI'̚ɷ(bJw1111F&zܷ9JyV\΂[ P-ʻO#暟a~ِ lSwaZ KN={""i`?>3bcBX C {/t:Tc8iٰn8o)FS!E/ӕZ^.F$QJtGGOY|`,ׄƵ0A8U2Лi27Cn@bbj*KX(҄\*O!@%L&ZBȌ4YP6'A(*ڽ k&2Ht:Lm#hv;0\ ]O\.O6}_}c~UGG}}Wа{X,n7BIN8PcQ;Zy{3Ƹ.,oe43(ݭBQpxH4Jܽ+[fZ/Ō+u8B**l)+:{G)]*.PjAdd`aߖ^`'3FqIWWgg(DT>8;r㡬VI,l *ZőÞJ*e~G*=:;vz]. t>˯Ӱ&)Wn9y{'%"I}|1jnBqGVkmtv66:ɔA] ]{^Pޅy!z7c,bF|z MP(ϵy~5|tƏ8HcFV+"1x|9VNNkT|EJ].KRh JYّ#>*`҃' k?\ H HLEҔ f͚camޅ@]v IS xN߽X p]H(:mm]]K!MOӱDTh/4<"DOlP Tvq4 czd~5VTh4ˆR< ҴRm|8BAf5UIdE ow:֮K?,C uW_KYׁO.Z_?7йB17Qf646:@kg11ّLƊV+RTFG$_@_I^Ȫ]Tvô/V|Q/Ȅ417\^^S47S&yku}v፷8^?*5߫|:j?n[۵hC5@^ޘ1 =b t8YA1x5e0I&>pPQ 4Y3]v3[y04Fl`ؽ#o5ws}ֳ–y|EA~ ܔF`Aoy,5޽&6YII@ddj*MHXXf)+l;sc/+-'z߱ef7_= (|pu7RisQ;7rdD-E2SR(6P2D!ɬly/Zj45_Q$~2ɿI)gn>pY3yύ럾h@}|?xj=?^8 ²p@Oa'7bt׵KZrݹeŸNH/K?j܂OUʥ g6mŊ*U{܀lTzi( >>*dRRe2.H*JyaPZ )jk:ee$1u`ܡagk&d04{߰C^8}<;N潿Vc^x_crxq60KR j߻^DYu]V[UwG_qʺOD<6N+u׿[ /rl@?e7(|'XZtC? vYq8T/v"#5]r-'wzŹOTG=Xd]:ʶ|/z:کx>ٝX?~4|'꓃/l'U3ɳ%+_{_٦5*V>`ϙ9(_e\.'~Xsqg~{{&/w5z<qC NS-~;՛w z1dݳu߁B]2zg~ppS;v^ٴ~f䗯5D=Y,3ogj׭Oڜq׶j~J /ō-ۀq-0ه.gw^t祋Oh}QQyp34_f {5ryTY0fW*PcMuDixV"f]u?o뗀5dMqY@Gv")c\,"H1BuM0跥މe|7uȣnk=MW;G\pFɳgg5Uu7 ohhh! h7DC44!!  ohhxC4D@ OE%tEXtdate:create2009-08-31T01:36:31+02:00p+T%tEXtdate:modify2009-08-31T01:36:31+02:00@tEXtsvg:base-urifile:///home/chenno/projects/elyxer/test/elyxer.svg*#IENDB`elyxer-1.2.5/test/with images-1-5.lyx0000644000175000017500000000446712074107030016560 0ustar chennochenno#LyX 1.5.7 created this file. For more info see http://www.lyx.org/ \lyxformat 276 \begin_document \begin_header \textclass article \begin_preamble % eLyXer -- convert LyX source files to HTML output. % % Copyright (C) 2009-2010 Alex Fernández % % This program is free software: 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 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 % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . \end_preamble \language english \inputencoding auto \font_roman default \font_sans default \font_typewriter default \font_default_family default \font_sc false \font_osf false \font_sf_scale 100 \font_tt_scale 100 \graphics default \paperfontsize default \spacing single \papersize default \use_geometry false \use_amsmath 1 \use_esint 1 \cite_engine basic \use_bibtopic false \paperorientation portrait \secnumdepth 3 \tocdepth 3 \paragraph_separation skip \defskip medskip \quotes_language english \papercolumns 1 \papersides 1 \paperpagestyle default \tracking_changes false \output_changes false \author "" \author "" \end_header \begin_body \begin_layout Title Images Tests \end_layout \begin_layout Standard \begin_inset Graphics filename elyxer-svg.svg lyxscale 50 scale 50 \end_inset First image: regular path. \end_layout \begin_layout Standard \begin_inset Graphics filename elyxer-svg.svg lyxscale 50 scale 50 \end_inset Second image: convoluted path. \end_layout \begin_layout Standard \begin_inset Graphics filename ../docs/elyxer.svg lyxscale 50 scale 50 \end_inset Third image: from another directory. \end_layout \begin_layout Standard \begin_inset Graphics filename mini-elyxer.jpg \end_inset Fourth image: from a JPEG file. \end_layout \begin_layout Standard \begin_inset Graphics filename square.png lyxscale 1000 scale 1000 \end_inset Fifth image: from a PNG file. \end_layout \end_body \end_document elyxer-1.2.5/test/docs/0000755000175000017500000000000012074107030014236 5ustar chennochennoelyxer-1.2.5/test/docs/elyxer.png0000644000175000017500000010235512074107030016262 0ustar chennochennoPNG  IHDR_nbKGD X pHYs229 vpAgIDATx}w|iջdɽWt 5!$@H $! ͗PrC rS$Z l{%]q|Z gvfvvy9(Gr!q>r!ӅC9!-rC9[0r`90n#ra"G9øEs!qC}nv۷ottttttJRT… .\̜9s̙sᣍ~@x<x^{5oxcqM7X,xӦM6m_׿50}ӧ!b{o xgy Rp8l6f qؿBP(<3>8]N%X,:uԩSzAhrFٶT*J,^xOӟ{rÍ,}w}z5׈jZV B“W6&D|^>>[nݺu89C:rNQz^೟g?Y3f̘1Cl+Zbz„ &Lo߾}M0\`׾}k^X#ɖ͛7o<`֭[n=ݣCnpPYYYYYyG3> // @@"qF0N,8Q"ljjjjj:묳:ԟo9|#8|ÇE-3-8dIr'[5838Cw99hxㆍ6nn馛nr(#GGqA%fk׮]_$r =p8,Rm."JٳgϞ ̝;wܹms#q ̕ :eZ[[[[[E5믿?ݣCM{ pǎ;vH_/wp`0 ?NG^{}rxqD=BDI:Xexȗ9p,{99|Ks=sb3qx,ǀD2LAV@JR Dqat9ʋ0N5M ywySH$' )gKޠjI!O[t\. CP8}{6dlgȮ]v\r%\r n&nx'H|#W >H>^]۲USؽ{ݻ}s瀫ꪫ:ݣs7s4b2K:N$Ï;-r?9kNh}+_W\p\pV=CP0Ę%x<uH$8tFC ņXAWJljh :@5B<O8_AorDqŸ%@Νc$w$Dwwq{87Fc]+sk7F{--@0lLħFv`}60uqK$@ɖ?ªHėL9o B^/eL9L$B!Z~gNdr8> @3NMa8Csx``OwOwOg$"z[oN;ZZzz\.Z ==N{tp:=@Fcx"8F^Q6ɨ7v֖0aByy~>-mqca?Hr<"})/ 1/2T5fIY%H(X%>(~O\O||>ut w77w> KK+\n7f3{`Lz=i4)P4 `$8mOTV \yg6L~Lt==OvZ( H&c1"HzA{&@h j]PzBҳ8xqK 87567 bx" X,FN,Z4uje%0yrUUa!`Lǚ ? vdb_yE8)AP(J">RZ P(J$7onoVZaȑ~sp^PRRTK~]p՗_>e PPp~7FjTlEcјD>QYOvRbjG"776+WnDxW+_.ILZVI9[irU;zW;Z46 'Vضs"($ .; -) I.ٞ@cAUؒ?4ЬJ%/ZK rV՚@QQQ"~. kp2}D?ڵ֭;vtwC]qt"h(Iq̀Vk4׋9hb`65K/KEaґĵk| o܉ʀYKK`J2+٬k4@UJ%I0iD2IR<hFDbd2-Blk˾JR߫V[{7v`-+w Mm#=Շw:?=UW ɚ YNsDS?Z +*****F}-[}ZZfϮΊ8Rl7Xĉ'N*2l`<d a[`-0 9뮻ɌFcx}q @_Sgח ee!p۳\7L ,P"cbDUWs@_/ ^lTj5:0w~|艏1n .ᅣQvrªU{V\ӫ,,<'%>(G?oF<jl z!.nǭ.]|~`Ŋ+{/뮛>">}iʄ\t(&l b1zaA`fc'_G^O5F r*L:G'd2k׬YBbŋ/ 5W׿h<<ˆqK555555믽k/7ܱhX` ʉU JKm6,G(lB*4^N8>Ea7&eBPXeg"KPr 1z p:~߸Esc悂+>. Ri4aFfh4juxp  7pu3fU4X7FgR-;%%:ߏ 0޳g&薽 ^@ uPzQ]Uէ?կĉf*@کD'MM>D4_׬ M;= p$֖-U^-ȆrcȾcǮ]==d|Km%?yoV{ϣu T$a={zz)/z j.ۏYFlϦΙ3sfi)pyg]SYnX/jjk'LN22f/NG7H"Àӹe˻JtD.W_?V[,v;`6N8 bdkVrDˣ\nO3355TWrz0ɽ,y71A2fS}am:;r/TjupIf̸jihZ|$ |>_4JI+**(3;omBQPd JRT|xmׯXZl08aoX Z^PM'Es䕀^_RRUED' +ަ={#Gx}3f~jq4q'9̂-[P(;Z O8;4D<HdF__kDKx1*c,O-3W"ql4L|`EnXwyɫd/~fL&`Ui2Z`ܹ_sʹiuz2e9sn%R5{WI{er"^$x4tBu5%<6/PbyrT׮_xǀ/&`ڴ|#,Xz玖fS/[;?)N {kى!kabx9aq}^Ri zEŋ}}vZr\ٳYawtwG痉ٖ7})EE…WT+%l{͙S_L#~PU^~?js} ݗZ":m9sPM&EJpx}嗁w |O~~~&Ӌ7< }rc{IE",`0Ղ &y72y 4Kx|!ό+,r4|'m):o8nߗCbK/zdE""9[l;kP^p$J(ɃHھ]BtGmt>_Kˁ"b4y@/.N OmA&˟xڱcZ`˯XUNr(Ljlۓ8$E}rfiVUYcdKL\͈` DPUzad+Yg{WB޻>,ӱl#IRFE#;sY()"8УuFQoAo'R6n|MRY/׭{5 xϱd<hf]pF|8 ѱtق`¿ujbih9Sz2G% <ާ:(GG ue(*cKL@$r,Ejm6%#o|@XvÆtK~\_~2V/o6LNT__P^Eh2F"n|@w7 qΝPRl6W]OWy]x]۷*pHsݔ!~ 孒Iz1BE.)).XrI 's޼y^]N#"A```ݺ_WZ pnL)_p0$N2L&`(-$G}X\}}D|3:ٿ͋o*QZ*prǣ(?(c(vhj/;=&B7V:XR \哟Iʷ3oXq^:q\$HZNG=7(WoojsfΤ:]&fϟ:8%KN9碋(~1s:ɶ:8Hb8,RJdOq(0x,lv՘A {z$UJHuڱc: D"lS*5RY&wTE0u+O>  &ΙL@4j4g\6⓯#8xu0zx$⳥Y,6ĉ@__ooKKLFJZ{@?DJ"dpe/5])"_ VQU*P,>uۺW:/v8"rL-`ʔ"/o tz@omfssڵԸna3#͊%GXΝQ٪+|*+{!I[JdcN71=67wu9@⨱ >0P\&`0kkº:1vM;8 }tÆ'뮻ʩSPRGA_TE[{;vVfR`WXZ,WTdL@^y9>%HQ,ٹCCTvlLuȑ@xJ}|A&zTU}<]q7ڇ] t:E 3OZZIih:֖꫁l4~:lG͛Q|3^;}:pphLR\"Pb)Jںy3wȆ ںe &n"-[xܽGKZģUHz0 ,Ued߿mp={„f}T`Ҥ)Svؾ}ӦnԔ~ .¡u6ShTd2si%%?yf'L+*Uh#GF'AeZMha`vv (_HP 9(|?otf{'Ϝ}NMg>̚UZdɇ_ ;:$F{z3\X'Ϛum@OOwwK =5:75ҋ.jhniq(JS=? @'L&2Uj,8o}Kx&'PsswuIu. ?ȑ  Ob1)14xi!m `XZ֮4iR ~ ꫧwsΩpALώw㜹?1xqmן{48^ cpyٵkE;˓e5{zm_>{vx7F4 uu+Wگ~4665h~rP^^V\~UW}{O}kywݻWBA}m={eFhmݴTw<>wu.׶mk*̙W\h4_ԑZ(bH6p8`0dظnᦦXlz=LՁV/XCK|o[7( ÆqKk*;&M,(s'OِHbCC޽۷o$Jԏ:U9Ef;㌯|j L҆ ZظaPP@ѱe VӎÏ7MM}mFCJ%Gňh2i4dHIBlm=r$6n\k$@@]7PEQFwr 0"*c@8|HlRS Js$(Tc*BA6چ8xpa  (>@a2Io=ZOjz n _N⊥K*=>+(u*x]v٢E RWT9eݺ={ہUvlkBg/ r`T'*ahtwG"@oogg4J )V#"J}K];٬坂lwt(J%WTZsz.gO~̸!p8 ;iR)6*Ѩ̚E&a'\3mR #‹/Ry"A6,ʢqpR TW:$Q*EؔFѐhT"dp8"Jٽ.$SUuPX%'BqJ/BJ>kyT!Kz>kp0YBd8q2Gb1}I T )jMU~M&p/~v-,X|S~'9Bx{/֯߿or`۶ë=J= Jnj/ >}˴bm<( >cQ ۠ /F#"X 0&&I (DT 72`  Ӧ>0sf~>`it [>rٳu+wt $S\v ^r  â$>VJTRQx Wju:l|j5*P\\Zj0-/z{~'7o‚`PJ|,*"t:ry"Et[UU0sfYم<'G^w;;Kׯ`۟SdTV>JT&"e.tf~^O·onu}>RiB"~h4 //?_%O Iq9Z-NfJEq( `ggPTBmoomP0Iz1JˮJGU>E3"RaƬrQ6$ZhT!Z6*Idɮ7&O6nEEڿxزeffh)L&c1tn'U2.W_/I%.䱪S(P[A 55uuf30{y0s9yy驆,:4 v  B()``NP(ZjԪ 74Og9dopz W__0HHfQ*ɓb0 j5e )DR' j4B!z}RT0 E۾{vn3ibMCKO r+|n`׮ěBQ(x\F?Y 5p8 o>ݣz^x lFXLp:Is損#Fi11j+@Q%PIecf'AGGk/kϞ;)LǁŽlljȬ`#$*VD@8];+Wٹ! ?&BCL!" '@wwGG O*<;gXu# ,)-ٵkhT~[LLulZ-5~>^=kOKLH^CGuum<ҥ_DiHdω!H x, ~xnj_yDyG?NTUVĘ'N*{9ۉ8.m`v SQ B}0^dVFYfU!4I@t|1ft>J%_X$b$h&2"BoIYU%ekkK xd\^b֮]b 'On]ORʜ h}{$AS*ǶZ-ۻ曁 .hhE18M5͛z Wz/ єnFLMW%BRX鮻A1_oϼ 2g9A^?}{_g>N2PPihx|۶F/ ӠP'GIIi()"77{-7 o8_Z|=5xgd(ϴ_cyQ R8GDDŽ( ,9J0F/ -J3E]۶ TT?ϦOn_N-[6n<\Q*M&^n@'O;ڵ-_<ҥwTT8& Ru  2zaT#FBQ[ 8&ӝwm8Ip#m|9?TPhӦ/Y:Qj[,ƶ> .rZT@AAq^O*\2 dZVL74$Dj5BP@XrD^bjMl:y8}=tCN*ቜ`,KmBeN  1 /?"(/2EBDz=6 vSbfY;J'4~dR>|U5?[3i#M| ׿z۾ TTLzhӛZ2PXRTR̤*2b0k$PVr=_رM9i\Z{@2cbHm}4 %1zn*6@ l~Z-ep@磔.A|DtVB^[*P* I62%A":@A U|:y>؋G,AJeDT;R^^Yi0&"fhŠ{zC!੧x. `ƌ3v5(i<ġF"ΝnYg6^_Twliۿ{/} | /x ^OKӛ"}{熆~ʭ[FOp 7l>qr0sfU~W'+TORgSU3}_;+X*<>X2E! @jٴZ``/NA Ϫ4KDR"H$,WGIU%! RYF2I*'-(µIR '(*HU9ABVKN^f 8CG"dZhQZm;TxUJJJJt:!ɳ`pX=}` ??H4 SUV-\HFOzAC/WqJJ %Kv]:q2&5=Aw:OJ8p#'H9ƫ$g4vwl9BەJ 3v Y5|]  T;v]G6)RyS%d}t@߁~ʰ`FkJ԰La)T[tD*1r聁P$&"t"@n)$S&{dD+g"Z8KR%@2 QJ|&HZ"@ ǁPHHbaɯ;yOvZ$PPP\l0nEȚ9]]_>e׿/[v]"s$/m66;zJR&qn|+5J,LJu޽$9&hTyWZ5DPGT#;E|| .4?8`45YPA\6@s:[ZK.O T$N?-%>NPFi dcbgYH$u MXlLP, TD`*%^)%@X"#M.踉K"PNlMgN!$g65<Թ"^d԰FF =D+O06[^HIЉݻd@ƙ0N9]o߲ebɨ*,4)=YqzcDP=P*H9~(UrB*FC.KD\ɤqih &^1NǍPJJVoqϋֶm`4mJ 46D BdvldfG}3\ Ι^̦ `@`-Gְ75?2*hLiiyHHWI"epdmfŢVSj pLț6_tjuuT@mCCN'[K}xCDJll߿wߒ-[S>;v{G:$9KIy95xD%~PZJ, vMy  U?XBiDp?M ~` Q'87yR@IɊ5Ւ$w?p DJK'Oa;:LIUؤ!5IH/B;dKg@dnxTOPJ[(D&K<$Ad:/a; S|9U(JޟcmTsu{ PmڨڂA47*S٤!@b8X2: hnܺ4૯n닊J"zb(RJlTeW*dYY$Iңb0h BtV+ U|}]JUPl|,!21TJWTeAe $T.i`7D#g NR؊<:' OF5zhȟI2a0t;)R!NdddI ==ԎHH,ѵ81 ZFTTTWSYf*T_:;NXm>s>F/6;s {9QJeEi?>_El:sv Iy$}{AZVFD@Smy=*5m4(YU8B3DRdB!U~L{eRY"[H2I&@MGBa6j5Zttju^lStHZN @ns{~qr}1IQ6KK:;'M8_B~L0p^oX\Z({R?D8|!c$ IhҔiDj4 \bJ|lz'*K V*bNh繐j4JĞ)%dN6iJpߧ`;JR<^T*-XHE"4j%G^U<^T(L6L7?  Kw0r'?TN ."k(Dc̉L<*Hq r! JI׋WS y4AGKŒ+4%D5ĒIH_\.RWG,r> ddxhQTeh4_I It_89%'4X hnnj2щ%k}h ܩϓVKϪ5+k!YJPL$V9rxd5b` l3o߫>tSXC8sܹ4řc0h&'M*i&',J@ydp륪!΋E7GVeF"HB@(DK ;bT y(\QRIi?4e ӕRXI(TE%B(T%l\D}K:/pRɃT49#K-ORN|&B^τGi=%gyy: ($6*P3q$|f/1{;x<ce4z{C!a ;-_tnNDǑ~,DVS}EzstY#5e8`0M jmo~3mM4DE,Qqݥf|H#$=yGj"P(lOW5<`RNnl`c{ 'vԼSx< %FJ:* 9^-U*T9U*)5,sNUǤIV<1Ye@/%TL 8N0UU6""? b!I$+&>}rqv>n7IB"'$@~ޥrgiJ=?,#uNI`.h8(HBVL$nڲe?iij{A{* όVj3yDTa'"Y:X.GMڀj 91Q*8ZRAu:D(xVXLxh(Cի)BΓbjK( 񥄗}:eȽ,tDC#cI/l7,ҁD|Lrp _BN2A\4rUZlHU'aM7D\c(G/t0Z-9J+V<T?ko߼()۫iY$~ vǶL<Z#].%OkKi,FUV6iWRR^NKxs3RD~Ng2Q|"DJB^lė:AK|3R,R9P<]-Z2/oɍ bI&+v6-$@&}SCn4 FC2#9];S#֥*/{}Z2c-t:K*-2SJJHjiz.ZF#ߧRYPOkΛF7oӟ/{H/*yp]6 &KANxY,qcd#OSHǪn(DҺR MRﱔ4ӥ-1&]!ᴍ 382|}+)O/֠OH#pB`0śTzLCdBFB: VVr[ʽ{ ?*1Rl0)ҿ=SA94*>qƍ}G5i<ѨVϞ-p< /] ;2?F6}Pz< FKτ;zER9Fcc=WYᣉ@^ ەXiJ RQAuV$B^hqwma%2wX,)DJ-*H"Vyt:A:-Y ?$kbω`2鴣ߝFX(HA_*Rĉ{g~\, UEvVYF`XbɖpPА-ˏ̽ h,*@HRe44l@cYgu$NR%%FwK8ҥhqUe;bة {z߱Ty]rY~hVBD"ҏT@5ZKK?a2i4v `x8^x"7h!̈́ɬ*Ht A^ c|(%%[JE>EeE?6-z2`P#jJ-m h?};,'p(セ1ADJ$wcv`'zƩkEE9rQDRE!+`dqHX2eܦ'Ɨzq:Z-OZہ P6FdpE9M%H~@r=xkkI=NXHRtLldbjkt"XHt:=㱥UV⋀^WRRU iZNq(䁜)_X,`0PCFla6F٬5?cÇNNWT 8Dª7K^MqVU z<ҥZM9UUz=Ida*1:W`vq3K_8L,Yd[ @6Czf!L&S(D}*>'tY>__KS>pz}Qi #r"}uqhI$@Yu OMj6fA=#Դ2hB )3`t:b2YkV T`#'.u?vu:*uri~x8liiy ȑ;j?ni`@jj|>"&GU(Dd~ImP<+_>C*!& S(rr'L0hVj)m%T Xk# e`B$Y !¯JDx\Η$H&nBJKȴnk'ʺq#EV*IEDZ"nN;#o-*|Yu-553g<`AAUUmmm]v" |iJp̜Iq~ TRUbq>?vfsYىd:Dcxbd"DE#ܷ{`u̵׺\j5p?meeݟ[V+TB6S9<*+kjF`'_JEeL&Q .`Pt5yA4e #?ݝPq :T;x< eEu25TEy7:;>>K~逩^\>89^ӈZtS.X(r$d vvw[;.L៩~쟤7$<#ҚF"c~rHU{loip/⭷\py@II~P$ \w(Fs|BhQ9m#[N?%pn6{K^MX(m"AeZ/]fޟwzz#G={:;{$a`"O.V% @&' --@4g? I"|DO&MIJ4Z-`v;0}̙f3@yZ- d [J %pD,f`Lz}SbD 2)7olI뼬(H\B-/O9p}Q,B {Mk/l|G;kFAɳfz= ]xRm(,u Ӓ|, Jņiaȝ&%\nj0z0FJ|ttum~w={zG3oEN!ذa޶6`Φƞn"YU˩w DƍN:=$IPrȶakWGǪU R C]ڨ8|h^{hmA pV@yUUF#I^옪Ȼ54@iiYNTWqW6ljez^r: GU)lDK.tK! #s+WbKZJ or$TVJ3g8טWJ-zfauO&¨fKŵu31[$\t[jŋUr2Mq>paUƍ#ѨѨEcҥT';M,2"Bi@Ԯ4a18ON-Cj H؋ӯAD'I&KyJ|]]pÛ.<|1Ό<sΙ6M,N'rAAa`@$@iIg; С3hޠT*RACzzl )SiO)i0ş\1I0UU*[[Rw72k֜9V+x [JaljPȄjG/Re\6KHxS)%+B);tI$@aaQNG6Pv<^:b^΅PY2TDB I=l{$HV!co/ Xp3Ϥ N5b ++kC^07XRDtL 0 T*Rْ&i~JPg9HW==D4k;'}Wx߳ /GB08448ʕ?P*zDJJK' L^wwv]Kہbry:`DRՏX|(Ǜؾ}ŏ=xxg[,D%I~8MdDK|KcBSSOvZEH6B~BcF3 yq@N _4YF*5m#0WM{ >55f-Xp,h{JIq~vIdhhOnJN4&rg41F l?'vLؾRp* csZ~lLjp`I2z5Zb:FHx)vW(h$˜VӧSRYQ{"%wزԃ'o~SS#4={v ׬q+!:! $h4xU]8%C*u=g8Yt%Vs]7mS،$?燎gSXxH2~:_$^75Ӧ{ɈQ'M9Ng*~?tM 7߃RQEpO# YT:r x3e0Q eeTh2^.{.SJK]8Y@$y<=/'c„S`ɏl\:]& g̡C==\v;U>Ldqj2އBC`0(BBb]IrRK]/]‡"#E& Tdj?Y’K*1WnfIKIӦLvl>0 Q^zEԁO5TR6Gk>;2"yyBq )?!эFi [Z n1+--"p:} P=ɶ>jK,WIFMG7n|s{4A'qϞe˞zh?e@2I u:!4!B!S`8& 0k0ejjtK)*, k!AjuK|I=_x2jt9^hRh%KV˯xMM=*,0+l}m!./! FjbTﱨDɋt DE18HpX*@M 90Y\wnRR2G0.AKjk9UU?80m 7qo]K>%I|PyS&x?UEE',~2Q$EM6s}ܹf3tRh$7{RPas*f1 /y4!ǒW(CF**lGG{{8  PZZZRsAxzYVtd`s!Abbft*FÒ?1p- @f?X0 `ʔ9sK./} 0O@gmu[԰|NǮ]O>@4>bOϞ=[Tn`0$Rl&۞NG̑oյwxa p8j Z-{{)0yǎwZ[Lh:u:n*x6_i)l~ʿ-uwXhʶn| (-\**@.lp`a'ѦV+l6MExs?j2!†(H364f3UTh I˶! FEuk` #I1?JP(:S(W X Y/E=+=d2[cמyX!ipY4z=%ld0)BҜI^JmCM Hi(x}j-uƷDFC //۵cӟ.ՕI3/,-R*>J :;ID0 RRbO'W@2Ҁ]cǕ>1BM/(=^__ooWrĉWW"MD%U-v[N Vat:ZWU @M IDeeZ-e 9Mf .((,s!3Kiy*ytTl6Tde%|`9ϧ;%75F)Ӆ{q_bi sx {zIp)Kn2~憻,'Vqzڀ^OnشiMp]6Evzz]K'T0SG f:2h+us:6:\M/Jp0.6" c^{DeLd0gpDrbd㔼VJY(Jaƌ'._\q1j8t:nMoJJ,ڹsF cR'h@JEejJr D:A* )`D}9RbsS0`kJ7 dv«Jٹi;;wֲeb'W=\YcDTTSL⥑>nL5Rl媶j˥.0ֶn]Gw!G|3dDό|R*IsFIuum^Db2E"c;,5 iixTqb,) )t @TiqWS3a> [PqI"xSonO?hO1"&LX1kVs}qbD/h9_ⷿ ф}~~7mHu9epb{0v@8gO(vHe0Rɽr/S$U{Es Fܗ^\8*ǁΎzޔ {}}]] F#Kσ|U*N60y8^IՕ:rpR| k׶ڦ:lQ(Hh|o"[}餶՜k)nWH [Z_ճ{En/*ߗfR#![j`gg B􍊊*VGD\܀$3)$BAvSMƷd^+8oRT.'٪&L>s_1󥗞xxeo~s@{vgjN?tH&hh0lF#_[k6Fwi"R5f*tؘ'"3^  xrښɓ.eM]8Z2=eG "LUYq3ŨtZ-RR=.WkkOb˯_Lq#W\t)޾`}@7IsOtbdAA2V Px B9t|&<&'Y^_ R4J{mm]gV%[wo>/nQ '@[*Uy@E>_?XA5Vr2ߚ)S[s'wկ`zu#cHL,ÔN)MfsQ 64XNGHٛ+CdOZomm@oΝl")綱kjjoO=V)#b63?~:qF&N>7<M{hfwW2ifi^bV1K(((*R)CmDBZLzF<'u4'%{_s$$Bg dTP({|~>z{{zb1{)xG̹xɑ}B9T0NrԜ'? |snoӟ+W>? x\Llr3[U&XJ2 47Q̘QXt"ud:ommkh\\V*1r"L?gFVKe,&$T\Rmx6ML blSsG&*#mm@WlGRՍFϿ.70|p5ӧ;@MM^ތ_w+=6̘̙p!l19溧ԌFʵM$HӑK98,lU|J|RA Cx|wP)/Wn/g|S-N;2Zf.{Gᢋ x{vׁ޾tHNt"d)%nQlrhC%m.6HP\. *񉭀TRRY>n:͖=a.R5=9TrTz6eLp[Iv=~UZf+~Lp饟{g./brJGn طoښ'NL̙$2qlv;U:fJTwI)Hj3(:RsYpST^$/59mD?"dqw::(0zma ),|]o|yep,p̩;QfϾjή.@d$gV2mE"=kٜfj)_<D"dA M=l*g3$(*Zq7󟓄*-x<Ν/@0#ȽY" DŽ 4)=Y!!|>_j5OZ\KNQ;&8s'LF*() 8|xRJR(D01Ll{qg{(@To<IS*oOtົ;:q`ݺիC!P(.+_.kL&;9'lc NN8Fc+<46C7 |Nunsj@*{zdL|oD^/PJxߗ~f |0.ߟ{nM  RэghDQvh .30 }j8|]nu&K-^ÿ=3K_~:kɒS~$vK}+wZD׮Ofxx" u:t;L;9 )qR\EػKKqfH z$p=0gT6mk+` s3ޟUUyyӎ2\{p]7LD#UISc'/A᱈G S__(+>}޼3y763̆t[`vJ> hFF_0x@ t|ُmKv9poo/|xBӟ_߱gHd; $mmKEE60y) 0u*j)$9W!2<؎M|ݱx@8 45ZBlֶlf 8Hb[fJe,sM(..- jX BA8NQ\rq;8ߟH(`4Je~~c#־ PR<{p0pS6>H$(+7~/X._Dc%̟E|+?|T⬫;.7y y>nyݞdTFOq_ /]{^N`֎W_}=-[u\@;H&'NI"ˤksȶiJnJ%׃ *6@2pUUW +*IqZhh(('>6`"\ԧիW^F8^[Xs*omYg.Y|hzzdžիہw}^N nl8MFWxׁөD2]]5Œ)IDATOc#47a @(|G%Qֳ^VMޠј̀Ţ9$UVVk}PVf?tn|΁Kի6nܺu۶LG&cUyJJop%?ħ>$r_z閛/صOSJIc%%Βb٠x룏>M+V<r![E٬T{B…3ft7TTqƩq@sHA, @o]7I]6M0e PR2gYgQt_E99!->?d9Ç9!-rC9[0r`90n#ra"G9øEs!qC9!-rC9[0r&dk8%tEXtdate:create2009-08-31T01:36:31+02:00p+T%tEXtdate:modify2009-08-31T01:36:31+02:00JtEXtsvg:base-urifile:///home/chenno/projects/elyxer/test/./../docs/elyxer.svgJYdIENDB`elyxer-1.2.5/test/docs/elyxer.jpg0000644000175000017500000001234512074107030016255 0ustar chennochennoJFIF22C       C oo" <!1A"Qa 2Bq#br$3R%S8 !1AQaq"23BRb ?=4h5{F;s=lٴiKɭS 8p_!@+(3_uwvd I"۽éV\ ||A5[[\;{BWKEDK3Jm)RХ; TF(F(F(F(F(#k?')9>8)L+: dF ?z:ү{м촬 q> "~d[rLxQL,ppOjDS)V|ԛU6z`2׃}G\$)Iz6 ڛOV'dUm&ƜkiS!1\JXC9LS$-C! ?_; .զ%]RɁ&R>~sYx,uN^ymlq(m *RprO;37HI 9!ws$Uǩ?1 ۫!kJֳHz8B@ ]#K"r H:ZZ+ɹAJdKZƠ{TIO.S *JBTqJqMCvoȎLVqըN`˗ɽux!Fr93ΟRҼ$em[TJ}46產{#}e]{ GYhdT噅T<PR~X=1ӗf[>0%7JUzHVzHE*PSWaPn PRJsܧ$̭HHRuI5P}%u>,k${c)!퐾 Wqfj*2rJ8RBiFM{\Ԫm=INe&#}}xg4EG8%Usg-SHbcfx  SaD`wJb._PFht$oN-@ZW4kTR\֪q)rDH5(>IS6ޮ)Tu d4\O}SKI?=rB M]qK_6S|i8#ƒV:0U4hfXG#M2?m՛պ#,"yGm(i( )jXBhjܱ$I앸BAH=V2aN-4}ڇ`HH _vu C6>&7Q;l#ѣF;vnP%12r%, 2I ##KĴG$čTR~Th }հ,]wtzUFHiD{zz]B5ӺPlSH4j2$CeխKRR"xtުU*4*ڔÈ#}NxER$o^ඎnzLݒ2J%R*$sAg q bb[*cp ~CKr8,)kԲJYpQY\k>X)׶ݭμ ~US % 6R[JBe CGgN 1G]O6n49u-ŎZZ,qd'=u@MT 5:0d8sNQwZ͸ijո,합d]SN^d1kv?+^jO<1*w%Ss'"ZNVYfIpoHuN-GTIԪYDߛ%EdF>(n+)邦vΊmOj9sR$)tjVg'^櫋cBƒuD@* F]<~pnAd-i1ĉ$+Ŷ~T='SXf^vEjz[ F^Bs0)PEDqFz]-ļ<0c6brbG)[׶=I}]@u [ Ȑ#py=zNwLʯq0ce0ᶵ%ST?OպV@ $IG=~Z<-P?5;!lsJ.uXWê9<~~; lT.,<HH)~G1tvHQ-Son^\gVv$q=ib8ZN/ Hsj1nѫT$'\JRU ADQTÍǪU[%\7k JՙjE*SKu=AGMC-nIn8[&ulW(Bz|iTT뎣JnNsa#A#ƨ}ţFW֥栅 y/"BhF1o:X;gHHF[ Cb;+':p~Mܧ(Iө46ٹrcS݋]^ZG8 =4W{m}yq_PIJJ֑[ѩTh.-K/bQ:)J.-X8kiooEI?5LT+=ګ=IU! KTS m8ꀦ = N;]e[90F!Ϗp+\ c?Û F#FeEښy m(aIROE=47iu.sgsOWס@ח WrD^lyMrK=N2u˧Wha#;\1M?lٍ=Ox. GP8#RKpm=:qn )^篦G}sn5xyƝO>QO n|Dmn 2uGʐRIVTzZ]-k* ȨB~!>Tˆe*%j<}ܓW5*a9aTiRJL!>@IJjqZiQr'=]>O{ ˻Rr @:Jow+:8#Aqkvz1ا-PeAe! A t]۵oP6 &Q?S Q)٘ܺV"Wj._vFBJAQ3ߋCPROB axm ''¾xcU>X?wAQA䢠H_ H'NZ*Ȏ؇mr?CWסEh\IG ny 4׉ m*ިEWh5q:n 9kPE? Fu) s,&DvʠXvҕ5 BV!d^j:Us\Pi2qqt6~n ckHle-iRQLrNBJNPJRY caSJoI٠\` f8)@+xOp ӟ D]5j0:}=$ #u^n:"ɯ3ө̏L'c68(1:(r2z*"}6Dƍ4jKU?uFD*[J͎}prMQY@Riy)^\ 9S΀qѦn[>"MI[M8B{|QڢiNZ :.+ :Uu=`MgܪW)̈́/*D)msIq'[h h6T#shyjwgk/je;WmQX/ JeM}>AN[F{r$?Hk{Veٔic^S 7(RIQI$뽣XfcSϝm}bxAQ-JLD\ :,~6d[WZ4}ClN^gXcR]"DZdHPrb䔀5ѠʰF+5elyxer-1.2.5/test/table-1-6.lyx0000644000175000017500000007426212074107030015447 0ustar chennochenno#LyX 1.6.5 created this file. For more info see http://www.lyx.org/ \lyxformat 345 \begin_document \begin_header \textclass article \begin_preamble % eLyXer -- convert LyX source files to HTML output. % % Copyright (C) 2009-2010 Alex Fernández % % This program is free software: 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 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 % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . \end_preamble \use_default_options true \language english \inputencoding auto \font_roman default \font_sans default \font_typewriter default \font_default_family default \font_sc false \font_osf false \font_sf_scale 100 \font_tt_scale 100 \graphics default \paperfontsize default \spacing single \use_hyperref false \papersize default \use_geometry false \use_amsmath 1 \use_esint 1 \cite_engine basic \use_bibtopic false \paperorientation portrait \secnumdepth 3 \tocdepth 3 \paragraph_separation skip \defskip medskip \quotes_language english \papercolumns 1 \papersides 1 \paperpagestyle default \tracking_changes false \output_changes false \author "" \author "" \end_header \begin_body \begin_layout Title Table Test \end_layout \begin_layout Author Alex Fernández (elyxer@gmail.com) \end_layout \begin_layout Standard This test may contain several tables. \end_layout \begin_layout Section Longtable \end_layout \begin_layout Standard The first one comes straight from the LyX User Guide, shortened. \end_layout \begin_layout Standard \align center \begin_inset Tabular \begin_inset Text \begin_layout Plain Layout \series bold Example Phone List (ignore the names) \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \series bold NAME \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \series bold TEL. \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \series bold Example Phone List \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \series bold NAME \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \series bold TEL. \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \series bold continue ... \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \series bold Annovi \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Silvia \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 555 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \series bold Bertoli \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Stefano \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 555 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \series bold Bozzi \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Walter \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 555 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \series bold Cachia \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Maurizio \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 555 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \series bold Cinquemani \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Giusi \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 555 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \series bold Colin \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Bernard \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 555 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \series bold Dal Bosco \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Carolina \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 555 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \series bold Dalpiaz \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Annamaria \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 555 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \series bold Feliciello \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Domenico \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 555 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \series bold Focarelli \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Paola \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 555 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \series bold Galletti \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Oreste \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 555 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \series bold Rizzardi \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Paola \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 555 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \series bold Malfatti \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Luciano \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 555 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \series bold Meneguzzo \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Roberto \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 555 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \series bold Pirpamer \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Erich \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 555 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \series bold Radina \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Claudio \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 555 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \series bold Unterkalmsteiner \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Frieda \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 555 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \series bold Vigna \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Jürgen \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 999 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \series bold Winkler \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Franz \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 555 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \series bold End \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \end_inset \end_layout \begin_layout Section Multicolumn \end_layout \begin_layout Standard The second table contains some multicolumn cells. \end_layout \begin_layout Standard \align center \begin_inset Tabular \begin_inset Text \begin_layout Plain Layout 12 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 3 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 4 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 1 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 23 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 4 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 1 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 2 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 3 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 4 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 1234 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 1 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 234 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 12 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 34 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 123 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 4 \end_layout \end_inset \end_inset \end_layout \begin_layout Section Alignment \end_layout \begin_layout Standard Now for some non-standard alignments. \end_layout \begin_layout Standard \begin_inset Tabular \begin_inset Text \begin_layout Plain Layout left \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout center \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout right \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout left-top \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \begin_inset Graphics filename elyxer.png \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout right-top \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout left-middle \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout center-middle \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \begin_inset Graphics filename elyxer.png \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \begin_inset Graphics filename elyxer.png \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout center-bottom \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout right-bottom \end_layout \end_inset \end_inset \end_layout \begin_layout Standard Bit of a mess, wasn't it. \end_layout \begin_layout Section Multi-row \end_layout \begin_layout Standard A table with several rows per cell. \end_layout \begin_layout Standard \begin_inset Tabular \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \series bold \size footnotesize First Part \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \series bold \size footnotesize Second Part \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \size footnotesize First subpart \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \size footnotesize Second subpart \end_layout \begin_layout Plain Layout \size footnotesize Now with a supplementary row \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \size footnotesize Third subpart \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \size footnotesize Fourth subpart \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \series bold \size footnotesize row \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \size footnotesize The first row \end_layout \begin_layout Plain Layout \size footnotesize The second row \end_layout \begin_layout Plain Layout \size scriptsize The third row \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \size footnotesize Empty \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \size footnotesize The first row \end_layout \begin_layout Plain Layout \size footnotesize The second row \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \size footnotesize Empty too \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \series bold \size footnotesize row \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \size footnotesize Only three rows: first \end_layout \begin_layout Plain Layout \size footnotesize Only three rows: second \end_layout \begin_layout Plain Layout \size footnotesize Only three rows: fourth \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \size scriptsize Mostly empty \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \size footnotesize Not empty \end_layout \end_inset \end_inset \end_layout \end_body \end_document elyxer-1.2.5/test/spacing.lyx0000644000175000017500000001556712074107030015506 0ustar chennochenno#LyX 1.6.7 created this file. For more info see http://www.lyx.org/ \lyxformat 345 \begin_document \begin_header \textclass article \begin_preamble % eLyXer -- convert LyX source files to HTML output. % % Copyright (C) 2009-2010 Alex Fernández % % This program is free software: 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 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 % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . \end_preamble \use_default_options false \language english \inputencoding auto \font_roman default \font_sans default \font_typewriter default \font_default_family default \font_sc false \font_osf false \font_sf_scale 100 \font_tt_scale 100 \graphics default \paperfontsize default \spacing single \use_hyperref false \papersize default \use_geometry false \use_amsmath 1 \use_esint 1 \cite_engine basic \use_bibtopic false \paperorientation portrait \secnumdepth 3 \tocdepth 3 \paragraph_separation indent \defskip medskip \quotes_language english \papercolumns 1 \papersides 1 \paperpagestyle default \tracking_changes false \output_changes false \author "" \author "" \end_header \begin_body \begin_layout Title Spacing Test \end_layout \begin_layout Section Paragraph \end_layout \begin_layout Standard As our world turns more complex, paragraph spacing tends to be more and more important. \end_layout \begin_layout Standard Some people would say that paragraph spacing is the first and foremost issue in our modern culture. Perhaps they can be said to be exaggerating, but not by much. \end_layout \begin_layout Section Issues in Horizontal Spacing \end_layout \begin_layout Standard Some new issues arise every day. Today we would like to explore horizontal fill. \end_layout \begin_layout Standard \begin_inset space \hfill{} \end_inset \begin_inset Tabular \begin_inset Text \begin_layout Plain Layout Cheese \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout available \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Red Leicester \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout no \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tilsit \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout no \end_layout \end_inset \end_inset \begin_inset space \hfill{} \end_inset \begin_inset Tabular \begin_inset Text \begin_layout Plain Layout Cheese \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout available \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Camembert \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout runny \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Cheddar \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout no \end_layout \end_inset \end_inset \begin_inset space \hfill{} \end_inset \end_layout \begin_layout Standard These tables should be separated by equal horizontal spacing. Can it be done? It should. \end_layout \begin_layout Subsection Horizontal Space \end_layout \begin_layout Standard The horizontal space is inserted using Insert\SpecialChar \menuseparator Format\SpecialChar \menuseparator Horizontal space. The result is as follows: a \begin_inset space \space{} \end_inset b \begin_inset space ~ \end_inset c \begin_inset space \enskip{} \end_inset d \begin_inset space \quad{} \end_inset e \begin_inset space \qquad{} \end_inset f. \end_layout \begin_layout Standard Custom spaces can also be used: 0 \begin_inset space \hspace{} \length 1cm \end_inset 1cm \begin_inset space \hspace{} \length 1in \end_inset 1in. \end_layout \begin_layout Subsection Half Spaces \end_layout \begin_layout Standard As reported by Uwe Stöhr: 22 \begin_inset space \thinspace{} \end_inset m, 3.53 \begin_inset space \thinspace{} \end_inset €. It is correctly converted to a thin space. \end_layout \begin_layout Section Issues in Vertical Spacing \end_layout \begin_layout Standard Vertical spacing can also be added. Let us now separate a few sentences with it. \end_layout \begin_layout Standard \begin_inset VSpace defskip \end_inset \end_layout \begin_layout Standard J. Losey \begin_inset VSpace smallskip \end_inset \end_layout \begin_layout Standard L. Anderson \begin_inset VSpace medskip \end_inset \end_layout \begin_layout Standard S. Kubrick \begin_inset VSpace bigskip \end_inset \end_layout \begin_layout Standard P.P. Pasolini \end_layout \begin_layout Standard \begin_inset VSpace 1.5ex \end_inset \end_layout \begin_layout Standard O. Welles \begin_inset VSpace 1in \end_inset \end_layout \begin_layout Standard The Late B. Forbes \end_layout \end_body \end_document elyxer-1.2.5/test/bibtex-plain.bib0000644000175000017500000000262012074107030016342 0ustar chennochenno%% eLyXer: test BibTeX bibliography. %% Created on 20090905 by Alex Fernandez. @preamble { This text should be ignored. } @STRING{ tei = "The Spanish Inquisition" } @sTrIng { cleese = "Cleese, J.M." } @string{ inlowercase = "string in lowercase" } @article { randomref, Author = {Colonel, S.W.}, Journal = {Journal of the Society for Putting Things onto Other Things}, Number = {1}, Pages = {1348--1350}, Publisher = {Monty Python Ltd}, Title = {{Summary for Year 1969}}, Volume = {457}, Year = {1969}} Comment outside an entry @article{unused, Author = {Teabag, J.M.}, Journal = {Journal of the Silly Walking Committee}, Number = {384}, Silly-Putty = putty-silly, Pages = {589--1530}, Publisher = {Monty Python Ltd}, Title = {{Some Techniques from our French Cousins}}, Volume = {3}, Year = {1970}} @article{reduced, Author = {Pudey, Z.X.}, Journal = {Private Walkings}, Title = {My Silly Walks}, Year = {1970}} @COMMENT { Do not look at the pretty lights } @comment { "A comment including double quotes because we like it." } @book {pythonesque:1971, Author = cleese # " and Palin, M.E.", Date-Added = {2009-09-05 16:32:00 +0100}, Date-Modified = {2009-09-05 16:33:00 +0100}, Publisher = "Python Monty " # "Editions", Title = {{And Now for Something Different from Voigtl{\"a}nder}}, Year = {1971}, Conceptual-Disaster = {{\"O}berg} } elyxer-1.2.5/test/elyxer-eps.png0000644000175000017500000002273412074107030016121 0ustar chennochennoPNG  IHDR:wbKGD X pHYsdd vpAgX @$IDATx}p}N>t-,#`˥83t`93@M`mjҤotJC&O&iJ3OfhqM0[~2"Jl" [/,ݝNoܭvng{ݻoyT*J8ˏww} (XEJAX>XzeWnW0a?CeK=67 ю XmF} fy,XqŨ#md+Psۃyn' 2,VHqko"e8re~EtX65sKBnoB7oSxkVGInajuկBUUF6aŪCS 5} ",VC 5pU[iTϞH D8bF uN{L=Rq80vb9 xAkFW@/."޳a b͈րnoW+ ,فr<8UEpz_q0NbU2<5øUDz5 a#*DZH0 <59BU311111Xw"3r|eeeeeeM1b%"?BU XzT2Q={p9d&SD*T!*ĸG{\kvv0alJ,O1Dq==b;ge +y5ʦ!b)ݻ+cBښ/BURӈ'bgRXǔ]tsWUF"Dp4H ͛xOoiC$rn_Yvk!0DP݈5V U{F-Rx裓'z(.+[򮻄KJKoM+p*SP՘o|Fh>Ko{#Y/\&{zKSэ :Bmmݾ}>VYܲQ7J$LG1n$"X1XA8?'"BөwܱlYmo~y wDZ!fg2.^{nX{jLa:DDuVuYڽMMx<75h?Yf(g˒% ,`=΍[AV"(NTd4Y"=yɯVE7j= CZد)=7[bjjjjjJyh?[bcc==DP8x1QIIyvMGAd ""M/@e (^#[zw??ℨZS )n!Rq"[5rKc?G^MTV6~sֳqp{`z!TڣZxdL&ɤ.Gq^WuDdEEEEEE"Ukjus?1sb㧞*".PBXF#B NK|k( BҬX굺T@:448qH 46A\RnJ/bB"Os7o޼y󈊋_ϨN$>XK8~ȵ~jPq˙H$$-Zٯ]v5"ᰒBnwPI$&&K ouF UQwjvjTDl_%^lh$ УokI&w\FOݻŲI7+\EjDH֨x {C RX yuY&{|t+FW7Jǭr,b 3=#EרVUuwa>s_X8b;yfޭ3J;,2ʎr‰Ҋ`*3802rk=ˏ|y5k+կ<P*nʷ "S6w'XF͹sw,[ʣشI*[>Pu2,T"m-w0ޫQܪ~EEg `FT>SDeHt[GnF06xRr(¨`GGO"?r`bg^KT9߅0:::ۍ~>2|oT+ekEZ"8r-+#IǤsé*ߺd@*evXDFoΥH5]:J /Dv]P͋D-L#9U0'P?.hȝf=XHnՃץH5(^!]").K,TcG fon{*JDD]]FO#Kt "׺:?)A']5ĚYGيs Z{:RƏjǏ?~<98R ?YVVuֳ:s܍GX-ۇ5RbA=5~WCGd,'wPϼH3ʗhŚr\aB{T=kyCZ\uyz.>szz/R.+-ۏ˥rŪzr-ܮ? pA+;>yg)U(nm#5fWu:'#U Jl>|-PoaѢ͛.6HFnz] k֗K uNAduӂ\ihhp̿=k7/=Ν+ֵguӯdnGAu)qqL?cX"+~Y (GGTSt0?&+J#ZPKޮ'r)4P5#͖9w6vuJA=vhu*@ݍHu/ﱻ*RDWOŚjpqي-U`dbh1I"11qٳD7tmWV||?ee+WmTkoB.r_PwY;/]mii¨He qDFɶ HF@(qynu@BDt_P}v``fU7PG*Ui[k O-#DETRRRRR\ |_~hh護S O_^*"zgg+TbU~ f=QW?E֭s{Z=^@"X,i4 FTjrr|ʕÇ#z!Rdr||tTyhY"kצS)SffΜtc{*`.bի@WǠcVZoɑB@D#>9w9|X{#Ps@OOLRD>{BZ2y/VunʪzbA\GF\y}[}Wx,vҹs0cߏ SO RD~,  n!,I vQBb99)*ԩ?'$?ؾ_$vOgg.\xdRY+pJJDFF2*|^Yd?.VG'Oj 7?9W? Cmp"Qq]}}D+V D'NLOΝĕ+srpZJDvD+r~M  W YEhH4sG%PH,b{߿dVwߏ~@tSSD'O򗉄hLױȭ׊:x||pYYcF"H$]BxWnht{$%*.I$rg^SS X[o߷/rjI^,"TXp8Dr,TwAdZ\\^^YIzUT|_uѪEJ=hC2 ~:?LފUU8%VbX,fu>obbh.VFht T{ѩS?Oj[ Z TOVvt7-+0U DXOђ% uF"kˠ =RVvZ[R< xndY#"PHDN-nm[bݶM9-VcH|df&ˑBpxlQZhTTBVUT-ZDžx!dWB?(Pe VUpXDXD"pǬP0: r+PWfMOQ$RR BM7bk--n@d SrS[;o"SqB,`u[7o޲G,#Yu..X[}*U`s{ULO˗GDeehN X/2WuseqL p`)>? eєxT*E##Qq}G(Qu}D G&g-\J}7ξfA_˥֮}ᅷ޲u)bx5EX,&`w뫪^xͽ+O#1>vDCEeB]hGϜ!J&OXNh<{VTaXc[X_n}Qn߈uÆ}*Y?~#Doyމ2Ѻ K崴ԀN>k*SO=0T9RZ'U9V^{̙3GxV[XEd#S^7bqP=o|r w(XPDd:߿V'ظQ0~ӧSO?P7]#n +^3֯׋\]Z"Rukky'o}kÆ[**p%ZT|>ׅW۷_@tk|nocSS[sN5]H3えUp}رω Xlt4vkWn6)s-;w54tK/^V^gy]hkPDhSZhE.,`r睟/ˍY2z)Ī.ڽ[,*T )= aY e fcGׂPczuPq %oDBԍr[3 %xrHI]=njΝ~=*5 rq )-ߌ1~=Ȃի)bMolWK/=eʷL~u#ƆU]FŷLfv# T"░ 6'ۖ [255i#V_8sň)8RerfrWF-8iwu_?;׮^[z͡~=D"گ{ncud U&DXcժ_Tq&'8!D$DY^EOv ryծ]VSL8Q}[(0bjˠ귩B-/-*"*..)|&Wqمۅϗ\H9zhÆ{\t0*TPZZUY?Pm@*gkhU OFzV*ʤS^hQQCª۱bŽ%e=e:б+VZEH ΦRohͱpa4ZWY7"^8~\[Zxz߻ݻ~۴fdD"2߃yVUFtkbpd̙C%jiy(r(>qhl,2GFDUXs?"둪\1bkX= )꒒͛++H rE ZyԂSAv#?X2Fܲ-. 3 :*hU=RرWRrJ ѫJGz*%gXBe{X%Oso'ʉ\\Fclc&=Z./=6Ӌ{YF~BkUU5Ԥ^XW'&\!ٺW gj`J(\54N92G~X⍔y}ȷ}diiWWEw74՚gq|j,U !ڎA (ZF1; ,MPBb n{V4-_ /TVn&n1}{vz^9jFe5Vv!Z~Xvn?ق~G$q|P}S8D[=B3`0tuקˢN!s+s&V. t*vVfC+z_!X4-cZCfB6 :?b J$ _/~uPWF]#CS- ,s#E[~fX_#Y kj-'->~B盽ŷ !ZLƑ1EH]47³bhitsqR)qܜ?>F P@XkiUUoSP"1`L==vީ[\Q ؈Vy*ػw%K*OS7>A#{߉*p8U5P? !Z:﻾^.Z+De2?"Xe@ Nlv|m2p@ "a=Qj( PL##VT* q\'bj.n,\駂d1#otk Nb$TEVWb u{#_-Bb֚qq7Nm)N8TC,\b?񒗪ܶBqxmN==bY_̴|t+,NL 77/s8ڊ n }!Wlt c)n%"D8*V-y=jD%/,xe{㉺ k)Pq,VfNЕXAƬx3Lna1:5K*=2 <GsDE^AR%tEXtdate:create2011-10-04T10:06:34+02:006%tEXtdate:modify2011-10-04T10:06:34+02:00킎8 tEXtps:HiResBoundingBox123x109+2+10AktEXtps:LevelAdobe-3.0 EPSF-3.0 pIENDB`elyxer-1.2.5/test/bibtex-latin1.bib0000644000175000017500000000251712074107030016434 0ustar chennochenno@preamble { Please ignore. } @string { mykey = "myvalue" } @Article{AcentsTest, Author = {{Latin1 Accents !`\copyright{}\textordfeminine{}\textregistered{}\textordmasculine{}?` \`A\'A\^A\~A\"A\AA{}\r A\AE{}\c{C}\`E\'E\^E\"E\`I\'I\^I\"I\DH{}\~N \`O\'O\^O\~O\"O\O{}\`U\'U\^U\"U\'Y\TH{} \ss{}\`a\'a\^a\~a\"a\aa{}\ae{}\c{c}\`e\'e\^e\"e \`i\`\i\`{\i}\'{\i}\^{\i}\"{\i}\dh{}\~n \`o\'o\^o\~o\"o\o{}\`u\'u\^u\"u\'y\th{}\"y in Name}}, Title = {Latin1 Accents !`\copyright{}\textordfeminine{}\textregistered{}\textordmasculine{}?` \`{A}\'{A}\^{A}\~{A}\"{A}\AA{}\r {A}\AE{}\c{{C}}\`{E}\'{E}\^{E}\"{E}\`{I}\'{I}\^{I}\"{I}\DH{}\~{N} \`{O}\'{O}\^{O}\~{O}\"{O}\O{}\`{U}\'{U}\^{U}\"{U}\'{Y}\TH{} \ss{}\`a\'a\^a\~a\"a\aa{}\ae{}\c{c}\`e\'e\^e\"e \`i\`\i\`{\i}\'{\i}\^{\i}\"{\i}\dh{}\~n \`o\'o\^o\~o\"o\o{}\`u\'u\^u\"u\'y\th{}\"y in title}, Journal = {Test}, year = 2010 } @article{alphaeqs, Author = {Somebody in the $20^{th}$ Century}, Title = {Finding $\epsilon^{n}$ decimals of the number $\pi$}, Journal = {About \(\zeta\) in \(\pi\) things}, Year = {1934}, note = {According to The Society for $$\sum\epsilon^{n}$$ decimals of the number \[\sum\pi\], only 1 in $2n$ dentists read this magazine.} } elyxer-1.2.5/test/with images-1-5-noconvert-good.html0000644000175000017500000000316012074107030021636 0ustar chennochenno Images Tests

Images Tests

figure elyxer-svg.svg First image: regular path.
figure elyxer-svg.svg Second image: convoluted path.
figure ../docs/elyxer.svg Third image: from another directory.
figure mini-elyxer.jpg Fourth image: from a JPEG file.
figure square.png Fifth image: from a PNG file.
elyxer-1.2.5/test/elyxer-eps.eps0000644000175000017500000010413412074107030016117 0ustar chennochenno%!PS-Adobe-3.0 EPSF-3.0 %%Creator: inkscape 0.46 %%Pages: 1 %%Orientation: Portrait %%BoundingBox: 2 10 125 119 %%HiResBoundingBox: 2.2857151 10.705055 124.8714 118.85715 %%EndComments %%Page: 1 1 0 128 translate 0.8 -0.8 scale 0 0 0 setrgbcolor [] 0 setdash 1 setlinewidth 0 setlinejoin 0 setlinecap gsave [1 0 0 1 0 0] concat gsave [1 0 0 1 -549.09823 -447.62427] concat gsave [1.6412659 -0.049648468 0.045147815 1.8048788 539.20253 448.91643] concat gsave 0.12941177 0.12941177 0.12941177 setrgbcolor newpath 24.859391 31.907937 moveto 23.419824 24.350211 24.964801 11.778293 30.054438 8.9789918 curveto 35.144076 6.1796912 40.379124 5.3034583 41.760605 9.7424375 curveto 43.243834 14.508354 39.448349 16.768623 34.704351 20.597833 curveto 29.745701 24.600304 28.340109 28.103497 24.859391 31.907937 curveto closepath eofill grestore grestore gsave 0.40000001 0.5411765 0.68235296 setrgbcolor newpath 580.10453 531.54842 moveto 580.10453 531.54842 579.6867 492.49241 611.02396 486.97862 curveto 642.36123 481.46483 653.85156 533.84584 651.5535 542.11652 curveto 649.25543 550.3872 619.7687 571.03208 600.54851 564.13984 curveto 581.32832 557.24761 583.02934 548.08979 580.10453 531.54842 curveto closepath eofill grestore gsave << /ShadingType 2 /ColorSpace /DeviceRGB /Coords [61.980095 88.524223 51.749805 51.554661] /Extend [true true] /Domain [0 1] /Function << /FunctionType 3 /Functions [ << /FunctionType 2 /Domain [0 1] /C0 [1 1 1] /C1 [1 1 1] /N 1 >> ] /Domain [0 1] /Bounds [ ] /Encode [ 0 1 ] >> >> newpath 584.83412 532.92616 moveto 584.83412 532.92616 584.45739 497.71217 612.71194 492.74079 curveto 640.96649 487.7694 652.64504 537.06898 649.25449 542.45465 curveto 645.86394 547.84032 623.2603 556.95452 605.93085 550.74029 curveto 588.60139 544.52606 587.47121 547.84032 584.83412 532.92616 curveto closepath eoclip gsave [1.7854196 0 0 1.6604081 538.73934 444.56248] concat shfill grestore grestore gsave << /ShadingType 2 /ColorSpace /DeviceRGB /Coords [46.503231 26.114084 46.767101 52.293003] /Extend [true true] /Domain [0 1] /Function << /FunctionType 3 /Functions [ << /FunctionType 2 /Domain [0 1] /C0 [1 1 1] /C1 [1 1 1] /N 1 >> ] /Domain [0 1] /Bounds [ ] /Encode [ 0 1 ] >> >> newpath 581.25097 532.88232 moveto 581.25097 532.88232 580.83314 493.82631 612.1704 488.31252 curveto 643.50767 482.79873 656.4604 537.47714 652.69993 543.45042 curveto 648.93946 549.42369 623.86965 559.5323 604.64946 552.64007 curveto 585.42927 545.74783 584.17578 549.42369 581.25097 532.88232 curveto closepath eoclip gsave [1.7854196 0 0 1.6604081 538.73934 444.56248] concat shfill grestore grestore gsave 0.6156863 0.21960784 0.074509807 setrgbcolor newpath 605.59217 576.5777 moveto 605.59217 568.99624 620.95005 543.07752 627.46707 542.68271 curveto 634.13135 542.27897 630.66198 547.17083 635.67595 546.71134 curveto 640.68991 546.25186 649.04651 546.71134 650.71783 552.68462 curveto 652.38916 558.65789 652.80699 575.65874 647.37519 577.03719 curveto 641.9434 578.41563 637.34727 579.79408 634.42246 584.38891 curveto 631.49764 588.98373 622.72321 597.25442 614.36661 593.11907 curveto 606.18558 589.07062 605.59217 584.15916 605.59217 576.5777 curveto closepath eofill grestore gsave 0.87843138 0.80784315 0.11372549 setrgbcolor newpath 617.29142 580.71305 moveto 617.70925 577.95615 621.46972 558.1984 626.06585 554.98203 curveto 630.66198 551.76565 627.73717 558.1984 629.40849 561.41478 curveto 631.07981 564.63116 639.43642 551.76565 639.43642 557.27944 curveto 639.43642 562.79323 631.91547 566.46909 636.92944 565.55012 curveto 641.9434 564.63116 655.7318 560.03634 648.62868 566.00961 curveto 641.52557 571.98288 637.7651 580.71305 632.75114 577.95615 curveto 627.73717 575.19926 626.06585 583.92942 621.88755 583.92942 curveto 617.70925 583.92942 616.87359 583.92942 617.29142 580.71305 curveto closepath eofill grestore gsave << /ShadingType 2 /ColorSpace /DeviceRGB /Coords [50.659912 88.177994 53.563347 65.57518] /Extend [true true] /Domain [0 1] /Function << /FunctionType 3 /Functions [ << /FunctionType 2 /Domain [0 1] /C0 [0 0 0] /C1 [0 0 0] /N 1 >> ] /Domain [0 1] /Bounds [ ] /Encode [ 0 1 ] >> >> newpath 606.02896 575.57264 moveto 606.02896 567.99118 621.38684 542.07246 627.90386 541.67764 curveto 634.56814 541.2739 631.09877 546.16576 636.11273 545.70628 curveto 641.12669 545.2468 649.4833 545.70628 651.15463 551.67955 curveto 652.82595 557.65282 653.24378 574.65367 647.81197 576.03212 curveto 642.38019 577.41057 637.78406 578.78902 634.85925 583.38384 curveto 631.93443 587.97867 623.15999 596.24935 614.8034 592.11401 curveto 606.62237 588.06555 606.02896 583.1541 606.02896 575.57264 curveto closepath eoclip gsave [1.6300939 0 0 1.8186149 538.73934 444.56248] concat shfill grestore grestore gsave << /ShadingType 2 /ColorSpace /DeviceRGB /Coords [32.921471 69.997231 49.624016 77.805328] /Extend [true true] /Domain [0 1] /Function << /FunctionType 3 /Functions [ << /FunctionType 2 /Domain [0 1] /C0 [0 0 0] /C1 [0 0 0] /N 1 >> ] /Domain [0 1] /Bounds [ ] /Encode [ 0 1 ] >> >> newpath 622.72321 525.57515 moveto 667.84887 539.81911 lineto 703.36444 511.33119 lineto 622.72321 525.57515 lineto closepath eoclip gsave [2.896845 0 0 1.0233611 538.73934 444.56248] concat shfill grestore grestore gsave [1.9828475 0 0 2.1805117 515.32574 433.14447] concat gsave 0.95686275 0.95686275 0.95686275 setrgbcolor newpath 70.49148 30.108479 moveto 70.49148 35.025069 66.501204 39.015345 61.584614 39.015345 curveto 56.668024 39.015345 52.677748 35.025069 52.677748 30.108479 curveto 52.677748 25.191888 56.668024 21.201612 61.584614 21.201612 curveto 66.501204 21.201612 70.49148 25.191888 70.49148 30.108479 curveto closepath eofill grestore grestore gsave 0.6156863 0.21960784 0.074509807 setrgbcolor newpath 584.70066 544.87341 moveto 584.70066 544.87341 583.865 549.92772 587.62547 554.52255 curveto 591.38594 559.11737 606.84566 574.73977 601.41387 583.92942 curveto 595.98208 593.11907 581.77585 594.03804 576.76189 587.60528 curveto 571.74792 581.17253 553.3634 572.90184 553.78123 569.68547 curveto 554.19906 566.46909 547.09594 550.3872 558.37736 549.46824 curveto 569.65877 548.54927 577.17972 540.27859 580.52236 539.81911 curveto 583.865 539.35962 585.11849 541.65704 584.70066 544.87341 curveto closepath eofill grestore gsave 0.87843138 0.80784315 0.11372549 setrgbcolor newpath 581.77585 555.44151 moveto 581.77585 555.44151 585.95415 566.46909 590.13245 572.44236 curveto 594.31076 578.41563 588.87896 586.68632 583.44717 581.17253 curveto 578.01538 575.65874 560.88434 571.5234 561.30217 566.00961 curveto 561.72 560.49582 568.82311 570.60443 570.0766 566.00961 curveto 571.33009 561.41478 561.72 550.84669 566.73396 552.22513 curveto 571.74792 553.60358 575.5084 567.38806 576.76189 559.57685 curveto 578.01538 551.76565 576.34406 544.87341 581.77585 555.44151 curveto closepath eofill grestore gsave << /ShadingType 2 /ColorSpace /DeviceRGB /Coords [13.065491 85.119431 26.982304 67.89669] /Extend [true true] /Domain [0 1] /Function << /FunctionType 3 /Functions [ << /FunctionType 2 /Domain [0 1] /C0 [0 0 0] /C1 [0 0 0] /N 1 >> ] /Domain [0 1] /Bounds [ ] /Encode [ 0 1 ] >> >> newpath 585.18255 544.61321 moveto 585.18255 544.61321 584.34689 549.66752 588.10736 554.26234 curveto 591.86783 558.85717 607.32755 574.47957 601.89575 583.66922 curveto 596.46396 592.85887 582.25773 593.77784 577.24377 587.34508 curveto 572.22981 580.91233 553.84528 572.64164 554.26311 569.42527 curveto 554.68094 566.20889 547.57783 550.127 558.85924 549.20804 curveto 570.14066 548.28907 577.6616 540.01839 581.00424 539.55891 curveto 584.34689 539.09942 585.60038 541.39684 585.18255 544.61321 curveto closepath eoclip gsave [1.6986295 0 0 1.7452532 538.73934 444.56248] concat shfill grestore grestore gsave [1.5953948 0 0 1.754435 539.61141 446.55548] concat gsave 0.87450981 0.82352942 0.44705883 setrgbcolor newpath 70.49148 30.108479 moveto 70.49148 35.025069 66.501204 39.015345 61.584614 39.015345 curveto 56.668024 39.015345 52.677748 35.025069 52.677748 30.108479 curveto 52.677748 25.191888 56.668024 21.201612 61.584614 21.201612 curveto 66.501204 21.201612 70.49148 25.191888 70.49148 30.108479 curveto closepath eofill grestore grestore gsave [1.6418859 0 0 1.8055607 538.59447 444.01461] concat gsave 0 0 0 setrgbcolor newpath 67.437697 31.126406 moveto 67.437697 34.357308 64.815516 36.979489 61.584614 36.979489 curveto 58.353712 36.979489 55.731531 34.357308 55.731531 31.126406 curveto 55.731531 27.895504 58.353712 25.273323 61.584614 25.273323 curveto 64.815516 25.273323 67.437697 27.895504 67.437697 31.126406 curveto closepath eofill grestore grestore gsave 0.27058825 0.48627451 0.05882353 setrgbcolor newpath 581.35802 532.0079 moveto 581.35802 532.0079 590.96811 531.08894 587.62547 536.60273 curveto 584.28283 542.11652 573.00141 543.95445 580.10453 546.25186 curveto 587.20764 548.54927 624.81236 549.46824 628.99066 551.76565 curveto 633.16896 554.06306 621.05189 568.30702 613.11311 565.55012 curveto 605.17434 562.79323 593.89293 551.30617 582.19368 553.1441 curveto 570.49443 554.98203 559.21302 562.33375 558.79519 554.52255 curveto 558.37736 546.71134 567.56962 534.30532 581.35802 532.0079 curveto closepath eofill grestore gsave << /ShadingType 2 /ColorSpace /DeviceRGB /Coords [9.9581957 96.715332 22.288982 86.950264] /Extend [true true] /Domain [0 1] /Function << /FunctionType 3 /Functions [ << /FunctionType 2 /Domain [0 1] /C0 [1 1 1] /C1 [1 1 1] /N 1 >> ] /Domain [0 1] /Bounds [ ] /Encode [ 0 1 ] >> >> newpath 584.91531 528.92355 moveto 584.91531 528.92355 594.12586 528.0428 590.92219 533.32734 curveto 587.71852 538.61189 576.90615 540.3734 583.71394 542.5753 curveto 590.52173 544.77719 626.56298 545.65795 630.56756 547.85984 curveto 634.57215 550.06174 622.95886 563.71348 615.35015 561.07121 curveto 607.74144 558.42894 596.92906 547.41947 585.71623 549.18098 curveto 574.5034 550.9425 563.69102 557.98856 563.29056 550.50212 curveto 562.89011 543.01568 571.70019 531.12545 584.91531 528.92355 curveto closepath eoclip gsave [2.4909379 0 0 1.1901263 538.73934 444.56248] concat shfill grestore grestore gsave 0.32156864 0.57647061 0.074509807 setrgbcolor newpath 651.5535 540.27859 moveto 651.5535 540.27859 666.17755 545.3329 657.40312 547.17083 curveto 648.62868 549.00876 626.90151 546.71134 620.63406 551.30617 curveto 614.36661 555.90099 607.26349 570.60443 612.27746 573.36133 curveto 617.29142 576.11822 630.66198 560.49582 642.36123 558.1984 curveto 654.06048 555.90099 679.13029 557.27944 680.38378 552.68462 curveto 681.63727 548.08979 657.68987 534.19383 653.09374 534.19383 curveto 648.49761 534.19383 651.5535 540.27859 651.5535 540.27859 curveto closepath eofill grestore gsave [1.5138028 0 0 1.6647094 573.78363 440.3665] concat gsave << /ShadingType 2 /ColorSpace /DeviceRGB /Coords [39.077763 45.47282 38.935726 34.73687] /Extend [true true] /Domain [0 1] /Function << /FunctionType 3 /Functions [ << /FunctionType 2 /Domain [0 1] /C0 [0 0 0] /C1 [0 0 0] /N 1 >> ] /Domain [0 1] /Bounds [ ] /Encode [ 0 1 ] >> >> newpath 51.150857 35.452599 moveto 51.150857 40.509662 47.046573 44.613946 41.98951 44.613946 curveto 36.932446 44.613946 32.828162 40.509662 32.828162 35.452599 curveto 32.828162 30.395535 36.932446 26.291251 41.98951 26.291251 curveto 47.046573 26.291251 51.150857 30.395535 51.150857 35.452599 curveto closepath eoclip shfill grestore grestore gsave [1.9194088 0 0 2.110749 526.87749 437.18904] concat gsave 0.95686275 0.95686275 0.95686275 setrgbcolor newpath 51.150857 35.452599 moveto 51.150857 40.509662 47.046573 44.613946 41.98951 44.613946 curveto 36.932446 44.613946 32.828162 40.509662 32.828162 35.452599 curveto 32.828162 30.395535 36.932446 26.291251 41.98951 26.291251 curveto 47.046573 26.291251 51.150857 30.395535 51.150857 35.452599 curveto closepath eofill grestore grestore gsave [1.5138028 0 0 1.6647094 544.11762 452.31315] concat gsave 0.87450981 0.82352942 0.44705883 setrgbcolor newpath 51.150857 35.452599 moveto 51.150857 40.509662 47.046573 44.613946 41.98951 44.613946 curveto 36.932446 44.613946 32.828162 40.509662 32.828162 35.452599 curveto 32.828162 30.395535 36.932446 26.291251 41.98951 26.291251 curveto 47.046573 26.291251 51.150857 30.395535 51.150857 35.452599 curveto closepath eofill grestore grestore gsave [1.5138028 0 0 1.6647094 544.11762 451.85354] concat gsave << /ShadingType 2 /ColorSpace /DeviceRGB /Coords [39.077763 45.47282 38.935726 34.73687] /Extend [true true] /Domain [0 1] /Function << /FunctionType 3 /Functions [ << /FunctionType 2 /Domain [0 1] /C0 [0 0 0] /C1 [0 0 0] /N 1 >> ] /Domain [0 1] /Bounds [ ] /Encode [ 0 1 ] >> >> newpath 51.150857 35.452599 moveto 51.150857 40.509662 47.046573 44.613946 41.98951 44.613946 curveto 36.932446 44.613946 32.828162 40.509662 32.828162 35.452599 curveto 32.828162 30.395535 36.932446 26.291251 41.98951 26.291251 curveto 47.046573 26.291251 51.150857 30.395535 51.150857 35.452599 curveto closepath eoclip shfill grestore grestore gsave [1.6418859 0 0 1.8055607 539.38094 444.75289] concat gsave 0 0 0 setrgbcolor newpath 48.351557 36.216045 moveto 48.351557 39.587421 45.615368 42.32361 42.243992 42.32361 curveto 38.872616 42.32361 36.136427 39.587421 36.136427 36.216045 curveto 36.136427 32.84467 38.872616 30.10848 42.243992 30.10848 curveto 45.615368 30.10848 48.351557 32.84467 48.351557 36.216045 curveto closepath eofill grestore grestore gsave [1.2624477 0 0 1.3882974 552.1086 456.0066] concat gsave << /ShadingType 3 /ColorSpace /DeviceRGB /Coords [42.243992 36.216045 0 42.243992 36.216045 6.1075649] /Extend [true true] /Domain [0 1] /Function << /FunctionType 3 /Functions [ << /FunctionType 2 /Domain [0 1] /C0 [1 1 1] /C1 [1 1 1] /N 1 >> ] /Domain [0 1] /Bounds [ ] /Encode [ 0 1 ] >> >> newpath 48.351557 36.216045 moveto 48.351557 39.587421 45.615368 42.32361 42.243992 42.32361 curveto 38.872616 42.32361 36.136427 39.587421 36.136427 36.216045 curveto 36.136427 32.84467 38.872616 30.10848 42.243992 30.10848 curveto 45.615368 30.10848 48.351557 32.84467 48.351557 36.216045 curveto closepath eoclip shfill grestore grestore gsave [1.2624477 0 0 1.3882974 582.90721 446.3383] concat gsave << /ShadingType 3 /ColorSpace /DeviceRGB /Coords [42.243992 36.216045 0 42.243992 36.216045 6.1075649] /Extend [true true] /Domain [0 1] /Function << /FunctionType 3 /Functions [ << /FunctionType 2 /Domain [0 1] /C0 [1 1 1] /C1 [1 1 1] /N 1 >> ] /Domain [0 1] /Bounds [ ] /Encode [ 0 1 ] >> >> newpath 48.351557 36.216045 moveto 48.351557 39.587421 45.615368 42.32361 42.243992 42.32361 curveto 38.872616 42.32361 36.136427 39.587421 36.136427 36.216045 curveto 36.136427 32.84467 38.872616 30.10848 42.243992 30.10848 curveto 45.615368 30.10848 48.351557 32.84467 48.351557 36.216045 curveto closepath eoclip shfill grestore grestore gsave << /ShadingType 2 /ColorSpace /DeviceRGB /Coords [51.998035 87.448608 44.157574 78.630959] /Extend [true true] /Domain [0 1] /Function << /FunctionType 3 /Functions [ << /FunctionType 2 /Domain [0 1] /C0 [1 1 1] /C1 [1 1 1] /N 1 >> ] /Domain [0 1] /Bounds [ ] /Encode [ 0 1 ] >> >> newpath 649.96666 539.48867 moveto 649.96666 539.48867 664.59071 544.54298 655.81627 546.38091 curveto 647.04185 548.21884 625.31467 545.92142 619.04722 550.51625 curveto 612.77977 555.11107 605.67665 569.81451 610.69062 572.57141 curveto 615.70458 575.3283 629.07514 559.7059 640.77439 557.40848 curveto 652.47364 555.11107 677.54345 556.48952 678.79694 551.8947 curveto 680.05042 547.29987 656.10303 533.40391 651.5069 533.40391 curveto 646.91076 533.40391 649.96666 539.48867 649.96666 539.48867 curveto closepath eoclip gsave [2.2898233 0 0 1.2946538 538.73934 444.56248] concat shfill grestore grestore gsave [1.400681 -0.042370668 0.03852975 1.5403108 548.74078 452.34447] concat gsave << /ShadingType 2 /ColorSpace /DeviceRGB /Coords [50.072014 13.720966 26.487234 13.768328] /Extend [true true] /Domain [0 1] /Function << /FunctionType 3 /Functions [ << /FunctionType 2 /Domain [0 1] /C0 [1 1 1] /C1 [1 1 1] /N 1 >> ] /Domain [0 1] /Bounds [ ] /Encode [ 0 1 ] >> >> newpath 24.859391 31.907937 moveto 23.419824 24.350211 24.964801 11.778293 30.054438 8.9789918 curveto 35.144076 6.1796912 40.379124 5.3034583 41.760605 9.7424375 curveto 43.243834 14.508354 39.448349 16.768623 34.704351 20.597833 curveto 29.745701 24.600304 28.340109 28.103497 24.859391 31.907937 curveto closepath eoclip gsave [0.838005 0 0 1.19331 0 0] concat shfill grestore grestore grestore gsave << /ShadingType 2 /ColorSpace /DeviceRGB /Coords [84.674622 134.8858 79.578964 116.69227] /Extend [true true] /Domain [0 1] /Function << /FunctionType 3 /Functions [ << /FunctionType 2 /Domain [0 1] /C0 [1 1 1] /C1 [1 1 1] /N 1 >> ] /Domain [0 1] /Bounds [ ] /Encode [ 0 1 ] >> >> newpath 616.907 580.83088 moveto 617.32484 578.07397 621.08532 558.31616 625.68146 555.09978 curveto 630.27761 551.88339 627.35279 558.31616 629.02412 561.53256 curveto 630.69544 564.74894 639.05207 551.88339 639.05207 557.3972 curveto 639.05207 562.91101 631.5311 566.58688 636.54508 565.6679 curveto 641.55906 564.74894 655.3475 560.1541 648.24436 566.12739 curveto 641.14122 572.10068 637.38074 580.83088 632.36677 578.07397 curveto 627.35279 575.31707 625.68146 584.04726 621.50315 584.04726 curveto 617.32484 584.04726 616.48917 584.04726 616.907 580.83088 curveto closepath eoclip gsave [1.2747221 0 0 1.1373574 531.37626 430.58177] concat shfill grestore grestore gsave << /ShadingType 2 /ColorSpace /DeviceRGB /Coords [36.185604 131.57237 34.983452 109.63145] /Extend [true true] /Domain [0 1] /Function << /FunctionType 3 /Functions [ << /FunctionType 2 /Domain [0 1] /C0 [1 1 1] /C1 [1 1 1] /N 1 >> ] /Domain [0 1] /Bounds [ ] /Encode [ 0 1 ] >> >> newpath 581.39134 555.55926 moveto 581.39134 555.55926 585.56965 566.58688 589.74796 572.56017 curveto 593.92628 578.53345 588.49447 586.80416 583.06266 581.29036 curveto 577.63086 575.77656 560.49977 571.6412 560.9176 566.12739 curveto 561.33543 560.61358 568.43856 570.72224 569.69206 566.12739 curveto 570.94555 561.53256 561.33543 550.96442 566.34941 552.34288 curveto 571.36338 553.72133 575.12387 567.50584 576.37736 559.69462 curveto 577.63086 551.88339 575.95953 544.99114 581.39134 555.55926 curveto closepath eoclip gsave [1.1551703 0 0 1.2550639 531.37626 430.58177] concat shfill grestore grestore gsave [0.3512975 0 0 0.3512975 625.25272 503.74669] concat gsave [0 -0.525214 0.525214 0 11.42181 267.4213] concat gsave 0.34117648 0.63529414 0.05882353 setrgbcolor newpath 428.62836 222.16092 moveto 428.62836 323.67816 346.23755 406.06897 244.72031 406.06897 curveto 143.20306 406.06897 60.812256 323.67816 60.812256 222.16092 curveto 60.812256 120.64368 143.20306 38.252869 244.72031 38.252869 curveto 346.23755 38.252869 428.62836 120.64368 428.62836 222.16092 curveto closepath fill grestore 0.34117648 0.63529414 0.05882353 setrgbcolor [] 0 setdash 10.839739 setlinewidth 1 setlinejoin 0 setlinecap newpath 428.62836 222.16092 moveto 428.62836 323.67816 346.23755 406.06897 244.72031 406.06897 curveto 143.20306 406.06897 60.812256 323.67816 60.812256 222.16092 curveto 60.812256 120.64368 143.20306 38.252869 244.72031 38.252869 curveto 346.23755 38.252869 428.62836 120.64368 428.62836 222.16092 curveto closepath stroke grestore gsave [0 -0.525214 0.525214 0 11.42181 267.4213] concat gsave << /ShadingType 2 /ColorSpace /DeviceRGB /Coords [60.812256 222.16092 428.62836 222.16092] /Extend [true true] /Domain [0 1] /Function << /FunctionType 3 /Functions [ << /FunctionType 2 /Domain [0 1] /C0 [0.34509805 0.28627452 0.90980393] /C1 [0.12941177 0.074509807 0.6156863] /N 1 >> ] /Domain [0 1] /Bounds [ ] /Encode [ 0 1 ] >> >> newpath 428.62836 222.16092 moveto 428.62836 323.67816 346.23755 406.06897 244.72031 406.06897 curveto 143.20306 406.06897 60.812256 323.67816 60.812256 222.16092 curveto 60.812256 120.64368 143.20306 38.252869 244.72031 38.252869 curveto 346.23755 38.252869 428.62836 120.64368 428.62836 222.16092 curveto closepath clip shfill grestore grestore gsave [0 -0.525214 0.525214 0 11.42181 267.4213] concat gsave << /ShadingType 3 /ColorSpace /DeviceRGB /Coords [244.72031 222.16092 0 244.72031 222.16092 183.90805] /Extend [true true] /Domain [0 1] /Function << /FunctionType 3 /Functions [ << /FunctionType 2 /Domain [0 1] /C0 [1 1 1] /C1 [0.11764706 0.074509807 0.6156863] /N 1 >> << /FunctionType 2 /Domain [0 1] /C0 [0.11764706 0.074509807 0.6156863] /C1 [0.34509805 0.28627452 0.90980393] /N 1 >> ] /Domain [0 1] /Bounds [ 0.80000001 ] /Encode [ 0 1 0 1 ] >> >> newpath 428.62836 222.16092 moveto 428.62836 323.67816 346.23755 406.06897 244.72031 406.06897 curveto 143.20306 406.06897 60.812256 323.67816 60.812256 222.16092 curveto 60.812256 120.64368 143.20306 38.252869 244.72031 38.252869 curveto 346.23755 38.252869 428.62836 120.64368 428.62836 222.16092 curveto closepath clip shfill grestore grestore gsave [0 0.382405 0.382405 0 43.14837 21.00481] concat gsave << /ShadingType 3 /ColorSpace /DeviceRGB /Coords [49.709621 222.16092 0 49.709621 222.16092 183.90805] /Extend [true true] /Domain [0 1] /Function << /FunctionType 3 /Functions [ << /FunctionType 2 /Domain [0 1] /C0 [1 1 1] /C1 [1 1 1] /N 1 >> ] /Domain [0 1] /Bounds [ ] /Encode [ 0 1 ] >> >> newpath 428.62836 222.16092 moveto 428.62836 323.67816 346.23755 406.06897 244.72031 406.06897 curveto 143.20306 406.06897 60.812256 323.67816 60.812256 222.16092 curveto 60.812256 120.64368 143.20306 38.252869 244.72031 38.252869 curveto 346.23755 38.252869 428.62836 120.64368 428.62836 222.16092 curveto closepath clip gsave [1.353938 0 0 1.353938 -33.88875 -78.63119] concat shfill grestore grestore grestore gsave [0 -0.306725 0.412392 0 36.48655 251.3615] concat gsave << /ShadingType 3 /ColorSpace /DeviceRGB /Coords [69.944862 222.16092 0 69.944862 222.16092 183.90805] /Extend [true true] /Domain [0 1] /Function << /FunctionType 3 /Functions [ << /FunctionType 2 /Domain [0 1] /C0 [1 1 1] /C1 [1 1 1] /N 1 >> ] /Domain [0 1] /Bounds [ ] /Encode [ 0 1 ] >> >> newpath 428.62836 222.16092 moveto 428.62836 323.67816 346.23755 406.06897 244.72031 406.06897 curveto 143.20306 406.06897 60.812256 323.67816 60.812256 222.16092 curveto 60.812256 120.64368 143.20306 38.252869 244.72031 38.252869 curveto 346.23755 38.252869 428.62836 120.64368 428.62836 222.16092 curveto closepath clip gsave [1.353938 0 0 1.353938 -33.88875 -78.63119] concat shfill grestore grestore grestore gsave [0.525214 0 0 0.525214 -0.426697 22.2088] concat gsave << /ShadingType 2 /ColorSpace /DeviceRGB /Coords [98 240.92043 420 240.92043] /Extend [true true] /Domain [0 1] /Function << /FunctionType 3 /Functions [ << /FunctionType 2 /Domain [0 1] /C0 [1 1 1] /C1 [1 1 1] /N 1 >> ] /Domain [0 1] /Bounds [ ] /Encode [ 0 1 ] >> >> newpath 201.58219 398.66524 moveto 201.58219 398.66524 25.59643 220.69905 234.16166 39.888097 curveto -1.634599 220.03851 202.12567 397.72391 201.58219 398.66524 curveto closepath eoclip gsave [0.543478 -0.941332 0.941332 0.543478 -156.6701 314.8289] concat shfill grestore grestore gsave << /ShadingType 2 /ColorSpace /DeviceRGB /Coords [98 240.92043 420 240.92043] /Extend [true true] /Domain [0 1] /Function << /FunctionType 3 /Functions [ << /FunctionType 2 /Domain [0 1] /C0 [1 1 1] /C1 [1 1 1] /N 1 >> ] /Domain [0 1] /Bounds [ ] /Encode [ 0 1 ] >> >> newpath 418.06183 185.18557 moveto 418.06183 185.18557 240.09557 9.1998797 59.284695 217.76518 curveto 239.43502 -18.031148 417.12049 185.72905 418.06183 185.18557 curveto closepath eoclip gsave [-0.941332 0.543478 0.543478 0.941332 334.2253 -173.0667] concat shfill grestore grestore gsave << /ShadingType 2 /ColorSpace /DeviceRGB /Coords [98 240.92043 420 240.92043] /Extend [true true] /Domain [0 1] /Function << /FunctionType 3 /Functions [ << /FunctionType 2 /Domain [0 1] /C0 [1 1 1] /C1 [1 1 1] /N 1 >> ] /Domain [0 1] /Bounds [ ] /Encode [ 0 1 ] >> >> newpath 66.93794 267.02123 moveto 66.93794 267.02123 244.9042 443.00692 425.71507 234.44162 curveto 245.56475 470.23795 67.879272 266.47776 66.93794 267.02123 curveto closepath eoclip gsave [0.941332 -0.543478 -0.543478 -0.941332 150.7744 625.2735] concat shfill grestore grestore gsave << /ShadingType 2 /ColorSpace /DeviceRGB /Coords [98 240.92043 420 240.92043] /Extend [true true] /Domain [0 1] /Function << /FunctionType 3 /Functions [ << /FunctionType 2 /Domain [0 1] /C0 [1 1 1] /C1 [1 1 1] /N 1 >> ] /Domain [0 1] /Bounds [ ] /Encode [ 0 1 ] >> >> newpath 283.41758 47.541558 moveto 283.41758 47.541558 459.40333 225.50774 250.83811 406.3187 curveto 486.63436 226.16829 282.8741 48.482895 283.41758 47.541558 curveto closepath eoclip gsave [-0.543478 0.941332 -0.941332 -0.543478 641.6699 131.3779] concat shfill grestore grestore gsave << /ShadingType 3 /ColorSpace /DeviceRGB /Coords [246.35255 226.88303 0 246.35255 226.88303 154.3577] /Extend [true true] /Domain [0 1] /Function << /FunctionType 3 /Functions [ << /FunctionType 2 /Domain [0 1] /C0 [1 1 1] /C1 [1 1 1] /N 1 >> ] /Domain [0 1] /Bounds [ ] /Encode [ 0 1 ] >> >> newpath 92 316 moveto 92 316 262.42047 243.53212 400.71024 137.76606 curveto 239 206 91 316 92 316 curveto closepath eoclip gsave [1 -0.57734 0.12401 0.214795 -28.13556 320.3787] concat shfill grestore grestore gsave << /ShadingType 3 /ColorSpace /DeviceRGB /Coords [246.35255 226.88303 0 246.35255 226.88303 154.3577] /Extend [true true] /Domain [0 1] /Function << /FunctionType 3 /Functions [ << /FunctionType 2 /Domain [0 1] /C0 [1 1 1] /C1 [1 1 1] /N 1 >> ] /Domain [0 1] /Bounds [ ] /Encode [ 0 1 ] >> >> newpath 335.46957 381.23563 moveto 335.46957 381.23563 263.00169 210.81516 157.23563 72.525391 curveto 225.46957 234.23563 335.46957 382.23563 335.46957 381.23563 curveto closepath eoclip gsave [-0.57734 -1 0.214795 -0.12401 339.8483 501.3712] concat shfill grestore grestore grestore gsave [0.983093 0 0 0.983093 -24.81549 -4.294319] concat gsave << /ShadingType 3 /ColorSpace /DeviceRGB /Coords [156.5 148.5 0 156.5 148.5 19.5] /Extend [true true] /Domain [0 1] /Function << /FunctionType 3 /Functions [ << /FunctionType 2 /Domain [0 1] /C0 [1 1 1] /C1 [1 1 1] /N 1 >> << /FunctionType 2 /Domain [0 1] /C0 [1 1 1] /C1 [1 1 1] /N 1 >> ] /Domain [0 1] /Bounds [ 0.34999999 ] /Encode [ 0 1 0 1 ] >> >> newpath 176 148.5 moveto 176 159.264 167.264 168 156.5 168 curveto 145.736 168 137 159.264 137 148.5 curveto 137 137.736 145.736 129 156.5 129 curveto 167.264 129 176 137.736 176 148.5 curveto closepath clip shfill grestore grestore gsave [0.417478 0 0 0.417478 112.5483 29.80421] concat gsave << /ShadingType 3 /ColorSpace /DeviceRGB /Coords [156.5 148.5 0 156.5 148.5 19.5] /Extend [true true] /Domain [0 1] /Function << /FunctionType 3 /Functions [ << /FunctionType 2 /Domain [0 1] /C0 [1 1 1] /C1 [1 1 1] /N 1 >> << /FunctionType 2 /Domain [0 1] /C0 [1 1 1] /C1 [1 1 1] /N 1 >> ] /Domain [0 1] /Bounds [ 0.34999999 ] /Encode [ 0 1 0 1 ] >> >> newpath 176 148.5 moveto 176 159.264 167.264 168 156.5 168 curveto 145.736 168 137 159.264 137 148.5 curveto 137 137.736 145.736 129 156.5 129 curveto 167.264 129 176 137.736 176 148.5 curveto closepath clip shfill grestore grestore gsave [0.255874 0 0 0.255874 157.2722 63.78154] concat gsave << /ShadingType 3 /ColorSpace /DeviceRGB /Coords [156.5 148.5 0 156.5 148.5 19.5] /Extend [true true] /Domain [0 1] /Function << /FunctionType 3 /Functions [ << /FunctionType 2 /Domain [0 1] /C0 [1 1 1] /C1 [1 1 1] /N 1 >> << /FunctionType 2 /Domain [0 1] /C0 [1 1 1] /C1 [1 1 1] /N 1 >> ] /Domain [0 1] /Bounds [ 0.34999999 ] /Encode [ 0 1 0 1 ] >> >> newpath 176 148.5 moveto 176 159.264 167.264 168 156.5 168 curveto 145.736 168 137 159.264 137 148.5 curveto 137 137.736 145.736 129 156.5 129 curveto 167.264 129 176 137.736 176 148.5 curveto closepath clip shfill grestore grestore gsave [0.525214 0 0 0.525214 15.85494 9.603656] concat gsave << /ShadingType 3 /ColorSpace /DeviceRGB /Coords [156.5 148.5 0 156.5 148.5 19.5] /Extend [true true] /Domain [0 1] /Function << /FunctionType 3 /Functions [ << /FunctionType 2 /Domain [0 1] /C0 [1 1 1] /C1 [1 1 1] /N 1 >> << /FunctionType 2 /Domain [0 1] /C0 [1 1 1] /C1 [1 1 1] /N 1 >> ] /Domain [0 1] /Bounds [ 0.34999999 ] /Encode [ 0 1 0 1 ] >> >> newpath 176 148.5 moveto 176 159.264 167.264 168 156.5 168 curveto 145.736 168 137 159.264 137 148.5 curveto 137 137.736 145.736 129 156.5 129 curveto 167.264 129 176 137.736 176 148.5 curveto closepath clip shfill grestore grestore gsave [0.525214 0 0 0.525214 100.9397 30.61223] concat gsave << /ShadingType 3 /ColorSpace /DeviceRGB /Coords [156.5 148.5 0 156.5 148.5 19.5] /Extend [true true] /Domain [0 1] /Function << /FunctionType 3 /Functions [ << /FunctionType 2 /Domain [0 1] /C0 [1 1 1] /C1 [1 1 1] /N 1 >> << /FunctionType 2 /Domain [0 1] /C0 [1 1 1] /C1 [1 1 1] /N 1 >> ] /Domain [0 1] /Bounds [ 0.34999999 ] /Encode [ 0 1 0 1 ] >> >> newpath 176 148.5 moveto 176 159.264 167.264 168 156.5 168 curveto 145.736 168 137 159.264 137 148.5 curveto 137 137.736 145.736 129 156.5 129 curveto 167.264 129 176 137.736 176 148.5 curveto closepath clip shfill grestore grestore gsave [0.525214 0 0 0.525214 76.2546 115.6969] concat gsave << /ShadingType 3 /ColorSpace /DeviceRGB /Coords [156.5 148.5 0 156.5 148.5 19.5] /Extend [true true] /Domain [0 1] /Function << /FunctionType 3 /Functions [ << /FunctionType 2 /Domain [0 1] /C0 [1 1 1] /C1 [1 1 1] /N 1 >> << /FunctionType 2 /Domain [0 1] /C0 [1 1 1] /C1 [1 1 1] /N 1 >> ] /Domain [0 1] /Bounds [ 0.34999999 ] /Encode [ 0 1 0 1 ] >> >> newpath 176 148.5 moveto 176 159.264 167.264 168 156.5 168 curveto 145.736 168 137 159.264 137 148.5 curveto 137 137.736 145.736 129 156.5 129 curveto 167.264 129 176 137.736 176 148.5 curveto closepath clip shfill grestore grestore gsave [0.525214 0 0 0.525214 -10.93098 96.264] concat gsave << /ShadingType 3 /ColorSpace /DeviceRGB /Coords [156.5 148.5 0 156.5 148.5 19.5] /Extend [true true] /Domain [0 1] /Function << /FunctionType 3 /Functions [ << /FunctionType 2 /Domain [0 1] /C0 [1 1 1] /C1 [1 1 1] /N 1 >> << /FunctionType 2 /Domain [0 1] /C0 [1 1 1] /C1 [1 1 1] /N 1 >> ] /Domain [0 1] /Bounds [ 0.34999999 ] /Encode [ 0 1 0 1 ] >> >> newpath 176 148.5 moveto 176 159.264 167.264 168 156.5 168 curveto 145.736 168 137 159.264 137 148.5 curveto 137 137.736 145.736 129 156.5 129 curveto 167.264 129 176 137.736 176 148.5 curveto closepath clip shfill grestore grestore gsave [0.417478 0 0 0.417478 109.9222 127.494] concat gsave << /ShadingType 3 /ColorSpace /DeviceRGB /Coords [156.5 148.5 0 156.5 148.5 19.5] /Extend [true true] /Domain [0 1] /Function << /FunctionType 3 /Functions [ << /FunctionType 2 /Domain [0 1] /C0 [1 1 1] /C1 [1 1 1] /N 1 >> << /FunctionType 2 /Domain [0 1] /C0 [1 1 1] /C1 [1 1 1] /N 1 >> ] /Domain [0 1] /Bounds [ 0.34999999 ] /Encode [ 0 1 0 1 ] >> >> newpath 176 148.5 moveto 176 159.264 167.264 168 156.5 168 curveto 145.736 168 137 159.264 137 148.5 curveto 137 137.736 145.736 129 156.5 129 curveto 167.264 129 176 137.736 176 148.5 curveto closepath clip shfill grestore grestore gsave [0.255874 0 0 0.255874 123.1333 167.7739] concat gsave << /ShadingType 3 /ColorSpace /DeviceRGB /Coords [156.5 148.5 0 156.5 148.5 19.5] /Extend [true true] /Domain [0 1] /Function << /FunctionType 3 /Functions [ << /FunctionType 2 /Domain [0 1] /C0 [1 1 1] /C1 [1 1 1] /N 1 >> << /FunctionType 2 /Domain [0 1] /C0 [1 1 1] /C1 [1 1 1] /N 1 >> ] /Domain [0 1] /Bounds [ 0.34999999 ] /Encode [ 0 1 0 1 ] >> >> newpath 176 148.5 moveto 176 159.264 167.264 168 156.5 168 curveto 145.736 168 137 159.264 137 148.5 curveto 137 137.736 145.736 129 156.5 129 curveto 167.264 129 176 137.736 176 148.5 curveto closepath clip shfill grestore grestore gsave [0.417478 0 0 0.417478 13.28276 129.5949] concat gsave << /ShadingType 3 /ColorSpace /DeviceRGB /Coords [156.5 148.5 0 156.5 148.5 19.5] /Extend [true true] /Domain [0 1] /Function << /FunctionType 3 /Functions [ << /FunctionType 2 /Domain [0 1] /C0 [1 1 1] /C1 [1 1 1] /N 1 >> << /FunctionType 2 /Domain [0 1] /C0 [1 1 1] /C1 [1 1 1] /N 1 >> ] /Domain [0 1] /Bounds [ 0.34999999 ] /Encode [ 0 1 0 1 ] >> >> newpath 176 148.5 moveto 176 159.264 167.264 168 156.5 168 curveto 145.736 168 137 159.264 137 148.5 curveto 137 137.736 145.736 129 156.5 129 curveto 167.264 129 176 137.736 176 148.5 curveto closepath clip shfill grestore grestore gsave [0.417478 0 0 0.417478 13.28276 31.90504] concat gsave << /ShadingType 3 /ColorSpace /DeviceRGB /Coords [156.5 148.5 0 156.5 148.5 19.5] /Extend [true true] /Domain [0 1] /Function << /FunctionType 3 /Functions [ << /FunctionType 2 /Domain [0 1] /C0 [1 1 1] /C1 [1 1 1] /N 1 >> << /FunctionType 2 /Domain [0 1] /C0 [1 1 1] /C1 [1 1 1] /N 1 >> ] /Domain [0 1] /Bounds [ 0.34999999 ] /Encode [ 0 1 0 1 ] >> >> newpath 176 148.5 moveto 176 159.264 167.264 168 156.5 168 curveto 145.736 168 137 159.264 137 148.5 curveto 137 137.736 145.736 129 156.5 129 curveto 167.264 129 176 137.736 176 148.5 curveto closepath clip shfill grestore grestore gsave [0.255874 0 0 0.255874 19.66611 143.614] concat gsave << /ShadingType 3 /ColorSpace /DeviceRGB /Coords [156.5 148.5 0 156.5 148.5 19.5] /Extend [true true] /Domain [0 1] /Function << /FunctionType 3 /Functions [ << /FunctionType 2 /Domain [0 1] /C0 [1 1 1] /C1 [1 1 1] /N 1 >> << /FunctionType 2 /Domain [0 1] /C0 [1 1 1] /C1 [1 1 1] /N 1 >> ] /Domain [0 1] /Bounds [ 0.34999999 ] /Encode [ 0 1 0 1 ] >> >> newpath 176 148.5 moveto 176 159.264 167.264 168 156.5 168 curveto 145.736 168 137 159.264 137 148.5 curveto 137 137.736 145.736 129 156.5 129 curveto 167.264 129 176 137.736 176 148.5 curveto closepath clip shfill grestore grestore gsave [0.255874 0 0 0.255874 50.65376 36.99558] concat gsave << /ShadingType 3 /ColorSpace /DeviceRGB /Coords [156.5 148.5 0 156.5 148.5 19.5] /Extend [true true] /Domain [0 1] /Function << /FunctionType 3 /Functions [ << /FunctionType 2 /Domain [0 1] /C0 [1 1 1] /C1 [1 1 1] /N 1 >> << /FunctionType 2 /Domain [0 1] /C0 [1 1 1] /C1 [1 1 1] /N 1 >> ] /Domain [0 1] /Bounds [ 0.34999999 ] /Encode [ 0 1 0 1 ] >> >> newpath 176 148.5 moveto 176 159.264 167.264 168 156.5 168 curveto 145.736 168 137 159.264 137 148.5 curveto 137 137.736 145.736 129 156.5 129 curveto 167.264 129 176 137.736 176 148.5 curveto closepath clip shfill grestore grestore grestore gsave 0.72156864 0.20392157 0.015686275 setrgbcolor newpath 621.46972 524.65618 moveto 703.36444 498.92517 lineto 664.0884 533.38635 lineto 621.46972 524.65618 lineto closepath eofill grestore gsave << /ShadingType 2 /ColorSpace /DeviceRGB /Coords [58.108067 60.616997 42.782681 60.616997] /Extend [true true] /Domain [0 1] /Function << /FunctionType 3 /Functions [ << /FunctionType 2 /Domain [0 1] /C0 [1 1 1] /C1 [1 1 1] /N 1 >> ] /Domain [0 1] /Bounds [ ] /Encode [ 0 1 ] >> >> newpath 630.28777 523.32068 moveto 697.733 502.12964 lineto 665.38682 530.5105 lineto 630.28777 523.32068 lineto closepath eoclip gsave [2.6542399 0 0 1.1169018 538.73934 444.56248] concat shfill grestore grestore grestore grestore showpage %%EOF elyxer-1.2.5/test/branches-1-5.lyx0000644000175000017500000000447212074107030016140 0ustar chennochenno#LyX 1.5.7 created this file. For more info see http://www.lyx.org/ \lyxformat 276 \begin_document \begin_header \textclass article \begin_preamble % eLyXer -- convert LyX source files to HTML output. % % Copyright (C) 2009-2010 Alex Fernández % % This program is free software: 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 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 % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . \end_preamble \language english \inputencoding auto \font_roman default \font_sans default \font_typewriter default \font_default_family default \font_sc false \font_osf false \font_sf_scale 100 \font_tt_scale 100 \graphics default \paperfontsize default \spacing single \papersize default \use_geometry false \use_amsmath 1 \use_esint 1 \cite_engine basic \use_bibtopic false \paperorientation portrait \branch First \selected 0 \color #faf0e6 \end_branch \branch Second \selected 1 \color #fa6a6a \end_branch \secnumdepth 3 \tocdepth 3 \paragraph_separation skip \defskip medskip \quotes_language english \papercolumns 1 \papersides 1 \paperpagestyle default \tracking_changes false \output_changes false \author "" \author "" \end_header \begin_body \begin_layout Title Document with branches \end_layout \begin_layout Standard First some stupid text. \end_layout \begin_layout Standard \begin_inset Branch First status collapsed \begin_layout Standard In this first branch, without color, we carn write whatever we want: it is inactive. \end_layout \end_inset \end_layout \begin_layout Standard Now some intermediately stupid text. \end_layout \begin_layout Standard \begin_inset Branch Second status open \begin_layout Standard In this second branch, reddish, we have to be more careful: it is active. \end_layout \end_inset \end_layout \begin_layout Standard Finally some terminally stupid text. \end_layout \end_body \end_document elyxer-1.2.5/test/bibtex-good.html0000644000175000017500000002150012074107030016375 0ustar chennochenno BibTeX Test

BibTeX Test

1 Ethel the Frog

Some random text. With a random reference [2].

2 The Other Other Operation

And a book to prove that we have read one (untrue): [1].

3 Spiny Norman

We are going to need a reference here [3].

4 In the Grillomat

There are two kinds of vancouver references: with volume information[4] and without[5].

5 Alpha, Mr Belpit

Two references in one: [BB69, PB69]. Also, a repeated reference[BB69].

References

[1] J.M. Cleese, M.E. Palin. And Now for Something Different from Voigtländer. Python Monty Editions, 1971.

[2] S.W. Colonel. Summary for Year 1969. Journal of the Society for Putting Things onto Other Things, 457(1):1348—1350, 1969.

[3] Z.X. Pudey. My Silly Walks. Private Walkings, 1970.

References

[4] J. Linkman. A Little Hors d'Oeuvres. Just The Words, 1969;300(3):1—300. URL: http://www.ibras.dk/montypython/episode18.htm.

[5] J. Linkman. Our Main Course: Prawn Salad. Just The Words, 1969. URL: http://www.ibras.dk/montypython/episode18.htm.

References

[BB69] B. Bishop, W. Belpit. Your legs are so swollen. Just The Words, 1969. http://www.ibras.dk/montypython/episode18.htm. bibtex-good.html. Found on http://www.ibras.dk/montypython/episode18.htm.

[PB69] E. Praline, B. Brooky. The population explosion. Just The Words, 1(1): 2—4, 1969. http://www.ibras.dk/montypython/episode18.htm.

References

[Nam10] Latin1 Accents !`©ª®º?` ÀÁÂÃÄÅÅÆÇÈÉÊËÌÍÎÏÐÑ ÒÓÔÕÖØÙÚÛÜÝÞ ßàáâãäåæçèéêë ìı̀ı̀ı́ı̂ı̈ðñ òóôõöøùúûüýþÿ in Name. Latin1 Accents !`©ª®º?` ÀÁÂÃÄÅÅÆÇÈÉÊËÌÍÎÏÐÑ ÒÓÔÕÖØÙÚÛÜÝÞ ßàáâãäåæçèéêë ìı̀ı̀ı́ı̂ı̈ðñ òóôõöøùúûüýþÿ in title. Test, 2010.

[Cen34] Somebody in the Century. Finding ϵn decimals of the number π. About ζ in π things, 1934. According to The Society for

ϵn
decimals of the number
π
, only 1 in 2n dentists read this magazine.

elyxer-1.2.5/test/abstract.lyx0000644000175000017500000000233712074107030015654 0ustar chennochenno#LyX 1.6.7 created this file. For more info see http://www.lyx.org/ \lyxformat 345 \begin_document \begin_header \textclass article \use_default_options true \begin_modules theorems-ams eqs-within-sections figs-within-sections \end_modules \language english \inputencoding auto \font_roman default \font_sans default \font_typewriter default \font_default_family default \font_sc false \font_osf false \font_sf_scale 100 \font_tt_scale 100 \graphics default \paperfontsize default \spacing single \use_hyperref false \papersize default \use_geometry false \use_amsmath 1 \use_esint 1 \cite_engine basic \use_bibtopic false \paperorientation portrait \secnumdepth 3 \tocdepth 3 \paragraph_separation indent \defskip medskip \quotes_language english \papercolumns 1 \papersides 1 \paperpagestyle default \tracking_changes false \output_changes false \author "" \author "" \end_header \begin_body \begin_layout Title Abstract Test \end_layout \begin_layout Abstract This document is a test of the abstract capabilities of LyX. \end_layout \begin_layout Abstract When exported in LyX, this abstract should be shown contiguous. \end_layout \begin_layout Standard Apart from the abstract, not much more yet. \end_layout \end_body \end_document elyxer-1.2.5/test/appendix-1-6-frameset.html0000644000175000017500000000025112074107030020107 0ustar chennochenno elyxer-1.2.5/test/with images-1-5-inkscape-good.html0000644000175000017500000000310112074107030021411 0ustar chennochenno Images Tests

Images Tests

figure elyxer-svg.png First image: regular path.
figure elyxer-svg.png Second image: convoluted path.
figure docs/elyxer.png Third image: from another directory.
figure mini-elyxer.jpg Fourth image: from a JPEG file.
figure square.png Fifth image: from a PNG file.
elyxer-1.2.5/test/table-1-6-good.html0000644000175000017500000002336412074107030016522 0ustar chennochenno Table Test

Table Test

Alex Fernández (elyxer@gmail.com)

This test may contain several tables.

1 Longtable

The first one comes straight from the LyX User Guide, shortened.
Example Phone List (ignore the names)
NAME TEL.
Annovi Silvia 555
Bertoli Stefano 555
Bozzi Walter 555
Cachia Maurizio 555
Cinquemani Giusi 555
Colin Bernard 555
Dal Bosco Carolina 555
Dalpiaz Annamaria 555
Feliciello Domenico 555
Focarelli Paola 555
Galletti Oreste 555
Rizzardi Paola 555
Malfatti Luciano 555
Meneguzzo Roberto 555
Pirpamer Erich 555
Radina Claudio 555
Unterkalmsteiner Frieda 555
Vigna Jürgen 999
Winkler Franz 555
End

2 Multicolumn

The second table contains some multicolumn cells.
12 3 4
1 23 4
1 2 3 4
1234
1 234
12 34
123 4

3 Alignment

Now for some non-standard alignments.
left center right
left-top figure elyxer.png right-top
left-middle center-middle figure elyxer.png
figure elyxer.png center-bottom right-bottom
Bit of a mess, wasn’t it.

4 Multi-row

A table with several rows per cell.
First Part Second Part
First subpart
Second subpart
Now with a supplementary row
Third subpart Fourth subpart
row
The first row
The second row
The third row
Empty
The first row
The second row
Empty too
row
Only three rows: first
Only three rows: second
Only three rows: fourth
Mostly empty Not empty
elyxer-1.2.5/test/elyxer-svg.jpg0000644000175000017500000002056012074107030016120 0ustar chennochennoJFIF22C       C " D!1AQa"2q #BR$r3b4CD&ds= !1AQ"aq2B#Rb3r ?ڞ4!4hЄhѥx|VdO.o CO٣ 'B/I#i ԑx?}R|oǘᦿj6.n.3oaLoSj)v;´(z0H ]FF4!4hЄhѣBFF4!4hЄhѣBvI㷵i+?nR0JQ(sOyµ/< Jz8tm@:\D2Ejp%fNnj žxA}Uw Ay O6Zd6\*dSg>iߟs!?LٓaR0R$FJ@R$N`:$%:)(I zJz%(BNy WFFzhBFF4!4hЄhѣBFFwMa6Wd  =m/SPZkT^\hB-n-^*ZrI9?={W![v-sRՆHq]s ˵U&3LEvLr BR9I]n?c쩵yaA*$7D6栟!+*J3u"C*){}KL Xf)8@22@)nF>4?KU=x| #Ȥ5}ݦ=qï:ƷjlVVy!gZyji}ZLm>Pa1ں_#?x/-dIn,@9v۾VKڗߩBT ɋ! (!+A)P{[ns%'>#*sJ7^"ۍ%b~k'C8}@Spl-Jfݏx["M1[ǟIǑQ,VzY8ZNX[ Ƕ[Z{V^ݽUԉM沐P(kvLio50/Ijҥ#3Y&zn~'Km @m$%/7x@ OSFI:Z;-5iصZTث=T':{WA%#`, ZG7em!GRTN"g Kl$IӵkºjR@~ZD96z!)g$Ƒ6/v'ԥd"a K@hѣShѯ r)JX#Uk \,atWA7wHvzG>F= -[ nv˰.zL pCTeJy_@~E}՘UK=SCb8*Zː*]Pj[RW4B}@'9¢tck iql4䓧h|Otk]k{ra. ;F辪ڵ7-^$OS;=#f~5~!BQ~ZM*_ LuiwhǑ ~yTWh)ZR#꺎 q4+#Sp"*dŰ6pR `mTxTڧ}7!Kj{ȤBwΈ w%= ΗRzW+]IoA^O™Aw;|u{SX|:'_T̟ՏC$MmzuFQn)F98ZȹxdaY+`ngCzvVgz F ɸmK M&XqlS~SU:#"m6šB^%"cy5@`$w%@bZ5Ol,@|yakqZ$kѐS$9$SpU] 9Ґ;Vfvo6wphیc<@2˩wj)?}D)P٨S5&,/4829GEQ4h"6=>빪L^}Ԩ$Xs\` \1r\ )+q$ I۽]jnm V]QL;Ld*3N8ڐ]QJTH9G-ދy[U)#sǺJ_TUFp{ s9N%SF-~#_rSQ\Go};πR\+Td(d G|)Ч8EjR[),-^#UWPz$Kfni-4jILpt#,gFn-58)Km>Ip9j_7%r}La0uH>|#LBz=ٜu镕 nVe ļ/}UrQF{i||zs'X4Bqj!k) ⠜

Ұ5 FW%sil)uq _~z_T ~͊%w:]q⡎CW4dGdyYPKPRHrһB#qLsA76p-f#CALpj/săᦫDˮj3y31*qDu2O쿸#[Ue@l-֪alAG c㞩e]oZb&ʖKg~PfJul8)[aq;BIDRNZq.|ti%qRYl.βGmv _jb Ae9(+3GܶsBEC8r<`8#Z9)$u9I#es7;^( ]o/nJ_T)peGu'ՇHj=o.)lss*5^[w"ňXp > A9`=T;5-ujh5S7^ǑOk[wSTUifk*<%39A Ny#0RS(P?=5RE.Jē#S^jS;rĪnPq$X}+S E<< Y=R;Y^Sk"@8GC:mc{b 6ܝi[d9&ba N{knݼؚ$iJI@J#&dU4'PIH9 DuvCHKM!(BJRC+x ]܋֓~Wui 3r ۵oꭽŶبLEˣAˡ0G-Ntk lr>lG0W`uZz[ˋ@G?'5C7jZSG}q$-q mą%@$<+L݀V܆/EG>-'<8McR1]!mE-~G|9VnV E}2JTϨey\k4Е)mcA /PjDtO K\A)Pjڞ;ͻәfX"RңhxO,|)QUH%P$Juy_G ]Y'kvz:H)v5~º [tʁ].ɒrcx&*Y[8d(YEӦj 1;jyzNIBK7yӢ݋ε⢳XЊp J <ӹGMwr:[|fTG1<20u%OlM)wV;$-,] Ʊ˗ ydի vjytU,_$0=<7IQu';U:{t\qԣ  B[aBW[4-aC88^g}BoMXuڱ_糖%6GBA #]`S`:_~ՀOcnZhy)\ 1 J!³H_;ږ>Sj!ާ8'vpgpv$}ħĆ? ף@@#g3d}UyunҦSv <$ WVݻ="ER&->LVՅ,gs?liګzz+3rZg)pK\A~.$(HB'NQ l.ﻴ?죻-B"Yq_yGjGF]n4X#FQF\Vk QI5FFGb[Eo2Jmą%i#yG4hFy;vdVX˦>E2R㴳) *F['لe8 Converted document

Hello world

(C) 2013

elyxer-1.2.5/test/with images-1-5-jpg-good.html0000644000175000017500000000345512074107030020410 0ustar chennochenno Images Tests

Images Tests

figure elyxer-svg.jpg First image: regular path.
figure elyxer-svg.jpg Second image: convoluted path.
figure docs/elyxer.jpg Third image: from another directory.
figure mini-elyxer.jpg Fourth image: from a JPEG file.
figure square.jpg Fifth image: from a PNG file.
elyxer-1.2.5/test/plain-text-good.html0000644000175000017500000000355212074107030017214 0ustar chennochenno Plain Text Test

Plain Text Test

This document will test whatever happens with plain text.

1 Paragraph Justification

Well, to discuss the implications of that sketch and to consider the moral problems raised by the law-enforcement methods involved we have a duck, a cat and a lizard.
Now first of all I’d like to put this question to you please, lizard. How effective do you consider the legal weapons employed by legal customs officers, nowadays?
Well while you’re thinking about that, I’d like to bring the duck in here, and ask her, if possible, to clarify the whole question of currency restrictions, and customs regulations in the world today.
Perhaps the cat would rather answer that?
That is all for now.
elyxer-1.2.5/test/mourning.svg0000644000175000017500000001372312074107030015673 0ustar chennochenno image/svg+xml elyxer-1.2.5/test/Test.java0000755000175000017500000000343112074107030015074 0ustar chennochenno// Comment. // A Test class based on Paul Hunter's Selection.java in MathToWeb. /* * Another comment. */ // A third comment. public class Test implements AnInterface { // Constructor public Test(int par1, int par2) { if (par1 > par2) { this.attr1 = par2; this.attr2 = par1; } else { attr1 = par1; attr2 = par2; } } public Test(Test original) { attr1 = original.attr2; attr2 = original.attr2; } // Empty constructor. public Test() { attr1 = -1; attr2 = -1; } public Object clone() // Embedded comment. { try { return super.clone(); // Another embedded comment } catch (CloneNotSupportedException e) { return null; } } public void indecrease() { this.attr1++; this.attr2--; } public void plusize() { return new Test(this.attr1++, this.attr2++); } public String toString() { return ("attr1 = " + attr1 + ", " + "attr2 = " + attr2); } public void message(String message, Test original) { for (int i = 0; i < message.length(); i++) { if(message.charAt(i) == '\'') { System.out.println("Quote in message"); } else if (message.charAt(i) == 'P') { System.out.println("P in message"); } try { System.out.println("Hullo"); } catch (Exception e) { // nothing to do here } } String mossage = (String)message; int value = (5 * 8) / 40; while (value != -1) { value--; } } public void runThread() { Test test = null; this.message("hello", (Test)test); new Thread(new Runnable() { public void run() { total = 0; int i = 0; while (i < 100) { total += i; } } }).start(); } public int attr1; public int attr2; } elyxer-1.2.5/test/index-1-6.lyx0000644000175000017500000002630012074107030015455 0ustar chennochenno#LyX 1.6.7 created this file. For more info see http://www.lyx.org/ \lyxformat 345 \begin_document \begin_header \textclass book \begin_preamble % eLyXer -- convert LyX source files to HTML output. % % Copyright (C) 2009-2010 Alex Fernández % % This program is free software: 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 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 % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % DO NOT ALTER THIS PREAMBLE!!! % % This preamble is designed to ensure that the User's Guide prints % out as advertised. If you mess with this preamble, % parts of the User's Guide may not print out as expected. If you % have problems LaTeXing this file, please contact % the documentation team % email: lyx-docs@lists.lyx.org \usepackage{ifpdf} % part of the hyperref bundle \ifpdf % if pdflatex is used % set fonts for nicer pdf view \IfFileExists{lmodern.sty}{\usepackage{lmodern}}{} \fi % end if pdflatex is used % for correct jump positions whe clicking on a link to a float \usepackage[figure]{hypcap} % the pages of the TOC is numbered roman % and a pdf-bookmark for the TOC is added \let\myTOC\tableofcontents \renewcommand{\tableofcontents}{% \frontmatter \pdfbookmark[1]{\contentsname}{} \myTOC \mainmatter } % redefine the \LyX macro for PDF bookmarks \def\LyX{\texorpdfstring{% L\kern-.1667em\lower.25em\hbox{Y}\kern-.125emX\@} {LyX}} % define a short command for \textvisiblespace \newcommand{\spce}{\textvisiblespace} % macro for italic page numbers in the index \newcommand{\IndexDef}[1]{\textit{#1}} % redefine the greyed out note \end_preamble \options intoc,bibtotoc,idxtotoc,BCOR7mm,tablecaptionabove \use_default_options false \begin_modules theorems-ams eqs-within-sections figs-within-sections \end_modules \language english \inputencoding auto \font_roman default \font_sans default \font_typewriter default \font_default_family default \font_sc false \font_osf false \font_sf_scale 100 \font_tt_scale 100 \graphics default \paperfontsize 12 \spacing single \use_hyperref true \pdf_title "Index Test" \pdf_author "Alex Fernández" \pdf_subject "Reconstituted from various sources" \pdf_keywords "LyX" \pdf_bookmarks true \pdf_bookmarksnumbered true \pdf_bookmarksopen false \pdf_bookmarksopenlevel 1 \pdf_breaklinks false \pdf_pdfborder false \pdf_colorlinks true \pdf_backref false \pdf_pdfusetitle false \pdf_quoted_options "linkcolor=black, citecolor=black, urlcolor=blue, filecolor=blue,pdfpagelayout=OneColumn, pdfnewwindow=true,pdfstartview=XYZ, plainpages=false, pdfpagelabels,pdftex" \papersize default \use_geometry false \use_amsmath 1 \use_esint 0 \cite_engine basic \use_bibtopic false \paperorientation portrait \secnumdepth 3 \tocdepth 3 \paragraph_separation skip \defskip medskip \quotes_language english \papercolumns 1 \papersides 2 \paperpagestyle default \tracking_changes false \output_changes false \author "" \author "" \end_header \begin_body \begin_layout Title Index Test \end_layout \begin_layout Standard \begin_inset CommandInset toc LatexCommand tableofcontents \end_inset \end_layout \begin_layout Part The Making \end_layout \begin_layout Chapter Explanations \end_layout \begin_layout Standard This chapter contains a lot of explanations for terms \begin_inset Index status open \begin_layout Plain Layout terms \end_layout \end_inset , which you might want to \begin_inset Index status open \begin_layout Plain Layout look ! up \end_layout \end_inset look up later \begin_inset Index status open \begin_layout Plain Layout later \end_layout \end_inset . Because better sooner \begin_inset Index status open \begin_layout Plain Layout sooner \end_layout \end_inset than later, although later \begin_inset Index status open \begin_layout Plain Layout later \end_layout \end_inset has been repeated twice \begin_inset Index status open \begin_layout Plain Layout twice \end_layout \end_inset . Actually, thrice \begin_inset Index status open \begin_layout Plain Layout thrice \end_layout \end_inset now. \end_layout \begin_layout Standard Do you not want to look any of them up \begin_inset Index status open \begin_layout Plain Layout look ! up \end_layout \end_inset right now? No problem. You will be able \begin_inset Index status open \begin_layout Plain Layout able \end_layout \end_inset to do it later, in the index \begin_inset Index status open \begin_layout Plain Layout index \end_layout \end_inset . \end_layout \begin_layout Standard Now we will add two cites in one, just because \begin_inset CommandInset citation LatexCommand cite key "key-1,key-2" \end_inset . \end_layout \begin_layout Standard As we will see in \begin_inset CommandInset ref LatexCommand ref reference "cha:Bulk" \end_inset , not everything is clear. \end_layout \begin_layout Standard You could also look down \begin_inset Index status open \begin_layout Plain Layout look ! down \end_layout \end_inset on someone, but that is not nice. \end_layout \begin_layout Section \family typewriter Magical \family roman type \family default \emph on face \emph default \series medium changes \series default \noun on in \noun default \size normal the \size default world \end_layout \begin_layout Standard Little more can be added, at least at this point. \end_layout \begin_layout Section \color red Color \color inherit \begin_inset space ~ \end_inset and \lang british colour \end_layout \begin_layout Standard At this other point, however, more could be added, but won't. \end_layout \begin_layout Section* Unnumbered Section \end_layout \begin_layout Standard They have a right to live too. \end_layout \begin_layout Itemize A list would be nice here. \end_layout \begin_layout Itemize Because it corrupts the next chapter's beginning. \end_layout \begin_layout Chapter Nomenclature \end_layout \begin_layout Standard We should explain what an index \begin_inset Index status open \begin_layout Plain Layout index \end_layout \end_inset is. We can do that with the nomenclature \begin_inset CommandInset nomenclature LatexCommand nomenclature symbol "nomenclature" description "A list of common words with an explanation." \end_inset . Normally we will want to mix index \begin_inset CommandInset nomenclature LatexCommand nomenclature symbol "index" description "A list of terms with a reference to where they occur." \end_inset \begin_inset Index status open \begin_layout Plain Layout index \end_layout \end_inset and nomenclature terms. But what happens if we actually do? We will know later \begin_inset Index status open \begin_layout Plain Layout later \end_layout \end_inset , when we generate \begin_inset CommandInset nomenclature LatexCommand nomenclature symbol "generate" description "An activity that requires a source and a destination, something like eLyXer does with files." \end_inset the file. \end_layout \begin_layout Section Reminder \end_layout \begin_layout Standard We have to remind the reader that things will be remembered \begin_inset Index status open \begin_layout Plain Layout remembered \end_layout \end_inset . \end_layout \begin_layout Section Remainder \end_layout \begin_layout Standard Whatever remains should be explained \begin_inset Index status open \begin_layout Plain Layout explained \end_layout \end_inset here. \end_layout \begin_layout Part The Additions \end_layout \begin_layout Chapter Bulk \begin_inset OptArg status open \begin_layout Plain Layout Bulk, or what used to be bulk text \end_layout \end_inset \begin_inset CommandInset label LatexCommand label name "cha:Bulk" \end_inset \end_layout \begin_layout Standard We actually need a lot more text \begin_inset Index status open \begin_layout Plain Layout text \end_layout \end_inset in order for our index \begin_inset Index status open \begin_layout Plain Layout index \end_layout \end_inset to have more terms \begin_inset Index status open \begin_layout Plain Layout term \end_layout \end_inset ; so we can find out if the links \begin_inset Index status open \begin_layout Plain Layout link \end_layout \end_inset are working. Since they are anchors \begin_inset Index status open \begin_layout Plain Layout anchor \end_layout \end_inset inside the page \begin_inset Index status open \begin_layout Plain Layout page \end_layout \end_inset , they might otherwise just take us to the \begin_inset Index status open \begin_layout Plain Layout top of the page \end_layout \end_inset top of the page, and we would not like that. \end_layout \begin_layout Standard Yes, it would be bad for us. But on the other hand \begin_inset Index status open \begin_layout Plain Layout hand \end_layout \end_inset too much text \begin_inset Index status open \begin_layout Plain Layout text \end_layout \end_inset can hide \begin_inset Index status open \begin_layout Plain Layout error \end_layout \end_inset errors. So not much more text \begin_inset Index status open \begin_layout Plain Layout text \end_layout \end_inset is needed. \end_layout \begin_layout Standard Thanks for reading us. \end_layout \begin_layout Part* Unnumbered Part \end_layout \begin_layout Chapter* Unnumbered Chapter \end_layout \begin_layout Standard This extra chapter contains nothing of interest except for a couple of unnumbere d parts (one actual part and one chapter). \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand include filename "toc-book.lyx" \end_inset \end_layout \begin_layout Standard \begin_inset CommandInset index_print LatexCommand printindex \end_inset \end_layout \begin_layout Standard \begin_inset CommandInset nomencl_print LatexCommand printnomenclature \end_inset \end_layout \begin_layout Bibliography \begin_inset CommandInset bibitem LatexCommand bibitem key "wordreference-elixir" \end_inset WordReference.com: \begin_inset Quotes eld \end_inset definition of elixir \begin_inset Quotes erd \end_inset , accessed March 2009. \begin_inset Flex URL status collapsed \begin_layout Plain Layout http://www.wordreference.com/definition/elixir \end_layout \end_inset \end_layout \begin_layout Bibliography \begin_inset CommandInset bibitem LatexCommand bibitem key "key-1" \end_inset W3C: \begin_inset Quotes eld \end_inset HTML 4.01 Specification \begin_inset Quotes erd \end_inset , 24 December 1999. \begin_inset Flex URL status collapsed \begin_layout Plain Layout http://www.w3.org/TR/REC-html40/ \end_layout \end_inset \end_layout \begin_layout Bibliography \begin_inset CommandInset bibitem LatexCommand bibitem key "key-2" \end_inset W3C: \begin_inset Quotes eld \end_inset HTML 4.01 Specification \begin_inset Quotes erd \end_inset , 24 December 1999. \begin_inset Flex URL status collapsed \begin_layout Plain Layout http://www.w3.org/TR/REC-html40/ \end_layout \end_inset \end_layout \end_body \end_document elyxer-1.2.5/test/footnotes-1-6-good.html0000644000175000017500000001273312074107030017451 0ustar chennochenno Footnotes Tests

Footnotes Tests

1 This is just some random section text used to insert some footnotes. [A]  [A] And this is one of those footnotes. And this is a margin note, also tested here.

Lorem ipsum dolor sit amet, consectetur adipisicing [B]  [B] adipisicing elit [C]  [C] elit, sed do eiusmod eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa  [D]  [D] culpa qui officia  [E]  [E] officia deserunt mollit anim id est laborum.
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum [F]  [F] laborum, laborum.
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do tempor incididunt ut  [G]  [G] ut labore [H]  [H] labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis Duis aute irure dolor in reprehenderit in voluptate velit [I]  [I] velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id id est laborum.

Nomenclature

eiusmod eiusmod indeed

References

Index

ullamco:

elyxer-1.2.5/test/mourning.png0000644000175000017500000003417312074107030015662 0ustar chennochennoPNG  IHDR[,ƽbKGD X pHYsdd vpAg[3=7TIDATxw@sPQ+WiWjy+ m.53fjLDEbÁ3>?\[yρ<J""*+*T&?xW a ,p>e2E59!ĵ=7/ޥ J 5ީOn7GMDDeC¦l`}?=Yl=sˮ""r6r368׌_yEϿHnd~BDTapP\? H=+?.Cih9 ]!""gPQ@kt˩*@d\m:xl""*-*1 H{z&&<}yAEDDC%o@ިQEE`t-!o!"Pb8`Gܮ+TPWُ']ADD%šB8?`5s ""*)rȖ77 ֢k''yw9~""*.[E܍#EהܵW'_]ADDšBkH)H蚒+pOFtVtS-oo2>0wU újG)>SgS` Ӆ6 yM@Z?=4|b lJ^ xjO}:.qg뉈JCuG9 I7Eהªrխ.sE}G2poY~1T*8y/3pF2P5@΂e##"*S7\ϼ@;EהN.#l>?* Ngd*gxQm =ǽXڬ}DDǡB*]8Eה<+π ,`64,KDlD͸[?:`>`kؽ:czW\s9`Ϗ rRoRVFVpI#]4F#4DDTD:EtE)ll@HSױxZ|-Oou`˯'G #=Rfk߿ "'*_׻? `!\5%'S4uzjo]=8@M8'IDD%OTz;h$4a'z͒U<vo(k{u\/8TruL@njNsſh LsN˝m*W`{-s>Xۼ>~05DDP?HA- ]41{Ҧ*(Ήu_6DqПX5fFm=ÖgUs9+;wX)gid }4eGlE= &'6.uIX%S~RKNxI}Te/t)DDjšBy8!U?[5@- mqAwh׸Qҿ  GUnnvWhxs]fEb@_bcyIGtmhD3=娩 ^wCww[񈢼,rc?sH+”3G\\&vz.,))$r{SG>=奀2}@>ݍ@*]ʎCTC kk#$][`S3`_t@nRWB@U G4 zxWkR MM&ЪoKcsk*]nJ?-@ʶϰ9XH13zO,Qz}ӻ X0[D џhomkʏΒ3xᵉo=yFtMW42|~@n^tEOmk]A Q1 扦ykOj@@sg^G Eה½lTs^`G1Tp֤5iM@ ]S~MGxPqK97{2_W\3sl8TJ߼o: HjTHL.4s$:FyW5qFcʊC=gumV;fJͪ-Byh h"5kJ%*+Rh,i.vy5TtMٳllDWW n'-R\ ;mG2t+蚲_St+?F4_)=C'OʊC 4VYcNрRΖ+ꬨ) : EW8OzhʎCȉhosW26-F}LM}Ls{ tULEuyEtUv*De`@@V/ƈ)&Oz]^~44ڊ0L?Mڽ6It Uv*Deh_ [ u ^Ƭ ߯zߩk[CR/p7}8TΣ֎X a쮛˙|=\Ǿ/F4gDW8O-oAtѿiEU&Cj=^}@2Ùig5TXvkWҧ` c~·)s˷@UWwۦ%PV5>ZWu)^TGtUUYeƌ~"P!r!E_55L &q3_|T+ooo~u`y=%qpen/qU77: HڹjegC1iTCIr;w6ŀ}}c4r_=ʇ2[޽Ps@`v`w1*DDe$쏳?Nt|tz*#;c:p7 oR`ind73HA};ʝ mg\j5A@ Sͦ6 dlm P!"""╈DDDZ*DDDZ*DDDZ*DDDZ*DDDZ*DDDZ*DDDZ*DDDZ*DDDZ*DDDZ*DDDZ*DDDZ*DDDZ*DDDZ*DDDZ*DDDZ*DDDZ*DDDZ*DDDZ*DDDZ*DDDZ*DDDZ*DDDZZDquI!pث.l[a@U?zw]TSeRIQrcZ|߿t;eCz4w^u:PegAקZ՚!興p*:;왴w%,Ea~Qe/?mq'm_4 n+艈 ) SQm4=hҹG ZU=۶"p[oh-$rF~=Mièf:1`QšBb{^}3<Hik̀X4I%ѵ_{os&]'\Ь+nAm""<8TLmڿ? W~Sk&X͢JNgmW@ف*.*9uti}id|DW9m u^zA 8" C*kԹow\< ?V &rύbh]cZ\oFN@`S;[yJk1k6m]MNDW>~BNeΣ t5)MɹGopr?~Ht'*T*9O弒3pg}. o-6^Nt PRY`s9F/}!F}r YiIE*o1Z:/]bRy/ptndșc\JH%{恟{Dר_-_ DDPdϼy>(}'uXtDW*]!F?~alw""BŒbΛZ`]. w ""sT!1KcUR#m8wqtɸT~?^^/-ֹ@k6d_E;DD Y1sc1ǁ|7ѭ Mе. ޻Q(ߔ\i#Mn@hޝfZ֤-ǁDDDC\Mk3 @۱Y#o?s{&`~~0xyO>U< 4jtᣀ7޳g>""z"""R-TCTCTCTCTCTC=:"Ya7}THA݂Ma Myjv\@R(/|gw ԝZ\'VQšBDTF~[Ȫw\IcR`zsm  U.*DDNq2#;S,'R@JDjzoѕTYp9ɩSQ6G\zzEKUa 'r?v}}7`H4bDGREáBD$NMQ_Y+l> _֢Fz@f}B~]GCI~Y+c<};ˢkT ZUzAǀCtkȐy[tr9IlEWs٤wn "VX}Wـh5Z#I Q)Dˍ׷Fwƞ^EW}9ThYXkm5#Dӽ"P!"*) S+,ai1ȳ*%6}=1St 9 $μTR/@v3t0w﫠)D戎!gP!"b~ KyVوo"΋!gP!"tCɜ`TR'ם6>[t9 Vޢ+s1]Q 3P!"eY@t|fЪ1c8TBY6jhšBDG&@t4C7-8{z5TR*DD w]Ar+qWEWPIq *7 #<[*쪴*gu-Bt@ Wm(MIiYYhٛؗIӀëtJk]3ꄪv}ZHQֈnғW&q\HnjSU(IGtQE5ӷ+߿5pM΀1@?Fj(T ra Bəw!IGu]t.ײR?^[[Z'M!gI e*šBT ο?Zt㊾:¼^DWn]c,w/^m-šBTEEL.M]S|}IwؕvU77ԫkjvKDPi}U_t9C"3Nx:TxngϺIOvX<-E-I]C%B r Q1ܜwgT+Oե^]^CNAm ޖ̢+Q*D( VWg1䈮)G󌣽?n;uV1F@hf5(^ EW8T83q ԵUHLN>U#4݁?y굌k{c("/Kr qR>DW֤5iM@smj% {*#{Vw*֩@t0}ҘFL4 n+DP!*Gs!N4O޿5<1A~ 6;װ=`?c>c2*9E~eiTyɖdI}/xHW@.D{D [vHndk|fUITBzS#<ك1 n4k(8Qp?06޳#,0= KEݧtUv)y@6 6 D'1>1k6[H0@3W&Wŀclz> ]ܼAV"* *D at<ѷ@q0m8Sw5olU+t]z~} EKDDCH d]TR fnfi&i!L[=oc{ < `$sp޲@6 <tޱs|Z*Jc646Dl>O@zM\k.eyuk};ܧ35CDDáRAxũqCr!XA:>U*""R/m<2bǾ'&Jo&r#,&EWh*.GE䳆EW9EYhl 3@ 8""*w**=̩`_X$IʏFcZ qO5:y""¡R':8u)O"J肤@hZcc[@V^Lt5)eP\ld?RF*:% O~ua@6&R uq5_))F_{/xpkӷREq5uz\`ig@]׋r{罖څONIt9 OXiƀ N2>(ٻ7""9*~EʇX|ڗ2b=DDj8Tٞ^aBDTE7rxj0UDD e9ÁI2df{5nt ""R7ryɞ/×dYѤƉ#!4-)*""+*D3O~T%nF#!pq]xUDDG*$`uc>??{e>?@DF䏑񢫈J9;3hgWtnpdOBk9GNDT""R+rRuϼ*oR4O jԞzTtQšRN7Ƕ<^t9l*ge<m/*2}ڬ0̅9qk id""**elǨywn*Pi8oO^DE> :P)c)>y'/ ˁ=M H韲0e("C\{ڞk*Ţkي.rWKEU\*e$Nߊ!ʚclKDTV8Tȍ1Ygr/nش6 PqKˋ/n'ʋls1}3|־5DD3r3X͢k{LO#Pq d&YcEkU\p8Hc՘5f;DZl!rP)m;>Ѯ+d{_5jx~QtP)GDDא/P#_tP)Q Y>(O]CDDT1qNk!+w?\P` bP)zmkbZt6VzN&up8Iuki7d?Tp{=]tn_g "rr萊=oL79ȨmgT:]j{?8}lQkԏC>TXvkoD5nR&R)0k>!L""pi0p̉N&% 7j [:E7Ct%2R)Y@[y۷=v*""rVh5'vD88+W֚ƀͰSt%!@fN?QDDCEa@tggz\)8` H{<5,(zT۬:'=wk*""šRAwJ2 Z:!"yJקTU* ??tn_G?oBuDDC5[@l;ׇI= Ͱ̱6G5rYt $aʋ9݀Z||}h=:j窝EGU<*(P\v-;՗nǧ? 7o(o)n%ns4]Q8~|dt?ڽl>_B'!SZhW P!k@w9MrF99Ksyy?>׀.Q75_0d+t]J-3u S@I653c Change Test

Change Test

Prisoner:Well... I’d just like to say, m’lud, I’ve got a family... a wife and six kids... and I hoope very much you don’t have to take away my freedom... because... well, because m’lud freedom is a state much prized within the realm of civilized society. It is a bond wherewith the savage man may charm the outward hatchments of his soul, and soothe the troubled breast into a magnitude of quiet. It is most precious as a blessed balm, the saviour of princes, the harbinger of happiness, yea, the very stuff and pith of all we hold most dear. What frees the prisoner in his lonely cell, chained within the bondage of rude walls, far from the owl of Thebbes? What fires and stirs the woodcock in his springe or wakes the drowsy apricot betides? What goddess doth the storm toss’d mariner offer her most tempestuous prayers to? Freedom! Freedom! Freedom!
Judge:It’s only a bloody parking offence.
elyxer-1.2.5/test/footnotes-1-6.lyx0000644000175000017500000001325012074107030016366 0ustar chennochenno#LyX 1.6.7 created this file. For more info see http://www.lyx.org/ \lyxformat 345 \begin_document \begin_header \textclass article \begin_preamble % eLyXer -- convert LyX source files to HTML output. % % Copyright (C) 2009-2010 Alex Fernández % % This program is free software: 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 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 % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . \end_preamble \use_default_options false \language english \inputencoding auto \font_roman default \font_sans default \font_typewriter default \font_default_family default \font_sc false \font_osf false \font_sf_scale 100 \font_tt_scale 100 \graphics default \paperfontsize default \spacing single \use_hyperref false \papersize default \use_geometry false \use_amsmath 1 \use_esint 1 \cite_engine basic \use_bibtopic false \paperorientation portrait \secnumdepth 3 \tocdepth 3 \paragraph_separation indent \defskip medskip \quotes_language english \papercolumns 1 \papersides 1 \paperpagestyle default \tracking_changes false \output_changes false \author "" \author "" \end_header \begin_body \begin_layout Title Footnotes Tests \end_layout \begin_layout Standard \begin_inset CommandInset toc LatexCommand tableofcontents \end_inset \end_layout \begin_layout Section This is just some random section text used to insert some footnotes. \begin_inset Foot status open \begin_layout Plain Layout And this is one of those footnotes. \end_layout \end_inset \begin_inset Marginal status open \begin_layout Plain Layout And this is a margin note, also tested here. \end_layout \end_inset \end_layout \begin_layout Standard Lorem ipsum dolor sit amet, consectetur adipisicing \begin_inset Foot status open \begin_layout Plain Layout adipisicing \end_layout \end_inset elit \begin_inset Foot status open \begin_layout Plain Layout elit \end_layout \end_inset , sed do eiusmod \begin_inset Marginal status open \begin_layout Plain Layout eiusmod \end_layout \end_inset tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa \begin_inset Foot status open \begin_layout Plain Layout culpa \end_layout \end_inset qui officia \begin_inset Foot status open \begin_layout Plain Layout officia \end_layout \end_inset deserunt mollit anim id est laborum. \end_layout \begin_layout Standard Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum \begin_inset Foot status open \begin_layout Plain Layout laborum, laborum \end_layout \end_inset . \end_layout \begin_layout Standard Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do \begin_inset CommandInset nomenclature LatexCommand nomenclature symbol "eiusmod" description "eiusmod indeed" \end_inset tempor incididunt ut \begin_inset Foot status open \begin_layout Plain Layout ut \end_layout \end_inset labore \begin_inset Foot status open \begin_layout Plain Layout labore \end_layout \end_inset et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco \begin_inset Index status open \begin_layout Plain Layout ullamco \end_layout \end_inset laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. \end_layout \begin_layout Standard Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod \begin_inset Marginal status open \begin_layout Plain Layout eiusmod \end_layout \end_inset tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis \begin_inset Marginal status open \begin_layout Plain Layout Duis \end_layout \end_inset aute irure dolor in reprehenderit in voluptate velit \begin_inset Foot status open \begin_layout Plain Layout velit \end_layout \end_inset esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id \begin_inset Marginal status open \begin_layout Plain Layout id \end_layout \end_inset est laborum. \end_layout \begin_layout Standard \begin_inset CommandInset nomencl_print LatexCommand printnomenclature \end_inset \end_layout \begin_layout Standard \begin_inset CommandInset bibtex LatexCommand bibtex bibfiles "bibtex-alpha" options "plain" \end_inset \end_layout \begin_layout Standard \begin_inset CommandInset index_print LatexCommand printindex \end_inset \end_layout \end_body \end_document elyxer-1.2.5/test/copyimages/0000755000175000017500000000000012074107224015453 5ustar chennochennoelyxer-1.2.5/test/copyimages/elyxer-svg.svg0000644000175000017500000015524512074107030020310 0ustar chennochenno image/svg+xml elyxer-1.2.5/test/copyimages/with images-1-5-good.html0000644000175000017500000000315512074107030021767 0ustar chennochenno Images Tests

Images Tests

figure elyxer-svg.svg First image: regular path.
figure elyxer-svg.svg Second image: convoluted path.
figure docs/elyxer.svg Third image: from another directory.
figure mini-elyxer.jpg Fourth image: from a JPEG file.
figure square.png Fifth image: from a PNG file.
elyxer-1.2.5/test/copyimages/mini-elyxer.jpg0000644000175000017500000000304712074107030020416 0ustar chennochennoJFIFddC  !"$"$C2:"0!1A"Q2aRr#Bq'1A!"Qa2 ?죬jɣ 'UўIO@d/~#xCuO_L3M:!5;{{ 5,$}t3,%H)?s~ԋ8$3ΐ?XZ,T5U"OC bF˜9UJs;lz-OC)l$vtvu-5Jv;4UFG`A zquԣ#]`=u:B|^5ixbS~Jʇ ({}18|QSKQfE.뜖Wf0z7\,* DK/y{ Qk멧j(dsPsǼnq c;k]iN,cgl@K`W r"|DheIϗV$*n{|+3IJdD_EEqN6`,4OJr} :ݩ;ܷ.ਹ9U'.rA>ge>{:+_Ը.s!op|~&*6m^+3eɗļov%edvoQi@d+'9}`k<#BB7lJNdU5uSҼBHA7zC2:b\.skK45*ŠWKHV+Ĝ04_WTΪ4;$\/MNzι]]wGU|8?o};:Y8$֑>QDu5B㶧yQDJZ@![vN''2jh@ZoomǸ6Ҿ% u Ӿ,&$q%}smtTI(7=陼VǸܨiW[y7@븐ay = W&\7d۶J)9OW J?kZ-;j[픩MNU$Ē}$l5*4 u4j>:4hCF$@jth elyxer-1.2.5/test/copyimages/docs/0000755000175000017500000000000012074107224016403 5ustar chennochennoelyxer-1.2.5/test/copyimages/docs/elyxer.svg0000644000175000017500000015524512074107030020443 0ustar chennochenno image/svg+xml elyxer-1.2.5/test/copyimages/with images-1-5-test.html0000644000175000017500000000315512117174766022040 0ustar chennochenno Images Tests

Images Tests

figure elyxer-svg.svg First image: regular path.
figure elyxer-svg.svg Second image: convoluted path.
figure docs/elyxer.svg Third image: from another directory.
figure mini-elyxer.jpg Fourth image: from a JPEG file.
figure square.png Fifth image: from a PNG file.
elyxer-1.2.5/test/copyimages/square.png0000644000175000017500000000025512074107030017456 0ustar chennochennoPNG  IHDRJ"sRGB pHYs  tIME +}D tEXtCommentCreated with GIMPWIDATcc`$\ ]IENDB`elyxer-1.2.5/test/bibtex.lyx0000644000175000017500000000761512074107030015332 0ustar chennochenno#LyX 1.6.7 created this file. For more info see http://www.lyx.org/ \lyxformat 345 \begin_document \begin_header \textclass article \begin_preamble % eLyXer -- convert LyX source files to HTML output. % % Copyright (C) 2009-2010 Alex Fernández % % This program is free software: 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 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 % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . \end_preamble \use_default_options false \language english \inputencoding auto \font_roman default \font_sans default \font_typewriter default \font_default_family default \font_sc false \font_osf false \font_sf_scale 100 \font_tt_scale 100 \graphics default \paperfontsize default \spacing single \use_hyperref false \papersize default \use_geometry false \use_amsmath 1 \use_esint 1 \cite_engine basic \use_bibtopic false \paperorientation portrait \secnumdepth 3 \tocdepth 3 \paragraph_separation skip \defskip medskip \quotes_language english \papercolumns 1 \papersides 1 \paperpagestyle default \tracking_changes false \output_changes false \author "" \author "" \end_header \begin_body \begin_layout Title BibTeX Test \end_layout \begin_layout Standard \begin_inset CommandInset toc LatexCommand tableofcontents \end_inset \end_layout \begin_layout Section Ethel the Frog \end_layout \begin_layout Standard Some random text. With a random reference \begin_inset CommandInset citation LatexCommand cite key "randomref" \end_inset . \end_layout \begin_layout Section The Other Other Operation \end_layout \begin_layout Standard And a book to prove that we have read one (untrue): \begin_inset CommandInset citation LatexCommand cite key "pythonesque:1971" \end_inset . \end_layout \begin_layout Section Spiny Norman \end_layout \begin_layout Standard We are going to need a reference here \begin_inset CommandInset citation LatexCommand cite key "reduced" \end_inset . \end_layout \begin_layout Section In the Grillomat \end_layout \begin_layout Standard There are two kinds of vancouver references: with volume information \begin_inset CommandInset citation LatexCommand cite key "withvolume" \end_inset and without \begin_inset CommandInset citation LatexCommand cite key "withoutvolume" \end_inset . \end_layout \begin_layout Section Alpha, Mr Belpit \end_layout \begin_layout Standard Two references in one: \begin_inset CommandInset citation LatexCommand cite key "alphabasic,alphavolume" \end_inset . Also, a repeated reference \begin_inset CommandInset citation LatexCommand cite key "alphabasic" \end_inset . \end_layout \begin_layout Standard \begin_inset CommandInset bibtex LatexCommand bibtex bibfiles "bibtex-plain" options "bibtotoc,plain" \end_inset \end_layout \begin_layout Standard \begin_inset CommandInset bibtex LatexCommand bibtex bibfiles "bibtex-vancouver" options "vancouver" \end_inset \end_layout \begin_layout Standard \begin_inset CommandInset bibtex LatexCommand bibtex bibfiles "bibtex-alpha" options "alpha" \end_inset \end_layout \begin_layout Standard \begin_inset CommandInset bibtex LatexCommand bibtex btprint "btPrintAll" bibfiles "bibtex-latin1" options "alpha" \end_inset \end_layout \begin_layout Standard \begin_inset Note Comment status open \begin_layout Plain Layout \begin_inset CommandInset bibtex LatexCommand bibtex btprint "btPrintAll" bibfiles "bibtex-latin1" options "bibtotoc,alpha" \end_inset \end_layout \end_inset \end_layout \end_body \end_document elyxer-1.2.5/test/toc-article-good.html0000644000175000017500000000625012074107030017333 0ustar chennochenno Article TOC Test

Article TOC Test

Part I. Our Definition

1 The definition

A TOC is a Table Of Contents.

2 But I Already Knew That

You were lucky.

I Want My Money Back

There you have your 0€ back.

Completely Unfair Dude

Hey, I didn’t call you here.
A Paragraph For You
Totally uncalled for.

Unordered Section

Just to show that it works.
And now a list.
  1. First item.
  2. We will embed an ordered subsection here just to fake it.

    There We Go

  3. See if it’s in your TOC.
But There Is More
And nothing else.

A Appendix

An appendix here, an appendix there.
elyxer-1.2.5/test/languages.lyx0000644000175000017500000000255312074107030016017 0ustar chennochenno#LyX 2.0 created this file. For more info see http://www.lyx.org/ \lyxformat 413 \begin_document \begin_header \textclass article \use_default_options true \maintain_unincluded_children false \language russian \language_package default \inputencoding auto \fontencoding global \font_roman default \font_sans default \font_typewriter default \font_default_family default \use_non_tex_fonts false \font_sc false \font_osf false \font_sf_scale 100 \font_tt_scale 100 \graphics default \default_output_format default \output_sync 0 \bibtex_command default \index_command default \paperfontsize default \spacing single \use_hyperref false \papersize default \use_geometry false \use_amsmath 1 \use_esint 1 \use_mhchem 1 \use_mathdots 1 \cite_engine basic \use_bibtopic false \use_indices false \paperorientation portrait \suppress_date false \use_refstyle 1 \index Index \shortcut idx \color #008000 \end_index \secnumdepth 3 \tocdepth 3 \paragraph_separation indent \paragraph_indentation default \quotes_language english \papercolumns 1 \papersides 1 \paperpagestyle default \tracking_changes false \output_changes false \html_math_output 0 \html_css_as_file 0 \html_be_strict false \end_header \begin_body \begin_layout Standard \lang english This is some English text. \end_layout \begin_layout Standard \lang spanish Esto es texto en español. \end_layout \end_body \end_document elyxer-1.2.5/test/laurindas-anger.svg0000644000175000017500000002425412074107030017112 0ustar chennochenno image/svg+xml elyxer-1.2.5/test/random.png0000644000175000017500000003663112074107030015305 0ustar chennochennoPNG  IHDRXsRGBbKGD pHYs  tIME Z tEXtCommentCreated with GIMPW IDATxit\y&]kZX WɒEQʔ(oJd9m'۝X 褝LOM&=sN'g܎s>Jm2{ӉٖmŶIlDIP$A;[n;?. E =N*,Sϻ>/ZjZjZjZjZjK(oh& []/ սnQzR$s4h@+ T&n3eK np-5 M aJzڜ5 -snN8Xz %Y F*T";pTZ^ 1@G)u2Xk^۬ Lm9_SnT/p0ҏpO궦1rFAe.fڵ"ucu߬\䪳8/\DlĩvoSqKcoܪb $X!i2zi(8aS;| U&A3Uk~N(*@,Y[Xuإ` S `$eԮ&#^ *u; `V@rtW˪hq---ϬY}}}* |/鱥|PV |DoՒjD;[(իW7o6lY敎ﶴtر#i&M8"*0'ٳgE\0K]Do!ocD NވT YՅN!񶶶w}www[olggpa$_QMD]+˲n?tп:q]'Sή]tLҲXܩPJ3MB03aܬ$mw=}B<Μ9("ضͮbvv֐R644r"W > СCබ6ID@!3Rdc#R.T;Nq1,ƪUfNo?EgϞ5 aYΝ;m۶y'K/x122SN< tTbPAss/ኡk!$3r.4q[m۶C;o> b߾}um  nՇ?{キ><?~|R0sIJϾ3;@H)g0曫+)Rعs3dΝ;'8 @R;Vb/[c#.ƶmׯ6nnz^B0r뭷fEk׮^,\͛aÆGWJ}ruwwGl"Dto~irXx 3/"'W111!8>}mn\fMeY:X h}aVZn]L)ˡDԶgs%1H .ȑ#Ą "y {|Rо>@,+aƫj:tHAmooos]WϠ7wNLLd(Ҍ4aɓT.E* xy#VZK 7=zT4`-Dt;+ IfL `ut=Le׭[իWöm a(izzB-[p?w5\CahKw0stJBApa0M988hiW+e%T~A f4>}:xܹstQT;vVHmbDΝ;W55 "aȆa@j`l6Ka8%kA<GRYI4#"* !fAkk+_{;v)":u^xJ""23D\I^)uSh4wXy":*eYب_ flRnV/`_ӟt+J̜B644SSSZD$0 ttt{3K"zMDOܹRVK&''_:::&LthoowvYnhhpY:UL S\Y4=\O>WW}˲lذNOOx嗭U>u,FD"PJi !JB=o?3N׿e˫4Q?b_'nf0 Qȑ#'T*AN(4h泍8L\8$ubm@?洮pԀr?OvQ/CD- "ٿ<=M煈Ϫv6VQ33oC/^"af$a.RJ)N:bX\'Q0 OLL[n劀#e`6O{w3/DQf_ѷ{]3A㈵!zke| `ku q8p<~8yG p$,};ălWyW*K:q0$U_P~ߎ;`}˲V !EQt`ݮ(~^Yˈzj | {1ZADz.eaaZN>ͪKVԏ$c+}PV5>8G߼87oߏ<-Ϫ*<0'SnD,Fw ` 3Oѝ UcIFiFWWoڴiuĵnV!,}*+Pw{9waxcϞ=B{zĭ3ӯ>í333 xu,D@mT*6 07vppeDk>JDۘy0mBrjCCi4}0rQ^a,b5!N!bz`Hă=>V;/Į"RV(R@RAЩ!)PbnS@6xGⱡ+n%(}?00 eV5WJJle>lh#iZ13 rn:P(TSNR ^bQ%4n`N:(ǩ{B<}WZU>qD#"r`5Ѭ^O,ޠۥ@REI)) Caff#]R))咚Y "/R10` %:_/̇>":8NKcc::ipVLRPq#+%T2&BDX+tWCQ1(p}T*eT*A 8y-˂amjժ###K.\:7.亀똂ҏI8|eY|*4}޽{] hX׌]vr·1@n۶-lDtil%.Dd%c6kԱ48&XX * fJrɓK.$\w׹8|p.իDE7>Cs=B{ʺ'B?L<p3;U\(6 %(`-뙹\ҁylR"T*J%eJl&[Uma/? oߎ hwp]QO^X%Au166x~A6P&q!^Fui@$A~VDQRvX#\TnrgbJdNR,:e8FҥEXDRAk;sܶퟙCj؏ڀRrznR\y"P}7vwwGB哛u_9 {RQ "jRnRުbk;X,6lܸѳmLzViy(*CrYTUDQĪPȎmۓX6 ֳjgggivvX`&;Sd2/۶|7k;wհp1H@Bu!#u2s0 Sğ9lD\8 /7!n|t{ll DЀÇscc#DН?ʝb)%/*RRE !tJ{q'뺏?W_*r! 8p_  '"p \7#nE/㛉&3&"+L혘@RիWCQBnTRrTV\.ZZ]CYs8?1M;>}m^ض}Ur~+ I<:un-7=2^Y,П߅UpNDۙv* j-j* hjj8FMT*)Uv azzq8Cm߶F/O}ݬ@YM߾Kv)Pdx 3;DqdM8B̙3EuvvPhPWy* {GA$k#me]}uY}uwvvJ=r'dX3]ץS$\DJo Ar=3oR㯂QBpOOMLL`zzz{{q蘭 y[ CPkxpgeYq]w{ _|鹪 n(R 6_P|#jeO2~һBDtwyP]( ( mWc((;UVA 8H8αL&eY?,)u=B ݖ@PBnſM&l^ъ"%} ⾩vf6ra ((>c-n^$͚/6 07Ƨ =v чlWSIl\.GDDRJjRIJ%X,rLip0 2MSf٩|>(fdfG֬YS?0s-^C[3:).py+RFf9eYHfsAJӢZ_( *! Èǩ{: ;iqq 1rd F:0[UXZvnc5jUi!* y$pd2/۶۶lY!۶ H]vEj ^ߌ"z b[Rj`7 ߟͯ繧G2^@QT*Z.뺳 Gs>jYLeY__b!Xɶ\EkDӔK>`vvvvJ}FNT1E-8R0DcccExzzR a&sCf~ywwttL~_  :Xz@ԘB#|>;33ĉ| Ӭ ) Z* DtE#/ʛ6m ]m",N03U*.J{+3oxxxXS)\كwJz Zb۶ƍ|> ,eY-)% 7B/׬YZՐpxU| LDOaX)@ @^@|^ 6H4kkkڥҩ[5RľWADa?A)@~ÄE!h1(ˡGf2BRJ<"W*H4#Rg(e oʪO'^,I0B0P(v""+FT*ZR)%:<&|!nI#ț:SCJǣE?KR1@LFtwws.3Mv}g|O" yfMWYE)>MH!:;;ŦiW*eA"H~>f~E'!R*ȯOwnfͷ:ʼn'@eV 7o,D=(b 0 tܡ%"z$ia-6sⶓ*=",Ӑ8N<[YvmAaj})%yG*0 .{ G  o*{F%G\իgU BAdBIz+$퉢DtF"Gb*&ѦMgsL ڰi&}]IiIJj =VetV jxIP)@ުC[ƜP{T;f6l& T ]iWZ1V /8ߓR>S*[pHvhpl(uR\5}vzf1ODBerrtSvR?OIH){\z|!O-ALn߾V L5dl:s{~|;}c0 nB{w\.,raBNf0j1rXI#eal߾fv"j0?:<<, '";֭lbR-wMOO_~ߗf__٢~(>H:+ 5`D[̼ѓE '\!@eKK ݻ+?ŗ^zC=4qƳΙ.>*o?xEb,"\} D7J_ E7DTp3:cXa " \.,'(:}ZȓRx|||@̙3W< E4Ogm̖\D6K(ir&RwhOCskjpCY\}۶eUƉe˲öf+k׮Θ(˹ Ð*z!BWk7{Z v뙹ϵ'%u3;' (uҌMDBq]т>H>d#}2L;dbڋ'qzRJ\-)V}pkWl8%0>TFJ$y<ƫj.Y$D"\E֭[SpY)^fv;;zmY¯IfIS}H=p% .3'?ZtkTsq~x”p(_.!&z#ao~)LdcSa>\ ћ=,PM23 `0˲O|)LVp'U+yhs \.%N]BLA:3#**Jw3,A\ C?WA14@M}M"HzS\D";|Qz@Ѕ 7qPn,˂iRa'0U%@ i&K(4I0%]. 0A*ذm L "TLl=6\j-o$]ZMq2=)\+bfqO,^9LyKt΋GtIEKw !)@.E[GkuKH_JfjO48c՟ 4!(8{.ea\0X@_ &Q+V[ɦEҥ&,˪#4R, "%."3O19 ֤3S֒t0 R0 A|fVKqL@Gԏ꾫>D]`n:a" ژ8r)Z\.֯f2"I*񆈙TѲA<{y٭djٲ,誺i@&8Hμoq5'OwFb*XQE~}uCu! by-)*U/%Z9IR6.dtoQ"ξ}&#X"CCCQPQ CUA#Y5W6?J7b%jBfp]WHAl"M-P $ó۷ox*x<}-xLD:(.""NDUld E, qT՚']& b5i D%3dBQ Q^0szN6fvX\d;l6 4k?;3ua3 $nW{*`\J >#VB3g-~;gcY\.۶ \SOj)@(XlLUnSJ---]%"*VCQԖ1 چ瞓bBqnf{U'A*jbY }ʈGj>9$dTU 2I-Ȳ4@%ѝ{"6R,Ocf]iȋDbW.Ȋ0"#Pf@~`` x)@ "cN_^zn*0ʊ)@%0Vĭ,1HRT1ҟ*+Y~8pbޔyFbhj)@5XCD 8ͪ"^3R+ȲtM֪;SqBUijO]%liWs5jEBRQB(`s̼~lj2Ȳ6f6TѨODQ/(޽;uR,kXC'^" ]vɁԽJ- (FuRRE0 _UIS, =yRsjϝ;'OÇ3###"&kgZ[[L&#Md0jq/kKJVXXbnC*pGzd%] -JHr6\ zK76.r7R^BO )YFw 8-Q3K+[뙐ּ%W,kr͞Q1Lj),7b$.v%A?2Yf!d ؃7 PMRKf='|bF$x'X^Ԗ@nui\=s.1~mG܋ʼnUeMv t!wTTmֹS V6u.q1yҤ)@U8Iz5&\Y[=g#^v &ϣN> WI !N0PLfĩV͈\@/RK,GܐXTr`bRxqoەUұ "cN:sH!^sJ,=%YvƊƕßč7+@?<xQI Yjry䀊IC8nS\o׋W*v-(f!lu`E**⍽ +ֽl-$]b\R6IENDB`elyxer-1.2.5/test/compressed-good.html0000644000175000017500000000213012074107030017262 0ustar chennochenno Compressed Test

Compressed Test

A simple test of a compressed document.

Part I. The Main Part

Nothing else here.

Index

elyxer-1.2.5/test/lists-1-6-good.html0000644000175000017500000000677012074107030016573 0ustar chennochenno List Test

List Test

This document was created with LyX 1.6.2rc2, a great text editor. It is used to test lists, descriptions and item lists.

1 List and Description

Utenim ad minim veniam, quis nostrud exercitation
ullamcolaboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est
laborum.
Duis aute irure dolor in reprehenderit in
voluptate velit esse cillum dolore eu fugiat nulla pariatur.

2 Itemize and Enumerate

  1. First enumerated,
  2. second enumerated.
  • First itemized,
  • second itemized.

3 Lists with Levels

First a simple nested list.
  • Level one:
    • level two first item,
    • level two second item.
Now a more complex example.
  • First in first level:
    • first in second level,
    • second in second level,
  • second in first level:
    • now third on second level:
      • third level 1,
      • third level 2.
  • back to third in first level.
  1. Now 1st in 1st level:
    1. 1st on 2nd level:
      1. 1st on 3rd level!
      2. 2nd on 3rd level.
      • And now mixing 3rd level itemized,
      • and another.
    2. back to 2nd on 2nd street, sorry, level,
  2. and back to 1st level:
    Now with some non-list text.
    1. And an ordered list.
      Just the nested text.
      Repeated twice.
    2. Second element in the ordered list.
    • For a still more difficult number: unordered now.

    3.1 And now a new subsection.

  3. 3rd on 1st level.
elyxer-1.2.5/test/square.jpg0000644000175000017500000000061112074107030015306 0ustar chennochennoJFIFCreated with GIMPC       C "!12AQa ?}w뺼eeN)v_5bEcoKKD[&+ T,q%␯Ե\W9U)FSV2cnxelyxer-1.2.5/test/version2.0-good.html0000644000175000017500000000213312074107030017026 0ustar chennochenno Version 2.0 Test

Version 2.0 Test

Some random document for preliminary 2.0 tests.
Savannah bug 33961: Apparently super and subscript fails.
elyxer-1.2.5/test/elyxer-svg.png0000644000175000017500000010234712074107030016130 0ustar chennochennoPNG  IHDR_nbKGD X pHYsdd vpAgIDATx}w|iջdɽWt 5!$@H $! ͗PrC rS$Z l{%]q|Z gvfvvy9(Gr!q>r!ӅC9!-rC9[0r`90n#ra"G9øEs!qC}nv۷ottttttJRT… .\̜9s̙sᣍ~@x<x^{5oxcqM7X,xӦM6m_׿50}ӧ!b{o xgy Rp8l6f qؿBP(<3>8]N%X,:uԩSzAhrFٶT*J,^xOӟ{rÍ,}w}z5׈jZV B“W6&D|^>>[nݺu89C:rNQz^೟g?Y3f̘1Cl+Zbz„ &Lo߾}M0\`׾}k^X#ɖ͛7o<`֭[n=ݣCnpPYYYYYyG3> // @@"qF0N,8Q"ljjjjj:묳:ԟo9|#8|ÇE-3-8dIr'[5838Cw99hxㆍ6nn馛nr(#GGqA%fk׮]_$r =p8,Rm."JٳgϞ ̝;wܹms#q ̕ :eZ[[[[[E5믿?ݣCM{ pǎ;vH_/wp`0 ?NG^{}rxqD=BDI:Xexȗ9p,{99|Ks=sb3qx,ǀD2LAV@JR Dqat9ʋ0N5M ywySH$' )gKޠjI!O[t\. CP8}{6dlgȮ]v\r%\r n&nx'H|#W >H>^]۲USؽ{ݻ}s瀫ꪫ:ݣs7s4b2K:N$Ï;-r?9kNh}+_W\p\pV=CP0Ę%x<uH$8tFC ņXAWJljh :@5B<O8_AorDqŸ%@Νc$w$Dwwq{87Fc]+sk7F{--@0lLħFv`}60uqK$@ɖ?ªHėL9o B^/eL9L$B!Z~gNdr8> @3NMa8Csx``OwOwOg$"z[oN;ZZzz\.Z ==N{tp:=@Fcx"8F^Q6ɨ7v֖0aByy~>-mqca?Hr<"})/ 1/2T5fIY%H(X%>(~O\O||>ut w77w> KK+\n7f3{`Lz=i4)P4 `$8mOTV \yg6L~Lt==OvZ( H&c1"HzA{&@h j]PzBҳ8xqK 87567 bx" X,FN,Z4uje%0yrUUa!`Lǚ ? vdb_yE8)AP(J">RZ P(J$7onoVZaȑ~sp^PRRTK~]p՗_>e PPp~7FjTlEcјD>QYOvRbjG"776+WnDxW+_.ILZVI9[irU;zW;Z46 'Vضs"($ .; -) I.ٞ@cAUؒ?4ЬJ%/ZK rV՚@QQQ"~. kp2}D?ڵ֭;vtwC]qt"h(Iq̀Vk4׋9hb`65K/KEaґĵk| o܉ʀYKK`J2+٬k4@UJ%I0iD2IR<hFDbd2-Blk˾JR߫V[{7v`-+w Mm#=Շw:?=UW ɚ YNsDS?Z +*****F}-[}ZZfϮΊ8Rl7Xĉ'N*2l`<d a[`-0 9뮻ɌFcx}q @_Sgח ee!p۳\7L ,P"cbDUWs@_/ ^lTj5:0w~|艏1n .ᅣQvrªU{V\ӫ,,<'%>(G?oF<jl z!.nǭ.]|~`Ŋ+{/뮛>">}iʄ\t(&l b1zaA`fc'_G^O5F r*L:G'd2k׬YBbŋ/ 5W׿h<<ˆqK555555믽k/7ܱhX` ʉU JKm6,G(lB*4^N8>Ea7&eBPXeg"KPr 1z p:~߸Esc悂+>. Ri4aFfh4juxp  7pu3fU4X7FgR-;%%:ߏ 0޳g&薽 ^@ uPzQ]Uէ?կĉf*@کD'MM>D4_׬ M;= p$֖-U^-ȆrcȾcǮ]==d|Km%?yoV{ϣu T$a={zz)/z j.ۏYFlϦΙ3sfi)pyg]SYnX/jjk'LN22f/NG7H"Àӹe˻JtD.W_?V[,v;`6N8 bdkVrDˣ\nO3355TWrz0ɽ,y71A2fS}am:;r/TjupIf̸jihZ|$ |>_4JI+**(3;omBQPd JRT|xmׯXZl08aoX Z^PM'Es䕀^_RRUED' +ަ={#Gx}3f~jq4q'9̂-[P(;Z O8;4D<HdF__kDKx1*c,O-3W"ql4L|`EnXwyɫd/~fL&`Ui2Z`ܹ_sʹiuz2e9sn%R5{WI{er"^$x4tBu5%<6/PbyrT׮_xǀ/&`ڴ|#,Xz玖fS/[;?)N {kى!kabx9aq}^Ri zEŋ}}vZr\ٳYawtwG痉ٖ7})EE…WT+%l{͙S_L#~PU^~?js} ݗZ":m9sPM&EJpx}嗁w |O~~~&Ӌ7< }rc{IE",`0Ղ &y72y 4Kx|!ό+,r4|'m):o8nߗCbK/zdE""9[l;kP^p$J(ɃHھ]BtGmt>_Kˁ"b4y@/.N OmA&˟xڱcZ`˯XUNr(Ljlۓ8$E}rfiVUYcdKL\͈` DPUzad+Yg{WB޻>,ӱl#IRFE#;sY()"8УuFQoAo'R6n|MRY/׭{5 xϱd<hf]pF|8 ѱtق`¿ujbih9Sz2G% <ާ:(GG ue(*cKL@$r,Ejm6%#o|@XvÆtK~\_~2V/o6LNT__P^Eh2F"n|@w7 qΝPRl6W]OWy]x]۷*pHsݔ!~ 孒Iz1BE.)).XrI 's޼y^]N#"A```ݺ_WZ pnL)_p0$N2L&`(-$G}X\}}D|3:ٿ͋o*QZ*prǣ(?(c(vhj/;=&B7V:XR \哟Iʷ3oXq^:q\$HZNG=7(WoojsfΤ:]&fϟ:8%KN9碋(~1s:ɶ:8Hb8,RJdOq(0x,lv՘A {z$UJHuڱc: D"lS*5RY&wTE0u+O>  &ΙL@4j4g\6⓯#8xu0zx$⳥Y,6ĉ@__ooKKLFJZ{@?DJ"dpe/5])"_ VQU*P,>uۺW:/v8"rL-`ʔ"/o tz@omfssڵԸna3#͊%GXΝQ٪+|*+{!I[JdcN71=67wu9@⨱ >0P\&`0kkº:1vM;8 }tÆ'뮻ʩSPRGA_TE[{;vVfR`WXZ,WTdL@^y9>%HQ,ٹCCTvlLuȑ@xJ}|A&zTU}<]q7ڇ] t:E 3OZZIih:֖꫁l4~:lG͛Q|3^;}:pphLR\"Pb)Jںy3wȆ ںe &n"-[xܽGKZģUHz0 ,Ued߿mp={„f}T`Ҥ)Svؾ}ӦnԔ~ .¡u6ShTd2si%%?yf'L+*Uh#GF'AeZMha`vv (_HP 9(|?otf{'Ϝ}NMg>̚UZdɇ_ ;:$F{z3\X'Ϛum@OOwwK =5:75ҋ.jhniq(JS=? @'L&2Uj,8o}Kx&'PsswuIu. ?ȑ  Ob1)14xi!m `XZ֮4iR ~ ꫧwsΩpALώw㜹?1xqmן{48^ cpyٵkE;˓e5{zm_>{vx7F4 uu+Wگ~4665h~rP^^V\~UW}{O}kywݻWBA}m={eFhmݴTw<>wu.׶mk*̙W\h4_ԑZ(bH6p8`0dظnᦦXlz=LՁV/XCK|o[7( ÆqKk*;&M,(s'OِHbCC޽۷o$Jԏ:U9Ef;㌯|j L҆ ZظaPP@ѱe VӎÏ7MM}mFCJ%Gňh2i4dHIBlm=r$6n\k$@@]7PEQFwr 0"*c@8|HlRS Js$(Tc*BA6چ8xpa  (>@a2Io=ZOjz n _N⊥K*=>+(u*x]v٢E RWT9eݺ={ہUvlkBg/ r`T'*ahtwG"@oogg4J )V#"J}K];٬坂lwt(J%WTZsz.gO~̸!p8 ;iR)6*Ѩ̚E&a'\3mR #‹/Ry"A6,ʢqpR TW:$Q*EؔFѐhT"dp8"Jٽ.$SUuPX%'BqJ/BJ>kyT!Kz>kp0YBd8q2Gb1}I T )jMU~M&p/~v-,X|S~'9Bx{/֯߿or`۶ë=J= Jnj/ >}˴bm<( >cQ ۠ /F#"X 0&&I (DT 72`  Ӧ>0sf~>`it [>rٳu+wt $S\v ^r  â$>VJTRQx Wju:l|j5*P\\Zj0-/z{~'7o‚`PJ|,*"t:ry"Et[UU0sfYم<'G^w;;Kׯ`۟SdTV>JT&"e.tf~^O·onu}>RiB"~h4 //?_%O Iq9Z-NfJEq( `ggPTBmoomP0Iz1JˮJGU>E3"RaƬrQ6$ZhT!Z6*Idɮ7&O6nEEڿxزeffh)L&c1tn'U2.W_/I%.䱪S(P[A 55uuf30{y0s9yy驆,:4 v  B()``NP(ZjԪ 74Og9dopz W__0HHfQ*ɓb0 j5e )DR' j4B!z}RT0 E۾{vn3ibMCKO r+|n`׮ěBQ(x\F?Y 5p8 o>ݣz^x lFXLp:Is損#Fi11j+@Q%PIecf'AGGk/kϞ;)LǁŽlljȬ`#$*VD@8];+Wٹ! ?&BCL!" '@wwGG O*<;gXu# ,)-ٵkhT~[LLulZ-5~>^=kOKLH^CGuum<ҥ_DiHdω!H x, ~xnj_yDyG?NTUVĘ'N*{9ۉ8.m`v SQ B}0^dVFYfU!4I@t|1ft>J%_X$b$h&2"BoIYU%ekkK xd\^b֮]b 'On]ORʜ h}{$AS*ǶZ-ۻ曁 .hhE18M5͛z Wz/ єnFLMW%BRX鮻A1_oϼ 2g9A^?}{_g>N2PPihx|۶F/ ӠP'GIIi()"77{-7 o8_Z|=5xgd(ϴ_cyQ R8GDDŽ( ,9J0F/ -J3E]۶ TT?ϦOn_N-[6n<\Q*M&^n@'O;ڵ-_<ҥwTT8& Ru  2zaT#FBQ[ 8&ӝwm8Ip#m|9?TPhӦ/Y:Qj[,ƶ> .rZT@AAq^O*\2 dZVL74$Dj5BP@XrD^bjMl:y8}=tCN*ቜ`,KmBeN  1 /?"(/2EBDz=6 vSbfY;J'4~dR>|U5?[3i#M| ׿z۾ TTLzhӛZ2PXRTR̤*2b0k$PVr=_رM9i\Z{@2cbHm}4 %1zn*6@ l~Z-ep@磔.A|DtVB^[*P* I62%A":@A U|:y>؋G,AJeDT;R^^Yi0&"fhŠ{zC!੧x. `ƌ3v5(i<ġF"ΝnYg6^_Twliۿ{/} | /x ^OKӛ"}{熆~ʭ[FOp 7l>qr0sfU~W'+TORgSU3}_;+X*<>X2E! @jٴZ``/NA Ϫ4KDR"H$,WGIU%! RYF2I*'-(µIR '(*HU9ABVKN^f 8CG"dZhQZm;TxUJJJJt:!ɳ`pX=}` ??H4 SUV-\HFOzAC/WqJJ %Kv]:q2&5=Aw:OJ8p#'H9ƫ$g4vwl9BەJ 3v Y5|]  T;v]G6)RyS%d}t@߁~ʰ`FkJ԰La)T[tD*1r聁P$&"t"@n)$S&{dD+g"Z8KR%@2 QJ|&HZ"@ ǁPHHbaɯ;yOvZ$PPP\l0nEȚ9]]_>e׿/[v]"s$/m66;zJR&qn|+5J,LJu޽$9&hTyWZ5DPGT#;E|| .4?8`45YPA\6@s:[ZK.O T$N?-%>NPFi dcbgYH$u MXlLP, TD`*%^)%@X"#M.踉K"PNlMgN!$g65<Թ"^d԰FF =D+O06[^HIЉݻd@ƙ0N9]o߲ebɨ*,4)=YqzcDP=P*H9~(UrB*FC.KD\ɤqih &^1NǍPJJVoqϋֶm`4mJ 46D BdvldfG}3\ Ι^̦ `@`-Gְ75?2*hLiiyHHWI"epdmfŢVSj pLț6_tjuuT@mCCN'[K}xCDJll߿wߒ-[S>;v{G:$9KIy95xD%~PZJ, vMy  U?XBiDp?M ~` Q'87yR@IɊ5Ւ$w?p DJK'Oa;:LIUؤ!5IH/B;dKg@dnxTOPJ[(D&K<$Ad:/a; S|9U(JޟcmTsu{ PmڨڂA47*S٤!@b8X2: hnܺ4૯n닊J"zb(RJlTeW*dYY$Iңb0h BtV+ U|}]JUPl|,!21TJWTeAe $T.i`7D#g NR؊<:' OF5zhȟI2a0t;)R!NdddI ==ԎHH,ѵ81 ZFTTTWSYf*T_:;NXm>s>F/6;s {9QJeEi?>_El:sv Iy$}{AZVFD@Smy=*5m4(YU8B3DRdB!U~L{eRY"[H2I&@MGBa6j5Zttju^lStHZN @ns{~qr}1IQ6KK:;'M8_B~L0p^oX\Z({R?D8|!c$ IhҔiDj4 \bJ|lz'*K V*bNh繐j4JĞ)%dN6iJpߧ`;JR<^T*-XHE"4j%G^U<^T(L6L7?  Kw0r'?TN ."k(Dc̉L<*Hq r! JI׋WS y4AGKŒ+4%D5ĒIH_\.RWG,r> ddxhQTeh4_I It_89%'4X hnnj2щ%k}h ܩϓVKϪ5+k!YJPL$V9rxd5b` l3o߫>tSXC8sܹ4řc0h&'M*i&',J@ydp륪!΋E7GVeF"HB@(DK ;bT y(\QRIi?4e ӕRXI(TE%B(T%l\D}K:/pRɃT49#K-ORN|&B^τGi=%gyy: ($6*P3q$|f/1{;x<ce4z{C!a ;-_tnNDǑ~,DVS}EzstY#5e8`0M jmo~3mM4DE,Qqݥf|H#$=yGj"P(lOW5<`RNnl`c{ 'vԼSx< %FJ:* 9^-U*T9U*)5,sNUǤIV<1Ye@/%TL 8N0UU6""? b!I$+&>}rqv>n7IB"'$@~ޥrgiJ=?,#uNI`.h8(HBVL$nڲe?iij{A{* όVj3yDTa'"Y:X.GMڀj 91Q*8ZRAu:D(xVXLxh(Cի)BΓbjK( 񥄗}:eȽ,tDC#cI/l7,ҁD|Lrp _BN2A\4rUZlHU'aM7D\c(G/t0Z-9J+V<T?ko߼()۫iY$~ vǶL<Z#].%OkKi,FUV6iWRR^NKxs3RD~Ng2Q|"DJB^lė:AK|3R,R9P<]-Z2/oɍ bI&+v6-$@&}SCn4 FC2#9];S#֥*/{}Z2c-t:K*-2SJJHjiz.ZF#ߧRYPOkΛF7oӟ/{H/*yp]6 &KANxY,qcd#OSHǪn(DҺR MRﱔ4ӥ-1&]!ᴍ 382|}+)O/֠OH#pB`0śTzLCdBFB: VVr[ʽ{ ?*1Rl0)ҿ=SA94*>qƍ}G5i<ѨVϞ-p< /] ;2?F6}Pz< FKτ;zER9Fcc=WYᣉ@^ ەXiJ RQAuV$B^hqwma%2wX,)DJ-*H"Vyt:A:-Y ?$kbω`2鴣ߝFX(HA_*Rĉ{g~\, UEvVYF`XbɖpPА-ˏ̽ h,*@HRe44l@cYgu$NR%%FwK8ҥhqUe;bة {z߱Ty]rY~hVBD"ҏT@5ZKK?a2i4v `x8^x"7h!̈́ɬ*Ht A^ c|(%%[JE>EeE?6-z2`P#jJ-m h?};,'p(セ1ADJ$wcv`'zƩkEE9rQDRE!+`dqHX2eܦ'Ɨzq:Z-OZہ P6FdpE9M%H~@r=xkkI=NXHRtLldbjkt"XHt:=㱥UV⋀^WRRU iZNq(䁜)_X,`0PCFla6F٬5?cÇNNWT 8Dª7K^MqVU z<ҥZM9UUz=Ida*1:W`vq3K_8L,Yd[ @6Czf!L&S(D}*>'tY>__KS>pz}Qi #r"}uqhI$@Yu OMj6fA=#Դ2hB )3`t:b2YkV T`#'.u?vu:*uri~x8liiy ȑ;j?ni`@jj|>"&GU(Dd~ImP<+_>C*!& S(rr'L0hVj)m%T Xk# e`B$Y !¯JDx\Η$H&nBJKȴnk'ʺq#EV*IEDZ"nN;#o-*|Yu-553g<`AAUUmmm]v" |iJp̜Iq~ TRUbq>?vfsYىd:Dcxbd"DE#ܷ{`u̵׺\j5p?meeݟ[V+TB6S9<*+kjF`'_JEeL&Q .`Pt5yA4e #?ݝPq :T;x< eEu25TEy7:;>>K~逩^\>89^ӈZtS.X(r$d vvw[;.L៩~쟤7$<#ҚF"c~rHU{loip/⭷\py@II~P$ \w(Fs|BhQ9m#[N?%pn6{K^MX(m"AeZ/]fޟwzz#G={:;{$a`"O.V% @&' --@4g? I"|DO&MIJ4Z-`v;0}̙f3@yZ- d [J %pD,f`Lz}SbD 2)7olI뼬(H\B-/O9p}Q,B {Mk/l|G;kFAɳfz= ]xRm(,u Ӓ|, Jņiaȝ&%\nj0z0FJ|ttum~w={zG3oEN!ذa޶6`Φƞn"YU˩w DƍN:=$IPrȶakWGǪU R C]ڨ8|h^{hmA pV@yUUF#I^옪Ȼ54@iiYNTWqW6ljez^r: GU)lDK.tK! #s+WbKZJ or$TVJ3g8טWJ-zfauO&¨fKŵu31[$\t[jŋUr2Mq>paUƍ#ѨѨEcҥT';M,2"Bi@Ԯ4a18ON-Cj H؋ӯAD'I&KyJ|]]pÛ.<|1Ό<sΙ6M,N'rAAa`@$@iIg; С3hޠT*RACzzl )SiO)i0ş\1I0UU*[[Rw72k֜9V+x [JaljPȄjG/Re\6KHxS)%+B);tI$@aaQNG6Pv<^:b^΅PY2TDB I=l{$HV!co/ Xp3Ϥ N5b ++kC^07XRDtL 0 T*Rْ&i~JPg9HW==D4k;'}Wx߳ /GB08448ʕ?P*zDJJK' L^wwv]Kہbry:`DRՏX|(Ǜؾ}ŏ=xxg[,D%I~8MdDK|KcBSSOvZEH6B~BcF3 yq@N _4YF*5m#0WM{ >55f-Xp,h{JIq~vIdhhOnJN4&rg41F l?'vLؾRp* csZ~lLjp`I2z5Zb:FHx)vW(h$˜VӧSRYQ{"%wزԃ'o~SS#4={v ׬q+!:! $h4xU]8%C*u=g8Yt%Vs]7mS،$?燎gSXxH2~:_$^75Ӧ{ɈQ'M9Ng*~?tM 7߃RQEpO# YT:r x3e0Q eeTh2^.{.SJK]8Y@$y<=/'c„S`ɏl\:]& g̡C==\v;U>Ldqj2އBC`0(BBb]IrRK]/]‡"#E& Tdj?Y’K*1WnfIKIӦLvl>0 Q^zEԁO5TR6Gk>;2"yyBq )?!эFi [Z n1+--"p:} P=ɶ>jK,WIFMG7n|s{4A'qϞe˞zh?e@2I u:!4!B!S`8& 0k0ejjtK)*, k!AjuK|I=_x2jt9^hRh%KV˯xMM=*,0+l}m!./! FjbTﱨDɋt DE18HpX*@M 90Y\wnRR2G0.AKjk9UU?80m 7qo]K>%I|PyS&x?UEE',~2Q$EM6s}ܹf3tRh$7{RPas*f1 /y4!ǒW(CF**lGG{{8  PZZZRsAxzYVtd`s!Abbft*FÒ?1p- @f?X0 `ʔ9sK./} 0O@gmu[԰|NǮ]O>@4>bOϞ=[Tn`0$Rl&۞NG̑oյwxa p8j Z-{{)0yǎwZ[Lh:u:n*x6_i)l~ʿ-uwXhʶn| (-\**@.lp`a'ѦV+l6MExs?j2!†(H364f3UTh I˶! FEuk` #I1?JP(:S(W X Y/E=+=d2[cמyX!ipY4z=%ld0)BҜI^JmCM Hi(x}j-uƷDFC //۵cӟ.ՕI3/,-R*>J :;ID0 RRbO'W@2Ҁ]cǕ>1BM/(=^__ooWrĉWW"MD%U-v[N Vat:ZWU @M IDeeZ-e 9Mf .((,s!3Kiy*ytTl6Tde%|`9ϧ;%75F)Ӆ{q_bi sx {zIp)Kn2~憻,'Vqzڀ^OnشiMp]6Evzz]K'T0SG f:2h+us:6:\M/Jp0.6" c^{DeLd0gpDrbd㔼VJY(Jaƌ'._\q1j8t:nMoJJ,ڹsF cR'h@JEejJr D:A* )`D}9RbsS0`kJ7 dv«Jٹi;;wֲeb'W=\YcDTTSL⥑>nL5Rl媶j˥.0ֶn]Gw!G|3dDό|R*IsFIuum^Db2E"c;,5 iixTqb,) )t @TiqWS3a> [PqI"xSonO?hO1"&LX1kVs}qbD/h9_ⷿ ф}~~7mHu9epb{0v@8gO(vHe0Rɽr/S$U{Es Fܗ^\8*ǁΎzޔ {}}]] F#Kσ|U*N60y8^IՕ:rpR| k׶ڦ:lQ(Hh|o"[}餶՜k)nWH [Z_ճ{En/*ߗfR#![j`gg B􍊊*VGD\܀$3)$BAvSMƷd^+8oRT.'٪&L>s_1󥗞xxeo~s@{vgjN?tH&hh0lF#_[k6Fwi"R5f*tؘ'"3^  xrښɓ.eM]8Z2=eG "LUYq3ŨtZ-RR=.WkkOb˯_Lq#W\t)޾`}@7IsOtbdAA2V Px B9t|&<&'Y^_ R4J{mm]gV%[wo>/nQ '@[*Uy@E>_?XA5Vr2ߚ)S[s'wկ`zu#cHL,ÔN)MfsQ 64XNGHٛ+CdOZomm@oΝl")綱kjjoO=V)#b63?~:qF&N>7<M{hfwW2ifi^bV1K(((*R)CmDBZLzF<'u4'%{_s$$Bg dTP({|~>z{{zb1{)xG̹xɑ}B9T0NrԜ'? |snoӟ+W>? x\Llr3[U&XJ2 47Q̘QXt"ud:ommkh\\V*1r"L?gFVKe,&$T\Rmx6ML blSsG&*#mm@WlGRՍFϿ.70|p5ӧ;@MM^ތ_w+=6̘̙p!l19溧ԌFʵM$HӑK98,lU|J|RA Cx|wP)/Wn/g|S-N;2Zf.{Gᢋ x{vׁ޾tHNt"d)%nQlrhC%m.6HP\. *񉭀TRRY>n:͖=a.R5=9TrTz6eLp[Iv=~UZf+~Lp饟{g./brJGn طoښ'NL̙$2qlv;U:fJTwI)Hj3(:RsYpST^$/59mD?"dqw::(0zma ),|]o|yep,p̩;QfϾjή.@d$gV2mE"=kٜfj)_<D"dA M=l*g3$(*Zq7󟓄*-x<Ν/@0#ȽY" DŽ 4)=Y!!|>_j5OZ\KNQ;&8s'LF*() 8|xRJR(D01Ll{qg{(@To<IS*oOtົ;:q`ݺիC!P(.+_.kL&;9'lc NN8Fc+<46C7 |Nunsj@*{zdL|oD^/PJxߗ~f |0.ߟ{nM  RэghDQvh .30 }j8|]nu&K-^ÿ=3K_~:kɒS~$vK}+wZD׮Ofxx" u:t;L;9 )qR\EػKKqfH z$p=0gT6mk+` s3ޟUUyyӎ2\{p]7LD#UISc'/A᱈G S__(+>}޼3y763̆t[`vJ> hFF_0x@ t|ُmKv9poo/|xBӟ_߱gHd; $mmKEE60y) 0u*j)$9W!2<؎M|ݱx@8 45ZBlֶlf 8Hb[fJe,sM(..- jX BA8NQ\rq;8ߟH(`4Je~~c#־ PR<{p0pS6>H$(+7~/X._Dc%̟E|+?|T⬫;.7y y>nyݞdTFOq_ /]{^N`֎W_}=-[u\@;H&'NI"ˤksȶiJnJ%׃ *6@2pUUW +*IqZhh(('>6`"\ԧիW^F8^[Xs*omYg.Y|hzzdžիہw}^N nl8MFWxׁөD2]]5Œ)IDATOc#47a @(|G%Qֳ^VMޠј̀Ţ9$UVVk}PVf?tn|΁Kի6nܺu۶LG&cUyJJop%?ħ>$r_z閛/صOSJIc%%Βb٠x룏>M+V<r![E٬T{B…3ft7TTqƩq@sHA, @o]7I]6M0e PR2gYgQt_E99!->?d9Ç9!-rC9[0r`90n#ra"G9øEs!qC9!-rC9[0r&dk8%tEXtdate:create2010-01-22T02:44:07+01:00ZrUk%tEXtdate:modify2010-01-22T02:44:07+01:00+/DtEXtsvg:base-urifile:///home/chenno/projects/elyxer/test/elyxer-svg.svgT IENDB`elyxer-1.2.5/test/helloworld-raw-good.html0000644000175000017500000000011312074107030020057 0ustar chennochenno
Hello world
elyxer-1.2.5/test/rabbit-walrus.png0000644000175000017500000003767712074107030016616 0ustar chennochennoPNG  IHDR[,ƽbKGD X pHYsdd vpAg[3=?JIDATxy|]u?sd_n(,Ȧ"8#WqtfQd~7ø⸎ JqԯETvJe,h6MIsM.sy=iܜ6YU0DDDD!M  """ -*DDDZ,T(XQhP!""bBDDDBB  """ -*DDDZ,T(XD}wܝm0t08) zlH~˙ _kh }6QR8 Tj @&9{3rJy^k6@ԎH?DDTXԌ],@_z E+$k/h'…ɔ@ Qp7;R ~ q5Y:U T-q+hͺߓL)""_"NaI(cw_O hQ"'\"w@KfR: y02wgtr0q#Ig"""itnotrt b kxX:IcJ:`mۤTRP >oVt&""4^ !|<ߵF6w7;E ˿Py2$aiNz@iLDDTn -g˰ -Hg #ɶMWt*W{h9F aU6 7MҙXPydptj8/;dmDDD¡q{4V:K5K %nODT};tsFH = DDDB%t3Ԓ޸5_'J8K֎ҙhX+tZ)0ԼisDDDavz x0J:K[2zd rnϟ;/L4otɿjd @ ?Le^p牊ڥ3ЄC} 7{,Dt`X`8(_Բ-P 3K`5;HΕDTi΂n'`؝w6 A}CBUC?zf6p:СbojnG;N: Qcc07{eҙJIa _UWϷzhr_ T?Mj@)ߕ{ Rm5# 3*,@G7SB4cs6F:ZՆUBp]lL4*>jP(.t}YpUܭ@Jg}>71@JgcB4#Q:T /ok_-% #'|=d( X͈[2lKg!sDo~H6Zh$3Ė$ QQ2Ns&3j9`2]!}X EXǟ#^kS5pZ\wtjo }פg PY5]>rHt v|8[Hg~,TBC7 kzs(|R];Smq`|1>ugԲC)12s38j,TzeN Y 1S_/h|]}BrtF/9N: _;WHg^,TB~w#D7Eyh6`mkbΠtB%t92 /PP<U6+*' cOR}XQϐBV8eHg!9M|՝6>eeqvW{گUvB =inrxtB% JgV&`xYՉ s-zP -!lx;NBVCYxc}w@+P8;w R(tqeF21HaY(߹ Kg ?BݸQ: UNSr1`%{(EN#=)45%-@祳{TBZʬt:L8!I%0~PYr/ogIgqW'.}pD:KxP ?_[`cR *Ӹa,t83 7Qr:'!XTؒJg[ B(c2S:KP3M\9bF7 P{$jGppKg *UC[&ےA;tF/ٵPGkptaRuަ& Ty3jE9xYv^zg#n2JձP sF?WTv1,BU9t3(% F3wBёKJg*U~qtg4sC2rIg-ϋXTMjȭ x0J: E"So4 X=.*qyL g@2;[5+lK$aJr?s(ʜ;Q M@ݣIgBY?o;˾o?OsFW8iPW[Ջś@׌ k@nF,Od$\BW86ܭYIx op,3WHgBfp(Vs#Tҁ۷2ө)ܣF:M56N 驔t 6ĥKZ( }2($P^{t ܠt9,Tj6~~ a6x1U'.A ;y !t!!r{FKg! F:_`tZוFKz>(hL:*5+vEH[-!L-6E: JͲ58`,?"/(xt0ND $g4oB/AB.1tR3KgB%rWvIgQZGr0;3= DfϮ[(A ȱz*vt*B] )ƽxJ 3cY/t*eoKg\>~ tj,XDV|ey'P\) D:!Ԭe'$*2 g9F$ NoXtRkH:CxP/ڻ3Ptƾ_:wm;R_ɿOn'%#[!TQf0'%#+%Xğu>OS:tsƤ3@)Ð^,TeO3oP: MPYMM;,DMXT#*T! j:"3sujġ^zYƴ-TaNY6/@}AJma ),Jny PeDTEG]G[&niCBt}=l2/.j{THL8g#EƷaW3QPp jt" m> hdZ Jz!|DeX4-(}0M{u3QeV%jet& *$Em.g=,DՉ )wA d+%,= .P^n0\Zx}ju?2T$wr TQ}s-A家\*z-m9S:QuaBE '3SaGJ"1{} sRH?udrBTXPӧJG('È$oC*P)WJaNJg DՁ ttr2x\:@UEZˀD4*TZ&]6n$檔g%?7D'e"My@nL=;tr(@6qKPK8o1)p샋*ocPxsORaIy9o_ ː[}>1]: Q8WU™.u뀉 xaoz*h-Wd8DtX,Th T1*W{{n[nذaÆ 3JR ;^m$::*4C3TB6;00*yW^y]wu]~駟~D2}*&jWoXdbB3w ?Нwywu}>O|~:J=df8cccc \U6\Г… MWM3# /JM;s]u]`ڵk׮^MQAtM7t _~_\A~iTtpNTJɴ;/THWWWWWԯcǎ;vL'J:r׿g?~~o'~mvm3y ;7.h/qQir 0Wej͛7o޼_}ϟ# = N}ȫnoWя~عsΝ;gqJپj?<((X4#3HP&}%\r%GRS}<0:kW9899/ٳgϞ=GJahƍ7nY*ụ3 3= ER:9->^x^8nnXf͚5ktBN_4Ms&[[eMoyqa9ԆjWvU1>DGMPH*}LW&[5yys56o޼yfs9s . .8} C2>PU0vBlڴiӦMm۶mvڵk0{ٳ6ںڣVm}sBhl}_Fw?+%L 65-]LiWR۶ hײe뮻..&x^믿/}K_QVd2}ZLS:[ Dá"wIW(|O@a.Kz{vr]z饗^zd˗/_|b27x7_/͛(q4{0)أBSz3WRuus@<>+&J^^ ȶ,jl,jɺ@Qmmi]X: Ч)Զ)3VxɿV ^ *~ ·YmL* L |{mI9%/PbBG`,* zߓJ+Pw@:_l`hQ* d+̌^Y3)XQ^MY(< / ;-/H`7*ɴDD<>%H :Om)Y}tdPO֌B'ywr2E "㷉3E I5,Th3?.(rǸ" MܴC:QԹͣU̝hXt DB,?VOJ'!F-X4)tߕ{ ,뤈`BӤQ!.@T,Thts *4MjtVIg r4)[X&z~ww?OʥP ^eIJ`v&y 6_4$SsyQ`b}B]-0?g#_,WR~}}~(ŶОUm._-85ߧz7XM=*R3o0 Nw7'f{DJ@X4 s%o xu^ nWuN NZ3W*w)qwԔDnQRvhY O.u+P^n}9dކ݋+o:۽oFWv,G8uzo(DSBN%44߽r%8[\׺"r6NJX=kwGb> [@N8bhY4܇2?]Zvx3w.ĶsnQ-U9I@vZp/yx w9%{# vI6H%{gZU.{sV^o ^I) n {zʷ'-80үd;njwH(WPjt}T锝:xGRkے7uJ͏8\R0|y+b 5LXK s?صK0g7YC?iF'C=E]oeS9Kg)I{tU: Qm`B7LΥ"{UZr1{ :hh=v|.P9E 4oV ¥SLP=R% sy?nt=5>$m*q ԝ=g/7(6PH  JPZ7?Hjρxɐxa ͸34[MpbBQ gK~OVU( 5yۀ}b*Crg2WPD攷 j Tg *Ew];U Q+pS ur :sO>)`oHDT}T(2?X=ulSɫJ0]xq3s@Oó۳z0zb"bnr|/Xz5ڏ=_Dt(P$W;] D 6b.ɭЌ#(QY3 =2/* {73i8G"%0o>ϗNs(3y%h翸g!ZDD4S,T(RQgkI8x5%@U@aDT;XP OU)֩[բKUF:]:U3*)* 7].ll^!PHq-2uPsUF~PhPPP@)IaSo.Ņ3Z`;DTXP$1k0=/rj.nArz)Y.vOtI jB" a^} da]ҍ};t "f,T(:K:W_eN0Ftk^0Ԧmh&"פS5_FV ݘjdݹaP^svUΑN391Uru}yt "F,Tezi&lSJ:[s(oO0RMDU դ 9 x+sCx!?S+2jT)5*ݘCW9˽A< $v\Z:4|W7:r\I7jBG?6NCDՄ զӼ?+CLQx`鮧}]ҭ:W:U*TEz5A o3ct]ph‹ $u9S={s 9ct{s=5)P,T'I+A]p)^/s1[uv6F^(XPmQ4fFY#f;3.HH?( )֑&,;;LߐKOBs&L.î0nLGDBjggst"/ɺۋK0Vk՛4;-&bB3> @Cө[u;[s\gZ|SJ!jBj>3 Z6D[sXm~X" )jKp?)}Y?7߯;cbzNADՄ F_)Cn}^?SSQ5aB5E6S/xNWˊ  Jx,T(7!LkNKq &_݉KSQ5aB5EEW:co0omc"NvP'ݪGm4WP)3g qI뮆khn&jY "ʠJI:$#:?_yi L4DT "𫑢$B {ee)*?]rX 0Yaa4nVK jBjJ on伕rNADՀ զzESX]*nǩwP%aB5IDN19cj1_\ni/ U  MK6%brj0ʹewK*ʣ};;]'Œ $u>ONq\_5'ҭ=:oDf,T6݂TtC>^.ڣ\[NDTXPMRB*COp-ҭ:b DF,T6y[qt>C59 ?l<ǼNADaBjN)^~.n r?ۘt " #*T-P\~-nNN |2P~N:  IO:šORAzt+g~t " *T3M!0a y6nn>_: Ijup:_:š١]_3v[9sjUα!aB5)x2hNq(5l:q9v$ʙ zU)D&,T&MX̑N1AE?Xe,0m|Wӧ[: I>7I`\c/>b,nL(""*TeH3+EJz;} ֦9CD/BjӨBոl>]:3#i}ܬ3BJP!*#DM ]vT}zLҭ:md": *DeOv֦O4Q)(XPmN1||OqtN=F&>`hN Iz)\+Y qt " 3*Tսs_rnsߔ*g݈NADaBjS\7+U/ sS6N]E~+jjD_`蒻s6 $4; !ׂe$t'c.׊Q!#`BW.|@ݢߨz*{6rW0;>vy;h#cB5xrS=iآs/ ڧU`QWY vjӺwJ!jBjҾxr3^o1! zкv{Z $8eqȇ 4}rS?^) ߘn<>%vvc<$q7fɳD4,Ty+b4'K%y}ŀTC[g ijrORY/ɓݕuj%dٱҭ'ZBjUFـJԷ>I-F`ĥ[\)3}@o0Ʀ2g^O9tPHЮ)cio\c|J3Kb-{PI+_DTKXP$h*2ecgtVNZjS O%w$ΐn%"* j]x8vVjzQ²c8F NDTXP$2\7e,R nYx4t3?bܓDDՏ E^J]ҭ:DSxqȦXj}D}Z(2X|ISiK)bVtPhP^\ԟN,SSnʼnb'Ar@U>DT^,T(TzCPleKn@][ggڛҭ (`BѰGQA.gܙNQE?]ܑ|=?5K7 ERV+ݦ♿IbgMY6H'(`BM#Kχy tJhݩ`^K'(`B0>Q,sntcJ< Njޯ:SQPHQO'y3/hͱBt`ا$w[թ^0cFN"&B~fρZ9Fk|a򇩳տ˒bXPfTX7/ӗPbwltSXPܩ?i /zJ4SvD= PVy>>tJ"*-zt6hnL3•_~ ̟%.ӡ_7SQPHQ'MI~D:uñ_w tD%,T(Rԃ*;ǍeSg$jD>U@A*#-U @c*N6U:̯oߘFID,T(ZWkɿ2)ZVoǏ+u `jo65gB"Eu}|طZ~^Z:]>6[S:Q%8I sq`:KN_1[˩`tJ |#h԰԰t"" """ -:QhP!""bBDDDBB  """ -*DDDZ,T(XQhP!""bBDDDBB  """ ̖*IENDB`elyxer-1.2.5/test/references.lyx0000644000175000017500000000762412074107030016176 0ustar chennochenno#LyX 2.0.0svn created this file. For more info see http://www.lyx.org/ \lyxformat 410 \begin_document \begin_header \textclass book \begin_preamble % eLyXer -- convert LyX source files to HTML output. % % Copyright (C) 2009-2010 Alex Fernández % % This program is free software: 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 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 % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . \end_preamble \use_default_options true \maintain_unincluded_children false \language english \inputencoding auto \fontencoding global \font_roman default \font_sans default \font_typewriter default \font_default_family default \use_non_tex_fonts false \font_sc false \font_osf false \font_sf_scale 100 \font_tt_scale 100 \graphics default \default_output_format default \output_sync 0 \bibtex_command default \index_command default \paperfontsize default \spacing single \use_hyperref false \papersize default \use_geometry false \use_amsmath 1 \use_esint 1 \use_mhchem 1 \use_mathdots 1 \cite_engine basic \use_bibtopic false \use_indices false \paperorientation portrait \suppress_date false \use_refstyle 0 \index Index \shortcut idx \color #008000 \end_index \secnumdepth 3 \tocdepth 3 \paragraph_separation indent \paragraph_indentation default \quotes_language english \papercolumns 1 \papersides 1 \paperpagestyle default \tracking_changes false \output_changes false \html_math_output 0 \html_be_strict false \end_header \begin_body \begin_layout Title References Test \begin_inset Note Note status open \begin_layout Plain Layout This note should not appear in the resulting page title \end_layout \end_inset \end_layout \begin_layout Author Alex Fernández (elyxer@gmail.com) \end_layout \begin_layout Chapter First Chapter \end_layout \begin_layout Standard This first chapter contains the reference: \begin_inset CommandInset ref LatexCommand ref reference "cha:inchapter2" \end_inset , contained in chapter: \begin_inset CommandInset ref LatexCommand ref reference "cha:Second-Chapter" \end_inset . \end_layout \begin_layout Section Sectioned \end_layout \begin_layout Standard This section contains a reference in brackets: \begin_inset CommandInset ref LatexCommand eqref reference "cha:inchapter2" \end_inset . It should be on page: \begin_inset CommandInset ref LatexCommand pageref reference "cha:inchapter2" \end_inset , and so be: \begin_inset CommandInset ref LatexCommand vref reference "cha:inchapter2" \end_inset . \end_layout \begin_layout Standard Adding a pretty reference: \begin_inset CommandInset ref LatexCommand formatted reference "cha:inchapter2" \end_inset . Now a named reference: \begin_inset CommandInset ref LatexCommand nameref reference "cha:inchapter2" \end_inset . \end_layout \begin_layout Chapter Second Chapter \begin_inset CommandInset label LatexCommand label name "cha:Second-Chapter" \end_inset \end_layout \begin_layout Standard This second chapter contains the label \begin_inset CommandInset label LatexCommand label name "cha:inchapter2" \end_inset . \end_layout \begin_layout Section URIs \end_layout \begin_layout Standard Now a couple of test URIs: \begin_inset CommandInset href LatexCommand href name "Savannah interface" target "https://savannah.nongnu.org/bugs/?func=additem&group=elyxer" \end_inset , \begin_inset CommandInset href LatexCommand href target "https://savannah.nongnu.org/bugs/?func=additem&group=elyxer" \end_inset . \end_layout \end_body \end_document elyxer-1.2.5/test/ert.lyx0000644000175000017500000000714612074107030014646 0ustar chennochenno#LyX 1.6.7 created this file. For more info see http://www.lyx.org/ \lyxformat 345 \begin_document \begin_header \textclass article \begin_preamble \usepackage{url} \usepackage{color} \end_preamble \use_default_options true \begin_modules theorems-ams eqs-within-sections figs-within-sections \end_modules \language english \inputencoding auto \font_roman default \font_sans default \font_typewriter default \font_default_family default \font_sc false \font_osf false \font_sf_scale 100 \font_tt_scale 100 \graphics default \paperfontsize default \spacing single \use_hyperref false \papersize default \use_geometry false \use_amsmath 1 \use_esint 1 \cite_engine basic \use_bibtopic false \paperorientation portrait \secnumdepth 3 \tocdepth 3 \paragraph_separation indent \defskip medskip \quotes_language english \papercolumns 1 \papersides 1 \paperpagestyle default \tracking_changes false \output_changes false \author "" \author "" \end_header \begin_body \begin_layout Title ERT Test \end_layout \begin_layout Standard This is a test for Evil Red Test ( \begin_inset ERT status open \begin_layout Plain Layout TeX \end_layout \end_inset code). \end_layout \begin_layout Standard Pure TeX can contain formulas: \begin_inset ERT status open \begin_layout Plain Layout Equation $a=b$ \end_layout \end_inset . This activates the dorky math mode. \end_layout \begin_layout Standard It can also contain arbitrary commands: \begin_inset ERT status open \begin_layout Plain Layout \backslash $ \backslash url{http://elyxer.nongnu.org/} \backslash Circle \end_layout \end_inset . \end_layout \begin_layout Standard ERTs can be left open \begin_inset ERT status open \begin_layout Plain Layout { \end_layout \end_inset and be closed afterwards \begin_inset ERT status open \begin_layout Plain Layout } with text \end_layout \end_inset . This allows us to apply commands to arbitrary text: \begin_inset ERT status open \begin_layout Plain Layout { \backslash color{red} \end_layout \end_inset this text should be red \begin_inset ERT status open \begin_layout Plain Layout } \end_layout \end_inset , \begin_inset ERT status open \begin_layout Plain Layout \backslash url{ \end_layout \end_inset http://should.be.an.url/ \begin_inset ERT status open \begin_layout Plain Layout } \end_layout \end_inset . \end_layout \begin_layout Standard ERTs can also be inserted in formulas: \end_layout \begin_layout Standard \begin_inset Formula \begin{equation} a=b\tag{{unnumbered}}.\end{equation} \end_inset \end_layout \begin_layout Standard Curly brackets can be inserted escaping them: \begin_inset ERT status open \begin_layout Plain Layout \backslash { like this \backslash } \end_layout \end_inset . Also in a formula: \begin_inset Formula $\{h\}$ \end_inset . Escaped curly brackets should not be confused with regular TeX brackets: \begin_inset ERT status open \begin_layout Plain Layout { \backslash { \backslash }} \end_layout \end_inset . \end_layout \begin_layout Standard A rule in an ERT: \begin_inset ERT status open \begin_layout Plain Layout \backslash rule{3cm}{2pt} \end_layout \end_inset . \end_layout \begin_layout Standard Other commands can be ignored: \begin_inset ERT status open \begin_layout Plain Layout \backslash fboxrule 3mm \backslash fboxsep 0.4mm \end_layout \end_inset . TeX comments should also be ignored: \begin_inset ERT status open \begin_layout Plain Layout %comment \end_layout \begin_layout Plain Layout but not text between comments. \end_layout \begin_layout Plain Layout % another comment \end_layout \end_inset \end_layout \end_body \end_document elyxer-1.2.5/test/plain-text.lyx0000644000175000017500000000347012074107030016135 0ustar chennochenno#LyX 1.6.7 created this file. For more info see http://www.lyx.org/ \lyxformat 345 \begin_document \begin_header \textclass article \use_default_options true \language english \inputencoding auto \font_roman default \font_sans default \font_typewriter default \font_default_family default \font_sc false \font_osf false \font_sf_scale 100 \font_tt_scale 100 \graphics default \paperfontsize default \use_hyperref false \papersize default \use_geometry false \use_amsmath 1 \use_esint 1 \cite_engine basic \use_bibtopic false \paperorientation portrait \secnumdepth 3 \tocdepth 3 \paragraph_separation indent \defskip medskip \quotes_language english \papercolumns 1 \papersides 1 \paperpagestyle default \tracking_changes false \output_changes false \author "" \end_header \begin_body \begin_layout Title Plain Text Test \end_layout \begin_layout Standard This document will test whatever happens with plain text. \end_layout \begin_layout Section Paragraph Justification \end_layout \begin_layout Standard \align block Well, to discuss the implications of that sketch and to consider the moral problems raised by the law-enforcement methods involved we have a duck, a cat and a lizard. \end_layout \begin_layout Standard \align left Now first of all I'd like to put this question to you please, lizard. How effective do you consider the legal weapons employed by legal customs officers, nowadays? \end_layout \begin_layout Standard \align center Well while you're thinking about that, I'd like to bring the duck in here, and ask her, if possible, to clarify the whole question of currency restriction s, and customs regulations in the world today. \end_layout \begin_layout Standard \align right Perhaps the cat would rather answer that? \end_layout \begin_layout Standard That is all for now. \end_layout \end_body \end_document elyxer-1.2.5/test/square.png0000644000175000017500000000025512074107030015316 0ustar chennochennoPNG  IHDRJ"sRGB pHYs  tIME +}D tEXtCommentCreated with GIMPWIDATcc`$\ ]IENDB`elyxer-1.2.5/test/image-scaling-good.html0000644000175000017500000000624512074107030017631 0ustar chennochenno Image Scaling Tests

Image Scaling Tests

1 Scale

figure elyxer.png PNG unscaled.
figure elyxer.png PNG scaled 50%.
figure elyxer-eps.png Unscaled EPS.
figure elyxer-eps.png EPS scaled 50%.

2 Exploring Width

figure elyxer.png 50% column width.
figure elyxer.png 5cm wide.
figure elyxer.png 50% line width.
figure elyxer.png 5mm wide.

3 Exploring Height

figure elyxer.png 50% column height.
figure elyxer.png 5cm high.
figure elyxer.png 50% page height.
figure elyxer.png 5 mm high.
elyxer-1.2.5/test/toc-article.lyx0000644000175000017500000000734712074107030016265 0ustar chennochenno#LyX 1.6.7 created this file. For more info see http://www.lyx.org/ \lyxformat 345 \begin_document \begin_header \textclass article \begin_preamble % eLyXer -- convert LyX source files to HTML output. % % Copyright (C) 2009-2010 Alex Fernández % % This program is free software: 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 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 % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . \end_preamble \use_default_options false \language english \inputencoding auto \font_roman default \font_sans default \font_typewriter default \font_default_family default \font_sc false \font_osf false \font_sf_scale 100 \font_tt_scale 100 \graphics default \paperfontsize default \spacing single \use_hyperref false \papersize default \use_geometry false \use_amsmath 1 \use_esint 1 \cite_engine basic \use_bibtopic false \paperorientation portrait \secnumdepth 1 \tocdepth 2 \paragraph_separation skip \defskip medskip \quotes_language english \papercolumns 1 \papersides 1 \paperpagestyle default \tracking_changes false \output_changes false \author "" \author "" \end_header \begin_body \begin_layout Title Article TOC Test \end_layout \begin_layout Standard \begin_inset CommandInset toc LatexCommand tableofcontents \end_inset \end_layout \begin_layout Part Our Definition \end_layout \begin_layout Section The definition \end_layout \begin_layout Standard A TOC is a Table Of Contents. \end_layout \begin_layout Standard \begin_inset Note Comment status open \begin_layout Section Hidden Section \end_layout \begin_layout Plain Layout This section should be hidden from mortals, and from the TOC. \end_layout \end_inset \end_layout \begin_layout Section But I Already Knew That \end_layout \begin_layout Standard You were lucky. \end_layout \begin_layout Subsection I Want My Money Back \end_layout \begin_layout Standard There you have your 0€ back. \end_layout \begin_layout Subsubsection Completely Unfair Dude \end_layout \begin_layout Standard Hey, I didn't call you here. \end_layout \begin_layout Paragraph A Paragraph For You \end_layout \begin_layout Standard Totally uncalled for. \end_layout \begin_layout Section* Unordered Section \end_layout \begin_layout Standard Just to show that it works. \end_layout \begin_layout Standard And now a list. \end_layout \begin_layout Enumerate First item. \end_layout \begin_layout Enumerate We will embed an ordered subsection here just to fake it. \end_layout \begin_deeper \begin_layout Subsection There We Go \end_layout \end_deeper \begin_layout Enumerate See if it's in your TOC. \end_layout \begin_layout Paragraph But There Is More \end_layout \begin_layout Standard And nothing else. \end_layout \begin_layout Standard \begin_inset Note Comment status open \begin_layout Plain Layout \begin_inset CommandInset index_print LatexCommand printindex \end_inset \end_layout \end_inset \end_layout \begin_layout Section \start_of_appendix Appendix \end_layout \begin_layout Standard An appendix here, an appendix there. \end_layout \begin_layout Standard \begin_inset Note Comment status open \begin_layout Plain Layout \begin_inset CommandInset bibtex LatexCommand bibtex bibfiles "bibtex-plain" options "bibtotoc,plain" \end_inset \end_layout \end_inset \end_layout \end_body \end_document elyxer-1.2.5/test/laurindas-anger.png0000644000175000017500000005117112074107030017075 0ustar chennochennoPNG  IHDR[,ƽbKGD X pHYsdd vpAg[3=QMIDATxwU>gzٝe JHФ$rHQ^DQP"+A"b - =@*^ggvvzeBL23睙Lvlv=9ߣJ""""Q@DDD/,*DDDX,*DDDX,*DDDX,*DDDX,*DDDX,*DDDX,*DDDX,*DDDX,*DDDX,*DDDX,*DDDX,*DDDX,*DDDX,*DDDX,*DDDX,*DDDX,*DDDX,*DDDX,*DDDX,*DDDX,*DDDX,*DDDX,*DDDX,*DDDX,*DDDX,*DDDX,*DDDX,*DDDX,*DDDX,*DDDXZhPhd?Zכ̀JVk4S %X8 mm}@0߿e ۀD" z4jn:ШM&hM& jFcWH/M&@f@1m6@Ri4hRSߧIh VTB%,""UrA L$b1 ^u($/P78Z3Rs]0׷ir}x7X$q(LjVk0*VYf@V5ZIJ4ZC1J3Fo0"d lZn /Zhb՚LŀF#wJ*bD9,*78]]}==@_@$b1`@L&YX%%^( Zd60O f|>?׭(RU^oWcIiS`465&SUՌRS3gNjEƎE*Dްa2iE7{ZFc29xsokocw; ^Vǃ2lW1['vIG Cqq]DƢB>08304g/p:gYp8LY8XTh7mz > %:UIQz"l޼o|0KJkw}IXZ;CB.̥er99gΙg6d2F_O{StQA֨gɜ9gϛw%ңիO,PzUz zJJ=\PaaQahk{śnJ:JZqI&¢l@eQG};GEDEJ^Aٹo0fmj7^kn(XTh:;-nٸqrihGD5ǟp JqljNE,*%Û6:+?4D43gz*PUuW]%i}"0Q.aQ!qbزb  nѩh"uuv>FD IJ08z_‚BOᡡ6`/-[VhlXT ivhh͚_2Aܲ~08GO?-:谨`P7Qz{W|q~2x\t4cQ)p`_矋NAD" YK@[ۋ/|3HD|K7)JǃAGt "ܤn.E"d2D "%'On!u(H,*ў޾ ;˵צRZLt "R``f`嚫X)XT TQ1yDd@矿{JE Vk29D!"% 6mNݦHb<%DhoK?ٺm;.NVZFۥ h&ӗT*Z'H$aH$I łA  ^/@"G"? +ֆCN?JD|âB?~Y{Lt\&b  - ו_/ZnV+"w2HH088^og' tw BΝ@($ZsTuuK,DBPڱغ7DQ.PLœ&fsQQsl..nnNtx< @`hhf plkf xvVh*s~k@eGP`Q/ټwy@$tN#h'~:`UU͝˟$L$b1 to|>ksoGMn(.9SE\ǢB_ӳb\|׿N#J47tPY9}|$" ymmRq^z;w Dңh4td24ʧVk5F#Kh,-mir }Ν 7NM IM͜9&P\\_hL$K&0x8<2bכ ,oFC!{RDAK: ~A_RLj'f[H_b̙Q@D4Gˏpjj:?nBѩhOߓVk4:IE&zzڴ ֯l"^87v˵s'08GO? qNE+*W۷?uEɜ3/ hwn?>_uSJ֋.Ft*H{e̞#:E8MMɛٳ @h rG2G"@w'PaQ2f"tj̋.rJ8--yt,Yt10*+g8ޖBp|.`hO7iH4oo#)ƯK*+EB'*-mi9x<6l|SǠ#@_t?? 8sy&VtFT,*%x8Ck_~Yt~B-/om=tYO-n>KY0lo$x4*:}bgZS|CI&o@< yZZ:mә%%M$]]={7 L|q=fp?Y/cQ)x*==+Vdzae3QS3D@}a]}u4[Ap׬y%iH)XT T8v۷?%˗9Շ*: Qv45pPWwa3e~++$aQs?tw˖lsV^~Z՚Le^Y9w.P_\#EXp>{iH4^JGIZx֯?wַߒ6fN}_}u 6Q!7nᇁD"ŕ l*.&O~Z: D Jx6n׿к Eb)/Z[/yVO##W~ɤ'-TT,Xpe@Y_x4m,*9BS20O= {6mz5 x"Nٳ/X,E!R;x^f4jn&O7zJn%]Phppv``'`سyoP% Jh4z}4Dt65-^ D"08u?!:Vz zEE!b1z{~<ßo|5* * E>bڴ~kF toj5ktΚt)`4M$:eOvK^l. ky| /<~2)(#Mt*4,G_wv,[v]@WݗrҥS`ZS9GtKnܸWELcQɒD" &3qr5FZBN%%--'(ojfzѨ78(: e J;:^y?|?*ȷrQzTgN2v&ۮ¢a|SȎ+:Mj ]ZI9iZ^>k`6L,:|mm}^.cQy)r`'irWiIJFc0NIjZ ZtW^('HQ\pNw2ʊwݶmJi(]%.C֬y C!irVk4:0MRTS"!VRIDVMYT@0^үFb)):0s2v|w44yKmAF zn}~ZZN;MI':plPSSY MMuuP[[U%%@jC^ 1CD ʞfiNeey9WWjQq:9Ft@lo6NEŢfphhMt#zeLWLPZtG24:SQQZ сGwgcvl|vf=,*i8~lʃ(tD^UNeeY,t\\D2 /<Ӎ@(r!:Jz=tN&:Zy yS:"vȗvu-_~{taQI3Z3l*.&LōSMJ}3QJI%-6[yy>Y0ۻq#r^쳢Ёiu5fIj~[tܡ[,^QoT U^Y7AtJM8쫘&OޱX<2F ^ʿ#\n2l*i~e%|SOUO> -- z}QQmT'dںhCRZٸ*2.)7B!ڪ6˅@+gعd4M@4X]tL: fIrQ GMS_"@W=xɡdҲ`Q!3Z^'%7͎՞++F~t#~ En ||]>>(/*J-VQQm\TQgm˖NC{bQZ5_Z6w׾&:M.Do2td2xD柨|[YhjiލRɟwrAFy\.2Nvɏd-3NK_ʕJ:NC2 +)9~hL&"V Ie/sΝ;wsΝ;w./|9 $(cEb"#y&3(3b`3 ONC2 WVL>NѣJ&XLd%ҦO?O>O>$GfʛooygyF3^OJ^W uMTXᨩ90i0G'? >9oE)XT'teJsUhX, d|hOңߎyGy$W>-6ןkFʞ"^^:-e*F%k%q^%Q2㕭y%<&u֭[7o޼ysގ(H~4z=x|\?E \$Mqa2eО)˞3E>E$_0z])TB,*@O @ յv4E%Xlb)=ǢP8)k/ʞ\.˟ΩY J?E_,*YHD,*JIK ^bt8|颶GhۣQ/o߾@4PhdY, NAc!eۑW*'^U2Hƍ*:LaQɲX@<c+O*tLn8N4䏟2 {Ktâe#:'@wdDt\%.*Ogygs%\r%y Ê+qv /cQɲPھMt ڷ>Lܸu}w]ve]vD^&/Szx<6,[&:E`Qɲp&:[4*WZ:0 |Up8{|}Û7&ۖӃE%B!kv)|>_t7p 7<>=s=]y2}:& n>J,OWt:0UFcSGK{TE.,W^z5o}[0yɓ'6ʷq|7|3aÆ 6K,YdI:i4,*⌌}Y nޔ"ekd|[n̙3gΜP\(>Ν~q6E6dI ӳa4v<wrKmʺӇh"x<&cQɒ`gz)h|>iJ$΢$7#0{^x8ɤ4oo#ir$dA2 7NBrݢ3(8+҉[ :,*ݝ@< e'PsVNދ20+ (E"  sdX0ȕ24@(Β rqc~54ң}/ TBm[E],*to_'JfԋRIwSEyK::gݴiV`2+|i1Bb`3,ݮ̻ƎE%Â޾ \QC垞/a`{QVD" ʕݩ@+/[" W  I$bPn&wTMnM"/?"qOot #}WVw&fd'`Q; lH$8jNg6N1ᰴi[Zaɵ1~k%VLV{~CR2GNK.ʙ:EFȓE%C>n=dr:y=K>(mjtb+B7h6~\pz+k`x땊^n>]h@E%CBA^>8z&(:E:==JicM$yA'KZIٺuxXxɏ0xlyXrA4N`ŲPdH8vN;LID{>/UzV|6o?'N۴ihH'~?y%%HD"ޡ㥄 N;ʹsEȆ=7;`6Lx;7xɛS~ ezu9)&}ŤC6h4Ml3eG<ΟcQIX,px<' 6[MJt ht:,*,yӮR"?qw04J}J"y)_ٺ=$|t ݋\"gY,? $–D<I{U\.@ZDR>v4ŤO@?ZR\\Wp44^qxc{)TD{N7W/ Jb~f/mGmFK{(m&Ɍ`0y|AMMe%tڜ&_ҞGrl>F~'DX(/ܹOz&[Zr)xHg}xG p6{*/>&ˏ\.WLY"r 豨7^QqA`J?S.:htDFI%=LFӾOhwD$¢2z,*iLʻioΦ+nRǿj1,qnl{cc!GâfvN:\RX3fNCe4aw+{;WgZ`HwK/o:VdǣQ2=ZKϼ&ɤ4O"?nk4^n"݃$Hxhȣs@ǣQ>;Zg4\gDP& 0E'ڰahHıpX$M$ yqZ"wL篽]]k׊N<FP.oE޸Q>6]TP=DD|ܖ]4IM2NѨ70GEQ..M? aGD~NX;cQd2DۀX,T1Me0¼l0?lߞɳӓݽ14:06=j--4Qw@wS)^oҭ50+5w$_n71PR$:EaQ9t;nF|;vTwHdsL B!H@4 n3F)r>$D,tv.[v]wd붕N{ZE%wT61##]Ztc0X,_z?7o^Bt*"1Z>RO>",*o-~WgNE$ZV+tvʣIx\7p6o&wTNLSN{ ~EE.(;w>kaAI7mVT|>i*䕔d2b2UVN TZtUED" v @0?/DpnQ`P pWRS3g|v[ۋ/r n :UFA)hNQ]XY&7wnEEy9Muڮ.`jjDʼ6nܱc6`ǎΎp<`ߟHH0EjZd2v?h4j5`L `4z=tz=PTdl@iiqqq1PUUVV^TTh0e/Hsp^n l O8ՀJ̜YVt6jj5B͜dRz4;2"%VkCa?h4fsQ7$08}̙s饢Oww?󯽶|9rf͖-6x6ի\ˏdh1{5_’o^~|X߽ro/W.ilƲIS-*tK+tB{>L&TwS{|$Oʊѱrhl b~%:H_'mm|(pXt;?D{4%l֖ |Ba`ǎUcaT`tx<8'/@ J#@޶ǐM6wuWT:"cʔcSfY-ѩ&n֬ɓL~3Bt*:h4MЎ˗~NoNQx ==׋NAVk@yG~W)+NXSSSGG"ZIwO7x*%st:E%XT --G*z\ yQXjZ⋿ ?0N@QdZ\\,_:V^.:E)uuY#:b55͛d6KsJ+*$5u'uԢE߃>0PUUVƟs@R*hO1vѡ׾Q&}QD=.iHjtF`a--&~c!L>cTni3UqTLj h hF+V}Q 97uuVk2IymWAQVUH6B9|^s9餓O*UT$uxr8v/&Zٜ`()i~a o,:b067g-ZW9T5U`;몫kONJUY%^)ZχJc08 S(*}}6NAGuj몪&\A×uǟxhG9Hn4F;lYTxk=z=/llpQ .qEeOڪjZ&ȭCDuuuu_ÿp%gq晩D4:?o97_+>E Q4AIUG@Q@UWW]|jNw(<{׿.hɒ3H=(t6bc=tΘ1u*X,Hb3$j^g6Xhy_TED Qr싼ץAt_L$Ud2wGD?90sfkɢeN'mJ~/ӧMKI$"_{?ƒҦlƧb2UVN 6[9X :~WTv=8UNLJ,;cƤIrW^y5Kv͛ FcYiKET*9cɧNB){L̅5_~4/.K.8>̿d2Eh,-4It *ųf-] Vk & L$DgaUEEi)u)ᘴ||9#~\eɒ%K,no%{o7B!}0fmO|RfoiYx4-x(N{lE]tLA:eRZ*=1D,86\}^r O> \u\|1PTd)yDҥK.] {={/ouLQtYgNA,*bU^&iӮ|lvWI =dvE/x?ᩧ}8hԩؔ:V \}UW]}5ͳlf\\790!,ڃLʊӁ`wx<"ɛvc^~Oda8l(e0 !D";i͙g{gߥ7nڴi+++VXbyBCc` 7t7fodt QgzMDWTdG̻" + =)\dSF_6}QhH$wU8":v{*NzD%HdzwMU}2iӦMzy]wzu֭[lݺm֭@oOOwo??? խp@VAJKˀӧM>8OiHɌ&(.*F%%rιPE"\YVfK/vՊNA{bQCq̙k Nj-+Ģ`Z²d4.!:)| ) >|YgI?J ]6)2KRy4ZZV&:Eet:Z': MT8<4ԶSt Rt:EEXTxSO&*q;:ޅBDY%<8,* j̦"ihX,"Wt"RJ3SS<,*RZ-(2uqDCCܫBJx)tVk)((Y &:MT$v++Zu7)(Y,uuռF=OWD$jEcQ%͵5sNCx<=Sh4:'*Y,5gNAx<STj~7T,Ռt׋NAKc1i@XTƈE%%H@4NCDD¢2Fz}qq]ZG/g㡐#:)A" Sо[%g~44^X BDHD/,*TUuW]* E JD"ŢаGt  P㏿i ܡNDB,*ox<"Wt  Rcm55'x̀Fc4ڬSсdRӊ&C!iEĢ&%%tWE}Q(.1E!Jx~&"v;9ZqXTҬht~Tc_ut̼AtJ&c1>HaQQ4*V#: )S;)vuebQI/&T*?GU%P]}q_/: Qf ^ѱz'~+M@g ǣQiz4b(Q"wI<,*i68O=%:VkcᇋNCWT&"L&I`ddǎd,*ilܸ|90'HjNg2UU]q4D\Q@{:)HƢ2A##۷ZtuE#b@**D!ʮX,E}`_矋NA2jhh͚_zzxg? I VcSZz!+: Ѩ':E nI5T4NtŢ2Jt7LW?0nٲbT$++? /*Td"D".Yr_D<D##^_TTS#:UbQ9;}|bqhHt*tVki PaFGFR)="XT / x<6.[&:KY_xWRqPYfD##|& dp׭{g W2l*.J pno"pү2lQ ہ^{AZFt*b猙 TZ^/: X+*HG%("m6s> 9&'DG!ROE?D4=?}QDT4QNKNA ##۷sv&T* wEexxӦ_:;ϻL@M,ffkn^@t"e+;2H1l6)(oJ ӳ~=eIfoj>b!~_G'E_ZtNAys׏{hڿH"Dt[Z.Hvd4fόR)(tݺuۢP+(Vkcy)2Kw8i_/*Ͳb=`Y": 2xwpmifSq1v4E2b;`)A{Ǒ3`p44NA/*d"NAbTWϚ%:2,:E3**&Od9_TT*JMޛb2UTL": 2}|":E3fd9_Tt:Bt J7bdC;c5#gRRd9St|Q닊jjZ5Dt1f vvbqhHte2NdRZCDt1z)we2/*2cʔŋEt1YT$`͢S?Wt(Oɓ=hL&Ͻ<鬫HBE_:V^O4)*)ҹs44^4`I5D!+&oÃ;vNl#w=mʓ7EEVZzg-5rih8(EhH!1EESp/yWT5_s44V-GVa>$lhT+*2y|1uNjNC՚DNY,$o㮿055'tM+H)x<HZDtg2J[ .: UA 5Ѷ~ɒ&ѩ W<S)XV":E++? 4b<j-+#:2͕ӧjVki13JJeBihXTI3x u eG,pnD^XؔW,X_*rh,-mnO?{4jVtDRRr!+:E0g͒VR:Jt(0O㎿zi_462? :UUӧK/F*:҅Eeg8D2#tNALҕ e|I-G-䜔|â2F]q`56q4' d"NC,`MM_6:j\[NCƢ2F*)SnǙ-L&I zyk,tVki)=tΙso؅hm]t `08|6tz8sfE"^oOD&^ɗ\u+RqjD̼C=|)(SXT&?3k  GOX4:2닊jjړNS.?swVun4Ut43/Yr<аt=NCTX>5@oρpdȵs~W*z25x Xuu Ƣ"H$twK+,7 CCmmS) Qa_*6RhvmuH{F)IQ닊կR:. # Alex 20091129: accept all test files as good echo "Accepting all eLyXer test files as good" echo "You should only do this if you have made a large change in all test files" echo " and you are sure that all files come out right!" # first from the test directory for oldfile in *-test.html; do newfile=${oldfile/"test"/"good"} mv -f "$oldfile" "$newfile" done # now the test file in subdir cd subdir for oldfile in *-test.html; do newfile=${oldfile/"test"/"good"} mv -f "$oldfile" "$newfile" done cd .. # and now for splitpart test files cd parts ./accept-all elyxer-1.2.5/test/lists-1-6.lyx0000644000175000017500000001135412074107030015507 0ustar chennochenno#LyX 1.6.5 created this file. For more info see http://www.lyx.org/ \lyxformat 345 \begin_document \begin_header \textclass article \begin_preamble % eLyXer -- convert LyX source files to HTML output. % % Copyright (C) 2009-2010 Alex Fernández % % This program is free software: 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 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 % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . \end_preamble \use_default_options true \language spanish \inputencoding auto \font_roman default \font_sans default \font_typewriter default \font_default_family default \font_sc false \font_osf false \font_sf_scale 100 \font_tt_scale 100 \graphics default \paperfontsize default \spacing single \use_hyperref false \papersize default \use_geometry false \use_amsmath 1 \use_esint 1 \cite_engine basic \use_bibtopic false \paperorientation portrait \secnumdepth 3 \tocdepth 3 \paragraph_separation skip \defskip medskip \quotes_language english \papercolumns 1 \papersides 1 \paperpagestyle default \tracking_changes false \output_changes false \author "" \author "" \end_header \begin_body \begin_layout Title List Test \end_layout \begin_layout Standard This document was created with LyX 1.6.2rc2, a great text editor. It is used to test lists, descriptions and item lists. \end_layout \begin_layout Section List and Description \end_layout \begin_layout List \labelwidthstring 00.00.0000 Ut enim ad minim veniam, quis nostrud exercitation \end_layout \begin_layout List \labelwidthstring 00.00.0000 ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est \end_layout \begin_layout List \labelwidthstring 00.00.0000 laborum. \end_layout \begin_layout Description Duis aute irure dolor in reprehenderit in \end_layout \begin_layout Description voluptate velit esse cillum dolore eu fugiat nulla pariatur. \end_layout \begin_layout Section Itemize and Enumerate \end_layout \begin_layout Enumerate First enumerated, \end_layout \begin_layout Enumerate second enumerated. \end_layout \begin_layout Itemize First itemized, \end_layout \begin_layout Itemize second itemized. \end_layout \begin_layout Section Lists with Levels \end_layout \begin_layout Standard First a simple nested list. \end_layout \begin_layout Itemize Level one: \end_layout \begin_deeper \begin_layout Itemize level two first item, \end_layout \begin_layout Itemize level two second item. \end_layout \end_deeper \begin_layout Standard Now a more complex example. \end_layout \begin_layout Itemize First in first level: \end_layout \begin_deeper \begin_layout Itemize first in second level, \end_layout \begin_layout Itemize second in second level, \end_layout \end_deeper \begin_layout Itemize second in first level: \end_layout \begin_deeper \begin_layout Itemize now third on second level: \end_layout \begin_deeper \begin_layout Itemize third level 1, \end_layout \begin_layout Itemize third level 2. \end_layout \end_deeper \end_deeper \begin_layout Itemize back to third in first level. \end_layout \begin_layout Enumerate Now 1st in 1st level: \end_layout \begin_deeper \begin_layout Enumerate 1st on 2nd level: \end_layout \begin_deeper \begin_layout Enumerate 1st on 3rd level! \end_layout \begin_layout Enumerate 2nd on 3rd level. \end_layout \begin_layout Itemize And now mixing 3rd level itemized, \end_layout \begin_layout Itemize and another. \end_layout \end_deeper \begin_layout Enumerate back to 2nd on 2nd street, sorry, level, \end_layout \end_deeper \begin_layout Enumerate and back to 1st level: \end_layout \begin_deeper \begin_layout Standard Now with some non-list text. \end_layout \begin_layout Enumerate And an ordered list. \end_layout \begin_deeper \begin_layout Standard Just the nested text. \end_layout \begin_layout Standard Repeated twice. \end_layout \end_deeper \begin_layout Enumerate Second element in the ordered list. \end_layout \begin_layout Itemize For a still more difficult number: unordered now. \end_layout \begin_layout Subsection And now a new subsection. \end_layout \end_deeper \begin_layout Enumerate 3rd on 1st level. \end_layout \end_body \end_document elyxer-1.2.5/test/formula.lyx0000644000175000017500000000303512074107030015512 0ustar chennochenno#LyX 2.0 created this file. For more info see http://www.lyx.org/ \lyxformat 413 \begin_document \begin_header \textclass article \use_default_options true \maintain_unincluded_children false \language english \language_package default \inputencoding auto \fontencoding global \font_roman default \font_sans default \font_typewriter default \font_default_family default \use_non_tex_fonts false \font_sc false \font_osf false \font_sf_scale 100 \font_tt_scale 100 \graphics default \default_output_format default \output_sync 0 \bibtex_command default \index_command default \paperfontsize default \use_hyperref false \papersize default \use_geometry false \use_amsmath 1 \use_esint 1 \use_mhchem 1 \use_mathdots 1 \cite_engine basic \use_bibtopic false \use_indices false \paperorientation portrait \suppress_date false \use_refstyle 1 \index Index \shortcut idx \color #008000 \end_index \secnumdepth 3 \tocdepth 3 \paragraph_separation indent \paragraph_indentation default \quotes_language english \papercolumns 1 \papersides 1 \paperpagestyle default \tracking_changes false \output_changes false \html_math_output 0 \html_css_as_file 0 \html_be_strict false \end_header \begin_body \begin_layout Title Formula Test \end_layout \begin_layout Standard Inline formula: \begin_inset Formula $a=b$ \end_inset . Display formula: \begin_inset Formula \[ b=a. \] \end_inset Numbered formula: \begin_inset Formula \begin{equation} c=c \end{equation} \end_inset \end_layout \begin_layout Standard No more, no less. \end_layout \end_body \end_document elyxer-1.2.5/test/index-1-6-good.html0000644000175000017500000004452112074107030016540 0ustar chennochenno Index Test

Index Test

Part I. The Making

1 Explanations

This chapter contains a lot of explanations for terms, which you might want to look up later. Because better sooner than later, although later has been repeated twice. Actually, thrice now.
Do you not want to look any of them up right now? No problem. You will be able to do it later, in the index.
Now we will add two cites in one, just because [2, 3].
As we will see in 3↓, not everything is clear.
You could also look down on someone, but that is not nice.

1.1Magical type face changes in the world

Little more can be added, at least at this point.

1.2Color and colour

At this other point, however, more could be added, but won’t.

Unnumbered Section

They have a right to live too.
  • A list would be nice here.
  • Because it corrupts the next chapter’s beginning.

2 Nomenclature

We should explain what an index is. We can do that with the nomenclature. Normally we will want to mix index and nomenclature terms. But what happens if we actually do? We will know later, when we generate the file.

2.1 Reminder

We have to remind the reader that things will be remembered.

2.2 Remainder

Whatever remains should be explained here.

Part II. The Additions

3 Bulk

We actually need a lot more text in order for our index to have more terms; so we can find out if the links are working. Since they are anchors inside the page, they might otherwise just take us to the top of the page, and we would not like that.
Yes, it would be bad for us. But on the other hand too much text can hide errors. So not much more text is needed.
Thanks for reading us.

Unnumbered Part

Unnumbered Chapter

This extra chapter contains nothing of interest except for a couple of unnumbered parts (one actual part and one chapter).
List of Figures

Part III. Our Definition

4 The definition

A TOC is a Table Of Contents.

4.1 But I Already Knew That

You were lucky.

4.1.1 I Want My Money Back

There you have your 0€ back.

4.1.1.1 Completely Unfair Dude

Hey, I didn’t call you here.
A Paragraph For You
Totally uncalled for.
figure elyxer-svg.png
Figure 4.1 eLyXer logo

Unordered Section

Just to show that it works.
And now a list.
  1. First item.
  2. We will embed an ordered subsection here just to fake it.

    4.1.2 There We Go

  3. See if it’s in your TOC.
But There Is More
And nothing else.

A Appendix

An appendix here, an appendix there.

Index

able:

anchor:

error:

explained:

hand:

index: , , ,

later: , ,

link:

look:

down:

up: ,

page:

remembered:

sooner:

term:

terms:

text: , ,

thrice:

top of the page:

twice:

Nomenclature

generate An activity that requires a source and a destination, something like eLyXer does with files.
index A list of terms with a reference to where they occur.
nomenclature A list of common words with an explanation.

Bibliography

[1] WordReference.com: “definition of elixir”, accessed March 2009. http://www.wordreference.com/definition/elixir

[2] W3C: “HTML 4.01 Specification”, 24 December 1999. http://www.w3.org/TR/REC-html40/

[3] W3C: “HTML 4.01 Specification”, 24 December 1999. http://www.w3.org/TR/REC-html40/

elyxer-1.2.5/test/test.css0000644000175000017500000000007112074107030014775 0ustar chennochenno/* * Test CSS */ div.Standard { background: #909090; } elyxer-1.2.5/test/appendix-1-6-good.html0000644000175000017500000004234112074107030017237 0ustar chennochenno Appendix Test

Appendix Test

Alex Fernández (elyxer@gmail.com)

Part I. Of How Our Hero Came and Went

1 The Coming

Our hero came in. He was tired. He thought the world belonged to him.

1.1 The Meeting

Our hero met with Laurinda. She was smiling. But our hero was not amused. His whiskers were dripping wet, he was astonishingly thirsty, and the contradiction was killing him. “Give me some beer, woman!”, he ordered.

1.2 The Melting

Laurinda smiled again. “But Wenceslau, you don’t belong here.” What a stupid thing to say at that precise moment, our hero thought to himself. Only that it came out loud. At that precise moment he knew that the desired beer would not be forthcoming.
He turned to the bartender and tried to obtain a beer by the very old method of purchasing it. But being ignored was not one of Laurinda’s specialities.

2 The Going

It could not last. Laurinda’s hips were flapping, and she was hopping mad.

2.1 Our Hero’s Imagination

Our hero imagined her as a rabbit with long ears and a fine set of tusks. In a short time the image drifted to a walrus, and our hero could not help letting his sinister smile giving him away. Figure 2.1↓ shows a gross approximation of the rabbit-walrus.
figure rabbit-walrus.png
Figure 2.1 The rabbit-walrus.

2.2 Laurinda’s Anger

“Wasn’t it great”, said Laurinda. Actually she said it in the present tense, but our poor storytelling skills have changed that to a cheesy past. Don’t do this at home, kids. You want to be regarded for your authenticity, and misquoting isn’t going to help much.
Anyway, back to the story. Laurinda wanted to hit him in the head with a big ham that she kept just for occassions like this, and being a solid Hitchcock fan she was ready to cook the ham afterwards and serve the resulting stew to any policemen that might come by. She was also a huge Almodóvar fan, but she was unaware that in an early film the divine Pedro had copied the scene. Actually both directors had copied the idea from a short story by Roald Dahl, very much worth reading. Although it must be said that in this story it was a lamb leg, which hardly offers the consistency and stiffness necessary to kill a sturdy husband.
But who cares. Laurinda meanwhile had a funny appearance; if you want to see why please direct your eyes to figure 2.2↓.
figure laurindas-anger.png
Figure 2.2 Laurinda’s anger pictured in a mildly humorous tone.
And yet, how furious was really Laurinda, whom we may optionally refer to as Melinda from now on? Table 2.1↓ vainly attempts to quantify it.
Anger Time
1 2
Table 2.1 Laurinda’s anger as a function of time.
For the sake of Laurinda’s furiousness, here is figure 2.3↓ again.
figure laurindas-anger.png
Figure 2.3 Laurinda’s anger, again.
But how did Laurinda compute her anger? We cannot but speculate; here is a stupid suggestion in listing 2.1↓.
anger = time - 1
Algorithm 2.1 Laurinda computes her anger.
The result is in table 2.2↓, proving we were right all along. Also subtables a↓ and b↓ show anger and time, respectively.
Anger
1
(a) Only Anger.
Time
2
(b) Only Time.
Table 2.2 Laurinda’s anger quantified, divided in two.
Interested in that last table? Let us repeat it but without a label and with a table and a subtable a↓.
Censored
(a) The rabbit-walrus does an encore.
Anger Time
1 2
Table 2.3 One more time.

2.3 The Passing Away

Our hero was passing by the village. He had only stopped to say “Hi!” Again here our lousy skills have made us spoil the quote, but this time for the opposite reasons: everyone knows how to say “Hi!”, so we don’t need an actual quote. It is enough to report that the had stopped to say hi, even maybe qualifying it a bit to make do for the missing exclamation sign: he could have stopped to say a friendly hi. Getting all literary he could have stopped to say a longing hi, although this road leads to bizarreness. It could be cool though.
But anyway. Laurinda was so mad, so hopping mad that she called her friend, the Assassin. He was not in town at that precise moment, but that didn’t help our hero as he was just outside town killing people in a small barn. Just for practice.
Our hero left the village, but Laurinda cunningly annotated the MAC address of his laptop’s wifi card. The lack of networking knowledge on the part of our hero (who really couldn’t tell a SYN packet from an ACK) was to play an important part in the story — if he had known how to change the MAC address, which identified him with the precision of a surgeon’s scalpel, he would have been safe.
Let’s not even get into that last scalpel metaphor, shall we not? It leaks worse than the Titanic.

Part II. Of How Our Hero Went No More

3 The Killing

Our hero led a happy existence for a long time afterwards, randomly avoiding all points within connecting distance of a wifi network. It could not last.
Our hero went to the next village, found a friendly Moonrams cafe and connected to the net. Quickly the assassin (who knew the very people that run the internet, and who by this display of nerdiness no longer merits the starting capital letter) traced a bunch of IP packets coming from our hero’s MAC address. He deployed a team of murderous African bees, which as surely as a well-cared-for AK-47 reached our hero and killed him with three fast stings. Of course they died afterwards, being bees and all, so it was an astounding feat this training of wild African bees just for this one murder. Maybe the Assassin merits that capital letter after all.

3.1 The Passing Away

Our hero was undone. He was no more. He was, actually, an ex-hero. We shall narrate his wake soon.
  • But first a message from our kind sponsors. They want to present you the next section in this deeper inset.

    3.2 The Mourning

    Everyone cried in the ceremony. It was so sad that we need an image of this moment. You can find it in figure 3.1↓. Mental note: never pay the artist beforehand.
figure mourning.png
Figure 3.1 A crude approximation to our hero’s mourning.
And thusly everything happened.

4 The Mourning

We have already talked at length about the mourning, and under sponsorship no less, so no further details will be given here. Suffice to say that our hero was mourned. A lot.

A The Rebirth

Surprising everyone, our hero was about to make a comeback.

A.1 Coming Again

As it happened, our hero had never died; he had just faked his own death to find out his assassin. It was not difficult, what with the capital letter and all.

A.2 Two is Better than One

How to make another comeback? This is left as an exercise to the reader.

B Our Recommendation to Kids

Never trust killer bees. Or Assassins.

B.1 Killer Bees and Their Perils

A killer bee cannot be trained consistently, since it will die at the first sting. Better use killing wasps — or, even better, solve your differencies talking.
For the sake of your education, check figure B.1↓. It shows a bunch of killer bees, or something.
figure mourning.png
Figure B.1 A gathering of killer bees. Supposedly.

B.2 Assassins: Inherently Unreliable

Someone who kills people (even for business) is not someone you want to deal with. Watch “Fargo” by the Coen Brothers if you don’t believe me. And remember: a hero under the belt is a feather on the hat.
elyxer-1.2.5/test/descriptions-1-5-good.html0000644000175000017500000000537312074107030020140 0ustar chennochenno Descriptions Tests

Descriptions Tests

First description.
Second description.
Third description which should hold all words but these.
Fourth description.
Fifth description with odd spaces.
Mixed font description.
Aneven more difficult description with change of font in the middle.
Animpossible description with intermixed changes of font and color.
A description which leads to fixed text in dif(fere)nt colors. And now some more.
ERT precedes this description, it should be kept.
ERT is the description  and not only the first word.
Word that leads a description and which appears in the Index.

Index

Word:

elyxer-1.2.5/test/ert-good.html0000644000175000017500000000404112074107030015713 0ustar chennochenno ERT Test

ERT Test

This is a test for Evil Red Test (TeX code).
Pure TeX can contain formulas: Equation a = b. This activates the dorky math mode.
It can also contain arbitrary commands: $ http://elyxer.nongnu.org/ ○.
ERTs can be left open and be closed afterwards with text. This allows us to apply commands to arbitrary text: this text should be red, http://should.be.an.url/.
ERTs can also be inserted in formulas:
(unnumbered) a = b.
Curly brackets can be inserted escaping them: { like this }. Also in a formula: {h}. Escaped curly brackets should not be confused with regular TeX brackets: {}.
A rule in an ERT:
.
Other commands can be ignored: . TeX comments should also be ignored: but not text between comments.
elyxer-1.2.5/test/bibtex-vancouver.bib0000644000175000017500000000115212074107030017246 0ustar chennochenno%% eLyXer: test BibTeX bibliography for vancouver style. %% Created on 20100529 by Alex Fernandez. @article{withvolume, Author = {J. Linkman}, Journal = {Just The Words}, Number = {3}, Pages = {1--300}, Publisher = {Grillomat Snack Bar, Paignton}, Title = {A Little Hors d'Oeuvres}, Volume = {300}, Year = {1969}, url = {http://www.ibras.dk/montypython/episode18.htm} } @article{withoutvolume, Author = {J. Linkman}, Journal = {Just The Words}, Publisher = {Grillomat Snack Bar, Paignton}, Title = {Our Main Course: Prawn Salad}, Year = {1969}, url = http://www.ibras.dk/montypython/episode18.htm }