--- /dev/null
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL. It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it. You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+ When we speak of free software, we are referring to freedom of use,
+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 this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+ To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights. These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ To protect each distributor, we want to make it very clear that
+there is no warranty for the free library. Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+\f
+ Finally, software patents pose a constant threat to the existence of
+any free program. We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder. Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+ Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License. This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License. We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+ When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library. The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom. The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+ We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License. It also provides other free software developers Less
+of an advantage over competing non-free programs. These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries. However, the Lesser license provides advantages in certain
+special circumstances.
+
+ For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard. To achieve this, non-free programs must be
+allowed to use the library. A more frequent case is that a free
+library does the same job as widely used non-free libraries. In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+ In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software. For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+ Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+\f
+ GNU LESSER GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+ You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+\f
+ 2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+\f
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+ If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+\f
+ 6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (1) uses at run time a
+ copy of the library already present on the user's computer system,
+ rather than copying library functions into the executable, and (2)
+ will operate properly with a modified version of the library, if
+ the user installs one, as long as the modified version is
+ interface-compatible with the version that the work was made with.
+
+ c) Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ d) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ e) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+\f
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License. However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+ 9. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+\f
+ 11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+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
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded. In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser 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 Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation. If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+\f
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission. For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this. Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+ NO WARRANTY
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "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
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY 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
+LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+\f
+ How to Apply These Terms to Your New Libraries
+
+ If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change. You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+ To apply these terms, attach the following notices to the library. It is
+safest to attach them to the start of each source file to most effectively
+convey 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 library's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
+ library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+ <signature of Ty Coon>, 1 April 1990
+ Ty Coon, President of Vice
+
+That's all there is to it!
+
+
--- /dev/null
+Summary
+
+ A powerful and robust templating system for Python.
+
+
+Overview
+
+ EmPy is a system for embedding Python expressions and statements
+ in template text; it takes an EmPy source file, processes it, and
+ produces output. This is accomplished via expansions, which are
+ special signals to the EmPy system and are set off by a special
+ prefix (by default the at sign, '@'). EmPy can expand arbitrary
+ Python expressions and statements in this way, as well as a
+ variety of special forms. Textual data not explicitly delimited
+ in this way is sent unaffected to the output, allowing Python to
+ be used in effect as a markup language. Also supported are
+ callbacks via hooks, recording and playback via diversions, and
+ dynamic, chainable filters. The system is highly configurable via
+ command line options and embedded commands.
+
+ Expressions are embedded in text with the '@(...)' notation;
+ variations include conditional expressions with '@(...?...!...)'
+ and the ability to handle thrown exceptions with '@(...$...)'. As
+ a shortcut, simple variables and expressions can be abbreviated as
+ '@variable', '@object.attribute', '@function(arguments)',
+ '@sequence' [index], and combinations. Full-fledged statements
+ are embedded with '@{...}'. Control flow in terms of conditional
+ or repeated expansion is available with '@[...]'. A '@' followed
+ by a whitespace character (including a newline) expands to
+ nothing, allowing string concatenations and line continuations.
+ Comments are indicated with '@#' and consume the rest of the line,
+ up to and including the trailing newline. '@%' indicate
+ "significators," which are special forms of variable assignment
+ intended to specify per-file identification information in a
+ format which is easy to parse externally. Context name and line
+ number changes can be done with '@?' and '@!' respectively.
+ '@<...>' markups are customizeable by the user and can be used for
+ any desired purpose. Escape sequences analogous to those in C can
+ be specified with '@\...', and finally a '@@' sequence expands to
+ a single literal at sign.
+
+
+Getting the software
+
+ The current version of empy is 3.3.2.
+
+ The latest version of the software is available in a tarball here:
+ "http://www.alcyone.com/software/empy/empy-latest.tar.gz",
+ http://www.alcyone.com/software/empy/empy-latest.tar.gz.
+
+ The official URL for this Web site is
+ "http://www.alcyone.com/software/empy/",
+ http://www.alcyone.com/software/empy/.
+
+
+Requirements
+
+ EmPy should work with any version of Python from 2.4 onward,
+ including 3.x.
+
+
+License
+
+ This code is released under the "LGPL",
+ http://www.gnu.org/copyleft/lesser.html.
+
+
+Mailing lists
+
+ There are two EmPy related mailing lists available. The first is
+ a receive-only, very low volume list for important announcements
+ (including releases). To subscribe, send an email to
+ "empy-announce-list-subscribe@alcyone.com",
+ mailto:empy-announce-list-subscribe@alcyone.com.
+
+ The second is a general discussion list for topics related to
+ EmPy, and is open for everyone to contribute; announcements
+ related to EmPy will also be made on this list. The author of
+ EmPy (and any future developers) will also be on the list, so it
+ can be used not only to discuss EmPy features with other users,
+ but also to ask questions of the author(s). To subscribe, send an
+ email to "empy-list-subscribe@alcyone.com",
+ mailto:empy-list-subscribe@alcyone.com.
+
+
+Basics
+
+ EmPy is intended for embedding Python code in otherwise
+ unprocessed text. Source files are processed, and the results are
+ written to an output file. Normal text is sent to the output
+ unchanged, but markups are processed, expanded to their results,
+ and then written to the output file as strings (that is, with the
+ 'str' function, not 'repr'). The act of processing EmPy source
+ and handling markups is called "expansion."
+
+ Code that is processed is executed exactly as if it were entered
+ into the Python interpreter; that is, it is executed with the
+ equivalent of 'eval' (for expressions) and 'exec' (for
+ statements). EmPy is intended to be a very thin (though powerful)
+ layer on top of a running Python system; Python and EmPy files can
+ be mixed together (via command line options) without
+ complications.
+
+ By default the embedding prefix is the at sign ('@'), which
+ appears neither in valid Python code nor commonly in arbitrary
+ texts; it can be overridden with the -p option (or with the
+ 'empy.setPrefix' function). The prefix indicates to the EmPy
+ interpreter that a special sequence follows and should be
+ processed rather than sent to the output untouched (to indicate a
+ literal at sign, it can be doubled as in '@@').
+
+ When the interpreter starts processing its target file, no modules
+ are imported by default, save the 'empy' pseudomodule (see below),
+ which is placed in the globals; the 'empy' pseudomodule is
+ associated with a particular interpreter -- in fact, they are the
+ same object -- and it is important that it not be removed from
+ that interpreter's globals, nor that it be shared with other
+ interpreters running concurrently (a name other than 'empy' can be
+ specified with the -m option). The globals are not cleared or
+ reset in any way. It is perfectly legal to set variables or
+ explicitly import modules and then use them in later markups,
+ *e.g.*, '@{import time} ... @time.time()'. Scoping rules are as
+ in normal Python, although all defined variables and objects are
+ taken to be in the global namespace.
+
+ Indentation is significant in Python, and therefore is also
+ significant in EmPy. EmPy statement markups ('@{...}'), when
+ spanning multiple lines, must be flush with the left margin. This
+ is because (multiline) statement markups are not treated specially
+ in EmPy and are simply passed to the Python interpreter, where
+ indentation is significant.
+
+ Activities you would like to be done before any processing of the
+ main EmPy file can be specified with the -I, -D, -E, -F, and -P
+ options. -I imports modules, -D executes a Python variable
+ assignment, -E executes an arbitrary Python (not EmPy) statement,
+ -F executes a Python (not EmPy) file, and -P processes an EmPy
+ (not Python) file. These operations are done in the order they
+ appear on the command line; any number of each (including, of
+ course, zero) can be used.
+
+
+Expansions
+
+ The following markups are supported. For concreteness below, '@'
+ is taken for the sake of argument to be the prefix character,
+ although this can be changed.
+
+ **'@# COMMENT NEWLINE'** -- A comment. Comments, including the
+ trailing newline, are stripped out completely. Comments should
+ only be present outside of expansions. The comment itself is
+ not processed in any way: It is completely discarded. This
+ allows '@#' comments to be used to disable markups. *Note:* As
+ special support for "bangpaths" in Unix-like operating systems,
+ if the first line of a file (or indeed any context) begins with
+ '#!', and the interpreter has a 'processBangpaths' option set to
+ true (default), it is treated as a '@#' comment. A '#!'
+ sequence appearing anywhere else will be handled literally and
+ unaltered in the expansion. Example::
+
+ @# This line is a comment.
+ @# This will NOT be expanded: @x.
+
+ **'@? NAME NEWLINE'** -- Set the name of the current context to be
+ the given string. Variables are not allowed here; the name is
+ treated as a literal. (If you wish to use arbitrary
+ expressions, use the 'empy.setContextName' function instead.)
+ Example::
+
+ @?NewName
+ The context name is now @empy.identify()[0] (NewName).
+
+ **'@! INTEGER NEWLINE'** -- Set the line number of the current
+ context to be the given integer value; this is similar to the
+ '#line' C preprocessor directive. This is done in such a way
+ that the *next* line will have the specified numeric value, not
+ the current one. Expressions are not allowed here; the number
+ must be a literal integer. (If you wish to use arbitrary
+ expressions, use the 'empy.setContextLine' function instead.)
+ Example::
+
+ @!100
+ The context line is now @empy.identify()[1] (100).
+
+ **'@ WHITESPACE'** -- A '@' followed by one whitespace character
+ (a space, horizontal tab, vertical tab, carriage return, or
+ newline) is expanded to nothing; it serves as a way to
+ explicitly separate two elements which might otherwise be
+ interpreted as being the same symbol (such as '@name@ s' to mean
+ '@(name)s' -- see below). Also, since a newline qualifies as
+ whitespace here, the lone '@' at the end of a line represents a
+ line continuation, similar to the backslash in other languages.
+ Coupled with statement expansion below, spurious newlines can be
+ eliminated in statement expansions by use of the '@{...}@'
+ construct. Example::
+
+ This will appear as one word: salt@ water.
+ This is a line continuation; @
+ this text will appear on the same line.
+
+ **'@\ ESCAPE_CODE'** -- An escape code. Escape codes in EmPy are
+ similar to C-style escape codes, although they all begin with
+ the prefix character. Valid escape codes include:
+
+ '@\0' -- NUL, null
+
+ '@\a' -- BEL, bell
+
+ '@\b' -- BS, backspace
+
+ '@\d' -- three-digital decimal code DDD
+
+ '@\e' -- ESC, escape
+
+ '@\f' -- FF, form feed
+
+ '@\h' -- DEL, delete
+
+ '@\n' -- LF, linefeed character, newline
+
+ '@\oOOO' -- three-digit octal code OOO
+
+ '@\qQQQQ' -- four-digit quaternary code QQQQ
+
+ '@\r' -- CR, carriage return
+
+ '@\s' -- SP, space
+
+ '@\t' -- HT, horizontal tab
+
+ '@\v' -- VT, vertical tab
+
+ '@\xHH' -- two-digit hexadecimal code HH
+
+ '@\z' -- EOT, end of transmission
+
+ '@^X' -- the control character ^X
+
+ Unlike in C-style escape codes, escape codes taking some number
+ of digits afterward always take the same number to prevent
+ ambiguities. Furthermore, unknown escape codes are treated as
+ parse errors to discourage potential subtle mistakes. Note
+ that, while '@\0' represents the NUL character, to represent an
+ octal code, one must use '@\o...', in contrast to C. Example::
+
+ This embeds a newline.@\nThis is on the following line.
+ This beeps!@\a
+ There is a tab here:@\tSee?
+ This is the character with octal code 141: @\o141.
+
+ **'@@'** -- A literal at sign ('@'). To embed two adjacent at
+ signs, use '@@@@', and so on. Any literal at sign that you wish
+ to appear in your text must be written this way, so that it will
+ not be processed by the system. *Note:* If a prefix other than
+ '@' has been chosen via the command line option, one expresses
+ that literal prefix by doubling it, not by appending a '@'.
+ Example::
+
+ The prefix character is @@.
+ To get the expansion of x you would write @@x.
+
+ **'@)', '@]', '@}'** -- These expand to literal close parentheses,
+ close brackets, and close braces, respectively; these are
+ included for completeness and explicitness only. Example::
+
+ This is a close parenthesis: @).
+
+ **'@"..."', '@"""..."""', etc.** -- These string literals expand
+ to the literals themselves, so '@"test"' expands to 'test'.
+ Since they are inherently no-operations, the only reason for
+ their use is to override their behavior with hooks.
+
+ **'@( EXPRESSION )'** -- Evaluate an expression, and expand with
+ the string (via a call to 'str') representation evaluation of
+ that expression. Whitespace immediately inside the parentheses
+ is ignored; '@( expression )' is equivalent to '@(expression)'.
+ If the expression evaluates to 'None', nothing is expanded in
+ its place; this allows function calls that depend on side
+ effects (such as printing) to be called as expressions. (If you
+ really *do* want a 'None' to appear in the output, then use the
+ Python string '"None"'.) *Note:* If an expression prints
+ something to 'sys.stdout' as a side effect, then that printing
+ will be spooled to the output *before* the expression's return
+ value is. Example::
+
+ 2 + 2 is @(2 + 2).
+ 4 squared is @(4**2).
+ The value of the variable x is @(x).
+ This will be blank: @(None).
+
+ **'@( TEST ? THEN (! ELSE)_opt ($ EXCEPT)_opt )'** -- A special
+ form of expression evaluation representing conditional and
+ protected evaluation. Evaluate the "test" expression; if it
+ evaluates to true (in the Pythonic sense), then evaluate the
+ "then" section as an expression and expand with the 'str' of
+ that result. If false, then the "else" section is evaluated and
+ similarly expanded. The "else" section is optional and, if
+ omitted, is equivalent to 'None' (that is, no expansion will
+ take place). *Note*: For backward compatibility, the "else"
+ section delimiter, '!', may be expressed as a ':'. This
+ behavior is supported but deprecated.
+
+ If the "except" section is present, then if any of the prior
+ expressions raises an exception when evaluated, the expansion
+ will be replaced with the evaluation of the except expression.
+ (If the "except" expression itself raises, then that exception
+ will be propagated normally.) The except section is optional
+ and, if omitted, is equivalent to 'None' (that is, no expansion
+ will take place). An exception (cough) to this is if one of
+ these first expressions raises a SyntaxError; in that case the
+ protected evaluation lets the error through without evaluating
+ the "except" expression. The intent of this construct is to
+ except runtime errors, and if there is actually a syntax error
+ in the "try" code, that is a problem that should probably be
+ diagnosed rather than hidden. Example::
+
+ What is x? x is @(x ? "true" ! "false").
+ Pluralization: How many words? @x word@(x != 1 ? 's').
+ The value of foo is @(foo $ "undefined").
+ Division by zero is @(x/0 $ "illegal").
+
+ **'@ SIMPLE_EXPRESSION'** -- As a shortcut for the '@(...)'
+ notation, the parentheses can be omitted if it is followed by a
+ "simple expression." A simple expression consists of a name
+ followed by a series of function applications, array
+ subscriptions, or attribute resolutions, with no intervening
+ whitespace. For example:
+
+ - a name, possibly with qualifying attributes (*e.g.*,
+ '@value', '@os.environ').
+
+ - a straightforward function call (*e.g.*, '@min(2, 3)',
+ '@time.ctime()'), with no space between the function name
+ and the open parenthesis.
+
+ - an array subscription (*e.g.*, '@array[index]',
+ '@os.environ[name]', with no space between the name and
+ the open bracket.
+
+ - any combination of the above (*e.g.*,
+ '@function(args).attr[sub].other[i](foo)').
+
+ In essence, simple expressions are expressions that can be
+ written ambiguously from text, without intervening space. Note
+ that trailing dots are not considered part of the expansion
+ (*e.g.*, '@x.' is equivalent to '@(x).', not '@(x.)', which
+ would be illegal anyway). Also, whitespace is allowed within
+ parentheses or brackets since it is unambiguous, but not between
+ identifiers and parentheses, brackets, or dots. Explicit
+ '@(...)' notation can be used instead of the abbreviation when
+ concatenation is what one really wants (*e.g.*, '@(word)s' for
+ simple pluralization of the contents of the variable 'word').
+ As above, if the expression evaluates to the 'None' object,
+ nothing is expanded. Note that since a curly appearing where
+ EmPy would expect an open parenthesis or bracket in is
+ meaningless in Python, it is treated as a parse error (*e.g.*,
+ '@x{1, 2}' results in an error). Example::
+
+ The value of x is @x.
+ The ith value of a is @a[i].
+ The result of calling f with q is @f(q).
+ The attribute a of x is @x.a.
+ The current time is @time.ctime(time.time()).
+ The current year is @time.localtime(time.time())[0].
+ These are the same: @min(2,3) and @min(2, 3).
+ But these are not the same: @min(2, 3) vs. @min (2, 3).
+ The plural of @name is @(name)s, or @name@ s.
+
+ **'@` EXPRESSION `'** -- Evaluate a expression, and expand with
+ the 'repr' (instead of the 'str' which is the default) of the
+ evaluation of that expression. This expansion is primarily
+ intended for debugging and is unlikely to be useful in actual
+ practice. That is, a '@`...`' is identical to '@(repr(...))'.
+ Example::
+
+ The repr of the value of x is @`x`.
+ This print the Python repr of a module: @`time`.
+ This actually does print None: @`None`.
+
+ **'@: EXPRESSION : DUMMY :'** -- Evaluate an expression and then
+ expand to a '@:', the original expression, a ':', the evaluation
+ of the expression, and then a ':'. The current contents of the
+ dummy area are ignored in the new expansion. In this sense it
+ is self-evaluating; the syntax is available for use in
+ situations where the same text will be sent through the EmPy
+ processor multiple times. Example::
+
+ This construct allows self-evaluation:
+ @:2 + 2:this will get replaced with 4:
+
+ **'@{ STATEMENTS }'** -- Execute a (potentially compound)
+ statement; statements have no return value, so the expansion is
+ not replaced with anything. Multiple statements can either be
+ separated on different lines, or with semicolons; indentation is
+ significant, just as in normal Python code. Statements,
+ however, can have side effects, including printing; output to
+ 'sys.stdout' (explicitly or via a 'print' statement) is
+ collected by the interpreter and sent to the output (unless this
+ behavior is suppressed with the -n option). The usual Python
+ indentation rules must be followed, although if the statement
+ consists of only one statement, leading and trailing whitespace
+ is ignored (*e.g.*, '@{ print time.time() }' is equivalent to
+ '@{print time.time()}'). Example::
+
+ @{x = 123}
+ @{a = 1; b = 2}
+ @{print time.time()}
+ @# Note that extra newlines will appear above because of the
+ @# newlines trailing the close braces. To suppress them
+ @# use a @ before the newline:
+ @{
+ for i in range(10):
+ print "i is %d" % i
+ }@
+ @{print "Welcome to EmPy."}@
+
+ **'@% KEY (WHITESPACE VALUE)_opt NEWLINE'** -- Declare a
+ significator. Significators consume the whole line (including
+ the trailing newline), and consist of a key string containing no
+ whitespace, and than optional value prefixed by whitespace. The
+ key may not start with or contain internal whitespace, but the
+ value may; preceding or following whitespace in the value is
+ stripped. Significators are totally optional, and are intended
+ to be used for easy external (that is, outside of EmPy)
+ identification when used in large scale environments with many
+ EmPy files to be processed. The purpose of significators is to
+ provide identification information about each file in a special,
+ easy-to-parse form so that external programs can process the
+ significators and build databases, independently of EmPy.
+ Inside of EmPy, when a significator is encountered, its key,
+ value pair is translated into a simple assignment of the form
+ '__KEY__ = VALUE' , where "__KEY__" is the key string with two
+ underscores on either side and "VALUE" is a Python expression.
+ Example::
+
+ @%title "Gravitation"
+ @%author "Misner", "Thorne", "Wheeler"
+ @%publisher "W.H. Freeman and Company"
+ @%pages 1279
+ @%keywords 'physics', 'gravity', 'Einstein', 'relativity'
+ @%copyright 1970, 1971
+
+ **'@< CONTENTS >'** -- Invoke a custom markup. The custom markup
+ is a special markup reserved for use by the user; it has no
+ prescribed meaning on its own. If 'contents' is a string
+ representing what appears in between the angle brackets, then
+ expanding this markup is equivalent to
+ 'empy.invokeCallback(contents)'. See the "Custom markup"
+ section for more information.
+
+
+Control
+
+ EmPy version 3 and above includes the ability to direct
+ conditional and repeated expansion of blocks of EmPy code with
+ control markups (the obsolescent "substitution" markups are
+ unavailable as of version 3.0). Control markups have analogs to
+ control flow structures in Python such as 'if/elif/else', 'for', and
+ 'while'. Control markups are set off with the '@[...]' notation.
+
+ Control markups are designed to be used in precisely the same way
+ that their internal Python analogues are used, except that the
+ control markups are intended to be used where there is much more
+ markup than control structure.
+
+ Some control markups are considered "primary," (*e.g.*, 'if',
+ 'for', 'while') as they begin a control markup. Others are
+ considered "secondary," since they can only appear inside control
+ flow markups delineated by primary markups (*e.g.*, 'elif',
+ 'else', 'continue', 'break').
+
+ Since EmPy, unlike Python, cannot use indentation to determine
+ where control structures begin and end, all primary control
+ markups *must* be followed by a corresponding terminating control
+ markup::
+
+ @[PRIMARY ...]...@[end PRIMARY]
+
+ (where 'PRIMARY' represents one of the primary keywords). The end
+ markup is mandatory, as is the space between the 'end' and the
+ starting keyword. For instance::
+
+ @# If `person' is alive, show their age.
+ @person.name is @
+ @[if person.isAlive]@person.age@[else]dead@[end if].
+
+ All primary markups must be terminated in this way, and the
+ keyword appearing in the appropriate 'end' markup must match the
+ primary markup it corresponds to; if either of these conditions
+ are not satisfied, the result is a parse error. Everything
+ between the starting control flow marker ('@[PRIMARY ...]') and
+ the ending marker ('@[end PRIMARY]') -- including other markups,
+ even control markups -- is considered part of the markup. Control
+ markups can be nested::
+
+ @# Print all non-false elements on separate lines.
+ @[for elem in elements]@[if elem]@elem@\n@[end if]@[end for]
+
+ Three major types of primary control markups are available:
+ conditional (*e.g.*, 'if', 'try'), looping (*e.g.*, 'for',
+ 'while'), and definitional (*e.g.*, 'def', discussed below).
+ Conditional control markups conditionally expand their contents,
+ whereas looping control markups repeatedly expand their contents.
+ The third type, definitional markups, will define new objects in
+ the globals relating to their contents. Conditional and looping
+ markups also differ in one substantial respect: Looping constructs
+ support '@[continue]' and '@[break]' markups which, like their
+ Python equivalents, continue with the next iteration or break out
+ of the innermost looping construct, respectively ('@[continue]'
+ and '@[break]' markups have no meaning inside conditional markups
+ and are an error). Also like their Python equivalents,
+ '@[continue]' and '@[break]' may appear inside nested markups, so
+ long as they ultimately are contained by at least one looping
+ control markup::
+
+ @# Walk a long a linked list, printing each element.
+ @[while 1]@
+ @node
+ @{node = node.next}@
+ @[if not node]@[break]@[end if]@
+ @[end while]
+
+ The provided markups are designed to mimic the internal Python
+ control structures as closely as possible. The supported control
+ markups are (the phrases in all uppercase are intended to signify
+ user-selectable patterns)::
+
+ @[if CONDITION1]...@[elif CONDITION2]...@[else]...@[end if]
+ @[try]...@[except ...]...@[except ...]...@[end try]
+ @[try]...@[finally]...@[end try]
+ @[for VARIABLE in SEQUENCE]...@[else]...@[end for]
+ @[while CONDITION]...@[else]...@[end while]
+ @[def SIGNATURE]...@[end def]
+
+ All recognizable forms behave like their Python equivalents; 'if'
+ can contain multiple 'elif' secondary markups within it; the
+ 'else' markups are optional (but must appear at the end), the
+ 'try' form with the 'except' clause can contain multiple ones
+ which are handled in sequence, the 'try' form can either contain
+ one or more 'except' clauses or one 'finally' clause (but not
+ both), and the 'for' and 'while' structures can contain 'continue'
+ or 'break' clauses internally (even if contained within other
+ markups).
+
+ The third type of primary control markup is "definitional," in
+ that they create objects in the globals for later use (*e.g.*,
+ 'def'). This allows the definition of a callable object which,
+ when called, will expand the contained markup (which can in turn,
+ of course, contain further markups). The argument to the markup
+ can be any legal Python function signature::
+
+ @[def f(x, y, z=2, *args, **keywords)]...@[end def]
+
+ would define a function in the globals named 'f' that takes the
+ given arguments. A macro markup of the form '@[def
+ SIGNATURE]CODE@[end def]' is equivalent to the Python code::
+
+ def SIGNATURE:
+ r"""CODE""" # so it is a doc string
+ empy.expand(r"""CODE""", locals())
+
+ That is, it creates a Python function with the same name and
+ function arguments, whose docstring is the contents of the EmPy
+ markup that will be expanded when called. And, when called, it
+ will expand those contents, with the locals passed in.
+
+
+Unicode support
+
+ EmPy version 3.1 and above includes intrinsic Unicode support.
+ EmPy's Unicode support defers to Python's internal Unicode
+ support, available in Python 2.0 and up, in order to allow
+ seamless and transparent translation of different encodings to the
+ native Python Unicode format.
+
+ Knowledge of Python's Unicode support is expected, although not
+ completely required, to gain full benefit of EmPy's Unicode
+ features. To enable Unicode support, start EmPy with the
+ -u/--unicode option. EmPy will then transparently encode from the
+ input stream, process markups internally with native Unicode, and
+ then decode transparently to the output stream.
+
+ By default, Python sets 'sys.stdin' and 'sys.stdout' with a
+ default encoding which is accessible via
+ 'sys.getdefaultencoding()'; encodings are represented by string
+ names. These streams have encodings set by the system and
+ *cannot* be changed.
+
+ However, encodings for newly created files (files to be read when
+ specified on the command line, and/or files to be written when
+ used with the -o and -a arguments) can be specified for EmPy via
+ command line options. The --unicode-encoding option
+ simultaneously indicates the encoding to be used for both input
+ and output, whereas the --unicode-input-encoding and
+ --unicode-output-encoding options can each be used to specify
+ different encodings for both input and output. (If an encoding is
+ not explicitly indicated, it resorts to the system default in
+ 'sys.getdefaultencoding()', which is locale dependent.)
+
+ Python's Unicode implementation has the concept of error handlers,
+ registered with the 'codecs' module, which can be specified to
+ determine what action should take place if input cannot be decoded
+ into Unicode, or Unicode cannot be encoded into output. EmPy uses
+ these same "errors," as they are called, and can be specified via
+ command line options. The three most common error handlers are:
+ 'ignore', where invalid sequences are simply ignored; 'replace',
+ where invalid sequences are replaced with an encoding-specific
+ indicator, usually a question mark; and 'strict', where invalid
+ sequences raise an error. The --unicode-errors command line
+ option specifies the same error handler to be used for both input
+ and output, and the --unicode-input-errors and
+ --unicode-output-errors options can specify different error
+ handlers for input and output. If an error handler is not
+ explicitly specified, the 'strict' handler (which will raise
+ errors) is used.
+
+ Remember, to specify input encodings or errors that will take
+ effect, one cannot take input from 'sys.stdin' and must explicitly
+ specify an EmPy file to process on the command line. Similarly,
+ for output encodings or errors, 'sys.stdout' cannot be used and an
+ explicit output file must be specified with the -o or -a options.
+ It is perfectly valid to enable the Unicode subsystem (-u option)
+ while using 'sys.stdin' and 'sys.stdout', but the encodings and
+ errors of these preexisting streams cannot be changed.
+
+ Combined with the --no-prefix option, which disables all markup
+ processing, EmPy can act merely as an encoding translator, relying
+ on Python's Unicode facilities::
+
+ em.py --no-prefix \
+ --unicode-input-encoding=utf-8 \
+ --unicode-output-encoding=latin-1 \
+ -o filename.Latin-1 filename.UTF-8
+
+
+Significators
+
+ Significators, introduced in EmPy version 1.2, are intended to
+ represent special assignment in a form that is easy to externally
+ parse. For instance, if one has a system that contains many EmPy
+ files, each of which has its own title, one could use a 'title'
+ significator in each file and use a simple regular expression to
+ find this significator in each file and organize a database of the
+ EmPy files to be built. This is an easier proposition than, for
+ instance, attempting to grep for a normal Python assignment
+ (inside a '@{...}' expansion) of the desired variable.
+
+ Significators look like the following::
+
+ @%KEY VALUE
+
+ including the trailing newline, where "key" is a name and "value"
+ is a Python expression, and are separated by any whitespace. This
+ is equivalent to the following Python code::
+
+ __KEY__ = VALUE
+
+ That is to say, a significator key translates to a Python variable
+ consisting of that key surrounded by double underscores on either
+ side. The value may contain spaces, but the key may not. So::
+
+ @%title "All Roads Lead to Rome"
+
+ translates to the Python code::
+
+ __title__ = "All Roads Lead to Rome"
+
+ but obviously in a way that easier to detect externally than if
+ this Python code were to appear somewhere in an expansion. Since
+ significator keys are surrounded by double underscores,
+ significator keys can be any sequence of alphanumeric and
+ underscore characters; choosing '123' is perfectly valid for a
+ significator (although straight), since it maps to the name
+ '__123__' which is a legal Python identifier.
+
+ Note the value can be any Python expression. The value can be
+ omitted; if missing, it is treated as 'None'.
+
+ Significators are completely optional; it is completely legal for
+ a EmPy file or files to be processed without containing any
+ significators. Significators can appear anywhere within a file
+ outside of other markups, but typically they are placed near the
+ top of the file to make them easy to spot and edit by humans.
+
+ A regular expression string designed to match significators (with
+ the default prefix) is available as 'empy.SIGNIFICATOR_RE_STRING',
+ and also is a toplevel definition in the 'em' module itself.
+
+
+
+Diversions
+
+ EmPy supports an extended form of diversions, which are a
+ mechanism for deferring and recalling output on demand, similar to
+ the functionality included in m4. Multiple "streams" of output
+ can be diverted (deferred) and undiverted (recalled) in this
+ manner. A diversion is identified with a name, which is any
+ immutable object such an integer or string. When recalled,
+ diverted code is *not* resent through the EmPy interpreter
+ (although a filter could be set up to do this).
+
+ By default, no diversions take place. When no diversion is in
+ effect, processing output goes directly to the specified output
+ file. This state can be explicitly requested at any time by
+ calling the 'empy.stopDiverting' function. It is always legal to
+ call this function.
+
+ When diverted, however, output goes to a deferred location which
+ can then be recalled later. Output is diverted with the
+ 'empy.startDiversion' function, which takes an argument that is
+ the name of the diversion. If there is no diversion by that name,
+ a new diversion is created and output will be sent to that
+ diversion; if the diversion already exists, output will be
+ appended to that preexisting diversion.
+
+ Output send to diversions can be recalled in two ways. The first
+ is through the 'empy.playDiversion' function, which takes the
+ name of the diversion as an argument. This recalls the named
+ diversion, sends it to the output, and then erases that
+ diversion. A variant of this behavior is the
+ 'empy.replayDiversion', which recalls the named diversion but does
+ not eliminate it afterwards; 'empy.replayDiversion' can be
+ repeatedly called with the same diversion name, and will replay
+ that diversion repeatedly. 'empy.createDiversion' create a
+ diversion without actually diverting to it, for cases where you
+ want to make sure a diversion exists but do not yet want to send
+ anything to it.
+
+ The diversion object itself can be retrieved with
+ 'empy.retrieveDiversion'. Diversions act as writable
+ file-objects, supporting the usual 'write', 'writelines', 'flush',
+ and 'close' methods. The data that has been diverted to them can
+ be retrieved in one of two ways; either through the 'asString'
+ method, which returns the entire contents of the diversion as a
+ single strong, or through the 'asFile' method, which returns the
+ contents of the diversion as a readable (not writable) file-like
+ object.
+
+ Diversions can also be explicitly deleted without recalling them
+ with the 'empy.purgeDiversion' function, which takes the desired
+ diversion name as an argument.
+
+ Additionally there are three functions which will apply the above
+ operations to all existing diversions: 'empy.playAllDiversions',
+ 'empy.replayAllDiversions', and 'empy.purgeAllDiversions'. All
+ three will do the equivalent of a 'empy.stopDiverting' call before
+ they do their thing.
+
+ The name of the current diversion can be requested with the
+ 'empy.getCurrentDiversion' function; also, the names of all
+ existing diversions (in sorted order) can be retrieved with
+ 'empy.getAllDiversions'.
+
+ When all processing is finished, the equivalent of a call to
+ 'empy.playAllDiversions' is done.
+
+
+Filters
+
+ EmPy also supports dynamic filters, introduced in version 1.3.
+ Filters are put in place right "before" the final output file, and
+ so are only invoked after all other processing has taken place
+ (including interpreting and diverting). Filters take input, remap
+ it, and then send it to the output.
+
+ The current filter can be retrieved with the 'empy.getFilter'
+ function. The filter can be cleared (reset to no filter) with
+ 'empy.resetFilter' and a special "null filter" which does not send
+ any output at all can be installed with 'empy.nullFilter'. A
+ custom filter can be set with the 'empy.setFilter' function; for
+ convenience, specialized shortcuts for filters preexist and can be
+ used in lieu of actual 'empy.Filter' instances for the
+ 'empy.setFilter' or 'empy.attachFilter' argument:
+
+ - 'None' is a special filter meaning "no filter"; when installed,
+ no filtering whatsoever will take place. 'empy.setFilter(None)'
+ is equivalent to 'empy.resetFilter()'.
+
+ - '0' (or any other numeric constant equal to zero) is another
+ special filter that represents the null filter; when installed,
+ no output will ever be sent to the filter's sink.
+
+ - A filter specified as a function (or lambda) is expected to take
+ one string argument and return one string argument; this filter
+ will execute the function on any input and use the return value
+ as output.
+
+ - A filter that is a string is a 256-character table is
+ substituted with the result of a call to 'string.translate'
+ using that table.
+
+ - A filter can be an instance of a subclass of 'empy.Filter'.
+ This is the most general form of filter. (In actuality, it can
+ be any object that exhibits a 'Filter' interface, which would
+ include the normal file-like 'write', 'flush', and 'close'
+ methods, as well as 'next', 'attach', and 'detach' methods for
+ filter-specific behavior.)
+
+ - Finally, the argument to 'empy.setFilter' can be a Python list
+ consisting of one or more of the above objects. In that case,
+ those filters are chained together in the order they appear in
+ the list. An empty list is the equivalent of 'None'; all
+ filters will be uninstalled.
+
+ Filters are, at their core, simply file-like objects (minimally
+ supporting 'write', 'flush', and 'close' methods that behave in
+ the usual way) which, after performing whatever processing they
+ need to do, send their work to the next file-like object or filter
+ in line, called that filter's "sink." That is to say, filters can
+ be "chained" together; the action of each filter takes place in
+ sequence, with the output of one filter being the input of the
+ next. Additionally, filters support a '_flush' method (note the
+ leading underscore) which will always flush the filter's
+ underlying sink; this method should be not overridden.
+
+ Filters also support three additional methods, not part of the
+ traditional file interface: 'attach', which takes as an argument a
+ file-like object (perhaps another filter) and sets that as the
+ filter's "sink" -- that is, the next filter/file-like object in
+ line. 'detach' (which takes no arguments) is another method which
+ flushes the filter and removes its sink, leaving it isolated.
+ Finally, 'next' is an accessor method which returns the filter's
+ sink -- or 'None', if the filter does not yet have a sink
+ attached.
+
+ To create your own filter, you can create an object which supports
+ the above described interface, or simply derive from the
+ 'empy.Filter' class and override its 'write' and possibly 'flush'
+ methods. You can chain filters together by passing them as
+ elements in a list to the 'empy.setFilter' function, or you can
+ chain them together manually with the 'attach' method::
+
+ firstFilter.attach(secondFilter)
+ empy.setFilter(firstFilter)
+
+ or just let EmPy do the chaining for you::
+
+ empy.setFilter([firstFilter, secondFilter])
+
+ In either case, EmPy will walk the filter chain and find the end
+ and then hook that into the appropriate interpreter stream; you
+ need not do this manually. The function 'empy.attachFilter' can
+ be used to attach a single filter (or shortcut, as above) to the
+ end of a currently existing chain. Note that unlike its cousin
+ 'empy.setFilter', one cannot pass a sequence of filters (or filter
+ shortcuts) to 'empy.attachFilter'. (If there is no existing
+ filter chain installed, 'empy.attachFilter' will behave the same
+ as 'empy.setFilter'.)
+
+ Subclasses of 'empy.Filter' are already provided with the above
+ null, function, and string functionality described above; they are
+ 'NullFilter', 'FunctionFilter', and 'StringFilter', respectively.
+ In addition, a filter which supports buffering, 'BufferedFilter',
+ is provided. Several variants are included: 'SizeBufferedFilter',
+ a filter which buffers into fixed-sized chunks,
+ 'LineBufferedFilter', a filter which buffers by lines, and
+ 'MaximallyBufferedFilter', a filter which completely buffers its
+ input.
+
+
+Hooks
+
+ The EmPy system allows for the registry of hooks with a running
+ EmPy interpreter. Originally introduced in version 2.0 and much
+ improved in 3.2, hooks are objects, registered with an
+ interpreter, whose methods represent specific callbacks. Any
+ number of hook objects can be registered with an interpreter, and
+ when a callback is invoked, the associated method on each one of
+ those hook objects will be called by the interpreter in sequence.
+
+ Hooks are simply instances, nominally derived from the 'empy.Hook'
+ class. The 'empy.Hook' class itself defines a series of methods,
+ with the expected arguments, which would be called by a running
+ EmPy interpreter. This scenario, much improved from the prior
+ implementation in 2.0, allows hooks to keep state and have more
+ direct access to the interpreter they are running in (the
+ 'empy.Hook' instance contains an 'interpreter' attribute).
+
+ To use a hook, derive a class from 'empy.Hook' and override the
+ desired methods (with the same signatures as they appear in the
+ base class). Create an instance of that subclass, and then
+ register it with a running interpreter with the 'empy.addHook'
+ function. (This same hook instance can be removed with the
+ 'empy.removeHook' function.)
+
+ More than one hook instance can be registered with an interpreter;
+ in such a case, the appropriate methods are invoked on each
+ instance in the order in which they were registered. To adjust
+ this behavior, an optional 'prepend' argument to the
+ 'empy.addHook' function can be used dictate that the new hook
+ should placed at the *beginning* of the sequence of hooks, rather
+ than at the end (which is the default).
+
+ All hooks can be enabled and disabled entirely for a given
+ interpreter; this is done with the 'empy.enableHooks' and
+ 'empy.disableHooks' functions. By default hooks are enabled, but
+ obviously if no hooks have been registered no hook callbacks will
+ be made. Whether hooks are enabled or disabled can be determined
+ by calling 'empy.areHooksEnabled'. To get a (copy of) the list of
+ registered hooks, call 'empy.getHooks'. Finally, to invoke a hook
+ manually, use 'empy.invokeHook'.
+
+ For a list of supported hook callbacks, see the 'empy.Hook' class
+ definition.
+
+ As a practical example, this sample Python code would print a
+ pound sign followed by the name of every file that is included
+ with 'empy.include'::
+
+ class IncludeHook(empy.Hook):
+ def beforeInclude(self, name, file, locals):
+ print "# %s" % name
+
+ empy.addHook(IncludeHook())
+
+
+Custom markup
+
+ Since version 3.2.1, the markup '@<...>' is reserved for
+ user-defined use. Unlike the other markups, this markup has no
+ specified meaning on its own, and can be provided a meaning by the
+ user. This meaning is provided with the use of a "custom
+ callback," or just "callback," which can be set, queried, or reset
+ using the pseudomodule function.
+
+ The custom callback is a callable object which, when invoked, is
+ passed a single argument: a string representing the contents of
+ what was found inside the custom markup '@<...>'.
+
+ To register a callback, call 'empy.registerCallback'. To remove
+ one, call 'empy.deregisterCallback'. To retrieve the callback (if
+ any) registered with the interpreter, use 'empy.getCallback'.
+ Finally, to invoke the callback just as if the custom markup were
+ encountered, call 'empy.invokeCallback'. For instance, '@<This
+ text>' would be equivalent to the call '@empy.invokeCallback("This
+ text")'.
+
+ By default, to invoke a callback (either explicitly with
+ 'empy.invokeCallback' or by processing a '@<...>' custom markup)
+ when no callback has been registered is an error. This behavior
+ can be changed with the 'CALLBACK_OPT' option, or the
+ --no-callback-error command line option.
+
+
+Pseudomodule
+
+ The 'empy' pseudomodule is available only in an operating EmPy
+ system. (The name of the module, by default 'empy', can be
+ changed with the -m option or the 'EMPY_PSEUDO' environment
+ variable). It is called a pseudomodule because it is not actually
+ a module, but rather exports a module-like interface. In fact,
+ the pseudmodule is actually the same internal object as the
+ interpreter itself.
+
+ The pseudomodule contains the following functions and objects (and
+ their signatures, with a suffixed 'opt' indicating an optional
+ argument):
+
+ First, basic identification:
+
+ **'VERSION'** -- A constant variable which contains a
+ string representation of the EmPy version.
+
+ **'SIGNIFICATOR_RE_STRING'** -- A constant variable representing a
+ regular expression string (using the default prefix) that can be
+ used to find significators in EmPy code.
+
+ **'SIGNIFICATOR_RE_SUFFIX'** -- The portion of the significator
+ regular expression string excluding the prefix, so that those
+ using non-standard prefix can build their own custom regular
+ expression string with 'myPrefix + empy.SIGNIFICATOR_RE_SUFFIX'.
+
+ **'interpreter'** -- The instance of the interpreter that is
+ currently being used to perform execution. *Note:* This is now
+ obsolete; the pseudomodule is itself the interpreter. Instead
+ of using 'empy.interpreter', simply use 'empy'.
+
+ **'argv'** -- A list consisting of the name of the primary EmPy
+ script and its command line arguments, in analogue to the
+ 'sys.argv' list.
+
+ **'args'** -- A list of the command line arguments following the
+ primary EmPy script; this is equivalent to 'empy.argv[1:]'.
+
+ **'identify() -> string, integer'** -- Retrieve identification
+ information about the current parsing context. Returns a
+ 2-tuple consisting of a filename and a line number; if the file
+ is something other than from a physical file (*e.g.*, an
+ explicit expansion with 'empy.expand', a file-like object within
+ Python, or via the -E or -F command line options), a string
+ representation is presented surrounded by angle brackets. Note
+ that the context only applies to the *EmPy* context, not the
+ Python context.
+
+ **'atExit(callable)'** -- Register a callable object (such as a
+ function) taking no arguments which will be called at the end of
+ a normal shutdown. Callable objects registered in this way are
+ called in the reverse order in which they are added, so the
+ first callable registered with 'empy.atExit' is the last one to
+ be called. Note that although the functionality is related to
+ hooks, 'empy.atExit' does no work via the hook mechanism, and
+ you are guaranteed that the interpreter and stdout will be in a
+ consistent state when the callable is invoked.
+
+ Context manipulation:
+
+ **'pushContext(name_opt, line_opt)'** -- Create a new context with
+ the given name and line and push it on the stack.
+
+ **'popContext()'** -- Pop the top context and dispose of it.
+
+ **'setContextName(name)'** -- Manually set the name of the current
+ context.
+
+ **'setContextLine(line)'** -- Manually set the line number of the
+ current context; line must be a numeric value. Note that
+ afterward the line number will increment by one for each newline
+ that is encountered, as before.
+
+ Globals manipulation:
+
+ **'getGlobals()'** -- Retrieve the globals dictionary for this
+ interpreter. Unlike when calling 'globals()' in Python, this
+ dictionary *can* be manipulated and you *can* expect changes you
+ make to it to be reflected in the interpreter that holds it.
+
+ **'setGlobals(globals)'** -- Reseat the globals dictionary
+ associated with this interpreter to the provided mapping type.
+
+ **'updateGlobals(globals)'** -- Merge the given dictionary into
+ this interpreter's globals.
+
+ **'clearGlobals(globals_opt)'** -- Clear out the globals
+ (restoring, of course, the 'empy' pseudomodule). Optionally,
+ instead of starting with a refresh dictionary, use the
+ dictionary provided.
+
+ **'saveGlobals(deep=True)'** -- Save a copy of the globals onto an
+ internal history stack from which it can be restored later. The
+ optional 'deep' argument indicates whether or not the copying
+ should be a deep copy (default) or a shallow one. Copying is
+ done with 'copy.deepcopy' or 'copy.copy', respectively.
+
+ **'restoreGlobals(destructive=True)'** -- Restore the most
+ recently saved globals from the history stack to as the current
+ globals for this instance. The optional 'destructive' argument
+ indicates whether or not the restore should remove the restored
+ globals from the history stack (default), or whether it should
+ be left there for subsequent restores.
+
+ Types:
+
+ **'Interpreter'** -- The actual interpreter class.
+
+ The following functions allow direct execution; optional 'locals'
+ arguments, if specified, are treated as the locals dictionary in
+ evaluation and execution:
+
+ **'defined(name, locals_opt)'** -- Return true if the given name
+ is defined either in the (optional) locals or the interpreter
+ globals; return false otherwise.
+
+ **'evaluate(expression, locals_opt)'** -- Evaluate the given
+ expression.
+
+ **'serialize(expression, locals_opt)'** -- Serialize the
+ expression, just as the interpreter would: If it is not None,
+ convert it to a string with the 'str' builtin function, and then
+ write out the result. If it evaluates to None, do nothing.
+
+ **'execute(statements, locals_opt)'** -- Execute the given
+ statement(s).
+
+ **'single(source, locals_opt)'** -- Interpret the "single" source
+ code, just as the Python interactive interpreter would.
+
+ **'import_(name, locals_opt)'** -- Import a module.
+
+ **'atomic(name, value, locals_opt)'** -- Perform a single, atomic
+ assignment. In this case name is the string denoating the name
+ of the (single) variable to be assigned to, and value is a
+ Python object which the name is to be bound to.
+
+ **'assign(name, value, locals_opt)'** -- Perform general
+ assignment. This decays to atomic assignment (above) in the
+ normal case, but supports "tuple unpacking" in the sense that if
+ name string contains commas, it is treated as a sequence of
+ names and memberwise assignment with each member of the value
+ (still a Python object, but which must be a sequence). This
+ function will raise a 'TypeError' or 'ValueError' just like
+ Python would if tuple unpacking is not possible (that is, if the
+ value is not a sequence or is of an incompatible length,
+ respectively). This only supports the assignment of Python
+ identifiers, not arbitrary Python lvalues.
+
+ **'significate(key, value_opt, locals_opt)'** -- Do a manual
+ signification. If 'value' is not specified, it is treated as
+ 'None'.
+
+ The following functions relate to source manipulation:
+
+ **'include(file_or_filename, locals_opt)'** -- Include another
+ EmPy file, by processing it in place. The argument can either
+ be a filename (which is then opened with 'open' in text mode) or
+ a file object, which is used as is. Once the included file is
+ processed, processing of the current file continues. Includes
+ can be nested. The call also takes an optional locals
+ dictionary which will be passed into the evaluation function.
+
+ **'expand(string, locals_opt)' -> string** -- Explicitly invoke
+ the EmPy parsing system to process the given string and return
+ its expansion. This allows multiple levels of expansion,
+ *e.g.*, '@(empy.expand("@(2 + 2)"))'. The call also takes an
+ optional locals dictionary which will be passed into the
+ evaluation function. This is necessary when text is being
+ expanded inside a function definition and it is desired that the
+ function arguments (or just plain local variables) are available
+ to be referenced within the expansion.
+
+ **'quote(string) -> string'** -- The inverse process of
+ 'empy.expand', this will take a string and return a new string
+ that, when expanded, would expand to the original string. In
+ practice, this means that appearances of the prefix character
+ are doubled, except when they appear inside a string literal.
+
+ **'escape(string, more_opt) -> string'** -- Given a string, quote
+ the nonprintable characters contained within it with EmPy
+ escapes. The optional 'more' argument specifies additional
+ characters that should be escaped.
+
+ **'flush()'** -- Do an explicit flush on the underlying stream.
+
+ **'string(string, name_opt, locals_opt)'** -- Explicitly process a
+ string-like object. This differs from 'empy.expand' in that the
+ string is directly processed into the EmPy system, rather than
+ being evaluated in an isolated context and then returned as a
+ string.
+
+ Changing the behavior of the pseudomodule itself:
+
+ **'flatten(keys_opt)'** -- Perform the equivalent of 'from empy
+ import ...' in code (which is not directly possible because
+ 'empy' is a pseudomodule). If keys is omitted, it is taken as
+ being everything in the 'empy' pseudomodule. Each of the
+ elements of this pseudomodule is flattened into the globals
+ namespace; after a call to 'empy.flatten', they can be referred
+ to simple as globals, *e.g.*, '@divert(3)' instead of
+ '@empy.divert(3)'. If any preexisting variables are bound to
+ these names, they are silently overridden. Doing this is
+ tantamount to declaring an 'from ... import ...' which is often
+ considered bad form in Python.
+
+ Prefix-related functions:
+
+ **'getPrefix() -> char'** -- Return the current prefix.
+
+ **'setPrefix(char)'** -- Set a new prefix. Immediately after this
+ call finishes, the prefix will be changed. Changing the prefix
+ affects only the current interpreter; any other created
+ interpreters are unaffected. Setting the prefix to None or the
+ null string means that no further markups will be processed,
+ equivalent to specifying the --no-prefix command line argument.
+
+ Diversions:
+
+ **'stopDiverting()'** -- Any diversions that are currently taking
+ place are stopped; thereafter, output will go directly to the
+ output file as normal. It is never illegal to call this
+ function.
+
+ **'createDiversion(name)'** -- Create a diversion, but do not
+ begin diverting to it. This is the equivalent of starting a
+ diversion and then immediately stopping diversion; it is used in
+ cases where you want to make sure that a diversion will exist
+ for future replaying but may be empty.
+
+ **'startDiversion(name)'** -- Start diverting to the specified
+ diversion name. If such a diversion does not already exist, it
+ is created; if it does, then additional material will be
+ appended to the preexisting diversions.
+
+ **'playDiversion(name)'** -- Recall the specified diversion and
+ then purge it. The provided diversion name must exist.
+
+ **'replayDiversion(name)'** -- Recall the specified diversion
+ without purging it. The provided diversion name must exist.
+
+ **'purgeDiversion(name)'** -- Purge the specified diversion
+ without recalling it. The provided diversion name must exist.
+
+ **'playAllDiversions()'** -- Play (and purge) all existing
+ diversions in the sorted order of their names. This call does
+ an implicit 'empy.stopDiverting' before executing.
+
+ **'replayAllDiversions()'** -- Replay (without purging) all
+ existing diversions in the sorted order of their names. This
+ call does an implicit 'empy.stopDiverting' before executing.
+
+ **'purgeAllDiversions()'** -- Purge all existing diversions
+ without recalling them. This call does an implicit
+ 'empy.stopDiverting' before executing.
+
+ **'getCurrentDiversion() -> diversion'** -- Return the name of the
+ current diversion.
+
+ **'getAllDiversions() -> sequence'** -- Return a sorted list of
+ all existing diversions.
+
+ Filters:
+
+ **'getFilter() -> filter'** -- Retrieve the current filter.
+ 'None' indicates no filter is installed.
+
+ **'resetFilter()'** -- Reset the filter so that no filtering is
+ done.
+
+ **'nullFilter()'** -- Install a special null filter, one which
+ consumes all text and never sends any text to the output.
+
+ **'setFilter(shortcut)'** -- Install a new filter. A filter is
+ 'None' or an empty sequence representing no filter, or '0' for a
+ null filter, a function for a function filter, a string for a
+ string filter, or an instance of 'empy.Filter' (or a workalike
+ object). If filter is a list of the above things, they will be
+ chained together manually; if it is only one, it will be
+ presumed to be solitary or to have already been manually chained
+ together. See the "Filters" section for more information.
+
+ **'attachFilter(shortcut)'** -- Attach a single filter (sequences
+ are not allowed here) to the end of a currently existing filter
+ chain, or if there is no current chain, install it as
+ 'empy.setFilter' would. As with 'empy.setFilter', the shortcut
+ versions of filters are also allowed here.
+
+ Hooks:
+
+ **'areHooksEnabled()'** -- Return whether or not hooks are
+ presently enabled.
+
+ **'enableHooks()'** -- Enable invocation of hooks. By default
+ hooks are enabled.
+
+ **'disableHooks()'** -- Disable invocation of hooks. Hooks can
+ still be added, removed, and queried, but invocation of hooks
+ will not occur (even explicit invocation with
+ 'empy.invokeHook').
+
+ **'getHooks()'** -- Get a (copy of the) list of the hooks
+ currently registered.
+
+ **'clearHooks()'** -- Clear all the hooks registered with this
+ interpreter.
+
+ **'addHook(hook, prepend_opt)'** -- Add this hook to the hooks
+ associated with this interpreter. By default, the hook is
+ appended to the end of the existing hooks, if any; if the
+ optional insert argument is present and true, it will be
+ prepended to the list instead.
+
+ **'removeHook(hook)'** -- Remove this hook from the hooks
+ associated with this interpreter.
+
+ **'invokeHook(_name, ...)'** -- Manually invoke a hook method.
+ The remaining arguments are treated as keyword arguments and the
+ resulting dictionary is passed in as the second argument to the
+ hooks.
+
+ Custom markup callback:
+
+ **'getCallback() -> callback'** -- Retrieve the current callback
+ associated with this interpreter, or 'None' if it does not yet
+ have one.
+
+ **'registerCallback(callback)'** -- Register a callback to be
+ called whenever a custom markup ('@<...>') is encountered. When
+ encountered, 'invokeCallback' is called.
+
+ **'deregisterCallback()'** -- Clear any callback previously
+ registered with the interpreter for being called when a custom
+ markup is encountered.
+
+ **'invokeCallback(contents)'** -- Invoke a custom callback. This
+ function is called whenever a custom markup ('@<...>') is
+ encountered. It in turn calls the registered callback, with a
+ single argument, 'contents', which is a string representing of
+ the contents of the custom markup.
+
+
+Invocation
+
+ Basic invocation involves running the interpreter on an EmPy file
+ and some optional arguments. If no file are specified, or the
+ file is named '-', EmPy takes its input from stdin. One can
+ suppress option evaluation (to, say, specify a file that begins
+ with a dash) by using the canonical '--' option.
+
+ **'-h'/'--help'** -- Print usage and exit.
+
+ **'-H'/'--extended-help'** -- Print extended usage and exit.
+ Extended usage includes a rundown of all the legal expansions,
+ escape sequences, pseudomodule contents, used hooks, and
+ supported environment variables.
+
+ **'-v'/'--verbose'** -- The EmPy system will print all manner of
+ details about what it is doing and what it is processing to
+ stderr.
+
+ **'-V'/'--version'** -- Print version and exit.
+
+ **'-a'/'--append' (filename)** -- Open the specified file for
+ append instead of using stdout.
+
+ **'-b'/'--buffered-output'** -- Fully buffer processing output,
+ including the file open itself. This is helpful when, should an
+ error occur, you wish that no output file be generated at all
+ (for instance, when using EmPy in conjunction with make). When
+ specified, either the -o or -a options must be specified, and
+ the -b option must precede them. This can also be specified
+ through the existence of the 'EMPY_BUFFERED_OUTPUT' environment
+ variable.
+
+ **'-f'/'--flatten'** -- Before processing, move the contents of
+ the 'empy' pseudomodule into the globals, just as if
+ 'empy.flatten()' were executed immediately after starting the
+ interpreter. That is, *e.g.*, 'empy.include' can be referred to
+ simply as 'include' when this flag is specified on the command
+ line. This can also be specified through the existence of the
+ 'EMPY_FLATTEN' environment variable.
+
+ **'-i'/'--interactive'** -- After the main EmPy file has been
+ processed, the state of the interpreter is left intact and
+ further processing is done from stdin. This is analogous to the
+ Python interpreter's -i option, which allows interactive
+ inspection of the state of the system after a main module is
+ executed. This behaves as expected when the main file is stdin
+ itself. This can also be specified through the existence of the
+ 'EMPY_INTERACTIVE' environment variable.
+
+ **'-k'/'--suppress-errors'** -- Normally when an error is
+ encountered, information about its location is printed and the
+ EmPy interpreter exits. With this option, when an error is
+ encountered (except for keyboard interrupts), processing stops
+ and the interpreter enters interactive mode, so the state of
+ affairs can be assessed. This is also helpful, for instance,
+ when experimenting with EmPy in an interactive manner. -k
+ implies -i.
+
+ **'-n'/'--no-override-stdout'** -- Do not override 'sys.stdout'
+ with a proxy object which the EmPy system interacts with. If
+ suppressed, this means that side effect printing will not be
+ captured and routed through the EmPy system. However, if this
+ option is specified, EmPy can support multithreading.
+
+ **'-o'/'--output' (filename)** -- Open the specified file for
+ output instead of using stdout. If a file with that name
+ already exists it is overwritten.
+
+ **'-p'/'--prefix' (prefix)** -- Change the prefix used to detect
+ expansions. The argument is the one-character string that will
+ be used as the prefix. Note that whatever it is changed to, the
+ way to represent the prefix literally is to double it, so if '$'
+ is the prefix, a literal dollar sign is represented with '$$'.
+ Note that if the prefix is changed to one of the secondary
+ characters (those that immediately follow the prefix to indicate
+ the type of action EmPy should take), it will not be possible to
+ represent literal prefix characters by doubling them (*e.g.*, if
+ the prefix were inadvisedly changed to '#' then '##' would
+ already have to represent a comment, so '##' could not represent
+ a literal '#'). This can also be specified through the
+ 'EMPY_PREFIX' environment variable.
+
+ **'-r'/'--raw-errors'** -- Normally, EmPy catches Python
+ exceptions and prints them alongside an error notation
+ indicating the EmPy context in which it occurred. This option
+ causes EmPy to display the full Python traceback; this is
+ sometimes helpful for debugging. This can also be specified
+ through the existence of the 'EMPY_RAW_ERRORS' environment
+ variable.
+
+ **'-u'/'--unicode'** -- Enable the Unicode subsystem. This option
+ only need be present if you wish to enable the Unicode subsystem
+ with the defaults; any other Unicode-related option (starting
+ with --unicode...) will also enable the Unicode subsystem.
+
+ **'-D'/'--define' (assignment)** -- Execute a Python assignment of
+ the form 'variable = expression'. If only a variable name is
+ provided (*i.e.*, the statement does not contain an '=' sign),
+ then it is taken as being assigned to None. The -D option is
+ simply a specialized -E option that special cases the lack of an
+ assignment operator. Multiple -D options can be specified.
+
+ **'-E'/'--execute' (statement)** -- Execute the Python (not EmPy)
+ statement before processing any files. Multiple -E options can
+ be specified.
+
+ **'-F'/'--execute-file' (filename)** -- Execute the Python (not
+ EmPy) file before processing any files. This is equivalent to
+ '-E execfile("filename")' but provides a more readable context.
+ Multiple -F options can be specified.
+
+ **'-I'/'--import' (module)** -- Imports the specified module name
+ before processing any files. Multiple modules can be specified
+ by separating them by commas, or by specifying multiple -I
+ options.
+
+ **'-P'/'--preprocess' (filename)** -- Process the EmPy file before
+ processing the primary EmPy file on the command line.
+
+ **'--binary'** -- Treat the file as a binary file, and read in
+ chunks rather than line by line. In this mode, the "line"
+ indicator represents the number of bytes read, not the number of
+ lines processed.
+
+ **'--no-prefix'** -- Disable the prefixing system entirely; when
+ specified, EmPy will not expand any markups. This allows EmPy
+ to merely act as a Unicode encoding translator..
+
+ **'--pause-at-end'** -- If present, then 'raw_input' will be
+ called at the end of processing. Useful in systems where the
+ output window would otherwise be closed by the operating
+ system/window manager immediately after EmPy exited.
+
+ **'--relative-path'** -- When present, the path the EmPy script
+ being invoked is contained in will be prepended to 'sys.path'.
+ This is analogous to Python's internal handling of 'sys.path'
+ and scripts. If input is from stdin ('-' for a filename or no
+ filename is specified), then nothing is added to the path.
+
+ **'--no-callback-error'** -- Do not consider it an error if the
+ custom markup is invoked '@<...>' and there is no callback
+ function registered for it.
+
+ **'--chunk-size' (chunk)** -- Use the specific binary chunk size
+ rather than the default; implies --binary.
+
+ **'--unicode-encoding' (encoding)** -- Specify the Unicode
+ encoding to be used for both input and output.
+
+ **'--unicode-input-encoding' (encoding)** -- Specify the Unicode
+ encoding to be used for input.
+
+ **'--unicode-output-encoding' (encoding)** -- Specify the Unicode
+ encoding to be used for output.
+
+ **'--unicode-input-errors (errors)** -- Specify the Unicode error
+ handling to be used for input.
+
+ **'--unicode-errors (errors)** -- Specify the Unicode error
+ handling to be used for both input and output.
+
+ **'--unicode-output-errors (errors)** -- Specify the Unicode error
+ handling to be used for output.
+
+
+Environment variables
+
+ EmPy also supports a few environment variables to predefine
+ certain behaviors. The settings chosen by environment variables
+ can be overridden via command line arguments. The following
+ environment variables have meaning to EmPy:
+
+ **'EMPY_OPTIONS'** -- If present, the contents of this environment
+ variable will be treated as options, just as if they were
+ entered on the command line, *before* the actual command line
+ arguments are processed. Note that these arguments are *not*
+ processed by the shell, so quoting, filename globbing, and the
+ like, will not work.
+
+ **'EMPY_PREFIX'** -- If present, the value of this environment
+ variable represents the prefix that will be used; this is
+ equivalent to the -p command line option.
+
+ **'EMPY_PSEUDO'** -- If present, the value of this environment
+ variable represents the name of the pseudomodule that will be
+ incorporated into every running EmPy system; this is equivalent
+ to the -m command line option.
+
+ **'EMPY_FLATTEN'** -- If defined, this is equivalent to including
+ -f on the command line.
+
+ **'EMPY_RAW_ERRORS'** -- If defined, this is equivalent to
+ including -r on the command line.
+
+ **'EMPY_INTERACTIVE'** -- If defined, this is equivalent to
+ including -i on the command line.
+
+ **'EMPY_BUFFERED_OUTPUT'** -- If defined, this is equivalent to
+ including -b on the command line.
+
+ **'EMPY_UNICODE'** -- If defined, this is equivalent to including
+ -u on the command line.
+
+ **'EMPY_UNICODE_INPUT_ENCODING'** -- If present, the value of this
+ environment variable indicates the name of the Unicode input
+ encoding to be used. This is equivalent to the
+ --unicode-input-encoding command line option.
+
+ **'EMPY_UNICODE_OUTPUT_ENCODING'** -- If present, the value of
+ this environment variable indicates the name of the Unicode
+ output encoding to be used. This is equivalent to the
+ --unicode-output-encoding command line option.
+
+ **'EMPY_UNICODE_INPUT_ERRORS'** -- If present, the value of this
+ environment variable indicates the name of the error handler to
+ be used for input. This is equivalent to the
+ --unicode-input-errors command line option.
+
+ **'EMPY_UNICODE_OUTPUT_ERRORS'** -- If present, the value of this
+ environment variable indicates the name of the error handler to
+ be used for output. This is equivalent to the
+ --unicode-output-errors command line option.
+
+
+Examples and testing EmPy
+
+ See the sample EmPy file 'sample.em' which is included with the
+ distribution. Run EmPy on it by typing something like::
+
+ ./em.py sample.em
+
+ and compare the results and the sample source file side by side.
+ The sample content is intended to be self-documenting, and even an
+ introduction to the basic features of EmPy while simultaneously
+ exercising them.
+
+ The file 'sample.bench' is the benchmark output of the sample.
+ Running the EmPy interpreter on the provided 'sample.em' file
+ should produce precisely the same results. You can run the
+ provided test script to see if your EmPy environment is behaving
+ as expected (presuming a Unix-like operating system)::
+
+ ./test.sh
+
+ By default this will test with the first Python interpreter
+ available in the path; if you want to test with another
+ interpreter, you can provide it as the first argument on the
+ command line, *e.g.*::
+
+ ./test.sh python2.1
+ ./test.sh /usr/bin/python1.5
+ ./test.sh jython
+
+ A more comprehensive test suite and set of real-world examples is
+ planned for a future version.
+
+
+Embedding EmPy
+
+ For atomic applications, the 'expand' function is provided (the
+ extra keyword arguments passed in are treated as locals)::
+
+ import em
+ print em.expand("@x + @y is @(x + y).", x=2, y=3)
+
+ One can specify a globals dictionary and all the other interpreter
+ options (below) as well. One can specify a globals dictionary
+ that will be used if one wants persistence::
+
+ import em
+ g = {}
+ em.expand("@{x = 10}", g)
+ print em.expand("x is @x.", g)
+
+ The standalone 'expand' function, however, creates and destroys an
+ 'Interpreter' instance each time it is called. For repeated
+ expansions, this can be expensive. Instead, you will probably
+ want to use the full-fledged features of embedding. An EmPy
+ interpreter can be created with as code as simple as::
+
+ import em
+ interpreter = em.Interpreter()
+ # The following prints the results to stdout:
+ interpreter.string("@{x = 123}@x\n")
+ # This expands to the same thing, but puts the results as a
+ # string in the variable result:
+ result = interpreter.expand("@{x = 123}@x\n")
+ # This just prints the value of x directly:
+ print interpreter.globals['x']
+ # Process an actual file (and output to stdout):
+ interpreter.file(open('/path/to/some/file'))
+ interpreter.shutdown() # this is important; see below
+
+ One can capture the output of a run in something other than stdout
+ by specifying the *output* parameter::
+
+ import em, StringIO
+ output = StringIO.StringIO()
+ interpreter = em.Interpreter(output=output)
+ # Do something.
+ interpreter.file(open('/path/to/some/file'))
+ interpreter.shutdown() # again, this is important; see below
+ print output.getvalue() # this is the result from the session
+
+ When you are finished with your interpreter, it is important to
+ call its shutdown method::
+
+ interpreter.shutdown()
+
+ This will ensure that the interpreter cleans up all its overhead,
+ entries in the 'sys.stdout' proxy, and so forth. It is usually
+ advisable that this be used in a try...finally clause::
+
+ interpreter = em.Interpreter(...)
+ try:
+ ...
+ finally:
+ interpreter.shutdown()
+
+ The 'em.Interpreter' constructor takes the following arguments;
+ all are optional. Since options may be added in the future, it is
+ highly recommended that the constructor be invoked via keyword
+ arguments, rather than assuming their order. The arguments are:
+
+ *output* -- The output file which the interpreter will be sending
+ all its processed data to. This need only be a file-like object;
+ it need not be an actual file. If omitted, 'sys.__stdout__' is
+ used.
+
+ *argv* -- An argument list analogous to 'sys.argv', consisting of
+ the script name and zero or more arguments. These are available
+ to executing interpreters via 'empy.argv' and 'empy.args'. If
+ omitted, a non-descript script name is used with no arguments.
+
+ *prefix* -- The prefix (a single-character string). Defaults to
+ '@'. It is an error for this to be anything other than one
+ character.
+
+ *pseudo* -- The name (string) of the pseudmodule. Defaults to
+ 'empy'.
+
+ *options* -- A dictionary of options that can override the default
+ behavior of the interpreter. The names of the options are
+ constant names ending in '_OPT' and their defaults are given in
+ 'Interpreter.DEFAULT_OPTIONS'.
+
+ *globals* -- By default, interpreters begin with a pristine
+ dictionary of globals (except, of course, for the 'empy'
+ pseudomodule). Specifying this argument will allow the globals
+ to start with more.
+
+ *hooks* -- A sequence of hooks (or 'None' for none) to register
+ with the interpreter at startup. Hooks can, of course, be added
+ after the fact, but this allows the hooks to intercept the
+ 'atStartup' event (otherwise, the startup event would already
+ have occurred by the time new hooks could be registered)..
+
+ Many things can be done with EmPy interpreters; for the full
+ developer documentation, see the generated documentation for the
+ 'em' module.
+
+
+Interpreter options
+
+ The following options (passed in as part of the options dictionary
+ to the Interpreter constructor) have the following meanings. The
+ defaults are shown below and are also indicated in an
+ 'Interpreter.DEFAULT_OPTIONS' dictionary.
+
+ **'BANGPATH_OPT'** -- Should a bangpath ('#!') as the first line
+ of an EmPy file be treated as if it were an EmPy comment? Note
+ that '#!' sequences starting lines or appearing anywhere else in
+ the file are untouched regardless of the value of this option.
+ Default: true.
+
+ **'BUFFERED_OPT'** -- Should an 'abort' method be called upon
+ failure? This relates to the fully-buffered option, where all
+ output can be buffered including the file open; this option only
+ relates to the interpreter's behavior *after* that proxy file
+ object has been created. Default: false.
+
+ **'RAW_OPT'** -- Should errors be displayed as raw Python errors
+ (that is, the exception is allowed to propagate through to the
+ toplevel so that the user gets a standard Python traceback)?
+ Default: false.
+
+ **'EXIT_OPT'** -- Upon an error, should execution continue
+ (although the interpreter stacks will be purged)? Note that
+ even in the event this is set, the interpreter will halt upon
+ receiving a 'KeyboardInterrupt'. Default: true.
+
+ **'FLATTEN_OPT'** -- Upon initial startup, should the 'empy'
+ pseudomodule namespace be flattened, *i.e.*, should
+ 'empy.flatten' be called? Note this option only has an effect
+ when the interpreter is first created; thereafter it is
+ ignored. Default: false.
+
+ **'OVERRIDE_OPT'** -- Should the 'sys.stdout' object be overridden
+ with a proxy object? If not, side effect output cannot be
+ captured by the EmPy system, but EmPy will support
+ multithreading. Default: true.
+
+ **'CALLBACK_OPT'** -- If a callback is invoked when none has yet
+ been registered, should an error be raised or should the
+ situation be ignored? Default: true.
+
+
+Data flow
+
+ **input -> interpreter -> diversions -> filters -> output**
+
+ Here, in summary, is how data flows through a working EmPy system:
+
+ 1. Input comes from a source, such an .em file on the command
+ line, or via an 'empy.include' statement.
+
+ 2. The interpreter processes this material as it comes in,
+ expanding EmPy expansions as it goes.
+
+ 3. After interpretation, data is then sent through the diversion
+ layer, which may allow it directly through (if no diversion is
+ in progress) or defer it temporarily. Diversions that are
+ recalled initiate from this point.
+
+ 4. Any filters in place are then used to filter the data and
+ produce filtered data as output.
+
+ 5. Finally, any material surviving this far is sent to the output
+ stream. That stream is stdout by default, but can be changed
+ with the -o or -a options, or may be fully buffered with the -b
+ option (that is, the output file would not even be opened until
+ the entire system is finished).
+
+
+Author's notes
+
+ I originally conceived EmPy as a replacement for my "Web
+ templating system", http://www.alcyone.com/max/info/m4.html which
+ uses "m4", http://www.seindal.dk/rene/gnu/ (a general
+ macroprocessing system for Unix).
+
+ Most of my Web sites include a variety of m4 files, some of which
+ are dynamically generated from databases, which are then scanned
+ by a cataloging tool to organize them hierarchically (so that,
+ say, a particular m4 file can understand where it is in the
+ hierarchy, or what the titles of files related to it are without
+ duplicating information); the results of the catalog are then
+ written in database form as an m4 file (which every other m4 file
+ implicitly includes), and then GNU make converts each m4 to an
+ HTML file by processing it.
+
+ As the Web sites got more complicated, the use of m4 (which I had
+ originally enjoyed for the challenge and abstractness) really
+ started to become an impediment to serious work; while I am very
+ knowledgeable about m4 -- having used it for for so many years --
+ getting even simple things done with it is awkward and difficult.
+ Worse yet, as I started to use Python more and more over the
+ years, the cataloging programs which scanned the m4 and built m4
+ databases were migrated to Python and made almost trivial, but
+ writing out huge awkward tables of m4 definitions simply to make
+ them accessible in other m4 scripts started to become almost
+ farcical -- especially when coupled with the difficulty in getting
+ simple things done in m4.
+
+ It occurred to me what I really wanted was an all-Python solution.
+ But replacing what used to be the m4 files with standalone Python
+ programs would result in somewhat awkward programs normally
+ consisting mostly of unprocessed text punctuated by small portions
+ where variables and small amounts of code need to be substituted.
+ Thus the idea was a sort of inverse of a Python interpreter: a
+ program that normally would just pass text through unmolested, but
+ when it found a special signifier would execute Python code in a
+ normal environment. I looked at existing Python templating
+ systems, and didn't find anything that appealed to me -- I wanted
+ something where the desired markups were simple and unobtrusive.
+ After considering between choices of signifiers, I settled on '@'
+ and EmPy was born.
+
+ As I developed the tool, I realized it could have general appeal,
+ even to those with widely varying problems to solve, provided the
+ core tool they needed was an interpreter that could embed Python
+ code inside templated text. As I continue to use the tool, I have
+ been adding features as unintrusively as possible as I see areas
+ that can be improved.
+
+ A design goal of EmPy is that its feature set should work on
+ several levels; at each level, if the user does not wish or need
+ to use features from another level, they are under no obligation
+ to do so. If you have no need of diversions, for instance, you
+ are under no obligation to use them. If significators will not
+ help you organize a set of EmPy scripts globally, then you need
+ not use them. New features that are being added are whenever
+ possible transparently backward compatible; if you do not need
+ them, their introduction should not affect you in any way. The
+ use of unknown prefix sequences results in errors, guaranteeing
+ that they are reserved for future use.
+
+
+Glossary
+
+ **control** -- A control markup, used to direct high-level control
+ flow within an EmPy session. Control markups are expressed with
+ the '@[...]' notation.
+
+ **diversion** -- A process by which output is deferred, and can be
+ recalled later on demand, multiple times if necessary.
+
+ **document** -- The abstraction of an EmPy document as used by a
+ processor.
+
+ **escape** -- A markup designed to expand to a single (usually
+ non-printable) character, similar to escape sequences in C or
+ other languages.
+
+ **expansion** -- The process of processing EmPy markups and
+ producing output.
+
+ **expression** -- An expression markup represents a Python
+ expression to be evaluated, and replaced with the 'str' of its
+ value. Expression markups are expressed with the '@(...)'
+ notation.
+
+ **filter** -- A file-like object which can be chained to other
+ objects (primarily the final stream) and can buffer, alter, or
+ manipulate in any way the data sent. Filters can also be
+ chained together in arbitrary order.
+
+ **globals** -- The dictionary (or dictionary-like object) which
+ resides inside the interpreter and holds the currently-defined
+ variables.
+
+ **hook** -- A callable object that can be registered in a
+ dictionary, and which will be invoked before, during, or after
+ certain internal operations, identified by name with a string.
+
+ **interpreter** -- The application (or class instance) which
+ processes EmPy markup.
+
+ **markup** -- EmPy substitutions set off with a prefix and
+ appropriate delimeters.
+
+ **output** -- The final destination of the result of processing an
+ EmPy file.
+
+ **prefix** -- The ASCII character used to set off an expansions.
+ By default, '@'.
+
+ **processor** -- An extensible system which processes a group of
+ EmPy files, usually arranged in a filesystem, and scans them for
+ significators.
+
+ **pseudomodule** -- The module-like object named 'empy' which is
+ exposed internally inside every EmPy system.
+
+ **shortcut** -- A special object which takes the place of an
+ instance of the 'Filter' class, to represent a special form of
+ filter. These include 0 for a null filter, a callable (function
+ or lambda) to represent a callable filter, or a 256-character
+ string which represents a translation filter.
+
+ **significator** -- A special form of an assignment markup in EmPy
+ which can be easily parsed externally, primarily designed for
+ representing uniform assignment across a collection of files.
+ Significators are indicated with the '@%' markup.
+
+ **statement** -- A line of code that needs to be executed;
+ statements do not have return values. In EmPy, statements are
+ set off with '@{...}'.
+
+
+Acknowledgements
+
+ Questions, suggestions, bug reports, evangelism, and even
+ complaints from many people have helped make EmPy what it is
+ today. Some, but by no means all, of these people are (in
+ alphabetical order by surname):
+
+ - Biswapesh Chattopadhyay
+
+ - Beni Cherniavsky
+
+ - Dr. S. Candelaria de Ram
+
+ - Eric Eide
+
+ - Dinu Gherman
+
+ - Grzegorz Adam Hankiewicz
+
+ - Bohdan Kushnir
+
+ - Robert Kroeger
+
+ - Kouichi Takahashi
+
+ - Ville Vainio
+
+
+Known issues and caveats
+
+ - EmPy was primarily intended for static processing of documents,
+ rather than dynamic use, and hence speed of processing was not
+ the primary consideration in its design.
+
+ - EmPy is not threadsafe by default. This is because of the need
+ for EmPy to override the 'sys.stdout' file with a proxy object
+ which can capture effects of 'print' and other spooling to
+ stdout. This proxy can be suppressed with the -n option, which
+ will result in EmPy being unable to do anything meaningful with
+ this output, but will allow EmPy to be threadsafe.
+
+ - To function properly, EmPy must override 'sys.stdout' with a
+ proxy file object, so that it can capture output of side effects
+ and support diversions for each interpreter instance. It is
+ important that code executed in an environment *not* rebind
+ 'sys.stdout', although it is perfectly legal to invoke it
+ explicitly (*e.g.*, '@sys.stdout.write("Hello world\n")'). If
+ one really needs to access the "true" stdout, then use
+ 'sys.__stdout__' instead (which should also not be rebound).
+ EmPy uses the standard Python error handlers when exceptions are
+ raised in EmPy code, which print to 'sys.stderr'.
+
+ - Due to Python's curious handling of the 'print' statement --
+ particularly the form with a trailing comma to suppress the
+ final newline -- mixing statement expansions using prints inline
+ with unexpanded text will often result in surprising behavior,
+ such as extraneous (sometimes even deferred!) spaces. This is a
+ Python "feature," and occurs in non-EmPy applications as well;
+ for finer control over output formatting, use 'sys.stdout.write'
+ or 'empy.interpreter.write' directly.
+
+ - The 'empy' "module" exposed through the EmPy interface (*e.g.*,
+ '@empy') is an artificial module. It cannot be imported with
+ the 'import' statement (and shouldn't -- it is an artifact of
+ the EmPy processing system and does not correspond to any
+ accessible .py file).
+
+ - For an EmPy statement expansion all alone on a line, *e.g.*,
+ '@{a = 1}', note that this will expand to a blank line due to
+ the newline following the closing curly brace. To suppress this
+ blank line, use the symmetric convention '@{a = 1}@'.
+
+ - When using EmPy with make, note that partial output may be
+ created before an error occurs; this is a standard caveat when
+ using make. To avoid this, write to a temporary file and move
+ when complete, delete the file in case of an error, use the -b
+ option to fully buffer output (including the open), or (with GNU
+ make) define a '.DELETE_ON_ERROR' target.
+
+ - 'empy.identify' tracks the context of executed *EmPy* code, not
+ Python code. This means that blocks of code delimited with '@{'
+ and '}' will identify themselves as appearing on the line at
+ which the '}' appears, and that pure Python code executed via
+ the -D, -E and -F command line arguments will show up as all taking
+ place on line 1. If you're tracking errors and want more
+ information about the location of the errors from the Python
+ code, use the -r command line option, which will provide you
+ with the full Python traceback.
+
+ - The conditional form of expression expansion '@(...?...!...)'
+ allows the use of a colon instead of an exclamation point,
+ *e.g.*, '@(...?...:...)'. This behavior is supported for
+ backward compatibility, but is deprecated. Due to an oversight,
+ the colon was a poor choice since colons can appear legally in
+ expressions (*e.g.*, dictionary literals or lambda expressions).
+
+ - The '@[try]' construct only works with Python exceptions derived
+ from 'Exception'. It is not able to catch string exceptions.
+
+ - The '@[for]' variable specification supports tuples for tuple
+ unpacking, even recursive tuples. However, it is limited in
+ that the names included may only be valid Python identifiers,
+ not arbitrary Python lvalues. Since the internal Python
+ mechanism is very rarely used for this purpose (*e.g.*, 'for (x,
+ l[0], q.a) in sequence'), it is not thought to be a significant
+ limitation.
+
+
+Wish list
+
+ Here are some random ideas for future revisions of EmPy. If any
+ of these are of particular interest to you, your input would be
+ appreciated.
+
+ - Some real-world examples should really be included for
+ demonstrating the power and expressiveness of EmPy first-hand.
+
+ - More extensive help (rather than a ridiculously long README),
+ probably inherently using the EmPy system itself for building to
+ HTML and other formats, thereby acting as a help facility and a
+ demonstration of the working system.
+
+ - A "trivial" mode, where all the EmPy system does is scan for
+ simple symbols to replace them with evaluations/executions,
+ rather than having to do the contextual scanning it does now.
+ This has the down side of being much less configurable and
+ powerful but the upside of being extremely efficient.
+
+ - A "debug" mode, where EmPy prints the contents of everything
+ it's about to evaluate (probably to stderr) before it does?
+
+ - The ability to funnel all code through a configurable 'RExec'
+ for user-controlled security control. This would probably
+ involve abstracting the execution functionality outside of the
+ interpreter. [This suggestion is on hold until the
+ rexec/Bastion exploits are worked out.]
+
+ - Optimized handling of processing would be nice for the
+ possibility of an Apache module devoted to EmPy processing.
+
+ - An EmPy emacs mode.
+
+ - An optimization of offloading diversions to files when they
+ become truly huge. (This is made possible by the abstraction of
+ the 'Diversion' class.)
+
+ - Support for mapping filters (specified by dictionaries).
+
+ - Support for some sort of batch processing, where several EmPy
+ files can be listed at once and all of them evaluated with the
+ same initial (presumably expensive) environment.
+ 'empy.saveGlobals' and 'empy.restoreGlobals' have been
+ introduced as a partial solution, but they need to be made more
+ robust.
+
+ - A more elaborate interactive mode, perhaps with a prompt and
+ readline support.
+
+ - A StructuredText and/or reStructuredText filter would be quite
+ useful, as would SGML/HTML/XML/XHTML, s-expression, Python,
+ etc. auto-indenter filters.
+
+ - An indexing filter, which can process text and pick out
+ predefined keywords and thereby setup links to them.
+
+ - The ability to rerun diverted material back through the
+ interpreter. (This can be done, awkwardly, by manually creating
+ a filter which itself contains an interpreter, but it might be
+ helpful if this was an all-in-one operation.)
+
+ - A caching system that stores off the compilations of repeated
+ evaluations and executions so that in a persistent environment
+ the same code does not have to be repeatedly evaluated/executed.
+ This would probably be a necessity in an Apache module-based
+ solution. Perhaps caching even to the point of generating pure
+ PyWM bytecode?
+
+ - An option to change the format of the standard EmPy errors in a
+ traceback.
+
+ - Support for some manner of implicitly processed /etc/empyrc
+ and/or ~/.empyrc file, and of course an option to inhibit its
+ processing. This can already be accomplished (and with greater
+ control) via use of EMPY_OPTIONS, though.
+
+ - More uniform handling of the preprocessing directives (-I, -D,
+ -E, -F, and -P), probably mapping directly to methods in the
+ 'Interpreter' class.
+
+ - Support for integration with mod_python.
+
+ - In simple expressions, a '{...}' suffix has no meaning in Python
+ (*e.g.*, in Python, '@x(...)' is a call, '@x[...]' is
+ subscription, but '@x{...}' is illegal). This could be
+ exploited by having a '{...}' suffix in a simple expression
+ representing an encapsulation of an expanded string; *e.g.*,
+ '@bullet{There are @count people here}' would be equivalent to
+ '@bullet(empy.expand("There are @count people here",
+ locals()))}'.
+
+ - A tool to collect significator information from a hierarchy of
+ .em files and put them in a database form available for
+ individual scripts would be extremely useful -- this tool should
+ be extensible so that users can use it to, say, build ordered
+ hierarchies of their EmPy files by detecting contextual
+ information like application-specific links to other EmPy
+ documents.
+
+ - Extensions of the basic EmPy concepts to projects for other
+ interpreted languages, such as Java, Lua, Ruby, and/or Perl.
+
+ - Ignore 'SystemExit' when doing error handling, letting the
+ exception progagate up? So far no one seems to worry about
+ this; deliberately exiting early in a template seems to be an
+ unlikely occurrence. (Furthermore, there are the 'os.abort' and
+ 'os._exit' facilities for terminating without exception
+ propagation.)
+
+ - A new markup which is the equivalent of '$...:...$' in source
+ control systems, where the left-hand portion represents a
+ keyword and the right-hand portion represents its value which is
+ substituted in by the EmPy system.
+
+ - The ability to obtain the filename (if relevant) and mode of the
+ primary output file.
+
+ - The ability to redirect multiple streams of output; not
+ diversions, but rather the ability to write to one file and then
+ another. Since output would be under the EmPy script's control,
+ this would imply a useful --no-output option, where by default
+ no output is written. This would also suggest the usefulness of
+ all the output file delegates (diversions, filters, abstract
+ files, etc.) passing unrecognized method calls all the way down
+ to underlying file object.
+
+ - In addition to the em.py script, an additional support library
+ (non-executable) should be included which includes ancillary
+ functionality for more advanced features, but which is not
+ necessary to use EmPy in its basic form as a standalone
+ executable. Such features would include things like
+ significator processing, metadata scanning, and advanced
+ prompting systems.
+
+
+Release history
+
+ - 3.3.2; 2014 Jan 24. Additional fix for source compatibility
+ between 2.x and 3.0.
+
+ - 3.3.1; 2014 Jan 22. Source compatibility for 2.x and 3.0;
+ 1.x and Jython compatibility dropped.
+
+ - 3.3; 2003 Oct 27. Custom markup '@<...>'; remove separate
+ pseudomodule instance for greater transparency; deprecate
+ 'interpreter' attribute of pseudomodule; deprecate auxiliary
+ class name attributes associated with pseudomodule in
+ preparation for separate support library in 4.0; add
+ --no-callback-error and --no-bangpath-processing command line
+ options; add 'atToken' hook.
+
+ - 3.2; 2003 Oct 7. Reengineer hooks support to use hook
+ instances; add -v option; add --relative-path option; reversed
+ PEP 317 style; modify Unicode support to give less confusing
+ errors in the case of unknown encodings and error handlers;
+ relicensed under LGPL.
+
+ - 3.1.1; 2003 Sep 20. Add literal '@"..."' markup; add
+ --pause-at-end command line option; fix improper globals
+ collision error via the 'sys.stdout' proxy.
+
+ - 3.1; 2003 Aug 8. Unicode support (Python 2.0 and above); add
+ Document and Processor helper classes for processing
+ significators; add --no-prefix option for suppressing all
+ markups.
+
+ - 3.0.4; 2003 Aug 7. Implement somewhat more robust lvalue
+ parsing for '@[for]' construct (thanks to Beni Cherniavsky for
+ inspiration).
+
+ - 3.0.3; 2003 Jul 9. Fix bug regarding recursive tuple unpacking
+ using '@[for]'; add 'empy.saveGlobals', 'empy.restoreGlobals',
+ and 'empy.defined' functions.
+
+ - 3.0.2; 2003 Jun 19. '@?' and '@!' markups for changing the
+ current context name and line, respectively; add 'update' method
+ to interpreter; new and renamed context operations,
+ 'empy.setContextName', 'empy.setContextLine',
+ 'empy.pushContext', 'empy.popContext'.
+
+ - 3.0.1; 2003 Jun 9. Fix simple bug preventing command line
+ preprocessing directives (-I, -D, -E, -F, -P) from executing
+ properly; defensive PEP 317 compliance [defunct].
+
+ - 3.0; 2003 Jun 1. Control markups with '@[...]'; remove
+ substitutions (use control markups instead); support
+ '@(...?...!...)' for conditional expressions in addition to the
+ now-deprecated '@(...?...:...)' variety; add acknowledgements
+ and glossary sections to documentation; rename buffering option
+ back to -b; add -m option and 'EMPY_PSEUDO' environment variable
+ for changing the pseudomodule name; add -n option and
+ 'EMPY_NO_OVERRIDE' environment variable for suppressing
+ 'sys.stdout' proxy; rename main error class to 'Error'; add
+ standalone 'expand' function; add --binary and --chunk-size
+ options; reengineer parsing system to use Tokens for easy
+ extensibility; safeguard curly braces in simple expressions
+ (meaningless in Python and thus likely a typographical error) by
+ making them a parse error; fix bug involving custom Interpreter
+ instances ignoring globals argument; distutils support.
+
+ - 2.3; 2003 Feb 20. Proper and full support for concurrent and
+ recursive interpreters; protection from closing the true stdout
+ file object; detect edge cases of interpreter globals or
+ 'sys.stdout' proxy collisions; add globals manipulation
+ functions 'empy.getGlobals', 'empy.setGlobals', and
+ 'empy.updateGlobals' which properly preserve the 'empy'
+ pseudomodule; separate usage info out into easily accessible
+ lists for easier presentation; have -h option show simple usage
+ and -H show extened usage; add 'NullFile' utility class.
+
+ - 2.2.6; 2003 Jan 30. Fix a bug in the 'Filter.detach' method
+ (which would not normally be called anyway).
+
+ - 2.2.5; 2003 Jan 9. Strip carriage returns out of executed code
+ blocks for DOS/Windows compatibility.
+
+ - 2.2.4; 2002 Dec 23. Abstract Filter interface to use methods
+ only; add '@[noop: ...]' substitution for completeness and block
+ commenting [defunct].
+
+ - 2.2.3; 2002 Dec 16. Support compatibility with Jython by
+ working around a minor difference between CPython and Jython in
+ string splitting.
+
+ - 2.2.2; 2002 Dec 14. Include better docstrings for pseudomodule
+ functions; segue to a dictionary-based options system for
+ interpreters; add 'empy.clearAllHooks' and 'empy.clearGlobals';
+ include a short documentation section on embedding interpreters;
+ fix a bug in significator regular expression.
+
+ - 2.2.1; 2002 Nov 30. Tweak test script to avoid writing
+ unnecessary temporary file; add 'Interpreter.single' method;
+ expose 'evaluate', 'execute', 'substitute' [defunct], and
+ 'single' methods to the pseudomodule; add (rather obvious)
+ 'EMPY_OPTIONS' environment variable support; add
+ 'empy.enableHooks' and 'empy.disableHooks'; include optimization
+ to transparently disable hooks until they are actually used.
+
+ - 2.2; 2002 Nov 21. Switched to -V option for version
+ information; 'empy.createDiversion' for creating initially empty
+ diversion; direct access to diversion objects with
+ 'empy.retrieveDiversion'; environment variable support; removed
+ --raw long argument (use --raw-errors instead); added quaternary
+ escape code (well, why not).
+
+ - 2.1; 2002 Oct 18. 'empy.atExit' registry separate from hooks to
+ allow for normal interpreter support; include a benchmark sample
+ and test.sh verification script; expose 'empy.string' directly;
+ -D option for explicit defines on command line; remove
+ ill-conceived support for '@else:' separator in '@[if ...]'
+ substitution [defunct] ; handle nested substitutions properly
+ [defunct] ; '@[macro ...]' substitution for creating recallable
+ expansions [defunct].
+
+ - 2.0.1; 2002 Oct 8. Fix missing usage information; fix
+ after_evaluate hook not getting called; add 'empy.atExit' call
+ to register values.
+
+ - 2.0; 2002 Sep 30. Parsing system completely revamped and
+ simplified, eliminating a whole class of context-related bugs;
+ builtin support for buffered filters; support for registering
+ hooks; support for command line arguments; interactive mode with
+ -i; significator value extended to be any valid Python
+ expression.
+
+ - 1.5.1; 2002 Sep 24. Allow '@]' to represent unbalanced close
+ brackets in '@[...]' markups [defunct].
+
+ - 1.5; 2002 Sep 18. Escape codes ('@\...'); conditional and
+ repeated expansion substitutions [defunct] ; replaced with control
+ markups]; fix a few bugs involving files which do not end in
+ newlines.
+
+ - 1.4; 2002 Sep 7. Fix bug with triple quotes; collapse
+ conditional and protected expression syntaxes into the single
+ generalized '@(...)' notation; 'empy.setName' and 'empy.setLine'
+ functions [deprecated] ; true support for multiple concurrent
+ interpreters with improved sys.stdout proxy; proper support for
+ 'empy.expand' to return a string evaluated in a subinterpreter
+ as intended; merged Context and Parser classes together, and
+ separated out Scanner functionality.
+
+ - 1.3; 2002 Aug 24. Pseudomodule as true instance; move toward
+ more verbose (and clear) pseudomodule functions; fleshed out
+ diversion model; filters; conditional expressions; protected
+ expressions; preprocessing with -P (in preparation for
+ possible support for command line arguments).
+
+ - 1.2; 2002 Aug 16. Treat bangpaths as comments; 'empy.quote' for
+ the opposite process of 'empy.expand'; significators ('@%...'
+ sequences); -I option; -f option; much improved documentation.
+
+ - 1.1.5; 2002 Aug 15. Add a separate 'invoke' function that can be
+ called multiple times with arguments to simulate multiple runs.
+
+ - 1.1.4; 2002 Aug 12. Handle strings thrown as exceptions
+ properly; use getopt to process command line arguments; cleanup
+ file buffering with AbstractFile; very slight documentation and
+ code cleanup.
+
+ - 1.1.3; 2002 Aug 9. Support for changing the prefix from within
+ the 'empy' pseudomodule.
+
+ - 1.1.2; 2002 Aug 5. Renamed buffering option [defunct], added -F
+ option for interpreting Python files from the command line,
+ fixed improper handling of exceptions from command line options
+ (-E, -F).
+
+ - 1.1.1; 2002 Aug 4. Typo bugfixes; documentation clarification.
+
+ - 1.1; 2002 Aug 4. Added option for fully buffering output
+ (including file opens), executing commands through the command
+ line; some documentation errors fixed.
+
+ - 1.0; 2002 Jul 23. Renamed project to EmPy. Documentation and
+ sample tweaks; added 'empy.flatten'. Added -a option.
+
+ - 0.3; 2002 Apr 14. Extended "simple expression" syntax,
+ interpreter abstraction, proper context handling, better error
+ handling, explicit file inclusion, extended samples.
+
+ - 0.2; 2002 Apr 13. Bugfixes, support non-expansion of Nones,
+ allow choice of alternate prefix.
+
+ - 0.1.1; 2002 Apr 12. Bugfixes, support for Python 1.5.x, add -r
+ option.
+
+ - 0.1; 2002 Apr 12. Initial early access release.
+
+
+Author
+
+ This module was written by "Erik Max Francis",
+ http://www.alcyone.com/max/. If you use this software, have
+ suggestions for future releases, or bug reports, "I'd love to hear
+ about it", mailto:software@alcyone.com.
+
+ Even if you try out EmPy for a project and find it unsuitable, I'd
+ like to know what stumbling blocks you ran into so they can
+ potentially be addressed in a future version.
+
+
+Version
+
+ Version 3.3.2 $Date: 2014-01-24 13:39:38 -0800 (Fri, 24 Jan 2014) $ $Author: max $
--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html40/loose.dtd">
+
+<html>
+
+ <head>
+ <title>Module: em</title>
+ </head>
+
+ <body bgcolor="#ffffff">
+
+ <p><i><a href="../../../../../index.html">Table of Contents</a></i></p>
+
+ <table border="0" cellpadding="5" cellspacing="0" width="100%">
+ <tr>
+ <th rowspan="2"
+ valign="top"
+ align="left"
+ width="10%"
+ bgcolor="#88bbee"><font color="#000000">Module: em</font>
+ </th>
+ <th bgcolor="#88bbee"
+ width="90%"
+ align="right"><font color="#000000">em.py</font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<p>A system for processing Python as markup embedded in text.</p>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Imported modules">Imported modules</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<b>import</b> <a href="http://www.python.org/doc/current/lib/module-copy.html">copy</a><br>
+<b>import</b> <a href="http://www.python.org/doc/current/lib/module-getopt.html">getopt</a><br>
+<b>import</b> <a href="http://www.python.org/doc/current/lib/module-os.html">os</a><br>
+<b>import</b> <a href="http://www.python.org/doc/current/lib/module-re.html">re</a><br>
+<b>import</b> <a href="http://www.python.org/doc/current/lib/module-string.html">string</a><br>
+<b>import</b> <a href="http://www.python.org/doc/current/lib/module-sys.html">sys</a><br>
+<b>import</b> <a href="http://www.python.org/doc/current/lib/module-types.html">types</a><br>
+
+</td></tr>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Functions">Functions</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<a href="#environment">environment</a><br>
+<a href="#expand">expand</a><br>
+<a href="#info">info</a><br>
+<a href="#invoke">invoke</a><br>
+<a href="#main">main</a><br>
+<a href="#usage">usage</a><br>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="environment"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">environment </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+environment ( name, default=None )
+
+</pre></font>
+
+<p>Get data from the current environment. If the default is True
+ or False, then presume that we're only interested in the existence
+ or non-existence of the environment variable.</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="expand"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">expand </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+expand (
+ _data,
+ _globals=None,
+ _argv=None,
+ _prefix=DEFAULT_PREFIX,
+ _pseudo=None,
+ _options=None,
+ **_locals,
+ )
+
+</pre></font>
+
+<p>Do an atomic expansion of the given source data, creating and
+ shutting down an interpreter dedicated to the task. The sys.stdout
+ object is saved off and then replaced before this function
+ returns.</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="info"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">info </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+info ( table )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="invoke"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">invoke </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+invoke ( args )
+
+</pre></font>
+
+<p>Run a standalone instance of an EmPy interpeter.</p>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Exceptions">Exceptions</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+Error, "prefix must be single-character string"<br>
+ValueError, "-b only makes sense with -o or -a arguments"<br>
+
+</td></tr>
+</table>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="main"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">main </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+main ()
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="usage"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">usage </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+usage ( verbose=True )
+
+</pre></font>
+
+<p>Print usage information.</p>
+</td></tr>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Classes">Classes</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<table border="0" cellpadding="3" cellspacing="0">
+<tr><td valign="top" align="left"><p><a href="em/AbstractFile.html">AbstractFile</a></p></td><td valign="top" align="left">
+<p>An abstracted file that, when buffered, will totally buffer the</p>
+</td></tr>
+<tr><td valign="top" align="left"><p><a href="em/BreakFlow.html">BreakFlow</a></p></td><td valign="top" align="left">
+<p>A break control flow.</p>
+</td></tr>
+<tr><td valign="top" align="left"><p><a href="em/BufferedFilter.html">BufferedFilter</a></p></td><td valign="top" align="left">
+<p>A buffered filter is one that doesn't modify the source data</p>
+</td></tr>
+<tr><td valign="top" align="left"><p><a href="em/CommentToken.html">CommentToken</a></p></td><td valign="top" align="left">
+<p>A comment markup.</p>
+</td></tr>
+<tr><td valign="top" align="left"><p><a href="em/Context.html">Context</a></p></td><td valign="top" align="left">
+<p>An interpreter context, which encapsulates a name, an input</p>
+</td></tr>
+<tr><td valign="top" align="left"><p><a href="em/ContextLineToken.html">ContextLineToken</a></p></td><td valign="top" align="left">
+<p>A context line change markup.</p>
+</td></tr>
+<tr><td valign="top" align="left"><p><a href="em/ContextNameToken.html">ContextNameToken</a></p></td><td valign="top" align="left">
+<p>A context name change markup.</p>
+</td></tr>
+<tr><td valign="top" align="left"><p><a href="em/ContinueFlow.html">ContinueFlow</a></p></td><td valign="top" align="left">
+<p>A continue control flow.</p>
+</td></tr>
+<tr><td valign="top" align="left"><p><a href="em/ControlToken.html">ControlToken</a></p></td><td valign="top" align="left">
+<p>A control token.</p>
+</td></tr>
+<tr><td valign="top" align="left"><p><a href="em/CustomToken.html">CustomToken</a></p></td><td valign="top" align="left">
+<p>A custom markup.</p>
+</td></tr>
+<tr><td valign="top" align="left"><p><a href="em/Diversion.html">Diversion</a></p></td><td valign="top" align="left">
+<p>The representation of an active diversion. Diversions act as</p>
+</td></tr>
+<tr><td valign="top" align="left"><p><a href="em/DiversionError.html">DiversionError</a></p></td><td valign="top" align="left">
+<p>An error related to diversions.</p>
+</td></tr>
+<tr><td valign="top" align="left"><p><a href="em/Document.html">Document</a></p></td><td valign="top" align="left">
+<p>A representation of an individual EmPy document, as used by a</p>
+</td></tr>
+<tr><td valign="top" align="left"><p><a href="em/Error.html">Error</a></p></td><td valign="top" align="left">
+<p>The base class for all EmPy errors.</p>
+</td></tr>
+<tr><td valign="top" align="left"><p><a href="em/EscapeToken.html">EscapeToken</a></p></td><td valign="top" align="left">
+<p>An escape markup.</p>
+</td></tr>
+<tr><td valign="top" align="left"><p><a href="em/ExpansionToken.html">ExpansionToken</a></p></td><td valign="top" align="left">
+<p>A token that involves an expansion.</p>
+</td></tr>
+<tr><td valign="top" align="left"><p><a href="em/ExpressionToken.html">ExpressionToken</a></p></td><td valign="top" align="left">
+<p>An expression markup.</p>
+</td></tr>
+<tr><td valign="top" align="left"><p><a href="em/Filter.html">Filter</a></p></td><td valign="top" align="left">
+<p>An abstract filter.</p>
+</td></tr>
+<tr><td valign="top" align="left"><p><a href="em/FilterError.html">FilterError</a></p></td><td valign="top" align="left">
+<p>An error related to filters.</p>
+</td></tr>
+<tr><td valign="top" align="left"><p><a href="em/FlowError.html">FlowError</a></p></td><td valign="top" align="left">
+<p>An exception related to control flow.</p>
+</td></tr>
+<tr><td valign="top" align="left"><p><a href="em/FunctionFilter.html">FunctionFilter</a></p></td><td valign="top" align="left">
+<p>A filter that works simply by pumping its input through a</p>
+</td></tr>
+<tr><td valign="top" align="left"><p><a href="em/Hook.html">Hook</a></p></td><td valign="top" align="left">
+<p>The base class for implementing hooks.</p>
+</td></tr>
+<tr><td valign="top" align="left"><p><a href="em/InPlaceToken.html">InPlaceToken</a></p></td><td valign="top" align="left">
+<p>An in-place markup.</p>
+</td></tr>
+<tr><td valign="top" align="left"><p><a href="em/Interpreter.html">Interpreter</a></p></td><td valign="top" align="left">
+<p>An interpreter can process chunks of EmPy code.</p>
+</td></tr>
+<tr><td valign="top" align="left"><p><a href="em/LineBufferedFilter.html">LineBufferedFilter</a></p></td><td valign="top" align="left">
+<p>A line-buffered filter only lets data through when it sees</p>
+</td></tr>
+<tr><td valign="top" align="left"><p><a href="em/LiteralToken.html">LiteralToken</a></p></td><td valign="top" align="left">
+<p>A literal markup.</p>
+</td></tr>
+<tr><td valign="top" align="left"><p><a href="em/MaximallyBufferedFilter.html">MaximallyBufferedFilter</a></p></td><td valign="top" align="left">
+<p>A maximally-buffered filter only lets its data through on the final</p>
+</td></tr>
+<tr><td valign="top" align="left"><p><a href="em/MetaError.html">MetaError</a></p></td><td valign="top" align="left">
+<p>A wrapper around a real Python exception for including a copy of</p>
+</td></tr>
+<tr><td valign="top" align="left"><p><a href="em/NullFile.html">NullFile</a></p></td><td valign="top" align="left">
+<p>A simple class that supports all the file-like object methods</p>
+</td></tr>
+<tr><td valign="top" align="left"><p><a href="em/NullFilter.html">NullFilter</a></p></td><td valign="top" align="left">
+<p>A filter that never sends any output to its sink.</p>
+</td></tr>
+<tr><td valign="top" align="left"><p><a href="em/NullToken.html">NullToken</a></p></td><td valign="top" align="left">
+<p>A chunk of data not containing markups.</p>
+</td></tr>
+<tr><td valign="top" align="left"><p><a href="em/ParseError.html">ParseError</a></p></td><td valign="top" align="left">
+<p>A parse error occurred.</p>
+</td></tr>
+<tr><td valign="top" align="left"><p><a href="em/PrefixToken.html">PrefixToken</a></p></td><td valign="top" align="left">
+<p>A prefix markup.</p>
+</td></tr>
+<tr><td valign="top" align="left"><p><a href="em/Processor.html">Processor</a></p></td><td valign="top" align="left">
+<p>An entity which is capable of processing a hierarchy of EmPy</p>
+</td></tr>
+<tr><td valign="top" align="left"><p><a href="em/ProxyFile.html">ProxyFile</a></p></td><td valign="top" align="left">
+<p>The proxy file object that is intended to take the place of</p>
+</td></tr>
+<tr><td valign="top" align="left"><p><a href="em/ReprToken.html">ReprToken</a></p></td><td valign="top" align="left">
+<p>A repr markup.</p>
+</td></tr>
+<tr><td valign="top" align="left"><p><a href="em/Scanner.html">Scanner</a></p></td><td valign="top" align="left">
+<p>A scanner holds a buffer for lookahead parsing and has the</p>
+</td></tr>
+<tr><td valign="top" align="left"><p><a href="em/SignificatorToken.html">SignificatorToken</a></p></td><td valign="top" align="left">
+<p>A significator markup.</p>
+</td></tr>
+<tr><td valign="top" align="left"><p><a href="em/SimpleExpressionToken.html">SimpleExpressionToken</a></p></td><td valign="top" align="left">
+<p>A simple expression markup.</p>
+</td></tr>
+<tr><td valign="top" align="left"><p><a href="em/SizeBufferedFilter.html">SizeBufferedFilter</a></p></td><td valign="top" align="left">
+<p>A size-buffered filter only in fixed size chunks (excepting the</p>
+</td></tr>
+<tr><td valign="top" align="left"><p><a href="em/Stack.html">Stack</a></p></td><td valign="top" align="left">
+<p>A simple stack that behaves as a sequence (with 0 being the top</p>
+</td></tr>
+<tr><td valign="top" align="left"><p><a href="em/StackUnderflowError.html">StackUnderflowError</a></p></td><td valign="top" align="left">
+<p>A stack underflow.</p>
+</td></tr>
+<tr><td valign="top" align="left"><p><a href="em/StatementToken.html">StatementToken</a></p></td><td valign="top" align="left">
+<p>A statement markup.</p>
+</td></tr>
+<tr><td valign="top" align="left"><p><a href="em/Stream.html">Stream</a></p></td><td valign="top" align="left">
+<p>A wrapper around an (output) file object which supports</p>
+</td></tr>
+<tr><td valign="top" align="left"><p><a href="em/StringFilter.html">StringFilter</a></p></td><td valign="top" align="left">
+<p>A filter that takes a translation string (256 characters) and</p>
+</td></tr>
+<tr><td valign="top" align="left"><p><a href="em/StringLiteralToken.html">StringLiteralToken</a></p></td><td valign="top" align="left">
+<p>A string token markup.</p>
+</td></tr>
+<tr><td valign="top" align="left"><p><a href="em/Subsystem.html">Subsystem</a></p></td><td valign="top" align="left">
+<p>The subsystem class defers file creation so that it can create</p>
+</td></tr>
+<tr><td valign="top" align="left"><p><a href="em/SubsystemError.html">SubsystemError</a></p></td><td valign="top" align="left">
+<p>An error associated with the Unicode subsystem.</p>
+</td></tr>
+<tr><td valign="top" align="left"><p><a href="em/Token.html">Token</a></p></td><td valign="top" align="left">
+<p>An element of expansion.</p>
+</td></tr>
+<tr><td valign="top" align="left"><p><a href="em/TransientParseError.html">TransientParseError</a></p></td><td valign="top" align="left">
+<p>A parse error occurred which may be resolved by feeding more data.</p>
+</td></tr>
+<tr><td valign="top" align="left"><p><a href="em/UncloseableFile.html">UncloseableFile</a></p></td><td valign="top" align="left">
+<p>A simple class which wraps around a delegate file-like object</p>
+</td></tr>
+<tr><td valign="top" align="left"><p><a href="em/VerboseHook.html">VerboseHook</a></p></td><td valign="top" align="left">
+<p>A verbose hook that reports all information received by the</p>
+</td></tr>
+<tr><td valign="top" align="left"><p><a href="em/WhitespaceToken.html">WhitespaceToken</a></p></td><td valign="top" align="left">
+<p>A whitespace markup.</p>
+</td></tr>
+</table>
+</td></tr>
+</td></tr>
+</table>
+
+ </td>
+ </tr>
+ </table>
+
+ <hr>
+
+ <p><i><a href="../../../../../index.html">Table of Contents</a></i></p>
+
+ <font size="-2"><i>This document was automatically generated
+ on Mon Oct 27 01:29:13 2003 by
+ <a href="http://happydoc.sourceforge.net">HappyDoc</a> version
+ 2.1</i></font>
+
+ </body>
+ </html>
+
\ No newline at end of file
--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html40/loose.dtd">
+
+<html>
+
+ <head>
+ <title>Class: AbstractFile</title>
+ </head>
+
+ <body bgcolor="#ffffff">
+
+ <p><i><a href="../../../../../../index.html">Table of Contents</a></i></p>
+
+ <table border="0" cellpadding="5" cellspacing="0" width="100%">
+ <tr>
+ <th rowspan="2"
+ valign="top"
+ align="left"
+ width="10%"
+ bgcolor="#88bbee"><font color="#000000">Class: AbstractFile</font>
+ </th>
+ <th bgcolor="#88bbee"
+ width="90%"
+ align="right"><font color="#000000">em.py</font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<p>An abstracted file that, when buffered, will totally buffer the
+ file, including even the file open.</p>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Methods">Methods</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<a href="#__del__">__del__</a><br>
+<a href="#__init__">__init__</a><br>
+<a href="#abort">abort</a><br>
+<a href="#close">close</a><br>
+<a href="#commit">commit</a><br>
+<a href="#flush">flush</a><br>
+<a href="#write">write</a><br>
+<a href="#writelines">writelines</a><br>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="__del__"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">__del__ </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+__del__ ( self )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="__init__"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">__init__ </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+__init__ (
+ self,
+ filename,
+ mode='w',
+ buffered=False,
+ )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="abort"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">abort </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+abort ( self )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="close"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">close </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+close ( self )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="commit"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">commit </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+commit ( self )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="flush"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">flush </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+flush ( self )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="write"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">write </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+write ( self, data )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="writelines"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">writelines </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+writelines ( self, data )
+
+</pre></font>
+
+</td></tr>
+</td></tr>
+</table>
+
+ </td>
+ </tr>
+ </table>
+
+ <hr>
+
+ <p><i><a href="../../../../../../index.html">Table of Contents</a></i></p>
+
+ <font size="-2"><i>This document was automatically generated
+ on Mon Oct 27 01:29:13 2003 by
+ <a href="http://happydoc.sourceforge.net">HappyDoc</a> version
+ 2.1</i></font>
+
+ </body>
+ </html>
+
\ No newline at end of file
--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html40/loose.dtd">
+
+<html>
+
+ <head>
+ <title>Class: BreakFlow</title>
+ </head>
+
+ <body bgcolor="#ffffff">
+
+ <p><i><a href="../../../../../../index.html">Table of Contents</a></i></p>
+
+ <table border="0" cellpadding="5" cellspacing="0" width="100%">
+ <tr>
+ <th rowspan="2"
+ valign="top"
+ align="left"
+ width="10%"
+ bgcolor="#88bbee"><font color="#000000">Class: BreakFlow</font>
+ </th>
+ <th bgcolor="#88bbee"
+ width="90%"
+ align="right"><font color="#000000">em.py</font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<p>A break control flow.</p>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Base Classes">Base Classes</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<a href="FlowError.html">FlowError</a><br>
+<ul>
+
+<a href="Error.html">Error</a><br>
+<ul>
+
+Exception<br>
+
+</ul>
+
+</ul>
+
+</td></tr>
+</table>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+</td></tr>
+</table>
+
+ </td>
+ </tr>
+ </table>
+
+ <hr>
+
+ <p><i><a href="../../../../../../index.html">Table of Contents</a></i></p>
+
+ <font size="-2"><i>This document was automatically generated
+ on Mon Oct 27 01:29:13 2003 by
+ <a href="http://happydoc.sourceforge.net">HappyDoc</a> version
+ 2.1</i></font>
+
+ </body>
+ </html>
+
\ No newline at end of file
--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html40/loose.dtd">
+
+<html>
+
+ <head>
+ <title>Class: BufferedFilter</title>
+ </head>
+
+ <body bgcolor="#ffffff">
+
+ <p><i><a href="../../../../../../index.html">Table of Contents</a></i></p>
+
+ <table border="0" cellpadding="5" cellspacing="0" width="100%">
+ <tr>
+ <th rowspan="2"
+ valign="top"
+ align="left"
+ width="10%"
+ bgcolor="#88bbee"><font color="#000000">Class: BufferedFilter</font>
+ </th>
+ <th bgcolor="#88bbee"
+ width="90%"
+ align="right"><font color="#000000">em.py</font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<p>A buffered filter is one that doesn't modify the source data
+ sent to the sink, but instead holds it for a time. The standard
+ variety only sends the data along when it receives a flush
+ command.</p>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Base Classes">Base Classes</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<a href="Filter.html">Filter</a><br>
+
+</td></tr>
+</table>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Methods">Methods</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<a href="#__init__">__init__</a><br>
+<a href="#flush">flush</a><br>
+<a href="#write">write</a><br>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="__init__"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">__init__ </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+__init__ ( self )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="flush"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">flush </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+flush ( self )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="write"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">write </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+write ( self, data )
+
+</pre></font>
+
+</td></tr>
+</td></tr>
+</table>
+
+ </td>
+ </tr>
+ </table>
+
+ <hr>
+
+ <p><i><a href="../../../../../../index.html">Table of Contents</a></i></p>
+
+ <font size="-2"><i>This document was automatically generated
+ on Mon Oct 27 01:29:13 2003 by
+ <a href="http://happydoc.sourceforge.net">HappyDoc</a> version
+ 2.1</i></font>
+
+ </body>
+ </html>
+
\ No newline at end of file
--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html40/loose.dtd">
+
+<html>
+
+ <head>
+ <title>Class: CommentToken</title>
+ </head>
+
+ <body bgcolor="#ffffff">
+
+ <p><i><a href="../../../../../../index.html">Table of Contents</a></i></p>
+
+ <table border="0" cellpadding="5" cellspacing="0" width="100%">
+ <tr>
+ <th rowspan="2"
+ valign="top"
+ align="left"
+ width="10%"
+ bgcolor="#88bbee"><font color="#000000">Class: CommentToken</font>
+ </th>
+ <th bgcolor="#88bbee"
+ width="90%"
+ align="right"><font color="#000000">em.py</font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<p>A comment markup.</p>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Base Classes">Base Classes</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<a href="ExpansionToken.html">ExpansionToken</a><br>
+<ul>
+
+<a href="Token.html">Token</a><br>
+
+</ul>
+
+</td></tr>
+</table>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Methods">Methods</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<a href="#scan">scan</a><br>
+<a href="#string">string</a><br>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="scan"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">scan </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+scan ( self, scanner )
+
+</pre></font>
+
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Exceptions">Exceptions</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+TransientParseError, "comment expects newline"<br>
+
+</td></tr>
+</table>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="string"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">string </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+string ( self )
+
+</pre></font>
+
+</td></tr>
+</td></tr>
+</table>
+
+ </td>
+ </tr>
+ </table>
+
+ <hr>
+
+ <p><i><a href="../../../../../../index.html">Table of Contents</a></i></p>
+
+ <font size="-2"><i>This document was automatically generated
+ on Mon Oct 27 01:29:13 2003 by
+ <a href="http://happydoc.sourceforge.net">HappyDoc</a> version
+ 2.1</i></font>
+
+ </body>
+ </html>
+
\ No newline at end of file
--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html40/loose.dtd">
+
+<html>
+
+ <head>
+ <title>Class: Context</title>
+ </head>
+
+ <body bgcolor="#ffffff">
+
+ <p><i><a href="../../../../../../index.html">Table of Contents</a></i></p>
+
+ <table border="0" cellpadding="5" cellspacing="0" width="100%">
+ <tr>
+ <th rowspan="2"
+ valign="top"
+ align="left"
+ width="10%"
+ bgcolor="#88bbee"><font color="#000000">Class: Context</font>
+ </th>
+ <th bgcolor="#88bbee"
+ width="90%"
+ align="right"><font color="#000000">em.py</font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<p>An interpreter context, which encapsulates a name, an input
+ file object, and a parser object.</p>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Methods">Methods</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<a href="#__init__">__init__</a><br>
+<a href="#__str__">__str__</a><br>
+<a href="#bump">bump</a><br>
+<a href="#identify">identify</a><br>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="__init__"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">__init__ </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+__init__ (
+ self,
+ name,
+ line=0,
+ units=DEFAULT_UNIT,
+ )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="__str__"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">__str__ </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+__str__ ( self )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="bump"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">bump </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+bump ( self, quantity=1 )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="identify"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">identify </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+identify ( self )
+
+</pre></font>
+
+</td></tr>
+</td></tr>
+</table>
+
+ </td>
+ </tr>
+ </table>
+
+ <hr>
+
+ <p><i><a href="../../../../../../index.html">Table of Contents</a></i></p>
+
+ <font size="-2"><i>This document was automatically generated
+ on Mon Oct 27 01:29:13 2003 by
+ <a href="http://happydoc.sourceforge.net">HappyDoc</a> version
+ 2.1</i></font>
+
+ </body>
+ </html>
+
\ No newline at end of file
--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html40/loose.dtd">
+
+<html>
+
+ <head>
+ <title>Class: ContextLineToken</title>
+ </head>
+
+ <body bgcolor="#ffffff">
+
+ <p><i><a href="../../../../../../index.html">Table of Contents</a></i></p>
+
+ <table border="0" cellpadding="5" cellspacing="0" width="100%">
+ <tr>
+ <th rowspan="2"
+ valign="top"
+ align="left"
+ width="10%"
+ bgcolor="#88bbee"><font color="#000000">Class: ContextLineToken</font>
+ </th>
+ <th bgcolor="#88bbee"
+ width="90%"
+ align="right"><font color="#000000">em.py</font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<p>A context line change markup.</p>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Base Classes">Base Classes</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<a href="ExpansionToken.html">ExpansionToken</a><br>
+<ul>
+
+<a href="Token.html">Token</a><br>
+
+</ul>
+
+</td></tr>
+</table>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Methods">Methods</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<a href="#run">run</a><br>
+<a href="#scan">scan</a><br>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="run"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">run </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+run (
+ self,
+ interpreter,
+ locals,
+ )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="scan"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">scan </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+scan ( self, scanner )
+
+</pre></font>
+
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Exceptions">Exceptions</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+ParseError, "context line requires integer"<br>
+TransientParseError, "context line expects newline"<br>
+
+</td></tr>
+</table>
+</td></tr>
+</td></tr>
+</table>
+
+ </td>
+ </tr>
+ </table>
+
+ <hr>
+
+ <p><i><a href="../../../../../../index.html">Table of Contents</a></i></p>
+
+ <font size="-2"><i>This document was automatically generated
+ on Mon Oct 27 01:29:13 2003 by
+ <a href="http://happydoc.sourceforge.net">HappyDoc</a> version
+ 2.1</i></font>
+
+ </body>
+ </html>
+
\ No newline at end of file
--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html40/loose.dtd">
+
+<html>
+
+ <head>
+ <title>Class: ContextNameToken</title>
+ </head>
+
+ <body bgcolor="#ffffff">
+
+ <p><i><a href="../../../../../../index.html">Table of Contents</a></i></p>
+
+ <table border="0" cellpadding="5" cellspacing="0" width="100%">
+ <tr>
+ <th rowspan="2"
+ valign="top"
+ align="left"
+ width="10%"
+ bgcolor="#88bbee"><font color="#000000">Class: ContextNameToken</font>
+ </th>
+ <th bgcolor="#88bbee"
+ width="90%"
+ align="right"><font color="#000000">em.py</font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<p>A context name change markup.</p>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Base Classes">Base Classes</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<a href="ExpansionToken.html">ExpansionToken</a><br>
+<ul>
+
+<a href="Token.html">Token</a><br>
+
+</ul>
+
+</td></tr>
+</table>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Methods">Methods</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<a href="#run">run</a><br>
+<a href="#scan">scan</a><br>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="run"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">run </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+run (
+ self,
+ interpreter,
+ locals,
+ )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="scan"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">scan </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+scan ( self, scanner )
+
+</pre></font>
+
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Exceptions">Exceptions</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+TransientParseError, "context name expects newline"<br>
+
+</td></tr>
+</table>
+</td></tr>
+</td></tr>
+</table>
+
+ </td>
+ </tr>
+ </table>
+
+ <hr>
+
+ <p><i><a href="../../../../../../index.html">Table of Contents</a></i></p>
+
+ <font size="-2"><i>This document was automatically generated
+ on Mon Oct 27 01:29:13 2003 by
+ <a href="http://happydoc.sourceforge.net">HappyDoc</a> version
+ 2.1</i></font>
+
+ </body>
+ </html>
+
\ No newline at end of file
--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html40/loose.dtd">
+
+<html>
+
+ <head>
+ <title>Class: ContinueFlow</title>
+ </head>
+
+ <body bgcolor="#ffffff">
+
+ <p><i><a href="../../../../../../index.html">Table of Contents</a></i></p>
+
+ <table border="0" cellpadding="5" cellspacing="0" width="100%">
+ <tr>
+ <th rowspan="2"
+ valign="top"
+ align="left"
+ width="10%"
+ bgcolor="#88bbee"><font color="#000000">Class: ContinueFlow</font>
+ </th>
+ <th bgcolor="#88bbee"
+ width="90%"
+ align="right"><font color="#000000">em.py</font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<p>A continue control flow.</p>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Base Classes">Base Classes</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<a href="FlowError.html">FlowError</a><br>
+<ul>
+
+<a href="Error.html">Error</a><br>
+<ul>
+
+Exception<br>
+
+</ul>
+
+</ul>
+
+</td></tr>
+</table>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+</td></tr>
+</table>
+
+ </td>
+ </tr>
+ </table>
+
+ <hr>
+
+ <p><i><a href="../../../../../../index.html">Table of Contents</a></i></p>
+
+ <font size="-2"><i>This document was automatically generated
+ on Mon Oct 27 01:29:13 2003 by
+ <a href="http://happydoc.sourceforge.net">HappyDoc</a> version
+ 2.1</i></font>
+
+ </body>
+ </html>
+
\ No newline at end of file
--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html40/loose.dtd">
+
+<html>
+
+ <head>
+ <title>Class: ControlToken</title>
+ </head>
+
+ <body bgcolor="#ffffff">
+
+ <p><i><a href="../../../../../../index.html">Table of Contents</a></i></p>
+
+ <table border="0" cellpadding="5" cellspacing="0" width="100%">
+ <tr>
+ <th rowspan="2"
+ valign="top"
+ align="left"
+ width="10%"
+ bgcolor="#88bbee"><font color="#000000">Class: ControlToken</font>
+ </th>
+ <th bgcolor="#88bbee"
+ width="90%"
+ align="right"><font color="#000000">em.py</font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<p>A control token.</p>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Base Classes">Base Classes</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<a href="ExpansionToken.html">ExpansionToken</a><br>
+<ul>
+
+<a href="Token.html">Token</a><br>
+
+</ul>
+
+</td></tr>
+</table>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Methods">Methods</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<a href="#build">build</a><br>
+<a href="#run">run</a><br>
+<a href="#scan">scan</a><br>
+<a href="#string">string</a><br>
+<a href="#subrun">subrun</a><br>
+<a href="#subscan">subscan</a><br>
+<a href="#substring">substring</a><br>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="build"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">build </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+build ( self, allowed=None )
+
+</pre></font>
+
+<p>Process the list of subtokens and divide it into a list of
+ 2-tuples, consisting of the dividing tokens and the list of
+ subtokens that follow them. If allowed is specified, it will
+ represent the list of the only secondary markup types which
+ are allowed.</p>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Exceptions">Exceptions</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+ParseError, "control unexpected secondary: '%s'" % subtoken.type<br>
+
+</td></tr>
+</table>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="run"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">run </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+run (
+ self,
+ interpreter,
+ locals,
+ )
+
+</pre></font>
+
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Exceptions">Exceptions</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+
+ <table border="0" cellspacing="2" cellpadding="2" width="100%">
+ <tr>
+ <td align="LEFT" valign="TOP">
+BreakFlow, "control 'break' without 'for', 'while'"<br>
+ContinueFlow, "control 'continue' without 'for', 'while'"<br>
+ParseError, "control '%s' cannot be at this level" % self.type<br>
+ParseError, "control 'end' requires primary markup"<br>
+ParseError, "control 'for' expects at most one 'else'"<br>
+ParseError, "control 'if' unexpected secondary: '%s'" % secondary.type<br>
+</td>
+<td align="LEFT" valign="TOP">
+ParseError, "control 'try' can only have one 'finally'"<br>
+ParseError, "control 'try' cannot have 'except' and 'finally'"<br>
+ParseError, "control 'try' needs 'except' or 'finally'"<br>
+ParseError, "control 'while' expects at most one 'else'"<br>
+ParseError, "control expected 'for x in seq'"<br>
+</td>
+</tr>
+ </table>
+
+</td></tr>
+</table>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="scan"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">scan </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+scan ( self, scanner )
+
+</pre></font>
+
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Exceptions">Exceptions</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+ParseError, "control '%s' needs arguments" % self.type<br>
+ParseError, "unknown control markup: '%s'" % self.type<br>
+
+</td></tr>
+</table>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="string"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">string </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+string ( self )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="subrun"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">subrun </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+subrun (
+ self,
+ tokens,
+ interpreter,
+ locals,
+ )
+
+</pre></font>
+
+<p>Execute a sequence of tokens.</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="subscan"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">subscan </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+subscan (
+ self,
+ scanner,
+ primary,
+ )
+
+</pre></font>
+
+<p>Do a subscan for contained tokens.</p>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Exceptions">Exceptions</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+ParseError, "control must end with 'end %s'" % primary<br>
+TransientParseError, "control '%s' needs more tokens" % primary<br>
+
+</td></tr>
+</table>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="substring"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">substring </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+substring ( self )
+
+</pre></font>
+
+</td></tr>
+</td></tr>
+</table>
+
+ </td>
+ </tr>
+ </table>
+
+ <hr>
+
+ <p><i><a href="../../../../../../index.html">Table of Contents</a></i></p>
+
+ <font size="-2"><i>This document was automatically generated
+ on Mon Oct 27 01:29:13 2003 by
+ <a href="http://happydoc.sourceforge.net">HappyDoc</a> version
+ 2.1</i></font>
+
+ </body>
+ </html>
+
\ No newline at end of file
--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html40/loose.dtd">
+
+<html>
+
+ <head>
+ <title>Class: CustomToken</title>
+ </head>
+
+ <body bgcolor="#ffffff">
+
+ <p><i><a href="../../../../../../index.html">Table of Contents</a></i></p>
+
+ <table border="0" cellpadding="5" cellspacing="0" width="100%">
+ <tr>
+ <th rowspan="2"
+ valign="top"
+ align="left"
+ width="10%"
+ bgcolor="#88bbee"><font color="#000000">Class: CustomToken</font>
+ </th>
+ <th bgcolor="#88bbee"
+ width="90%"
+ align="right"><font color="#000000">em.py</font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<p>A custom markup.</p>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Base Classes">Base Classes</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<a href="ExpansionToken.html">ExpansionToken</a><br>
+<ul>
+
+<a href="Token.html">Token</a><br>
+
+</ul>
+
+</td></tr>
+</table>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Methods">Methods</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<a href="#run">run</a><br>
+<a href="#scan">scan</a><br>
+<a href="#string">string</a><br>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="run"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">run </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+run (
+ self,
+ interpreter,
+ locals,
+ )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="scan"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">scan </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+scan ( self, scanner )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="string"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">string </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+string ( self )
+
+</pre></font>
+
+</td></tr>
+</td></tr>
+</table>
+
+ </td>
+ </tr>
+ </table>
+
+ <hr>
+
+ <p><i><a href="../../../../../../index.html">Table of Contents</a></i></p>
+
+ <font size="-2"><i>This document was automatically generated
+ on Mon Oct 27 01:29:13 2003 by
+ <a href="http://happydoc.sourceforge.net">HappyDoc</a> version
+ 2.1</i></font>
+
+ </body>
+ </html>
+
\ No newline at end of file
--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html40/loose.dtd">
+
+<html>
+
+ <head>
+ <title>Class: Diversion</title>
+ </head>
+
+ <body bgcolor="#ffffff">
+
+ <p><i><a href="../../../../../../index.html">Table of Contents</a></i></p>
+
+ <table border="0" cellpadding="5" cellspacing="0" width="100%">
+ <tr>
+ <th rowspan="2"
+ valign="top"
+ align="left"
+ width="10%"
+ bgcolor="#88bbee"><font color="#000000">Class: Diversion</font>
+ </th>
+ <th bgcolor="#88bbee"
+ width="90%"
+ align="right"><font color="#000000">em.py</font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<p>The representation of an active diversion. Diversions act as
+ (writable) file objects, and then can be recalled either as pure
+ strings or (readable) file objects.</p>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Methods">Methods</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<a href="#__init__">__init__</a><br>
+<a href="#asFile">asFile</a><br>
+<a href="#asString">asString</a><br>
+<a href="#close">close</a><br>
+<a href="#flush">flush</a><br>
+<a href="#write">write</a><br>
+<a href="#writelines">writelines</a><br>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="__init__"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">__init__ </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+__init__ ( self )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="asFile"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">asFile </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+asFile ( self )
+
+</pre></font>
+
+<p>Return the diversion as a file.</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="asString"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">asString </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+asString ( self )
+
+</pre></font>
+
+<p>Return the diversion as a string.</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="close"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">close </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+close ( self )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="flush"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">flush </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+flush ( self )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="write"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">write </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+write ( self, data )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="writelines"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">writelines </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+writelines ( self, lines )
+
+</pre></font>
+
+</td></tr>
+</td></tr>
+</table>
+
+ </td>
+ </tr>
+ </table>
+
+ <hr>
+
+ <p><i><a href="../../../../../../index.html">Table of Contents</a></i></p>
+
+ <font size="-2"><i>This document was automatically generated
+ on Mon Oct 27 01:29:13 2003 by
+ <a href="http://happydoc.sourceforge.net">HappyDoc</a> version
+ 2.1</i></font>
+
+ </body>
+ </html>
+
\ No newline at end of file
--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html40/loose.dtd">
+
+<html>
+
+ <head>
+ <title>Class: DiversionError</title>
+ </head>
+
+ <body bgcolor="#ffffff">
+
+ <p><i><a href="../../../../../../index.html">Table of Contents</a></i></p>
+
+ <table border="0" cellpadding="5" cellspacing="0" width="100%">
+ <tr>
+ <th rowspan="2"
+ valign="top"
+ align="left"
+ width="10%"
+ bgcolor="#88bbee"><font color="#000000">Class: DiversionError</font>
+ </th>
+ <th bgcolor="#88bbee"
+ width="90%"
+ align="right"><font color="#000000">em.py</font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<p>An error related to diversions.</p>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Base Classes">Base Classes</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<a href="Error.html">Error</a><br>
+<ul>
+
+Exception<br>
+
+</ul>
+
+</td></tr>
+</table>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+</td></tr>
+</table>
+
+ </td>
+ </tr>
+ </table>
+
+ <hr>
+
+ <p><i><a href="../../../../../../index.html">Table of Contents</a></i></p>
+
+ <font size="-2"><i>This document was automatically generated
+ on Mon Oct 27 01:29:13 2003 by
+ <a href="http://happydoc.sourceforge.net">HappyDoc</a> version
+ 2.1</i></font>
+
+ </body>
+ </html>
+
\ No newline at end of file
--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html40/loose.dtd">
+
+<html>
+
+ <head>
+ <title>Class: Document</title>
+ </head>
+
+ <body bgcolor="#ffffff">
+
+ <p><i><a href="../../../../../../index.html">Table of Contents</a></i></p>
+
+ <table border="0" cellpadding="5" cellspacing="0" width="100%">
+ <tr>
+ <th rowspan="2"
+ valign="top"
+ align="left"
+ width="10%"
+ bgcolor="#88bbee"><font color="#000000">Class: Document</font>
+ </th>
+ <th bgcolor="#88bbee"
+ width="90%"
+ align="right"><font color="#000000">em.py</font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<p>A representation of an individual EmPy document, as used by a
+ processor.</p>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Methods">Methods</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<a href="#__init__">__init__</a><br>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="__init__"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">__init__ </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+__init__ (
+ self,
+ ID,
+ filename,
+ )
+
+</pre></font>
+
+</td></tr>
+</td></tr>
+</table>
+
+ </td>
+ </tr>
+ </table>
+
+ <hr>
+
+ <p><i><a href="../../../../../../index.html">Table of Contents</a></i></p>
+
+ <font size="-2"><i>This document was automatically generated
+ on Mon Oct 27 01:29:13 2003 by
+ <a href="http://happydoc.sourceforge.net">HappyDoc</a> version
+ 2.1</i></font>
+
+ </body>
+ </html>
+
\ No newline at end of file
--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html40/loose.dtd">
+
+<html>
+
+ <head>
+ <title>Class: Error</title>
+ </head>
+
+ <body bgcolor="#ffffff">
+
+ <p><i><a href="../../../../../../index.html">Table of Contents</a></i></p>
+
+ <table border="0" cellpadding="5" cellspacing="0" width="100%">
+ <tr>
+ <th rowspan="2"
+ valign="top"
+ align="left"
+ width="10%"
+ bgcolor="#88bbee"><font color="#000000">Class: Error</font>
+ </th>
+ <th bgcolor="#88bbee"
+ width="90%"
+ align="right"><font color="#000000">em.py</font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<p>The base class for all EmPy errors.</p>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Base Classes">Base Classes</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+Exception<br>
+
+</td></tr>
+</table>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+</td></tr>
+</table>
+
+ </td>
+ </tr>
+ </table>
+
+ <hr>
+
+ <p><i><a href="../../../../../../index.html">Table of Contents</a></i></p>
+
+ <font size="-2"><i>This document was automatically generated
+ on Mon Oct 27 01:29:13 2003 by
+ <a href="http://happydoc.sourceforge.net">HappyDoc</a> version
+ 2.1</i></font>
+
+ </body>
+ </html>
+
\ No newline at end of file
--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html40/loose.dtd">
+
+<html>
+
+ <head>
+ <title>Class: EscapeToken</title>
+ </head>
+
+ <body bgcolor="#ffffff">
+
+ <p><i><a href="../../../../../../index.html">Table of Contents</a></i></p>
+
+ <table border="0" cellpadding="5" cellspacing="0" width="100%">
+ <tr>
+ <th rowspan="2"
+ valign="top"
+ align="left"
+ width="10%"
+ bgcolor="#88bbee"><font color="#000000">Class: EscapeToken</font>
+ </th>
+ <th bgcolor="#88bbee"
+ width="90%"
+ align="right"><font color="#000000">em.py</font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<p>An escape markup.</p>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Base Classes">Base Classes</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<a href="ExpansionToken.html">ExpansionToken</a><br>
+<ul>
+
+<a href="Token.html">Token</a><br>
+
+</ul>
+
+</td></tr>
+</table>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Methods">Methods</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<a href="#run">run</a><br>
+<a href="#scan">scan</a><br>
+<a href="#string">string</a><br>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="run"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">run </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+run (
+ self,
+ interpreter,
+ locals,
+ )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="scan"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">scan </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+scan ( self, scanner )
+
+</pre></font>
+
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Exceptions">Exceptions</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+ParseError, "invalid escape control code"<br>
+ParseError, "invalid numeric escape code"<br>
+ParseError, "unrecognized escape code"<br>
+ParseError, r"Unicode name escape should be \N{...}"<br>
+SubsystemError, "unknown Unicode character name: %s" % name<br>
+
+</td></tr>
+</table>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="string"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">string </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+string ( self )
+
+</pre></font>
+
+</td></tr>
+</td></tr>
+</table>
+
+ </td>
+ </tr>
+ </table>
+
+ <hr>
+
+ <p><i><a href="../../../../../../index.html">Table of Contents</a></i></p>
+
+ <font size="-2"><i>This document was automatically generated
+ on Mon Oct 27 01:29:13 2003 by
+ <a href="http://happydoc.sourceforge.net">HappyDoc</a> version
+ 2.1</i></font>
+
+ </body>
+ </html>
+
\ No newline at end of file
--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html40/loose.dtd">
+
+<html>
+
+ <head>
+ <title>Class: ExpansionToken</title>
+ </head>
+
+ <body bgcolor="#ffffff">
+
+ <p><i><a href="../../../../../../index.html">Table of Contents</a></i></p>
+
+ <table border="0" cellpadding="5" cellspacing="0" width="100%">
+ <tr>
+ <th rowspan="2"
+ valign="top"
+ align="left"
+ width="10%"
+ bgcolor="#88bbee"><font color="#000000">Class: ExpansionToken</font>
+ </th>
+ <th bgcolor="#88bbee"
+ width="90%"
+ align="right"><font color="#000000">em.py</font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<p>A token that involves an expansion.</p>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Base Classes">Base Classes</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<a href="Token.html">Token</a><br>
+
+</td></tr>
+</table>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Methods">Methods</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<a href="#__init__">__init__</a><br>
+<a href="#run">run</a><br>
+<a href="#scan">scan</a><br>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="__init__"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">__init__ </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+__init__ (
+ self,
+ prefix,
+ first,
+ )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="run"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">run </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+run (
+ self,
+ interpreter,
+ locals,
+ )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="scan"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">scan </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+scan ( self, scanner )
+
+</pre></font>
+
+</td></tr>
+</td></tr>
+</table>
+
+ </td>
+ </tr>
+ </table>
+
+ <hr>
+
+ <p><i><a href="../../../../../../index.html">Table of Contents</a></i></p>
+
+ <font size="-2"><i>This document was automatically generated
+ on Mon Oct 27 01:29:13 2003 by
+ <a href="http://happydoc.sourceforge.net">HappyDoc</a> version
+ 2.1</i></font>
+
+ </body>
+ </html>
+
\ No newline at end of file
--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html40/loose.dtd">
+
+<html>
+
+ <head>
+ <title>Class: ExpressionToken</title>
+ </head>
+
+ <body bgcolor="#ffffff">
+
+ <p><i><a href="../../../../../../index.html">Table of Contents</a></i></p>
+
+ <table border="0" cellpadding="5" cellspacing="0" width="100%">
+ <tr>
+ <th rowspan="2"
+ valign="top"
+ align="left"
+ width="10%"
+ bgcolor="#88bbee"><font color="#000000">Class: ExpressionToken</font>
+ </th>
+ <th bgcolor="#88bbee"
+ width="90%"
+ align="right"><font color="#000000">em.py</font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<p>An expression markup.</p>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Base Classes">Base Classes</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<a href="ExpansionToken.html">ExpansionToken</a><br>
+<ul>
+
+<a href="Token.html">Token</a><br>
+
+</ul>
+
+</td></tr>
+</table>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Methods">Methods</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<a href="#run">run</a><br>
+<a href="#scan">scan</a><br>
+<a href="#string">string</a><br>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="run"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">run </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+run (
+ self,
+ interpreter,
+ locals,
+ )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="scan"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">scan </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+scan ( self, scanner )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="string"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">string </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+string ( self )
+
+</pre></font>
+
+</td></tr>
+</td></tr>
+</table>
+
+ </td>
+ </tr>
+ </table>
+
+ <hr>
+
+ <p><i><a href="../../../../../../index.html">Table of Contents</a></i></p>
+
+ <font size="-2"><i>This document was automatically generated
+ on Mon Oct 27 01:29:13 2003 by
+ <a href="http://happydoc.sourceforge.net">HappyDoc</a> version
+ 2.1</i></font>
+
+ </body>
+ </html>
+
\ No newline at end of file
--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html40/loose.dtd">
+
+<html>
+
+ <head>
+ <title>Class: Filter</title>
+ </head>
+
+ <body bgcolor="#ffffff">
+
+ <p><i><a href="../../../../../../index.html">Table of Contents</a></i></p>
+
+ <table border="0" cellpadding="5" cellspacing="0" width="100%">
+ <tr>
+ <th rowspan="2"
+ valign="top"
+ align="left"
+ width="10%"
+ bgcolor="#88bbee"><font color="#000000">Class: Filter</font>
+ </th>
+ <th bgcolor="#88bbee"
+ width="90%"
+ align="right"><font color="#000000">em.py</font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<p>An abstract filter.</p>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Methods">Methods</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+
+ <table border="0" cellspacing="2" cellpadding="2" width="100%">
+ <tr>
+ <td align="LEFT" valign="TOP">
+<a href="#__init__">__init__</a><br>
+<a href="#_flush">_flush</a><br>
+<a href="#attach">attach</a><br>
+<a href="#close">close</a><br>
+<a href="#detach">detach</a><br>
+</td>
+<td align="LEFT" valign="TOP">
+<a href="#flush">flush</a><br>
+<a href="#last">last</a><br>
+<a href="#next">next</a><br>
+<a href="#write">write</a><br>
+<a href="#writelines">writelines</a><br>
+</td>
+</tr>
+ </table>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="__init__"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">__init__ </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+__init__ ( self )
+
+</pre></font>
+
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Exceptions">Exceptions</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+NotImplementedError<br>
+
+</td></tr>
+</table>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="_flush"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">_flush </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+_flush ( self )
+
+</pre></font>
+
+<p>The _flush method should always flush the sink and should not
+ be overridden.</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="attach"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">attach </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+attach ( self, filter )
+
+</pre></font>
+
+<p>Attach a filter to this one.</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="close"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">close </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+close ( self )
+
+</pre></font>
+
+<p>Close the filter. Do an explicit flush first, then close the
+ sink.</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="detach"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">detach </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+detach ( self )
+
+</pre></font>
+
+<p>Detach a filter from its sink.</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="flush"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">flush </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+flush ( self )
+
+</pre></font>
+
+<p>The flush method can be overridden.</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="last"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">last </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+last ( self )
+
+</pre></font>
+
+<p>Find the last filter in this chain.</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="next"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">next </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+next ( self )
+
+</pre></font>
+
+<p>Return the next filter/file-like object in the sequence, or None.</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="write"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">write </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+write ( self, data )
+
+</pre></font>
+
+<p>The standard write method; this must be overridden in subclasses.</p>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Exceptions">Exceptions</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+NotImplementedError<br>
+
+</td></tr>
+</table>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="writelines"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">writelines </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+writelines ( self, lines )
+
+</pre></font>
+
+<p>Standard writelines wrapper.</p>
+</td></tr>
+</td></tr>
+</table>
+
+ </td>
+ </tr>
+ </table>
+
+ <hr>
+
+ <p><i><a href="../../../../../../index.html">Table of Contents</a></i></p>
+
+ <font size="-2"><i>This document was automatically generated
+ on Mon Oct 27 01:29:13 2003 by
+ <a href="http://happydoc.sourceforge.net">HappyDoc</a> version
+ 2.1</i></font>
+
+ </body>
+ </html>
+
\ No newline at end of file
--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html40/loose.dtd">
+
+<html>
+
+ <head>
+ <title>Class: FilterError</title>
+ </head>
+
+ <body bgcolor="#ffffff">
+
+ <p><i><a href="../../../../../../index.html">Table of Contents</a></i></p>
+
+ <table border="0" cellpadding="5" cellspacing="0" width="100%">
+ <tr>
+ <th rowspan="2"
+ valign="top"
+ align="left"
+ width="10%"
+ bgcolor="#88bbee"><font color="#000000">Class: FilterError</font>
+ </th>
+ <th bgcolor="#88bbee"
+ width="90%"
+ align="right"><font color="#000000">em.py</font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<p>An error related to filters.</p>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Base Classes">Base Classes</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<a href="Error.html">Error</a><br>
+<ul>
+
+Exception<br>
+
+</ul>
+
+</td></tr>
+</table>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+</td></tr>
+</table>
+
+ </td>
+ </tr>
+ </table>
+
+ <hr>
+
+ <p><i><a href="../../../../../../index.html">Table of Contents</a></i></p>
+
+ <font size="-2"><i>This document was automatically generated
+ on Mon Oct 27 01:29:13 2003 by
+ <a href="http://happydoc.sourceforge.net">HappyDoc</a> version
+ 2.1</i></font>
+
+ </body>
+ </html>
+
\ No newline at end of file
--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html40/loose.dtd">
+
+<html>
+
+ <head>
+ <title>Class: FlowError</title>
+ </head>
+
+ <body bgcolor="#ffffff">
+
+ <p><i><a href="../../../../../../index.html">Table of Contents</a></i></p>
+
+ <table border="0" cellpadding="5" cellspacing="0" width="100%">
+ <tr>
+ <th rowspan="2"
+ valign="top"
+ align="left"
+ width="10%"
+ bgcolor="#88bbee"><font color="#000000">Class: FlowError</font>
+ </th>
+ <th bgcolor="#88bbee"
+ width="90%"
+ align="right"><font color="#000000">em.py</font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<p>An exception related to control flow.</p>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Base Classes">Base Classes</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<a href="Error.html">Error</a><br>
+<ul>
+
+Exception<br>
+
+</ul>
+
+</td></tr>
+</table>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+</td></tr>
+</table>
+
+ </td>
+ </tr>
+ </table>
+
+ <hr>
+
+ <p><i><a href="../../../../../../index.html">Table of Contents</a></i></p>
+
+ <font size="-2"><i>This document was automatically generated
+ on Mon Oct 27 01:29:13 2003 by
+ <a href="http://happydoc.sourceforge.net">HappyDoc</a> version
+ 2.1</i></font>
+
+ </body>
+ </html>
+
\ No newline at end of file
--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html40/loose.dtd">
+
+<html>
+
+ <head>
+ <title>Class: FunctionFilter</title>
+ </head>
+
+ <body bgcolor="#ffffff">
+
+ <p><i><a href="../../../../../../index.html">Table of Contents</a></i></p>
+
+ <table border="0" cellpadding="5" cellspacing="0" width="100%">
+ <tr>
+ <th rowspan="2"
+ valign="top"
+ align="left"
+ width="10%"
+ bgcolor="#88bbee"><font color="#000000">Class: FunctionFilter</font>
+ </th>
+ <th bgcolor="#88bbee"
+ width="90%"
+ align="right"><font color="#000000">em.py</font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<p>A filter that works simply by pumping its input through a
+ function which maps strings into strings.</p>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Base Classes">Base Classes</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<a href="Filter.html">Filter</a><br>
+
+</td></tr>
+</table>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Methods">Methods</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<a href="#__init__">__init__</a><br>
+<a href="#write">write</a><br>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="__init__"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">__init__ </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+__init__ ( self, function )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="write"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">write </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+write ( self, data )
+
+</pre></font>
+
+</td></tr>
+</td></tr>
+</table>
+
+ </td>
+ </tr>
+ </table>
+
+ <hr>
+
+ <p><i><a href="../../../../../../index.html">Table of Contents</a></i></p>
+
+ <font size="-2"><i>This document was automatically generated
+ on Mon Oct 27 01:29:13 2003 by
+ <a href="http://happydoc.sourceforge.net">HappyDoc</a> version
+ 2.1</i></font>
+
+ </body>
+ </html>
+
\ No newline at end of file
--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html40/loose.dtd">
+
+<html>
+
+ <head>
+ <title>Class: Hook</title>
+ </head>
+
+ <body bgcolor="#ffffff">
+
+ <p><i><a href="../../../../../../index.html">Table of Contents</a></i></p>
+
+ <table border="0" cellpadding="5" cellspacing="0" width="100%">
+ <tr>
+ <th rowspan="2"
+ valign="top"
+ align="left"
+ width="10%"
+ bgcolor="#88bbee"><font color="#000000">Class: Hook</font>
+ </th>
+ <th bgcolor="#88bbee"
+ width="90%"
+ align="right"><font color="#000000">em.py</font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<p>The base class for implementing hooks.</p>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Methods">Methods</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+
+ <table border="0" cellspacing="2" cellpadding="2" width="100%">
+ <tr>
+ <td align="LEFT" valign="TOP">
+<a href="#__init__">__init__</a><br>
+<a href="#afterAtomic">afterAtomic</a><br>
+<a href="#afterBinary">afterBinary</a><br>
+<a href="#afterClause">afterClause</a><br>
+<a href="#afterControl">afterControl</a><br>
+<a href="#afterDefined">afterDefined</a><br>
+<a href="#afterEscape">afterEscape</a><br>
+<a href="#afterEvaluate">afterEvaluate</a><br>
+<a href="#afterExecute">afterExecute</a><br>
+<a href="#afterExpand">afterExpand</a><br>
+<a href="#afterFile">afterFile</a><br>
+<a href="#afterImport">afterImport</a><br>
+<a href="#afterInclude">afterInclude</a><br>
+<a href="#afterLiteral">afterLiteral</a><br>
+<a href="#afterMulti">afterMulti</a><br>
+<a href="#afterQuote">afterQuote</a><br>
+<a href="#afterSerialize">afterSerialize</a><br>
+<a href="#afterSignificate">afterSignificate</a><br>
+</td>
+<td align="LEFT" valign="TOP">
+<a href="#afterSingle">afterSingle</a><br>
+<a href="#afterString">afterString</a><br>
+<a href="#atFinalize">atFinalize</a><br>
+<a href="#atHandle">atHandle</a><br>
+<a href="#atInteract">atInteract</a><br>
+<a href="#atParse">atParse</a><br>
+<a href="#atReady">atReady</a><br>
+<a href="#atShutdown">atShutdown</a><br>
+<a href="#atStartup">atStartup</a><br>
+<a href="#atToken">atToken</a><br>
+<a href="#beforeAtomic">beforeAtomic</a><br>
+<a href="#beforeBinary">beforeBinary</a><br>
+<a href="#beforeClause">beforeClause</a><br>
+<a href="#beforeControl">beforeControl</a><br>
+<a href="#beforeDefined">beforeDefined</a><br>
+<a href="#beforeEscape">beforeEscape</a><br>
+<a href="#beforeEvaluate">beforeEvaluate</a><br>
+<a href="#beforeExecute">beforeExecute</a><br>
+</td>
+<td align="LEFT" valign="TOP">
+<a href="#beforeExpand">beforeExpand</a><br>
+<a href="#beforeFile">beforeFile</a><br>
+<a href="#beforeImport">beforeImport</a><br>
+<a href="#beforeInclude">beforeInclude</a><br>
+<a href="#beforeLiteral">beforeLiteral</a><br>
+<a href="#beforeMulti">beforeMulti</a><br>
+<a href="#beforeQuote">beforeQuote</a><br>
+<a href="#beforeSerialize">beforeSerialize</a><br>
+<a href="#beforeSignificate">beforeSignificate</a><br>
+<a href="#beforeSingle">beforeSingle</a><br>
+<a href="#beforeString">beforeString</a><br>
+<a href="#deregister">deregister</a><br>
+<a href="#null">null</a><br>
+<a href="#pop">pop</a><br>
+<a href="#push">push</a><br>
+<a href="#register">register</a><br>
+</td>
+</tr>
+ </table>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="__init__"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">__init__ </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+__init__ ( self )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="afterAtomic"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">afterAtomic </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+afterAtomic ( self )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="afterBinary"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">afterBinary </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+afterBinary ( self )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="afterClause"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">afterClause </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+afterClause (
+ self,
+ exception,
+ variable,
+ )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="afterControl"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">afterControl </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+afterControl ( self )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="afterDefined"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">afterDefined </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+afterDefined ( self, result )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="afterEscape"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">afterEscape </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+afterEscape ( self, result )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="afterEvaluate"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">afterEvaluate </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+afterEvaluate ( self, result )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="afterExecute"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">afterExecute </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+afterExecute ( self )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="afterExpand"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">afterExpand </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+afterExpand ( self, result )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="afterFile"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">afterFile </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+afterFile ( self )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="afterImport"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">afterImport </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+afterImport ( self )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="afterInclude"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">afterInclude </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+afterInclude ( self )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="afterLiteral"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">afterLiteral </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+afterLiteral ( self )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="afterMulti"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">afterMulti </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+afterMulti ( self )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="afterQuote"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">afterQuote </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+afterQuote ( self, result )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="afterSerialize"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">afterSerialize </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+afterSerialize ( self )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="afterSignificate"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">afterSignificate </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+afterSignificate ( self )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="afterSingle"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">afterSingle </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+afterSingle ( self )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="afterString"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">afterString </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+afterString ( self )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="atFinalize"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">atFinalize </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+atFinalize ( self )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="atHandle"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">atHandle </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+atHandle ( self, meta )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="atInteract"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">atInteract </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+atInteract ( self )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="atParse"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">atParse </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+atParse (
+ self,
+ scanner,
+ locals,
+ )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="atReady"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">atReady </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+atReady ( self )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="atShutdown"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">atShutdown </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+atShutdown ( self )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="atStartup"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">atStartup </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+atStartup ( self )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="atToken"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">atToken </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+atToken ( self, token )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="beforeAtomic"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">beforeAtomic </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+beforeAtomic (
+ self,
+ name,
+ value,
+ locals,
+ )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="beforeBinary"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">beforeBinary </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+beforeBinary (
+ self,
+ name,
+ file,
+ chunkSize,
+ locals,
+ )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="beforeClause"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">beforeClause </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+beforeClause (
+ self,
+ catch,
+ locals,
+ )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="beforeControl"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">beforeControl </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+beforeControl (
+ self,
+ type,
+ rest,
+ locals,
+ )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="beforeDefined"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">beforeDefined </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+beforeDefined (
+ self,
+ name,
+ locals,
+ )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="beforeEscape"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">beforeEscape </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+beforeEscape (
+ self,
+ string,
+ more,
+ )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="beforeEvaluate"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">beforeEvaluate </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+beforeEvaluate (
+ self,
+ expression,
+ locals,
+ )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="beforeExecute"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">beforeExecute </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+beforeExecute (
+ self,
+ statements,
+ locals,
+ )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="beforeExpand"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">beforeExpand </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+beforeExpand (
+ self,
+ string,
+ locals,
+ )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="beforeFile"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">beforeFile </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+beforeFile (
+ self,
+ name,
+ file,
+ locals,
+ )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="beforeImport"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">beforeImport </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+beforeImport (
+ self,
+ name,
+ locals,
+ )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="beforeInclude"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">beforeInclude </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+beforeInclude (
+ self,
+ name,
+ file,
+ locals,
+ )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="beforeLiteral"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">beforeLiteral </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+beforeLiteral ( self, text )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="beforeMulti"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">beforeMulti </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+beforeMulti (
+ self,
+ name,
+ values,
+ locals,
+ )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="beforeQuote"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">beforeQuote </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+beforeQuote ( self, string )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="beforeSerialize"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">beforeSerialize </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+beforeSerialize (
+ self,
+ expression,
+ locals,
+ )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="beforeSignificate"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">beforeSignificate </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+beforeSignificate (
+ self,
+ key,
+ value,
+ locals,
+ )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="beforeSingle"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">beforeSingle </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+beforeSingle (
+ self,
+ source,
+ locals,
+ )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="beforeString"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">beforeString </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+beforeString (
+ self,
+ name,
+ string,
+ locals,
+ )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="deregister"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">deregister </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+deregister ( self, interpreter )
+
+</pre></font>
+
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Exceptions">Exceptions</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+Error, "hook not associated with this interpreter"<br>
+
+</td></tr>
+</table>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="null"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">null </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+null ( self )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="pop"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">pop </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+pop ( self )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="push"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">push </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+push ( self )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="register"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">register </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+register ( self, interpreter )
+
+</pre></font>
+
+</td></tr>
+</td></tr>
+</table>
+
+ </td>
+ </tr>
+ </table>
+
+ <hr>
+
+ <p><i><a href="../../../../../../index.html">Table of Contents</a></i></p>
+
+ <font size="-2"><i>This document was automatically generated
+ on Mon Oct 27 01:29:13 2003 by
+ <a href="http://happydoc.sourceforge.net">HappyDoc</a> version
+ 2.1</i></font>
+
+ </body>
+ </html>
+
\ No newline at end of file
--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html40/loose.dtd">
+
+<html>
+
+ <head>
+ <title>Class: HookError</title>
+ </head>
+
+ <body bgcolor="#ffffff">
+
+ <p><i><a href="../../../../../../index.html">Table of Contents</a></i></p>
+
+ <table border="0" cellpadding="5" cellspacing="0" width="100%">
+ <tr>
+ <th rowspan="2"
+ valign="top"
+ align="left"
+ width="10%"
+ bgcolor="#88bbee"><font color="#000000">Class: HookError</font>
+ </th>
+ <th bgcolor="#88bbee"
+ width="90%"
+ align="right"><font color="#000000">em.py</font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<p>An exception associated with hooks.</p>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Base Classes">Base Classes</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<a href="Error.html">Error</a><br>
+<ul>
+
+Exception<br>
+
+</ul>
+
+</td></tr>
+</table>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+</td></tr>
+</table>
+
+ </td>
+ </tr>
+ </table>
+
+ <hr>
+
+ <p><i><a href="../../../../../../index.html">Table of Contents</a></i></p>
+
+ <font size="-2"><i>This document was automatically generated
+ on Mon Oct 27 00:58:36 2003 by
+ <a href="http://happydoc.sourceforge.net">HappyDoc</a> version
+ 2.1</i></font>
+
+ </body>
+ </html>
+
\ No newline at end of file
--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html40/loose.dtd">
+
+<html>
+
+ <head>
+ <title>Class: InPlaceToken</title>
+ </head>
+
+ <body bgcolor="#ffffff">
+
+ <p><i><a href="../../../../../../index.html">Table of Contents</a></i></p>
+
+ <table border="0" cellpadding="5" cellspacing="0" width="100%">
+ <tr>
+ <th rowspan="2"
+ valign="top"
+ align="left"
+ width="10%"
+ bgcolor="#88bbee"><font color="#000000">Class: InPlaceToken</font>
+ </th>
+ <th bgcolor="#88bbee"
+ width="90%"
+ align="right"><font color="#000000">em.py</font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<p>An in-place markup.</p>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Base Classes">Base Classes</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<a href="ExpansionToken.html">ExpansionToken</a><br>
+<ul>
+
+<a href="Token.html">Token</a><br>
+
+</ul>
+
+</td></tr>
+</table>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Methods">Methods</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<a href="#run">run</a><br>
+<a href="#scan">scan</a><br>
+<a href="#string">string</a><br>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="run"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">run </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+run (
+ self,
+ interpreter,
+ locals,
+ )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="scan"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">scan </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+scan ( self, scanner )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="string"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">string </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+string ( self )
+
+</pre></font>
+
+</td></tr>
+</td></tr>
+</table>
+
+ </td>
+ </tr>
+ </table>
+
+ <hr>
+
+ <p><i><a href="../../../../../../index.html">Table of Contents</a></i></p>
+
+ <font size="-2"><i>This document was automatically generated
+ on Mon Oct 27 01:29:13 2003 by
+ <a href="http://happydoc.sourceforge.net">HappyDoc</a> version
+ 2.1</i></font>
+
+ </body>
+ </html>
+
\ No newline at end of file
--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html40/loose.dtd">
+
+<html>
+
+ <head>
+ <title>Class: Interpreter</title>
+ </head>
+
+ <body bgcolor="#ffffff">
+
+ <p><i><a href="../../../../../../index.html">Table of Contents</a></i></p>
+
+ <table border="0" cellpadding="5" cellspacing="0" width="100%">
+ <tr>
+ <th rowspan="2"
+ valign="top"
+ align="left"
+ width="10%"
+ bgcolor="#88bbee"><font color="#000000">Class: Interpreter</font>
+ </th>
+ <th bgcolor="#88bbee"
+ width="90%"
+ align="right"><font color="#000000">em.py</font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<p>An interpreter can process chunks of EmPy code.</p>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Methods">Methods</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+
+ <table border="0" cellspacing="2" cellpadding="2" width="100%">
+ <tr>
+ <td align="LEFT" valign="TOP">
+<a href="#__del__">__del__</a><br>
+<a href="#__init__">__init__</a><br>
+<a href="#__repr__">__repr__</a><br>
+<a href="#addHook">addHook</a><br>
+<a href="#areHooksEnabled">areHooksEnabled</a><br>
+<a href="#assign">assign</a><br>
+<a href="#atExit">atExit</a><br>
+<a href="#atomic">atomic</a><br>
+<a href="#attachFilter">attachFilter</a><br>
+<a href="#binary">binary</a><br>
+<a href="#clause">clause</a><br>
+<a href="#clear">clear</a><br>
+<a href="#clearGlobals">clearGlobals</a><br>
+<a href="#clearHooks">clearHooks</a><br>
+<a href="#close">close</a><br>
+<a href="#context">context</a><br>
+<a href="#createDiversion">createDiversion</a><br>
+<a href="#defined">defined</a><br>
+<a href="#deregister">deregister</a><br>
+<a href="#deregisterCallback">deregisterCallback</a><br>
+<a href="#disableHooks">disableHooks</a><br>
+<a href="#enableHooks">enableHooks</a><br>
+<a href="#escape">escape</a><br>
+<a href="#evaluate">evaluate</a><br>
+<a href="#execute">execute</a><br>
+<a href="#expand">expand</a><br>
+<a href="#fail">fail</a><br>
+<a href="#file">file</a><br>
+<a href="#finalize">finalize</a><br>
+<a href="#fix">fix</a><br>
+<a href="#flatten">flatten</a><br>
+<a href="#flush">flush</a><br>
+<a href="#getAllDiversions">getAllDiversions</a><br>
+</td>
+<td align="LEFT" valign="TOP">
+<a href="#getCallback">getCallback</a><br>
+<a href="#getCurrentDiversion">getCurrentDiversion</a><br>
+<a href="#getFilter">getFilter</a><br>
+<a href="#getGlobals">getGlobals</a><br>
+<a href="#getHooks">getHooks</a><br>
+<a href="#getPrefix">getPrefix</a><br>
+<a href="#handle">handle</a><br>
+<a href="#identify">identify</a><br>
+<a href="#import_">import_</a><br>
+<a href="#include">include</a><br>
+<a href="#installProxy">installProxy</a><br>
+<a href="#interact">interact</a><br>
+<a href="#invoke">invoke</a><br>
+<a href="#invokeCallback">invokeCallback</a><br>
+<a href="#invokeHook">invokeHook</a><br>
+<a href="#literal">literal</a><br>
+<a href="#meta">meta</a><br>
+<a href="#multi">multi</a><br>
+<a href="#nullFilter">nullFilter</a><br>
+<a href="#ok">ok</a><br>
+<a href="#parse">parse</a><br>
+<a href="#playAllDiversions">playAllDiversions</a><br>
+<a href="#playDiversion">playDiversion</a><br>
+<a href="#pop">pop</a><br>
+<a href="#popContext">popContext</a><br>
+<a href="#purgeAllDiversions">purgeAllDiversions</a><br>
+<a href="#purgeDiversion">purgeDiversion</a><br>
+<a href="#push">push</a><br>
+<a href="#pushContext">pushContext</a><br>
+<a href="#quote">quote</a><br>
+<a href="#ready">ready</a><br>
+<a href="#register">register</a><br>
+<a href="#registerCallback">registerCallback</a><br>
+</td>
+<td align="LEFT" valign="TOP">
+<a href="#removeHook">removeHook</a><br>
+<a href="#replayAllDiversions">replayAllDiversions</a><br>
+<a href="#replayDiversion">replayDiversion</a><br>
+<a href="#reset">reset</a><br>
+<a href="#resetFilter">resetFilter</a><br>
+<a href="#restore">restore</a><br>
+<a href="#restoreGlobals">restoreGlobals</a><br>
+<a href="#retrieveDiversion">retrieveDiversion</a><br>
+<a href="#safe">safe</a><br>
+<a href="#save">save</a><br>
+<a href="#saveGlobals">saveGlobals</a><br>
+<a href="#serialize">serialize</a><br>
+<a href="#setContextLine">setContextLine</a><br>
+<a href="#setContextName">setContextName</a><br>
+<a href="#setFilter">setFilter</a><br>
+<a href="#setGlobals">setGlobals</a><br>
+<a href="#setPrefix">setPrefix</a><br>
+<a href="#shutdown">shutdown</a><br>
+<a href="#significate">significate</a><br>
+<a href="#single">single</a><br>
+<a href="#startDiversion">startDiversion</a><br>
+<a href="#stopDiverting">stopDiverting</a><br>
+<a href="#stream">stream</a><br>
+<a href="#string">string</a><br>
+<a href="#tokenize">tokenize</a><br>
+<a href="#unfix">unfix</a><br>
+<a href="#update">update</a><br>
+<a href="#updateGlobals">updateGlobals</a><br>
+<a href="#wrap">wrap</a><br>
+<a href="#write">write</a><br>
+<a href="#writelines">writelines</a><br>
+</td>
+</tr>
+ </table>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="__del__"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">__del__ </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+__del__ ( self )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="__init__"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">__init__ </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+__init__ (
+ self,
+ output=None,
+ argv=None,
+ prefix=DEFAULT_PREFIX,
+ pseudo=None,
+ options=None,
+ globals=None,
+ hooks=None,
+ )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="__repr__"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">__repr__ </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+__repr__ ( self )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="addHook"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">addHook </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+addHook (
+ self,
+ hook,
+ prepend=False,
+ )
+
+</pre></font>
+
+<p>Add a new hook; optionally insert it rather than appending it.</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="areHooksEnabled"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">areHooksEnabled </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+areHooksEnabled ( self )
+
+</pre></font>
+
+<p>Return whether or not hooks are presently enabled.</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="assign"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">assign </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+assign (
+ self,
+ name,
+ value,
+ locals=None,
+ )
+
+</pre></font>
+
+<p>Do a potentially complex (including tuple unpacking) assignment.</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="atExit"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">atExit </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+atExit ( self, callable )
+
+</pre></font>
+
+<p>Register a function to be called at exit.</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="atomic"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">atomic </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+atomic (
+ self,
+ name,
+ value,
+ locals=None,
+ )
+
+</pre></font>
+
+<p>Do an atomic assignment.</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="attachFilter"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">attachFilter </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+attachFilter ( self, shortcut )
+
+</pre></font>
+
+<p>Attach a single filter to the end of the current filter chain.</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="binary"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">binary </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+binary (
+ self,
+ file,
+ name='<binary>',
+ chunkSize=0,
+ locals=None,
+ )
+
+</pre></font>
+
+<p>Parse the entire contents of a file-like object, in chunks.</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="clause"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">clause </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+clause (
+ self,
+ catch,
+ locals=None,
+ )
+
+</pre></font>
+
+<p>Given the string representation of an except clause, turn it into
+ a 2-tuple consisting of the class name, and either a variable name
+ or None.</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="clear"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">clear </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+clear ( self )
+
+</pre></font>
+
+<p>Clear out the globals dictionary with a brand new one.</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="clearGlobals"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">clearGlobals </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+clearGlobals ( self )
+
+</pre></font>
+
+<p>Clear out the globals with a brand new dictionary.</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="clearHooks"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">clearHooks </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+clearHooks ( self )
+
+</pre></font>
+
+<p>Clear all hooks.</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="close"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">close </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+close ( self )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="context"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">context </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+context ( self )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="createDiversion"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">createDiversion </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+createDiversion ( self, name )
+
+</pre></font>
+
+<p>Create a diversion (but do not divert to it) if it does not
+ already exist.</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="defined"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">defined </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+defined (
+ self,
+ name,
+ locals=None,
+ )
+
+</pre></font>
+
+<p>Return a Boolean indicating whether or not the name is
+ defined either in the locals or the globals.</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="deregister"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">deregister </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+deregister ( self, hook )
+
+</pre></font>
+
+<p>Remove an already registered hook.</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="deregisterCallback"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">deregisterCallback </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+deregisterCallback ( self )
+
+</pre></font>
+
+<p>Remove any previously registered callback with this interpreter.</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="disableHooks"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">disableHooks </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+disableHooks ( self )
+
+</pre></font>
+
+<p>Disable hooks.</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="enableHooks"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">enableHooks </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+enableHooks ( self )
+
+</pre></font>
+
+<p>Enable hooks.</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="escape"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">escape </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+escape (
+ self,
+ data,
+ more='',
+ )
+
+</pre></font>
+
+<p>Escape a string so that nonprintable characters are replaced
+ with compatible EmPy expansions.</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="evaluate"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">evaluate </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+evaluate (
+ self,
+ expression,
+ locals=None,
+ )
+
+</pre></font>
+
+<p>Evaluate an expression.</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="execute"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">execute </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+execute (
+ self,
+ statements,
+ locals=None,
+ )
+
+</pre></font>
+
+<p>Execute a statement.</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="expand"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">expand </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+expand (
+ self,
+ data,
+ locals=None,
+ )
+
+</pre></font>
+
+<p>Do an explicit expansion on a subordinate stream.</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="fail"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">fail </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+fail (
+ self,
+ error,
+ fatal=False,
+ )
+
+</pre></font>
+
+<p>Handle an actual error that occurred.</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="file"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">file </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+file (
+ self,
+ file,
+ name='<file>',
+ locals=None,
+ )
+
+</pre></font>
+
+<p>Parse the entire contents of a file-like object, line by line.</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="finalize"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">finalize </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+finalize ( self )
+
+</pre></font>
+
+<p>Execute any remaining final routines.</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="fix"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">fix </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+fix ( self )
+
+</pre></font>
+
+<p>Reset the globals, stamping in the pseudomodule.</p>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Exceptions">Exceptions</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+Error, "interpreter globals collision"<br>
+
+</td></tr>
+</table>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="flatten"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">flatten </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+flatten ( self, keys=None )
+
+</pre></font>
+
+<p>Flatten the contents of the pseudo-module into the globals
+ namespace.</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="flush"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">flush </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+flush ( self )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="getAllDiversions"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">getAllDiversions </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+getAllDiversions ( self )
+
+</pre></font>
+
+<p>Get the names of all existing diversions.</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="getCallback"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">getCallback </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+getCallback ( self )
+
+</pre></font>
+
+<p>Get the callback registered with this interpreter, or None.</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="getCurrentDiversion"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">getCurrentDiversion </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+getCurrentDiversion ( self )
+
+</pre></font>
+
+<p>Get the name of the current diversion.</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="getFilter"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">getFilter </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+getFilter ( self )
+
+</pre></font>
+
+<p>Get the current filter.</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="getGlobals"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">getGlobals </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+getGlobals ( self )
+
+</pre></font>
+
+<p>Retrieve the globals.</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="getHooks"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">getHooks </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+getHooks ( self )
+
+</pre></font>
+
+<p>Get the current hooks.</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="getPrefix"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">getPrefix </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+getPrefix ( self )
+
+</pre></font>
+
+<p>Get the current prefix.</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="handle"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">handle </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+handle ( self, meta )
+
+</pre></font>
+
+<p>Handle a MetaError.</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="identify"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">identify </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+identify ( self )
+
+</pre></font>
+
+<p>Identify the topmost context with a 2-tuple of the name and
+ line number.</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="import_"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">import_ </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+import_ (
+ self,
+ name,
+ locals=None,
+ )
+
+</pre></font>
+
+<p>Do an import.</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="include"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">include </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+include (
+ self,
+ fileOrFilename,
+ locals=None,
+ )
+
+</pre></font>
+
+<p>Do an include pass on a file or filename.</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="installProxy"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">installProxy </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+installProxy ( self )
+
+</pre></font>
+
+<p>Install a proxy if necessary.</p>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Exceptions">Exceptions</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+Error, "interpreter stdout proxy lost"<br>
+
+</td></tr>
+</table>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="interact"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">interact </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+interact ( self )
+
+</pre></font>
+
+<p>Perform interaction.</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="invoke"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">invoke </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+invoke (
+ self,
+ _name,
+ **keywords,
+ )
+
+</pre></font>
+
+<p>Invoke the hook(s) associated with the hook name, should they
+ exist.</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="invokeCallback"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">invokeCallback </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+invokeCallback ( self, contents )
+
+</pre></font>
+
+<p>Invoke the callback.</p>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Exceptions">Exceptions</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+Error, "custom markup invoked with no defined callback"<br>
+
+</td></tr>
+</table>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="invokeHook"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">invokeHook </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+invokeHook (
+ self,
+ _name,
+ **keywords,
+ )
+
+</pre></font>
+
+<p>Manually invoke a hook.</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="literal"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">literal </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+literal ( self, text )
+
+</pre></font>
+
+<p>Process a string literal.</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="meta"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">meta </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+meta ( self, exc=None )
+
+</pre></font>
+
+<p>Construct a MetaError for the interpreter's current state.</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="multi"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">multi </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+multi (
+ self,
+ names,
+ values,
+ locals=None,
+ )
+
+</pre></font>
+
+<p>Do a (potentially recursive) assignment.</p>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Exceptions">Exceptions</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+TypeError, "unpack non-sequence"<br>
+ValueError, "unpack tuple of wrong size"<br>
+
+</td></tr>
+</table>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="nullFilter"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">nullFilter </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+nullFilter ( self )
+
+</pre></font>
+
+<p>Install a filter that will consume all text.</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="ok"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">ok </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+ok ( self )
+
+</pre></font>
+
+<p>Is the interpreter still active?</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="parse"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">parse </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+parse (
+ self,
+ scanner,
+ locals=None,
+ )
+
+</pre></font>
+
+<p>Parse and run as much from this scanner as possible.</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="playAllDiversions"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">playAllDiversions </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+playAllDiversions ( self )
+
+</pre></font>
+
+<p>Play all existing diversions and then purge them.</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="playDiversion"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">playDiversion </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+playDiversion ( self, name )
+
+</pre></font>
+
+<p>Play the given diversion and then purge it.</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="pop"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">pop </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+pop ( self )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="popContext"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">popContext </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+popContext ( self )
+
+</pre></font>
+
+<p>Pop the top context.</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="purgeAllDiversions"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">purgeAllDiversions </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+purgeAllDiversions ( self )
+
+</pre></font>
+
+<p>Purge all existing diversions.</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="purgeDiversion"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">purgeDiversion </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+purgeDiversion ( self, name )
+
+</pre></font>
+
+<p>Eliminate the given diversion.</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="push"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">push </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+push ( self )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="pushContext"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">pushContext </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+pushContext (
+ self,
+ name='<unnamed>',
+ line=0,
+ )
+
+</pre></font>
+
+<p>Create a new context and push it.</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="quote"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">quote </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+quote ( self, data )
+
+</pre></font>
+
+<p>Quote the given string so that if it were expanded it would
+ evaluate to the original.</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="ready"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">ready </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+ready ( self )
+
+</pre></font>
+
+<p>Declare the interpreter ready for normal operations.</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="register"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">register </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+register (
+ self,
+ hook,
+ prepend=False,
+ )
+
+</pre></font>
+
+<p>Register the provided hook.</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="registerCallback"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">registerCallback </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+registerCallback ( self, callback )
+
+</pre></font>
+
+<p>Register a custom markup callback with this interpreter.</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="removeHook"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">removeHook </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+removeHook ( self, hook )
+
+</pre></font>
+
+<p>Remove a preexisting hook.</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="replayAllDiversions"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">replayAllDiversions </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+replayAllDiversions ( self )
+
+</pre></font>
+
+<p>Replay all existing diversions without purging them.</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="replayDiversion"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">replayDiversion </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+replayDiversion ( self, name )
+
+</pre></font>
+
+<p>Replay the diversion without purging it.</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="reset"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">reset </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+reset ( self )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="resetFilter"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">resetFilter </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+resetFilter ( self )
+
+</pre></font>
+
+<p>Reset the filter so that it does no filtering.</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="restore"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">restore </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+restore ( self, destructive=True )
+
+</pre></font>
+
+<p>Restore the topmost historic globals.</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="restoreGlobals"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">restoreGlobals </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+restoreGlobals ( self, destructive=True )
+
+</pre></font>
+
+<p>Restore the most recently saved copy of the globals.</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="retrieveDiversion"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">retrieveDiversion </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+retrieveDiversion ( self, name )
+
+</pre></font>
+
+<p>Retrieve the diversion object associated with the name.</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="safe"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">safe </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+safe (
+ self,
+ scanner,
+ final=False,
+ locals=None,
+ )
+
+</pre></font>
+
+<p>Do a protected parse. Catch transient parse errors; if
+ final is true, then make a final pass with a terminator,
+ otherwise ignore the transient parse error (more data is
+ pending).</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="save"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">save </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+save ( self, deep=True )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="saveGlobals"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">saveGlobals </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+saveGlobals ( self, deep=True )
+
+</pre></font>
+
+<p>Save a copy of the globals off onto the history stack.</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="serialize"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">serialize </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+serialize (
+ self,
+ expression,
+ locals=None,
+ )
+
+</pre></font>
+
+<p>Do an expansion, involving evaluating an expression, then
+ converting it to a string and writing that string to the
+ output if the evaluation is not None.</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="setContextLine"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">setContextLine </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+setContextLine ( self, line )
+
+</pre></font>
+
+<p>Set the name of the topmost context.</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="setContextName"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">setContextName </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+setContextName ( self, name )
+
+</pre></font>
+
+<p>Set the name of the topmost context.</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="setFilter"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">setFilter </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+setFilter ( self, shortcut )
+
+</pre></font>
+
+<p>Set the filter.</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="setGlobals"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">setGlobals </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+setGlobals ( self, globals )
+
+</pre></font>
+
+<p>Set the globals to the specified dictionary.</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="setPrefix"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">setPrefix </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+setPrefix ( self, prefix )
+
+</pre></font>
+
+<p>Set the prefix.</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="shutdown"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">shutdown </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+shutdown ( self )
+
+</pre></font>
+
+<p>Declare this interpreting session over; close the stream file
+ object. This method is idempotent.</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="significate"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">significate </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+significate (
+ self,
+ key,
+ value=None,
+ locals=None,
+ )
+
+</pre></font>
+
+<p>Declare a significator.</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="single"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">single </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+single (
+ self,
+ source,
+ locals=None,
+ )
+
+</pre></font>
+
+<p>Execute an expression or statement, just as if it were
+ entered into the Python interactive interpreter.</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="startDiversion"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">startDiversion </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+startDiversion ( self, name )
+
+</pre></font>
+
+<p>Start diverting to the given diversion name.</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="stopDiverting"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">stopDiverting </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+stopDiverting ( self )
+
+</pre></font>
+
+<p>Stop any diverting.</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="stream"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">stream </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+stream ( self )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="string"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">string </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+string (
+ self,
+ data,
+ name='<string>',
+ locals=None,
+ )
+
+</pre></font>
+
+<p>Parse a string.</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="tokenize"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">tokenize </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+tokenize ( self, name )
+
+</pre></font>
+
+<p>Take an lvalue string and return a name or a (possibly recursive)
+ list of names.</p>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Exceptions">Exceptions</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+ParseError, "unexpected assignment token: '%s'" % garbage<br>
+
+</td></tr>
+</table>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="unfix"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">unfix </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+unfix ( self )
+
+</pre></font>
+
+<p>Remove the pseudomodule (if present) from the globals.</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="update"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">update </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+update ( self, other )
+
+</pre></font>
+
+<p>Update the current globals dictionary with another dictionary.</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="updateGlobals"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">updateGlobals </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+updateGlobals ( self, otherGlobals )
+
+</pre></font>
+
+<p>Merge another mapping object into this interpreter's globals.</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="wrap"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">wrap </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+wrap (
+ self,
+ callable,
+ args,
+ )
+
+</pre></font>
+
+<p>Wrap around an application of a callable and handle errors.
+ Return whether no error occurred.</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="write"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">write </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+write ( self, data )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="writelines"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">writelines </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+writelines ( self, stuff )
+
+</pre></font>
+
+</td></tr>
+</td></tr>
+</table>
+
+ </td>
+ </tr>
+ </table>
+
+ <hr>
+
+ <p><i><a href="../../../../../../index.html">Table of Contents</a></i></p>
+
+ <font size="-2"><i>This document was automatically generated
+ on Mon Oct 27 01:29:13 2003 by
+ <a href="http://happydoc.sourceforge.net">HappyDoc</a> version
+ 2.1</i></font>
+
+ </body>
+ </html>
+
\ No newline at end of file
--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html40/loose.dtd">
+
+<html>
+
+ <head>
+ <title>Class: LineBufferedFilter</title>
+ </head>
+
+ <body bgcolor="#ffffff">
+
+ <p><i><a href="../../../../../../index.html">Table of Contents</a></i></p>
+
+ <table border="0" cellpadding="5" cellspacing="0" width="100%">
+ <tr>
+ <th rowspan="2"
+ valign="top"
+ align="left"
+ width="10%"
+ bgcolor="#88bbee"><font color="#000000">Class: LineBufferedFilter</font>
+ </th>
+ <th bgcolor="#88bbee"
+ width="90%"
+ align="right"><font color="#000000">em.py</font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<p>A line-buffered filter only lets data through when it sees
+ whole lines.</p>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Base Classes">Base Classes</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<a href="BufferedFilter.html">BufferedFilter</a><br>
+<ul>
+
+<a href="Filter.html">Filter</a><br>
+
+</ul>
+
+</td></tr>
+</table>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Methods">Methods</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<a href="#__init__">__init__</a><br>
+<a href="#write">write</a><br>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="__init__"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">__init__ </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+__init__ ( self )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="write"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">write </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+write ( self, data )
+
+</pre></font>
+
+</td></tr>
+</td></tr>
+</table>
+
+ </td>
+ </tr>
+ </table>
+
+ <hr>
+
+ <p><i><a href="../../../../../../index.html">Table of Contents</a></i></p>
+
+ <font size="-2"><i>This document was automatically generated
+ on Mon Oct 27 01:29:13 2003 by
+ <a href="http://happydoc.sourceforge.net">HappyDoc</a> version
+ 2.1</i></font>
+
+ </body>
+ </html>
+
\ No newline at end of file
--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html40/loose.dtd">
+
+<html>
+
+ <head>
+ <title>Class: LiteralToken</title>
+ </head>
+
+ <body bgcolor="#ffffff">
+
+ <p><i><a href="../../../../../../index.html">Table of Contents</a></i></p>
+
+ <table border="0" cellpadding="5" cellspacing="0" width="100%">
+ <tr>
+ <th rowspan="2"
+ valign="top"
+ align="left"
+ width="10%"
+ bgcolor="#88bbee"><font color="#000000">Class: LiteralToken</font>
+ </th>
+ <th bgcolor="#88bbee"
+ width="90%"
+ align="right"><font color="#000000">em.py</font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<p>A literal markup.</p>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Base Classes">Base Classes</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<a href="ExpansionToken.html">ExpansionToken</a><br>
+<ul>
+
+<a href="Token.html">Token</a><br>
+
+</ul>
+
+</td></tr>
+</table>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Methods">Methods</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<a href="#run">run</a><br>
+<a href="#string">string</a><br>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="run"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">run </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+run (
+ self,
+ interpreter,
+ locals,
+ )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="string"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">string </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+string ( self )
+
+</pre></font>
+
+</td></tr>
+</td></tr>
+</table>
+
+ </td>
+ </tr>
+ </table>
+
+ <hr>
+
+ <p><i><a href="../../../../../../index.html">Table of Contents</a></i></p>
+
+ <font size="-2"><i>This document was automatically generated
+ on Mon Oct 27 01:29:13 2003 by
+ <a href="http://happydoc.sourceforge.net">HappyDoc</a> version
+ 2.1</i></font>
+
+ </body>
+ </html>
+
\ No newline at end of file
--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html40/loose.dtd">
+
+<html>
+
+ <head>
+ <title>Class: MaximallyBufferedFilter</title>
+ </head>
+
+ <body bgcolor="#ffffff">
+
+ <p><i><a href="../../../../../../index.html">Table of Contents</a></i></p>
+
+ <table border="0" cellpadding="5" cellspacing="0" width="100%">
+ <tr>
+ <th rowspan="2"
+ valign="top"
+ align="left"
+ width="10%"
+ bgcolor="#88bbee"><font color="#000000">Class: MaximallyBufferedFilter</font>
+ </th>
+ <th bgcolor="#88bbee"
+ width="90%"
+ align="right"><font color="#000000">em.py</font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<p>A maximally-buffered filter only lets its data through on the final
+ close. It ignores flushes.</p>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Base Classes">Base Classes</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<a href="BufferedFilter.html">BufferedFilter</a><br>
+<ul>
+
+<a href="Filter.html">Filter</a><br>
+
+</ul>
+
+</td></tr>
+</table>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Methods">Methods</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<a href="#__init__">__init__</a><br>
+<a href="#close">close</a><br>
+<a href="#flush">flush</a><br>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="__init__"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">__init__ </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+__init__ ( self )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="close"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">close </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+close ( self )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="flush"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">flush </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+flush ( self )
+
+</pre></font>
+
+</td></tr>
+</td></tr>
+</table>
+
+ </td>
+ </tr>
+ </table>
+
+ <hr>
+
+ <p><i><a href="../../../../../../index.html">Table of Contents</a></i></p>
+
+ <font size="-2"><i>This document was automatically generated
+ on Mon Oct 27 01:29:13 2003 by
+ <a href="http://happydoc.sourceforge.net">HappyDoc</a> version
+ 2.1</i></font>
+
+ </body>
+ </html>
+
\ No newline at end of file
--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html40/loose.dtd">
+
+<html>
+
+ <head>
+ <title>Class: MetaError</title>
+ </head>
+
+ <body bgcolor="#ffffff">
+
+ <p><i><a href="../../../../../../index.html">Table of Contents</a></i></p>
+
+ <table border="0" cellpadding="5" cellspacing="0" width="100%">
+ <tr>
+ <th rowspan="2"
+ valign="top"
+ align="left"
+ width="10%"
+ bgcolor="#88bbee"><font color="#000000">Class: MetaError</font>
+ </th>
+ <th bgcolor="#88bbee"
+ width="90%"
+ align="right"><font color="#000000">em.py</font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<p>A wrapper around a real Python exception for including a copy of
+ the context.</p>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Base Classes">Base Classes</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+Exception<br>
+
+</td></tr>
+</table>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Methods">Methods</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<a href="#__init__">__init__</a><br>
+<a href="#__str__">__str__</a><br>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="__init__"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">__init__ </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+__init__ (
+ self,
+ contexts,
+ exc,
+ )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="__str__"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">__str__ </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+__str__ ( self )
+
+</pre></font>
+
+</td></tr>
+</td></tr>
+</table>
+
+ </td>
+ </tr>
+ </table>
+
+ <hr>
+
+ <p><i><a href="../../../../../../index.html">Table of Contents</a></i></p>
+
+ <font size="-2"><i>This document was automatically generated
+ on Mon Oct 27 01:29:13 2003 by
+ <a href="http://happydoc.sourceforge.net">HappyDoc</a> version
+ 2.1</i></font>
+
+ </body>
+ </html>
+
\ No newline at end of file
--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html40/loose.dtd">
+
+<html>
+
+ <head>
+ <title>Class: NullFile</title>
+ </head>
+
+ <body bgcolor="#ffffff">
+
+ <p><i><a href="../../../../../../index.html">Table of Contents</a></i></p>
+
+ <table border="0" cellpadding="5" cellspacing="0" width="100%">
+ <tr>
+ <th rowspan="2"
+ valign="top"
+ align="left"
+ width="10%"
+ bgcolor="#88bbee"><font color="#000000">Class: NullFile</font>
+ </th>
+ <th bgcolor="#88bbee"
+ width="90%"
+ align="right"><font color="#000000">em.py</font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<p>A simple class that supports all the file-like object methods
+ but simply does nothing at all.</p>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Methods">Methods</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<a href="#__init__">__init__</a><br>
+<a href="#close">close</a><br>
+<a href="#flush">flush</a><br>
+<a href="#write">write</a><br>
+<a href="#writelines">writelines</a><br>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="__init__"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">__init__ </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+__init__ ( self )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="close"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">close </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+close ( self )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="flush"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">flush </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+flush ( self )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="write"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">write </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+write ( self, data )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="writelines"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">writelines </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+writelines ( self, lines )
+
+</pre></font>
+
+</td></tr>
+</td></tr>
+</table>
+
+ </td>
+ </tr>
+ </table>
+
+ <hr>
+
+ <p><i><a href="../../../../../../index.html">Table of Contents</a></i></p>
+
+ <font size="-2"><i>This document was automatically generated
+ on Mon Oct 27 01:29:13 2003 by
+ <a href="http://happydoc.sourceforge.net">HappyDoc</a> version
+ 2.1</i></font>
+
+ </body>
+ </html>
+
\ No newline at end of file
--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html40/loose.dtd">
+
+<html>
+
+ <head>
+ <title>Class: NullFilter</title>
+ </head>
+
+ <body bgcolor="#ffffff">
+
+ <p><i><a href="../../../../../../index.html">Table of Contents</a></i></p>
+
+ <table border="0" cellpadding="5" cellspacing="0" width="100%">
+ <tr>
+ <th rowspan="2"
+ valign="top"
+ align="left"
+ width="10%"
+ bgcolor="#88bbee"><font color="#000000">Class: NullFilter</font>
+ </th>
+ <th bgcolor="#88bbee"
+ width="90%"
+ align="right"><font color="#000000">em.py</font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<p>A filter that never sends any output to its sink.</p>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Base Classes">Base Classes</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<a href="Filter.html">Filter</a><br>
+
+</td></tr>
+</table>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Methods">Methods</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<a href="#write">write</a><br>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="write"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">write </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+write ( self, data )
+
+</pre></font>
+
+</td></tr>
+</td></tr>
+</table>
+
+ </td>
+ </tr>
+ </table>
+
+ <hr>
+
+ <p><i><a href="../../../../../../index.html">Table of Contents</a></i></p>
+
+ <font size="-2"><i>This document was automatically generated
+ on Mon Oct 27 01:29:13 2003 by
+ <a href="http://happydoc.sourceforge.net">HappyDoc</a> version
+ 2.1</i></font>
+
+ </body>
+ </html>
+
\ No newline at end of file
--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html40/loose.dtd">
+
+<html>
+
+ <head>
+ <title>Class: NullToken</title>
+ </head>
+
+ <body bgcolor="#ffffff">
+
+ <p><i><a href="../../../../../../index.html">Table of Contents</a></i></p>
+
+ <table border="0" cellpadding="5" cellspacing="0" width="100%">
+ <tr>
+ <th rowspan="2"
+ valign="top"
+ align="left"
+ width="10%"
+ bgcolor="#88bbee"><font color="#000000">Class: NullToken</font>
+ </th>
+ <th bgcolor="#88bbee"
+ width="90%"
+ align="right"><font color="#000000">em.py</font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<p>A chunk of data not containing markups.</p>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Base Classes">Base Classes</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<a href="Token.html">Token</a><br>
+
+</td></tr>
+</table>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Methods">Methods</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<a href="#__init__">__init__</a><br>
+<a href="#run">run</a><br>
+<a href="#string">string</a><br>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="__init__"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">__init__ </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+__init__ ( self, data )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="run"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">run </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+run (
+ self,
+ interpreter,
+ locals,
+ )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="string"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">string </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+string ( self )
+
+</pre></font>
+
+</td></tr>
+</td></tr>
+</table>
+
+ </td>
+ </tr>
+ </table>
+
+ <hr>
+
+ <p><i><a href="../../../../../../index.html">Table of Contents</a></i></p>
+
+ <font size="-2"><i>This document was automatically generated
+ on Mon Oct 27 01:29:13 2003 by
+ <a href="http://happydoc.sourceforge.net">HappyDoc</a> version
+ 2.1</i></font>
+
+ </body>
+ </html>
+
\ No newline at end of file
--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html40/loose.dtd">
+
+<html>
+
+ <head>
+ <title>Class: ParseError</title>
+ </head>
+
+ <body bgcolor="#ffffff">
+
+ <p><i><a href="../../../../../../index.html">Table of Contents</a></i></p>
+
+ <table border="0" cellpadding="5" cellspacing="0" width="100%">
+ <tr>
+ <th rowspan="2"
+ valign="top"
+ align="left"
+ width="10%"
+ bgcolor="#88bbee"><font color="#000000">Class: ParseError</font>
+ </th>
+ <th bgcolor="#88bbee"
+ width="90%"
+ align="right"><font color="#000000">em.py</font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<p>A parse error occurred.</p>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Base Classes">Base Classes</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<a href="Error.html">Error</a><br>
+<ul>
+
+Exception<br>
+
+</ul>
+
+</td></tr>
+</table>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+</td></tr>
+</table>
+
+ </td>
+ </tr>
+ </table>
+
+ <hr>
+
+ <p><i><a href="../../../../../../index.html">Table of Contents</a></i></p>
+
+ <font size="-2"><i>This document was automatically generated
+ on Mon Oct 27 01:29:13 2003 by
+ <a href="http://happydoc.sourceforge.net">HappyDoc</a> version
+ 2.1</i></font>
+
+ </body>
+ </html>
+
\ No newline at end of file
--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html40/loose.dtd">
+
+<html>
+
+ <head>
+ <title>Class: PrefixToken</title>
+ </head>
+
+ <body bgcolor="#ffffff">
+
+ <p><i><a href="../../../../../../index.html">Table of Contents</a></i></p>
+
+ <table border="0" cellpadding="5" cellspacing="0" width="100%">
+ <tr>
+ <th rowspan="2"
+ valign="top"
+ align="left"
+ width="10%"
+ bgcolor="#88bbee"><font color="#000000">Class: PrefixToken</font>
+ </th>
+ <th bgcolor="#88bbee"
+ width="90%"
+ align="right"><font color="#000000">em.py</font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<p>A prefix markup.</p>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Base Classes">Base Classes</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<a href="ExpansionToken.html">ExpansionToken</a><br>
+<ul>
+
+<a href="Token.html">Token</a><br>
+
+</ul>
+
+</td></tr>
+</table>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Methods">Methods</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<a href="#run">run</a><br>
+<a href="#string">string</a><br>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="run"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">run </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+run (
+ self,
+ interpreter,
+ locals,
+ )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="string"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">string </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+string ( self )
+
+</pre></font>
+
+</td></tr>
+</td></tr>
+</table>
+
+ </td>
+ </tr>
+ </table>
+
+ <hr>
+
+ <p><i><a href="../../../../../../index.html">Table of Contents</a></i></p>
+
+ <font size="-2"><i>This document was automatically generated
+ on Mon Oct 27 01:29:13 2003 by
+ <a href="http://happydoc.sourceforge.net">HappyDoc</a> version
+ 2.1</i></font>
+
+ </body>
+ </html>
+
\ No newline at end of file
--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html40/loose.dtd">
+
+<html>
+
+ <head>
+ <title>Class: Processor</title>
+ </head>
+
+ <body bgcolor="#ffffff">
+
+ <p><i><a href="../../../../../../index.html">Table of Contents</a></i></p>
+
+ <table border="0" cellpadding="5" cellspacing="0" width="100%">
+ <tr>
+ <th rowspan="2"
+ valign="top"
+ align="left"
+ width="10%"
+ bgcolor="#88bbee"><font color="#000000">Class: Processor</font>
+ </th>
+ <th bgcolor="#88bbee"
+ width="90%"
+ align="right"><font color="#000000">em.py</font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<p>An entity which is capable of processing a hierarchy of EmPy
+ files and building a dictionary of document objects associated
+ with them describing their significator contents.</p>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Methods">Methods</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<a href="#__init__">__init__</a><br>
+<a href="#clear">clear</a><br>
+<a href="#directory">directory</a><br>
+<a href="#file">file</a><br>
+<a href="#identifier">identifier</a><br>
+<a href="#line">line</a><br>
+<a href="#postprocess">postprocess</a><br>
+<a href="#scan">scan</a><br>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="__init__"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">__init__ </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+__init__ ( self, factory=Document )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="clear"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">clear </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+clear ( self )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="directory"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">directory </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+directory (
+ self,
+ basename,
+ dirCriteria,
+ fileCriteria,
+ depth=None,
+ )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="file"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">file </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+file (
+ self,
+ document,
+ file,
+ )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="identifier"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">identifier </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+identifier (
+ self,
+ pathname,
+ filename,
+ )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="line"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">line </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+line (
+ self,
+ document,
+ line,
+ )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="postprocess"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">postprocess </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+postprocess ( self )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="scan"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">scan </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+scan (
+ self,
+ basename,
+ extensions=DEFAULT_EMPY_EXTENSIONS,
+ )
+
+</pre></font>
+
+</td></tr>
+</td></tr>
+</table>
+
+ </td>
+ </tr>
+ </table>
+
+ <hr>
+
+ <p><i><a href="../../../../../../index.html">Table of Contents</a></i></p>
+
+ <font size="-2"><i>This document was automatically generated
+ on Mon Oct 27 01:29:13 2003 by
+ <a href="http://happydoc.sourceforge.net">HappyDoc</a> version
+ 2.1</i></font>
+
+ </body>
+ </html>
+
\ No newline at end of file
--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html40/loose.dtd">
+
+<html>
+
+ <head>
+ <title>Class: ProxyFile</title>
+ </head>
+
+ <body bgcolor="#ffffff">
+
+ <p><i><a href="../../../../../../index.html">Table of Contents</a></i></p>
+
+ <table border="0" cellpadding="5" cellspacing="0" width="100%">
+ <tr>
+ <th rowspan="2"
+ valign="top"
+ align="left"
+ width="10%"
+ bgcolor="#88bbee"><font color="#000000">Class: ProxyFile</font>
+ </th>
+ <th bgcolor="#88bbee"
+ width="90%"
+ align="right"><font color="#000000">em.py</font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<p>The proxy file object that is intended to take the place of
+ sys.stdout. The proxy can manage a stack of file objects it is
+ writing to, and an underlying raw file object.</p>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Methods">Methods</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+
+ <table border="0" cellspacing="2" cellpadding="2" width="100%">
+ <tr>
+ <td align="LEFT" valign="TOP">
+<a href="#__init__">__init__</a><br>
+<a href="#_testProxy">_testProxy</a><br>
+<a href="#clear">clear</a><br>
+<a href="#close">close</a><br>
+<a href="#current">current</a><br>
+</td>
+<td align="LEFT" valign="TOP">
+<a href="#flush">flush</a><br>
+<a href="#pop">pop</a><br>
+<a href="#push">push</a><br>
+<a href="#write">write</a><br>
+<a href="#writelines">writelines</a><br>
+</td>
+</tr>
+ </table>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="__init__"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">__init__ </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+__init__ ( self, bottom )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="_testProxy"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">_testProxy </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+_testProxy ( self )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="clear"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">clear </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+clear ( self, interpreter )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="close"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">close </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+close ( self )
+
+</pre></font>
+
+<p>Close the current file. If the current file is the bottom, then
+ close it and dispose of it.</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="current"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">current </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+current ( self )
+
+</pre></font>
+
+<p>Get the current stream to write to.</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="flush"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">flush </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+flush ( self )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="pop"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">pop </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+pop ( self, interpreter )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="push"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">push </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+push ( self, interpreter )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="write"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">write </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+write ( self, data )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="writelines"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">writelines </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+writelines ( self, lines )
+
+</pre></font>
+
+</td></tr>
+</td></tr>
+</table>
+
+ </td>
+ </tr>
+ </table>
+
+ <hr>
+
+ <p><i><a href="../../../../../../index.html">Table of Contents</a></i></p>
+
+ <font size="-2"><i>This document was automatically generated
+ on Mon Oct 27 01:29:13 2003 by
+ <a href="http://happydoc.sourceforge.net">HappyDoc</a> version
+ 2.1</i></font>
+
+ </body>
+ </html>
+
\ No newline at end of file
--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html40/loose.dtd">
+
+<html>
+
+ <head>
+ <title>Class: ReprToken</title>
+ </head>
+
+ <body bgcolor="#ffffff">
+
+ <p><i><a href="../../../../../../index.html">Table of Contents</a></i></p>
+
+ <table border="0" cellpadding="5" cellspacing="0" width="100%">
+ <tr>
+ <th rowspan="2"
+ valign="top"
+ align="left"
+ width="10%"
+ bgcolor="#88bbee"><font color="#000000">Class: ReprToken</font>
+ </th>
+ <th bgcolor="#88bbee"
+ width="90%"
+ align="right"><font color="#000000">em.py</font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<p>A repr markup.</p>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Base Classes">Base Classes</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<a href="ExpansionToken.html">ExpansionToken</a><br>
+<ul>
+
+<a href="Token.html">Token</a><br>
+
+</ul>
+
+</td></tr>
+</table>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Methods">Methods</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<a href="#run">run</a><br>
+<a href="#scan">scan</a><br>
+<a href="#string">string</a><br>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="run"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">run </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+run (
+ self,
+ interpreter,
+ locals,
+ )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="scan"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">scan </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+scan ( self, scanner )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="string"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">string </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+string ( self )
+
+</pre></font>
+
+</td></tr>
+</td></tr>
+</table>
+
+ </td>
+ </tr>
+ </table>
+
+ <hr>
+
+ <p><i><a href="../../../../../../index.html">Table of Contents</a></i></p>
+
+ <font size="-2"><i>This document was automatically generated
+ on Mon Oct 27 01:29:13 2003 by
+ <a href="http://happydoc.sourceforge.net">HappyDoc</a> version
+ 2.1</i></font>
+
+ </body>
+ </html>
+
\ No newline at end of file
--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html40/loose.dtd">
+
+<html>
+
+ <head>
+ <title>Class: Scanner</title>
+ </head>
+
+ <body bgcolor="#ffffff">
+
+ <p><i><a href="../../../../../../index.html">Table of Contents</a></i></p>
+
+ <table border="0" cellpadding="5" cellspacing="0" width="100%">
+ <tr>
+ <th rowspan="2"
+ valign="top"
+ align="left"
+ width="10%"
+ bgcolor="#88bbee"><font color="#000000">Class: Scanner</font>
+ </th>
+ <th bgcolor="#88bbee"
+ width="90%"
+ align="right"><font color="#000000">em.py</font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<p>A scanner holds a buffer for lookahead parsing and has the
+ ability to scan for special symbols and indicators in that
+ buffer.</p>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Methods">Methods</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+
+ <table border="0" cellspacing="2" cellpadding="2" width="100%">
+ <tr>
+ <td align="LEFT" valign="TOP">
+<a href="#__getitem__">__getitem__</a><br>
+<a href="#__getslice__">__getslice__</a><br>
+<a href="#__init__">__init__</a><br>
+<a href="#__len__">__len__</a><br>
+<a href="#__nonzero__">__nonzero__</a><br>
+<a href="#acquire">acquire</a><br>
+<a href="#advance">advance</a><br>
+<a href="#check">check</a><br>
+<a href="#chop">chop</a><br>
+</td>
+<td align="LEFT" valign="TOP">
+<a href="#complex">complex</a><br>
+<a href="#feed">feed</a><br>
+<a href="#find">find</a><br>
+<a href="#last">last</a><br>
+<a href="#nested">nested</a><br>
+<a href="#next">next</a><br>
+<a href="#one">one</a><br>
+<a href="#phrase">phrase</a><br>
+<a href="#quote">quote</a><br>
+</td>
+<td align="LEFT" valign="TOP">
+<a href="#read">read</a><br>
+<a href="#release">release</a><br>
+<a href="#rest">rest</a><br>
+<a href="#retreat">retreat</a><br>
+<a href="#set">set</a><br>
+<a href="#simple">simple</a><br>
+<a href="#sync">sync</a><br>
+<a href="#unsync">unsync</a><br>
+<a href="#word">word</a><br>
+</td>
+</tr>
+ </table>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="__getitem__"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">__getitem__ </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+__getitem__ ( self, index )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="__getslice__"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">__getslice__ </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+__getslice__ (
+ self,
+ start,
+ stop,
+ )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="__init__"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">__init__ </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+__init__ (
+ self,
+ prefix,
+ data='',
+ )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="__len__"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">__len__ </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+__len__ ( self )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="__nonzero__"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">__nonzero__ </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+__nonzero__ ( self )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="acquire"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">acquire </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+acquire ( self )
+
+</pre></font>
+
+<p>Lock the scanner so it doesn't destroy data on sync.</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="advance"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">advance </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+advance ( self, count=1 )
+
+</pre></font>
+
+<p>Advance the pointer count characters.</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="check"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">check </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+check (
+ self,
+ i,
+ archetype=None,
+ )
+
+</pre></font>
+
+<p>Scan for the next single or triple quote, with the specified
+ archetype. Return the found quote or None.</p>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Exceptions">Exceptions</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+TransientParseError, "need to scan for rest of quote"<br>
+
+</td></tr>
+</table>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="chop"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">chop </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+chop (
+ self,
+ count=None,
+ slop=0,
+ )
+
+</pre></font>
+
+<p>Chop the first count + slop characters off the front, and return
+ the first count. If count is not specified, then return
+ everything.</p>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Exceptions">Exceptions</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+TransientParseError, "not enough data to read"<br>
+
+</td></tr>
+</table>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="complex"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">complex </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+complex (
+ self,
+ enter,
+ exit,
+ start=0,
+ end=None,
+ skip=None,
+ )
+
+</pre></font>
+
+<p>Scan from i for an ending sequence, respecting quotes,
+ entries and exits.</p>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Exceptions">Exceptions</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+TransientParseError, "expecting end of complex expression"<br>
+
+</td></tr>
+</table>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="feed"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">feed </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+feed ( self, data )
+
+</pre></font>
+
+<p>Feed some more data to the scanner.</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="find"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">find </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+find (
+ self,
+ sub,
+ start=0,
+ end=None,
+ )
+
+</pre></font>
+
+<p>Find the next occurrence of the character, or return -1.</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="last"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">last </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+last (
+ self,
+ char,
+ start=0,
+ end=None,
+ )
+
+</pre></font>
+
+<p>Find the first character that is <u>not</u> the specified character.</p>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Exceptions">Exceptions</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+TransientParseError, "expecting other than %s" % char<br>
+
+</td></tr>
+</table>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="nested"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">nested </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+nested (
+ self,
+ enter,
+ exit,
+ start=0,
+ end=None,
+ )
+
+</pre></font>
+
+<p>Scan from i for an ending sequence, respecting entries and exits
+ only.</p>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Exceptions">Exceptions</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+TransientParseError, "expecting end of complex expression"<br>
+
+</td></tr>
+</table>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="next"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">next </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+next (
+ self,
+ target,
+ start=0,
+ end=None,
+ mandatory=False,
+ )
+
+</pre></font>
+
+<p>Scan for the next occurrence of one of the characters in
+ the target string; optionally, make the scan mandatory.</p>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Exceptions">Exceptions</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+ParseError, "expecting %s, not found" % target<br>
+TransientParseError, "expecting ending character"<br>
+
+</td></tr>
+</table>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="one"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">one </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+one ( self )
+
+</pre></font>
+
+<p>Parse and return one token, or None if the scanner is empty.</p>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Exceptions">Exceptions</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+ParseError, "unknown markup: %s%s" %( self.prefix, first )<br>
+
+</td></tr>
+</table>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="phrase"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">phrase </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+phrase ( self, start=0 )
+
+</pre></font>
+
+<p>Scan from i for a phrase (e.g., <code>word</code>, <code>f(a, b, c)</code>, 'a<a href="#refi">[i]</a>', or
+ combinations like 'x<a href="#refi">[i]</a>(a)'.</p>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Exceptions">Exceptions</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+ParseError, "curly braces can't open simple expressions"<br>
+
+</td></tr>
+</table>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="quote"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">quote </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+quote (
+ self,
+ start=0,
+ end=None,
+ mandatory=False,
+ )
+
+</pre></font>
+
+<p>Scan for the end of the next quote.</p>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Exceptions">Exceptions</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+ParseError, "expecting end of string literal"<br>
+TransientParseError, "expecting end of string literal"<br>
+
+</td></tr>
+</table>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="read"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">read </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+read (
+ self,
+ i=0,
+ count=1,
+ )
+
+</pre></font>
+
+<p>Read count chars starting from i; raise a transient error if
+ there aren't enough characters remaining.</p>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Exceptions">Exceptions</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+TransientParseError, "need more data to read"<br>
+
+</td></tr>
+</table>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="release"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">release </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+release ( self )
+
+</pre></font>
+
+<p>Unlock the scanner.</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="rest"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">rest </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+rest ( self )
+
+</pre></font>
+
+<p>Get the remainder of the buffer.</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="retreat"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">retreat </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+retreat ( self, count=1 )
+
+</pre></font>
+
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Exceptions">Exceptions</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+ParseError, "can't retreat back over synced out chars"<br>
+
+</td></tr>
+</table>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="set"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">set </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+set ( self, data )
+
+</pre></font>
+
+<p>Start the scanner digesting a new batch of data; start the pointer
+ over from scratch.</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="simple"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">simple </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+simple ( self, start=0 )
+
+</pre></font>
+
+<p>Scan from i for a simple expression, which consists of one
+ more phrases separated by dots.</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="sync"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">sync </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+sync ( self )
+
+</pre></font>
+
+<p>Sync up the buffer with the read head.</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="unsync"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">unsync </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+unsync ( self )
+
+</pre></font>
+
+<p>Undo changes; reset the read head.</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="word"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">word </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+word ( self, start=0 )
+
+</pre></font>
+
+<p>Scan from i for a simple word.</p>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Exceptions">Exceptions</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+TransientParseError, "expecting end of word"<br>
+
+</td></tr>
+</table>
+</td></tr>
+</td></tr>
+</table>
+
+ </td>
+ </tr>
+ </table>
+
+ <hr>
+
+ <p><i><a href="../../../../../../index.html">Table of Contents</a></i></p>
+
+ <font size="-2"><i>This document was automatically generated
+ on Mon Oct 27 01:29:13 2003 by
+ <a href="http://happydoc.sourceforge.net">HappyDoc</a> version
+ 2.1</i></font>
+
+ </body>
+ </html>
+
\ No newline at end of file
--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html40/loose.dtd">
+
+<html>
+
+ <head>
+ <title>Class: SignificatorToken</title>
+ </head>
+
+ <body bgcolor="#ffffff">
+
+ <p><i><a href="../../../../../../index.html">Table of Contents</a></i></p>
+
+ <table border="0" cellpadding="5" cellspacing="0" width="100%">
+ <tr>
+ <th rowspan="2"
+ valign="top"
+ align="left"
+ width="10%"
+ bgcolor="#88bbee"><font color="#000000">Class: SignificatorToken</font>
+ </th>
+ <th bgcolor="#88bbee"
+ width="90%"
+ align="right"><font color="#000000">em.py</font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<p>A significator markup.</p>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Base Classes">Base Classes</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<a href="ExpansionToken.html">ExpansionToken</a><br>
+<ul>
+
+<a href="Token.html">Token</a><br>
+
+</ul>
+
+</td></tr>
+</table>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Methods">Methods</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<a href="#run">run</a><br>
+<a href="#scan">scan</a><br>
+<a href="#string">string</a><br>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="run"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">run </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+run (
+ self,
+ interpreter,
+ locals,
+ )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="scan"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">scan </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+scan ( self, scanner )
+
+</pre></font>
+
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Exceptions">Exceptions</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+ParseError, "no whitespace between % and key"<br>
+ParseError, "significator must have nonblank key"<br>
+TransientParseError, "significator expects newline"<br>
+
+</td></tr>
+</table>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="string"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">string </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+string ( self )
+
+</pre></font>
+
+</td></tr>
+</td></tr>
+</table>
+
+ </td>
+ </tr>
+ </table>
+
+ <hr>
+
+ <p><i><a href="../../../../../../index.html">Table of Contents</a></i></p>
+
+ <font size="-2"><i>This document was automatically generated
+ on Mon Oct 27 01:29:13 2003 by
+ <a href="http://happydoc.sourceforge.net">HappyDoc</a> version
+ 2.1</i></font>
+
+ </body>
+ </html>
+
\ No newline at end of file
--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html40/loose.dtd">
+
+<html>
+
+ <head>
+ <title>Class: SimpleExpressionToken</title>
+ </head>
+
+ <body bgcolor="#ffffff">
+
+ <p><i><a href="../../../../../../index.html">Table of Contents</a></i></p>
+
+ <table border="0" cellpadding="5" cellspacing="0" width="100%">
+ <tr>
+ <th rowspan="2"
+ valign="top"
+ align="left"
+ width="10%"
+ bgcolor="#88bbee"><font color="#000000">Class: SimpleExpressionToken</font>
+ </th>
+ <th bgcolor="#88bbee"
+ width="90%"
+ align="right"><font color="#000000">em.py</font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<p>A simple expression markup.</p>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Base Classes">Base Classes</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<a href="ExpansionToken.html">ExpansionToken</a><br>
+<ul>
+
+<a href="Token.html">Token</a><br>
+
+</ul>
+
+</td></tr>
+</table>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Methods">Methods</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<a href="#run">run</a><br>
+<a href="#scan">scan</a><br>
+<a href="#string">string</a><br>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="run"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">run </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+run (
+ self,
+ interpreter,
+ locals,
+ )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="scan"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">scan </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+scan ( self, scanner )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="string"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">string </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+string ( self )
+
+</pre></font>
+
+</td></tr>
+</td></tr>
+</table>
+
+ </td>
+ </tr>
+ </table>
+
+ <hr>
+
+ <p><i><a href="../../../../../../index.html">Table of Contents</a></i></p>
+
+ <font size="-2"><i>This document was automatically generated
+ on Mon Oct 27 01:29:13 2003 by
+ <a href="http://happydoc.sourceforge.net">HappyDoc</a> version
+ 2.1</i></font>
+
+ </body>
+ </html>
+
\ No newline at end of file
--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html40/loose.dtd">
+
+<html>
+
+ <head>
+ <title>Class: SizeBufferedFilter</title>
+ </head>
+
+ <body bgcolor="#ffffff">
+
+ <p><i><a href="../../../../../../index.html">Table of Contents</a></i></p>
+
+ <table border="0" cellpadding="5" cellspacing="0" width="100%">
+ <tr>
+ <th rowspan="2"
+ valign="top"
+ align="left"
+ width="10%"
+ bgcolor="#88bbee"><font color="#000000">Class: SizeBufferedFilter</font>
+ </th>
+ <th bgcolor="#88bbee"
+ width="90%"
+ align="right"><font color="#000000">em.py</font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<p>A size-buffered filter only in fixed size chunks (excepting the
+ final chunk).</p>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Base Classes">Base Classes</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<a href="BufferedFilter.html">BufferedFilter</a><br>
+<ul>
+
+<a href="Filter.html">Filter</a><br>
+
+</ul>
+
+</td></tr>
+</table>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Methods">Methods</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<a href="#__init__">__init__</a><br>
+<a href="#write">write</a><br>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="__init__"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">__init__ </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+__init__ ( self, bufferSize )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="write"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">write </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+write ( self, data )
+
+</pre></font>
+
+</td></tr>
+</td></tr>
+</table>
+
+ </td>
+ </tr>
+ </table>
+
+ <hr>
+
+ <p><i><a href="../../../../../../index.html">Table of Contents</a></i></p>
+
+ <font size="-2"><i>This document was automatically generated
+ on Mon Oct 27 01:29:13 2003 by
+ <a href="http://happydoc.sourceforge.net">HappyDoc</a> version
+ 2.1</i></font>
+
+ </body>
+ </html>
+
\ No newline at end of file
--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html40/loose.dtd">
+
+<html>
+
+ <head>
+ <title>Class: Stack</title>
+ </head>
+
+ <body bgcolor="#ffffff">
+
+ <p><i><a href="../../../../../../index.html">Table of Contents</a></i></p>
+
+ <table border="0" cellpadding="5" cellspacing="0" width="100%">
+ <tr>
+ <th rowspan="2"
+ valign="top"
+ align="left"
+ width="10%"
+ bgcolor="#88bbee"><font color="#000000">Class: Stack</font>
+ </th>
+ <th bgcolor="#88bbee"
+ width="90%"
+ align="right"><font color="#000000">em.py</font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<p>A simple stack that behaves as a sequence (with 0 being the top
+ of the stack, not the bottom).</p>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Methods">Methods</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+
+ <table border="0" cellspacing="2" cellpadding="2" width="100%">
+ <tr>
+ <td align="LEFT" valign="TOP">
+<a href="#__getitem__">__getitem__</a><br>
+<a href="#__init__">__init__</a><br>
+<a href="#__len__">__len__</a><br>
+<a href="#__nonzero__">__nonzero__</a><br>
+<a href="#__repr__">__repr__</a><br>
+<a href="#clone">clone</a><br>
+</td>
+<td align="LEFT" valign="TOP">
+<a href="#filter">filter</a><br>
+<a href="#pop">pop</a><br>
+<a href="#purge">purge</a><br>
+<a href="#push">push</a><br>
+<a href="#top">top</a><br>
+</td>
+</tr>
+ </table>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="__getitem__"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">__getitem__ </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+__getitem__ ( self, index )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="__init__"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">__init__ </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+__init__ ( self, seq=None )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="__len__"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">__len__ </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+__len__ ( self )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="__nonzero__"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">__nonzero__ </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+__nonzero__ ( self )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="__repr__"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">__repr__ </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+__repr__ ( self )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="clone"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">clone </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+clone ( self )
+
+</pre></font>
+
+<p>Create a duplicate of this stack.</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="filter"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">filter </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+filter ( self, function )
+
+</pre></font>
+
+<p>Filter the elements of the stack through the function.</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="pop"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">pop </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+pop ( self )
+
+</pre></font>
+
+<p>Pop the top element off the stack and return it.</p>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Exceptions">Exceptions</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+StackUnderflowError, "stack is empty for pop"<br>
+
+</td></tr>
+</table>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="purge"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">purge </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+purge ( self )
+
+</pre></font>
+
+<p>Purge the stack.</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="push"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">push </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+push ( self, object )
+
+</pre></font>
+
+<p>Push an element onto the top of the stack.</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="top"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">top </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+top ( self )
+
+</pre></font>
+
+<p>Access the top element on the stack.</p>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Exceptions">Exceptions</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+StackUnderflowError, "stack is empty for top"<br>
+
+</td></tr>
+</table>
+</td></tr>
+</td></tr>
+</table>
+
+ </td>
+ </tr>
+ </table>
+
+ <hr>
+
+ <p><i><a href="../../../../../../index.html">Table of Contents</a></i></p>
+
+ <font size="-2"><i>This document was automatically generated
+ on Mon Oct 27 01:29:13 2003 by
+ <a href="http://happydoc.sourceforge.net">HappyDoc</a> version
+ 2.1</i></font>
+
+ </body>
+ </html>
+
\ No newline at end of file
--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html40/loose.dtd">
+
+<html>
+
+ <head>
+ <title>Class: StackUnderflowError</title>
+ </head>
+
+ <body bgcolor="#ffffff">
+
+ <p><i><a href="../../../../../../index.html">Table of Contents</a></i></p>
+
+ <table border="0" cellpadding="5" cellspacing="0" width="100%">
+ <tr>
+ <th rowspan="2"
+ valign="top"
+ align="left"
+ width="10%"
+ bgcolor="#88bbee"><font color="#000000">Class: StackUnderflowError</font>
+ </th>
+ <th bgcolor="#88bbee"
+ width="90%"
+ align="right"><font color="#000000">em.py</font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<p>A stack underflow.</p>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Base Classes">Base Classes</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<a href="Error.html">Error</a><br>
+<ul>
+
+Exception<br>
+
+</ul>
+
+</td></tr>
+</table>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+</td></tr>
+</table>
+
+ </td>
+ </tr>
+ </table>
+
+ <hr>
+
+ <p><i><a href="../../../../../../index.html">Table of Contents</a></i></p>
+
+ <font size="-2"><i>This document was automatically generated
+ on Mon Oct 27 01:29:13 2003 by
+ <a href="http://happydoc.sourceforge.net">HappyDoc</a> version
+ 2.1</i></font>
+
+ </body>
+ </html>
+
\ No newline at end of file
--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html40/loose.dtd">
+
+<html>
+
+ <head>
+ <title>Class: StatementToken</title>
+ </head>
+
+ <body bgcolor="#ffffff">
+
+ <p><i><a href="../../../../../../index.html">Table of Contents</a></i></p>
+
+ <table border="0" cellpadding="5" cellspacing="0" width="100%">
+ <tr>
+ <th rowspan="2"
+ valign="top"
+ align="left"
+ width="10%"
+ bgcolor="#88bbee"><font color="#000000">Class: StatementToken</font>
+ </th>
+ <th bgcolor="#88bbee"
+ width="90%"
+ align="right"><font color="#000000">em.py</font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<p>A statement markup.</p>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Base Classes">Base Classes</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<a href="ExpansionToken.html">ExpansionToken</a><br>
+<ul>
+
+<a href="Token.html">Token</a><br>
+
+</ul>
+
+</td></tr>
+</table>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Methods">Methods</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<a href="#run">run</a><br>
+<a href="#scan">scan</a><br>
+<a href="#string">string</a><br>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="run"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">run </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+run (
+ self,
+ interpreter,
+ locals,
+ )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="scan"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">scan </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+scan ( self, scanner )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="string"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">string </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+string ( self )
+
+</pre></font>
+
+</td></tr>
+</td></tr>
+</table>
+
+ </td>
+ </tr>
+ </table>
+
+ <hr>
+
+ <p><i><a href="../../../../../../index.html">Table of Contents</a></i></p>
+
+ <font size="-2"><i>This document was automatically generated
+ on Mon Oct 27 01:29:13 2003 by
+ <a href="http://happydoc.sourceforge.net">HappyDoc</a> version
+ 2.1</i></font>
+
+ </body>
+ </html>
+
\ No newline at end of file
--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html40/loose.dtd">
+
+<html>
+
+ <head>
+ <title>Class: Stream</title>
+ </head>
+
+ <body bgcolor="#ffffff">
+
+ <p><i><a href="../../../../../../index.html">Table of Contents</a></i></p>
+
+ <table border="0" cellpadding="5" cellspacing="0" width="100%">
+ <tr>
+ <th rowspan="2"
+ valign="top"
+ align="left"
+ width="10%"
+ bgcolor="#88bbee"><font color="#000000">Class: Stream</font>
+ </th>
+ <th bgcolor="#88bbee"
+ width="90%"
+ align="right"><font color="#000000">em.py</font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<p>A wrapper around an (output) file object which supports
+ diversions and filtering.</p>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Methods">Methods</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+
+ <table border="0" cellspacing="2" cellpadding="2" width="100%">
+ <tr>
+ <td align="LEFT" valign="TOP">
+<a href="#__init__">__init__</a><br>
+<a href="#attach">attach</a><br>
+<a href="#close">close</a><br>
+<a href="#create">create</a><br>
+<a href="#divert">divert</a><br>
+<a href="#flush">flush</a><br>
+<a href="#install">install</a><br>
+<a href="#last">last</a><br>
+<a href="#purge">purge</a><br>
+</td>
+<td align="LEFT" valign="TOP">
+<a href="#purgeAll">purgeAll</a><br>
+<a href="#retrieve">retrieve</a><br>
+<a href="#revert">revert</a><br>
+<a href="#shortcut">shortcut</a><br>
+<a href="#undivert">undivert</a><br>
+<a href="#undivertAll">undivertAll</a><br>
+<a href="#write">write</a><br>
+<a href="#writelines">writelines</a><br>
+</td>
+</tr>
+ </table>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="__init__"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">__init__ </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+__init__ ( self, file )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="attach"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">attach </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+attach ( self, shortcut )
+
+</pre></font>
+
+<p>Attached a solitary filter (no sequences allowed here) at the
+ end of the current filter chain.</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="close"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">close </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+close ( self )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="create"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">create </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+create ( self, name )
+
+</pre></font>
+
+<p>Create a diversion if one does not already exist, but do not
+ divert to it yet.</p>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Exceptions">Exceptions</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+DiversionError, "diversion name must be non-None"<br>
+
+</td></tr>
+</table>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="divert"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">divert </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+divert ( self, name )
+
+</pre></font>
+
+<p>Start diverting.</p>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Exceptions">Exceptions</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+DiversionError, "diversion name must be non-None"<br>
+
+</td></tr>
+</table>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="flush"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">flush </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+flush ( self )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="install"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">install </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+install ( self, shortcut=None )
+
+</pre></font>
+
+<p>Install a new filter; None means no filter. Handle all the
+ special shortcuts for filters here.</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="last"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">last </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+last ( self )
+
+</pre></font>
+
+<p>Find the last filter in the current filter chain, or None if
+ there are no filters installed.</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="purge"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">purge </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+purge ( self, name )
+
+</pre></font>
+
+<p>Purge the specified diversion.</p>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Exceptions">Exceptions</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+DiversionError, "diversion name must be non-None"<br>
+
+</td></tr>
+</table>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="purgeAll"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">purgeAll </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+purgeAll ( self )
+
+</pre></font>
+
+<p>Eliminate all existing diversions.</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="retrieve"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">retrieve </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+retrieve ( self, name )
+
+</pre></font>
+
+<p>Retrieve the given diversion.</p>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Exceptions">Exceptions</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+DiversionError, "diversion name must be non-None"<br>
+DiversionError, "nonexistent diversion: %s" % name<br>
+
+</td></tr>
+</table>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="revert"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">revert </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+revert ( self )
+
+</pre></font>
+
+<p>Reset any current diversions.</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="shortcut"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">shortcut </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+shortcut ( self, shortcut )
+
+</pre></font>
+
+<p>Take a filter shortcut and translate it into a filter, returning
+ it. Sequences don't count here; these should be detected
+ independently.</p>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Exceptions">Exceptions</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+NotImplementedError, "mapping filters not yet supported"<br>
+
+</td></tr>
+</table>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="undivert"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">undivert </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+undivert (
+ self,
+ name,
+ purgeAfterwards=False,
+ )
+
+</pre></font>
+
+<p>Undivert a particular diversion.</p>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Exceptions">Exceptions</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+DiversionError, "diversion name must be non-None"<br>
+DiversionError, "nonexistent diversion: %s" % name<br>
+
+</td></tr>
+</table>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="undivertAll"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">undivertAll </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+undivertAll ( self, purgeAfterwards=True )
+
+</pre></font>
+
+<p>Undivert all pending diversions.</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="write"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">write </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+write ( self, data )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="writelines"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">writelines </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+writelines ( self, lines )
+
+</pre></font>
+
+</td></tr>
+</td></tr>
+</table>
+
+ </td>
+ </tr>
+ </table>
+
+ <hr>
+
+ <p><i><a href="../../../../../../index.html">Table of Contents</a></i></p>
+
+ <font size="-2"><i>This document was automatically generated
+ on Mon Oct 27 01:29:13 2003 by
+ <a href="http://happydoc.sourceforge.net">HappyDoc</a> version
+ 2.1</i></font>
+
+ </body>
+ </html>
+
\ No newline at end of file
--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html40/loose.dtd">
+
+<html>
+
+ <head>
+ <title>Class: StringFilter</title>
+ </head>
+
+ <body bgcolor="#ffffff">
+
+ <p><i><a href="../../../../../../index.html">Table of Contents</a></i></p>
+
+ <table border="0" cellpadding="5" cellspacing="0" width="100%">
+ <tr>
+ <th rowspan="2"
+ valign="top"
+ align="left"
+ width="10%"
+ bgcolor="#88bbee"><font color="#000000">Class: StringFilter</font>
+ </th>
+ <th bgcolor="#88bbee"
+ width="90%"
+ align="right"><font color="#000000">em.py</font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<p>A filter that takes a translation string (256 characters) and
+ filters any incoming data through it.</p>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Base Classes">Base Classes</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<a href="Filter.html">Filter</a><br>
+
+</td></tr>
+</table>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Methods">Methods</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<a href="#__init__">__init__</a><br>
+<a href="#write">write</a><br>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="__init__"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">__init__ </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+__init__ ( self, table )
+
+</pre></font>
+
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Exceptions">Exceptions</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+FilterError, "table must be 256-character string"<br>
+
+</td></tr>
+</table>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="write"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">write </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+write ( self, data )
+
+</pre></font>
+
+</td></tr>
+</td></tr>
+</table>
+
+ </td>
+ </tr>
+ </table>
+
+ <hr>
+
+ <p><i><a href="../../../../../../index.html">Table of Contents</a></i></p>
+
+ <font size="-2"><i>This document was automatically generated
+ on Mon Oct 27 01:29:13 2003 by
+ <a href="http://happydoc.sourceforge.net">HappyDoc</a> version
+ 2.1</i></font>
+
+ </body>
+ </html>
+
\ No newline at end of file
--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html40/loose.dtd">
+
+<html>
+
+ <head>
+ <title>Class: StringLiteralToken</title>
+ </head>
+
+ <body bgcolor="#ffffff">
+
+ <p><i><a href="../../../../../../index.html">Table of Contents</a></i></p>
+
+ <table border="0" cellpadding="5" cellspacing="0" width="100%">
+ <tr>
+ <th rowspan="2"
+ valign="top"
+ align="left"
+ width="10%"
+ bgcolor="#88bbee"><font color="#000000">Class: StringLiteralToken</font>
+ </th>
+ <th bgcolor="#88bbee"
+ width="90%"
+ align="right"><font color="#000000">em.py</font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<p>A string token markup.</p>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Base Classes">Base Classes</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<a href="ExpansionToken.html">ExpansionToken</a><br>
+<ul>
+
+<a href="Token.html">Token</a><br>
+
+</ul>
+
+</td></tr>
+</table>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Methods">Methods</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<a href="#run">run</a><br>
+<a href="#scan">scan</a><br>
+<a href="#string">string</a><br>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="run"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">run </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+run (
+ self,
+ interpreter,
+ locals,
+ )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="scan"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">scan </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+scan ( self, scanner )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="string"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">string </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+string ( self )
+
+</pre></font>
+
+</td></tr>
+</td></tr>
+</table>
+
+ </td>
+ </tr>
+ </table>
+
+ <hr>
+
+ <p><i><a href="../../../../../../index.html">Table of Contents</a></i></p>
+
+ <font size="-2"><i>This document was automatically generated
+ on Mon Oct 27 01:29:13 2003 by
+ <a href="http://happydoc.sourceforge.net">HappyDoc</a> version
+ 2.1</i></font>
+
+ </body>
+ </html>
+
\ No newline at end of file
--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html40/loose.dtd">
+
+<html>
+
+ <head>
+ <title>Class: Subsystem</title>
+ </head>
+
+ <body bgcolor="#ffffff">
+
+ <p><i><a href="../../../../../../index.html">Table of Contents</a></i></p>
+
+ <table border="0" cellpadding="5" cellspacing="0" width="100%">
+ <tr>
+ <th rowspan="2"
+ valign="top"
+ align="left"
+ width="10%"
+ bgcolor="#88bbee"><font color="#000000">Class: Subsystem</font>
+ </th>
+ <th bgcolor="#88bbee"
+ width="90%"
+ align="right"><font color="#000000">em.py</font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<p>The subsystem class defers file creation so that it can create
+ Unicode-wrapped files if desired (and possible).</p>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Methods">Methods</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<a href="#__init__">__init__</a><br>
+<a href="#assertUnicode">assertUnicode</a><br>
+<a href="#defaultOpen">defaultOpen</a><br>
+<a href="#initialize">initialize</a><br>
+<a href="#open">open</a><br>
+<a href="#unicodeOpen">unicodeOpen</a><br>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="__init__"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">__init__ </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+__init__ ( self )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="assertUnicode"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">assertUnicode </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+assertUnicode ( self )
+
+</pre></font>
+
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Exceptions">Exceptions</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+SubsystemError, "Unicode subsystem unavailable"<br>
+
+</td></tr>
+</table>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="defaultOpen"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">defaultOpen </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+defaultOpen (
+ self,
+ name,
+ mode=None,
+ )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="initialize"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">initialize </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+initialize (
+ self,
+ inputEncoding=None,
+ outputEncoding=None,
+ inputErrors=None,
+ outputErrors=None,
+ )
+
+</pre></font>
+
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Exceptions">Exceptions</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+SubsystemError, "Unicode subsystem unavailable"<br>
+
+</td></tr>
+</table>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="open"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">open </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+open (
+ self,
+ name,
+ mode=None,
+ )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="unicodeOpen"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">unicodeOpen </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+unicodeOpen (
+ self,
+ name,
+ mode=None,
+ )
+
+</pre></font>
+
+</td></tr>
+</td></tr>
+</table>
+
+ </td>
+ </tr>
+ </table>
+
+ <hr>
+
+ <p><i><a href="../../../../../../index.html">Table of Contents</a></i></p>
+
+ <font size="-2"><i>This document was automatically generated
+ on Mon Oct 27 01:29:13 2003 by
+ <a href="http://happydoc.sourceforge.net">HappyDoc</a> version
+ 2.1</i></font>
+
+ </body>
+ </html>
+
\ No newline at end of file
--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html40/loose.dtd">
+
+<html>
+
+ <head>
+ <title>Class: SubsystemError</title>
+ </head>
+
+ <body bgcolor="#ffffff">
+
+ <p><i><a href="../../../../../../index.html">Table of Contents</a></i></p>
+
+ <table border="0" cellpadding="5" cellspacing="0" width="100%">
+ <tr>
+ <th rowspan="2"
+ valign="top"
+ align="left"
+ width="10%"
+ bgcolor="#88bbee"><font color="#000000">Class: SubsystemError</font>
+ </th>
+ <th bgcolor="#88bbee"
+ width="90%"
+ align="right"><font color="#000000">em.py</font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<p>An error associated with the Unicode subsystem.</p>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Base Classes">Base Classes</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<a href="Error.html">Error</a><br>
+<ul>
+
+Exception<br>
+
+</ul>
+
+</td></tr>
+</table>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+</td></tr>
+</table>
+
+ </td>
+ </tr>
+ </table>
+
+ <hr>
+
+ <p><i><a href="../../../../../../index.html">Table of Contents</a></i></p>
+
+ <font size="-2"><i>This document was automatically generated
+ on Mon Oct 27 01:29:13 2003 by
+ <a href="http://happydoc.sourceforge.net">HappyDoc</a> version
+ 2.1</i></font>
+
+ </body>
+ </html>
+
\ No newline at end of file
--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html40/loose.dtd">
+
+<html>
+
+ <head>
+ <title>Class: Token</title>
+ </head>
+
+ <body bgcolor="#ffffff">
+
+ <p><i><a href="../../../../../../index.html">Table of Contents</a></i></p>
+
+ <table border="0" cellpadding="5" cellspacing="0" width="100%">
+ <tr>
+ <th rowspan="2"
+ valign="top"
+ align="left"
+ width="10%"
+ bgcolor="#88bbee"><font color="#000000">Class: Token</font>
+ </th>
+ <th bgcolor="#88bbee"
+ width="90%"
+ align="right"><font color="#000000">em.py</font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<p>An element of expansion.</p>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Methods">Methods</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<a href="#__str__">__str__</a><br>
+<a href="#run">run</a><br>
+<a href="#string">string</a><br>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="__str__"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">__str__ </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+__str__ ( self )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="run"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">run </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+run (
+ self,
+ interpreter,
+ locals,
+ )
+
+</pre></font>
+
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Exceptions">Exceptions</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+NotImplementedError<br>
+
+</td></tr>
+</table>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="string"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">string </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+string ( self )
+
+</pre></font>
+
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Exceptions">Exceptions</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+NotImplementedError<br>
+
+</td></tr>
+</table>
+</td></tr>
+</td></tr>
+</table>
+
+ </td>
+ </tr>
+ </table>
+
+ <hr>
+
+ <p><i><a href="../../../../../../index.html">Table of Contents</a></i></p>
+
+ <font size="-2"><i>This document was automatically generated
+ on Mon Oct 27 01:29:13 2003 by
+ <a href="http://happydoc.sourceforge.net">HappyDoc</a> version
+ 2.1</i></font>
+
+ </body>
+ </html>
+
\ No newline at end of file
--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html40/loose.dtd">
+
+<html>
+
+ <head>
+ <title>Class: TransientParseError</title>
+ </head>
+
+ <body bgcolor="#ffffff">
+
+ <p><i><a href="../../../../../../index.html">Table of Contents</a></i></p>
+
+ <table border="0" cellpadding="5" cellspacing="0" width="100%">
+ <tr>
+ <th rowspan="2"
+ valign="top"
+ align="left"
+ width="10%"
+ bgcolor="#88bbee"><font color="#000000">Class: TransientParseError</font>
+ </th>
+ <th bgcolor="#88bbee"
+ width="90%"
+ align="right"><font color="#000000">em.py</font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<p>A parse error occurred which may be resolved by feeding more data.
+ Such an error reaching the toplevel is an unexpected EOF error.</p>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Base Classes">Base Classes</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<a href="ParseError.html">ParseError</a><br>
+<ul>
+
+<a href="Error.html">Error</a><br>
+<ul>
+
+Exception<br>
+
+</ul>
+
+</ul>
+
+</td></tr>
+</table>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+</td></tr>
+</table>
+
+ </td>
+ </tr>
+ </table>
+
+ <hr>
+
+ <p><i><a href="../../../../../../index.html">Table of Contents</a></i></p>
+
+ <font size="-2"><i>This document was automatically generated
+ on Mon Oct 27 01:29:13 2003 by
+ <a href="http://happydoc.sourceforge.net">HappyDoc</a> version
+ 2.1</i></font>
+
+ </body>
+ </html>
+
\ No newline at end of file
--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html40/loose.dtd">
+
+<html>
+
+ <head>
+ <title>Class: UncloseableFile</title>
+ </head>
+
+ <body bgcolor="#ffffff">
+
+ <p><i><a href="../../../../../../index.html">Table of Contents</a></i></p>
+
+ <table border="0" cellpadding="5" cellspacing="0" width="100%">
+ <tr>
+ <th rowspan="2"
+ valign="top"
+ align="left"
+ width="10%"
+ bgcolor="#88bbee"><font color="#000000">Class: UncloseableFile</font>
+ </th>
+ <th bgcolor="#88bbee"
+ width="90%"
+ align="right"><font color="#000000">em.py</font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<p>A simple class which wraps around a delegate file-like object
+ and lets everything through except close calls.</p>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Methods">Methods</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<a href="#__init__">__init__</a><br>
+<a href="#close">close</a><br>
+<a href="#flush">flush</a><br>
+<a href="#write">write</a><br>
+<a href="#writelines">writelines</a><br>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="__init__"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">__init__ </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+__init__ ( self, delegate )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="close"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">close </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+close ( self )
+
+</pre></font>
+
+<p>Eat this one.</p>
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="flush"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">flush </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+flush ( self )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="write"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">write </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+write ( self, data )
+
+</pre></font>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="writelines"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">writelines </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+writelines ( self, lines )
+
+</pre></font>
+
+</td></tr>
+</td></tr>
+</table>
+
+ </td>
+ </tr>
+ </table>
+
+ <hr>
+
+ <p><i><a href="../../../../../../index.html">Table of Contents</a></i></p>
+
+ <font size="-2"><i>This document was automatically generated
+ on Mon Oct 27 01:29:13 2003 by
+ <a href="http://happydoc.sourceforge.net">HappyDoc</a> version
+ 2.1</i></font>
+
+ </body>
+ </html>
+
\ No newline at end of file
--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html40/loose.dtd">
+
+<html>
+
+ <head>
+ <title>Class: VerboseHook</title>
+ </head>
+
+ <body bgcolor="#ffffff">
+
+ <p><i><a href="../../../../../../index.html">Table of Contents</a></i></p>
+
+ <table border="0" cellpadding="5" cellspacing="0" width="100%">
+ <tr>
+ <th rowspan="2"
+ valign="top"
+ align="left"
+ width="10%"
+ bgcolor="#88bbee"><font color="#000000">Class: VerboseHook</font>
+ </th>
+ <th bgcolor="#88bbee"
+ width="90%"
+ align="right"><font color="#000000">em.py</font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<p>A verbose hook that reports all information received by the
+ hook interface. This class dynamically scans the Hook base class
+ to ensure that all hook methods are properly represented.</p>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Base Classes">Base Classes</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<a href="Hook.html">Hook</a><br>
+
+</td></tr>
+</table>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Methods">Methods</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<a href="#__init__">__init__</a><br>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="__init__"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">__init__ </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+__init__ ( self, output=sys.stderr )
+
+</pre></font>
+
+</td></tr>
+</td></tr>
+</table>
+
+ </td>
+ </tr>
+ </table>
+
+ <hr>
+
+ <p><i><a href="../../../../../../index.html">Table of Contents</a></i></p>
+
+ <font size="-2"><i>This document was automatically generated
+ on Mon Oct 27 01:29:13 2003 by
+ <a href="http://happydoc.sourceforge.net">HappyDoc</a> version
+ 2.1</i></font>
+
+ </body>
+ </html>
+
\ No newline at end of file
--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html40/loose.dtd">
+
+<html>
+
+ <head>
+ <title>Class: WhitespaceToken</title>
+ </head>
+
+ <body bgcolor="#ffffff">
+
+ <p><i><a href="../../../../../../index.html">Table of Contents</a></i></p>
+
+ <table border="0" cellpadding="5" cellspacing="0" width="100%">
+ <tr>
+ <th rowspan="2"
+ valign="top"
+ align="left"
+ width="10%"
+ bgcolor="#88bbee"><font color="#000000">Class: WhitespaceToken</font>
+ </th>
+ <th bgcolor="#88bbee"
+ width="90%"
+ align="right"><font color="#000000">em.py</font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<p>A whitespace markup.</p>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Base Classes">Base Classes</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<a href="ExpansionToken.html">ExpansionToken</a><br>
+<ul>
+
+<a href="Token.html">Token</a><br>
+
+</ul>
+
+</td></tr>
+</table>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Methods">Methods</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<a href="#string">string</a><br>
+
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="string"></a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000">string </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <font color="#000088"><pre>
+string ( self )
+
+</pre></font>
+
+</td></tr>
+</td></tr>
+</table>
+
+ </td>
+ </tr>
+ </table>
+
+ <hr>
+
+ <p><i><a href="../../../../../../index.html">Table of Contents</a></i></p>
+
+ <font size="-2"><i>This document was automatically generated
+ on Mon Oct 27 01:29:13 2003 by
+ <a href="http://happydoc.sourceforge.net">HappyDoc</a> version
+ 2.1</i></font>
+
+ </body>
+ </html>
+
\ No newline at end of file
--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html40/loose.dtd">
+
+<html>
+
+ <head>
+ <title>empy</title>
+ </head>
+
+ <body bgcolor="#ffffff">
+
+ <p><i><a href="index.html">Table of Contents</a></i></p>
+
+ <table border="0" cellpadding="5" cellspacing="0" width="100%">
+ <tr>
+ <th rowspan="2"
+ valign="top"
+ align="left"
+ width="10%"
+ bgcolor="#88bbee"><font color="#000000">empy</font>
+ </th>
+ <th bgcolor="#88bbee"
+ width="90%"
+ align="right"><font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<h3>Summary</h3>
+<p> A powerful and robust templating system for Python.</p>
+<h3>Overview</h3>
+<p> EmPy is a system for embedding Python expressions and statements
+ in template text; it takes an EmPy source file, processes it, and
+ produces output. This is accomplished via expansions, which are
+ special signals to the EmPy system and are set off by a special
+ prefix (by default the at sign, <code>@</code>). EmPy can expand arbitrary
+ Python expressions and statements in this way, as well as a
+ variety of special forms. Textual data not explicitly delimited
+ in this way is sent unaffected to the output, allowing Python to
+ be used in effect as a markup language. Also supported are
+ callbacks via hooks, recording and playback via diversions, and
+ dynamic, chainable filters. The system is highly configurable via
+ command line options and embedded commands.</p>
+<p> Expressions are embedded in text with the <code>@(...)</code> notation;
+ variations include conditional expressions with <code>@(...?...!...)</code>
+ and the ability to handle thrown exceptions with <code>@(...$...)</code>. As
+ a shortcut, simple variables and expressions can be abbreviated as
+ <code>@variable</code>, <code>@object.attribute</code>, <code>@function(arguments)</code>,
+ <code>@sequence</code> <a href="#index"><a href="#refindex">[index]</a></a>, and combinations. Full-fledged statements
+ are embedded with <code>@{...}</code>. Control flow in terms of conditional
+ or repeated expansion is available with <code>@[...]</code>. A <code>@</code> followed
+ by a whitespace character (including a newline) expands to
+ nothing, allowing string concatenations and line continuations.
+ Comments are indicated with <code>@#</code> and consume the rest of the line,
+ up to and including the trailing newline. <code>@%</code> indicate
+ "significators," which are special forms of variable assignment
+ intended to specify per-file identification information in a
+ format which is easy to parse externally. Context name and line
+ number changes can be done with <code>@?</code> and <code>@!</code> respectively.
+ '@<...>' markups are customizeable by the user and can be used for
+ any desired purpose. Escape sequences analogous to those in C can
+ be specified with <code>@\...</code>, and finally a <code>@@</code> sequence expands to
+ a single literal at sign.</p>
+<h3>Getting the software</h3>
+<p> The current version of empy is 3.3.2.</p>
+<p> The latest version of the software is available in a tarball here:
+ <a href="http://www.alcyone.com/software/empy/empy-latest.tar.gz">http://www.alcyone.com/software/empy/empy-latest.tar.gz</a>.</p>
+<p> The official URL for this Web site is
+ <a href="http://www.alcyone.com/software/empy/">http://www.alcyone.com/software/empy/</a>.</p>
+<h3>Requirements</h3>
+<p> EmPy should work with any version of Python from 2.4 onward,
+ including 3.x.</p>
+<h3>License</h3>
+<p> This code is released under the <a href="http://www.gnu.org/copyleft/lesser.html">LGPL</a>.</p>
+<h3>Mailing lists</h3>
+<p> There are two EmPy related mailing lists available. The first is
+ a receive-only, very low volume list for important announcements
+ (including releases). To subscribe, send an email to
+ <a href="mailto:empy-announce-list-subscribe@alcyone.com">empy-announce-list-subscribe@alcyone.com</a>.</p>
+<p> The second is a general discussion list for topics related to
+ EmPy, and is open for everyone to contribute; announcements
+ related to EmPy will also be made on this list. The author of
+ EmPy (and any future developers) will also be on the list, so it
+ can be used not only to discuss EmPy features with other users,
+ but also to ask questions of the author(s). To subscribe, send an
+ email to <a href="mailto:empy-list-subscribe@alcyone.com">empy-list-subscribe@alcyone.com</a>.</p>
+<h3>Basics</h3>
+<p> EmPy is intended for embedding Python code in otherwise
+ unprocessed text. Source files are processed, and the results are
+ written to an output file. Normal text is sent to the output
+ unchanged, but markups are processed, expanded to their results,
+ and then written to the output file as strings (that is, with the
+ <code>str</code> function, not <code>repr</code>). The act of processing EmPy source
+ and handling markups is called "expansion."</p>
+<p> Code that is processed is executed exactly as if it were entered
+ into the Python interpreter; that is, it is executed with the
+ equivalent of <code>eval</code> (for expressions) and <code>exec</code> (for
+ statements). EmPy is intended to be a very thin (though powerful)
+ layer on top of a running Python system; Python and EmPy files can
+ be mixed together (via command line options) without
+ complications.</p>
+<p> By default the embedding prefix is the at sign (<code>@</code>), which
+ appears neither in valid Python code nor commonly in arbitrary
+ texts; it can be overridden with the -p option (or with the
+ <code>empy.setPrefix</code> function). The prefix indicates to the EmPy
+ interpreter that a special sequence follows and should be
+ processed rather than sent to the output untouched (to indicate a
+ literal at sign, it can be doubled as in <code>@@</code>).</p>
+<p> When the interpreter starts processing its target file, no modules
+ are imported by default, save the <code>empy</code> pseudomodule (see below),
+ which is placed in the globals; the <code>empy</code> pseudomodule is
+ associated with a particular interpreter -- in fact, they are the
+ same object -- and it is important that it not be removed from
+ that interpreter's globals, nor that it be shared with other
+ interpreters running concurrently (a name other than <code>empy</code> can be
+ specified with the -m option). The globals are not cleared or
+ reset in any way. It is perfectly legal to set variables or
+ explicitly import modules and then use them in later markups,
+ <em>e.g.</em>, <code>@{import time} ... @time.time()</code>. Scoping rules are as
+ in normal Python, although all defined variables and objects are
+ taken to be in the global namespace.</p>
+<p> Indentation is significant in Python, and therefore is also
+ significant in EmPy. EmPy statement markups (<code>@{...}</code>), when
+ spanning multiple lines, must be flush with the left margin. This
+ is because (multiline) statement markups are not treated specially
+ in EmPy and are simply passed to the Python interpreter, where
+ indentation is significant.</p>
+<p> Activities you would like to be done before any processing of the
+ main EmPy file can be specified with the -I, -D, -E, -F, and -P
+ options. -I imports modules, -D executes a Python variable
+ assignment, -E executes an arbitrary Python (not EmPy) statement,
+ -F executes a Python (not EmPy) file, and -P processes an EmPy
+ (not Python) file. These operations are done in the order they
+ appear on the command line; any number of each (including, of
+ course, zero) can be used.</p>
+<h3>Expansions</h3>
+<p> The following markups are supported. For concreteness below, <code>@</code>
+ is taken for the sake of argument to be the prefix character,
+ although this can be changed.</p>
+<dl>
+<dt> <strong><code>@# COMMENT NEWLINE</code></strong></dt>
+<dd>A comment. Comments, including the
+ trailing newline, are stripped out completely. Comments should
+ only be present outside of expansions. The comment itself is
+ not processed in any way: It is completely discarded. This
+ allows <code>@#</code> comments to be used to disable markups. <em>Note:</em> As
+ special support for "bangpaths" in Unix-like operating systems,
+ if the first line of a file (or indeed any context) begins with
+ <code>#!</code>, and the interpreter has a <code>processBangpaths</code> option set to
+ true (default), it is treated as a <code>@#</code> comment. A <code>#!</code>
+ sequence appearing anywhere else will be handled literally and
+ unaltered in the expansion. Example:
+<pre>
+ @# This line is a comment.
+ @# This will NOT be expanded: @x.
+</pre>
+</dd>
+<dt> <strong><code>@? NAME NEWLINE</code></strong></dt>
+<dd>Set the name of the current context to be
+ the given string. Variables are not allowed here; the name is
+ treated as a literal. (If you wish to use arbitrary
+ expressions, use the <code>empy.setContextName</code> function instead.)
+ Example:
+<pre>
+ @?NewName
+ The context name is now @empy.identify()[0] (NewName).
+</pre>
+</dd>
+<dt> <strong><code>@! INTEGER NEWLINE</code></strong></dt>
+<dd>Set the line number of the current
+ context to be the given integer value; this is similar to the
+ <code>#line</code> C preprocessor directive. This is done in such a way
+ that the <em>next</em> line will have the specified numeric value, not
+ the current one. Expressions are not allowed here; the number
+ must be a literal integer. (If you wish to use arbitrary
+ expressions, use the <code>empy.setContextLine</code> function instead.)
+ Example:
+<pre>
+ @!100
+ The context line is now @empy.identify()[1] (100).
+</pre>
+</dd>
+<dt> <strong><code>@ WHITESPACE</code></strong></dt>
+<dd>A <code>@</code> followed by one whitespace character
+ (a space, horizontal tab, vertical tab, carriage return, or
+ newline) is expanded to nothing; it serves as a way to
+ explicitly separate two elements which might otherwise be
+ interpreted as being the same symbol (such as <code>@name@ s</code> to mean
+ <code>@(name)s</code> -- see below). Also, since a newline qualifies as
+ whitespace here, the lone <code>@</code> at the end of a line represents a
+ line continuation, similar to the backslash in other languages.
+ Coupled with statement expansion below, spurious newlines can be
+ eliminated in statement expansions by use of the <code>@{...}@</code>
+ construct. Example:
+<pre>
+ This will appear as one word: salt@ water.
+ This is a line continuation; @
+ this text will appear on the same line.
+</pre>
+</dd>
+<dt> <strong><code>@\ ESCAPE_CODE</code></strong></dt>
+<dd>An escape code. Escape codes in EmPy are
+ similar to C-style escape codes, although they all begin with
+ the prefix character. Valid escape codes include:<dl>
+<dt> <code>@\0</code></dt>
+<dd>NUL, null</dd>
+<dt> <code>@\a</code></dt>
+<dd>BEL, bell</dd>
+<dt> <code>@\b</code></dt>
+<dd>BS, backspace</dd>
+<dt> <code>@\d</code></dt>
+<dd>three-digital decimal code DDD</dd>
+<dt> <code>@\e</code></dt>
+<dd>ESC, escape</dd>
+<dt> <code>@\f</code></dt>
+<dd>FF, form feed</dd>
+<dt> <code>@\h</code></dt>
+<dd>DEL, delete</dd>
+<dt> <code>@\n</code></dt>
+<dd>LF, linefeed character, newline</dd>
+<dt> <code>@\oOOO</code></dt>
+<dd>three-digit octal code OOO</dd>
+<dt> <code>@\qQQQQ</code></dt>
+<dd>four-digit quaternary code QQQQ</dd>
+<dt> <code>@\r</code></dt>
+<dd>CR, carriage return</dd>
+<dt> <code>@\s</code></dt>
+<dd>SP, space</dd>
+<dt> <code>@\t</code></dt>
+<dd>HT, horizontal tab</dd>
+<dt> <code>@\v</code></dt>
+<dd>VT, vertical tab</dd>
+<dt> <code>@\xHH</code></dt>
+<dd>two-digit hexadecimal code HH</dd>
+<dt> <code>@\z</code></dt>
+<dd>EOT, end of transmission</dd>
+<dt> <code>@^X</code></dt>
+<dd>the control character ^X</dd>
+</dl>
+<p> Unlike in C-style escape codes, escape codes taking some number
+ of digits afterward always take the same number to prevent
+ ambiguities. Furthermore, unknown escape codes are treated as
+ parse errors to discourage potential subtle mistakes. Note
+ that, while <code>@\0</code> represents the NUL character, to represent an
+ octal code, one must use <code>@\o...</code>, in contrast to C. Example:
+<pre>
+ This embeds a newline.@\nThis is on the following line.
+ This beeps!@\a
+ There is a tab here:@\tSee?
+ This is the character with octal code 141: @\o141.
+</pre>
+</p>
+</dd>
+<dt> <strong><code>@@</code></strong></dt>
+<dd>A literal at sign (<code>@</code>). To embed two adjacent at
+ signs, use <code>@@@@</code>, and so on. Any literal at sign that you wish
+ to appear in your text must be written this way, so that it will
+ not be processed by the system. <em>Note:</em> If a prefix other than
+ <code>@</code> has been chosen via the command line option, one expresses
+ that literal prefix by doubling it, not by appending a <code>@</code>.
+ Example:
+<pre>
+ The prefix character is @@.
+ To get the expansion of x you would write @@x.
+</pre>
+</dd>
+<dt> <strong><code>@)</code>, <code>@]</code>, <code>@}</code></strong></dt>
+<dd>These expand to literal close parentheses,
+ close brackets, and close braces, respectively; these are
+ included for completeness and explicitness only. Example:
+<pre>
+ This is a close parenthesis: @).
+</pre>
+</dd>
+<dt> <strong><code>@"..."</code>, <code>@"""..."""</code>, etc.</strong></dt>
+<dd>These string literals expand
+ to the literals themselves, so <code>@"test"</code> expands to <code>test</code>.
+ Since they are inherently no-operations, the only reason for
+ their use is to override their behavior with hooks.</dd>
+<dt> <strong><code>@( EXPRESSION )</code></strong></dt>
+<dd>Evaluate an expression, and expand with
+ the string (via a call to <code>str</code>) representation evaluation of
+ that expression. Whitespace immediately inside the parentheses
+ is ignored; <code>@( expression )</code> is equivalent to <code>@(expression)</code>.
+ If the expression evaluates to <code>None</code>, nothing is expanded in
+ its place; this allows function calls that depend on side
+ effects (such as printing) to be called as expressions. (If you
+ really <em>do</em> want a <code>None</code> to appear in the output, then use the
+ Python string <code>"None"</code>.) <em>Note:</em> If an expression prints
+ something to <code>sys.stdout</code> as a side effect, then that printing
+ will be spooled to the output <em>before</em> the expression's return
+ value is. Example:
+<pre>
+ 2 + 2 is @(2 + 2).
+ 4 squared is @(4**2).
+ The value of the variable x is @(x).
+ This will be blank: @(None).
+</pre>
+</dd>
+<dt> <strong><code>@( TEST ? THEN (! ELSE)_opt ($ EXCEPT)_opt )</code></strong></dt>
+<dd>A special
+ form of expression evaluation representing conditional and
+ protected evaluation. Evaluate the "test" expression; if it
+ evaluates to true (in the Pythonic sense), then evaluate the
+ "then" section as an expression and expand with the <code>str</code> of
+ that result. If false, then the "else" section is evaluated and
+ similarly expanded. The "else" section is optional and, if
+ omitted, is equivalent to <code>None</code> (that is, no expansion will
+ take place). <em>Note</em>: For backward compatibility, the "else"
+ section delimiter, <code>!</code>, may be expressed as a <code>:</code>. This
+ behavior is supported but deprecated.<p> If the "except" section is present, then if any of the prior
+ expressions raises an exception when evaluated, the expansion
+ will be replaced with the evaluation of the except expression.
+ (If the "except" expression itself raises, then that exception
+ will be propagated normally.) The except section is optional
+ and, if omitted, is equivalent to <code>None</code> (that is, no expansion
+ will take place). An exception (cough) to this is if one of
+ these first expressions raises a SyntaxError; in that case the
+ protected evaluation lets the error through without evaluating
+ the "except" expression. The intent of this construct is to
+ except runtime errors, and if there is actually a syntax error
+ in the "try" code, that is a problem that should probably be
+ diagnosed rather than hidden. Example:
+<pre>
+ What is x? x is @(x ? "true" ! "false").
+ Pluralization: How many words? @x word@(x != 1 ? 's').
+ The value of foo is @(foo $ "undefined").
+ Division by zero is @(x/0 $ "illegal").
+</pre>
+</p>
+</dd>
+<dt> <strong><code>@ SIMPLE_EXPRESSION</code></strong></dt>
+<dd>As a shortcut for the <code>@(...)</code>
+ notation, the parentheses can be omitted if it is followed by a
+ "simple expression." A simple expression consists of a name
+ followed by a series of function applications, array
+ subscriptions, or attribute resolutions, with no intervening
+ whitespace. For example:
+<ul>
+<li><p>a name, possibly with qualifying attributes (<em>e.g.</em>,
+ <code>@value</code>, <code>@os.environ</code>).</p></li>
+<li><p>a straightforward function call (<em>e.g.</em>, <code>@min(2, 3)</code>,
+ <code>@time.ctime()</code>), with no space between the function name
+ and the open parenthesis.</p></li>
+<li><p>an array subscription (<em>e.g.</em>, '@array<a href="#refindex">[index]</a>',
+ '@os.environ<a href="#refname">[name]</a>', with no space between the name and
+ the open bracket.</p></li>
+<li><p>any combination of the above (<em>e.g.</em>,
+ '@function(args).attr<a href="#refsub">[sub]</a>.other<a href="#refi">[i]</a>(foo)').</p></li>
+
+</ul>
+<p> In essence, simple expressions are expressions that can be
+ written ambiguously from text, without intervening space. Note
+ that trailing dots are not considered part of the expansion
+ (<em>e.g.</em>, <code>@x.</code> is equivalent to <code>@(x).</code>, not <code>@(x.)</code>, which
+ would be illegal anyway). Also, whitespace is allowed within
+ parentheses or brackets since it is unambiguous, but not between
+ identifiers and parentheses, brackets, or dots. Explicit
+ <code>@(...)</code> notation can be used instead of the abbreviation when
+ concatenation is what one really wants (<em>e.g.</em>, <code>@(word)s</code> for
+ simple pluralization of the contents of the variable <code>word</code>).
+ As above, if the expression evaluates to the <code>None</code> object,
+ nothing is expanded. Note that since a curly appearing where
+ EmPy would expect an open parenthesis or bracket in is
+ meaningless in Python, it is treated as a parse error (<em>e.g.</em>,
+ <code>@x{1, 2}</code> results in an error). Example:
+<pre>
+ The value of x is @x.
+ The ith value of a is @a[i].
+ The result of calling f with q is @f(q).
+ The attribute a of x is @x.a.
+ The current time is @time.ctime(time.time()).
+ The current year is @time.localtime(time.time())[0].
+ These are the same: @min(2,3) and @min(2, 3).
+ But these are not the same: @min(2, 3) vs. @min (2, 3).
+ The plural of @name is @(name)s, or @name@ s.
+</pre>
+</p>
+</dd>
+<dt> <strong><code>@` EXPRESSION `</code></strong></dt>
+<dd>Evaluate a expression, and expand with
+ the <code>repr</code> (instead of the <code>str</code> which is the default) of the
+ evaluation of that expression. This expansion is primarily
+ intended for debugging and is unlikely to be useful in actual
+ practice. That is, a <code>@`...`</code> is identical to <code>@(repr(...))</code>.
+ Example:
+<pre>
+ The repr of the value of x is @`x`.
+ This print the Python repr of a module: @`time`.
+ This actually does print None: @`None`.
+</pre>
+</dd>
+<dt> <strong><code>@: EXPRESSION : DUMMY :</code></strong></dt>
+<dd>Evaluate an expression and then
+ expand to a <code>@:</code>, the original expression, a <code>:</code>, the evaluation
+ of the expression, and then a <code>:</code>. The current contents of the
+ dummy area are ignored in the new expansion. In this sense it
+ is self-evaluating; the syntax is available for use in
+ situations where the same text will be sent through the EmPy
+ processor multiple times. Example:
+<pre>
+ This construct allows self-evaluation:
+ @:2 + 2:this will get replaced with 4:
+</pre>
+</dd>
+<dt> <strong><code>@{ STATEMENTS }</code></strong></dt>
+<dd>Execute a (potentially compound)
+ statement; statements have no return value, so the expansion is
+ not replaced with anything. Multiple statements can either be
+ separated on different lines, or with semicolons; indentation is
+ significant, just as in normal Python code. Statements,
+ however, can have side effects, including printing; output to
+ <code>sys.stdout</code> (explicitly or via a <code>print</code> statement) is
+ collected by the interpreter and sent to the output (unless this
+ behavior is suppressed with the -n option). The usual Python
+ indentation rules must be followed, although if the statement
+ consists of only one statement, leading and trailing whitespace
+ is ignored (<em>e.g.</em>, <code>@{ print time.time() }</code> is equivalent to
+ <code>@{print time.time()}</code>). Example:
+<pre>
+ @{x = 123}
+ @{a = 1; b = 2}
+ @{print time.time()}
+ @# Note that extra newlines will appear above because of the
+ @# newlines trailing the close braces. To suppress them
+ @# use a @ before the newline:
+ @{
+ for i in range(10):
+ print "i is %d" % i
+ }@
+ @{print "Welcome to EmPy."}@
+</pre>
+</dd>
+<dt> <strong><code>@% KEY (WHITESPACE VALUE)_opt NEWLINE</code></strong></dt>
+<dd>Declare a
+ significator. Significators consume the whole line (including
+ the trailing newline), and consist of a key string containing no
+ whitespace, and than optional value prefixed by whitespace. The
+ key may not start with or contain internal whitespace, but the
+ value may; preceding or following whitespace in the value is
+ stripped. Significators are totally optional, and are intended
+ to be used for easy external (that is, outside of EmPy)
+ identification when used in large scale environments with many
+ EmPy files to be processed. The purpose of significators is to
+ provide identification information about each file in a special,
+ easy-to-parse form so that external programs can process the
+ significators and build databases, independently of EmPy.
+ Inside of EmPy, when a significator is encountered, its key,
+ value pair is translated into a simple assignment of the form
+ <code>__KEY__ = VALUE</code> , where "__KEY__" is the key string with two
+ underscores on either side and "VALUE" is a Python expression.
+ Example:
+<pre>
+ @%title "Gravitation"
+ @%author "Misner", "Thorne", "Wheeler"
+ @%publisher "W.H. Freeman and Company"
+ @%pages 1279
+ @%keywords 'physics', 'gravity', 'Einstein', 'relativity'
+ @%copyright 1970, 1971
+</pre>
+</dd>
+<dt> **'@< CONTENTS >'**</dt>
+<dd>Invoke a custom markup. The custom markup
+ is a special markup reserved for use by the user; it has no
+ prescribed meaning on its own. If <code>contents</code> is a string
+ representing what appears in between the angle brackets, then
+ expanding this markup is equivalent to
+ <code>empy.invokeCallback(contents)</code>. See the "Custom markup"
+ section for more information.</dd>
+</dl>
+<h3>Control</h3>
+<p> EmPy version 3 and above includes the ability to direct
+ conditional and repeated expansion of blocks of EmPy code with
+ control markups (the obsolescent "substitution" markups are
+ unavailable as of version 3.0). Control markups have analogs to
+ control flow structures in Python such as <code>if/elif/else</code>, <code>for</code>, and
+ <code>while</code>. Control markups are set off with the <code>@[...]</code> notation.</p>
+<p> Control markups are designed to be used in precisely the same way
+ that their internal Python analogues are used, except that the
+ control markups are intended to be used where there is much more
+ markup than control structure.</p>
+<p> Some control markups are considered "primary," (<em>e.g.</em>, <code>if</code>,
+ <code>for</code>, <code>while</code>) as they begin a control markup. Others are
+ considered "secondary," since they can only appear inside control
+ flow markups delineated by primary markups (<em>e.g.</em>, <code>elif</code>,
+ <code>else</code>, <code>continue</code>, <code>break</code>).</p>
+<p> Since EmPy, unlike Python, cannot use indentation to determine
+ where control structures begin and end, all primary control
+ markups <em>must</em> be followed by a corresponding terminating control
+ markup:
+<pre>
+ @[PRIMARY ...]...@[end PRIMARY]
+</pre>
+</p>
+<p> (where <code>PRIMARY</code> represents one of the primary keywords). The end
+ markup is mandatory, as is the space between the <code>end</code> and the
+ starting keyword. For instance:
+<pre>
+ @# If `person' is alive, show their age.
+ @person.name is @
+ @[if person.isAlive]@person.age@[else]dead@[end if].
+</pre>
+</p>
+<p> All primary markups must be terminated in this way, and the
+ keyword appearing in the appropriate <code>end</code> markup must match the
+ primary markup it corresponds to; if either of these conditions
+ are not satisfied, the result is a parse error. Everything
+ between the starting control flow marker (<code>@[PRIMARY ...]</code>) and
+ the ending marker (<code>@[end PRIMARY]</code>) -- including other markups,
+ even control markups -- is considered part of the markup. Control
+ markups can be nested:
+<pre>
+ @# Print all non-false elements on separate lines.
+ @[for elem in elements]@[if elem]@elem@\n@[end if]@[end for]
+</pre>
+</p>
+<p> Three major types of primary control markups are available:
+ conditional (<em>e.g.</em>, <code>if</code>, <code>try</code>), looping (<em>e.g.</em>, <code>for</code>,
+ <code>while</code>), and definitional (<em>e.g.</em>, <code>def</code>, discussed below).
+ Conditional control markups conditionally expand their contents,
+ whereas looping control markups repeatedly expand their contents.
+ The third type, definitional markups, will define new objects in
+ the globals relating to their contents. Conditional and looping
+ markups also differ in one substantial respect: Looping constructs
+ support '@<a href="#refcontinue">[continue]</a>' and '@<a href="#refbreak">[break]</a>' markups which, like their
+ Python equivalents, continue with the next iteration or break out
+ of the innermost looping construct, respectively ('@<a href="#refcontinue">[continue]</a>'
+ and '@<a href="#refbreak">[break]</a>' markups have no meaning inside conditional markups
+ and are an error). Also like their Python equivalents,
+ '@<a href="#refcontinue">[continue]</a>' and '@<a href="#refbreak">[break]</a>' may appear inside nested markups, so
+ long as they ultimately are contained by at least one looping
+ control markup:
+<pre>
+ @# Walk a long a linked list, printing each element.
+ @[while 1]@
+ @node
+ @{node = node.next}@
+ @[if not node]@[break]@[end if]@
+ @[end while]
+</pre>
+</p>
+<p> The provided markups are designed to mimic the internal Python
+ control structures as closely as possible. The supported control
+ markups are (the phrases in all uppercase are intended to signify
+ user-selectable patterns):
+<pre>
+ @[if CONDITION1]...@[elif CONDITION2]...@[else]...@[end if]
+ @[try]...@[except ...]...@[except ...]...@[end try]
+ @[try]...@[finally]...@[end try]
+ @[for VARIABLE in SEQUENCE]...@[else]...@[end for]
+ @[while CONDITION]...@[else]...@[end while]
+ @[def SIGNATURE]...@[end def]
+</pre>
+</p>
+<p> All recognizable forms behave like their Python equivalents; <code>if</code>
+ can contain multiple <code>elif</code> secondary markups within it; the
+ <code>else</code> markups are optional (but must appear at the end), the
+ <code>try</code> form with the <code>except</code> clause can contain multiple ones
+ which are handled in sequence, the <code>try</code> form can either contain
+ one or more <code>except</code> clauses or one <code>finally</code> clause (but not
+ both), and the <code>for</code> and <code>while</code> structures can contain <code>continue</code>
+ or <code>break</code> clauses internally (even if contained within other
+ markups).</p>
+<p> The third type of primary control markup is "definitional," in
+ that they create objects in the globals for later use (<em>e.g.</em>,
+ <code>def</code>). This allows the definition of a callable object which,
+ when called, will expand the contained markup (which can in turn,
+ of course, contain further markups). The argument to the markup
+ can be any legal Python function signature:
+<pre>
+ @[def f(x, y, z=2, *args, **keywords)]...@[end def]
+</pre>
+</p>
+<p> would define a function in the globals named <code>f</code> that takes the
+ given arguments. A macro markup of the form <code>@[def
+ SIGNATURE]CODE@[end def]</code> is equivalent to the Python code:
+<pre>
+ def SIGNATURE:
+ r"""CODE""" # so it is a doc string
+ empy.expand(r"""CODE""", locals())
+</pre>
+</p>
+<p> That is, it creates a Python function with the same name and
+ function arguments, whose docstring is the contents of the EmPy
+ markup that will be expanded when called. And, when called, it
+ will expand those contents, with the locals passed in.</p>
+<h3>Unicode support</h3>
+<p> EmPy version 3.1 and above includes intrinsic Unicode support.
+ EmPy's Unicode support defers to Python's internal Unicode
+ support, available in Python 2.0 and up, in order to allow
+ seamless and transparent translation of different encodings to the
+ native Python Unicode format.</p>
+<p> Knowledge of Python's Unicode support is expected, although not
+ completely required, to gain full benefit of EmPy's Unicode
+ features. To enable Unicode support, start EmPy with the
+ -u/--unicode option. EmPy will then transparently encode from the
+ input stream, process markups internally with native Unicode, and
+ then decode transparently to the output stream.</p>
+<p> By default, Python sets <code>sys.stdin</code> and <code>sys.stdout</code> with a
+ default encoding which is accessible via
+ 'sys.getdefaultencoding()'; encodings are represented by string
+ names. These streams have encodings set by the system and
+ <em>cannot</em> be changed.</p>
+<p> However, encodings for newly created files (files to be read when
+ specified on the command line, and/or files to be written when
+ used with the -o and -a arguments) can be specified for EmPy via
+ command line options. The --unicode-encoding option
+ simultaneously indicates the encoding to be used for both input
+ and output, whereas the --unicode-input-encoding and
+ --unicode-output-encoding options can each be used to specify
+ different encodings for both input and output. (If an encoding is
+ not explicitly indicated, it resorts to the system default in
+ <code>sys.getdefaultencoding()</code>, which is locale dependent.)</p>
+<p> Python's Unicode implementation has the concept of error handlers,
+ registered with the <code>codecs</code> module, which can be specified to
+ determine what action should take place if input cannot be decoded
+ into Unicode, or Unicode cannot be encoded into output. EmPy uses
+ these same "errors," as they are called, and can be specified via
+ command line options. The three most common error handlers are:
+ <code>ignore</code>, where invalid sequences are simply ignored; <code>replace</code>,
+ where invalid sequences are replaced with an encoding-specific
+ indicator, usually a question mark; and <code>strict</code>, where invalid
+ sequences raise an error. The --unicode-errors command line
+ option specifies the same error handler to be used for both input
+ and output, and the --unicode-input-errors and
+ --unicode-output-errors options can specify different error
+ handlers for input and output. If an error handler is not
+ explicitly specified, the <code>strict</code> handler (which will raise
+ errors) is used.</p>
+<p> Remember, to specify input encodings or errors that will take
+ effect, one cannot take input from <code>sys.stdin</code> and must explicitly
+ specify an EmPy file to process on the command line. Similarly,
+ for output encodings or errors, <code>sys.stdout</code> cannot be used and an
+ explicit output file must be specified with the -o or -a options.
+ It is perfectly valid to enable the Unicode subsystem (-u option)
+ while using <code>sys.stdin</code> and <code>sys.stdout</code>, but the encodings and
+ errors of these preexisting streams cannot be changed.</p>
+<p> Combined with the --no-prefix option, which disables all markup
+ processing, EmPy can act merely as an encoding translator, relying
+ on Python's Unicode facilities:
+<pre>
+ em.py --no-prefix \
+ --unicode-input-encoding=utf-8 \
+ --unicode-output-encoding=latin-1 \
+ -o filename.Latin-1 filename.UTF-8
+</pre>
+</p>
+<h3>Significators</h3>
+<p> Significators, introduced in EmPy version 1.2, are intended to
+ represent special assignment in a form that is easy to externally
+ parse. For instance, if one has a system that contains many EmPy
+ files, each of which has its own title, one could use a <code>title</code>
+ significator in each file and use a simple regular expression to
+ find this significator in each file and organize a database of the
+ EmPy files to be built. This is an easier proposition than, for
+ instance, attempting to grep for a normal Python assignment
+ (inside a <code>@{...}</code> expansion) of the desired variable.</p>
+<p> Significators look like the following:
+<pre>
+ @%KEY VALUE
+</pre>
+</p>
+<p> including the trailing newline, where "key" is a name and "value"
+ is a Python expression, and are separated by any whitespace. This
+ is equivalent to the following Python code:
+<pre>
+ __KEY__ = VALUE
+</pre>
+</p>
+<p> That is to say, a significator key translates to a Python variable
+ consisting of that key surrounded by double underscores on either
+ side. The value may contain spaces, but the key may not. So:
+<pre>
+ @%title "All Roads Lead to Rome"
+</pre>
+</p>
+<p> translates to the Python code:
+<pre>
+ __title__ = "All Roads Lead to Rome"
+</pre>
+</p>
+<p> but obviously in a way that easier to detect externally than if
+ this Python code were to appear somewhere in an expansion. Since
+ significator keys are surrounded by double underscores,
+ significator keys can be any sequence of alphanumeric and
+ underscore characters; choosing <code>123</code> is perfectly valid for a
+ significator (although straight), since it maps to the name
+ <code>__123__</code> which is a legal Python identifier.</p>
+<p> Note the value can be any Python expression. The value can be
+ omitted; if missing, it is treated as <code>None</code>.</p>
+<p> Significators are completely optional; it is completely legal for
+ a EmPy file or files to be processed without containing any
+ significators. Significators can appear anywhere within a file
+ outside of other markups, but typically they are placed near the
+ top of the file to make them easy to spot and edit by humans.</p>
+<p> A regular expression string designed to match significators (with
+ the default prefix) is available as <code>empy.SIGNIFICATOR_RE_STRING</code>,
+ and also is a toplevel definition in the <code>em</code> module itself.</p>
+<h3>Diversions</h3>
+<p> EmPy supports an extended form of diversions, which are a
+ mechanism for deferring and recalling output on demand, similar to
+ the functionality included in m4. Multiple "streams" of output
+ can be diverted (deferred) and undiverted (recalled) in this
+ manner. A diversion is identified with a name, which is any
+ immutable object such an integer or string. When recalled,
+ diverted code is <em>not</em> resent through the EmPy interpreter
+ (although a filter could be set up to do this).</p>
+<p> By default, no diversions take place. When no diversion is in
+ effect, processing output goes directly to the specified output
+ file. This state can be explicitly requested at any time by
+ calling the <code>empy.stopDiverting</code> function. It is always legal to
+ call this function.</p>
+<p> When diverted, however, output goes to a deferred location which
+ can then be recalled later. Output is diverted with the
+ <code>empy.startDiversion</code> function, which takes an argument that is
+ the name of the diversion. If there is no diversion by that name,
+ a new diversion is created and output will be sent to that
+ diversion; if the diversion already exists, output will be
+ appended to that preexisting diversion.</p>
+<p> Output send to diversions can be recalled in two ways. The first
+ is through the <code>empy.playDiversion</code> function, which takes the
+ name of the diversion as an argument. This recalls the named
+ diversion, sends it to the output, and then erases that
+ diversion. A variant of this behavior is the
+ <code>empy.replayDiversion</code>, which recalls the named diversion but does
+ not eliminate it afterwards; <code>empy.replayDiversion</code> can be
+ repeatedly called with the same diversion name, and will replay
+ that diversion repeatedly. <code>empy.createDiversion</code> create a
+ diversion without actually diverting to it, for cases where you
+ want to make sure a diversion exists but do not yet want to send
+ anything to it.</p>
+<p> The diversion object itself can be retrieved with
+ <code>empy.retrieveDiversion</code>. Diversions act as writable
+ file-objects, supporting the usual <code>write</code>, <code>writelines</code>, <code>flush</code>,
+ and <code>close</code> methods. The data that has been diverted to them can
+ be retrieved in one of two ways; either through the <code>asString</code>
+ method, which returns the entire contents of the diversion as a
+ single strong, or through the <code>asFile</code> method, which returns the
+ contents of the diversion as a readable (not writable) file-like
+ object.</p>
+<p> Diversions can also be explicitly deleted without recalling them
+ with the <code>empy.purgeDiversion</code> function, which takes the desired
+ diversion name as an argument.</p>
+<p> Additionally there are three functions which will apply the above
+ operations to all existing diversions: <code>empy.playAllDiversions</code>,
+ <code>empy.replayAllDiversions</code>, and <code>empy.purgeAllDiversions</code>. All
+ three will do the equivalent of a <code>empy.stopDiverting</code> call before
+ they do their thing.</p>
+<p> The name of the current diversion can be requested with the
+ <code>empy.getCurrentDiversion</code> function; also, the names of all
+ existing diversions (in sorted order) can be retrieved with
+ <code>empy.getAllDiversions</code>.</p>
+<p> When all processing is finished, the equivalent of a call to
+ <code>empy.playAllDiversions</code> is done.</p>
+<h3>Filters</h3>
+<p> EmPy also supports dynamic filters, introduced in version 1.3.
+ Filters are put in place right "before" the final output file, and
+ so are only invoked after all other processing has taken place
+ (including interpreting and diverting). Filters take input, remap
+ it, and then send it to the output.</p>
+<p> The current filter can be retrieved with the <code>empy.getFilter</code>
+ function. The filter can be cleared (reset to no filter) with
+ <code>empy.resetFilter</code> and a special "null filter" which does not send
+ any output at all can be installed with <code>empy.nullFilter</code>. A
+ custom filter can be set with the <code>empy.setFilter</code> function; for
+ convenience, specialized shortcuts for filters preexist and can be
+ used in lieu of actual <code>empy.Filter</code> instances for the
+ <code>empy.setFilter</code> or <code>empy.attachFilter</code> argument:</p>
+
+<ul>
+<li><p><code>None</code> is a special filter meaning "no filter"; when installed,
+ no filtering whatsoever will take place. <code>empy.setFilter(None)</code>
+ is equivalent to <code>empy.resetFilter()</code>.</p></li>
+<li><p><code>0</code> (or any other numeric constant equal to zero) is another
+ special filter that represents the null filter; when installed,
+ no output will ever be sent to the filter's sink.</p></li>
+<li><p>A filter specified as a function (or lambda) is expected to take
+ one string argument and return one string argument; this filter
+ will execute the function on any input and use the return value
+ as output.</p></li>
+<li><p>A filter that is a string is a 256-character table is
+ substituted with the result of a call to <code>string.translate</code>
+ using that table.</p></li>
+<li><p>A filter can be an instance of a subclass of <code>empy.Filter</code>.
+ This is the most general form of filter. (In actuality, it can
+ be any object that exhibits a <code>Filter</code> interface, which would
+ include the normal file-like <code>write</code>, <code>flush</code>, and <code>close</code>
+ methods, as well as <code>next</code>, <code>attach</code>, and <code>detach</code> methods for
+ filter-specific behavior.)</p></li>
+<li><p>Finally, the argument to <code>empy.setFilter</code> can be a Python list
+ consisting of one or more of the above objects. In that case,
+ those filters are chained together in the order they appear in
+ the list. An empty list is the equivalent of 'None'; all
+ filters will be uninstalled.</p></li>
+
+</ul>
+<p> Filters are, at their core, simply file-like objects (minimally
+ supporting <code>write</code>, <code>flush</code>, and <code>close</code> methods that behave in
+ the usual way) which, after performing whatever processing they
+ need to do, send their work to the next file-like object or filter
+ in line, called that filter's "sink." That is to say, filters can
+ be "chained" together; the action of each filter takes place in
+ sequence, with the output of one filter being the input of the
+ next. Additionally, filters support a <code>_flush</code> method (note the
+ leading underscore) which will always flush the filter's
+ underlying sink; this method should be not overridden.</p>
+<p> Filters also support three additional methods, not part of the
+ traditional file interface: <code>attach</code>, which takes as an argument a
+ file-like object (perhaps another filter) and sets that as the
+ filter's "sink" -- that is, the next filter/file-like object in
+ line. <code>detach</code> (which takes no arguments) is another method which
+ flushes the filter and removes its sink, leaving it isolated.
+ Finally, <code>next</code> is an accessor method which returns the filter's
+ sink -- or <code>None</code>, if the filter does not yet have a sink
+ attached.</p>
+<p> To create your own filter, you can create an object which supports
+ the above described interface, or simply derive from the
+ <code>empy.Filter</code> class and override its <code>write</code> and possibly <code>flush</code>
+ methods. You can chain filters together by passing them as
+ elements in a list to the <code>empy.setFilter</code> function, or you can
+ chain them together manually with the <code>attach</code> method:
+<pre>
+ firstFilter.attach(secondFilter)
+ empy.setFilter(firstFilter)
+</pre>
+</p>
+<p> or just let EmPy do the chaining for you:
+<pre>
+ empy.setFilter([firstFilter, secondFilter])
+</pre>
+</p>
+<p> In either case, EmPy will walk the filter chain and find the end
+ and then hook that into the appropriate interpreter stream; you
+ need not do this manually. The function <code>empy.attachFilter</code> can
+ be used to attach a single filter (or shortcut, as above) to the
+ end of a currently existing chain. Note that unlike its cousin
+ <code>empy.setFilter</code>, one cannot pass a sequence of filters (or filter
+ shortcuts) to <code>empy.attachFilter</code>. (If there is no existing
+ filter chain installed, <code>empy.attachFilter</code> will behave the same
+ as <code>empy.setFilter</code>.)</p>
+<p> Subclasses of <code>empy.Filter</code> are already provided with the above
+ null, function, and string functionality described above; they are
+ <code>NullFilter</code>, <code>FunctionFilter</code>, and <code>StringFilter</code>, respectively.
+ In addition, a filter which supports buffering, <code>BufferedFilter</code>,
+ is provided. Several variants are included: <code>SizeBufferedFilter</code>,
+ a filter which buffers into fixed-sized chunks,
+ <code>LineBufferedFilter</code>, a filter which buffers by lines, and
+ <code>MaximallyBufferedFilter</code>, a filter which completely buffers its
+ input.</p>
+<h3>Hooks</h3>
+<p> The EmPy system allows for the registry of hooks with a running
+ EmPy interpreter. Originally introduced in version 2.0 and much
+ improved in 3.2, hooks are objects, registered with an
+ interpreter, whose methods represent specific callbacks. Any
+ number of hook objects can be registered with an interpreter, and
+ when a callback is invoked, the associated method on each one of
+ those hook objects will be called by the interpreter in sequence.</p>
+<p> Hooks are simply instances, nominally derived from the <code>empy.Hook</code>
+ class. The <code>empy.Hook</code> class itself defines a series of methods,
+ with the expected arguments, which would be called by a running
+ EmPy interpreter. This scenario, much improved from the prior
+ implementation in 2.0, allows hooks to keep state and have more
+ direct access to the interpreter they are running in (the
+ <code>empy.Hook</code> instance contains an <code>interpreter</code> attribute).</p>
+<p> To use a hook, derive a class from <code>empy.Hook</code> and override the
+ desired methods (with the same signatures as they appear in the
+ base class). Create an instance of that subclass, and then
+ register it with a running interpreter with the <code>empy.addHook</code>
+ function. (This same hook instance can be removed with the
+ <code>empy.removeHook</code> function.)</p>
+<p> More than one hook instance can be registered with an interpreter;
+ in such a case, the appropriate methods are invoked on each
+ instance in the order in which they were registered. To adjust
+ this behavior, an optional <code>prepend</code> argument to the
+ <code>empy.addHook</code> function can be used dictate that the new hook
+ should placed at the <em>beginning</em> of the sequence of hooks, rather
+ than at the end (which is the default).</p>
+<p> All hooks can be enabled and disabled entirely for a given
+ interpreter; this is done with the <code>empy.enableHooks</code> and
+ <code>empy.disableHooks</code> functions. By default hooks are enabled, but
+ obviously if no hooks have been registered no hook callbacks will
+ be made. Whether hooks are enabled or disabled can be determined
+ by calling <code>empy.areHooksEnabled</code>. To get a (copy of) the list of
+ registered hooks, call <code>empy.getHooks</code>. Finally, to invoke a hook
+ manually, use <code>empy.invokeHook</code>.</p>
+<p> For a list of supported hook callbacks, see the <code>empy.Hook</code> class
+ definition.</p>
+<p> As a practical example, this sample Python code would print a
+ pound sign followed by the name of every file that is included
+ with 'empy.include':
+<pre>
+ class IncludeHook(empy.Hook):
+ def beforeInclude(self, name, file, locals):
+ print "# %s" % name
+
+ empy.addHook(IncludeHook())
+</pre>
+</p>
+<h3>Custom markup</h3>
+<p> Since version 3.2.1, the markup '@<...>' is reserved for
+ user-defined use. Unlike the other markups, this markup has no
+ specified meaning on its own, and can be provided a meaning by the
+ user. This meaning is provided with the use of a "custom
+ callback," or just "callback," which can be set, queried, or reset
+ using the pseudomodule function.</p>
+<p> The custom callback is a callable object which, when invoked, is
+ passed a single argument: a string representing the contents of
+ what was found inside the custom markup '@<...>'.</p>
+<p> To register a callback, call <code>empy.registerCallback</code>. To remove
+ one, call <code>empy.deregisterCallback</code>. To retrieve the callback (if
+ any) registered with the interpreter, use <code>empy.getCallback</code>.
+ Finally, to invoke the callback just as if the custom markup were
+ encountered, call <code>empy.invokeCallback</code>. For instance, '@<This
+ text>' would be equivalent to the call <code>@empy.invokeCallback("This
+ text")</code>.</p>
+<p> By default, to invoke a callback (either explicitly with
+ <code>empy.invokeCallback</code> or by processing a '@<...>' custom markup)
+ when no callback has been registered is an error. This behavior
+ can be changed with the <code>CALLBACK_OPT</code> option, or the
+ --no-callback-error command line option.</p>
+<h3>Pseudomodule</h3>
+<p> The <code>empy</code> pseudomodule is available only in an operating EmPy
+ system. (The name of the module, by default <code>empy</code>, can be
+ changed with the -m option or the <code>EMPY_PSEUDO</code> environment
+ variable). It is called a pseudomodule because it is not actually
+ a module, but rather exports a module-like interface. In fact,
+ the pseudmodule is actually the same internal object as the
+ interpreter itself.</p>
+<p> The pseudomodule contains the following functions and objects (and
+ their signatures, with a suffixed <code>opt</code> indicating an optional
+ argument):</p>
+<p> First, basic identification:</p>
+<dl>
+<dt> <strong><code>VERSION</code></strong></dt>
+<dd>A constant variable which contains a
+ string representation of the EmPy version.</dd>
+<dt> <strong><code>SIGNIFICATOR_RE_STRING</code></strong></dt>
+<dd>A constant variable representing a
+ regular expression string (using the default prefix) that can be
+ used to find significators in EmPy code.</dd>
+<dt> <strong><code>SIGNIFICATOR_RE_SUFFIX</code></strong></dt>
+<dd>The portion of the significator
+ regular expression string excluding the prefix, so that those
+ using non-standard prefix can build their own custom regular
+ expression string with <code>myPrefix + empy.SIGNIFICATOR_RE_SUFFIX</code>.</dd>
+<dt> <strong><code>interpreter</code></strong></dt>
+<dd>The instance of the interpreter that is
+ currently being used to perform execution. <em>Note:</em> This is now
+ obsolete; the pseudomodule is itself the interpreter. Instead
+ of using <code>empy.interpreter</code>, simply use <code>empy</code>.</dd>
+<dt> <strong><code>argv</code></strong></dt>
+<dd>A list consisting of the name of the primary EmPy
+ script and its command line arguments, in analogue to the
+ <code>sys.argv</code> list.</dd>
+<dt> <strong><code>args</code></strong></dt>
+<dd>A list of the command line arguments following the
+ primary EmPy script; this is equivalent to <code>empy.argv[1:]</code>.</dd>
+<dt> <strong><code>identify() -> string, integer</code></strong></dt>
+<dd>Retrieve identification
+ information about the current parsing context. Returns a
+ 2-tuple consisting of a filename and a line number; if the file
+ is something other than from a physical file (<em>e.g.</em>, an
+ explicit expansion with <code>empy.expand</code>, a file-like object within
+ Python, or via the -E or -F command line options), a string
+ representation is presented surrounded by angle brackets. Note
+ that the context only applies to the <em>EmPy</em> context, not the
+ Python context.</dd>
+<dt> <strong><code>atExit(callable)</code></strong></dt>
+<dd>Register a callable object (such as a
+ function) taking no arguments which will be called at the end of
+ a normal shutdown. Callable objects registered in this way are
+ called in the reverse order in which they are added, so the
+ first callable registered with <code>empy.atExit</code> is the last one to
+ be called. Note that although the functionality is related to
+ hooks, <code>empy.atExit</code> does no work via the hook mechanism, and
+ you are guaranteed that the interpreter and stdout will be in a
+ consistent state when the callable is invoked.</dd>
+</dl>
+<p> Context manipulation:</p>
+<dl>
+<dt> <strong><code>pushContext(name_opt, line_opt)</code></strong></dt>
+<dd>Create a new context with
+ the given name and line and push it on the stack.</dd>
+<dt> <strong><code>popContext()</code></strong></dt>
+<dd>Pop the top context and dispose of it.</dd>
+<dt> <strong><code>setContextName(name)</code></strong></dt>
+<dd>Manually set the name of the current
+ context.</dd>
+<dt> <strong><code>setContextLine(line)</code></strong></dt>
+<dd>Manually set the line number of the
+ current context; line must be a numeric value. Note that
+ afterward the line number will increment by one for each newline
+ that is encountered, as before.</dd>
+</dl>
+<p> Globals manipulation:</p>
+<dl>
+<dt> <strong><code>getGlobals()</code></strong></dt>
+<dd>Retrieve the globals dictionary for this
+ interpreter. Unlike when calling <code>globals()</code> in Python, this
+ dictionary <em>can</em> be manipulated and you <em>can</em> expect changes you
+ make to it to be reflected in the interpreter that holds it.</dd>
+<dt> <strong><code>setGlobals(globals)</code></strong></dt>
+<dd>Reseat the globals dictionary
+ associated with this interpreter to the provided mapping type.</dd>
+<dt> <strong><code>updateGlobals(globals)</code></strong></dt>
+<dd>Merge the given dictionary into
+ this interpreter's globals.</dd>
+<dt> <strong><code>clearGlobals(globals_opt)</code></strong></dt>
+<dd>Clear out the globals
+ (restoring, of course, the <code>empy</code> pseudomodule). Optionally,
+ instead of starting with a refresh dictionary, use the
+ dictionary provided.</dd>
+<dt> <strong><code>saveGlobals(deep=True)</code></strong></dt>
+<dd>Save a copy of the globals onto an
+ internal history stack from which it can be restored later. The
+ optional <code>deep</code> argument indicates whether or not the copying
+ should be a deep copy (default) or a shallow one. Copying is
+ done with <code>copy.deepcopy</code> or <code>copy.copy</code>, respectively.</dd>
+<dt> <strong><code>restoreGlobals(destructive=True)</code></strong></dt>
+<dd>Restore the most
+ recently saved globals from the history stack to as the current
+ globals for this instance. The optional <code>destructive</code> argument
+ indicates whether or not the restore should remove the restored
+ globals from the history stack (default), or whether it should
+ be left there for subsequent restores.</dd>
+</dl>
+<p> Types:</p>
+<dl>
+<dt> <strong><code>Interpreter</code></strong></dt>
+<dd>The actual interpreter class.</dd>
+</dl>
+<p> The following functions allow direct execution; optional <code>locals</code>
+ arguments, if specified, are treated as the locals dictionary in
+ evaluation and execution:</p>
+<dl>
+<dt> <strong><code>defined(name, locals_opt)</code></strong></dt>
+<dd>Return true if the given name
+ is defined either in the (optional) locals or the interpreter
+ globals; return false otherwise.</dd>
+<dt> <strong><code>evaluate(expression, locals_opt)</code></strong></dt>
+<dd>Evaluate the given
+ expression.</dd>
+<dt> <strong><code>serialize(expression, locals_opt)</code></strong></dt>
+<dd>Serialize the
+ expression, just as the interpreter would: If it is not None,
+ convert it to a string with the <code>str</code> builtin function, and then
+ write out the result. If it evaluates to None, do nothing.</dd>
+<dt> <strong><code>execute(statements, locals_opt)</code></strong></dt>
+<dd>Execute the given
+ statement(s).</dd>
+<dt> <strong><code>single(source, locals_opt)</code></strong></dt>
+<dd>Interpret the "single" source
+ code, just as the Python interactive interpreter would.</dd>
+<dt> <strong><code>import_(name, locals_opt)</code></strong></dt>
+<dd>Import a module.</dd>
+<dt> <strong><code>atomic(name, value, locals_opt)</code></strong></dt>
+<dd>Perform a single, atomic
+ assignment. In this case name is the string denoating the name
+ of the (single) variable to be assigned to, and value is a
+ Python object which the name is to be bound to.</dd>
+<dt> <strong><code>assign(name, value, locals_opt)</code></strong></dt>
+<dd>Perform general
+ assignment. This decays to atomic assignment (above) in the
+ normal case, but supports "tuple unpacking" in the sense that if
+ name string contains commas, it is treated as a sequence of
+ names and memberwise assignment with each member of the value
+ (still a Python object, but which must be a sequence). This
+ function will raise a <code>TypeError</code> or <code>ValueError</code> just like
+ Python would if tuple unpacking is not possible (that is, if the
+ value is not a sequence or is of an incompatible length,
+ respectively). This only supports the assignment of Python
+ identifiers, not arbitrary Python lvalues.</dd>
+<dt> <strong><code>significate(key, value_opt, locals_opt)</code></strong></dt>
+<dd>Do a manual
+ signification. If <code>value</code> is not specified, it is treated as
+ <code>None</code>.</dd>
+</dl>
+<p> The following functions relate to source manipulation:</p>
+<dl>
+<dt> <strong><code>include(file_or_filename, locals_opt)</code></strong></dt>
+<dd>Include another
+ EmPy file, by processing it in place. The argument can either
+ be a filename (which is then opened with <code>open</code> in text mode) or
+ a file object, which is used as is. Once the included file is
+ processed, processing of the current file continues. Includes
+ can be nested. The call also takes an optional locals
+ dictionary which will be passed into the evaluation function.</dd>
+<dt> <strong><code>expand(string, locals_opt)</code> -> string</strong></dt>
+<dd>Explicitly invoke
+ the EmPy parsing system to process the given string and return
+ its expansion. This allows multiple levels of expansion,
+ <em>e.g.</em>, <code>@(empy.expand("@(2 + 2)"))</code>. The call also takes an
+ optional locals dictionary which will be passed into the
+ evaluation function. This is necessary when text is being
+ expanded inside a function definition and it is desired that the
+ function arguments (or just plain local variables) are available
+ to be referenced within the expansion.</dd>
+<dt> <strong><code>quote(string) -> string</code></strong></dt>
+<dd>The inverse process of
+ <code>empy.expand</code>, this will take a string and return a new string
+ that, when expanded, would expand to the original string. In
+ practice, this means that appearances of the prefix character
+ are doubled, except when they appear inside a string literal.</dd>
+<dt> <strong><code>escape(string, more_opt) -> string</code></strong></dt>
+<dd>Given a string, quote
+ the nonprintable characters contained within it with EmPy
+ escapes. The optional <code>more</code> argument specifies additional
+ characters that should be escaped.</dd>
+<dt> <strong><code>flush()</code></strong></dt>
+<dd>Do an explicit flush on the underlying stream.</dd>
+<dt> <strong><code>string(string, name_opt, locals_opt)</code></strong></dt>
+<dd>Explicitly process a
+ string-like object. This differs from <code>empy.expand</code> in that the
+ string is directly processed into the EmPy system, rather than
+ being evaluated in an isolated context and then returned as a
+ string.</dd>
+</dl>
+<p> Changing the behavior of the pseudomodule itself:</p>
+<dl>
+<dt> <strong><code>flatten(keys_opt)</code></strong></dt>
+<dd>Perform the equivalent of <code>from empy
+ import ...</code> in code (which is not directly possible because
+ <code>empy</code> is a pseudomodule). If keys is omitted, it is taken as
+ being everything in the <code>empy</code> pseudomodule. Each of the
+ elements of this pseudomodule is flattened into the globals
+ namespace; after a call to <code>empy.flatten</code>, they can be referred
+ to simple as globals, <em>e.g.</em>, <code>@divert(3)</code> instead of
+ <code>@empy.divert(3)</code>. If any preexisting variables are bound to
+ these names, they are silently overridden. Doing this is
+ tantamount to declaring an <code>from ... import ...</code> which is often
+ considered bad form in Python.</dd>
+</dl>
+<p> Prefix-related functions:</p>
+<dl>
+<dt> <strong><code>getPrefix() -> char</code></strong></dt>
+<dd>Return the current prefix.</dd>
+<dt> <strong><code>setPrefix(char)</code></strong></dt>
+<dd>Set a new prefix. Immediately after this
+ call finishes, the prefix will be changed. Changing the prefix
+ affects only the current interpreter; any other created
+ interpreters are unaffected. Setting the prefix to None or the
+ null string means that no further markups will be processed,
+ equivalent to specifying the --no-prefix command line argument.</dd>
+</dl>
+<p> Diversions:</p>
+<dl>
+<dt> <strong><code>stopDiverting()</code></strong></dt>
+<dd>Any diversions that are currently taking
+ place are stopped; thereafter, output will go directly to the
+ output file as normal. It is never illegal to call this
+ function.</dd>
+<dt> <strong><code>createDiversion(name)</code></strong></dt>
+<dd>Create a diversion, but do not
+ begin diverting to it. This is the equivalent of starting a
+ diversion and then immediately stopping diversion; it is used in
+ cases where you want to make sure that a diversion will exist
+ for future replaying but may be empty.</dd>
+<dt> <strong><code>startDiversion(name)</code></strong></dt>
+<dd>Start diverting to the specified
+ diversion name. If such a diversion does not already exist, it
+ is created; if it does, then additional material will be
+ appended to the preexisting diversions.</dd>
+<dt> <strong><code>playDiversion(name)</code></strong></dt>
+<dd>Recall the specified diversion and
+ then purge it. The provided diversion name must exist.</dd>
+<dt> <strong><code>replayDiversion(name)</code></strong></dt>
+<dd>Recall the specified diversion
+ without purging it. The provided diversion name must exist.</dd>
+<dt> <strong><code>purgeDiversion(name)</code></strong></dt>
+<dd>Purge the specified diversion
+ without recalling it. The provided diversion name must exist.</dd>
+<dt> <strong><code>playAllDiversions()</code></strong></dt>
+<dd>Play (and purge) all existing
+ diversions in the sorted order of their names. This call does
+ an implicit <code>empy.stopDiverting</code> before executing.</dd>
+<dt> <strong><code>replayAllDiversions()</code></strong></dt>
+<dd>Replay (without purging) all
+ existing diversions in the sorted order of their names. This
+ call does an implicit <code>empy.stopDiverting</code> before executing.</dd>
+<dt> <strong><code>purgeAllDiversions()</code></strong></dt>
+<dd>Purge all existing diversions
+ without recalling them. This call does an implicit
+ <code>empy.stopDiverting</code> before executing.</dd>
+<dt> <strong><code>getCurrentDiversion() -> diversion</code></strong></dt>
+<dd>Return the name of the
+ current diversion.</dd>
+<dt> <strong><code>getAllDiversions() -> sequence</code></strong></dt>
+<dd>Return a sorted list of
+ all existing diversions.</dd>
+</dl>
+<p> Filters:</p>
+<dl>
+<dt> <strong><code>getFilter() -> filter</code></strong></dt>
+<dd>Retrieve the current filter.
+ <code>None</code> indicates no filter is installed.</dd>
+<dt> <strong><code>resetFilter()</code></strong></dt>
+<dd>Reset the filter so that no filtering is
+ done.</dd>
+<dt> <strong><code>nullFilter()</code></strong></dt>
+<dd>Install a special null filter, one which
+ consumes all text and never sends any text to the output.</dd>
+<dt> <strong><code>setFilter(shortcut)</code></strong></dt>
+<dd>Install a new filter. A filter is
+ <code>None</code> or an empty sequence representing no filter, or <code>0</code> for a
+ null filter, a function for a function filter, a string for a
+ string filter, or an instance of <code>empy.Filter</code> (or a workalike
+ object). If filter is a list of the above things, they will be
+ chained together manually; if it is only one, it will be
+ presumed to be solitary or to have already been manually chained
+ together. See the "Filters" section for more information.</dd>
+<dt> <strong><code>attachFilter(shortcut)</code></strong></dt>
+<dd>Attach a single filter (sequences
+ are not allowed here) to the end of a currently existing filter
+ chain, or if there is no current chain, install it as
+ <code>empy.setFilter</code> would. As with <code>empy.setFilter</code>, the shortcut
+ versions of filters are also allowed here.</dd>
+</dl>
+<p> Hooks:</p>
+<dl>
+<dt> <strong><code>areHooksEnabled()</code></strong></dt>
+<dd>Return whether or not hooks are
+ presently enabled.</dd>
+<dt> <strong><code>enableHooks()</code></strong></dt>
+<dd>Enable invocation of hooks. By default
+ hooks are enabled.</dd>
+<dt> <strong><code>disableHooks()</code></strong></dt>
+<dd>Disable invocation of hooks. Hooks can
+ still be added, removed, and queried, but invocation of hooks
+ will not occur (even explicit invocation with
+ <code>empy.invokeHook</code>).</dd>
+<dt> <strong><code>getHooks()</code></strong></dt>
+<dd>Get a (copy of the) list of the hooks
+ currently registered.</dd>
+<dt> <strong><code>clearHooks()</code></strong></dt>
+<dd>Clear all the hooks registered with this
+ interpreter.</dd>
+<dt> <strong><code>addHook(hook, prepend_opt)</code></strong></dt>
+<dd>Add this hook to the hooks
+ associated with this interpreter. By default, the hook is
+ appended to the end of the existing hooks, if any; if the
+ optional insert argument is present and true, it will be
+ prepended to the list instead.</dd>
+<dt> <strong><code>removeHook(hook)</code></strong></dt>
+<dd>Remove this hook from the hooks
+ associated with this interpreter.</dd>
+<dt> <strong><code>invokeHook(_name, ...)</code></strong></dt>
+<dd>Manually invoke a hook method.
+ The remaining arguments are treated as keyword arguments and the
+ resulting dictionary is passed in as the second argument to the
+ hooks.</dd>
+</dl>
+<p> Custom markup callback:</p>
+<dl>
+<dt> <strong><code>getCallback() -> callback</code></strong></dt>
+<dd>Retrieve the current callback
+ associated with this interpreter, or <code>None</code> if it does not yet
+ have one.</dd>
+<dt> <strong><code>registerCallback(callback)</code></strong></dt>
+<dd>Register a callback to be
+ called whenever a custom markup ('@<...>') is encountered. When
+ encountered, <code>invokeCallback</code> is called.</dd>
+<dt> <strong><code>deregisterCallback()</code></strong></dt>
+<dd>Clear any callback previously
+ registered with the interpreter for being called when a custom
+ markup is encountered.</dd>
+<dt> <strong><code>invokeCallback(contents)</code></strong></dt>
+<dd>Invoke a custom callback. This
+ function is called whenever a custom markup ('@<...>') is
+ encountered. It in turn calls the registered callback, with a
+ single argument, <code>contents</code>, which is a string representing of
+ the contents of the custom markup.</dd>
+</dl>
+<h3>Invocation</h3>
+<p> Basic invocation involves running the interpreter on an EmPy file
+ and some optional arguments. If no file are specified, or the
+ file is named <code>-</code>, EmPy takes its input from stdin. One can
+ suppress option evaluation (to, say, specify a file that begins
+ with a dash) by using the canonical <code>--</code> option.</p>
+<dl>
+<dt> <strong><code>-h</code>/<code>--help</code></strong></dt>
+<dd>Print usage and exit.</dd>
+<dt> <strong><code>-H</code>/<code>--extended-help</code></strong></dt>
+<dd>Print extended usage and exit.
+ Extended usage includes a rundown of all the legal expansions,
+ escape sequences, pseudomodule contents, used hooks, and
+ supported environment variables.</dd>
+<dt> <strong><code>-v</code>/<code>--verbose</code></strong></dt>
+<dd>The EmPy system will print all manner of
+ details about what it is doing and what it is processing to
+ stderr.</dd>
+<dt> <strong><code>-V</code>/<code>--version</code></strong></dt>
+<dd>Print version and exit.</dd>
+<dt> <strong><code>-a</code>/<code>--append</code> (filename)</strong></dt>
+<dd>Open the specified file for
+ append instead of using stdout.</dd>
+<dt> <strong><code>-b</code>/<code>--buffered-output</code></strong></dt>
+<dd>Fully buffer processing output,
+ including the file open itself. This is helpful when, should an
+ error occur, you wish that no output file be generated at all
+ (for instance, when using EmPy in conjunction with make). When
+ specified, either the -o or -a options must be specified, and
+ the -b option must precede them. This can also be specified
+ through the existence of the <code>EMPY_BUFFERED_OUTPUT</code> environment
+ variable.</dd>
+<dt> <strong><code>-f</code>/<code>--flatten</code></strong></dt>
+<dd>Before processing, move the contents of
+ the <code>empy</code> pseudomodule into the globals, just as if
+ <code>empy.flatten()</code> were executed immediately after starting the
+ interpreter. That is, <em>e.g.</em>, <code>empy.include</code> can be referred to
+ simply as <code>include</code> when this flag is specified on the command
+ line. This can also be specified through the existence of the
+ <code>EMPY_FLATTEN</code> environment variable.</dd>
+<dt> <strong><code>-i</code>/<code>--interactive</code></strong></dt>
+<dd>After the main EmPy file has been
+ processed, the state of the interpreter is left intact and
+ further processing is done from stdin. This is analogous to the
+ Python interpreter's -i option, which allows interactive
+ inspection of the state of the system after a main module is
+ executed. This behaves as expected when the main file is stdin
+ itself. This can also be specified through the existence of the
+ <code>EMPY_INTERACTIVE</code> environment variable.</dd>
+<dt> <strong><code>-k</code>/<code>--suppress-errors</code></strong></dt>
+<dd>Normally when an error is
+ encountered, information about its location is printed and the
+ EmPy interpreter exits. With this option, when an error is
+ encountered (except for keyboard interrupts), processing stops
+ and the interpreter enters interactive mode, so the state of
+ affairs can be assessed. This is also helpful, for instance,
+ when experimenting with EmPy in an interactive manner. -k
+ implies -i.</dd>
+<dt> <strong><code>-n</code>/<code>--no-override-stdout</code></strong></dt>
+<dd>Do not override <code>sys.stdout</code>
+ with a proxy object which the EmPy system interacts with. If
+ suppressed, this means that side effect printing will not be
+ captured and routed through the EmPy system. However, if this
+ option is specified, EmPy can support multithreading.</dd>
+<dt> <strong><code>-o</code>/<code>--output</code> (filename)</strong></dt>
+<dd>Open the specified file for
+ output instead of using stdout. If a file with that name
+ already exists it is overwritten.</dd>
+<dt> <strong><code>-p</code>/<code>--prefix</code> (prefix)</strong></dt>
+<dd>Change the prefix used to detect
+ expansions. The argument is the one-character string that will
+ be used as the prefix. Note that whatever it is changed to, the
+ way to represent the prefix literally is to double it, so if <code>$</code>
+ is the prefix, a literal dollar sign is represented with <code>$$</code>.
+ Note that if the prefix is changed to one of the secondary
+ characters (those that immediately follow the prefix to indicate
+ the type of action EmPy should take), it will not be possible to
+ represent literal prefix characters by doubling them (<em>e.g.</em>, if
+ the prefix were inadvisedly changed to <code>#</code> then <code>##</code> would
+ already have to represent a comment, so <code>##</code> could not represent
+ a literal <code>#</code>). This can also be specified through the
+ <code>EMPY_PREFIX</code> environment variable.</dd>
+<dt> <strong><code>-r</code>/<code>--raw-errors</code></strong></dt>
+<dd>Normally, EmPy catches Python
+ exceptions and prints them alongside an error notation
+ indicating the EmPy context in which it occurred. This option
+ causes EmPy to display the full Python traceback; this is
+ sometimes helpful for debugging. This can also be specified
+ through the existence of the <code>EMPY_RAW_ERRORS</code> environment
+ variable.</dd>
+<dt> <strong><code>-u</code>/<code>--unicode</code></strong></dt>
+<dd>Enable the Unicode subsystem. This option
+ only need be present if you wish to enable the Unicode subsystem
+ with the defaults; any other Unicode-related option (starting
+ with --unicode...) will also enable the Unicode subsystem.</dd>
+<dt> <strong><code>-D</code>/<code>--define</code> (assignment)</strong></dt>
+<dd>Execute a Python assignment of
+ the form <code>variable = expression</code>. If only a variable name is
+ provided (<em>i.e.</em>, the statement does not contain an <code>=</code> sign),
+ then it is taken as being assigned to None. The -D option is
+ simply a specialized -E option that special cases the lack of an
+ assignment operator. Multiple -D options can be specified.</dd>
+<dt> <strong><code>-E</code>/<code>--execute</code> (statement)</strong></dt>
+<dd>Execute the Python (not EmPy)
+ statement before processing any files. Multiple -E options can
+ be specified.</dd>
+<dt> <strong><code>-F</code>/<code>--execute-file</code> (filename)</strong></dt>
+<dd>Execute the Python (not
+ EmPy) file before processing any files. This is equivalent to
+ <code>-E execfile("filename")</code> but provides a more readable context.
+ Multiple -F options can be specified.</dd>
+<dt> <strong><code>-I</code>/<code>--import</code> (module)</strong></dt>
+<dd>Imports the specified module name
+ before processing any files. Multiple modules can be specified
+ by separating them by commas, or by specifying multiple -I
+ options.</dd>
+<dt> <strong><code>-P</code>/<code>--preprocess</code> (filename)</strong></dt>
+<dd>Process the EmPy file before
+ processing the primary EmPy file on the command line.</dd>
+<dt> <strong><code>--binary</code></strong></dt>
+<dd>Treat the file as a binary file, and read in
+ chunks rather than line by line. In this mode, the "line"
+ indicator represents the number of bytes read, not the number of
+ lines processed.</dd>
+<dt> <strong><code>--no-prefix</code></strong></dt>
+<dd>Disable the prefixing system entirely; when
+ specified, EmPy will not expand any markups. This allows EmPy
+ to merely act as a Unicode encoding translator..</dd>
+<dt> <strong><code>--pause-at-end</code></strong></dt>
+<dd>If present, then <code>raw_input</code> will be
+ called at the end of processing. Useful in systems where the
+ output window would otherwise be closed by the operating
+ system/window manager immediately after EmPy exited.</dd>
+<dt> <strong><code>--relative-path</code></strong></dt>
+<dd>When present, the path the EmPy script
+ being invoked is contained in will be prepended to <code>sys.path</code>.
+ This is analogous to Python's internal handling of <code>sys.path</code>
+ and scripts. If input is from stdin (<code>-</code> for a filename or no
+ filename is specified), then nothing is added to the path.</dd>
+<dt> <strong><code>--no-callback-error</code></strong></dt>
+<dd>Do not consider it an error if the
+ custom markup is invoked '@<...>' and there is no callback
+ function registered for it.</dd>
+<dt> <strong><code>--chunk-size</code> (chunk)</strong></dt>
+<dd>Use the specific binary chunk size
+ rather than the default; implies --binary.</dd>
+<dt> <strong><code>--unicode-encoding</code> (encoding)</strong></dt>
+<dd>Specify the Unicode
+ encoding to be used for both input and output.</dd>
+<dt> <strong><code>--unicode-input-encoding</code> (encoding)</strong></dt>
+<dd>Specify the Unicode
+ encoding to be used for input.</dd>
+<dt> <strong><code>--unicode-output-encoding</code> (encoding)</strong></dt>
+<dd>Specify the Unicode
+ encoding to be used for output.</dd>
+<dt> <strong>'--unicode-input-errors (errors)</strong></dt>
+<dd>Specify the Unicode error
+ handling to be used for input.</dd>
+<dt> <strong>'--unicode-errors (errors)</strong></dt>
+<dd>Specify the Unicode error
+ handling to be used for both input and output.</dd>
+<dt> <strong>'--unicode-output-errors (errors)</strong></dt>
+<dd>Specify the Unicode error
+ handling to be used for output.</dd>
+</dl>
+<h3>Environment variables</h3>
+<p> EmPy also supports a few environment variables to predefine
+ certain behaviors. The settings chosen by environment variables
+ can be overridden via command line arguments. The following
+ environment variables have meaning to EmPy:</p>
+<dl>
+<dt> <strong><code>EMPY_OPTIONS</code></strong></dt>
+<dd>If present, the contents of this environment
+ variable will be treated as options, just as if they were
+ entered on the command line, <em>before</em> the actual command line
+ arguments are processed. Note that these arguments are <em>not</em>
+ processed by the shell, so quoting, filename globbing, and the
+ like, will not work.</dd>
+<dt> <strong><code>EMPY_PREFIX</code></strong></dt>
+<dd>If present, the value of this environment
+ variable represents the prefix that will be used; this is
+ equivalent to the -p command line option.</dd>
+<dt> <strong><code>EMPY_PSEUDO</code></strong></dt>
+<dd>If present, the value of this environment
+ variable represents the name of the pseudomodule that will be
+ incorporated into every running EmPy system; this is equivalent
+ to the -m command line option.</dd>
+<dt> <strong><code>EMPY_FLATTEN</code></strong></dt>
+<dd>If defined, this is equivalent to including
+ -f on the command line.</dd>
+<dt> <strong><code>EMPY_RAW_ERRORS</code></strong></dt>
+<dd>If defined, this is equivalent to
+ including -r on the command line.</dd>
+<dt> <strong><code>EMPY_INTERACTIVE</code></strong></dt>
+<dd>If defined, this is equivalent to
+ including -i on the command line.</dd>
+<dt> <strong><code>EMPY_BUFFERED_OUTPUT</code></strong></dt>
+<dd>If defined, this is equivalent to
+ including -b on the command line.</dd>
+<dt> <strong><code>EMPY_UNICODE</code></strong></dt>
+<dd>If defined, this is equivalent to including
+ -u on the command line.</dd>
+<dt> <strong><code>EMPY_UNICODE_INPUT_ENCODING</code></strong></dt>
+<dd>If present, the value of this
+ environment variable indicates the name of the Unicode input
+ encoding to be used. This is equivalent to the
+ --unicode-input-encoding command line option.</dd>
+<dt> <strong><code>EMPY_UNICODE_OUTPUT_ENCODING</code></strong></dt>
+<dd>If present, the value of
+ this environment variable indicates the name of the Unicode
+ output encoding to be used. This is equivalent to the
+ --unicode-output-encoding command line option.</dd>
+<dt> <strong><code>EMPY_UNICODE_INPUT_ERRORS</code></strong></dt>
+<dd>If present, the value of this
+ environment variable indicates the name of the error handler to
+ be used for input. This is equivalent to the
+ --unicode-input-errors command line option.</dd>
+<dt> <strong><code>EMPY_UNICODE_OUTPUT_ERRORS</code></strong></dt>
+<dd>If present, the value of this
+ environment variable indicates the name of the error handler to
+ be used for output. This is equivalent to the
+ --unicode-output-errors command line option.</dd>
+</dl>
+<h3>Examples and testing EmPy</h3>
+<p> See the sample EmPy file <code>sample.em</code> which is included with the
+ distribution. Run EmPy on it by typing something like:
+<pre>
+ ./em.py sample.em
+</pre>
+</p>
+<p> and compare the results and the sample source file side by side.
+ The sample content is intended to be self-documenting, and even an
+ introduction to the basic features of EmPy while simultaneously
+ exercising them.</p>
+<p> The file <code>sample.bench</code> is the benchmark output of the sample.
+ Running the EmPy interpreter on the provided <code>sample.em</code> file
+ should produce precisely the same results. You can run the
+ provided test script to see if your EmPy environment is behaving
+ as expected (presuming a Unix-like operating system):
+<pre>
+ ./test.sh
+</pre>
+</p>
+<p> By default this will test with the first Python interpreter
+ available in the path; if you want to test with another
+ interpreter, you can provide it as the first argument on the
+ command line, <em>e.g.</em>:
+<pre>
+ ./test.sh python2.1
+ ./test.sh /usr/bin/python1.5
+ ./test.sh jython
+</pre>
+</p>
+<p> A more comprehensive test suite and set of real-world examples is
+ planned for a future version.</p>
+<h3>Embedding EmPy</h3>
+<p> For atomic applications, the <code>expand</code> function is provided (the
+ extra keyword arguments passed in are treated as locals):
+<pre>
+ import em
+ print em.expand("@x + @y is @(x + y).", x=2, y=3)
+</pre>
+</p>
+<p> One can specify a globals dictionary and all the other interpreter
+ options (below) as well. One can specify a globals dictionary
+ that will be used if one wants persistence:
+<pre>
+ import em
+ g = {}
+ em.expand("@{x = 10}", g)
+ print em.expand("x is @x.", g)
+</pre>
+</p>
+<p> The standalone <code>expand</code> function, however, creates and destroys an
+ <code>Interpreter</code> instance each time it is called. For repeated
+ expansions, this can be expensive. Instead, you will probably
+ want to use the full-fledged features of embedding. An EmPy
+ interpreter can be created with as code as simple as:
+<pre>
+ import em
+ interpreter = em.Interpreter()
+ # The following prints the results to stdout:
+ interpreter.string("@{x = 123}@x\n")
+ # This expands to the same thing, but puts the results as a
+ # string in the variable result:
+ result = interpreter.expand("@{x = 123}@x\n")
+ # This just prints the value of x directly:
+ print interpreter.globals['x']
+ # Process an actual file (and output to stdout):
+ interpreter.file(open('/path/to/some/file'))
+ interpreter.shutdown() # this is important; see below
+</pre>
+</p>
+<p> One can capture the output of a run in something other than stdout
+ by specifying the <em>output</em> parameter:
+<pre>
+ import em, StringIO
+ output = StringIO.StringIO()
+ interpreter = em.Interpreter(output=output)
+ # Do something.
+ interpreter.file(open('/path/to/some/file'))
+ interpreter.shutdown() # again, this is important; see below
+ print output.getvalue() # this is the result from the session
+</pre>
+</p>
+<p> When you are finished with your interpreter, it is important to
+ call its shutdown method:
+<pre>
+ interpreter.shutdown()
+</pre>
+</p>
+<p> This will ensure that the interpreter cleans up all its overhead,
+ entries in the <code>sys.stdout</code> proxy, and so forth. It is usually
+ advisable that this be used in a try...finally clause:
+<pre>
+ interpreter = em.Interpreter(...)
+ try:
+ ...
+ finally:
+ interpreter.shutdown()
+</pre>
+</p>
+<p> The <code>em.Interpreter</code> constructor takes the following arguments;
+ all are optional. Since options may be added in the future, it is
+ highly recommended that the constructor be invoked via keyword
+ arguments, rather than assuming their order. The arguments are:</p>
+<dl>
+<dt> <em>output</em></dt>
+<dd>The output file which the interpreter will be sending
+ all its processed data to. This need only be a file-like object;
+ it need not be an actual file. If omitted, <code>sys.__stdout__</code> is
+ used.</dd>
+<dt> <em>argv</em></dt>
+<dd>An argument list analogous to <code>sys.argv</code>, consisting of
+ the script name and zero or more arguments. These are available
+ to executing interpreters via <code>empy.argv</code> and <code>empy.args</code>. If
+ omitted, a non-descript script name is used with no arguments.</dd>
+<dt> <em>prefix</em></dt>
+<dd>The prefix (a single-character string). Defaults to
+ <code>@</code>. It is an error for this to be anything other than one
+ character.</dd>
+<dt> <em>pseudo</em></dt>
+<dd>The name (string) of the pseudmodule. Defaults to
+ <code>empy</code>.</dd>
+<dt> <em>options</em></dt>
+<dd>A dictionary of options that can override the default
+ behavior of the interpreter. The names of the options are
+ constant names ending in <code>_OPT</code> and their defaults are given in
+ <code>Interpreter.DEFAULT_OPTIONS</code>.</dd>
+<dt> <em>globals</em></dt>
+<dd>By default, interpreters begin with a pristine
+ dictionary of globals (except, of course, for the <code>empy</code>
+ pseudomodule). Specifying this argument will allow the globals
+ to start with more.</dd>
+<dt> <em>hooks</em></dt>
+<dd>A sequence of hooks (or <code>None</code> for none) to register
+ with the interpreter at startup. Hooks can, of course, be added
+ after the fact, but this allows the hooks to intercept the
+ <code>atStartup</code> event (otherwise, the startup event would already
+ have occurred by the time new hooks could be registered)..</dd>
+</dl>
+<p> Many things can be done with EmPy interpreters; for the full
+ developer documentation, see the generated documentation for the
+ <code>em</code> module.</p>
+<h3>Interpreter options</h3>
+<p> The following options (passed in as part of the options dictionary
+ to the Interpreter constructor) have the following meanings. The
+ defaults are shown below and are also indicated in an
+ <code>Interpreter.DEFAULT_OPTIONS</code> dictionary.</p>
+<dl>
+<dt> <strong><code>BANGPATH_OPT</code></strong></dt>
+<dd>Should a bangpath (<code>#!</code>) as the first line
+ of an EmPy file be treated as if it were an EmPy comment? Note
+ that <code>#!</code> sequences starting lines or appearing anywhere else in
+ the file are untouched regardless of the value of this option.
+ Default: true.</dd>
+<dt> <strong><code>BUFFERED_OPT</code></strong></dt>
+<dd>Should an <code>abort</code> method be called upon
+ failure? This relates to the fully-buffered option, where all
+ output can be buffered including the file open; this option only
+ relates to the interpreter's behavior <em>after</em> that proxy file
+ object has been created. Default: false.</dd>
+<dt> <strong><code>RAW_OPT</code></strong></dt>
+<dd>Should errors be displayed as raw Python errors
+ (that is, the exception is allowed to propagate through to the
+ toplevel so that the user gets a standard Python traceback)?
+ Default: false.</dd>
+<dt> <strong><code>EXIT_OPT</code></strong></dt>
+<dd>Upon an error, should execution continue
+ (although the interpreter stacks will be purged)? Note that
+ even in the event this is set, the interpreter will halt upon
+ receiving a <code>KeyboardInterrupt</code>. Default: true.</dd>
+<dt> <strong><code>FLATTEN_OPT</code></strong></dt>
+<dd>Upon initial startup, should the <code>empy</code>
+ pseudomodule namespace be flattened, <em>i.e.</em>, should
+ <code>empy.flatten</code> be called? Note this option only has an effect
+ when the interpreter is first created; thereafter it is
+ ignored. Default: false.</dd>
+<dt> <strong><code>OVERRIDE_OPT</code></strong></dt>
+<dd>Should the <code>sys.stdout</code> object be overridden
+ with a proxy object? If not, side effect output cannot be
+ captured by the EmPy system, but EmPy will support
+ multithreading. Default: true.</dd>
+<dt> <strong><code>CALLBACK_OPT</code></strong></dt>
+<dd>If a callback is invoked when none has yet
+ been registered, should an error be raised or should the
+ situation be ignored? Default: true.</dd>
+</dl>
+<h3>Data flow</h3>
+<p> <strong>input -> interpreter -> diversions -> filters -> output</strong></p>
+<p> Here, in summary, is how data flows through a working EmPy system:</p>
+
+<ol>
+<li><p> Input comes from a source, such an .em file on the command
+ line, or via an <code>empy.include</code> statement.</p></li>
+<li><p> The interpreter processes this material as it comes in,
+ expanding EmPy expansions as it goes.</p></li>
+<li><p> After interpretation, data is then sent through the diversion
+ layer, which may allow it directly through (if no diversion is
+ in progress) or defer it temporarily. Diversions that are
+ recalled initiate from this point.</p></li>
+<li><p> Any filters in place are then used to filter the data and
+ produce filtered data as output.</p></li>
+<li><p> Finally, any material surviving this far is sent to the output
+ stream. That stream is stdout by default, but can be changed
+ with the -o or -a options, or may be fully buffered with the -b
+ option (that is, the output file would not even be opened until
+ the entire system is finished).</p></li>
+
+</ol>
+<h3>Author's notes</h3>
+<p> I originally conceived EmPy as a replacement for my <a href="http://www.alcyone.com/max/info/m4.html">Web
+ templating system</a> which
+ uses <a href="http://www.seindal.dk/rene/gnu/">m4</a> (a general
+ macroprocessing system for Unix).</p>
+<p> Most of my Web sites include a variety of m4 files, some of which
+ are dynamically generated from databases, which are then scanned
+ by a cataloging tool to organize them hierarchically (so that,
+ say, a particular m4 file can understand where it is in the
+ hierarchy, or what the titles of files related to it are without
+ duplicating information); the results of the catalog are then
+ written in database form as an m4 file (which every other m4 file
+ implicitly includes), and then GNU make converts each m4 to an
+ HTML file by processing it.</p>
+<p> As the Web sites got more complicated, the use of m4 (which I had
+ originally enjoyed for the challenge and abstractness) really
+ started to become an impediment to serious work; while I am very
+ knowledgeable about m4 -- having used it for for so many years --
+ getting even simple things done with it is awkward and difficult.
+ Worse yet, as I started to use Python more and more over the
+ years, the cataloging programs which scanned the m4 and built m4
+ databases were migrated to Python and made almost trivial, but
+ writing out huge awkward tables of m4 definitions simply to make
+ them accessible in other m4 scripts started to become almost
+ farcical -- especially when coupled with the difficulty in getting
+ simple things done in m4.</p>
+<p> It occurred to me what I really wanted was an all-Python solution.
+ But replacing what used to be the m4 files with standalone Python
+ programs would result in somewhat awkward programs normally
+ consisting mostly of unprocessed text punctuated by small portions
+ where variables and small amounts of code need to be substituted.
+ Thus the idea was a sort of inverse of a Python interpreter: a
+ program that normally would just pass text through unmolested, but
+ when it found a special signifier would execute Python code in a
+ normal environment. I looked at existing Python templating
+ systems, and didn't find anything that appealed to me -- I wanted
+ something where the desired markups were simple and unobtrusive.
+ After considering between choices of signifiers, I settled on <code>@</code>
+ and EmPy was born.</p>
+<p> As I developed the tool, I realized it could have general appeal,
+ even to those with widely varying problems to solve, provided the
+ core tool they needed was an interpreter that could embed Python
+ code inside templated text. As I continue to use the tool, I have
+ been adding features as unintrusively as possible as I see areas
+ that can be improved.</p>
+<p> A design goal of EmPy is that its feature set should work on
+ several levels; at each level, if the user does not wish or need
+ to use features from another level, they are under no obligation
+ to do so. If you have no need of diversions, for instance, you
+ are under no obligation to use them. If significators will not
+ help you organize a set of EmPy scripts globally, then you need
+ not use them. New features that are being added are whenever
+ possible transparently backward compatible; if you do not need
+ them, their introduction should not affect you in any way. The
+ use of unknown prefix sequences results in errors, guaranteeing
+ that they are reserved for future use.</p>
+<h3>Glossary</h3>
+<dl>
+<dt> <strong>control</strong></dt>
+<dd>A control markup, used to direct high-level control
+ flow within an EmPy session. Control markups are expressed with
+ the <code>@[...]</code> notation.</dd>
+<dt> <strong>diversion</strong></dt>
+<dd>A process by which output is deferred, and can be
+ recalled later on demand, multiple times if necessary.</dd>
+<dt> <strong>document</strong></dt>
+<dd>The abstraction of an EmPy document as used by a
+ processor.</dd>
+<dt> <strong>escape</strong></dt>
+<dd>A markup designed to expand to a single (usually
+ non-printable) character, similar to escape sequences in C or
+ other languages.</dd>
+<dt> <strong>expansion</strong></dt>
+<dd>The process of processing EmPy markups and
+ producing output.</dd>
+<dt> <strong>expression</strong></dt>
+<dd>An expression markup represents a Python
+ expression to be evaluated, and replaced with the <code>str</code> of its
+ value. Expression markups are expressed with the <code>@(...)</code>
+ notation.</dd>
+<dt> <strong>filter</strong></dt>
+<dd>A file-like object which can be chained to other
+ objects (primarily the final stream) and can buffer, alter, or
+ manipulate in any way the data sent. Filters can also be
+ chained together in arbitrary order.</dd>
+<dt> <strong>globals</strong></dt>
+<dd>The dictionary (or dictionary-like object) which
+ resides inside the interpreter and holds the currently-defined
+ variables.</dd>
+<dt> <strong>hook</strong></dt>
+<dd>A callable object that can be registered in a
+ dictionary, and which will be invoked before, during, or after
+ certain internal operations, identified by name with a string.</dd>
+<dt> <strong>interpreter</strong></dt>
+<dd>The application (or class instance) which
+ processes EmPy markup.</dd>
+<dt> <strong>markup</strong></dt>
+<dd>EmPy substitutions set off with a prefix and
+ appropriate delimeters.</dd>
+<dt> <strong>output</strong></dt>
+<dd>The final destination of the result of processing an
+ EmPy file.</dd>
+<dt> <strong>prefix</strong></dt>
+<dd>The ASCII character used to set off an expansions.
+ By default, <code>@</code>.</dd>
+<dt> <strong>processor</strong></dt>
+<dd>An extensible system which processes a group of
+ EmPy files, usually arranged in a filesystem, and scans them for
+ significators.</dd>
+<dt> <strong>pseudomodule</strong></dt>
+<dd>The module-like object named <code>empy</code> which is
+ exposed internally inside every EmPy system.</dd>
+<dt> <strong>shortcut</strong></dt>
+<dd>A special object which takes the place of an
+ instance of the <code>Filter</code> class, to represent a special form of
+ filter. These include 0 for a null filter, a callable (function
+ or lambda) to represent a callable filter, or a 256-character
+ string which represents a translation filter.</dd>
+<dt> <strong>significator</strong></dt>
+<dd>A special form of an assignment markup in EmPy
+ which can be easily parsed externally, primarily designed for
+ representing uniform assignment across a collection of files.
+ Significators are indicated with the <code>@%</code> markup.</dd>
+<dt> <strong>statement</strong></dt>
+<dd>A line of code that needs to be executed;
+ statements do not have return values. In EmPy, statements are
+ set off with <code>@{...}</code>.</dd>
+</dl>
+<h3>Acknowledgements</h3>
+<p> Questions, suggestions, bug reports, evangelism, and even
+ complaints from many people have helped make EmPy what it is
+ today. Some, but by no means all, of these people are (in
+ alphabetical order by surname):</p>
+
+<ul>
+<li><p>Biswapesh Chattopadhyay</p></li>
+<li><p>Beni Cherniavsky</p></li>
+<li><p>Dr. S. Candelaria de Ram</p></li>
+<li><p>Eric Eide</p></li>
+<li><p>Dinu Gherman</p></li>
+<li><p>Grzegorz Adam Hankiewicz</p></li>
+<li><p>Bohdan Kushnir</p></li>
+<li><p>Robert Kroeger</p></li>
+<li><p>Kouichi Takahashi</p></li>
+<li><p>Ville Vainio</p></li>
+
+</ul>
+<h3>Known issues and caveats</h3>
+
+<ul>
+<li><p>EmPy was primarily intended for static processing of documents,
+ rather than dynamic use, and hence speed of processing was not
+ the primary consideration in its design.</p></li>
+<li><p>EmPy is not threadsafe by default. This is because of the need
+ for EmPy to override the <code>sys.stdout</code> file with a proxy object
+ which can capture effects of <code>print</code> and other spooling to
+ stdout. This proxy can be suppressed with the -n option, which
+ will result in EmPy being unable to do anything meaningful with
+ this output, but will allow EmPy to be threadsafe.</p></li>
+<li><p>To function properly, EmPy must override <code>sys.stdout</code> with a
+ proxy file object, so that it can capture output of side effects
+ and support diversions for each interpreter instance. It is
+ important that code executed in an environment <em>not</em> rebind
+ <code>sys.stdout</code>, although it is perfectly legal to invoke it
+ explicitly (<em>e.g.</em>, <code>@sys.stdout.write("Hello world\n")</code>). If
+ one really needs to access the "true" stdout, then use
+ <code>sys.__stdout__</code> instead (which should also not be rebound).
+ EmPy uses the standard Python error handlers when exceptions are
+ raised in EmPy code, which print to <code>sys.stderr</code>.</p></li>
+<li><p>Due to Python's curious handling of the <code>print</code> statement --
+ particularly the form with a trailing comma to suppress the
+ final newline -- mixing statement expansions using prints inline
+ with unexpanded text will often result in surprising behavior,
+ such as extraneous (sometimes even deferred!) spaces. This is a
+ Python "feature," and occurs in non-EmPy applications as well;
+ for finer control over output formatting, use <code>sys.stdout.write</code>
+ or <code>empy.interpreter.write</code> directly.</p></li>
+<li><p>The <code>empy</code> "module" exposed through the EmPy interface (<em>e.g.</em>,
+ <code>@empy</code>) is an artificial module. It cannot be imported with
+ the <code>import</code> statement (and shouldn't -- it is an artifact of
+ the EmPy processing system and does not correspond to any
+ accessible .py file).</p></li>
+<li><p>For an EmPy statement expansion all alone on a line, <em>e.g.</em>,
+ <code>@{a = 1}</code>, note that this will expand to a blank line due to
+ the newline following the closing curly brace. To suppress this
+ blank line, use the symmetric convention <code>@{a = 1}@</code>.</p></li>
+<li><p>When using EmPy with make, note that partial output may be
+ created before an error occurs; this is a standard caveat when
+ using make. To avoid this, write to a temporary file and move
+ when complete, delete the file in case of an error, use the -b
+ option to fully buffer output (including the open), or (with GNU
+ make) define a <code>.DELETE_ON_ERROR</code> target.</p></li>
+<li><p><code>empy.identify</code> tracks the context of executed <em>EmPy</em> code, not
+ Python code. This means that blocks of code delimited with <code>@{</code>
+ and <code>}</code> will identify themselves as appearing on the line at
+ which the <code>}</code> appears, and that pure Python code executed via
+ the -D, -E and -F command line arguments will show up as all taking
+ place on line 1. If you're tracking errors and want more
+ information about the location of the errors from the Python
+ code, use the -r command line option, which will provide you
+ with the full Python traceback.</p></li>
+<li><p>The conditional form of expression expansion <code>@(...?...!...)</code>
+ allows the use of a colon instead of an exclamation point,
+ <em>e.g.</em>, <code>@(...?...:...)</code>. This behavior is supported for
+ backward compatibility, but is deprecated. Due to an oversight,
+ the colon was a poor choice since colons can appear legally in
+ expressions (<em>e.g.</em>, dictionary literals or lambda expressions).</p></li>
+<li><p>The '@<a href="#reftry">[try]</a>' construct only works with Python exceptions derived
+ from <code>Exception</code>. It is not able to catch string exceptions.</p></li>
+<li><p>The '@<a href="#reffor">[for]</a>' variable specification supports tuples for tuple
+ unpacking, even recursive tuples. However, it is limited in
+ that the names included may only be valid Python identifiers,
+ not arbitrary Python lvalues. Since the internal Python
+ mechanism is very rarely used for this purpose (<em>e.g.</em>, 'for (x,
+ l<a href="#ref0">[0]</a>, q.a) in sequence'), it is not thought to be a significant
+ limitation.</p></li>
+
+</ul>
+<h3>Wish list</h3>
+<p> Here are some random ideas for future revisions of EmPy. If any
+ of these are of particular interest to you, your input would be
+ appreciated.</p>
+
+<ul>
+<li><p>Some real-world examples should really be included for
+ demonstrating the power and expressiveness of EmPy first-hand.</p></li>
+<li><p>More extensive help (rather than a ridiculously long README),
+ probably inherently using the EmPy system itself for building to
+ HTML and other formats, thereby acting as a help facility and a
+ demonstration of the working system.</p></li>
+<li><p>A "trivial" mode, where all the EmPy system does is scan for
+ simple symbols to replace them with evaluations/executions,
+ rather than having to do the contextual scanning it does now.
+ This has the down side of being much less configurable and
+ powerful but the upside of being extremely efficient.</p></li>
+<li><p>A "debug" mode, where EmPy prints the contents of everything
+ it's about to evaluate (probably to stderr) before it does?</p></li>
+<li><p>The ability to funnel all code through a configurable <code>RExec</code>
+ for user-controlled security control. This would probably
+ involve abstracting the execution functionality outside of the
+ interpreter. [This suggestion is on hold until the
+ rexec/Bastion exploits are worked out.]</p></li>
+<li><p>Optimized handling of processing would be nice for the
+ possibility of an Apache module devoted to EmPy processing.</p></li>
+<li><p>An EmPy emacs mode.</p></li>
+<li><p>An optimization of offloading diversions to files when they
+ become truly huge. (This is made possible by the abstraction of
+ the <code>Diversion</code> class.)</p></li>
+<li><p>Support for mapping filters (specified by dictionaries).</p></li>
+<li><p>Support for some sort of batch processing, where several EmPy
+ files can be listed at once and all of them evaluated with the
+ same initial (presumably expensive) environment.
+ <code>empy.saveGlobals</code> and <code>empy.restoreGlobals</code> have been
+ introduced as a partial solution, but they need to be made more
+ robust.</p></li>
+<li><p>A more elaborate interactive mode, perhaps with a prompt and
+ readline support.</p></li>
+<li><p>A StructuredText and/or reStructuredText filter would be quite
+ useful, as would SGML/HTML/XML/XHTML, s-expression, Python,
+ etc. auto-indenter filters.</p></li>
+<li><p>An indexing filter, which can process text and pick out
+ predefined keywords and thereby setup links to them.</p></li>
+<li><p>The ability to rerun diverted material back through the
+ interpreter. (This can be done, awkwardly, by manually creating
+ a filter which itself contains an interpreter, but it might be
+ helpful if this was an all-in-one operation.)</p></li>
+<li><p>A caching system that stores off the compilations of repeated
+ evaluations and executions so that in a persistent environment
+ the same code does not have to be repeatedly evaluated/executed.
+ This would probably be a necessity in an Apache module-based
+ solution. Perhaps caching even to the point of generating pure
+ PyWM bytecode?</p></li>
+<li><p>An option to change the format of the standard EmPy errors in a
+ traceback.</p></li>
+<li><p>Support for some manner of implicitly processed /etc/empyrc
+ and/or ~/.empyrc file, and of course an option to inhibit its
+ processing. This can already be accomplished (and with greater
+ control) via use of EMPY_OPTIONS, though.</p></li>
+<li><p>More uniform handling of the preprocessing directives (-I, -D,
+ -E, -F, and -P), probably mapping directly to methods in the
+ <code>Interpreter</code> class.</p></li>
+<li><p>Support for integration with mod_python.</p></li>
+<li><p>In simple expressions, a <code>{...}</code> suffix has no meaning in Python
+ (<em>e.g.</em>, in Python, <code>@x(...)</code> is a call, <code>@x[...]</code> is
+ subscription, but <code>@x{...}</code> is illegal). This could be
+ exploited by having a <code>{...}</code> suffix in a simple expression
+ representing an encapsulation of an expanded string; <em>e.g.</em>,
+ <code>@bullet{There are @count people here}</code> would be equivalent to
+ <code>@bullet(empy.expand("There are @count people here",
+ locals()))}</code>.</p></li>
+<li><p>A tool to collect significator information from a hierarchy of
+ .em files and put them in a database form available for
+ individual scripts would be extremely useful -- this tool should
+ be extensible so that users can use it to, say, build ordered
+ hierarchies of their EmPy files by detecting contextual
+ information like application-specific links to other EmPy
+ documents.</p></li>
+<li><p>Extensions of the basic EmPy concepts to projects for other
+ interpreted languages, such as Java, Lua, Ruby, and/or Perl.</p></li>
+<li><p>Ignore <code>SystemExit</code> when doing error handling, letting the
+ exception progagate up? So far no one seems to worry about
+ this; deliberately exiting early in a template seems to be an
+ unlikely occurrence. (Furthermore, there are the <code>os.abort</code> and
+ <code>os._exit</code> facilities for terminating without exception
+ propagation.)</p></li>
+<li><p>A new markup which is the equivalent of <code>$...:...$</code> in source
+ control systems, where the left-hand portion represents a
+ keyword and the right-hand portion represents its value which is
+ substituted in by the EmPy system.</p></li>
+<li><p>The ability to obtain the filename (if relevant) and mode of the
+ primary output file.</p></li>
+<li><p>The ability to redirect multiple streams of output; not
+ diversions, but rather the ability to write to one file and then
+ another. Since output would be under the EmPy script's control,
+ this would imply a useful --no-output option, where by default
+ no output is written. This would also suggest the usefulness of
+ all the output file delegates (diversions, filters, abstract
+ files, etc.) passing unrecognized method calls all the way down
+ to underlying file object.</p></li>
+<li><p>In addition to the em.py script, an additional support library
+ (non-executable) should be included which includes ancillary
+ functionality for more advanced features, but which is not
+ necessary to use EmPy in its basic form as a standalone
+ executable. Such features would include things like
+ significator processing, metadata scanning, and advanced
+ prompting systems.</p></li>
+
+</ul>
+<h3>Release history</h3>
+
+<ul>
+<li><p>3.3.2; 2014 Jan 24. Additional fix for source compatibility
+ between 2.x and 3.0.</p></li>
+<li><p>3.3.1; 2014 Jan 22. Source compatibility for 2.x and 3.0;
+ 1.x and Jython compatibility dropped.
+<li><p>3.3; 2003 Oct 27. Custom markup '@<...>'; remove separate
+ pseudomodule instance for greater transparency; deprecate
+ <code>interpreter</code> attribute of pseudomodule; deprecate auxiliary
+ class name attributes associated with pseudomodule in
+ preparation for separate support library in 4.0; add
+ --no-callback-error and --no-bangpath-processing command line
+ options; add <code>atToken</code> hook.</p></li>
+<li><p>3.2; 2003 Oct 7. Reengineer hooks support to use hook
+ instances; add -v option; add --relative-path option; reversed
+ PEP 317 style; modify Unicode support to give less confusing
+ errors in the case of unknown encodings and error handlers;
+ relicensed under LGPL.</p></li>
+<li><p>3.1.1; 2003 Sep 20. Add literal <code>@"..."</code> markup; add
+ --pause-at-end command line option; fix improper globals
+ collision error via the <code>sys.stdout</code> proxy.</p></li>
+<li><p>3.1; 2003 Aug 8. Unicode support (Python 2.0 and above); add
+ Document and Processor helper classes for processing
+ significators; add --no-prefix option for suppressing all
+ markups.</p></li>
+<li><p>3.0.4; 2003 Aug 7. Implement somewhat more robust lvalue
+ parsing for '@<a href="#reffor">[for]</a>' construct (thanks to Beni Cherniavsky for
+ inspiration).</p></li>
+<li><p>3.0.3; 2003 Jul 9. Fix bug regarding recursive tuple unpacking
+ using '@<a href="#reffor">[for]</a>'; add <code>empy.saveGlobals</code>, <code>empy.restoreGlobals</code>,
+ and <code>empy.defined</code> functions.</p></li>
+<li><p>3.0.2; 2003 Jun 19. <code>@?</code> and <code>@!</code> markups for changing the
+ current context name and line, respectively; add <code>update</code> method
+ to interpreter; new and renamed context operations,
+ <code>empy.setContextName</code>, <code>empy.setContextLine</code>,
+ <code>empy.pushContext</code>, <code>empy.popContext</code>.</p></li>
+<li><p>3.0.1; 2003 Jun 9. Fix simple bug preventing command line
+ preprocessing directives (-I, -D, -E, -F, -P) from executing
+ properly; defensive PEP 317 compliance <a href="#defunct"><a href="#refdefunct">[defunct]</a></a>.</p></li>
+<li><p>3.0; 2003 Jun 1. Control markups with '@<a href="#ref...">[...]</a>'; remove
+ substitutions (use control markups instead); support
+ <code>@(...?...!...)</code> for conditional expressions in addition to the
+ now-deprecated <code>@(...?...:...)</code> variety; add acknowledgements
+ and glossary sections to documentation; rename buffering option
+ back to -b; add -m option and <code>EMPY_PSEUDO</code> environment variable
+ for changing the pseudomodule name; add -n option and
+ <code>EMPY_NO_OVERRIDE</code> environment variable for suppressing
+ <code>sys.stdout</code> proxy; rename main error class to 'Error'; add
+ standalone <code>expand</code> function; add --binary and --chunk-size
+ options; reengineer parsing system to use Tokens for easy
+ extensibility; safeguard curly braces in simple expressions
+ (meaningless in Python and thus likely a typographical error) by
+ making them a parse error; fix bug involving custom Interpreter
+ instances ignoring globals argument; distutils support.</p></li>
+<li><p>2.3; 2003 Feb 20. Proper and full support for concurrent and
+ recursive interpreters; protection from closing the true stdout
+ file object; detect edge cases of interpreter globals or
+ <code>sys.stdout</code> proxy collisions; add globals manipulation
+ functions <code>empy.getGlobals</code>, <code>empy.setGlobals</code>, and
+ <code>empy.updateGlobals</code> which properly preserve the <code>empy</code>
+ pseudomodule; separate usage info out into easily accessible
+ lists for easier presentation; have -h option show simple usage
+ and -H show extened usage; add <code>NullFile</code> utility class.</p></li>
+<li><p>2.2.6; 2003 Jan 30. Fix a bug in the <code>Filter.detach</code> method
+ (which would not normally be called anyway).</p></li>
+<li><p>2.2.5; 2003 Jan 9. Strip carriage returns out of executed code
+ blocks for DOS/Windows compatibility.</p></li>
+<li><p>2.2.4; 2002 Dec 23. Abstract Filter interface to use methods
+ only; add <code>@[noop: ...]</code> substitution for completeness and block
+ commenting <a href="#defunct"><a href="#refdefunct">[defunct]</a></a>.</p></li>
+<li><p>2.2.3; 2002 Dec 16. Support compatibility with Jython by
+ working around a minor difference between CPython and Jython in
+ string splitting.</p></li>
+<li><p>2.2.2; 2002 Dec 14. Include better docstrings for pseudomodule
+ functions; segue to a dictionary-based options system for
+ interpreters; add <code>empy.clearAllHooks</code> and 'empy.clearGlobals';
+ include a short documentation section on embedding interpreters;
+ fix a bug in significator regular expression.</p></li>
+<li><p>2.2.1; 2002 Nov 30. Tweak test script to avoid writing
+ unnecessary temporary file; add <code>Interpreter.single</code> method;
+ expose <code>evaluate</code>, <code>execute</code>, <code>substitute</code> <a href="#defunct"><a href="#refdefunct">[defunct]</a></a>, and
+ <code>single</code> methods to the pseudomodule; add (rather obvious)
+ <code>EMPY_OPTIONS</code> environment variable support; add
+ <code>empy.enableHooks</code> and 'empy.disableHooks'; include optimization
+ to transparently disable hooks until they are actually used.</p></li>
+<li><p>2.2; 2002 Nov 21. Switched to -V option for version
+ information; <code>empy.createDiversion</code> for creating initially empty
+ diversion; direct access to diversion objects with
+ 'empy.retrieveDiversion'; environment variable support; removed
+ --raw long argument (use --raw-errors instead); added quaternary
+ escape code (well, why not).</p></li>
+<li><p>2.1; 2002 Oct 18. <code>empy.atExit</code> registry separate from hooks to
+ allow for normal interpreter support; include a benchmark sample
+ and test.sh verification script; expose <code>empy.string</code> directly;
+ -D option for explicit defines on command line; remove
+ ill-conceived support for <code>@else:</code> separator in <code>@[if ...]</code>
+ substitution <a href="#defunct"><a href="#refdefunct">[defunct]</a></a> ; handle nested substitutions properly
+ <a href="#defunct"><a href="#refdefunct">[defunct]</a></a> ; <code>@[macro ...]</code> substitution for creating recallable
+ expansions <a href="#defunct"><a href="#refdefunct">[defunct]</a></a>.</p></li>
+<li><p>2.0.1; 2002 Oct 8. Fix missing usage information; fix
+ after_evaluate hook not getting called; add <code>empy.atExit</code> call
+ to register values.</p></li>
+<li><p>2.0; 2002 Sep 30. Parsing system completely revamped and
+ simplified, eliminating a whole class of context-related bugs;
+ builtin support for buffered filters; support for registering
+ hooks; support for command line arguments; interactive mode with
+ -i; significator value extended to be any valid Python
+ expression.</p></li>
+<li><p>1.5.1; 2002 Sep 24. Allow <code>@]</code> to represent unbalanced close
+ brackets in <code>@[...]</code> markups <a href="#defunct"><a href="#refdefunct">[defunct]</a></a>.</p></li>
+<li><p>1.5; 2002 Sep 18. Escape codes (<code>@\...</code>); conditional and
+ repeated expansion substitutions <a href="#defunct"><a href="#refdefunct">[defunct]</a></a> ; replaced with control
+ markups]; fix a few bugs involving files which do not end in
+ newlines.</p></li>
+<li><p>1.4; 2002 Sep 7. Fix bug with triple quotes; collapse
+ conditional and protected expression syntaxes into the single
+ generalized <code>@(...)</code> notation; <code>empy.setName</code> and <code>empy.setLine</code>
+ functions <a href="#deprecated"><a href="#refdeprecated">[deprecated]</a></a> ; true support for multiple concurrent
+ interpreters with improved sys.stdout proxy; proper support for
+ <code>empy.expand</code> to return a string evaluated in a subinterpreter
+ as intended; merged Context and Parser classes together, and
+ separated out Scanner functionality.</p></li>
+<li><p>1.3; 2002 Aug 24. Pseudomodule as true instance; move toward
+ more verbose (and clear) pseudomodule functions; fleshed out
+ diversion model; filters; conditional expressions; protected
+ expressions; preprocessing with -P (in preparation for
+ possible support for command line arguments).</p></li>
+<li><p>1.2; 2002 Aug 16. Treat bangpaths as comments; <code>empy.quote</code> for
+ the opposite process of 'empy.expand'; significators (<code>@%...</code>
+ sequences); -I option; -f option; much improved documentation.</p></li>
+<li><p>1.1.5; 2002 Aug 15. Add a separate <code>invoke</code> function that can be
+ called multiple times with arguments to simulate multiple runs.</p></li>
+<li><p>1.1.4; 2002 Aug 12. Handle strings thrown as exceptions
+ properly; use getopt to process command line arguments; cleanup
+ file buffering with AbstractFile; very slight documentation and
+ code cleanup.</p></li>
+<li><p>1.1.3; 2002 Aug 9. Support for changing the prefix from within
+ the <code>empy</code> pseudomodule.</p></li>
+<li><p>1.1.2; 2002 Aug 5. Renamed buffering option <a href="#defunct"><a href="#refdefunct">[defunct]</a></a>, added -F
+ option for interpreting Python files from the command line,
+ fixed improper handling of exceptions from command line options
+ (-E, -F).</p></li>
+<li><p>1.1.1; 2002 Aug 4. Typo bugfixes; documentation clarification.</p></li>
+<li><p>1.1; 2002 Aug 4. Added option for fully buffering output
+ (including file opens), executing commands through the command
+ line; some documentation errors fixed.</p></li>
+<li><p>1.0; 2002 Jul 23. Renamed project to EmPy. Documentation and
+ sample tweaks; added <code>empy.flatten</code>. Added -a option.</p></li>
+<li><p>0.3; 2002 Apr 14. Extended "simple expression" syntax,
+ interpreter abstraction, proper context handling, better error
+ handling, explicit file inclusion, extended samples.</p></li>
+<li><p>0.2; 2002 Apr 13. Bugfixes, support non-expansion of Nones,
+ allow choice of alternate prefix.</p></li>
+<li><p>0.1.1; 2002 Apr 12. Bugfixes, support for Python 1.5.x, add -r
+ option.</p></li>
+<li><p>0.1; 2002 Apr 12. Initial early access release.</p></li>
+
+</ul>
+<h3>Author</h3>
+<p> This module was written by <a href="http://www.alcyone.com/max/">Erik Max Francis</a>. If you use this software, have
+ suggestions for future releases, or bug reports, <a href="mailto:software@alcyone.com">I'd love to hear
+ about it</a>.</p>
+<p> Even if you try out EmPy for a project and find it unsuitable, I'd
+ like to know what stumbling blocks you ran into so they can
+ potentially be addressed in a future version.</p>
+<h3>Version</h3>
+<p> Version 3.3.2 $Date: 2004-01-25 $ $Author: max $</p>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+ <tr>
+ <th bgcolor="#99ccff"
+ rowspan="2"
+ valign="top"
+ align="left"
+ width="20%"
+ >
+ <font color="#000000">
+ <a name="Modules and Packages">Modules and Packages</a>
+ </font>
+ </th>
+ <th bgcolor="#99ccff"
+ valign="top"
+ align="left"
+ width="80%"
+ >
+ <font color="#000000"> </font>
+ </th>
+ </tr>
+ <tr>
+ <td>
+
+<table border="0" cellpadding="3" cellspacing="0">
+<tr><td valign="top" align="left"><p><a href="home/max/projects/empy/doc/em.html">em</a></p></td><td valign="top" align="left">
+<p>A system for processing Python as markup embedded in text.</p>
+</td></tr>
+</table>
+</td></tr>
+</table>
+
+ </td>
+ </tr>
+ </table>
+
+ <hr>
+
+ <p><i><a href="index.html">Table of Contents</a></i></p>
+
+ <font size="-2"><i>This document was automatically generated
+ on Wed Jan 22 00:00:00 2014 by
+ <a href="http://happydoc.sourceforge.net">HappyDoc</a> version
+ 2.1</i></font>
+
+ </body>
+ </html>
+
\ No newline at end of file
--- /dev/null
+#!/usr/bin/env python
+#
+# $Id: em.py 5364 2014-01-24 21:39:38Z max $ $Date: 2014-01-24 13:39:38 -0800 (Fri, 24 Jan 2014) $
+
+"""
+A system for processing Python as markup embedded in text.
+"""
+
+
+__program__ = 'empy'
+__version__ = '3.3.2'
+__url__ = 'http://www.alcyone.com/software/empy/'
+__author__ = 'Erik Max Francis <max@alcyone.com>'
+__copyright__ = 'Copyright (C) 2002-2014 Erik Max Francis'
+__license__ = 'LGPL'
+
+
+import copy
+import getopt
+import inspect
+import os
+import re
+import sys
+import types
+
+# 2.x/3.0 compatbility
+try:
+ from StringIO import StringIO
+except ImportError:
+ from io import StringIO
+
+try:
+ _unicode = unicode # bytes will be undefined in 3.x releases
+ _str = str
+ _unichr = unichr
+ _input = raw_input
+ def _exec(code, globals, locals=None):
+ if globals is None:
+ exec("""exec code""")
+ else:
+ if locals is None:
+ exec("""exec code in globals""")
+ else:
+ exec("""exec code in globals, locals""")
+except NameError:
+ _unicode = str
+ _str = bytes
+ _unichr = chr
+ _input = input
+ try:
+ _exec = __builtins__.__dict__['exec']
+ except AttributeError:
+ _exec = __builtins__['exec']
+
+# Some basic defaults.
+FAILURE_CODE = 1
+DEFAULT_PREFIX = '@'
+DEFAULT_PSEUDOMODULE_NAME = 'empy'
+DEFAULT_SCRIPT_NAME = '?'
+SIGNIFICATOR_RE_SUFFIX = r"%(\S+)\s*(.*)\s*$"
+SIGNIFICATOR_RE_STRING = DEFAULT_PREFIX + SIGNIFICATOR_RE_SUFFIX
+BANGPATH = '#!'
+DEFAULT_CHUNK_SIZE = 8192
+DEFAULT_ERRORS = 'strict'
+
+# Character information.
+IDENTIFIER_FIRST_CHARS = '_abcdefghijklmnopqrstuvwxyz' \
+ 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+IDENTIFIER_CHARS = IDENTIFIER_FIRST_CHARS + '0123456789.'
+ENDING_CHARS = {'(': ')', '[': ']', '{': '}'}
+
+# Environment variable names.
+OPTIONS_ENV = 'EMPY_OPTIONS'
+PREFIX_ENV = 'EMPY_PREFIX'
+PSEUDO_ENV = 'EMPY_PSEUDO'
+FLATTEN_ENV = 'EMPY_FLATTEN'
+RAW_ENV = 'EMPY_RAW_ERRORS'
+INTERACTIVE_ENV = 'EMPY_INTERACTIVE'
+BUFFERED_ENV = 'EMPY_BUFFERED_OUTPUT'
+NO_OVERRIDE_ENV = 'EMPY_NO_OVERRIDE'
+UNICODE_ENV = 'EMPY_UNICODE'
+INPUT_ENCODING_ENV = 'EMPY_UNICODE_INPUT_ENCODING'
+OUTPUT_ENCODING_ENV = 'EMPY_UNICODE_OUTPUT_ENCODING'
+INPUT_ERRORS_ENV = 'EMPY_UNICODE_INPUT_ERRORS'
+OUTPUT_ERRORS_ENV = 'EMPY_UNICODE_OUTPUT_ERRORS'
+
+# Interpreter options.
+BANGPATH_OPT = 'processBangpaths' # process bangpaths as comments?
+BUFFERED_OPT = 'bufferedOutput' # fully buffered output?
+RAW_OPT = 'rawErrors' # raw errors?
+EXIT_OPT = 'exitOnError' # exit on error?
+FLATTEN_OPT = 'flatten' # flatten pseudomodule namespace?
+OVERRIDE_OPT = 'override' # override sys.stdout with proxy?
+CALLBACK_OPT = 'noCallbackError' # is no custom callback an error?
+
+# Usage info.
+OPTION_INFO = [
+("-V --version", "Print version and exit"),
+("-h --help", "Print usage and exit"),
+("-H --extended-help", "Print extended usage and exit"),
+("-k --suppress-errors", "Do not exit on errors; go interactive"),
+("-p --prefix=<char>", "Change prefix to something other than @"),
+(" --no-prefix", "Do not do any markup processing at all"),
+("-m --module=<name>", "Change the internal pseudomodule name"),
+("-f --flatten", "Flatten the members of pseudmodule to start"),
+("-r --raw-errors", "Show raw Python errors"),
+("-i --interactive", "Go into interactive mode after processing"),
+("-n --no-override-stdout", "Do not override sys.stdout with proxy"),
+("-o --output=<filename>", "Specify file for output as write"),
+("-a --append=<filename>", "Specify file for output as append"),
+("-b --buffered-output", "Fully buffer output including open"),
+(" --binary", "Treat the file as a binary"),
+(" --chunk-size=<chunk>", "Use this chunk size for reading binaries"),
+("-P --preprocess=<filename>", "Interpret EmPy file before main processing"),
+("-I --import=<modules>", "Import Python modules before processing"),
+("-D --define=<definition>", "Execute Python assignment statement"),
+("-E --execute=<statement>", "Execute Python statement before processing"),
+("-F --execute-file=<filename>", "Execute Python file before processing"),
+(" --pause-at-end", "Prompt at the ending of processing"),
+(" --relative-path", "Add path of EmPy script to sys.path"),
+(" --no-callback-error", "Custom markup without callback is error"),
+(" --no-bangpath-processing", "Suppress bangpaths as comments"),
+("-u --unicode", "Enable Unicode subsystem (Python 2+ only)"),
+(" --unicode-encoding=<e>", "Set both input and output encodings"),
+(" --unicode-input-encoding=<e>", "Set input encoding"),
+(" --unicode-output-encoding=<e>", "Set output encoding"),
+(" --unicode-errors=<E>", "Set both input and output error handler"),
+(" --unicode-input-errors=<E>", "Set input error handler"),
+(" --unicode-output-errors=<E>", "Set output error handler"),
+]
+
+USAGE_NOTES = """\
+Notes: Whitespace immediately inside parentheses of @(...) are
+ignored. Whitespace immediately inside braces of @{...} are ignored,
+unless ... spans multiple lines. Use @{ ... }@ to suppress newline
+following expansion. Simple expressions ignore trailing dots; `@x.'
+means `@(x).'. A #! at the start of a file is treated as a @#
+comment."""
+
+MARKUP_INFO = [
+("@# ... NL", "Comment; remove everything up to newline"),
+("@? NAME NL", "Set the current context name"),
+("@! INTEGER NL", "Set the current context line number"),
+("@ WHITESPACE", "Remove following whitespace; line continuation"),
+("@\\ ESCAPE_CODE", "A C-style escape sequence"),
+("@@", "Literal @; @ is escaped (duplicated prefix)"),
+("@), @], @}", "Literal close parenthesis, bracket, brace"),
+("@ STRING_LITERAL", "Replace with string literal contents"),
+("@( EXPRESSION )", "Evaluate expression and substitute with str"),
+("@( TEST [? THEN [! ELSE]] )", "If test is true, evaluate then, otherwise else"),
+("@( TRY $ CATCH )", "Expand try expression, or catch if it raises"),
+("@ SIMPLE_EXPRESSION", "Evaluate simple expression and substitute;\n"
+ "e.g., @x, @x.y, @f(a, b), @l[i], etc."),
+("@` EXPRESSION `", "Evaluate expression and substitute with repr"),
+("@: EXPRESSION : [DUMMY] :", "Evaluates to @:...:expansion:"),
+("@{ STATEMENTS }", "Statements are executed for side effects"),
+("@[ CONTROL ]", "Control markups: if E; elif E; for N in E;\n"
+ "while E; try; except E, N; finally; continue;\n"
+ "break; end X"),
+("@%% KEY WHITESPACE VALUE NL", "Significator form of __KEY__ = VALUE"),
+("@< CONTENTS >", "Custom markup; meaning provided by user"),
+]
+
+ESCAPE_INFO = [
+("@\\0", "NUL, null"),
+("@\\a", "BEL, bell"),
+("@\\b", "BS, backspace"),
+("@\\dDDD", "three-digit decimal code DDD"),
+("@\\e", "ESC, escape"),
+("@\\f", "FF, form feed"),
+("@\\h", "DEL, delete"),
+("@\\n", "LF, linefeed, newline"),
+("@\\N{NAME}", "Unicode character named NAME"),
+("@\\oOOO", "three-digit octal code OOO"),
+("@\\qQQQQ", "four-digit quaternary code QQQQ"),
+("@\\r", "CR, carriage return"),
+("@\\s", "SP, space"),
+("@\\t", "HT, horizontal tab"),
+("@\\uHHHH", "16-bit hexadecimal Unicode HHHH"),
+("@\\UHHHHHHHH", "32-bit hexadecimal Unicode HHHHHHHH"),
+("@\\v", "VT, vertical tab"),
+("@\\xHH", "two-digit hexadecimal code HH"),
+("@\\z", "EOT, end of transmission"),
+]
+
+PSEUDOMODULE_INFO = [
+("VERSION", "String representing EmPy version"),
+("SIGNIFICATOR_RE_STRING", "Regular expression matching significators"),
+("SIGNIFICATOR_RE_SUFFIX", "The above stub, lacking the prefix"),
+("interpreter", "Currently-executing interpreter instance"),
+("argv", "The EmPy script name and command line arguments"),
+("args", "The command line arguments only"),
+("identify()", "Identify top context as name, line"),
+("setContextName(name)", "Set the name of the current context"),
+("setContextLine(line)", "Set the line number of the current context"),
+("atExit(callable)", "Invoke no-argument function at shutdown"),
+("getGlobals()", "Retrieve this interpreter's globals"),
+("setGlobals(dict)", "Set this interpreter's globals"),
+("updateGlobals(dict)", "Merge dictionary into interpreter's globals"),
+("clearGlobals()", "Start globals over anew"),
+("saveGlobals([deep])", "Save a copy of the globals"),
+("restoreGlobals([pop])", "Restore the most recently saved globals"),
+("defined(name, [loc])", "Find if the name is defined"),
+("evaluate(expression, [loc])", "Evaluate the expression"),
+("serialize(expression, [loc])", "Evaluate and serialize the expression"),
+("execute(statements, [loc])", "Execute the statements"),
+("single(source, [loc])", "Execute the 'single' object"),
+("atomic(name, value, [loc])", "Perform an atomic assignment"),
+("assign(name, value, [loc])", "Perform an arbitrary assignment"),
+("significate(key, [value])", "Significate the given key, value pair"),
+("include(file, [loc])", "Include filename or file-like object"),
+("expand(string, [loc])", "Explicitly expand string and return"),
+("string(data, [name], [loc])", "Process string-like object"),
+("quote(string)", "Quote prefixes in provided string and return"),
+("flatten([keys])", "Flatten module contents into globals namespace"),
+("getPrefix()", "Get current prefix"),
+("setPrefix(char)", "Set new prefix"),
+("stopDiverting()", "Stop diverting; data sent directly to output"),
+("createDiversion(name)", "Create a diversion but do not divert to it"),
+("retrieveDiversion(name)", "Retrieve the actual named diversion object"),
+("startDiversion(name)", "Start diverting to given diversion"),
+("playDiversion(name)", "Recall diversion and then eliminate it"),
+("replayDiversion(name)", "Recall diversion but retain it"),
+("purgeDiversion(name)", "Erase diversion"),
+("playAllDiversions()", "Stop diverting and play all diversions in order"),
+("replayAllDiversions()", "Stop diverting and replay all diversions"),
+("purgeAllDiversions()", "Stop diverting and purge all diversions"),
+("getFilter()", "Get current filter"),
+("resetFilter()", "Reset filter; no filtering"),
+("nullFilter()", "Install null filter"),
+("setFilter(shortcut)", "Install new filter or filter chain"),
+("attachFilter(shortcut)", "Attach single filter to end of current chain"),
+("areHooksEnabled()", "Return whether or not hooks are enabled"),
+("enableHooks()", "Enable hooks (default)"),
+("disableHooks()", "Disable hook invocation"),
+("getHooks()", "Get all the hooks"),
+("clearHooks()", "Clear all hooks"),
+("addHook(hook, [i])", "Register the hook (optionally insert)"),
+("removeHook(hook)", "Remove an already-registered hook from name"),
+("invokeHook(name_, ...)", "Manually invoke hook"),
+("getCallback()", "Get interpreter callback"),
+("registerCallback(callback)", "Register callback with interpreter"),
+("deregisterCallback()", "Deregister callback from interpreter"),
+("invokeCallback(contents)", "Invoke the callback directly"),
+("Interpreter", "The interpreter class"),
+]
+
+ENVIRONMENT_INFO = [
+(OPTIONS_ENV, "Specified options will be included"),
+(PREFIX_ENV, "Specify the default prefix: -p <value>"),
+(PSEUDO_ENV, "Specify name of pseudomodule: -m <value>"),
+(FLATTEN_ENV, "Flatten empy pseudomodule if defined: -f"),
+(RAW_ENV, "Show raw errors if defined: -r"),
+(INTERACTIVE_ENV, "Enter interactive mode if defined: -i"),
+(BUFFERED_ENV, "Fully buffered output if defined: -b"),
+(NO_OVERRIDE_ENV, "Do not override sys.stdout if defined: -n"),
+(UNICODE_ENV, "Enable Unicode subsystem: -n"),
+(INPUT_ENCODING_ENV, "Unicode input encoding"),
+(OUTPUT_ENCODING_ENV, "Unicode output encoding"),
+(INPUT_ERRORS_ENV, "Unicode input error handler"),
+(OUTPUT_ERRORS_ENV, "Unicode output error handler"),
+]
+
+class Error(Exception):
+ """The base class for all EmPy errors."""
+ pass
+
+EmpyError = EmPyError = Error # DEPRECATED
+
+class DiversionError(Error):
+ """An error related to diversions."""
+ pass
+
+class FilterError(Error):
+ """An error related to filters."""
+ pass
+
+class StackUnderflowError(Error):
+ """A stack underflow."""
+ pass
+
+class SubsystemError(Error):
+ """An error associated with the Unicode subsystem."""
+ pass
+
+class FlowError(Error):
+ """An exception related to control flow."""
+ pass
+
+class ContinueFlow(FlowError):
+ """A continue control flow."""
+ pass
+
+class BreakFlow(FlowError):
+ """A break control flow."""
+ pass
+
+class ParseError(Error):
+ """A parse error occurred."""
+ pass
+
+class TransientParseError(ParseError):
+ """A parse error occurred which may be resolved by feeding more data.
+ Such an error reaching the toplevel is an unexpected EOF error."""
+ pass
+
+
+class MetaError(Exception):
+
+ """A wrapper around a real Python exception for including a copy of
+ the context."""
+
+ def __init__(self, contexts, exc):
+ Exception.__init__(self, exc)
+ self.contexts = contexts
+ self.exc = exc
+
+ def __str__(self):
+ backtrace = [str(x) for x in self.contexts]
+ return "%s: %s (%s)" % (self.exc.__class__, self.exc,
+ (', '.join(backtrace)))
+
+
+class Subsystem:
+
+ """The subsystem class defers file creation so that it can create
+ Unicode-wrapped files if desired (and possible)."""
+
+ def __init__(self):
+ self.useUnicode = False
+ self.inputEncoding = None
+ self.outputEncoding = None
+ self.errors = None
+
+ def initialize(self, inputEncoding=None, outputEncoding=None,
+ inputErrors=None, outputErrors=None):
+ self.useUnicode = True
+ defaultEncoding = sys.getdefaultencoding()
+ if inputEncoding is None:
+ inputEncoding = defaultEncoding
+ self.inputEncoding = inputEncoding
+ if outputEncoding is None:
+ outputEncoding = defaultEncoding
+ self.outputEncoding = outputEncoding
+ if inputErrors is None:
+ inputErrors = DEFAULT_ERRORS
+ self.inputErrors = inputErrors
+ if outputErrors is None:
+ outputErrors = DEFAULT_ERRORS
+ self.outputErrors = outputErrors
+
+ def assertUnicode(self):
+ if not self.useUnicode:
+ raise SubsystemError("Unicode subsystem unavailable")
+
+ def open(self, name, mode=None):
+ if self.useUnicode:
+ return self.unicodeOpen(name, mode)
+ else:
+ return self.defaultOpen(name, mode)
+
+ def defaultOpen(self, name, mode=None):
+ if mode is None:
+ mode = 'r'
+ return open(name, mode)
+
+ def unicodeOpen(self, name, mode=None):
+ import codecs
+ if mode is None:
+ mode = 'rb'
+ if mode.find('w') >= 0 or mode.find('a') >= 0:
+ encoding = self.outputEncoding
+ errors = self.outputErrors
+ else:
+ encoding = self.inputEncoding
+ errors = self.inputErrors
+ return codecs.open(name, mode, encoding, errors)
+
+theSubsystem = Subsystem()
+
+
+class Stack:
+
+ """A simple stack that behaves as a sequence (with 0 being the top
+ of the stack, not the bottom)."""
+
+ def __init__(self, seq=None):
+ if seq is None:
+ seq = []
+ self.data = seq
+
+ def top(self):
+ """Access the top element on the stack."""
+ try:
+ return self.data[-1]
+ except IndexError:
+ raise StackUnderflowError("stack is empty for top")
+
+ def pop(self):
+ """Pop the top element off the stack and return it."""
+ try:
+ return self.data.pop()
+ except IndexError:
+ raise StackUnderflowError("stack is empty for pop")
+
+ def push(self, object):
+ """Push an element onto the top of the stack."""
+ self.data.append(object)
+
+ def filter(self, function):
+ """Filter the elements of the stack through the function."""
+ self.data = list(filter(function, self.data))
+
+ def purge(self):
+ """Purge the stack."""
+ self.data = []
+
+ def clone(self):
+ """Create a duplicate of this stack."""
+ return self.__class__(self.data[:])
+
+ def __nonzero__(self): return len(self.data) != 0 # 2.x
+ def __bool__(self): return len(self.data) != 0 # 3.x
+ def __len__(self): return len(self.data)
+ def __getitem__(self, index): return self.data[-(index + 1)]
+
+ def __repr__(self):
+ return ('<%s instance at 0x%x [%s]>' %
+ (self.__class__, id(self),
+ ', '.join(repr(x) for x in self.data)))
+
+
+class AbstractFile:
+
+ """An abstracted file that, when buffered, will totally buffer the
+ file, including even the file open."""
+
+ def __init__(self, filename, mode='w', buffered=False):
+ # The calls below might throw, so start off by marking this
+ # file as "done." This way destruction of a not-completely-
+ # initialized AbstractFile will generate no further errors.
+ self.done = True
+ self.filename = filename
+ self.mode = mode
+ self.buffered = buffered
+ if buffered:
+ self.bufferFile = StringIO()
+ else:
+ self.bufferFile = theSubsystem.open(filename, mode)
+ # Okay, we got this far, so the AbstractFile is initialized.
+ # Flag it as "not done."
+ self.done = False
+
+ def __del__(self):
+ self.close()
+
+ def write(self, data):
+ self.bufferFile.write(data)
+
+ def writelines(self, data):
+ self.bufferFile.writelines(data)
+
+ def flush(self):
+ self.bufferFile.flush()
+
+ def close(self):
+ if not self.done:
+ self.commit()
+ self.done = True
+
+ def commit(self):
+ if self.buffered:
+ file = theSubsystem.open(self.filename, self.mode)
+ file.write(self.bufferFile.getvalue())
+ file.close()
+ else:
+ self.bufferFile.close()
+
+ def abort(self):
+ if self.buffered:
+ self.bufferFile = None
+ else:
+ self.bufferFile.close()
+ self.bufferFile = None
+ self.done = True
+
+
+class Diversion:
+
+ """The representation of an active diversion. Diversions act as
+ (writable) file objects, and then can be recalled either as pure
+ strings or (readable) file objects."""
+
+ def __init__(self):
+ self.file = StringIO()
+
+ # These methods define the writable file-like interface for the
+ # diversion.
+
+ def write(self, data):
+ self.file.write(data)
+
+ def writelines(self, lines):
+ for line in lines:
+ self.write(line)
+
+ def flush(self):
+ self.file.flush()
+
+ def close(self):
+ self.file.close()
+
+ # These methods are specific to diversions.
+
+ def asString(self):
+ """Return the diversion as a string."""
+ return self.file.getvalue()
+
+ def asFile(self):
+ """Return the diversion as a file."""
+ return StringIO(self.file.getvalue())
+
+
+class Stream:
+
+ """A wrapper around an (output) file object which supports
+ diversions and filtering."""
+
+ def __init__(self, file):
+ self.file = file
+ self.currentDiversion = None
+ self.diversions = {}
+ self.filter = file
+ self.done = False
+
+ def write(self, data):
+ if self.currentDiversion is None:
+ self.filter.write(data)
+ else:
+ self.diversions[self.currentDiversion].write(data)
+
+ def writelines(self, lines):
+ for line in lines:
+ self.write(line)
+
+ def flush(self):
+ self.filter.flush()
+
+ def close(self):
+ if not self.done:
+ self.undivertAll(True)
+ self.filter.close()
+ self.done = True
+
+ def shortcut(self, shortcut):
+ """Take a filter shortcut and translate it into a filter, returning
+ it. Sequences don't count here; these should be detected
+ independently."""
+ if shortcut == 0:
+ return NullFilter()
+ elif (isinstance(shortcut, types.FunctionType) or
+ inspect.ismethoddescriptor(shortcut) or
+ isinstance(shortcut, types.BuiltinFunctionType) or
+ isinstance(shortcut, types.BuiltinMethodType) or
+ isinstance(shortcut, types.LambdaType)):
+ return FunctionFilter(shortcut)
+ elif isinstance(shortcut, _str) or isinstance(shortcut, _unicode):
+ return StringFilter(filter)
+ elif isinstance(shortcut, dict):
+ raise NotImplementedError("mapping filters not yet supported")
+ else:
+ # Presume it's a plain old filter.
+ return shortcut
+
+ def last(self):
+ """Find the last filter in the current filter chain, or None if
+ there are no filters installed."""
+ if self.filter is None:
+ return None
+ thisFilter, lastFilter = self.filter, None
+ while thisFilter is not None and thisFilter is not self.file:
+ lastFilter = thisFilter
+ thisFilter = thisFilter.next()
+ return lastFilter
+
+ def install(self, shortcut=None):
+ """Install a new filter; None means no filter. Handle all the
+ special shortcuts for filters here."""
+ # Before starting, execute a flush.
+ self.filter.flush()
+ if shortcut is None or shortcut == [] or shortcut == ():
+ # Shortcuts for "no filter."
+ self.filter = self.file
+ else:
+ if isinstance(shortcut, list) or isinstance(shortcut, tuple):
+ shortcuts = list(shortcut)
+ else:
+ shortcuts = [shortcut]
+ # Run through the shortcut filter names, replacing them with
+ # full-fledged instances of Filter.
+ filters = []
+ for shortcut in shortcuts:
+ filters.append(self.shortcut(shortcut))
+ if len(filters) > 1:
+ # If there's more than one filter provided, chain them
+ # together.
+ lastFilter = None
+ for filter in filters:
+ if lastFilter is not None:
+ lastFilter.attach(filter)
+ lastFilter = filter
+ lastFilter.attach(self.file)
+ self.filter = filters[0]
+ else:
+ # If there's only one filter, assume that it's alone or it's
+ # part of a chain that has already been manually chained;
+ # just find the end.
+ filter = filters[0]
+ lastFilter = filter.last()
+ lastFilter.attach(self.file)
+ self.filter = filter
+
+ def attach(self, shortcut):
+ """Attached a solitary filter (no sequences allowed here) at the
+ end of the current filter chain."""
+ lastFilter = self.last()
+ if lastFilter is None:
+ # Just install it from scratch if there is no active filter.
+ self.install(shortcut)
+ else:
+ # Attach the last filter to this one, and this one to the file.
+ filter = self.shortcut(shortcut)
+ lastFilter.attach(filter)
+ filter.attach(self.file)
+
+ def revert(self):
+ """Reset any current diversions."""
+ self.currentDiversion = None
+
+ def create(self, name):
+ """Create a diversion if one does not already exist, but do not
+ divert to it yet."""
+ if name is None:
+ raise DiversionError("diversion name must be non-None")
+ if name not in self.diversions:
+ self.diversions[name] = Diversion()
+
+ def retrieve(self, name):
+ """Retrieve the given diversion."""
+ if name is None:
+ raise DiversionError("diversion name must be non-None")
+ if name in self.diversions:
+ return self.diversions[name]
+ else:
+ raise DiversionError("nonexistent diversion: %s" % name)
+
+ def divert(self, name):
+ """Start diverting."""
+ if name is None:
+ raise DiversionError("diversion name must be non-None")
+ self.create(name)
+ self.currentDiversion = name
+
+ def undivert(self, name, purgeAfterwards=False):
+ """Undivert a particular diversion."""
+ if name is None:
+ raise DiversionError("diversion name must be non-None")
+ if name in self.diversions:
+ diversion = self.diversions[name]
+ self.filter.write(diversion.asString())
+ if purgeAfterwards:
+ self.purge(name)
+ else:
+ raise DiversionError("nonexistent diversion: %s" % name)
+
+ def purge(self, name):
+ """Purge the specified diversion."""
+ if name is None:
+ raise DiversionError("diversion name must be non-None")
+ if name in self.diversions:
+ del self.diversions[name]
+ if self.currentDiversion == name:
+ self.currentDiversion = None
+
+ def undivertAll(self, purgeAfterwards=True):
+ """Undivert all pending diversions."""
+ if self.diversions:
+ self.revert() # revert before undiverting!
+ names = sorted(self.diversions.keys())
+ for name in names:
+ self.undivert(name)
+ if purgeAfterwards:
+ self.purge(name)
+
+ def purgeAll(self):
+ """Eliminate all existing diversions."""
+ if self.diversions:
+ self.diversions = {}
+ self.currentDiversion = None
+
+
+class NullFile:
+
+ """A simple class that supports all the file-like object methods
+ but simply does nothing at all."""
+
+ def __init__(self): pass
+ def write(self, data): pass
+ def writelines(self, lines): pass
+ def flush(self): pass
+ def close(self): pass
+
+
+class UncloseableFile:
+
+ """A simple class which wraps around a delegate file-like object
+ and lets everything through except close calls."""
+
+ def __init__(self, delegate):
+ self.delegate = delegate
+
+ def write(self, data):
+ self.delegate.write(data)
+
+ def writelines(self, lines):
+ self.delegate.writelines(data)
+
+ def flush(self):
+ self.delegate.flush()
+
+ def close(self):
+ """Eat this one."""
+ pass
+
+
+class ProxyFile:
+
+ """The proxy file object that is intended to take the place of
+ sys.stdout. The proxy can manage a stack of file objects it is
+ writing to, and an underlying raw file object."""
+
+ def __init__(self, bottom):
+ self.stack = Stack()
+ self.bottom = bottom
+
+ def current(self):
+ """Get the current stream to write to."""
+ if self.stack:
+ return self.stack[-1][1]
+ else:
+ return self.bottom
+
+ def push(self, interpreter):
+ self.stack.push((interpreter, interpreter.stream()))
+
+ def pop(self, interpreter):
+ result = self.stack.pop()
+ assert interpreter is result[0]
+
+ def clear(self, interpreter):
+ self.stack.filter(lambda x, i=interpreter: x[0] is not i)
+
+ def write(self, data):
+ self.current().write(data)
+
+ def writelines(self, lines):
+ self.current().writelines(lines)
+
+ def flush(self):
+ self.current().flush()
+
+ def close(self):
+ """Close the current file. If the current file is the bottom, then
+ close it and dispose of it."""
+ current = self.current()
+ if current is self.bottom:
+ self.bottom = None
+ current.close()
+
+ def _testProxy(self): pass
+
+
+class Filter:
+
+ """An abstract filter."""
+
+ def __init__(self):
+ if self.__class__ is Filter:
+ raise NotImplementedError
+ self.sink = None
+
+ def next(self):
+ """Return the next filter/file-like object in the sequence, or None."""
+ return self.sink
+
+ def __next__(self): return self.next()
+
+ def write(self, data):
+ """The standard write method; this must be overridden in subclasses."""
+ raise NotImplementedError
+
+ def writelines(self, lines):
+ """Standard writelines wrapper."""
+ for line in lines:
+ self.write(line)
+
+ def _flush(self):
+ """The _flush method should always flush the sink and should not
+ be overridden."""
+ self.sink.flush()
+
+ def flush(self):
+ """The flush method can be overridden."""
+ self._flush()
+
+ def close(self):
+ """Close the filter. Do an explicit flush first, then close the
+ sink."""
+ self.flush()
+ self.sink.close()
+
+ def attach(self, filter):
+ """Attach a filter to this one."""
+ if self.sink is not None:
+ # If it's already attached, detach it first.
+ self.detach()
+ self.sink = filter
+
+ def detach(self):
+ """Detach a filter from its sink."""
+ self.flush()
+ self._flush() # do a guaranteed flush to just to be safe
+ self.sink = None
+
+ def last(self):
+ """Find the last filter in this chain."""
+ this, last = self, self
+ while this is not None:
+ last = this
+ this = this.next()
+ return last
+
+class NullFilter(Filter):
+
+ """A filter that never sends any output to its sink."""
+
+ def write(self, data): pass
+
+class FunctionFilter(Filter):
+
+ """A filter that works simply by pumping its input through a
+ function which maps strings into strings."""
+
+ def __init__(self, function):
+ Filter.__init__(self)
+ self.function = function
+
+ def write(self, data):
+ self.sink.write(self.function(data))
+
+class StringFilter(Filter):
+
+ """A filter that takes a translation string (256 characters) and
+ filters any incoming data through it."""
+
+ def __init__(self, table):
+ if not ((isinstance(table, _str) or isinstance(table, _unicode))
+ and len(table) == 256):
+ raise FilterError("table must be 256-character string")
+ Filter.__init__(self)
+ self.table = table
+
+ def write(self, data):
+ self.sink.write(data.translate(self.table))
+
+class BufferedFilter(Filter):
+
+ """A buffered filter is one that doesn't modify the source data
+ sent to the sink, but instead holds it for a time. The standard
+ variety only sends the data along when it receives a flush
+ command."""
+
+ def __init__(self):
+ Filter.__init__(self)
+ self.buffer = ''
+
+ def write(self, data):
+ self.buffer += data
+
+ def flush(self):
+ if self.buffer:
+ self.sink.write(self.buffer)
+ self._flush()
+
+class SizeBufferedFilter(BufferedFilter):
+
+ """A size-buffered filter only in fixed size chunks (excepting the
+ final chunk)."""
+
+ def __init__(self, bufferSize):
+ BufferedFilter.__init__(self)
+ self.bufferSize = bufferSize
+
+ def write(self, data):
+ BufferedFilter.write(self, data)
+ while len(self.buffer) > self.bufferSize:
+ chunk, self.buffer = self.buffer[:self.bufferSize], self.buffer[self.bufferSize:]
+ self.sink.write(chunk)
+
+class LineBufferedFilter(BufferedFilter):
+
+ """A line-buffered filter only lets data through when it sees
+ whole lines."""
+
+ def __init__(self):
+ BufferedFilter.__init__(self)
+
+ def write(self, data):
+ BufferedFilter.write(self, data)
+ chunks = self.buffer.split('\n')
+ for chunk in chunks[:-1]:
+ self.sink.write(chunk + '\n')
+ self.buffer = chunks[-1]
+
+class MaximallyBufferedFilter(BufferedFilter):
+
+ """A maximally-buffered filter only lets its data through on the final
+ close. It ignores flushes."""
+
+ def __init__(self):
+ BufferedFilter.__init__(self)
+
+ def flush(self): pass
+
+ def close(self):
+ if self.buffer:
+ BufferedFilter.flush(self)
+ self.sink.close()
+
+
+class Context:
+
+ """An interpreter context, which encapsulates a name, an input
+ file object, and a parser object."""
+
+ DEFAULT_UNIT = 'lines'
+
+ def __init__(self, name, line=0, units=DEFAULT_UNIT):
+ self.name = name
+ self.line = line
+ self.units = units
+ self.pause = False
+
+ def bump(self, quantity=1):
+ if self.pause:
+ self.pause = False
+ else:
+ self.line += quantity
+
+ def identify(self):
+ return self.name, self.line
+
+ def __str__(self):
+ if self.units == self.DEFAULT_UNIT:
+ return "%s:%s" % (self.name, self.line)
+ else:
+ return "%s:%s[%s]" % (self.name, self.line, self.units)
+
+
+class Hook:
+
+ """The base class for implementing hooks."""
+
+ def __init__(self):
+ self.interpreter = None
+
+ def register(self, interpreter):
+ self.interpreter = interpreter
+
+ def deregister(self, interpreter):
+ if interpreter is not self.interpreter:
+ raise Error("hook not associated with this interpreter")
+ self.interpreter = None
+
+ def push(self):
+ self.interpreter.push()
+
+ def pop(self):
+ self.interpreter.pop()
+
+ def null(self): pass
+
+ def atStartup(self): pass
+ def atReady(self): pass
+ def atFinalize(self): pass
+ def atShutdown(self): pass
+ def atParse(self, scanner, locals): pass
+ def atToken(self, token): pass
+ def atHandle(self, meta): pass
+ def atInteract(self): pass
+
+ def beforeInclude(self, name, file, locals): pass
+ def afterInclude(self): pass
+
+ def beforeExpand(self, string, locals): pass
+ def afterExpand(self, result): pass
+
+ def beforeFile(self, name, file, locals): pass
+ def afterFile(self): pass
+
+ def beforeBinary(self, name, file, chunkSize, locals): pass
+ def afterBinary(self): pass
+
+ def beforeString(self, name, string, locals): pass
+ def afterString(self): pass
+
+ def beforeQuote(self, string): pass
+ def afterQuote(self, result): pass
+
+ def beforeEscape(self, string, more): pass
+ def afterEscape(self, result): pass
+
+ def beforeControl(self, type, rest, locals): pass
+ def afterControl(self): pass
+
+ def beforeSignificate(self, key, value, locals): pass
+ def afterSignificate(self): pass
+
+ def beforeAtomic(self, name, value, locals): pass
+ def afterAtomic(self): pass
+
+ def beforeMulti(self, name, values, locals): pass
+ def afterMulti(self): pass
+
+ def beforeImport(self, name, locals): pass
+ def afterImport(self): pass
+
+ def beforeClause(self, catch, locals): pass
+ def afterClause(self, exception, variable): pass
+
+ def beforeSerialize(self, expression, locals): pass
+ def afterSerialize(self): pass
+
+ def beforeDefined(self, name, locals): pass
+ def afterDefined(self, result): pass
+
+ def beforeLiteral(self, text): pass
+ def afterLiteral(self): pass
+
+ def beforeEvaluate(self, expression, locals): pass
+ def afterEvaluate(self, result): pass
+
+ def beforeExecute(self, statements, locals): pass
+ def afterExecute(self): pass
+
+ def beforeSingle(self, source, locals): pass
+ def afterSingle(self): pass
+
+class VerboseHook(Hook):
+
+ """A verbose hook that reports all information received by the
+ hook interface. This class dynamically scans the Hook base class
+ to ensure that all hook methods are properly represented."""
+
+ EXEMPT_ATTRIBUTES = ['register', 'deregister', 'push', 'pop']
+
+ def __init__(self, output=sys.stderr):
+ Hook.__init__(self)
+ self.output = output
+ self.indent = 0
+
+ class FakeMethod:
+ """This is a proxy method-like object."""
+ def __init__(self, hook, name):
+ self.hook = hook
+ self.name = name
+
+ def __call__(self, **keywords):
+ self.hook.output.write("%s%s: %s\n" %
+ (' ' * self.hook.indent,
+ self.name, repr(keywords)))
+
+ for attribute in dir(Hook):
+ if (attribute[:1] != '_' and
+ attribute not in self.EXEMPT_ATTRIBUTES):
+ self.__dict__[attribute] = FakeMethod(self, attribute)
+
+
+class Token:
+
+ """An element of expansion."""
+
+ def run(self, interpreter, locals):
+ raise NotImplementedError
+
+ def string(self):
+ raise NotImplementedError
+
+ def __str__(self): return self.string()
+
+class NullToken(Token):
+ """A chunk of data not containing markups."""
+ def __init__(self, data):
+ self.data = data
+
+ def run(self, interpreter, locals):
+ interpreter.write(self.data)
+
+ def string(self):
+ return self.data
+
+class ExpansionToken(Token):
+ """A token that involves an expansion."""
+ def __init__(self, prefix, first):
+ self.prefix = prefix
+ self.first = first
+
+ def scan(self, scanner):
+ pass
+
+ def run(self, interpreter, locals):
+ pass
+
+class WhitespaceToken(ExpansionToken):
+ """A whitespace markup."""
+ def string(self):
+ return '%s%s' % (self.prefix, self.first)
+
+class LiteralToken(ExpansionToken):
+ """A literal markup."""
+ def run(self, interpreter, locals):
+ interpreter.write(self.first)
+
+ def string(self):
+ return '%s%s' % (self.prefix, self.first)
+
+class PrefixToken(ExpansionToken):
+ """A prefix markup."""
+ def run(self, interpreter, locals):
+ interpreter.write(interpreter.prefix)
+
+ def string(self):
+ return self.prefix * 2
+
+class CommentToken(ExpansionToken):
+ """A comment markup."""
+ def scan(self, scanner):
+ loc = scanner.find('\n')
+ if loc >= 0:
+ self.comment = scanner.chop(loc, 1)
+ else:
+ raise TransientParseError("comment expects newline")
+
+ def string(self):
+ return '%s#%s\n' % (self.prefix, self.comment)
+
+class ContextNameToken(ExpansionToken):
+ """A context name change markup."""
+ def scan(self, scanner):
+ loc = scanner.find('\n')
+ if loc >= 0:
+ self.name = scanner.chop(loc, 1).strip()
+ else:
+ raise TransientParseError("context name expects newline")
+
+ def run(self, interpreter, locals):
+ context = interpreter.context()
+ context.name = self.name
+
+class ContextLineToken(ExpansionToken):
+ """A context line change markup."""
+ def scan(self, scanner):
+ loc = scanner.find('\n')
+ if loc >= 0:
+ try:
+ self.line = int(scanner.chop(loc, 1))
+ except ValueError:
+ raise ParseError("context line requires integer")
+ else:
+ raise TransientParseError("context line expects newline")
+
+ def run(self, interpreter, locals):
+ context = interpreter.context()
+ context.line = self.line
+ context.pause = True
+
+class EscapeToken(ExpansionToken):
+ """An escape markup."""
+ def scan(self, scanner):
+ try:
+ code = scanner.chop(1)
+ result = None
+ if code in '()[]{}\'\"\\': # literals
+ result = code
+ elif code == '0': # NUL
+ result = '\x00'
+ elif code == 'a': # BEL
+ result = '\x07'
+ elif code == 'b': # BS
+ result = '\x08'
+ elif code == 'd': # decimal code
+ decimalCode = scanner.chop(3)
+ result = chr(int(decimalCode, 10))
+ elif code == 'e': # ESC
+ result = '\x1b'
+ elif code == 'f': # FF
+ result = '\x0c'
+ elif code == 'h': # DEL
+ result = '\x7f'
+ elif code == 'n': # LF (newline)
+ result = '\x0a'
+ elif code == 'N': # Unicode character name
+ theSubsystem.assertUnicode()
+ import unicodedata
+ if scanner.chop(1) != '{':
+ raise ParseError("Unicode name escape should be \\N{...}")
+ i = scanner.find('}')
+ name = scanner.chop(i, 1)
+ try:
+ result = unicodedata.lookup(name)
+ except KeyError:
+ raise SubsystemError("unknown Unicode character name: %s" % name)
+ elif code == 'o': # octal code
+ octalCode = scanner.chop(3)
+ result = chr(int(octalCode, 8))
+ elif code == 'q': # quaternary code
+ quaternaryCode = scanner.chop(4)
+ result = chr(int(quaternaryCode, 4))
+ elif code == 'r': # CR
+ result = '\x0d'
+ elif code in 's ': # SP
+ result = ' '
+ elif code == 't': # HT
+ result = '\x09'
+ elif code in 'u': # Unicode 16-bit hex literal
+ theSubsystem.assertUnicode()
+ hexCode = scanner.chop(4)
+ result = _unichr(int(hexCode, 16))
+ elif code in 'U': # Unicode 32-bit hex literal
+ theSubsystem.assertUnicode()
+ hexCode = scanner.chop(8)
+ result = _unichr(int(hexCode, 16))
+ elif code == 'v': # VT
+ result = '\x0b'
+ elif code == 'x': # hexadecimal code
+ hexCode = scanner.chop(2)
+ result = chr(int(hexCode, 16))
+ elif code == 'z': # EOT
+ result = '\x04'
+ elif code == '^': # control character
+ controlCode = scanner.chop(1).upper()
+ if controlCode >= '@' and controlCode <= '`':
+ result = chr(ord(controlCode) - ord('@'))
+ elif controlCode == '?':
+ result = '\x7f'
+ else:
+ raise ParseError("invalid escape control code")
+ else:
+ raise ParseError("unrecognized escape code")
+ assert result is not None
+ self.code = result
+ except ValueError:
+ raise ParseError("invalid numeric escape code")
+
+ def run(self, interpreter, locals):
+ interpreter.write(self.code)
+
+ def string(self):
+ return '%s\\x%02x' % (self.prefix, ord(self.code))
+
+class SignificatorToken(ExpansionToken):
+ """A significator markup."""
+ def scan(self, scanner):
+ loc = scanner.find('\n')
+ if loc >= 0:
+ line = scanner.chop(loc, 1)
+ if not line:
+ raise ParseError("significator must have nonblank key")
+ if line[0] in ' \t\v\n':
+ raise ParseError("no whitespace between % and key")
+ # Work around a subtle CPython-Jython difference by stripping
+ # the string before splitting it: 'a '.split(None, 1) has two
+ # elements in Jython 2.1).
+ fields = line.strip().split(None, 1)
+ if len(fields) == 2 and fields[1] == '':
+ fields.pop()
+ self.key = fields[0]
+ if len(fields) < 2:
+ fields.append(None)
+ self.key, self.valueCode = fields
+ else:
+ raise TransientParseError("significator expects newline")
+
+ def run(self, interpreter, locals):
+ value = self.valueCode
+ if value is not None:
+ value = interpreter.evaluate(value.strip(), locals)
+ interpreter.significate(self.key, value)
+
+ def string(self):
+ if self.valueCode is None:
+ return '%s%%%s\n' % (self.prefix, self.key)
+ else:
+ return '%s%%%s %s\n' % (self.prefix, self.key, self.valueCode)
+
+class ExpressionToken(ExpansionToken):
+ """An expression markup."""
+ def scan(self, scanner):
+ z = scanner.complex('(', ')', 0)
+ try:
+ q = scanner.next('$', 0, z, True)
+ except ParseError:
+ q = z
+ try:
+ i = scanner.next('?', 0, q, True)
+ try:
+ j = scanner.next('!', i, q, True)
+ except ParseError:
+ try:
+ j = scanner.next(':', i, q, True) # DEPRECATED
+ except ParseError:
+ j = q
+ except ParseError:
+ i = j = q
+ code = scanner.chop(z, 1)
+ self.testCode = code[:i]
+ self.thenCode = code[i + 1:j]
+ self.elseCode = code[j + 1:q]
+ self.exceptCode = code[q + 1:z]
+
+ def run(self, interpreter, locals):
+ try:
+ result = interpreter.evaluate(self.testCode, locals)
+ if self.thenCode:
+ if result:
+ result = interpreter.evaluate(self.thenCode, locals)
+ else:
+ if self.elseCode:
+ result = interpreter.evaluate(self.elseCode, locals)
+ else:
+ result = None
+ except SyntaxError:
+ # Don't catch syntax errors; let them through.
+ raise
+ except:
+ if self.exceptCode:
+ result = interpreter.evaluate(self.exceptCode, locals)
+ else:
+ raise
+ if result is not None:
+ interpreter.write(str(result))
+
+ def string(self):
+ result = self.testCode
+ if self.thenCode:
+ result += '?' + self.thenCode
+ if self.elseCode:
+ result += '!' + self.elseCode
+ if self.exceptCode:
+ result += '$' + self.exceptCode
+ return '%s(%s)' % (self.prefix, result)
+
+class StringLiteralToken(ExpansionToken):
+ """A string token markup."""
+ def scan(self, scanner):
+ scanner.retreat()
+ assert scanner[0] == self.first
+ i = scanner.quote()
+ self.literal = scanner.chop(i)
+
+ def run(self, interpreter, locals):
+ interpreter.literal(self.literal)
+
+ def string(self):
+ return '%s%s' % (self.prefix, self.literal)
+
+class SimpleExpressionToken(ExpansionToken):
+ """A simple expression markup."""
+ def scan(self, scanner):
+ i = scanner.simple()
+ self.code = self.first + scanner.chop(i)
+
+ def run(self, interpreter, locals):
+ interpreter.serialize(self.code, locals)
+
+ def string(self):
+ return '%s%s' % (self.prefix, self.code)
+
+class ReprToken(ExpansionToken):
+ """A repr markup."""
+ def scan(self, scanner):
+ i = scanner.next('`', 0)
+ self.code = scanner.chop(i, 1)
+
+ def run(self, interpreter, locals):
+ interpreter.write(repr(interpreter.evaluate(self.code, locals)))
+
+ def string(self):
+ return '%s`%s`' % (self.prefix, self.code)
+
+class InPlaceToken(ExpansionToken):
+ """An in-place markup."""
+ def scan(self, scanner):
+ i = scanner.next(':', 0)
+ j = scanner.next(':', i + 1)
+ self.code = scanner.chop(i, j - i + 1)
+
+ def run(self, interpreter, locals):
+ interpreter.write("%s:%s:" % (interpreter.prefix, self.code))
+ try:
+ interpreter.serialize(self.code, locals)
+ finally:
+ interpreter.write(":")
+
+ def string(self):
+ return '%s:%s::' % (self.prefix, self.code)
+
+class StatementToken(ExpansionToken):
+ """A statement markup."""
+ def scan(self, scanner):
+ i = scanner.complex('{', '}', 0)
+ self.code = scanner.chop(i, 1)
+
+ def run(self, interpreter, locals):
+ interpreter.execute(self.code, locals)
+
+ def string(self):
+ return '%s{%s}' % (self.prefix, self.code)
+
+class CustomToken(ExpansionToken):
+ """A custom markup."""
+ def scan(self, scanner):
+ i = scanner.complex('<', '>', 0)
+ self.contents = scanner.chop(i, 1)
+
+ def run(self, interpreter, locals):
+ interpreter.invokeCallback(self.contents)
+
+ def string(self):
+ return '%s<%s>' % (self.prefix, self.contents)
+
+class ControlToken(ExpansionToken):
+
+ """A control token."""
+
+ PRIMARY_TYPES = ['if', 'for', 'while', 'try', 'def']
+ SECONDARY_TYPES = ['elif', 'else', 'except', 'finally']
+ TERTIARY_TYPES = ['continue', 'break']
+ GREEDY_TYPES = ['if', 'elif', 'for', 'while', 'def', 'end']
+ END_TYPES = ['end']
+
+ IN_RE = re.compile(r"\bin\b")
+
+ def scan(self, scanner):
+ scanner.acquire()
+ i = scanner.complex('[', ']', 0)
+ self.contents = scanner.chop(i, 1)
+ fields = self.contents.strip().split(' ', 1)
+ if len(fields) > 1:
+ self.type, self.rest = fields
+ else:
+ self.type = fields[0]
+ self.rest = None
+ self.subtokens = []
+ if self.type in self.GREEDY_TYPES and self.rest is None:
+ raise ParseError("control '%s' needs arguments" % self.type)
+ if self.type in self.PRIMARY_TYPES:
+ self.subscan(scanner, self.type)
+ self.kind = 'primary'
+ elif self.type in self.SECONDARY_TYPES:
+ self.kind = 'secondary'
+ elif self.type in self.TERTIARY_TYPES:
+ self.kind = 'tertiary'
+ elif self.type in self.END_TYPES:
+ self.kind = 'end'
+ else:
+ raise ParseError("unknown control markup: '%s'" % self.type)
+ scanner.release()
+
+ def subscan(self, scanner, primary):
+ """Do a subscan for contained tokens."""
+ while True:
+ token = scanner.one()
+ if token is None:
+ raise TransientParseError("control '%s' needs more tokens" % primary)
+ if (isinstance(token, ControlToken) and
+ token.type in self.END_TYPES):
+ if token.rest != primary:
+ raise ParseError("control must end with 'end %s'" % primary)
+ break
+ self.subtokens.append(token)
+
+ def build(self, allowed=None):
+ """Process the list of subtokens and divide it into a list of
+ 2-tuples, consisting of the dividing tokens and the list of
+ subtokens that follow them. If allowed is specified, it will
+ represent the list of the only secondary markup types which
+ are allowed."""
+ if allowed is None:
+ allowed = SECONDARY_TYPES
+ result = []
+ latest = []
+ result.append((self, latest))
+ for subtoken in self.subtokens:
+ if (isinstance(subtoken, ControlToken) and
+ subtoken.kind == 'secondary'):
+ if subtoken.type not in allowed:
+ raise ParseError("control unexpected secondary: '%s'" % subtoken.type)
+ latest = []
+ result.append((subtoken, latest))
+ else:
+ latest.append(subtoken)
+ return result
+
+ def run(self, interpreter, locals):
+ interpreter.invoke('beforeControl', type=self.type, rest=self.rest,
+ locals=locals)
+ if self.type == 'if':
+ info = self.build(['elif', 'else'])
+ elseTokens = None
+ if info[-1][0].type == 'else':
+ elseTokens = info.pop()[1]
+ for secondary, subtokens in info:
+ if secondary.type not in ('if', 'elif'):
+ raise ParseError("control 'if' unexpected secondary: '%s'" % secondary.type)
+ if interpreter.evaluate(secondary.rest, locals):
+ self.subrun(subtokens, interpreter, locals)
+ break
+ else:
+ if elseTokens:
+ self.subrun(elseTokens, interpreter, locals)
+ elif self.type == 'for':
+ sides = self.IN_RE.split(self.rest, 1)
+ if len(sides) != 2:
+ raise ParseError("control expected 'for x in seq'")
+ iterator, sequenceCode = sides
+ info = self.build(['else'])
+ elseTokens = None
+ if info[-1][0].type == 'else':
+ elseTokens = info.pop()[1]
+ if len(info) != 1:
+ raise ParseError("control 'for' expects at most one 'else'")
+ sequence = interpreter.evaluate(sequenceCode, locals)
+ for element in sequence:
+ try:
+ interpreter.assign(iterator, element, locals)
+ self.subrun(info[0][1], interpreter, locals)
+ except ContinueFlow:
+ continue
+ except BreakFlow:
+ break
+ else:
+ if elseTokens:
+ self.subrun(elseTokens, interpreter, locals)
+ elif self.type == 'while':
+ testCode = self.rest
+ info = self.build(['else'])
+ elseTokens = None
+ if info[-1][0].type == 'else':
+ elseTokens = info.pop()[1]
+ if len(info) != 1:
+ raise ParseError("control 'while' expects at most one 'else'")
+ atLeastOnce = False
+ while True:
+ try:
+ if not interpreter.evaluate(testCode, locals):
+ break
+ atLeastOnce = True
+ self.subrun(info[0][1], interpreter, locals)
+ except ContinueFlow:
+ continue
+ except BreakFlow:
+ break
+ if not atLeastOnce and elseTokens:
+ self.subrun(elseTokens, interpreter, locals)
+ elif self.type == 'try':
+ info = self.build(['except', 'finally'])
+ if len(info) == 1:
+ raise ParseError("control 'try' needs 'except' or 'finally'")
+ type = info[-1][0].type
+ if type == 'except':
+ for secondary, _tokens in info[1:]:
+ if secondary.type != 'except':
+ raise ParseError("control 'try' cannot have 'except' and 'finally'")
+ else:
+ assert type == 'finally'
+ if len(info) != 2:
+ raise ParseError("control 'try' can only have one 'finally'")
+ if type == 'except':
+ try:
+ self.subrun(info[0][1], interpreter, locals)
+ except FlowError:
+ raise
+ except Exception:
+ e = sys.exc_info()[1]
+ for secondary, tokens in info[1:]:
+ exception, variable = interpreter.clause(secondary.rest)
+ if variable is not None:
+ interpreter.assign(variable, e)
+ if isinstance(e, exception):
+ self.subrun(tokens, interpreter, locals)
+ break
+ else:
+ raise
+ else:
+ try:
+ self.subrun(info[0][1], interpreter, locals)
+ finally:
+ self.subrun(info[1][1], interpreter, locals)
+ elif self.type == 'continue':
+ raise ContinueFlow("control 'continue' without 'for', 'while'")
+ elif self.type == 'break':
+ raise BreakFlow("control 'break' without 'for', 'while'")
+ elif self.type == 'def':
+ signature = self.rest
+ definition = self.substring()
+ code = ('def %s:\n'
+ ' r"""%s"""\n'
+ ' return %s.expand(r"""%s""", locals())\n' %
+ (signature, definition, interpreter.pseudo, definition))
+ interpreter.execute(code, locals)
+ elif self.type == 'end':
+ raise ParseError("control 'end' requires primary markup")
+ else:
+ raise ParseError("control '%s' cannot be at this level" % self.type)
+ interpreter.invoke('afterControl')
+
+ def subrun(self, tokens, interpreter, locals):
+ """Execute a sequence of tokens."""
+ for token in tokens:
+ token.run(interpreter, locals)
+
+ def substring(self):
+ return ''.join(str(x) for x in self.subtokens)
+
+ def string(self):
+ if self.kind == 'primary':
+ return ('%s[%s]%s%s[end %s]' %
+ (self.prefix, self.contents, self.substring(),
+ self.prefix, self.type))
+ else:
+ return '%s[%s]' % (self.prefix, self.contents)
+
+
+class Scanner:
+
+ """A scanner holds a buffer for lookahead parsing and has the
+ ability to scan for special symbols and indicators in that
+ buffer."""
+
+ # This is the token mapping table that maps first characters to
+ # token classes.
+ TOKEN_MAP = [
+ (None, PrefixToken),
+ (' \t\v\r\n', WhitespaceToken),
+ (')]}', LiteralToken),
+ ('\\', EscapeToken),
+ ('#', CommentToken),
+ ('?', ContextNameToken),
+ ('!', ContextLineToken),
+ ('%', SignificatorToken),
+ ('(', ExpressionToken),
+ (IDENTIFIER_FIRST_CHARS, SimpleExpressionToken),
+ ('\'\"', StringLiteralToken),
+ ('`', ReprToken),
+ (':', InPlaceToken),
+ ('[', ControlToken),
+ ('{', StatementToken),
+ ('<', CustomToken),
+ ]
+
+ def __init__(self, prefix, data=''):
+ self.prefix = prefix
+ self.pointer = 0
+ self.buffer = data
+ self.lock = 0
+
+ def __nonzero__(self): return self.pointer < len(self.buffer) # 2.x
+ def __bool__(self): return self.pointer < len(self.buffer) # 3.x
+ def __len__(self): return len(self.buffer) - self.pointer
+
+ def __getitem__(self, index):
+ if isinstance(index, slice):
+ assert index.step is None or index.step == 1
+ return self.__getslice__(index.start, index.stop)
+ else:
+ return self.buffer[self.pointer + index]
+
+ def __getslice__(self, start, stop):
+ if start is None:
+ start = 0
+ if stop is None:
+ stop = len(self)
+ if stop > len(self):
+ stop = len(self)
+ return self.buffer[self.pointer + start:self.pointer + stop]
+
+ def advance(self, count=1):
+ """Advance the pointer count characters."""
+ self.pointer += count
+
+ def retreat(self, count=1):
+ self.pointer = self.pointer - count
+ if self.pointer < 0:
+ raise ParseError("can't retreat back over synced out chars")
+
+ def set(self, data):
+ """Start the scanner digesting a new batch of data; start the pointer
+ over from scratch."""
+ self.pointer = 0
+ self.buffer = data
+
+ def feed(self, data):
+ """Feed some more data to the scanner."""
+ self.buffer += data
+
+ def chop(self, count=None, slop=0):
+ """Chop the first count + slop characters off the front, and return
+ the first count. If count is not specified, then return
+ everything."""
+ if count is None:
+ assert slop == 0
+ count = len(self)
+ if count > len(self):
+ raise TransientParseError("not enough data to read")
+ result = self[:count]
+ self.advance(count + slop)
+ return result
+
+ def acquire(self):
+ """Lock the scanner so it doesn't destroy data on sync."""
+ self.lock += 1
+
+ def release(self):
+ """Unlock the scanner."""
+ self.lock -= 1
+
+ def sync(self):
+ """Sync up the buffer with the read head."""
+ if self.lock == 0 and self.pointer != 0:
+ self.buffer = self.buffer[self.pointer:]
+ self.pointer = 0
+
+ def unsync(self):
+ """Undo changes; reset the read head."""
+ if self.pointer != 0:
+ self.lock = 0
+ self.pointer = 0
+
+ def rest(self):
+ """Get the remainder of the buffer."""
+ return self[:]
+
+ def read(self, i=0, count=1):
+ """Read count chars starting from i; raise a transient error if
+ there aren't enough characters remaining."""
+ if len(self) < i + count:
+ raise TransientParseError("need more data to read")
+ else:
+ return self[i:i + count]
+
+ def check(self, i, archetype=None):
+ """Scan for the next single or triple quote, with the specified
+ archetype. Return the found quote or None."""
+ quote = None
+ if self[i] in '\'\"':
+ quote = self[i]
+ if len(self) - i < 3:
+ for j in range(i, len(self)):
+ if self[i] == quote:
+ return quote
+ else:
+ raise TransientParseError("need to scan for rest of quote")
+ if self[i + 1] == self[i + 2] == quote:
+ quote = quote * 3
+ if quote is not None:
+ if archetype is None:
+ return quote
+ else:
+ if archetype == quote:
+ return quote
+ elif len(archetype) < len(quote) and archetype[0] == quote[0]:
+ return archetype
+ else:
+ return None
+ else:
+ return None
+
+ def find(self, sub, start=0, end=None):
+ """Find the next occurrence of the character, or return -1."""
+ if end is not None:
+ return self.rest().find(sub, start, end)
+ else:
+ return self.rest().find(sub, start)
+
+ def last(self, char, start=0, end=None):
+ """Find the first character that is _not_ the specified character."""
+ if end is None:
+ end = len(self)
+ i = start
+ while i < end:
+ if self[i] != char:
+ return i
+ i += 1
+ else:
+ raise TransientParseError("expecting other than %s" % char)
+
+ def next(self, target, start=0, end=None, mandatory=False):
+ """Scan for the next occurrence of one of the characters in
+ the target string; optionally, make the scan mandatory."""
+ if mandatory:
+ assert end is not None
+ quote = None
+ if end is None:
+ end = len(self)
+ i = start
+ while i < end:
+ newQuote = self.check(i, quote)
+ if newQuote:
+ if newQuote == quote:
+ quote = None
+ else:
+ quote = newQuote
+ i += len(newQuote)
+ else:
+ c = self[i]
+ if quote:
+ if c == '\\':
+ i += 1
+ else:
+ if c in target:
+ return i
+ i += 1
+ else:
+ if mandatory:
+ raise ParseError("expecting %s, not found" % target)
+ else:
+ raise TransientParseError("expecting ending character")
+
+ def quote(self, start=0, end=None, mandatory=False):
+ """Scan for the end of the next quote."""
+ assert self[start] in '\'\"'
+ quote = self.check(start)
+ if end is None:
+ end = len(self)
+ i = start + len(quote)
+ while i < end:
+ newQuote = self.check(i, quote)
+ if newQuote:
+ i += len(newQuote)
+ if newQuote == quote:
+ return i
+ else:
+ c = self[i]
+ if c == '\\':
+ i += 1
+ i += 1
+ else:
+ if mandatory:
+ raise ParseError("expecting end of string literal")
+ else:
+ raise TransientParseError("expecting end of string literal")
+
+ def nested(self, enter, exit, start=0, end=None):
+ """Scan from i for an ending sequence, respecting entries and exits
+ only."""
+ depth = 0
+ if end is None:
+ end = len(self)
+ i = start
+ while i < end:
+ c = self[i]
+ if c == enter:
+ depth += 1
+ elif c == exit:
+ depth -= 1
+ if depth < 0:
+ return i
+ i += 1
+ else:
+ raise TransientParseError("expecting end of complex expression")
+
+ def complex(self, enter, exit, start=0, end=None, skip=None):
+ """Scan from i for an ending sequence, respecting quotes,
+ entries and exits."""
+ quote = None
+ depth = 0
+ if end is None:
+ end = len(self)
+ last = None
+ i = start
+ while i < end:
+ newQuote = self.check(i, quote)
+ if newQuote:
+ if newQuote == quote:
+ quote = None
+ else:
+ quote = newQuote
+ i += len(newQuote)
+ else:
+ c = self[i]
+ if quote:
+ if c == '\\':
+ i += 1
+ else:
+ if skip is None or last != skip:
+ if c == enter:
+ depth += 1
+ elif c == exit:
+ depth -= 1
+ if depth < 0:
+ return i
+ last = c
+ i += 1
+ else:
+ raise TransientParseError("expecting end of complex expression")
+
+ def word(self, start=0):
+ """Scan from i for a simple word."""
+ length = len(self)
+ i = start
+ while i < length:
+ if not self[i] in IDENTIFIER_CHARS:
+ return i
+ i += 1
+ else:
+ raise TransientParseError("expecting end of word")
+
+ def phrase(self, start=0):
+ """Scan from i for a phrase (e.g., 'word', 'f(a, b, c)', 'a[i]', or
+ combinations like 'x[i](a)'."""
+ # Find the word.
+ i = self.word(start)
+ while i < len(self) and self[i] in '([{':
+ enter = self[i]
+ if enter == '{':
+ raise ParseError("curly braces can't open simple expressions")
+ exit = ENDING_CHARS[enter]
+ i = self.complex(enter, exit, i + 1) + 1
+ return i
+
+ def simple(self, start=0):
+ """Scan from i for a simple expression, which consists of one
+ more phrases separated by dots."""
+ i = self.phrase(start)
+ length = len(self)
+ while i < length and self[i] == '.':
+ i = self.phrase(i)
+ # Make sure we don't end with a trailing dot.
+ while i > 0 and self[i - 1] == '.':
+ i -= 1
+ return i
+
+ def one(self):
+ """Parse and return one token, or None if the scanner is empty."""
+ if not self:
+ return None
+ if not self.prefix:
+ loc = -1
+ else:
+ loc = self.find(self.prefix)
+ if loc < 0:
+ # If there's no prefix in the buffer, then set the location to
+ # the end so the whole thing gets processed.
+ loc = len(self)
+ if loc == 0:
+ # If there's a prefix at the beginning of the buffer, process
+ # an expansion.
+ prefix = self.chop(1)
+ assert prefix == self.prefix
+ first = self.chop(1)
+ if first == self.prefix:
+ first = None
+ for firsts, factory in self.TOKEN_MAP:
+ if firsts is None:
+ if first is None:
+ break
+ elif first in firsts:
+ break
+ else:
+ raise ParseError("unknown markup: %s%s" % (self.prefix, first))
+ token = factory(self.prefix, first)
+ try:
+ token.scan(self)
+ except TransientParseError:
+ # If a transient parse error occurs, reset the buffer pointer
+ # so we can (conceivably) try again later.
+ self.unsync()
+ raise
+ else:
+ # Process everything up to loc as a null token.
+ data = self.chop(loc)
+ token = NullToken(data)
+ self.sync()
+ return token
+
+
+class Interpreter:
+
+ """An interpreter can process chunks of EmPy code."""
+
+ # Constants.
+
+ VERSION = __version__
+ SIGNIFICATOR_RE_SUFFIX = SIGNIFICATOR_RE_SUFFIX
+ SIGNIFICATOR_RE_STRING = None
+
+ # Types.
+
+ Interpreter = None # define this below to prevent a circular reference
+ Hook = Hook # DEPRECATED
+ Filter = Filter # DEPRECATED
+ NullFilter = NullFilter # DEPRECATED
+ FunctionFilter = FunctionFilter # DEPRECATED
+ StringFilter = StringFilter # DEPRECATED
+ BufferedFilter = BufferedFilter # DEPRECATED
+ SizeBufferedFilter = SizeBufferedFilter # DEPRECATED
+ LineBufferedFilter = LineBufferedFilter # DEPRECATED
+ MaximallyBufferedFilter = MaximallyBufferedFilter # DEPRECATED
+
+ # Tables.
+
+ ESCAPE_CODES = {0x00: '0', 0x07: 'a', 0x08: 'b', 0x1b: 'e', 0x0c: 'f',
+ 0x7f: 'h', 0x0a: 'n', 0x0d: 'r', 0x09: 't', 0x0b: 'v',
+ 0x04: 'z'}
+
+ ASSIGN_TOKEN_RE = re.compile(r"[_a-zA-Z][_a-zA-Z0-9]*|\(|\)|,")
+
+ DEFAULT_OPTIONS = {BANGPATH_OPT: True,
+ BUFFERED_OPT: False,
+ RAW_OPT: False,
+ EXIT_OPT: True,
+ FLATTEN_OPT: False,
+ OVERRIDE_OPT: True,
+ CALLBACK_OPT: False}
+
+ _wasProxyInstalled = False # was a proxy installed?
+
+ # Construction, initialization, destruction.
+
+ def __init__(self, output=None, argv=None, prefix=DEFAULT_PREFIX,
+ pseudo=None, options=None, globals=None, hooks=None):
+ self.interpreter = self # DEPRECATED
+ # Set up the stream.
+ if output is None:
+ output = UncloseableFile(sys.__stdout__)
+ self.output = output
+ self.prefix = prefix
+ if pseudo is None:
+ pseudo = DEFAULT_PSEUDOMODULE_NAME
+ self.pseudo = pseudo
+ if argv is None:
+ argv = [DEFAULT_SCRIPT_NAME]
+ self.argv = argv
+ self.args = argv[1:]
+ if options is None:
+ options = {}
+ self.options = options
+ # Initialize any hooks.
+ self.hooksEnabled = None # special sentinel meaning "false until added"
+ self.hooks = []
+ if hooks is None:
+ hooks = []
+ for hook in hooks:
+ self.register(hook)
+ # Initialize callback.
+ self.callback = None
+ # Finalizers.
+ self.finals = []
+ # The interpreter stacks.
+ self.contexts = Stack()
+ self.streams = Stack()
+ # Now set up the globals.
+ self.globals = globals
+ self.fix()
+ self.history = Stack()
+ # Install a proxy stdout if one hasn't been already.
+ self.installProxy()
+ # Finally, reset the state of all the stacks.
+ self.reset()
+ # Okay, now flatten the namespaces if that option has been set.
+ if self.options.get(FLATTEN_OPT, False):
+ self.flatten()
+ # Set up old pseudomodule attributes.
+ if prefix is None:
+ self.SIGNIFICATOR_RE_STRING = None
+ else:
+ self.SIGNIFICATOR_RE_STRING = prefix + self.SIGNIFICATOR_RE_SUFFIX
+ self.Interpreter = self.__class__
+ # Done. Now declare that we've started up.
+ self.invoke('atStartup')
+
+ def __del__(self):
+ self.shutdown()
+
+ def __repr__(self):
+ return ('<%s pseudomodule/interpreter at 0x%x>' %
+ (self.pseudo, id(self)))
+
+ def ready(self):
+ """Declare the interpreter ready for normal operations."""
+ self.invoke('atReady')
+
+ def fix(self):
+ """Reset the globals, stamping in the pseudomodule."""
+ if self.globals is None:
+ self.globals = {}
+ # Make sure that there is no collision between two interpreters'
+ # globals.
+ if self.pseudo in self.globals:
+ if self.globals[self.pseudo] is not self:
+ raise Error("interpreter globals collision")
+ self.globals[self.pseudo] = self
+
+ def unfix(self):
+ """Remove the pseudomodule (if present) from the globals."""
+ UNWANTED_KEYS = [self.pseudo, '__builtins__']
+ for unwantedKey in UNWANTED_KEYS:
+ if unwantedKey in self.globals:
+ del self.globals[unwantedKey]
+
+ def update(self, other):
+ """Update the current globals dictionary with another dictionary."""
+ self.globals.update(other)
+ self.fix()
+
+ def clear(self):
+ """Clear out the globals dictionary with a brand new one."""
+ self.globals = {}
+ self.fix()
+
+ def save(self, deep=True):
+ if deep:
+ copyMethod = copy.deepcopy
+ else:
+ copyMethod = copy.copy
+ """Save a copy of the current globals on the history stack."""
+ self.unfix()
+ self.history.push(copyMethod(self.globals))
+ self.fix()
+
+ def restore(self, destructive=True):
+ """Restore the topmost historic globals."""
+ if destructive:
+ fetchMethod = self.history.pop
+ else:
+ fetchMethod = self.history.top
+ self.unfix()
+ self.globals = fetchMethod()
+ self.fix()
+
+ def shutdown(self):
+ """Declare this interpreting session over; close the stream file
+ object. This method is idempotent."""
+ if self.streams is not None:
+ try:
+ self.finalize()
+ self.invoke('atShutdown')
+ while self.streams:
+ stream = self.streams.pop()
+ stream.close()
+ finally:
+ self.streams = None
+
+ def ok(self):
+ """Is the interpreter still active?"""
+ return self.streams is not None
+
+ # Writeable file-like methods.
+
+ def write(self, data):
+ self.stream().write(data)
+
+ def writelines(self, stuff):
+ self.stream().writelines(stuff)
+
+ def flush(self):
+ self.stream().flush()
+
+ def close(self):
+ self.shutdown()
+
+ # Stack-related activity.
+
+ def context(self):
+ return self.contexts.top()
+
+ def stream(self):
+ return self.streams.top()
+
+ def reset(self):
+ self.contexts.purge()
+ self.streams.purge()
+ self.streams.push(Stream(self.output))
+ if self.options.get(OVERRIDE_OPT, True):
+ sys.stdout.clear(self)
+
+ def push(self):
+ if self.options.get(OVERRIDE_OPT, True):
+ sys.stdout.push(self)
+
+ def pop(self):
+ if self.options.get(OVERRIDE_OPT, True):
+ sys.stdout.pop(self)
+
+ # Higher-level operations.
+
+ def include(self, fileOrFilename, locals=None):
+ """Do an include pass on a file or filename."""
+ if isinstance(fileOrFilename, _str):
+ # Either it's a string representing a filename ...
+ filename = fileOrFilename
+ name = filename
+ file = theSubsystem.open(filename, 'r')
+ else:
+ # ... or a file object.
+ file = fileOrFilename
+ name = "<%s>" % str(file.__class__)
+ self.invoke('beforeInclude', name=name, file=file, locals=locals)
+ self.file(file, name, locals)
+ self.invoke('afterInclude')
+
+ def expand(self, data, locals=None):
+ """Do an explicit expansion on a subordinate stream."""
+ outFile = StringIO()
+ stream = Stream(outFile)
+ self.invoke('beforeExpand', string=data, locals=locals)
+ self.streams.push(stream)
+ try:
+ self.string(data, '<expand>', locals)
+ stream.flush()
+ expansion = outFile.getvalue()
+ self.invoke('afterExpand', result=expansion)
+ return expansion
+ finally:
+ self.streams.pop()
+
+ def quote(self, data):
+ """Quote the given string so that if it were expanded it would
+ evaluate to the original."""
+ self.invoke('beforeQuote', string=data)
+ scanner = Scanner(self.prefix, data)
+ result = []
+ i = 0
+ try:
+ j = scanner.next(self.prefix, i)
+ result.append(data[i:j])
+ result.append(self.prefix * 2)
+ i = j + 1
+ except TransientParseError:
+ pass
+ result.append(data[i:])
+ result = ''.join(result)
+ self.invoke('afterQuote', result=result)
+ return result
+
+ def escape(self, data, more=''):
+ """Escape a string so that nonprintable characters are replaced
+ with compatible EmPy expansions."""
+ self.invoke('beforeEscape', string=data, more=more)
+ result = []
+ for char in data:
+ if char < ' ' or char > '~':
+ charOrd = ord(char)
+ if charOrd in Interpreter.ESCAPE_CODES:
+ result.append(self.prefix + '\\' +
+ Interpreter.ESCAPE_CODES[charOrd])
+ else:
+ result.append(self.prefix + '\\x%02x' % charOrd)
+ elif char in more:
+ result.append(self.prefix + '\\' + char)
+ else:
+ result.append(char)
+ result = ''.join(result)
+ self.invoke('afterEscape', result=result)
+ return result
+
+ # Processing.
+
+ def wrap(self, callable, args):
+ """Wrap around an application of a callable and handle errors.
+ Return whether no error occurred."""
+ try:
+ callable(*args)
+ self.reset()
+ return True
+ except KeyboardInterrupt:
+ # Handle keyboard interrupts specially: we should always exit
+ # from these.
+ e = sys.exc_info()[1]
+ self.fail(e, True)
+ except Exception:
+ # A standard exception (other than a keyboard interrupt).
+ e = sys.exc_info()[1]
+ self.fail(e)
+ except:
+ # If we get here, then either it's an exception not derived from
+ # Exception or it's a string exception, so get the error type
+ # from the sys module.
+ e = sys.exc_info()[1]
+ self.fail(e)
+ # An error occurred if we leak through to here, so do cleanup.
+ self.reset()
+ return False
+
+ def interact(self):
+ """Perform interaction."""
+ self.invoke('atInteract')
+ done = False
+ while not done:
+ result = self.wrap(self.file, (sys.stdin, '<interact>'))
+ if self.options.get(EXIT_OPT, True):
+ done = True
+ else:
+ if result:
+ done = True
+ else:
+ self.reset()
+
+ def fail(self, error, fatal=False):
+ """Handle an actual error that occurred."""
+ if self.options.get(BUFFERED_OPT, False):
+ try:
+ self.output.abort()
+ except AttributeError:
+ # If the output file object doesn't have an abort method,
+ # something got mismatched, but it's too late to do
+ # anything about it now anyway, so just ignore it.
+ pass
+ meta = self.meta(error)
+ self.handle(meta)
+ if self.options.get(RAW_OPT, False):
+ raise
+ if fatal or self.options.get(EXIT_OPT, True):
+ sys.exit(FAILURE_CODE)
+
+ def file(self, file, name='<file>', locals=None):
+ """Parse the entire contents of a file-like object, line by line."""
+ context = Context(name)
+ self.contexts.push(context)
+ self.invoke('beforeFile', name=name, file=file, locals=locals)
+ scanner = Scanner(self.prefix)
+ first = True
+ done = False
+ while not done:
+ self.context().bump()
+ line = file.readline()
+ if first:
+ if self.options.get(BANGPATH_OPT, True) and self.prefix:
+ # Replace a bangpath at the beginning of the first line
+ # with an EmPy comment.
+ if line.startswith(BANGPATH):
+ line = self.prefix + '#' + line[2:]
+ first = False
+ if line:
+ scanner.feed(line)
+ else:
+ done = True
+ self.safe(scanner, done, locals)
+ self.invoke('afterFile')
+ self.contexts.pop()
+
+ def binary(self, file, name='<binary>', chunkSize=0, locals=None):
+ """Parse the entire contents of a file-like object, in chunks."""
+ if chunkSize <= 0:
+ chunkSize = DEFAULT_CHUNK_SIZE
+ context = Context(name, units='bytes')
+ self.contexts.push(context)
+ self.invoke('beforeBinary', name=name, file=file,
+ chunkSize=chunkSize, locals=locals)
+ scanner = Scanner(self.prefix)
+ done = False
+ while not done:
+ chunk = file.read(chunkSize)
+ if chunk:
+ scanner.feed(chunk)
+ else:
+ done = True
+ self.safe(scanner, done, locals)
+ self.context().bump(len(chunk))
+ self.invoke('afterBinary')
+ self.contexts.pop()
+
+ def string(self, data, name='<string>', locals=None):
+ """Parse a string."""
+ context = Context(name)
+ self.contexts.push(context)
+ self.invoke('beforeString', name=name, string=data, locals=locals)
+ context.bump()
+ scanner = Scanner(self.prefix, data)
+ self.safe(scanner, True, locals)
+ self.invoke('afterString')
+ self.contexts.pop()
+
+ def safe(self, scanner, final=False, locals=None):
+ """Do a protected parse. Catch transient parse errors; if
+ final is true, then make a final pass with a terminator,
+ otherwise ignore the transient parse error (more data is
+ pending)."""
+ try:
+ self.parse(scanner, locals)
+ except TransientParseError:
+ if final:
+ # If the buffer doesn't end with a newline, try tacking on
+ # a dummy terminator.
+ buffer = scanner.rest()
+ if buffer and buffer[-1] != '\n':
+ scanner.feed(self.prefix + '\n')
+ # A TransientParseError thrown from here is a real parse
+ # error.
+ self.parse(scanner, locals)
+
+ def parse(self, scanner, locals=None):
+ """Parse and run as much from this scanner as possible."""
+ self.invoke('atParse', scanner=scanner, locals=locals)
+ while True:
+ token = scanner.one()
+ if token is None:
+ break
+ self.invoke('atToken', token=token)
+ token.run(self, locals)
+
+ # Medium-level evaluation and execution.
+
+ def tokenize(self, name):
+ """Take an lvalue string and return a name or a (possibly recursive)
+ list of names."""
+ result = []
+ stack = [result]
+ for garbage in self.ASSIGN_TOKEN_RE.split(name):
+ garbage = garbage.strip()
+ if garbage:
+ raise ParseError("unexpected assignment token: '%s'" % garbage)
+ tokens = self.ASSIGN_TOKEN_RE.findall(name)
+ # While processing, put a None token at the start of any list in which
+ # commas actually appear.
+ for token in tokens:
+ if token == '(':
+ stack.append([])
+ elif token == ')':
+ top = stack.pop()
+ if len(top) == 1:
+ top = top[0] # no None token means that it's not a 1-tuple
+ elif top[0] is None:
+ del top[0] # remove the None token for real tuples
+ stack[-1].append(top)
+ elif token == ',':
+ if len(stack[-1]) == 1:
+ stack[-1].insert(0, None)
+ else:
+ stack[-1].append(token)
+ # If it's a 1-tuple at the top level, turn it into a real subsequence.
+ if result and result[0] is None:
+ result = [result[1:]]
+ if len(result) == 1:
+ return result[0]
+ else:
+ return result
+
+ def significate(self, key, value=None, locals=None):
+ """Declare a significator."""
+ self.invoke('beforeSignificate', key=key, value=value, locals=locals)
+ name = '__%s__' % key
+ self.atomic(name, value, locals)
+ self.invoke('afterSignificate')
+
+ def atomic(self, name, value, locals=None):
+ """Do an atomic assignment."""
+ self.invoke('beforeAtomic', name=name, value=value, locals=locals)
+ if locals is None:
+ self.globals[name] = value
+ else:
+ locals[name] = value
+ self.invoke('afterAtomic')
+
+ def multi(self, names, values, locals=None):
+ """Do a (potentially recursive) assignment."""
+ self.invoke('beforeMulti', names=names, values=values, locals=locals)
+ # No zip in 1.5, so we have to do it manually.
+ i = 0
+ try:
+ values = tuple(values)
+ except TypeError:
+ raise TypeError("unpack non-sequence")
+ if len(names) != len(values):
+ raise ValueError("unpack tuple of wrong size")
+ for i in range(len(names)):
+ name = names[i]
+ if isinstance(name, _str) or isinstance(name, _unicode):
+ self.atomic(name, values[i], locals)
+ else:
+ self.multi(name, values[i], locals)
+ self.invoke('afterMulti')
+
+ def assign(self, name, value, locals=None):
+ """Do a potentially complex (including tuple unpacking) assignment."""
+ left = self.tokenize(name)
+ # The return value of tokenize can either be a string or a list of
+ # (lists of) strings.
+ if isinstance(left, _str) or isinstance(left, _unicode):
+ self.atomic(left, value, locals)
+ else:
+ self.multi(left, value, locals)
+
+ def import_(self, name, locals=None):
+ """Do an import."""
+ self.invoke('beforeImport', name=name, locals=locals)
+ self.execute('import %s' % name, locals)
+ self.invoke('afterImport')
+
+ def clause(self, catch, locals=None):
+ """Given the string representation of an except clause, turn it into
+ a 2-tuple consisting of the class name, and either a variable name
+ or None."""
+ self.invoke('beforeClause', catch=catch, locals=locals)
+ if catch is None:
+ exceptionCode, variable = None, None
+ elif catch.find(',') >= 0:
+ exceptionCode, variable = catch.strip().split(',', 1)
+ variable = variable.strip()
+ else:
+ exceptionCode, variable = catch.strip(), None
+ if not exceptionCode:
+ exception = Exception
+ else:
+ exception = self.evaluate(exceptionCode, locals)
+ self.invoke('afterClause', exception=exception, variable=variable)
+ return exception, variable
+
+ def serialize(self, expression, locals=None):
+ """Do an expansion, involving evaluating an expression, then
+ converting it to a string and writing that string to the
+ output if the evaluation is not None."""
+ self.invoke('beforeSerialize', expression=expression, locals=locals)
+ result = self.evaluate(expression, locals)
+ if result is not None:
+ self.write(str(result))
+ self.invoke('afterSerialize')
+
+ def defined(self, name, locals=None):
+ """Return a Boolean indicating whether or not the name is
+ defined either in the locals or the globals."""
+ self.invoke('beforeDefined', name=name, local=local)
+ if locals is not None:
+ if name in locals:
+ result = True
+ else:
+ result = False
+ elif name in self.globals:
+ result = True
+ else:
+ result = False
+ self.invoke('afterDefined', result=result)
+
+ def literal(self, text):
+ """Process a string literal."""
+ self.invoke('beforeLiteral', text=text)
+ self.serialize(text)
+ self.invoke('afterLiteral')
+
+ # Low-level evaluation and execution.
+
+ def evaluate(self, expression, locals=None):
+ """Evaluate an expression."""
+ if expression in ('1', 'True'): return True
+ if expression in ('0', 'False'): return False
+ self.push()
+ try:
+ self.invoke('beforeEvaluate',
+ expression=expression, locals=locals)
+ if locals is not None:
+ result = eval(expression, self.globals, locals)
+ else:
+ result = eval(expression, self.globals)
+ self.invoke('afterEvaluate', result=result)
+ return result
+ finally:
+ self.pop()
+
+ def execute(self, statements, locals=None):
+ """Execute a statement."""
+ # If there are any carriage returns (as opposed to linefeeds/newlines)
+ # in the statements code, then remove them. Even on DOS/Windows
+ # platforms,
+ if statements.find('\r') >= 0:
+ statements = statements.replace('\r', '')
+ # If there are no newlines in the statements code, then strip any
+ # leading or trailing whitespace.
+ if statements.find('\n') < 0:
+ statements = statements.strip()
+ self.push()
+ try:
+ self.invoke('beforeExecute',
+ statements=statements, locals=locals)
+ _exec(statements, self.globals, locals)
+ self.invoke('afterExecute')
+ finally:
+ self.pop()
+
+ def single(self, source, locals=None):
+ """Execute an expression or statement, just as if it were
+ entered into the Python interactive interpreter."""
+ self.push()
+ try:
+ self.invoke('beforeSingle',
+ source=source, locals=locals)
+ code = compile(source, '<single>', 'single')
+ _exec(code, self.globals, locals)
+ self.invoke('afterSingle')
+ finally:
+ self.pop()
+
+ # Hooks.
+
+ def register(self, hook, prepend=False):
+ """Register the provided hook."""
+ hook.register(self)
+ if self.hooksEnabled is None:
+ # A special optimization so that hooks can be effectively
+ # disabled until one is added or they are explicitly turned on.
+ self.hooksEnabled = True
+ if prepend:
+ self.hooks.insert(0, hook)
+ else:
+ self.hooks.append(hook)
+
+ def deregister(self, hook):
+ """Remove an already registered hook."""
+ hook.deregister(self)
+ self.hooks.remove(hook)
+
+ def invoke(self, _name, **keywords):
+ """Invoke the hook(s) associated with the hook name, should they
+ exist."""
+ if self.hooksEnabled:
+ for hook in self.hooks:
+ hook.push()
+ try:
+ method = getattr(hook, _name)
+ method(*(), **keywords)
+ finally:
+ hook.pop()
+
+ def finalize(self):
+ """Execute any remaining final routines."""
+ self.push()
+ self.invoke('atFinalize')
+ try:
+ # Pop them off one at a time so they get executed in reverse
+ # order and we remove them as they're executed in case something
+ # bad happens.
+ while self.finals:
+ final = self.finals.pop()
+ final()
+ finally:
+ self.pop()
+
+ # Error handling.
+
+ def meta(self, exc=None):
+ """Construct a MetaError for the interpreter's current state."""
+ return MetaError(self.contexts.clone(), exc)
+
+ def handle(self, meta):
+ """Handle a MetaError."""
+ first = True
+ self.invoke('atHandle', meta=meta)
+ for context in meta.contexts:
+ if first:
+ if meta.exc is not None:
+ desc = "error: %s: %s" % (meta.exc.__class__, meta.exc)
+ else:
+ desc = "error"
+ else:
+ desc = "from this context"
+ first = False
+ sys.stderr.write('%s: %s\n' % (context, desc))
+
+ def installProxy(self):
+ """Install a proxy if necessary."""
+ # Unfortunately, there's no surefire way to make sure that installing
+ # a sys.stdout proxy is idempotent, what with different interpreters
+ # running from different modules. The best we can do here is to try
+ # manipulating the proxy's test function ...
+ try:
+ sys.stdout._testProxy()
+ except AttributeError:
+ # ... if the current stdout object doesn't have one, then check
+ # to see if we think _this_ particularly Interpreter class has
+ # installed it before ...
+ if Interpreter._wasProxyInstalled:
+ # ... and if so, we have a proxy problem.
+ raise Error("interpreter stdout proxy lost")
+ else:
+ # Otherwise, install the proxy and set the flag.
+ sys.stdout = ProxyFile(sys.stdout)
+ Interpreter._wasProxyInstalled = True
+
+ #
+ # Pseudomodule routines.
+ #
+
+ # Identification.
+
+ def identify(self):
+ """Identify the topmost context with a 2-tuple of the name and
+ line number."""
+ return self.context().identify()
+
+ def atExit(self, callable):
+ """Register a function to be called at exit."""
+ self.finals.append(callable)
+
+ # Context manipulation.
+
+ def pushContext(self, name='<unnamed>', line=0):
+ """Create a new context and push it."""
+ self.contexts.push(Context(name, line))
+
+ def popContext(self):
+ """Pop the top context."""
+ self.contexts.pop()
+
+ def setContextName(self, name):
+ """Set the name of the topmost context."""
+ context = self.context()
+ context.name = name
+
+ def setContextLine(self, line):
+ """Set the name of the topmost context."""
+ context = self.context()
+ context.line = line
+
+ setName = setContextName # DEPRECATED
+ setLine = setContextLine # DEPRECATED
+
+ # Globals manipulation.
+
+ def getGlobals(self):
+ """Retrieve the globals."""
+ return self.globals
+
+ def setGlobals(self, globals):
+ """Set the globals to the specified dictionary."""
+ self.globals = globals
+ self.fix()
+
+ def updateGlobals(self, otherGlobals):
+ """Merge another mapping object into this interpreter's globals."""
+ self.update(otherGlobals)
+
+ def clearGlobals(self):
+ """Clear out the globals with a brand new dictionary."""
+ self.clear()
+
+ def saveGlobals(self, deep=True):
+ """Save a copy of the globals off onto the history stack."""
+ self.save(deep)
+
+ def restoreGlobals(self, destructive=True):
+ """Restore the most recently saved copy of the globals."""
+ self.restore(destructive)
+
+ # Hook support.
+
+ def areHooksEnabled(self):
+ """Return whether or not hooks are presently enabled."""
+ if self.hooksEnabled is None:
+ return True
+ else:
+ return self.hooksEnabled
+
+ def enableHooks(self):
+ """Enable hooks."""
+ self.hooksEnabled = True
+
+ def disableHooks(self):
+ """Disable hooks."""
+ self.hooksEnabled = False
+
+ def getHooks(self):
+ """Get the current hooks."""
+ return self.hooks[:]
+
+ def clearHooks(self):
+ """Clear all hooks."""
+ self.hooks = []
+
+ def addHook(self, hook, prepend=False):
+ """Add a new hook; optionally insert it rather than appending it."""
+ self.register(hook, prepend)
+
+ def removeHook(self, hook):
+ """Remove a preexisting hook."""
+ self.deregister(hook)
+
+ def invokeHook(self, _name, **keywords):
+ """Manually invoke a hook."""
+ self.invoke(*(_name,), **keywords)
+
+ # Callbacks.
+
+ def getCallback(self):
+ """Get the callback registered with this interpreter, or None."""
+ return self.callback
+
+ def registerCallback(self, callback):
+ """Register a custom markup callback with this interpreter."""
+ self.callback = callback
+
+ def deregisterCallback(self):
+ """Remove any previously registered callback with this interpreter."""
+ self.callback = None
+
+ def invokeCallback(self, contents):
+ """Invoke the callback."""
+ if self.callback is None:
+ if self.options.get(CALLBACK_OPT, False):
+ raise Error("custom markup invoked with no defined callback")
+ else:
+ self.callback(contents)
+
+ # Pseudomodule manipulation.
+
+ def flatten(self, keys=None):
+ """Flatten the contents of the pseudo-module into the globals
+ namespace."""
+ if keys is None:
+ keys = list(self.__dict__.keys()) + list(self.__class__.__dict__.keys())
+ dict = {}
+ for key in keys:
+ # The pseudomodule is really a class instance, so we need to
+ # fumble use getattr instead of simply fumbling through the
+ # instance's __dict__.
+ dict[key] = getattr(self, key)
+ # Stomp everything into the globals namespace.
+ self.globals.update(dict)
+
+ # Prefix.
+
+ def getPrefix(self):
+ """Get the current prefix."""
+ return self.prefix
+
+ def setPrefix(self, prefix):
+ """Set the prefix."""
+ self.prefix = prefix
+
+ # Diversions.
+
+ def stopDiverting(self):
+ """Stop any diverting."""
+ self.stream().revert()
+
+ def createDiversion(self, name):
+ """Create a diversion (but do not divert to it) if it does not
+ already exist."""
+ self.stream().create(name)
+
+ def retrieveDiversion(self, name):
+ """Retrieve the diversion object associated with the name."""
+ return self.stream().retrieve(name)
+
+ def startDiversion(self, name):
+ """Start diverting to the given diversion name."""
+ self.stream().divert(name)
+
+ def playDiversion(self, name):
+ """Play the given diversion and then purge it."""
+ self.stream().undivert(name, True)
+
+ def replayDiversion(self, name):
+ """Replay the diversion without purging it."""
+ self.stream().undivert(name, False)
+
+ def purgeDiversion(self, name):
+ """Eliminate the given diversion."""
+ self.stream().purge(name)
+
+ def playAllDiversions(self):
+ """Play all existing diversions and then purge them."""
+ self.stream().undivertAll(True)
+
+ def replayAllDiversions(self):
+ """Replay all existing diversions without purging them."""
+ self.stream().undivertAll(False)
+
+ def purgeAllDiversions(self):
+ """Purge all existing diversions."""
+ self.stream().purgeAll()
+
+ def getCurrentDiversion(self):
+ """Get the name of the current diversion."""
+ return self.stream().currentDiversion
+
+ def getAllDiversions(self):
+ """Get the names of all existing diversions."""
+ names = sorted(self.stream().diversions.keys())
+ return names
+
+ # Filter.
+
+ def resetFilter(self):
+ """Reset the filter so that it does no filtering."""
+ self.stream().install(None)
+
+ def nullFilter(self):
+ """Install a filter that will consume all text."""
+ self.stream().install(0)
+
+ def getFilter(self):
+ """Get the current filter."""
+ filter = self.stream().filter
+ if filter is self.stream().file:
+ return None
+ else:
+ return filter
+
+ def setFilter(self, shortcut):
+ """Set the filter."""
+ self.stream().install(shortcut)
+
+ def attachFilter(self, shortcut):
+ """Attach a single filter to the end of the current filter chain."""
+ self.stream().attach(shortcut)
+
+
+class Document:
+
+ """A representation of an individual EmPy document, as used by a
+ processor."""
+
+ def __init__(self, ID, filename):
+ self.ID = ID
+ self.filename = filename
+ self.significators = {}
+
+
+class Processor:
+
+ """An entity which is capable of processing a hierarchy of EmPy
+ files and building a dictionary of document objects associated
+ with them describing their significator contents."""
+
+ DEFAULT_EMPY_EXTENSIONS = ('.em',)
+ SIGNIFICATOR_RE = re.compile(SIGNIFICATOR_RE_STRING)
+
+ def __init__(self, factory=Document):
+ self.factory = factory
+ self.documents = {}
+
+ def identifier(self, pathname, filename): return filename
+
+ def clear(self):
+ self.documents = {}
+
+ def scan(self, basename, extensions=DEFAULT_EMPY_EXTENSIONS):
+ if isinstance(extensions, _str):
+ extensions = (extensions,)
+ def _noCriteria(x):
+ return True
+ def _extensionsCriteria(pathname, extensions=extensions):
+ if extensions:
+ for extension in extensions:
+ if pathname[-len(extension):] == extension:
+ return True
+ return False
+ else:
+ return True
+ self.directory(basename, _noCriteria, _extensionsCriteria, None)
+ self.postprocess()
+
+ def postprocess(self):
+ pass
+
+ def directory(self, basename, dirCriteria, fileCriteria, depth=None):
+ if depth is not None:
+ if depth <= 0:
+ return
+ else:
+ depth -= 1
+ filenames = os.listdir(basename)
+ for filename in filenames:
+ pathname = os.path.join(basename, filename)
+ if os.path.isdir(pathname):
+ if dirCriteria(pathname):
+ self.directory(pathname, dirCriteria, fileCriteria, depth)
+ elif os.path.isfile(pathname):
+ if fileCriteria(pathname):
+ documentID = self.identifier(pathname, filename)
+ document = self.factory(documentID, pathname)
+ self.file(document, open(pathname))
+ self.documents[documentID] = document
+
+ def file(self, document, file):
+ while True:
+ line = file.readline()
+ if not line:
+ break
+ self.line(document, line)
+
+ def line(self, document, line):
+ match = self.SIGNIFICATOR_RE.search(line)
+ if match:
+ key, valueS = match.groups()
+ valueS = valueS.strip()
+ if valueS:
+ value = eval(valueS)
+ else:
+ value = None
+ document.significators[key] = value
+
+
+def expand(_data, _globals=None,
+ _argv=None, _prefix=DEFAULT_PREFIX, _pseudo=None, _options=None, \
+ **_locals):
+ """Do an atomic expansion of the given source data, creating and
+ shutting down an interpreter dedicated to the task. The sys.stdout
+ object is saved off and then replaced before this function
+ returns."""
+ if len(_locals) == 0:
+ # If there were no keyword arguments specified, don't use a locals
+ # dictionary at all.
+ _locals = None
+ output = NullFile()
+ interpreter = Interpreter(output, argv=_argv, prefix=_prefix,
+ pseudo=_pseudo, options=_options,
+ globals=_globals)
+ if interpreter.options.get(OVERRIDE_OPT, True):
+ oldStdout = sys.stdout
+ try:
+ result = interpreter.expand(_data, _locals)
+ finally:
+ interpreter.shutdown()
+ if _globals is not None:
+ interpreter.unfix() # remove pseudomodule to prevent clashes
+ if interpreter.options.get(OVERRIDE_OPT, True):
+ sys.stdout = oldStdout
+ return result
+
+def environment(name, default=None):
+ """Get data from the current environment. If the default is True
+ or False, then presume that we're only interested in the existence
+ or non-existence of the environment variable."""
+ if name in os.environ:
+ # Do the True/False test by value for future compatibility.
+ if default == False or default == True:
+ return True
+ else:
+ return os.environ[name]
+ else:
+ return default
+
+def info(table):
+ DEFAULT_LEFT = 28
+ maxLeft = 0
+ maxRight = 0
+ for left, right in table:
+ if len(left) > maxLeft:
+ maxLeft = len(left)
+ if len(right) > maxRight:
+ maxRight = len(right)
+ FORMAT = ' %%-%ds %%s\n' % max(maxLeft, DEFAULT_LEFT)
+ for left, right in table:
+ if right.find('\n') >= 0:
+ for right in right.split('\n'):
+ sys.stderr.write(FORMAT % (left, right))
+ left = ''
+ else:
+ sys.stderr.write(FORMAT % (left, right))
+
+def usage(verbose=True):
+ """Print usage information."""
+ programName = sys.argv[0]
+ def warn(line=''):
+ sys.stderr.write("%s\n" % line)
+ warn("""\
+Usage: %s [options] [<filename, or '-' for stdin> [<argument>...]]
+Welcome to EmPy version %s.""" % (programName, __version__))
+ warn()
+ warn("Valid options:")
+ info(OPTION_INFO)
+ if verbose:
+ warn()
+ warn("The following markups are supported:")
+ info(MARKUP_INFO)
+ warn()
+ warn("Valid escape sequences are:")
+ info(ESCAPE_INFO)
+ warn()
+ warn("The %s pseudomodule contains the following attributes:" % DEFAULT_PSEUDOMODULE_NAME)
+ info(PSEUDOMODULE_INFO)
+ warn()
+ warn("The following environment variables are recognized:")
+ info(ENVIRONMENT_INFO)
+ warn()
+ warn(USAGE_NOTES)
+ else:
+ warn()
+ warn("Type %s -H for more extensive help." % programName)
+
+def invoke(args):
+ """Run a standalone instance of an EmPy interpeter."""
+ # Initialize the options.
+ _output = None
+ _options = {BUFFERED_OPT: environment(BUFFERED_ENV, False),
+ RAW_OPT: environment(RAW_ENV, False),
+ EXIT_OPT: True,
+ FLATTEN_OPT: environment(FLATTEN_ENV, False),
+ OVERRIDE_OPT: not environment(NO_OVERRIDE_ENV, False),
+ CALLBACK_OPT: False}
+ _preprocessing = []
+ _prefix = environment(PREFIX_ENV, DEFAULT_PREFIX)
+ _pseudo = environment(PSEUDO_ENV, None)
+ _interactive = environment(INTERACTIVE_ENV, False)
+ _extraArguments = environment(OPTIONS_ENV)
+ _binary = -1 # negative for not, 0 for default size, positive for size
+ _unicode = environment(UNICODE_ENV, False)
+ _unicodeInputEncoding = environment(INPUT_ENCODING_ENV, None)
+ _unicodeOutputEncoding = environment(OUTPUT_ENCODING_ENV, None)
+ _unicodeInputErrors = environment(INPUT_ERRORS_ENV, None)
+ _unicodeOutputErrors = environment(OUTPUT_ERRORS_ENV, None)
+ _hooks = []
+ _pauseAtEnd = False
+ _relativePath = False
+ if _extraArguments is not None:
+ _extraArguments = _extraArguments.split()
+ args = _extraArguments + args
+ # Parse the arguments.
+ pairs, remainder = getopt.getopt(args, 'VhHvkp:m:frino:a:buBP:I:D:E:F:', ['version', 'help', 'extended-help', 'verbose', 'null-hook', 'suppress-errors', 'prefix=', 'no-prefix', 'module=', 'flatten', 'raw-errors', 'interactive', 'no-override-stdout', 'binary', 'chunk-size=', 'output=' 'append=', 'preprocess=', 'import=', 'define=', 'execute=', 'execute-file=', 'buffered-output', 'pause-at-end', 'relative-path', 'no-callback-error', 'no-bangpath-processing', 'unicode', 'unicode-encoding=', 'unicode-input-encoding=', 'unicode-output-encoding=', 'unicode-errors=', 'unicode-input-errors=', 'unicode-output-errors='])
+ for option, argument in pairs:
+ if option in ('-V', '--version'):
+ sys.stderr.write("%s version %s\n" % (__program__, __version__))
+ return
+ elif option in ('-h', '--help'):
+ usage(False)
+ return
+ elif option in ('-H', '--extended-help'):
+ usage(True)
+ return
+ elif option in ('-v', '--verbose'):
+ _hooks.append(VerboseHook())
+ elif option in ('--null-hook',):
+ _hooks.append(Hook())
+ elif option in ('-k', '--suppress-errors'):
+ _options[EXIT_OPT] = False
+ _interactive = True # suppress errors implies interactive mode
+ elif option in ('-m', '--module'):
+ _pseudo = argument
+ elif option in ('-f', '--flatten'):
+ _options[FLATTEN_OPT] = True
+ elif option in ('-p', '--prefix'):
+ _prefix = argument
+ elif option in ('--no-prefix',):
+ _prefix = None
+ elif option in ('-r', '--raw-errors'):
+ _options[RAW_OPT] = True
+ elif option in ('-i', '--interactive'):
+ _interactive = True
+ elif option in ('-n', '--no-override-stdout'):
+ _options[OVERRIDE_OPT] = False
+ elif option in ('-o', '--output'):
+ _output = argument, 'w', _options[BUFFERED_OPT]
+ elif option in ('-a', '--append'):
+ _output = argument, 'a', _options[BUFFERED_OPT]
+ elif option in ('-b', '--buffered-output'):
+ _options[BUFFERED_OPT] = True
+ elif option in ('-B',): # DEPRECATED
+ _options[BUFFERED_OPT] = True
+ elif option in ('--binary',):
+ _binary = 0
+ elif option in ('--chunk-size',):
+ _binary = int(argument)
+ elif option in ('-P', '--preprocess'):
+ _preprocessing.append(('pre', argument))
+ elif option in ('-I', '--import'):
+ for module in argument.split(','):
+ module = module.strip()
+ _preprocessing.append(('import', module))
+ elif option in ('-D', '--define'):
+ _preprocessing.append(('define', argument))
+ elif option in ('-E', '--execute'):
+ _preprocessing.append(('exec', argument))
+ elif option in ('-F', '--execute-file'):
+ _preprocessing.append(('file', argument))
+ elif option in ('-u', '--unicode'):
+ _unicode = True
+ elif option in ('--pause-at-end',):
+ _pauseAtEnd = True
+ elif option in ('--relative-path',):
+ _relativePath = True
+ elif option in ('--no-callback-error',):
+ _options[CALLBACK_OPT] = True
+ elif option in ('--no-bangpath-processing',):
+ _options[BANGPATH_OPT] = False
+ elif option in ('--unicode-encoding',):
+ _unicodeInputEncoding = _unicodeOutputEncoding = argument
+ elif option in ('--unicode-input-encoding',):
+ _unicodeInputEncoding = argument
+ elif option in ('--unicode-output-encoding',):
+ _unicodeOutputEncoding = argument
+ elif option in ('--unicode-errors',):
+ _unicodeInputErrors = _unicodeOutputErrors = argument
+ elif option in ('--unicode-input-errors',):
+ _unicodeInputErrors = argument
+ elif option in ('--unicode-output-errors',):
+ _unicodeOutputErrors = argument
+ # Set up the Unicode subsystem if required.
+ if (_unicode or
+ _unicodeInputEncoding or _unicodeOutputEncoding or
+ _unicodeInputErrors or _unicodeOutputErrors):
+ theSubsystem.initialize(_unicodeInputEncoding,
+ _unicodeOutputEncoding,
+ _unicodeInputErrors, _unicodeOutputErrors)
+ # Now initialize the output file if something has already been selected.
+ if _output is not None:
+ _output = AbstractFile(*_output)
+ # Set up the main filename and the argument.
+ if not remainder:
+ remainder.append('-')
+ filename, arguments = remainder[0], remainder[1:]
+ # Set up the interpreter.
+ if _options[BUFFERED_OPT] and _output is None:
+ raise ValueError("-b only makes sense with -o or -a arguments")
+ if _prefix == 'None':
+ _prefix = None
+ if (_prefix and isinstance(_prefix, _str) and len(_prefix) != 1):
+ raise Error("prefix must be single-character string")
+ interpreter = Interpreter(output=_output,
+ argv=remainder,
+ prefix=_prefix,
+ pseudo=_pseudo,
+ options=_options,
+ hooks=_hooks)
+ try:
+ # Execute command-line statements.
+ i = 0
+ for which, thing in _preprocessing:
+ if which == 'pre':
+ command = interpreter.file
+ target = theSubsystem.open(thing, 'r')
+ name = thing
+ elif which == 'define':
+ command = interpreter.string
+ if thing.find('=') >= 0:
+ target = '%s{%s}' % (_prefix, thing)
+ else:
+ target = '%s{%s = None}' % (_prefix, thing)
+ name = '<define:%d>' % i
+ elif which == 'exec':
+ command = interpreter.string
+ target = '%s{%s}' % (_prefix, thing)
+ name = '<exec:%d>' % i
+ elif which == 'file':
+ command = interpreter.string
+ name = '<file:%d (%s)>' % (i, thing)
+ target = '%s{exec(open("""%s""").read())}' % (_prefix, thing)
+ elif which == 'import':
+ command = interpreter.string
+ name = '<import:%d>' % i
+ target = '%s{import %s}' % (_prefix, thing)
+ else:
+ assert 0
+ interpreter.wrap(command, (target, name))
+ i += 1
+ # Now process the primary file.
+ interpreter.ready()
+ if filename == '-':
+ if not _interactive:
+ name = '<stdin>'
+ path = ''
+ file = sys.stdin
+ else:
+ name, file = None, None
+ else:
+ name = filename
+ file = theSubsystem.open(filename, 'r')
+ path = os.path.split(filename)[0]
+ if _relativePath:
+ sys.path.insert(0, path)
+ if file is not None:
+ if _binary < 0:
+ interpreter.wrap(interpreter.file, (file, name))
+ else:
+ chunkSize = _binary
+ interpreter.wrap(interpreter.binary, (file, name, chunkSize))
+ # If we're supposed to go interactive afterwards, do it.
+ if _interactive:
+ interpreter.interact()
+ finally:
+ interpreter.shutdown()
+ # Finally, if we should pause at the end, do it.
+ if _pauseAtEnd:
+ try:
+ _input()
+ except EOFError:
+ pass
+
+def main():
+ invoke(sys.argv[1:])
+
+if __name__ == '__main__': main()
--- /dev/null
+#! This line however will appear (not the first line in the script).
+This is text. It should appear in the processed output.
+This is a literal at sign: @.
+This is a line continuation; this will appear on the same line.
+Note that it will actually eat any whitespace (one word).
+
+This will appear on one line.
+This will appear on a separate line.
+This is separated by a tab: See?
+These are uppercase As (presuming ASCII): A, A, A, A, A.
+This is more text.
+
+The basics: The square of 4 is 16, or 16.
+Internal whitespace is fine: 4 squared is 16.
+Statements: 4**2 = 16.
+Whitespace too: 4**2 = 16 (still).
+But only on single-line statement expansions.
+Internal whitespace on multi-line statements is significant.
+Normal Python indentation rules must be followed here.
+Normal Python indentation rules must be followed here.
+Simple expressions: x is 4, l is [3, 2, 1], s is "alpha," and 4 squared is 16.
+Literals too: x is 4, but would be written @x.
+Trailing dots are ignored: The value of x is 4.
+Quotes outside of expansions are also ignored: This is quoted: "x is 4."
+Array subscription: The first element of l is 3.
+But this is not: The first element of l is not [3, 2, 1] [0].
+That was equivalent to: [3, 2, 1] and then [0], not 3.
+But whitespace can go inside the brackets: 3 is 3.
+Same with functions: 16 is 16.
+The same applies to the other forms.
+Involved: The contained value is 3.
+More involved: The square of the contained value is 9.
+Following expressions: Pluralize "book" as "books," or maybe "books."
+By default str is used (alpha), but you can use repr if you want ('alpha').
+Conditional expressions: x is true.
+Pluralization: How many words? 4 words.
+Protected expressions: foo is not defined.
+Also here, whitespace isn't important: bar isn't defined either.
+The math module has been imported.
+The re module has not been imported.
+Division by zero is illegal.
+To swallow errors, use None: [two spaces].
+This is self-expanding: @:2 + 2:4:
+You can expand multiple times: @:2 + 2:4:
+
+c's class is C.
+c's name is empy.
+Method call: Hello, empy.
+Note that None is not expanded: [two spaces].
+But the string 'None' is, of course, printed fine: None.
+So a function can return None for side effects only: Hello, empy.
+
+If: a is positive.
+If/else: b is negative.
+If/elif/else: cmp(a, b) is positive.
+Numbers: 0 1 2 3 4 5 6 7 8 9.
+Evens: 0 2 4 6 8.
+Integers less than 5: 0 1 2 3 4.
+Countdown: 10 9 8 7 6 5 4 3 2 1 0.
+While/else: works.
+For/else: 0 1 2 also works.
+Tuple unpacking: <1> <2> <3> <4>.
+Tuple unpacking: <1> <2> <3> <4>.
+Tuple unpacking: <1> <2> <3> <4>.
+Tuple unpacking: <1, 2> <3, 4>.
+Tuple unpacking: <1, 2> <3, 4>.
+Tuple unpacking: <1, 2> <3, 4>.
+Tuple unpacking: <1, 2> <3, 4>.
+Tuple unpacking: <1, 2> <3, 4>.
+Tuple unpacking: <1, 2> <3, 4>.
+Tuple unpacking: <1, 2> <3, 4>.
+Tuple unpacking: <1, 2> <3, 4>.
+More tuple unpacking: <1, 2> <3, 4>.
+Garbage is not defined.
+Division by zero is illegal.
+Catch all: something happened.
+Finally works: finally, and caught.
+Define: 5 is positive, -3 is negative, 0 is zero.
+
+A. This text is undiverted.
+B. This text is also undiverted.
+C. This text is diverted.
+D. Again, this text is undiverted.
+E. This text is diverted and then undiverted.
+E. This text is diverted and then undiverted (this should appear twice).
+F. This text is diverted and then cancelled.
+G. This text is again undiverted.
+H. There should be one remaining diversion: ['x'].
+I. But not after purging it: [].
+J. This should be the final diversion, created manually.
+
+Blanks: , , , .
+Single quotes: ', ', '.
+Double quotes: ", ", ".
+Triple quotes: """, """, ''', '''.
+Quotes surrounded by spaces: " , ' .
+At signs: @, @, @, @.
+Close parentheses: ), ), ), ).
+Close parentheses in quotes: ')', ')'.
+Close braces with an intervening space: } }.
+Repr of a backquote: '`'.
+Exes: x, x, x, x, x.
+Dollar signs: $, $, $.
+These are strings:
+single quoted string
+double quoted string
+single quoted string with escaped 'single quotes'
+double quoted string with escaped "double quotes"
+triple single quoted string
+triple double quoted string
+single quoted string with "double quotes"
+double quoted string with 'single quotes'
+triple single quoted continued string
+triple double quoted continued string
+triple single quoted
+...multi-line string
+triple double quoted
+... multi-line string
+
+Encountered significators:
+a and b should be None: None, None
+c and d should be 'x': 'x', 'x'
+e and f should be 'x y': 'x y', 'x y'
+
+This line should be in mixed case.
+this line should be all lowercase.
+THIS LINE SHOULD BE ALL UPPERCASE (HOW GAUCHE).
+[This line should be bracketed.]
+[So should this line.]
+*There* shou*ld be* star*s eve*ry fi*ve ch*aract*ers o*n thi*s lin*e.
+This line should be back to mixed case.
+[THIS LINE SHOULD BE ALL UPPERCASE WITH BRACKETS.]
+This line should be back to mixed case (again).
+
+The new context is sample.em:264.
+File inclusion [sample.em:265]: 2 + 2 = 4 [<<class 'FakeFile'>>:1].
+Expansion [sample.em:266]: This should be appear [<expand>:1] on the same line as this [sample.em:268].
+More expansion [sample.em:269]: Another expansion [<expand>:1].
+This is the next line [sample.em:271].
+Quoting: x when quoted would be '@x' or @@x.
+More quoting: This will be @@doubled but '''@this is not'''.
+Here's the last view of the old context: sample.em:274.
+Creating a new context ...
+The current context is: <unnamed>:1.
+The context name should now be 'NewName': NewName:3.
+The line number should now be 1000: NewName:1000.
+Back to the old context: sample.em:277.
+
+Interpreter's q is 1.
+Embedded interpreter's q is 10.
+Interpreter's q is still 1; the embedded interpreter had no effect.
+Standalone expansion: 1 + 1 is 2.
+With locals: 2 + 3 is 5.
+With globals: g's x is 10.
+Still with globals: g's x + 1 is 11.
+g's x is still 10.
+
+Invoking the sample hook: [SampleHook.null invoked].
+
+Using a custom markup: [This appears in brackets].
+Again: [<There are angle brackets in this one>].
+Once more: [This is a right angle bracket in quotes: ">"].
+
+This is the penultimate line.
--- /dev/null
+#! $Id: sample.em 5359 2014-01-23 00:33:57Z max $ $Date: 2014-01-22 16:33:57 -0800 (Wed, 22 Jan 2014) $
+@# Bangpaths are handled properly (the above line will not appear).
+#! This line however will appear (not the first line in the script).
+@# This is a comment. This should not appear in the processed output.
+This is text. It should appear in the processed output.
+This is a literal at sign: @@.
+This is a line continuation; @
+this will appear on the same line.
+Note that it will actually eat any white@ space (one word).
+@{
+# The em.py script has to be somewhere in sys.path!
+import em
+}@
+
+@# Escape codes.
+This will appear on one line.@\nThis will appear on a separate line.
+This is separated by a tab:@\tSee?
+These are uppercase As (presuming ASCII): A, @\q1001, @\o101, @\d065, @\x41.
+@{
+import sys
+# This is just a normal Python comment.
+print("This is more text.")
+}@
+@# Note the @{ ... }@ convention to suppress the newline following the }.
+@# Also note that comments are completely tossed: This is not expanded: @(x).
+
+@# The basics.
+@{
+import sys, math
+x = 4
+s = 'alpha'
+word = "book"
+l = [3, 2, 1]
+def square(n):
+ return n**2
+friends = ['Albert', 'Betty', 'Charles', 'Donald']
+class Container(object):
+
+ def __init__(self, value):
+ self.value = value
+
+ def square(self):
+ return square(self.value)
+c = Container(3)
+}@
+The basics: The square of @(x) is @(x**2), or @(square(x)).
+Internal whitespace is fine: @( x ) squared is @( square(x) ).
+Statements: @{sys.stdout.write("%d**2 = %d" % (x, square(x)))}.
+Whitespace too: @{ sys.stdout.write("%d**2 = %d (still)" % (x, square(x))) }.
+@{
+print("But only on single-line statement expansions.")
+if 1:
+ print("Internal whitespace on multi-line statements is significant.")
+for i in range(2):
+ print("Normal Python indentation rules must be followed here.")
+}@
+Simple expressions: x is @x, l is @l, s is "@s," and @x squared is @square(x).
+Literals too: x is @x, but would be written @@x.
+Trailing dots are ignored: The value of x is @x.
+Quotes outside of expansions are also ignored: This is quoted: "x is @x."
+@# Whitespace is important in simple expressions.
+Array subscription: The first element of l is @l[0].
+But this is not: The first element of l is not @l [0].
+That was equivalent to: @(l) and then [0], not @l[0].
+But whitespace can go inside the brackets: @l[0] is @l[ 0 ].
+Same with functions: @square(x) is @square( x ).
+The same applies to the other forms.
+Involved: The contained value is @c.value.
+More involved: The square of the contained value is @c.square().
+Following expressions: Pluralize "@word" as "@(word)s," or maybe "@word@ s."
+By default str is used (@s), but you can use repr if you want (@`s`).
+Conditional expressions: @(x ? "x is true" ! "x is false").
+Pluralization: How many words? @x word@(x != 1 ? 's').
+Protected expressions: @(foo $ "foo is not defined").
+Also here, whitespace isn't important: @(bar$"bar isn't defined either").
+The math module has @(math ? "been imported" $ "not been imported").
+The re module has @(re ? "been imported" $ "not been imported").
+Division by zero is @(x/0 $ "illegal").
+To swallow errors, use None: @(buh $ None) [two spaces].
+This is self-expanding: @:2 + 2:(this will get replaced with 4):
+You can expand multiple times: @
+@empy.expand("@empy.expand('@:2 + 2:hugalugahglughalug:')")
+
+@# More complex examples, including classes.
+@{
+class C:
+ def __init__(self, name):
+ self.name = name
+
+ def greetString(self):
+ return "Hello, %s" % self.name
+
+ def printGreeting(self):
+ sys.stdout.write("Hello, %s" % self.name) # implicit None return
+
+c = C("empy")
+}@
+c's class is @c.__class__.__name__.
+c's name is @c.name.
+Method call: @c.greetString().
+Note that None is not expanded: @(None) [two spaces].
+But the string 'None' is, of course, printed fine: @('None').
+So a function can return None for side effects only: @c.printGreeting().
+
+@# Control.
+@{
+a = 5 # something positive
+b = -3 # something negative
+z = 0 # zero
+}@
+If: a is @[if a > 0]positive@[end if].
+If/else: b is @[if b > 0]positive@[else]negative@[end if].
+If/elif/else: cmp(a, b) is @
+@[if a < b]negative@[elif a > b]positive@[else]zero@[end if].
+Numbers:@
+@[for i in range(10)] @i@[end for].
+Evens:@
+@[for i in range(10)]@[if i % 2 == 1]@[continue]@[end if] @i@[end for].
+Integers less than 5:@
+@[for i in range(10)]@[if i >= 5]@[break]@[end if] @i@[end for].
+Countdown:@
+@{j = 10}@[while j >= 0] @j@{j = j - 1}@[end while].
+While/else: @[while z]shouldn't get here@[else]works@[end while].
+For/else:@
+@[for i in range(3)] @i@[else] also works@[end for].
+Tuple unpacking:@[for x in [1, 2, 3, 4]] <@x>@[end for].
+Tuple unpacking:@[for x, in [[1], [2], [3], [4]]] <@x>@[end for].
+Tuple unpacking:@[for (x,) in [[1], [2], [3], [4]]] <@x>@[end for].
+Tuple unpacking:@[for x, y in [[1, 2], [3, 4]]] <@x, @y>@[end for].
+Tuple unpacking:@[for (x), (y) in [[1, 2], [3, 4]]] <@x, @y>@[end for].
+Tuple unpacking:@[for (x, y) in [[1, 2], [3, 4]]] <@x, @y>@[end for].
+Tuple unpacking:@[for x, (y) in [[1, 2], [3, 4]]] <@x, @y>@[end for].
+Tuple unpacking:@[for x, (y,) in [[1, [2]], [3, [4]]]] <@x, @y>@[end for].
+Tuple unpacking:@[for (x), y in [[1, 2], [3, 4]]] <@x, @y>@[end for].
+Tuple unpacking:@[for (x,), y in [[[1], 2], [[3], 4]]] <@x, @y>@[end for].
+Tuple unpacking:@[for (x,), (y,) in [[[1], [2]], [[3], [4]]]] <@x, @y>@[end for].
+More tuple unpacking:@[for (((x))), ((y),) in [[1, [2]], [3, [4]]]] <@x, @y>@[end for].
+Garbage is @[try]@hglhagulahguha@[except NameError]not defined@[end try].
+Division by zero is @[try]@(a/z)@[except ZeroDivisionError]illegal@[end try].
+Catch all: @[try]@ghlaghlhagl@[except]something happened@[end try].
+Finally works: @
+@[try]@[try]@(1/0)@[finally]finally, @[end try]@[except]and caught@[end try].
+@[def sign(x)]@x is @[if x > 0]positive@[elif x < 0]negative@[else]zero@[end if]@[end def]@
+Define: @sign(a), @sign(b), @sign(z).
+
+@# Diversions. Again, a trailing @ is used to suppress the following newline.
+A. This text is undiverted.
+@empy.startDiversion(1)@
+C. This text is diverted.
+@empy.stopDiverting()@
+B. This text is also undiverted.
+@empy.playDiversion(1)@
+D. Again, this text is undiverted.
+@empy.startDiversion('a')@
+E. This text is diverted and then undiverted@
+@empy.stopDiverting()@
+@empy.replayDiversion('a').
+@empy.playDiversion('a') (this should appear twice).
+@empy.startDiversion('q')@
+F. This text is diverted and then cancelled.
+@empy.playDiversion('q')@
+G. This text is again undiverted.
+@empy.startDiversion('x')@
+X. This text will be purged and should not appear!
+@empy.stopDiverting()@
+H. There should be one remaining diversion: @empy.getAllDiversions().
+@empy.purgeDiversion('x')@
+I. But not after purging it: @empy.getAllDiversions().
+@{
+# Finally, make a manual diversion and manipulate it.
+empy.createDiversion('z')
+zDiversion = empy.retrieveDiversion('z')
+zDiversion.write("J. This should be the final diversion, created manually.\n")
+empy.playDiversion('z')
+}@
+
+@# Parsing checks.
+Blanks: @(''), @(""), @(''''''), @("""""").
+Single quotes: @('\''), @("'"), @("""'""").
+Double quotes: @("\""), @('"'), @('''"''').
+Triple quotes: @("\"\"\""), @('"""'), @('\'\'\''), @("'''").
+Quotes surrounded by spaces: @(""" " """), @(''' ' ''').
+At signs: @('@'), @("@"), @('''@'''), @("""@""").
+Close parentheses: @(')'), @(")"), @((")")), @((')')).
+Close parentheses in quotes: @("')'"), @('\')\'').
+Close braces with an intervening space: @
+@{sys.stdout.write("}")} @{sys.stdout.write('}')}.
+Repr of a backquote: @`'`'`.
+Exes: @("?"?'x'), @(0?"!"!'x'), @(0?":":'x'), @("]"?'x'), @(1?"x"!"]").
+Dollar signs: @("$"$None), @(asdf?"$"$"$"), @(1?asdf$"$").
+These are strings:
+@'single quoted string'
+@"double quoted string"
+@'single quoted string with escaped \'single quotes\''
+@"double quoted string with escaped \"double quotes\""
+@'''triple single quoted string'''
+@"""triple double quoted string"""
+@'single quoted string with "double quotes"'
+@"double quoted string with 'single quotes'"
+@'''triple single quoted continued \
+string'''
+@"""triple double quoted continued \
+string"""
+@'''triple single quoted
+...multi-line string'''
+@"""triple double quoted
+... multi-line string"""
+
+@# Significators.
+@%a
+@%b
+@%c "x"
+@%d "x"
+@%e "x y"
+@%f "x y"
+Encountered significators:
+a and b should be None: @`__a__`, @`__b__`
+c and d should be 'x': @`__c__`, @`__d__`
+e and f should be 'x y': @`__e__`, @`__f__`
+
+@# Filters.
+This line should be in mixed case.
+@empy.setFilter(lambda x: x.lower())@
+This line should be all lowercase.
+@empy.setFilter(lambda x: x.upper())@
+This line should be all uppercase (how gauche).
+@empy.setFilter([em.LineBufferedFilter(), lambda x: '[%s]\n' % x[:-1]])@
+This line should be bracketed.
+So should this line.
+@empy.setFilter([em.SizeBufferedFilter(5), lambda x: '*' + x])@
+There should be stars every five characters on this line.
+@empy.nullFilter()@
+This line should not appear at all!
+@empy.resetFilter()@
+This line should be back to mixed case.
+@empy.attachFilter(lambda x: x.upper())@
+@empy.attachFilter(em.LineBufferedFilter())@
+@empy.attachFilter(lambda x: '[%s]\n' % x[:-1])@
+This line should be all uppercase with brackets.
+@empy.resetFilter()@
+This line should be back to mixed case (again).
+
+@# Contexts, metaoperations.
+@{
+class FakeFile(object):
+
+ def __init__(self, line):
+ self.lines = [line]
+
+ def read(self):
+ return '\n'.join(self.lines) + '\n'
+
+ def readline(self):
+ if self.lines:
+ return self.lines.pop(0)
+ else:
+ return ''
+
+ def close(self): pass
+def context():
+ return "%s:%d" % empy.identify()
+stringFile = FakeFile("2 + 2 = @(2 + 2) [@context()].\n")
+}@
+The new context is @context().
+File inclusion [@context()]: @empy.include(stringFile)@
+Expansion [@context()]: @
+@empy.expand("This should be appear [@context()]") @
+on the same line as this [@context()].
+More expansion [@context()]: @
+@{sys.stdout.write(empy.expand("Another expansion [@context()]"))}.
+This is the next line [@context()].
+Quoting: @empy.quote("x when quoted would be '@x' or @x").
+More quoting: @empy.quote("This will be @doubled but '''@this is not'''").
+Here's the last view of the old context: @context().
+Creating a new context ...
+@empy.pushContext()@
+The current context is: @context().
+@?NewName
+The context name should now be 'NewName': @context().
+@!1000
+The line number should now be 1000: @context().
+@empy.popContext()@
+Back to the old context: @context().
+
+@# Embedded interpreters and standalone expansion.
+@{
+q = 1
+}@
+Interpreter's q is @q.
+@{
+try:
+ i = em.Interpreter()
+ i.string("@{q = 10}")
+ i.string("Embedded interpreter's q is @q.\n")
+finally:
+ i.shutdown()
+}@
+Interpreter's q is still @q; the embedded interpreter had no effect.
+Standalone expansion: @em.expand("1 + 1 is @(1 + 1).")
+With locals: @em.expand("@x + @y is @(x + y).", x=2, y=3)
+@{
+g = {}
+}@
+With globals: @em.expand("@{x = 10}g's x is @x.", g)
+Still with globals: @em.expand("g's x + 1 is @(x + 1).", g)
+g's x is still @g['x'].
+
+@# Hooks.
+@{
+class SampleHook(em.Hook):
+ def null(self):
+ self.interpreter.write('[SampleHook.null invoked]')
+
+sampleHook = SampleHook()
+empy.addHook(sampleHook)
+}@
+Invoking the sample hook: @empy.invokeHook('null').
+@{
+empy.removeHook(sampleHook)
+}@
+
+@# Custom.
+@{
+def customCallback(contents, empy=empy):
+ empy.write('[%s]' % contents)
+empy.registerCallback(customCallback)
+}@
+Using a custom markup: @<This appears in brackets>.
+Again: @<<There are angle brackets in this one>>.
+Once more: @<This is a right angle bracket in quotes: ">">.
+@{
+empy.deregisterCallback()
+}@
+
+@# Finals; note these are evaluated in reverse order.
+@empy.atExit(lambda: empy.write("This is the penultimate line.\n"))@
--- /dev/null
+#!/usr/bin/env python
+#
+# $Id: setup.py.pre 3116 2004-01-14 02:53:02Z max $ $Date: 2004-01-13 18:53:02 -0800 (Tue, 13 Jan 2004) $
+
+from distutils.core import setup
+
+DESCRIPTION = "A templating system for Python."
+
+LONG_DESCRIPTION = """\
+ EmPy is a system for embedding Python expressions and statements
+ in template text; it takes an EmPy source file, processes it, and
+ produces output. This is accomplished via expansions, which are
+ special signals to the EmPy system and are set off by a special
+ prefix (by default the at sign, '@'). EmPy can expand arbitrary
+ Python expressions and statements in this way, as well as a
+ variety of special forms. Textual data not explicitly delimited
+ in this way is sent unaffected to the output, allowing Python to
+ be used in effect as a markup language. Also supported are "hook"
+ callbacks, recording and playback via diversions, and dynamic,
+ chainable filters. The system is highly configurable via command
+ line options and embedded commands.
+"""
+
+setup(
+ name="empy",
+ version="3.3.2",
+ author="Erik Max Francis",
+ author_email="software@alcyone.com",
+ url="http://www.alcyone.com/software/empy",
+ license="%LICENSE",
+ py_modules=["em", "emlib"],
+ platforms=["unix", "linux", "win32"],
+ description=DESCRIPTION,
+ long_description=LONG_DESCRIPTION,
+)
--- /dev/null
+#!/bin/sh
+#
+# $Id: test.sh 5359 2014-01-23 00:33:57Z max $ $Date: 2014-01-22 16:33:57 -0800 (Wed, 22 Jan 2014) $
+
+if [ $# = 1 ]
+then
+ PYTHON="$1"
+else
+ PYTHON=python
+fi
+
+EMPY=em.py
+SAMPLE=sample.em
+BENCH=sample.bench
+
+if $PYTHON -c 'import sys; print(sys.version)' > /dev/null
+then
+ :
+else
+ echo "EmPy was not checked; $PYTHON looks broken." 1>&2
+ exit 1
+fi
+
+if $PYTHON $EMPY $SAMPLE | diff $BENCH -
+then
+ echo "EmPy checks out." 1>&2
+else
+ echo "EmPy does not check out! Please mail output to author." 1>&2
+fi