htmltmpl-1.22/0040775000076400007640000000000007407003263012034 5ustar triptriphtmltmpl-1.22/doc/0040775000076400007640000000000007407003263012601 5ustar triptriphtmltmpl-1.22/doc/examples/0040775000076400007640000000000007407003263014417 5ustar triptriphtmltmpl-1.22/doc/examples/products.html0100664000076400007640000000075707342033601017153 0ustar triptrip Our products

Our products

1 Seagate
2 Conner
3 Maxtor
htmltmpl-1.22/doc/examples/products.py0100664000076400007640000000316307344073045016641 0ustar triptrip import MySQLdb import MySQLdb.cursors from htmltmpl import TemplateManager, TemplateProcessor # Define some constants. DB = "test" USER = "" PASSWD = "" TABLE = """ CREATE TABLE IF NOT EXISTS Products ( id INTEGER NOT NULL AUTO_INCREMENT, name VARCHAR(255) NOT NULL, CONSTRAINT pkey_id PRIMARY KEY(id) ) """ template = TemplateManager().prepare("products.tmpl") tproc = TemplateProcessor() # Assign a string to template variable named "title". tproc.set("title", "Our products") # Connect the database. Create the table. db = MySQLdb.connect(db = DB, user = USER, passwd = PASSWD, cursorclass = MySQLdb.cursors.DictCursor) create_cur = db.cursor() create_cur.execute(TABLE) create_cur.close() # Insert some data. insert_cur = db.cursor() insert_cur.executemany(""" INSERT INTO Products (name) VALUES (%(name)s) """, [ {"name": "Seagate"}, {"name": "Conner"}, {"name": "Maxtor"} ]) insert_cur.close() # Select the products. products_cur = db.cursor() products_cur.execute(""" SELECT id, name FROM Products """) # Append product data in form of mappings (dictionaries) to the # products list. products = [] for i in range(products_cur.rowcount): products.append(products_cur.fetchone()) products_cur.close() db.close() # Assign the products list to template loop identifier 'Products'. # NOTE: htmltmpl automatically converts all the values # to strings using str(). tproc.set("Products", products) # Process the template and print the result. print tproc.process(template) htmltmpl-1.22/doc/examples/products.tmpl0100664000076400007640000000054407342033601017155 0ustar triptrip <TMPL_VAR title>

Our products

htmltmpl-1.22/doc/examples/template.html0100664000076400007640000000115307344073045017122 0ustar triptrip Our customers

Customers:

Total: 2

old customer 1 Joe Sixpack Los Angeles
new customer 2 Paul Newman New York
htmltmpl-1.22/doc/examples/template.py0100664000076400007640000000124507344073045016610 0ustar triptrip from htmltmpl import TemplateManager, TemplateProcessor # Compile or load already precompiled template. template = TemplateManager().prepare("template.tmpl") tproc = TemplateProcessor() # Set the title. tproc.set("title", "Our customers") # Create the 'Customers' loop. customers = [] # First customer. customer = {} customer["name"] = "Joe Sixpack" customer["city"] = "Los Angeles" customer["new"] = 0 customers.append(customer) # Second customer. customer = {} customer["name"] = "Paul Newman" customer["city"] = "New York" customer["new"] = 1 customers.append(customer) tproc.set("Customers", customers) # Print the processed template. print tproc.process(template) htmltmpl-1.22/doc/examples/template.tmpl0100664000076400007640000000127507344073045017137 0ustar triptrip <TMPL_VAR title>

Customers:

Total:

### this comment will be removed
new customer old customer
htmltmpl-1.22/doc/easydoc-api.html0100664000076400007640000001771307400313515015670 0ustar triptrip easydoc: documentation

easydoc

A module to autogenerate HTML documentation from docstrings.

VERSION: 1.01

AUTHOR: Tomas Styblo (tripie@cpan.org)

WEBSITE: http://htmltmpl.sourceforge.net/

LICENSE: GNU GPL

The documentation of this module can be found in 'doc' directory of the distribution tarball or at the website of this package. Latest versions of this module are also available at that website.

You can use and redistribute this module under conditions of the GNU General Public License that can be found either at http://www.gnu.org/ or in file "LICENSE" contained in the distribution tarball of this module.

Copyright (c) 2001 Tomas Styblo, tripie@cpan.org Prague, the Czech Republic


REQUIRES:


CLASSES:



CLASS: Easydoc

Autogenerate documentation from docstrings.

This class provides all the functionality of easydoc. You can subclass it and override its processing methods module(), mclass() and method() to customize its behaviour.

You also can easily use your own template to modify the output in any way you need. Output colors can be customized via parameters.

METHODS:

        process     Create documentation for a module.
        __init__     Constructor.

METHOD: process()

Create documentation for a module. (class Easydoc)

RETURN VALUE:

String containing the resulting HTML documentation.

PARAMETERS:

process(module, bgcolor, textcolor, linkcolor, with_hidden=0)

METHOD: __init__()

Constructor. (class Easydoc)

PARAMETERS:

__init__(template, debug=0)


htmltmpl-1.22/doc/easydoc.html0100664000076400007640000002176207400327060015120 0ustar triptrip htmltmpl - easydoc
htmltmpl: templating engine for separation of code and HTML

Easydoc is an example application that uses htmltmpl to provide flexible HTML output. It can process docstrings embedded in source file of a module and generate proper XHTML documentation from them. It's very similar to the javadoc program used by Java applications. The API documentation for htmltmpl and easydoc itself is auto-generated by easydoc.

The purpose of the program is to ease maintenance of documentation. It's very annoying to maintain more versions of documentation at once - docstrings in a source file and a HTML form of them which is much more convenient for common users. After a while the two versions always fail to be synchronized and become a maintenance nightmare.

The solution is to maintain the documentation only in form of docstrings in the source code and generate the HTML version automatically from them.

Of course, many other solutions exist for this purpose. This program was created to be similar to javadoc and as a test application for htmltmpl. The default template it uses is quite complex; it contains loops which are nested four levels deep. You can replace the default template with your own one to customize the output.

Easydoc is now part of the htmltmpl distribution and is automatically installed when you install htmltmpl. There also is a script called easy.py which provides command line interface to the module. It's included in the distribution. Run it without any parameters to view usage instructions.

The API documentation of the easydoc module can be found here.


Explanation and example

This example documented module illustrates and describes the special syntax of docstrings which easydoc requires. The syntax is similar to that of javadoc.


""" Short one line description of the module.

    Detailed description of the module which can span more lines. You can
    use HTML tags here, but you should use only in-line tags which will not
    break the page. Do NOT use <p> or <br> tags to separate
    paragraphs. Instead use empty lines which are automatically converted
    to paragraph separators. HTML brackets which are not part of a tag
    should be written as appropriate HTML entities. All strings in form
    [ http://some.url.com ] are automatically converted to
    hyperlinks.
    
    After the detailed description comes the 'meta' section which should be
    used to give the docstring processor some structured information about
    the section which is being documented. It uses special statements which
    begin with the '@' character. This character is ignored if it isn't the
    first non-whitespace character on a line. URLs in parameters that
    specify an URL should _NOT_ be written in the special hyperlink form
    described above.

    @name             easydoc
    @version          1.00
    @website          http://htmltmpl.sourceforge.net/
    @author-name      Tomas Styblo
    @author-email     tripie@cpan.org
    @license-name     GNU GPL
    @license-url      http://www.gnu.org/licenses/gpl.html
    @require          htmltmpl ([ http://htmltmpl.sourceforge.net ])
    @require          some other prerequisite ...
"""

class Example:
    """ One line description of the class. End it with a dot if appropriate.

    Detailed description which can span more lines. You can use HTML tags
    here, but you should use only in-line tags which will not break the page.
    Do NOT use <p> or <br> tags to separate paragraphs. Instead
    use empty lines which are automatically converted to paragraph separators.
    HTML brackets which are not part of a tag should be written as appropriate
    HTML entities. Code examples must be placed inside a <pre> block.
    
    After the detailed description comes the 'meta' section which should
    be used to give the docstring processor some structured information
    about the section which is being documented. It uses special statements
    which begin with the '@' character. This character is ignored if it isn't
    the first non-whitespace character on a line.
    
    @hidden The meta section can contain some special processing instructions.
    The @hidden instruction can be used to exclude the section which is being
    documented from the resulting documentation. This is useful for private
    classes and methods.
    
    The sections marked as hidden can be included in the output if you use
    the '--with-hidden' command line option of easydoc.
    """
    
    def method(param1, param2=""):
        """ Short one line description of the method.
        
        Detailed description of the method. Same rules as for detailed
        descriptions of classes apply here.
        
        The header statement below must contain a full header of the method,
        as it appears in the code. It's used for quick overview of the
        method's parameters and their default values. Do not include the
        self parameter of methods here.

        @return Short one line description of return value.
        Here comes detailed description of the return value. It can span
        more lines and contain appropriate HTML markup. You should explicitly
        document cases when the method has no return value.

        @header
        method(param1, param2="")

        @param param1 One Line description of parameter.
        More detailed description of the 'param' parameter which again can
        span  more lines and contain HTML tags. These detailed descriptions
        are terminated by either end of the docstring or by another statement.
        
        The detailed descriptions also can consist of more paragraphs
        separated by an empty line.
        
        @param param2 One line description of parameter.
        Detailed description of the second parameter.
         
        @hidden This statement has the same meaning as in classes.
        """
    
htmltmpl-1.22/doc/gettext.html0100664000076400007640000001625307400324463015160 0ustar triptrip htmltmpl templating engine
htmltmpl: templating engine for separation of code and HTML

This section is a description of the gettext support integrated in htmltmpl. It's of interest for anyone who would like to use htmltmpl to easily build a multilingual web application.

The section describes only the gettext support in htmltmpl. Please refer to other sources for general info on gettext and its principles. The info manual for gettext should be included in every modern UNIX distribution.

The gettext support in htmltmpl must be explicitely activated by setting the parameter 'gettext' of TemplateManager or TemplateCompiler constructor to TRUE.

The support will not work if your computer's locale system is not installed properly or if your Python or PHP interpreter is not configured to support locales and gettext. In Python, gettext support is part of the standard library. PHP must be compiled using the '--with-gettext' parameter, otherwise an attempt to use htmltmpl in gettext mode will result in a "call to undefined function" error.


Syntax

In the templates, all text which should be translated by gettext must be enclosed in double brackets. Example:

    <TMPL_LOOP Test>
    [[Product]]: <TMPL_VAR product><br>
    [[Price]]: <TMPL_VAR price><br>
    </TMPL_LOOP>
    

The brackets will be removed when the template is processed. If you need to include opening brackets somewhere in the text of the template, you can escape them using a backslash. In the following example the brackets will not be removed and the word 'jumps' will not be translated. The backslash will be removed always and only when it is placed right before opening or closing double brackets.

    Quick brown fox \[[jumps]] over a lazy dog.
    Sometimes we need to use the backslash '\'.

    ... will be printed as:

    Quick brown fox [[jumps]] over a lazy dog.
    Sometims we need to use the backslash '\'.
    

In some rare cases you need to print a backslash right before double brackets. You can use another backslash to escape the backslash. In that case, one backslash will be printed and the translation will take place. In the following example the word 'jumps' will be translated:

    Quick brown fox \\[[jumps]] over a lazy dog.

    ... will be printed as:

    Quick brown fox \jumps over a lazy dog.
    

The backslash can also be used to include closing double brackets in a text which should be translated. In the following example, the double brackets are taken as a part of the text to be translated. That means, the whole text 'jumps over ]] a lazy' will be translated.

    Quick brown fox [[jumps over \]] a lazy]] dog.
    

A backslash always escapes another backslash. That means that to print two backslashes, you must write four of them. An example:

    This will print one backslash: \.
    This will print one backslash: \\.
    This will print two backslashes: \\\\.

    ... will be printed as:

    This will print one backslash: \.
    This will print one backslash: \.
    This will print two backslashes: \\.
    

tmpl-xgettext

The gettext strings must usually be extracted using the xgettext program. The standard xgettext program cannot work with htmltmpl templates, though. You must use the tmpl-xgettext.pl script which is included in htmltmpl distribution to convert the templates into a format which xgettext can understand.

    cat template.tmpl | perl tmpl-xgettext.pl | xgettext -o file.po -
    

Programming

Your program must initialize gettext before it calls the process() method of TemplateProcessor. It usually means to call setlocale(), bindtextdomain() and textdomain() with appropriate parameters. Check documentation of PHP or Python gettext extensions for more information.

Also, your program is of course responsible for translation of any texts which are assigned as values to TMPL_VARs.

htmltmpl-1.22/doc/index.html0100664000076400007640000001744007406735714014615 0ustar triptrip htmltmpl templating engine
htmltmpl: templating engine for separation of code and HTML

Current versions:

htmltmpl for Python

easydoc for Python
1.22 2001/12/15 download
htmltmpl for PHP 1.12 2001/12/15 download

The purpose of the templating engine is to provide web application developers, who need to separate program code and design (HTML code) of their web application projects, with a templating tool that can be easily used by cooperating webdesigners who have no programming skills.

Templating language provided by the engine is inspired by Perl templating module HTML::Template. Templates created for HTML::Template can be used with this engine.

The engine is currently available for Python and PHP. The Python package includes easydoc, a module which uses the templating engine to generate HTML documentation from docstrings embedded in source files of Python modules.

The primary goal of the templating engine is to keep things simple for a webdesigner who creates the templates. Therefore, neither Python nor PHP code can be used in the templates. Instead, the templating engine provides its own simple templating language that supports basic programming operations like for example loops, conditionals and substitution of variables. These operations are controlled from within the templates by statements that look like HTML tags and integrate nicely with regular HTML code.

The secondary goal is good performance. High speed template processing is necessary when the engine is used by web applications.

I am aware that other templating solutions for Python and PHP exist. But none of them is similar to HTML::Template. I love its enforcement of strict separation of code and HTML and the style and syntax of its template language. I find it much more cleaner and maintainable than the other solutions. Also, I need to move some projects from Perl to Python and PHP and I want to reuse my old HTML::Template templates. These are the reasons why I created the templating engine.

The engine now also has an integrated support for gettext, which makes it very convenient for development of multilingual "skinnable" web applications.



Author and license

Copyright (c) 2001 Tomas Styblo

Email: tripie@cpan.org

Homepage: http://geocities.com/tripiecz/

Prague, the Czech Republic

You can use and redistribute the engine under conditions of the GNU General Public License that can be found either at http://www.gnu.org/ or in file "LICENSE" contained in the distribution tarball of the engine.

Author of the engine and its documentation is not an English native speaker. Corrections of grammar or spelling are welcome.


Credits

The engine is inspired by Perl templating module HTML::Template created by Sam Tregar (sam@tregar.com). Sam invented the excellent templating language. The htmltmpl implementation, however, was designed from scratch and is not based on code of HTML::Template.

You should check the documentation of HTML::Template. The templating language of htmltmpl is fully compatible with HTML::Template and the documentation of HTML::Template describes it much better than the yet unfinished documentation of htmltmpl.

Documentation of HTML::Template can be found at http://sam.tregar.com/html_template.html


Support

There is a mailing list for htmltmpl on SourceForge. Don't hesitate to post a message if you find a bug, want to contribute a patch or have some interesting idea.

htmltmpl-1.22/doc/lang.html0100664000076400007640000005120307400276175014415 0ustar triptrip htmltmpl templating engine
htmltmpl: templating engine for separation of code and HTML

This is a description of the templating language used by htmltmpl.


HTML::Template compatibility

Templates created for HTML::Template can be used with this engine in case they do not violate character case rules of htmltmpl.

WARNING: Template statements and their parameters must always be in uppercase. Variable names must always be in lowercase. Loop names must be in lowercase, but capitalized.

WARNING: All included templates must be located in a directory named 'inc' which must be a subdirectory of the directory in which the main template file is located. You must refer to these templates only by their filename, ie. without the 'inc' part of the path.

This engine offers all features of HTML::Template except:

The engine also offers some additional features:


Syntax overview

Statements

The control statements of the templating language look like HTML tags. They can be written in two forms:

There must be exactly one space after the opening "<!--" and before the closing "-->" if you use the longer form.

All statements except TMPL_VAR should be placed on a separate line.

All tabs and spaces on a line before a statement are removed, if there are no other characters except tabs and spaces between beginning of the line and the statement.

A trailing newline after a statement is removed if there are no other characters between the newline and the statement.

The white-space removing described above is a Good Thing, because it keeps the HTML nicely formatted, especially when loops are involved. If you want to preserve the newline after a statement, just add a space or a tab after the statement.

The statements do not need to follow HTML validity rules. For example, following usage of TMPL_VAR is absolutely valid:

    
            <img src="<TMPL_VAR image>" />
    

Unrecognized TMPL_* statements are detected and TemplateError is raised when one is found.

Statements must be completely in uppercase: for example "TMPL_VAR". It improves readability of the templates a lot. It makes the statements easily distinguishable from normal XHTML tags, that are always in lowercase.

Templates must not contain the '\0' character (ASCII code zero).


Parameters of the statements

Parameters can be written in two forms:

There must not be any space between the "=" character and the name or the value of the parameter.

Parameter names must be completely in uppercase: ESCAPE="HTML".

Predefined special values of parameters (like for example the "HTML", "URL" and "NONE" values of the ESCAPE parameter) must be completely in uppercase.

Parameter names and values can contain only alphanumeric characters (non-locale) plus some additional characters: dash, dot, underscore, colon, slash, backslash. They must NOT contain any spaces.


Identifiers

There are three types of identifiers:

Names of loops and variables can contain ASCII (non-locale) alphanumeric characters, underscores and dashes. Names of loops and variables are further restricted by the character case rules described below.

Template filenames in TMPL_INCLUDE statements can contain only the same characters that are allowed in values of parameters(see above). They must NOT contain any spaces.

Minimum length of an identifier is one character. Names of variables and loops can be specified in two ways:

Following character case rules apply to the names of variables and loops:


Valid statements and parameters

TMPL_INCLUDE NAME
TMPL_VAR NAME, ESCAPE, GLOBAL
TMPL_IF NAME, GLOBAL
TMPL_UNLESS NAME, GLOBAL
TMPL_ELSE  
/TMPL_IF  
/TMPL_UNLESS  
TMPL_LOOP NAME
/TMPL_LOOP  
TMPL_BOUNDARY  


Template comments

Comments are in form of "### some comment". Everything that follows these four characters - "### " - is removed before the template is processed. The ending space in "### " IS significant. Comments can be disabled using the 'comments' parameter.


Examples:

        <TMPL_VAR myname>    ### first comment
        <TMPL_VAR hisname>   ### second comment
    

Statements

Template inclusion

The <TMPL_INCLUDE> statement includes a template directly into the current template at the point where the statement is found. The included template contents are used exactly as if its contents were physically included in the main template.

All included templates must be located in a directory named 'inc' which must be a subdirectory of the directory in which the main template file is located. You must refer to these templates only by their filename, ie. without the 'inc' part of the path.

Examples:

In this example, the file header.tmpl must be located in the 'inc' subdirectory of the directory in which the main template file is located.

        <TMPL_INCLUDE header.tmpl>
        <TMPL_INCLUDE NAME="header.tmpl">
    

Variables

TODO

Variables defined by the TMPL_VAR statements are substituted with values associated with them by the set() method of TemplateProcessor.

Escaping of variables

All variables are automatically HTML escaped. This can be disabled using the 'html_escape' parameter. Escaping of variables can also be specified on a per variable basis using the ESCAPE parameter. This parameter overrides the default escaping setting. It can have three values:

Global look-up of variables

All variables that are inside a loop are local to that loop. If you want to reference a "global" variable from inside a loop, then you must either enable the 'global_vars' parameter or use the GLOBAL parameter to override 'global_vars' setting on a per variable basis.

Examples:

    <TMPL_VAR name>
    <TMPL_VAR NAME="city">
    <TMPL_VAR NAME="text1" ESCAPE="HTML">
    <TMPL_VAR NAME="text2" ESCAPE="NONE" GLOBAL="0">
    <TMPL_VAR address GLOBAL="1">
    <!-- TMPL_VAR test ESCAPE=URL -->
    

Conditionals

TODO

The TMPL_IF, /TMPL_IF, TMPL_ELSE, TMPL_UNLESS and /TMPL_UNLESS statements are conditionals. They mark start and end of a block that is included in the output only when the condition is true. Only names of variables or loops can be used in the condition. Conditional blocks may contain other nested conditional blocks.

If name of a loop is used in a condition, then the condition is true if the content of the loop will be included in the output at least once.

Examples:

    <TMPL_IF myvar>
        This block appears in the output if myvar is true.
    <TMPL_ELSE>
        This block appears in the output if myvar is false.
    </TMPL_IF>

    <TMPL_UNLESS hisvar>
        This block appears in the output if hisvar is false.
    <TMPL_ELSE>
        This block appears in the output if hisvar is true.
    </TMPL_UNLESS>
    

Loops

TODO

The TMPL_LOOP and /TMPL_LOOP statements mark start and end of a block which is printed once for each mapping in the list of mappings associated with the corresponding loop.

Loops can contain other nested loops. Every loop introduces its own namespace (scope) for variables. Variables located inside a loop cannot reference variables located outside the loop unless the 'global_vars' parameter is true, or unless this parameter is overridden for this variable using the 'GLOBAL' parameter of the corresponding TMPL_VAR statement.

Loop names used as variables in TMPL_VAR statements produce total number of passes in the corresponding loop.

examples

    <TMPL_LOOP Myloop>
        This block appears in the output
        once for every pass of the loop.
        <TMPL_VAR myvar>   ### Local variable.
    </TMPL_LOOP>
    

Magic loop variables

Magic context variables are automatically defined in every loop. They can be used the same way as normal variables. Their names always start with two underscores. Values of these variables are always integers (true = 1, false = 0).

Following list lists all recognized magic variables. Any other variable name which starts with two underscores is invalid. The TemplateError exception is raised when such a variable name is found.

__FIRST__

This variable is true if current pass is the first pass.

__LAST__

This variable is true if current pass is the last pass.

__INNER__

This variable is true if current pass is neither first nor last pass.

__ODD__

This variable is true if number of current pass is odd. That means it's true in the first, third, fifth, seventh ..... pass.

__PASS__

Value of this variable is the number of current pass. Passes are counted from one. Value of this variable is one in the first pass, two in the second pass etc.

__PASSTOTAL__

Value of this variable is total number of passes in current loop.

__EVERY__x

Where 'x' must be an integer. It can consist of more than one digit. This variable is true if number of current pass modulo 'x' equals to zero. The variable is never true in first or last pass, even if the condition above is true in such a pass. This variable can be used to put separators between every 'x' items of a list.


Multipart templates

Multipart templates can be created using the <TMPL_BOUNDARY> directive. This directive has no parameters.

Multipart templates are useful when you need to process and output a part of the template before all data needed to process the whole template are ready.

This can be useful to improve perceived responsiveness of web applications by sending the top part of a page to the client before the web application for example sends a slow query to the database and generates rest of the page from results of the query. Keep in mind that you probably will have to flush the output stream to achieve the desired effect. This can usually be done by calling sys.stdout.flush() in Python or flush() in PHP.

Multipart templates must follow this rule: every part itself must be a syntactically valid template. It means that boundaries between the parts must not be located inside a conditional block or inside a loop block.

The boundaries are processed after template inclusions are processed. It's possible to put the boundaries into the included templates, tough it's not recommended.

Please consult API documentation of the TemplateProcessor.process() method to find out how to correctly use multipart templates in your applications.

examples

    This is part one.
    <TMPL_BOUNDARY>
    This is part two.
    <TMPL_BOUNDARY>    
    This is part three.
    

Example

template.tmpl

<html>
    <head>
        <title><TMPL_VAR title></title>
    </head>
    <body>
        <h1>Customers:</h1>
        <p>
            Total: <TMPL_VAR Customers>
        </p>

        ### this comment will be removed

        <table>
            <TMPL_LOOP Customers>
                <tr>
                    <TMPL_IF new>
                        <td>new customer</td> 
                    <TMPL_ELSE>
                        <td>old customer</td>
                    </TMPL_IF>
                    <td><TMPL_VAR __PASS__></td>
                    <td><TMPL_VAR name></td>
                    <td><TMPL_VAR city></td>
                </tr>
            </TMPL_LOOP>            
        </table>
    </body>
</html>
    
htmltmpl-1.22/doc/main.css0100664000076400007640000000107107342133223014231 0ustar triptrip body { font-family: "Helvetica CE", "Arial CE", Helvetica, Arial, sans-serif; background-color: #d8d0a4; color: black; } a { color: red; font-weight: bold; } .red { color: red; font-weight: bold; } .title { font-size: larger; } .noborder { border-width: 0; } span.keyword { color: #ff0000; font-weight: bold; } /* font-lock-keyword-face */ span.string { color: #008b00; font-weight: bold; } /* font-lock-string-face */ span.comment { color: #00008b; font-style: italic; } /* font-lock-comment-face */ htmltmpl-1.22/doc/makedoc.sh0100775000076400007640000000016107400313521014530 0ustar triptrip#!/bin/sh python ../easy.py ../htmltmpl.py ./python-api.html python ../easy.py ../easydoc.py ./easydoc-api.html htmltmpl-1.22/doc/php.html0100664000076400007640000002021507400260036014247 0ustar triptrip htmltmpl templating engine
htmltmpl: templating engine for separation of code and HTML

This is the PHP version of htmltmpl. This page contains some basic information about the module and examples that illustrate its usage.

A complete documentation of the module's API can be found here. It contains description of all public classes and methods which the module provides. The documentation is automatically generated from docstrings in source file of the Python version of the module. There are some minor differences between the PHP and the Python version. These differences are described later on this page.

The PHP version of the module works on UNIX and Windows platforms. It requires PHP 4.0.6 or newer. If you get strange compilation errors, then your PHP is too old.

The API of the PHP version differs from the Python version in following aspects:

  • Debugging is activated by pointing a global variable $HTMLTMPL_DEBUG to a debugging logfile. No constructor takes the 'debug' parameter in the PHP version.

  • All the factory methods which return an internally constructed Template object return a REFERENCE to it. That means your code must use reference assignments:

    $manager = new TemplateManager();
    $template =& $manager->prepare($template_file);
                  
  • PHP does not support exceptions. The TemplateError exception class does not exist in the PHP version. Instead, all problems are handled via user_error() followed by exit().

The version numbering is mutually independent. The 1.00 release of the PHP version was based on the Python release 1.18.



Examples

Source files of all these examples are available in 'doc/examples' directory of the distribution. Files from the regression test suite (the 'test' directory) can also serve as examples.

simple:

template.tmpl

<html>
    <head>
        <title><TMPL_VAR title></title>
    </head>
    <body>
        <h1>Customers:</h1>
        <p>
            Total: <TMPL_VAR Customers> 
        </p>

        ### this comment will be removed

        <table>
            <TMPL_LOOP Customers>
                <tr>
                    <TMPL_IF new>
                        <td>new customer</td> 
                    <TMPL_ELSE>
                        <td>old customer</td>
                    </TMPL_IF>
                    <td><TMPL_VAR __PASS__></td>
                    <td><TMPL_VAR name></td>
                    <td><TMPL_VAR city></td>
                </tr>
            </TMPL_LOOP>
        </table>
    </body>
</html>
    

template.php

<?
require('htmltmpl.php');

# Compile or load already precompiled template.
$manager = new TemplateManager();
$template =& $manager->prepare("template.tmpl");
$tproc = new TemplateProcessor();

# Set the title.
$tproc->set("title", "Our customers");

# Create the 'Customers' loop. (regular array)
$customers = array();

# First customer (associative array).
$customer = array();
$customer['name'] = 'Joe Sixpack';
$customer['city'] = 'Los Angeles';
$customer['new'] = 0;
array_push($customers, $customer);

# Second customer.
$customer = array();
$customer['name'] = 'Paul Newman';
$customer['city'] = 'New York';
$customer['new'] = 1;
array_push($customers, $customer);

$tproc->set("Customers", $customers);

# Print the processed template.
echo $tproc->process($template);
?>
    

template.html

<html>
    <head>
        <title>Our customers</title>
    </head>
    <body>
        <h1>Customers:</h1>
        <p>
            Total: 2
        </p>



        <table>
            <tr>
                    <td>old customer</td>
                <td>1</td>
                <td>Joe Sixpack</td>
                <td>Los Angeles</td>
            </tr>
            <tr>
                    <td>new customer</td>
                <td>2</td>
                <td>Paul Newman</td>
                <td>New York</td>
            </tr>                
        </table>
    </body>
</html>
    
htmltmpl-1.22/doc/python-api.html0100664000076400007640000011020607400313515015551 0ustar triptrip htmltmpl: documentation

htmltmpl

A templating engine for separation of code and HTML.

VERSION: 1.20

AUTHOR: Tomas Styblo (tripie@cpan.org)

WEBSITE: http://htmltmpl.sourceforge.net/

LICENSE: GNU GPL

The documentation of this templating engine is separated to two parts:

1. Description of the templating language.

2. Documentation of classes and API of this module that provides a Python implementation of the templating language.

All the documentation can be found in 'doc' directory of the distribution tarball or at the homepage of the engine. Latest versions of this module are also available at that website.

You can use and redistribute this module under conditions of the GNU General Public License that can be found either at http://www.gnu.org/ or in file "LICENSE" contained in the distribution tarball of this module.

Copyright (c) 2001 Tomas Styblo, tripie@cpan.org


CLASSES:



CLASS: TemplateProcessor

Fill the template with data and process it.

This class provides actual processing of a compiled template. Use it to set template variables and loops and then obtain result of the processing.

METHODS:

        __init__     Constructor.
        process     Process a compiled template. Return the result as string.
        set     Associate a value with top-level template variable or loop.
        reset     Reset the template data.

METHOD: __init__()

Constructor. (class TemplateProcessor)

PARAMETERS:

__init__(html_escape=1, magic_vars=1, global_vars=0, debug=0)

METHOD: process()

Process a compiled template. Return the result as string. (class TemplateProcessor)

This method actually processes a template and returns the result.

RETURN VALUE:

Result of the processing as string.

PARAMETERS:

process(template, part=None)

METHOD: set()

Associate a value with top-level template variable or loop. (class TemplateProcessor)

A template identifier can represent either an ordinary variable (string) or a loop.

To assign a value to a string identifier pass a scalar as the 'value' parameter. This scalar will be automatically converted to string.

To assign a value to a loop identifier pass a list of mappings as the 'value' parameter. The engine iterates over this list and assigns values from the mappings to variables in a template loop block if a key in the mapping corresponds to a name of a variable in the loop block. The number of mappings contained in this list is equal to number of times the loop block is repeated in the output.

RETURN VALUE:

No return value.

PARAMETERS:

set(var, value)

METHOD: reset()

Reset the template data. (class TemplateProcessor)

This method resets the data contained in the template processor instance. The template processor instance can be used to process any number of templates, but this method must be called after a template is processed to reuse the instance,

RETURN VALUE:

No return value.

PARAMETERS:

reset(keep_data=0)


CLASS: TemplateError

Fatal exception. Raised on runtime or template syntax errors.

This exception is raised when a runtime error occurs or when a syntax error in the template is found. It has one parameter which always is a string containing a description of the error.

All potential IOError exceptions are handled by the module and are converted to TemplateError exceptions. That means you should catch the TemplateError exception if there is a possibility that for example the template file will not be accesssible.

The exception can be raised by constructors or by any method of any class.

The instance is no longer usable when this exception is raised.



CLASS: Template

This class represents a compiled template.

This class provides storage and methods for the compiled template and associated metadata. It's serialized by pickle if we need to save the compiled template to disk in a precompiled form.

You should never instantiate this class directly. Always use the TemplateManager or TemplateCompiler classes to create the instances of this class.

The only method which you can directly use is the is_uptodate method.

METHODS:

        is_uptodate     Check whether the compiled template is uptodate.

METHOD: is_uptodate()

Check whether the compiled template is uptodate. (class Template)

Return true if this compiled template is uptodate. Return false, if the template source file was changed on the disk since it was compiled. Works by comparison of modification times. Also takes modification times of all included templates into account.

RETURN VALUE:

True if the template is uptodate, false otherwise.

PARAMETERS:

is_uptodate(compile_params=None)


CLASS: TemplateCompiler

Preprocess, parse, tokenize and compile the template.

This class parses the template and produces a 'compiled' form of it. This compiled form is an instance of the Template class. The compiled form is used as input for the TemplateProcessor which uses it to actually process the template.

This class should be used direcly only when you need to compile a template from a string. If your template is in a file, then you should use the TemplateManager class which provides a higher level interface to this class and also can save the compiled template to disk in a precompiled form.

METHODS:

        __init__     Constructor.
        compile_string     Compile template from a string.
        compile     Compile template from a file.

METHOD: __init__()

Constructor. (class TemplateCompiler)

PARAMETERS:

__init__(include=1, max_include=5, comments=1, gettext=0, debug=0)

METHOD: compile_string()

Compile template from a string. (class TemplateCompiler)

This method compiles a template from a string. The template cannot include any templates. TMPL_INCLUDE statements are turned into warnings.

RETURN VALUE:

Compiled template. The return value is an instance of the Template class.

PARAMETERS:

compile_string(data)

METHOD: compile()

Compile template from a file. (class TemplateCompiler)

RETURN VALUE:

Compiled template. The return value is an instance of the Template class.

PARAMETERS:

compile(file)


CLASS: TemplateManager

Class that manages compilation and precompilation of templates.

You should use this class whenever you work with templates that are stored in a file. The class can create a compiled template and transparently manage its precompilation. It also keeps the precompiled templates up-to-date by modification times comparisons.

METHODS:

        __init__     Constructor.
        update     Update (recompile) a compiled template.
        prepare     Preprocess, parse, tokenize and compile the template.

METHOD: __init__()

Constructor. (class TemplateManager)

PARAMETERS:

__init__(include=1, max_include=5, precompile=1, comments=1, gettext=0, debug=0)

METHOD: update()

Update (recompile) a compiled template. (class TemplateManager)

This method recompiles a template compiled from a file. If precompilation is enabled then the precompiled form saved on disk is also updated.

RETURN VALUE:

Recompiled template. It's ensured that the returned template is up-to-date.

PARAMETERS:

update(template)

METHOD: prepare()

Preprocess, parse, tokenize and compile the template. (class TemplateManager)

If precompilation is enabled then this method tries to load a precompiled form of the template from the same directory in which the template source file is located. If it succeeds, then it compares modification times stored in the precompiled form to modification times of source files of the template, including source files of all templates included via the TMPL_INCLUDE statements. If any of the modification times differs, then the template is recompiled and the precompiled form updated.

If precompilation is disabled, then this method parses and compiles the template.

RETURN VALUE:

Compiled template. The methods returns an instance of the Template class which is a compiled form of the template. This instance can be used as input for the TemplateProcessor.

PARAMETERS:

prepare(file)


htmltmpl-1.22/doc/python.html0100664000076400007640000003140707400260062015005 0ustar triptrip htmltmpl templating engine
htmltmpl: templating engine for separation of code and HTML

This is the Python version of htmltmpl. This page contains some basic information about the module and examples that illustrate its usage.

A complete documentation of the module's API can be found here. It contains description of all public classes and methods which the module provides. The documentation is automatically generated from docstrings in source file of the module by my application easydoc, which uses htmltmpl and is included in the htmltmpl distribution.

The module should work on all platforms supported by Python. The module is supported by its author only on the UNIX platform using Python versions 2.1 or newer.

Releases 1.15 and up are vastly redesigned to be multi-task safe and more flexible. The design and interface was completely changed to be much more object oriented and more maintainable. The downside of this change is that the interface is no longer similar to that of HTML::Template.

The module is multi-task safe in terms of properly synchronized accesses to the precompiled templates that are loaded from and saved to disk. However, instances of any of its classes should NOT be shared by multiple threads. The only exception are instances of the Template class, which can be shared by multiple threads.

It would be possible to protect all critical data and sections by locks to achieve complete thread safeness, but the resulting overhead probably is not worth the effort. I hardly can imagine a situation in which someone would want or need to share the instances among multiple threads.


Examples

Source files of all these examples are available in 'doc/examples' directory of the distribution. Files from the regression test suite (the 'test' directory) can also serve as examples.

FAQ: Emacs (the 'htmlize-file' command) is used to colorify the source code examples.

simple:

template.tmpl

<html>
    <head>
        <title><TMPL_VAR title></title>
    </head>
    <body>
        <h1>Customers:</h1>
        <p>
            Total: <TMPL_VAR Customers> 
        </p>

        ### this comment will be removed

        <table>
            <TMPL_LOOP Customers>
                <tr>
                    <TMPL_IF new>
                        <td>new customer</td> 
                    <TMPL_ELSE>
                        <td>old customer</td>
                    </TMPL_IF>
                    <td><TMPL_VAR __PASS__></td>
                    <td><TMPL_VAR name></td>
                    <td><TMPL_VAR city></td>
                </tr>
            </TMPL_LOOP>
        </table>
    </body>
</html>
    

template.py

from htmltmpl import TemplateManager, TemplateProcessor

# Compile or load already precompiled template.
template = TemplateManager().prepare("template.tmpl")
tproc = TemplateProcessor()

# Set the title.
tproc.set("title", "Our customers")

# Create the 'Customers' loop.
customers = []

# First customer.
customer = {}
customer["name"] = "Joe Sixpack"
customer["city"] = "Los Angeles"
customer["new"] = 0
customers.append(customer)

# Second customer.
customer = {}
customer["name"] = "Paul Newman"
customer["city"] = "New York"
customer["new"] = 1
customers.append(customer)

tproc.set("Customers", customers)

# Print the processed template.
print tproc.process(template)
    

template.html

<html>
    <head>
        <title>Our customers</title>
    </head>
    <body>
        <h1>Customers:</h1>
        <p>
            Total: 2
        </p>



        <table>
            <tr>
                    <td>old customer</td>
                <td>1</td>
                <td>Joe Sixpack</td>
                <td>Los Angeles</td>
            </tr>
            <tr>
                    <td>new customer</td>
                <td>2</td>
                <td>Paul Newman</td>
                <td>New York</td>
            </tr>                
        </table>
    </body>
</html>
    

MySQL driven:

products.tmpl

<html>
    <head>
        <title><TMPL_VAR title></title>
    </head>
    <body>

    <h1>Our products</h1>

    <table>
        <TMPL_LOOP Products>
            <tr>
                <td><TMPL_VAR id></td>
                <td><TMPL_VAR name></td>
            </tr>
        </TMPL_LOOP>
    </table>

    </body>
</html>
    

products.py

import MySQLdb
import MySQLdb.cursors
from htmltmpl import TemplateManager, TemplateProcessor

# Define some constants.
DB = "test"
USER = ""
PASSWD = ""
TABLE = """

    CREATE TABLE IF NOT EXISTS Products (
        id            INTEGER        NOT NULL AUTO_INCREMENT,
        name          VARCHAR(255)   NOT NULL,
        CONSTRAINT pkey_id
            PRIMARY KEY(id)
    )
    
"""

template = TemplateManager().prepare("products.tmpl")
tproc = TemplateProcessor()
                
# Assign a string to template variable named "title".
tproc.set("title", "Our products")
        
# Connect the database. Create the table.
db = MySQLdb.connect(db = DB, user = USER, passwd = PASSWD,
                     cursorclass = MySQLdb.cursors.DictCursor)
create_cur = db.cursor()
create_cur.execute(TABLE)
create_cur.close()

# Insert some data.
insert_cur = db.cursor()
insert_cur.executemany("""

    INSERT INTO Products (name) VALUES (%(name)s)

""", [
    {"name": "Seagate"},
    {"name": "Conner"},
    {"name": "Maxtor"}
])
insert_cur.close()


# Select the products.
products_cur = db.cursor()
products_cur.execute("""

    SELECT id, name
    FROM Products
    
""")

# Append product data in form of mappings (dictionaries) to the
# products list.
products = []
for i in range(products_cur.rowcount):
    products.append(products_cur.fetchone())
products_cur.close()
db.close()

# Assign the products list to template loop identifier 'Products'.
# NOTE: htmltmpl automatically converts all the values
# to strings using str().
tproc.set("Products", products)
        
# Process the template and print the result.
print tproc.process(template)
    

products.html

<html>
    <head>
        <title>Our products</title>
    </head>
    <body>

        <h1>Our products</h1>

        <table>
                <tr>
                    <td>1</td>
                    <td>Seagate</td>
                </tr>
                <tr>
                    <td>2</td>
                    <td>Conner</td>
                </tr>
                <tr>
                    <td>3</td>
                    <td>Maxtor</td>
                </tr>
        </table>

    </body>
</html>
    
htmltmpl-1.22/test/0040775000076400007640000000000007407003263013013 5ustar triptriphtmltmpl-1.22/test/badtmpl/0040775000076400007640000000000007407003263014436 5ustar triptriphtmltmpl-1.22/test/badtmpl/README0100664000076400007640000000021707341332030015305 0ustar triptrip This directory contains some invalid templates. They are used to test if the detection of invalid template syntax works properly. htmltmpl-1.22/test/badtmpl/head.inc0100664000076400007640000000030407344073045016031 0ustar triptrip import sys import os from htmltmpl import TemplateManager, TemplateProcessor template = TemplateManager(precompile=0).prepare(TEST + ".tmpl") tproc = TemplateProcessor() tproc.process(template) htmltmpl-1.22/test/badtmpl/notclosecond.py0100664000076400007640000000010207344073045017475 0ustar triptrip#!/usr/bin/env python TEST = "notclosecond" execfile("head.inc") htmltmpl-1.22/test/badtmpl/notclosecond.tmpl0100664000076400007640000000020107341332030020006 0ustar triptrip <TMPL_VAR title> htmltmpl-1.22/test/badtmpl/notcloseloop.py0100664000076400007640000000010307344073045017524 0ustar triptrip#!/usr/bin/env python TEST = "notcloseloop" execfile("head.inc") htmltmpl-1.22/test/badtmpl/notcloseloop.tmpl0100664000076400007640000000020307341332030020036 0ustar triptrip <TMPL_VAR title> htmltmpl-1.22/test/badtmpl/notopencond.py0100664000076400007640000000010107344073045017330 0ustar triptrip#!/usr/bin/env python TEST = "notopencond" execfile("head.inc") htmltmpl-1.22/test/badtmpl/notopencond.tmpl0100664000076400007640000000017407341332030017653 0ustar triptrip <TMPL_VAR title> htmltmpl-1.22/test/badtmpl/notopenloop.py0100664000076400007640000000010207344073045017357 0ustar triptrip#!/usr/bin/env python TEST = "notopenloop" execfile("head.inc") htmltmpl-1.22/test/badtmpl/notopenloop.tmpl0100664000076400007640000000017607341332030017703 0ustar triptrip <TMPL_VAR title> htmltmpl-1.22/test/gettext/0040775000076400007640000000000007407003263014477 5ustar triptriphtmltmpl-1.22/test/gettext/locale/0040775000076400007640000000000007407003263015736 5ustar triptriphtmltmpl-1.22/test/gettext/locale/en/0040775000076400007640000000000007407003263016340 5ustar triptriphtmltmpl-1.22/test/gettext/locale/en/LC_MESSAGES/0040775000076400007640000000000007407003263020125 5ustar triptriphtmltmpl-1.22/test/gettext/locale/en/LC_MESSAGES/test.mo0100664000076400007640000000122207400254653021437 0ustar triptripÞ•T Œ¸¹ÁÕï÷ý&<D\t{€Pokusnydelsi dalsi [[ vetadelsi vec zkouska]] pokusretezecslovozkouska na vice radcichProject-Id-Version: htmltmpl 1.10 POT-Creation-Date: 2001-11-25 21:45+0100 PO-Revision-Date: 2001-11-25 22:23+0100 Last-Translator: Tomas Styblo Language-Team: en MIME-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Testinglonger next [[ sentencelonger thing test]] trystringwordtest on more rowshtmltmpl-1.22/test/gettext/en.po0100664000076400007640000000162407400254651015443 0ustar triptrip# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR Free Software Foundation, Inc. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: htmltmpl 1.10\n" "POT-Creation-Date: 2001-11-25 21:45+0100\n" "PO-Revision-Date: 2001-11-25 22:23+0100\n" "Last-Translator: Tomas Styblo \n" "Language-Team: en \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=ISO-8859-1\n" "Content-Transfer-Encoding: 7bit\n" #: standard input:23 msgid "Pokusny" msgstr "Testing" #: standard input:24 msgid "retezec" msgstr "string" #: standard input:25 msgid "" "zkouska\n" "na vice radcich" msgstr "" "test\n" "on more rows" #: standard input:26 standard input:27 msgid "delsi dalsi [[ veta" msgstr "longer next [[ sentence" #: standard input:28 msgid "delsi vec zkouska]] pokus" msgstr "longer thing test]] try" #: standard input:29 msgid "slovo" msgstr "word" htmltmpl-1.22/test/gettext/gettext.tmpl0100664000076400007640000000076207400302101017045 0ustar triptrip <TMPL_VAR title> [[Pokusny]] [[retezec]]. A ted [[zkouska na vice radcich]]. Eskejpnuta \[[pitomost]]. Zkusebni [[delsi dalsi [[ veta]]. Zkusebni [[delsi dalsi \[[ veta]]. Vnitrni eskejp [[delsi vec zkouska\]] pokus]] pokracovani. Texticek ]]. Texticek \]]. Dalsi pokus \a \b. Nevyeskejpovane \\[[slovo]]. Jedno zpetne lomitko \. Dve zpetna lomitka (jedno zobrazeno) \\. Ctyri zpetna lomitka (dve zobrazena) \\\\. htmltmpl-1.22/test/gettext/test-gettext.py0100664000076400007640000000072207400313027017503 0ustar triptrip#!/usr/bin/env python import sys import gettext import locale sys.path.insert(0, "../..") from htmltmpl import TemplateManager, TemplateProcessor locale.setlocale(locale.LC_MESSAGES, "en_US") gettext.bindtextdomain("test", "./locale") gettext.textdomain("test") man = TemplateManager(precompile = 0, gettext = 1, debug = 1) tmpl = man.prepare("gettext.tmpl") tproc = TemplateProcessor(debug = 1) tproc.set("title", "Gettext test page") print tproc.process(tmpl) htmltmpl-1.22/test/gettext/test.po0100664000076400007640000000147307400254201016011 0ustar triptrip# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR Free Software Foundation, Inc. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2001-11-25 21:45+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=CHARSET\n" "Content-Transfer-Encoding: ENCODING\n" #: standard input:23 msgid "Pokusny" msgstr "" #: standard input:24 msgid "retezec" msgstr "" #: standard input:25 msgid "" "zkouska\n" "na vice radcich" msgstr "" #: standard input:26 standard input:27 msgid "delsi dalsi [[ veta" msgstr "" #: standard input:28 msgid "delsi vec zkouska]] pokus" msgstr "" #: standard input:29 msgid "slovo" msgstr "" htmltmpl-1.22/test/inc/0040775000076400007640000000000007407003263013564 5ustar triptriphtmltmpl-1.22/test/inc/inc1.tmpl0100664000076400007640000000026507344073045015321 0ustar triptrip

inc1 include

### comment

No comments include

Comments include

htmltmpl-1.22/test/inc/inc2.tmpl0100664000076400007640000000010607341332030015301 0ustar triptrip

inc2 include, greeting:

### comment htmltmpl-1.22/test/inc/recurse.tmpl0100664000076400007640000000015107341332030016116 0ustar triptrip

Recursive include.

### comment htmltmpl-1.22/test/cached.py0100664000076400007640000000167207362501627014606 0ustar triptrip#!/usr/bin/env python TEST = "cached" execfile("head.inc") ####################################################### def fill(tproc): tproc.set("title", "Template world.") tproc.set("greeting", "Hello !") tproc.set("Boys", [ { "name" : "Tomas", "age" : 19 }, { "name" : "Pavel", "age" : 34 }, { "name" : "Janek", "age" : 67 }, { "name" : "Martin", "age" : 43 }, { "name" : "Viktor", "age" : 78 }, { "name" : "Marian", "age" : 90 }, { "name" : "Prokop", "age" : 23 }, { "name" : "Honzik", "age" : 46 }, { "name" : "Brudra", "age" : 64 }, { "name" : "Marek", "age" : 54 }, { "name" : "Peter", "age" : 42 }, { "name" : "Beda", "age" : 87 } ]) ####################################################### fill(tproc) tproc.process(template) tproc.reset() fill(tproc) tproc.process(template) tproc.reset() fill(tproc) execfile("foot.inc") htmltmpl-1.22/test/cached.res0100664000076400007640000001142207341332014014726 0ustar triptrip Template world.

Hello !

Total boys: 12

first odd 1 Tomas 19
inner even 2 Pavel 34
inner odd 3 Janek 67
EVERY third separator
inner even 4 Martin 43
inner odd 5 Viktor 78
inner even 6 Marian 90
EVERY third separator
inner odd 7 Prokop 23
inner even 8 Honzik 46
inner odd 9 Brudra 64
EVERY third separator
inner even 10 Marek 54
inner odd 11 Peter 42
last even 12 Beda 87
htmltmpl-1.22/test/cached.tmpl0100664000076400007640000000250307341332014015111 0ustar triptrip <TMPL_VAR title>

### Comment should be removed.

Total boys:

first inner last odd even
EVERY third separator
htmltmpl-1.22/test/compiled.py0100664000076400007640000000275407344073045015173 0ustar triptrip#!/usr/bin/env python TEST = "compiled" import sys import os sys.path.insert(0, "..") from htmltmpl import TemplateManager, TemplateProcessor man = TemplateManager(precompile = 1, debug = "debug" in sys.argv) template = man.prepare(TEST + ".tmpl") tproc = TemplateProcessor(debug = "debug" in sys.argv) ####################################################### def fill(tproc): tproc.set("title", "Template world.") tproc.set("greeting", "Hello !") tproc.set("Boys", [ { "name" : "Tomas", "age" : 19 }, { "name" : "Pavel", "age" : 34 }, { "name" : "Janek", "age" : 67 }, { "name" : "Martin", "age" : 43 }, { "name" : "Viktor", "age" : 78 }, { "name" : "Marian", "age" : 90 }, { "name" : "Prokop", "age" : 23 }, { "name" : "Honzik", "age" : 46 }, { "name" : "Brudra", "age" : 64 }, { "name" : "Marek", "age" : 54 }, { "name" : "Peter", "age" : 42 }, { "name" : "Beda", "age" : 87 } ]) ####################################################### fill(tproc) tproc.process(template) tproc.reset() fill(tproc) tproc.process(template) tproc.reset() fill(tproc) output = tproc.process(template) if "out" in sys.argv: sys.stdout.write(output) sys.exit(0) res = open("%s.res" % TEST).read() print TEST, "...", if output == res and os.access("%s.tmplc" % TEST, os.R_OK): print "OK" os.remove("%s.tmplc" % TEST) else: print "FAILED" open("%s.fail" % TEST, "w").write(output) htmltmpl-1.22/test/compiled.res0100664000076400007640000001142207341332017015316 0ustar triptrip Template world.

Hello !

Total boys: 12

first odd 1 Tomas 19
inner even 2 Pavel 34
inner odd 3 Janek 67
EVERY third separator
inner even 4 Martin 43
inner odd 5 Viktor 78
inner even 6 Marian 90
EVERY third separator
inner odd 7 Prokop 23
inner even 8 Honzik 46
inner odd 9 Brudra 64
EVERY third separator
inner even 10 Marek 54
inner odd 11 Peter 42
last even 12 Beda 87
htmltmpl-1.22/test/compiled.tmpl0100664000076400007640000000250307341332017015501 0ustar triptrip <TMPL_VAR title>

### Comment should be removed.

Total boys:

first inner last odd even
EVERY third separator
htmltmpl-1.22/test/complex.py0100664000076400007640000000231507344073045015037 0ustar triptrip#!/usr/bin/env python TEST = "complex" execfile("head.inc") ####################################################### tproc.set("title", "Hello template world.") tproc.set("blurb", 1) users = [ { "name" : "Joe User", "age" : 18, "city" : "London", "Skills" : [ { "skill" : "computers" }, { "skill" : "machinery" } ]}, { "name" : "Peter Nobody", "age" : 35, "city" : "Paris", "Skills" : [ { "skill" : "tennis" }, { "skill" : "football" }, { "skill" : "baseball" }, { "skill" : "fishing" } ]}, { "name" : "Jack Newman", "age" : 21, "city" : "Moscow", "Skills" : [ { "skill" : "guitar" }, { "skill" : "piano" }, { "skill" : "flute" } ]} ] tproc.set("Users", users) products = [ { "key" : 12, "name" : "cake", "selected" : 0 }, { "key" : 45, "name" : "milk", "selected" : 1 }, { "key" : 78, "name" : "pizza", "selected" : 0 }, { "key" : 32, "name" : "roll", "selected" : 0 }, { "key" : 98, "name" : "ham", "selected" : 0 }, ] tproc.set("Products", products) tproc.set("Unused_loop", []) ####################################################### execfile("foot.inc") htmltmpl-1.22/test/complex.res0100664000076400007640000000341207341332021015164 0ustar triptrip Hello template world.

Total users: 3

first person 1 Joe User 18 London Total skills: 2
  • 1. computers
  • 2. machinery
common person 2 Peter Nobody 35 Paris Total skills: 4
  • 1. tennis
  • 2. football
  • 3. baseball
  • 4. fishing
last person 3 Jack Newman 21 Moscow Total skills: 3
  • 1. guitar
  • 2. piano
  • 3. flute

BLURB: IF: this should appear in the output

PRODUCTS: IF: this should appear in the output

htmltmpl-1.22/test/complex.tmpl0100664000076400007640000000364507341332021015357 0ustar triptrip <TMPL_VAR title> ### Table of users

Total users:

first person last person common person Total skills:
  • .

UNUSED: IF: this should not appear in the output

BLURB: IF: this should appear in the output

BLURB: UNLESS: this should not appear in the output

### Selection of products

PRODUCTS: IF: this should appear in the output

UNUSED_LOOP: IF: this should not appear in the output

empty empty

htmltmpl-1.22/test/else.py0100664000076400007640000000041507344073045014317 0ustar triptrip#!/usr/bin/env python TEST = "else" execfile("head.inc") ####################################################### tproc.set("title", "Stranka") tproc.set("true", 1) tproc.set("false", 0) ####################################################### execfile("foot.inc") htmltmpl-1.22/test/else.res0100664000076400007640000000056007341332021014446 0ustar triptrip Stranka

OK = IF true, IF false, UNLESS true, UNLESS false

++ IF true

++ IF false

++ UNLESS true

++ UNLESS false

htmltmpl-1.22/test/else.tmpl0100664000076400007640000000141507341332021014631 0ustar triptrip <TMPL_VAR title>

OK = IF true, IF false, UNLESS true, UNLESS false

++ IF true

-- IF true

-- IF false

++ IF false

-- UNLESS true

++ UNLESS true

++ UNLESS false

-- UNLESS false

htmltmpl-1.22/test/escape.py0100664000076400007640000000050307344073045014625 0ustar triptrip#!/usr/bin/env python TEST = "escape" execfile("head.inc") ####################################################### tproc.set("title", "Template world.") tproc.set("greeting", "Hello !") tproc.set("data", ' &entita; ') ####################################################### execfile("foot.inc") htmltmpl-1.22/test/escape.res0100664000076400007640000000073507341332021014762 0ustar triptrip Template world.

Hello !

Raw: &entita;
HTML escaped (auto): <TAG PARAM="foo"> &entita; </TAG>
HTML escaped (param): <TAG PARAM="foo"> &entita; </TAG>
URL escaped: %3CTAG+PARAM%3D%22foo%22%3E+%26entita%3B+%3C%2FTAG%3E

htmltmpl-1.22/test/escape.tmpl0100664000076400007640000000064107341332021015141 0ustar triptrip <TMPL_VAR title>

### Comment should be removed.

Raw:
HTML escaped (auto):
HTML escaped (param):
URL escaped:

htmltmpl-1.22/test/foot.inc0100664000076400007640000000041007362501627014454 0ustar triptrip output += tproc.process(template) if "out" in sys.argv: sys.stdout.write(output) sys.exit(0) res = open("%s.res" % TEST).read() print TEST, "...", if output == res: print "OK" else: print "FAILED" open("%s.fail" % TEST, "w").write(output) htmltmpl-1.22/test/globalvars.py0100664000076400007640000000045307344073045015525 0ustar triptrip#!/usr/bin/env python TEST = "globalvars" execfile("head.inc") ####################################################### tproc.set("title", "Template world.") tproc.set("greeting", "Hello !") tproc.set("Loop1", [ {} ]) ####################################################### execfile("foot.inc") htmltmpl-1.22/test/globalvars.res0100664000076400007640000000032507341332021015651 0ustar triptrip Template world.

Hello !

++ Global, greeting is: Hello !

htmltmpl-1.22/test/globalvars.tmpl0100664000076400007640000000100207341332021016025 0ustar triptrip <TMPL_VAR title>

### Comment should be removed.

-- No global, greeting is:

++ Global, greeting is:

htmltmpl-1.22/test/head.inc0100664000076400007640000000042607362501627014415 0ustar triptrip import sys import os sys.path.insert(0, "..") from htmltmpl import TemplateManager, TemplateProcessor man = TemplateManager(precompile = 0, debug = "debug" in sys.argv) template = man.prepare(TEST + ".tmpl") tproc = TemplateProcessor(debug = "debug" in sys.argv) output = "" htmltmpl-1.22/test/if.py0100664000076400007640000000040207344073045013761 0ustar triptrip#!/usr/bin/env python TEST = "if" execfile("head.inc") ####################################################### tproc.set("true", 1) tproc.set("false", 0) tproc.set("true2", 1) ####################################################### execfile("foot.inc") htmltmpl-1.22/test/if.res0100664000076400007640000000034407341332023014116 0ustar triptrip

OK = IF true, IF true2

++ IF true

++ IF true2

htmltmpl-1.22/test/if.tmpl0100664000076400007640000000062307341332023014301 0ustar triptrip <TMPL_VAR title>

OK = IF true, IF true2

++ IF true

-- IF false

++ IF true2

htmltmpl-1.22/test/include.py0100664000076400007640000000041507344073045015012 0ustar triptrip#!/usr/bin/env python TEST = "include" execfile("head.inc") ####################################################### tproc.set("title", "Template world.") tproc.set("greeting", "Hello !") ####################################################### execfile("foot.inc") htmltmpl-1.22/test/include.res0100664000076400007640000000047407344073045015160 0ustar triptrip Template world.

Hello !

inc1 include

No comments include

inc2 include, greeting: Hello !

Comments include

inc2 include, greeting: Hello !

htmltmpl-1.22/test/include.tmpl0100664000076400007640000000030307341332023015321 0ustar triptrip <TMPL_VAR title>

### Comment htmltmpl-1.22/test/loop.py0100664000076400007640000000136407344073045014344 0ustar triptrip#!/usr/bin/env python TEST = "loop" execfile("head.inc") ####################################################### tproc.set("title", "Template world.") tproc.set("greeting", "Hello !") tproc.set("Boys", [ { "name" : "Tomas", "age" : 19 }, { "name" : "Pavel", "age" : 34 }, { "name" : "Janek", "age" : 67 }, { "name" : "Martin", "age" : 43 }, { "name" : "Viktor", "age" : 78 }, { "name" : "Marian", "age" : 90 }, { "name" : "Prokop", "age" : 23 }, { "name" : "Honzik", "age" : 46 }, { "name" : "Brudra", "age" : 64 }, { "name" : "Marek", "age" : 54 }, { "name" : "Peter", "age" : 42 }, { "name" : "Beda", "age" : 87 } ]) ####################################################### execfile("foot.inc") htmltmpl-1.22/test/loop.res0100664000076400007640000001142207341332026014473 0ustar triptrip Template world.

Hello !

Total boys: 12

first odd 1 Tomas 19
inner even 2 Pavel 34
inner odd 3 Janek 67
EVERY third separator
inner even 4 Martin 43
inner odd 5 Viktor 78
inner even 6 Marian 90
EVERY third separator
inner odd 7 Prokop 23
inner even 8 Honzik 46
inner odd 9 Brudra 64
EVERY third separator
inner even 10 Marek 54
inner odd 11 Peter 42
last even 12 Beda 87
htmltmpl-1.22/test/loop.tmpl0100664000076400007640000000250307341332026014656 0ustar triptrip <TMPL_VAR title>

### Comment should be removed.

Total boys:

first inner last odd even
EVERY third separator
htmltmpl-1.22/test/maxinclude.py0100664000076400007640000000042007344073045015514 0ustar triptrip#!/usr/bin/env python TEST = "maxinclude" execfile("head.inc") ####################################################### tproc.set("title", "Template world.") tproc.set("greeting", "Hello !") ####################################################### execfile("foot.inc") htmltmpl-1.22/test/maxinclude.res0100664000076400007640000000116607362501627015667 0ustar triptrip Template world.

Hello !

Recursive include. Hello !

Recursive include. Hello !

Recursive include. Hello !

Recursive include. Hello !

Recursive include. Hello !


HTMLTMPL WARNING:
Cannot include template: recurse.tmpl


htmltmpl-1.22/test/maxinclude.tmpl0100664000076400007640000000030607341332026016035 0ustar triptrip <TMPL_VAR title>

### Comment htmltmpl-1.22/test/multipart.py0100664000076400007640000000156207362501627015416 0ustar triptrip#!/usr/bin/env python import time TEST = "multipart" execfile("head.inc") ####################################################### tproc.set("title", "Template world.") tproc.set("greeting", "Hello !") output = tproc.process(template, 1) # time.sleep(1) tproc.set("Boys", [ { "name" : "Tomas", "age" : 19 }, { "name" : "Pavel", "age" : 34 }, { "name" : "Janek", "age" : 67 }, { "name" : "Martin", "age" : 43 }, { "name" : "Viktor", "age" : 78 }, { "name" : "Marian", "age" : 90 }, { "name" : "Prokop", "age" : 23 }, { "name" : "Honzik", "age" : 46 }, { "name" : "Brudra", "age" : 64 }, { "name" : "Marek", "age" : 54 }, { "name" : "Peter", "age" : 42 }, { "name" : "Beda", "age" : 87 } ]) output += tproc.process(template, 2) # time.sleep(1) ####################################################### execfile("foot.inc") htmltmpl-1.22/test/multipart.res0100664000076400007640000001150607362501627015556 0ustar triptrip Template world.

Hello !

Total boys: 12

first odd 1 Tomas 19
inner even 2 Pavel 34
inner odd 3 Janek 67
EVERY third separator
inner even 4 Martin 43
inner odd 5 Viktor 78
inner even 6 Marian 90
EVERY third separator
inner odd 7 Prokop 23
inner even 8 Honzik 46
inner odd 9 Brudra 64
EVERY third separator
inner even 10 Marek 54
inner odd 11 Peter 42
last even 12 Beda 87

Testing part 3.

htmltmpl-1.22/test/multipart.tmpl0100664000076400007640000000264307362501627015743 0ustar triptrip <TMPL_VAR title>

### Comment should be removed.

Total boys:

first inner last odd even
EVERY third separator

Testing part 3.

htmltmpl-1.22/test/nestcond.py0100664000076400007640000000071707344073045015211 0ustar triptrip#!/usr/bin/env python TEST = "nestcond" execfile("head.inc") ####################################################### tproc.set("title", "Template world.") tproc.set("greeting", "Hello !") tproc.set("var1", 1) tproc.set("var2", 0) tproc.set("var3", 1) tproc.set("var4", 0) tproc.set("var5", 0) tproc.set("var6", 0) tproc.set("var7", 1) tproc.set("var8", 1) tproc.set("var9", 0) ####################################################### execfile("foot.inc") htmltmpl-1.22/test/nestcond.res0100664000076400007640000000041307341332026015335 0ustar triptrip Template world.

Hello !

OK = TITLE, VAR1, VAR3, VAR8-1, VAR8-2

TITLE: OK VAR1: OK VAR3: OK VAR8-1: OK VAR8-2: OK htmltmpl-1.22/test/nestcond.tmpl0100664000076400007640000000165107341332026015525 0ustar triptrip <TMPL_VAR title>

OK = TITLE, VAR1, VAR3, VAR8-1, VAR8-2

TITLE: OK VAR1: OK VAR2: FAILED VAR3: OK VAR4-1: FAILED VAR5: FAILED VAR4-2: FAILED VAR6-1: FAILED VAR7: FAILED VAR6-2: FAILED VAR8-1: OK VAR9: FAILED VAR8-2: OK htmltmpl-1.22/test/nestloop.py0100664000076400007640000000102007344073045015223 0ustar triptrip#!/usr/bin/env python TEST = "nestloop" execfile("head.inc") ####################################################### tproc.set("title", "Template world.") tproc.set("greeting", "Hello !") tproc.set("Loop1", [ { "Loop2" : [ {}, {} ], "Loop3" : [], "Loop4" : [ { "Loop6" : [ {}, {}, {} ] } ], "Loop5" : [] }, { "Loop2" : [], "Loop3" : [ {}, {} ], "Loop4" : [], "Loop5" : [ {} ] } ]) ####################################################### execfile("foot.inc") htmltmpl-1.22/test/nestloop.res0100664000076400007640000000122307341332026015363 0ustar triptrip Template world.

Hello !

    OK are: LOOP1
                LOOP2 (2x)
                LOOP4
                    LOOP6 (3x)
            LOOP1
                LOOP3 (2x)
                LOOP5
    

LOOP1

LOOP2

LOOP2

LOOP4

LOOP6

LOOP6

LOOP6

LOOP1

LOOP3

LOOP3

LOOP5

htmltmpl-1.22/test/nestloop.tmpl0100664000076400007640000000141407341332030015543 0ustar triptrip <TMPL_VAR title>

    OK are: LOOP1
                LOOP2 (2x)
                LOOP4
                    LOOP6 (3x)
            LOOP1
                LOOP3 (2x)
                LOOP5
    

LOOP1

LOOP2

LOOP3

LOOP4

LOOP6

LOOP5

htmltmpl-1.22/test/params.py0100664000076400007640000000046307362501627014657 0ustar triptrip#!/usr/bin/env python TEST = "params" execfile("head.inc") ####################################################### tproc.set("title", "Template world.") tproc.set("greeting", "Hello world !") tproc.set("Loop", [ {} ]) ####################################################### execfile("foot.inc") htmltmpl-1.22/test/params.res0100664000076400007640000000070007362501627015012 0ustar triptrip Template world.

1: Hello world !

2: Hello world !

3: Hello world !

4: Hello world !

5: Hello <HTML> world !

6: Hello <HTML> world !

7:

8:

htmltmpl-1.22/test/params.tmpl0100664000076400007640000000130107362501627015173 0ustar triptrip <TMPL_VAR title> ### Comment should be removed.

1:

2:

3:

4:

5:

6:

7:

8:

htmltmpl-1.22/test/simple.py0100664000076400007640000000041407344073045014657 0ustar triptrip#!/usr/bin/env python TEST = "simple" execfile("head.inc") ####################################################### tproc.set("title", "Template world.") tproc.set("greeting", "Hello !") ####################################################### execfile("foot.inc") htmltmpl-1.22/test/simple.res0100664000076400007640000000063207341332030015007 0ustar triptrip Template world.

Total: 8



1: Hello !

2: Hello !

3: Hello !

4: Hello !

5: Hello !

6: Hello !

7: Hello !

8: Hello !

| Hello ! | htmltmpl-1.22/test/simple.tmpl0100664000076400007640000000133407341332030015172 0ustar triptrip <TMPL_VAR title>

Total: 8



### Comment should be removed.

1:

### Comment should be removed.

2:

3:

4:

5:

6:

7:

8:

| | ### The spaces should be preserved. htmltmpl-1.22/test/unless.py0100664000076400007640000000040607344073045014700 0ustar triptrip#!/usr/bin/env python TEST = "unless" execfile("head.inc") ####################################################### tproc.set("true", 1) tproc.set("false", 0) tproc.set("true2", 1) ####################################################### execfile("foot.inc") htmltmpl-1.22/test/unless.res0100664000076400007640000000026107341332030015025 0ustar triptrip

OK = UNLESS false

++ UNLESS false

htmltmpl-1.22/test/unless.tmpl0100664000076400007640000000064207341332030015213 0ustar triptrip <TMPL_VAR title>

OK = UNLESS false

-- UNLESS true

++ UNLESS false

-- UNLESS true2

htmltmpl-1.22/CODING0100664000076400007640000000057107341331774012732 0ustar triptrip Please follow this code style: Indent size is 4 spaces. Use spaces instead of real tabs. Never exceed maximum line width of 79 characters. Use (extend) the test suite. Function and variable naming style: cool_variable, cool_function All function and variable names are in lowercase. Class naming style: MyClass htmltmpl-1.22/Changes0100664000076400007640000001075707406736266013355 0ustar triptrip 1.22 : 2001/12/10 - precompilation with gettext bugfix (compile_params missing gettext) 1.21 : 2001/11/28 - this release fixes a major bug in the new gettext support 1.20 : 2001/11/25 - New major feature: integrated GETTEXT support which is ideal for easy creation of multilingual web applications. Check the documentation for description of this new feature. - documentation enhancements (clarification of included templates) 1.18 : 2001/10/08 - new feature: multipart templates. They can be created using the new directive. Please see the updated Language reference documentation for more information about this new feature. - rewritten parser: - bugfix: multiple parameters now can be specified in any order - better performance of parsing of template inclusions - bugfix: the magic variable __EVERY__x now works also if x > 9 - extended test-suite - some small documentation fixes 1.17 : 2001/09/03 - Added the "binary" flag to open() where it's appropriate. This could cause problems on Windows. - The most important function - TemplateProcessor().process() - was optimized and is now twice faster. The template 'test/complex.tmpl' can be processed 50x per second on my K6-350, when it's precompiled in memory. - The default template of easydoc was somewhat enhanced and is now indented properly. - easy.py has new option "--methodbg" 1.16 : 2001/09/02 - bugfix in easydoc: hidden classes were not hidden 1.15 : 2001/09/01 - !! This release is a major redesign of the module. It's incompatible with code using the old interface. I tried to make the old interface as similar to HTML::Template as possible, but it apparently was not a good idea, because design of HTML::Template is not much object oriented. So, please check the documentation for description of the new much more flexible interface. !! - The module is now multitask safe on UNIX and Windows platforms (precompiled '.tmplc' files are now properly locked). On Macintosh the locking is not implemented and precompilation is disabled on that platform. Anyone willing to implement the file locking on Mac ? - Corrupted or incompatible .tmplc files are now transparently detected, removed and recreated. - Templates are now recompiled, if the precompiled form was compiled with different 'include', 'max_include' or 'comments' settings. - Templates now can be compiled also from strings. - Test suite enhancements. 1.14 : 2001/08/26 - documentation updates 1.13 : 2001/08/26 - documentation updates & spellchecking - new examples in 'doc' - some pyChecker cleanups 1.10 : 2001/08/25 - !! Please note that you must delete all your old compiled templates (.tmplc files) before you upgrade to this version. This version introduces a new format of .tmplc files which is not compatible with the old one. !! - !! Exceptions TmplEx and FatalEx were removed. New exception TemplateError replaces them both. !! - FIXED: self._include_files list was not reset when the template has changed on the disk and was recompiled - FIXED: invocation of os.stat() on an included template which may be no longer accessible - new optimization: see merge_statements() - unrecognized TMPL_* statements are now detected and TemplateError is raised if one is found (it's more compatible with HTML::Template) - unrecognized magic variables are now detected and TemplateError is raised when one is found - better exception handling - OO design polishing => moved template metadata to a new separate Metadata class - the new .tmplc format is much more extensible - some code was replaced with library functions from os.path - some variables and methods now have more descriptive names - documentation enhancements - added this Changes file - general code polishing 1.00 : 2001/08/15 - first release - submitted to the Vaults of Parnassus htmltmpl-1.22/LICENSE0100664000076400007640000004310007341332001013024 0ustar triptrip GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 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. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. 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. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, 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) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, 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 Program, 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 Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) 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; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, 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 executable. However, as a special exception, the source code 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. If distribution of executable or 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 counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program 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. 5. 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 Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program 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 to this License. 7. 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 Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program 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 Program. 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. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program 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. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies 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 Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, 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 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. 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 PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively 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. Copyright (C) 19yy This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, 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. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) 19yy name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. htmltmpl-1.22/MANIFEST0100664000076400007640000000340707407003206013163 0ustar triptripCODING Changes LICENSE MANIFEST MANIFEST.in README TODO VERSION easy.py easydoc.py easydocp.py htmltmpl.py setup.py test.py tmpl-xgettext.pl doc/easydoc-api.html doc/easydoc.html doc/gettext.html doc/index.html doc/lang.html doc/main.css doc/makedoc.sh doc/php.html doc/python-api.html doc/python.html doc/examples/products.html doc/examples/products.py doc/examples/products.tmpl doc/examples/template.html doc/examples/template.py doc/examples/template.tmpl test/cached.py test/cached.res test/cached.tmpl test/compiled.py test/compiled.res test/compiled.tmpl test/complex.py test/complex.res test/complex.tmpl test/else.py test/else.res test/else.tmpl test/escape.py test/escape.res test/escape.tmpl test/foot.inc test/globalvars.py test/globalvars.res test/globalvars.tmpl test/head.inc test/if.py test/if.res test/if.tmpl test/include.py test/include.res test/include.tmpl test/loop.py test/loop.res test/loop.tmpl test/maxinclude.py test/maxinclude.res test/maxinclude.tmpl test/multipart.py test/multipart.res test/multipart.tmpl test/nestcond.py test/nestcond.res test/nestcond.tmpl test/nestloop.py test/nestloop.res test/nestloop.tmpl test/params.py test/params.res test/params.tmpl test/simple.py test/simple.res test/simple.tmpl test/unless.py test/unless.res test/unless.tmpl test/badtmpl/README test/badtmpl/head.inc test/badtmpl/notclosecond.py test/badtmpl/notclosecond.tmpl test/badtmpl/notcloseloop.py test/badtmpl/notcloseloop.tmpl test/badtmpl/notopencond.py test/badtmpl/notopencond.tmpl test/badtmpl/notopenloop.py test/badtmpl/notopenloop.tmpl test/gettext/.test-gettext.py.swp test/gettext/en.po test/gettext/gettext.tmpl test/gettext/test-gettext.py test/gettext/test.po test/gettext/locale/en/LC_MESSAGES/test.mo test/inc/inc1.tmpl test/inc/inc2.tmpl test/inc/recurse.tmpl htmltmpl-1.22/MANIFEST.in0100664000076400007640000000041507400313400013555 0ustar triptripinclude LICENSE include README include TODO include VERSION include CODING include MANIFEST include MANIFEST.in include Changes include test.py include easy.py include tmpl-xgettext.pl recursive-include test * recursive-include doc * global-exclude *.pyc *.tmplc *cvs* htmltmpl-1.22/README0100664000076400007640000000101307362502002012677 0ustar triptrip htmltmpl ======== A Python based templating engine for separation of code and HTML. To run the regression tests (recommended): python test.py To install the module: (become root) python setup.py install Documentation can be found in the 'doc' directory or at the homepage of this module: http://htmltmpl.sourceforge.net/ AUTHOR: Tomas Styblo, tripie@cpan.org LICENSE: GNU GPL (included in file "LICENSE") htmltmpl-1.22/TODO0100664000076400007640000000026207344073044012525 0ustar triptrip - Locking of .tmplc files on Macintosh to make the module thread safe on this platform (making the precompilation of templates possible on this platform). htmltmpl-1.22/VERSION0100664000076400007640000000000507406735572013112 0ustar triptrip1.22 htmltmpl-1.22/easy.py0100775000076400007640000002275207344516433013367 0ustar triptrip#!/usr/bin/env python import sys import getopt import easydoc BGCOLOR = "#d8d0a4" TEXTCOLOR = "black" LINKCOLOR = "red" METHODBG = "#d8e0d4" TEMPLATE = """ <TMPL_VAR name>: documentation

VERSION:

AUTHOR: ()

WEBSITE:

LICENSE:


REQUIRES:


FUNCTIONS:

           

CLASSES:

  • :

               

FUNCTION: ()

PARAMETERS:



CLASS:

METHODS:

           

METHOD: ()

(class )

### Constructors do not have return value.

RETURN VALUE:

PARAMETERS:



""" def main(): try: optlist, args = getopt.getopt(sys.argv[1:], "h", ["with-hidden", "help", "debug", "template=", "bgcolor=", "textcolor=", "linkcolor=", "methodbg="]) except: help("Invalid options.") # Process parameters. module = None output = None if len(args) == 0: help("Missing parameters.") elif len(args) == 2: module = args[0] output = args[1] else: help("Invalid number of parameters.") # Process options. with_hidden, debug = 0, 0 bgcolor, textcolor, linkcolor = BGCOLOR, TEXTCOLOR, LINKCOLOR methodbg = METHODBG template = TEMPLATE for x in optlist: opt, value = x if opt == "-h" or opt == "--help": help() elif opt == "--template": f = open(value) template = f.read() f.close() elif opt == "--with-hidden": with_hidden = 1 elif opt == "--debug": debug = 1 elif opt == "--bgcolor": bgcolor = value elif opt == "--textcolor": textcolor = value elif opt == "--linkcolor": linkcolor = value elif opt == "--methodbg": methodbg = value easy = easydoc.Easydoc(template, debug) out = open(output, "w") out.write(easy.process(module, bgcolor, textcolor, linkcolor, methodbg, with_hidden)) out.close() def help(error=""): print "easydoc for Python, version", easydoc.VERSION print "(c) 2001 Tomas Styblo, tripie@cpan.org" print if error: print error print print "easy [--template]" print " [--with-hidden]" print " [--bgcolor]" print " [--textcolor]" print " [--linkcolor]" print " [--methodbg]" print print " : filename of the module to document" print " : output file" print " --template : alternative template filename" print " --with-hidden : include sections marked as @hidden" print " --bgcolor : background color" print " --textcolor : text color" print " --linkcolor : hyperlink color" print " --methodbg : background color of method names" sys.exit() main() htmltmpl-1.22/easydoc.py0100664000076400007640000003146607345527511014054 0ustar triptrip """ A module to autogenerate HTML documentation from docstrings. The documentation of this module can be found in 'doc' directory of the distribution tarball or at the website of this package. Latest versions of this module are also available at that website. You can use and redistribute this module under conditions of the GNU General Public License that can be found either at [ http://www.gnu.org/ ] or in file "LICENSE" contained in the distribution tarball of this module. Copyright (c) 2001 Tomas Styblo, tripie@cpan.org Prague, the Czech Republic @name easydoc @version 1.01 @author-name Tomas Styblo @author-email tripie@cpan.org @website http://htmltmpl.sourceforge.net/ @license-name GNU GPL @license-url http://www.gnu.org/licenses/gpl.html @require htmltmpl ([ http://htmltmpl.sourceforge.net/ ]) """ __version__ = 1.01 __author__ = "Tomas Styblo (tripie@cpan.org)" # All imported modules except the 'htmltmpl' module are part of # the standard Python library. # The 'easydocp' module is stolen example module from documentation # of 'parser' module from the standard library. import sys import string import re import pprint import copy import parser from types import * from htmltmpl import TemplateCompiler, TemplateProcessor import easydocp VERSION = 1.00 KEEP_NEWLINES = 1 ############################################## # CLASS: Easydoc # ############################################## class Easydoc: """ Autogenerate documentation from docstrings. This class provides all the functionality of easydoc. You can subclass it and override its processing methods module(), mclass() and method() to customize its behaviour. You also can easily use your own template to modify the output in any way you need. Output colors can be customized via parameters. """ def __init__(self, template, debug=0): """ Constructor. @header __init__(template, debug=0) @param template String containing template data. @param debug Enable or disable debugging messages. This optional parameter can be used to enable or disable debugging messages which are printed to stderr. By default debugging messages are disabled. """ self._debug = debug self._classes = [] self._functions = [] self._class = {} self._template = TemplateCompiler().compile_string(template) self._tproc = TemplateProcessor(html_escape=0) def process(self, module, bgcolor, textcolor, linkcolor, methodbg, with_hidden=0): """ Create documentation for a module. @header process(module, bgcolor, textcolor, linkcolor, with_hidden=0) @return String containing the resulting HTML documentation. @param module Filename of the module to document. The module must be specified as filename. The module is not imported nor executed, only parsed. @param bgcolor Set background color. Accepts any valid CSS color value. @param textcolor Set text color. Accepts any valid CSS color value. @param linkcolor Set color of hyperlinks. Accepts any valid CSS color value. @param with_hidden Do not exclude hidden sections from output. This optional parameter can be used to force inclusion of hidden sections in the resulting documentation. Hidden sections are by default not included. """ mdict = {} self._tproc.set("bgcolor", bgcolor) self._tproc.set("textcolor", textcolor) self._tproc.set("linkcolor", linkcolor) self._tproc.set("methodbg", methodbg) # Parse the module. ast = parser.suite(open(module).read()) module_info = easydocp.ModuleInfo(ast.totuple()) self.module(module_info.get_docstring()) # Class info. for mclass in module_info.get_class_names(): class_info = module_info.get_class_info(mclass) if self.mclass(mclass, class_info.get_docstring(), with_hidden): # The class should be included in the output. self._class["Methods"] = [] for method in class_info.get_method_names(): method_info = class_info.get_method_info(method) self.method(mclass, method, method_info.get_docstring(), with_hidden) self.DEB("Finished class: " + mclass) self._classes.append(copy.copy(self._class)) self._class.clear() self._tproc.set("Classes", self._classes) # Functions info. for function in module_info.get_function_names(): function_info = module_info.get_function_info(function) self.method("", function, function_info.get_docstring(), with_hidden) self._tproc.set("Functions", self._functions) return self._tproc.process(self._template) ############################################## # PRIVATE METHODS # ############################################## def module(self, doc): """ Process docstring of a module. @hidden """ short, detailed, statements = self.parse(doc) self.DEB("Module: short: " + short) self.DEB("Module: statements: " + pprint.pformat(statements)) self._tproc.set("short", short.strip()) self._tproc.set("Detailed", self.detailed(detailed)) # Statements. requires = [] for statement in statements: param, data = statement if param == "name": self._tproc.set("name", data.strip()) self.DEB("Module: name: " + data) elif param == "version": self._tproc.set("version", data.strip()) elif param == "website": self._tproc.set("website", data.strip()) elif param == "author-name": self._tproc.set("author-name", self.mangle(data)) elif param == "author-email": self._tproc.set("author-email", data.strip()) elif param == "license-name": self._tproc.set("license-name", data.strip()) elif param == "license-url": self._tproc.set("license-url", data.strip()) elif param == "require": requires.append( {"require": self.mangle(data)} ) else: self.warn("Unknown statement: " + param) self._tproc.set("Requires", requires) def mclass(self, name, doc, with_hidden=0): """ Process docstring of a class. @hidden """ short, detailed, statements = self.parse(doc) self.DEB("Class: " + name + ": short: " + short) self.DEB("Class: " + name + ": statements: " + \ pprint.pformat(statements)) self._class["name"] = name self._class["short"] = short.strip() self._class["Detailed"] = self.detailed(detailed) for statement in statements: param, data = statement if param == "hidden": if not with_hidden: self.DEB("Class: " + name + ": HIDDEN") return 0 else: self.warn("Unknown statement: " + param) else: return 1 def method(self, mclass, name, doc, with_hidden=0): """ Process docstring of a method. @hidden """ method = {} short, detailed, statements = self.parse(doc) if mclass: self.DEB("Method: " + name + ": short: " + short) self.DEB("Method: " + name + ": statements: " + \ pprint.pformat(statements)) else: self.DEB("Function: " + name + ": short: " + short) self.DEB("Function: " + name + ": statements: " + \ pprint.pformat(statements)) method["name"] = name method["class"] = mclass method["short"] = short.strip() method["Detailed"] = self.detailed(detailed) parameters = [] for statement in statements: param, data = statement if param == "hidden": if not with_hidden: self.DEB("Method: " + name + ": HIDDEN") return 0 elif param == "header": header = data.strip() header = re.sub(r"\s+", " ", header) method["header"] = header elif param == "return": method["return"] = self.mangle(data) elif param == "param": parameter = {} # Split the data into first line and rest. lines = data.splitlines(KEEP_NEWLINES) first_line = lines[0].strip() # Split the first line into name and short description # of the parameter. fsplit = first_line.split(" ", 1) if len(fsplit) == 2: pname, pshort = fsplit elif len(fsplit) == 1: pname = fsplit[0] pshort = "" else: pname = "" pshort = "" if len(lines) > 1: pdetailed = string.join(lines[1:]) else: pdetailed = "" self.DEB("Parameter: " + pname.strip()) parameter["name"] = pname.strip() parameter["short"] = pshort.strip() parameter["Detailed"] = self.detailed(pdetailed) parameters.append(parameter) else: self.warn("Unknown statement: " + param) else: method["Parameters"] = parameters if mclass: self._class["Methods"].append(method) else: self._functions.append(method) return 1 def parse(self, doc): """ Parse a docstring. Split the docstring into short description, detailed description and a list containing a tuple for every statement. The first element of the tuple is name of the statement, the second is the data of the statement. @hidden """ short = "" detailed = "" statements = [] if not doc: return short, detailed, statements doc = doc.replace("\"\"\"", "") rc = re.compile(r""" ^\s*(@)([-\w]+) """, re.VERBOSE | re.MULTILINE) tokens = rc.split(doc) len_tokens = len(tokens) i = 0 skip_param = 0 while 1: if i == len_tokens: break if skip_param: skip_param = 0 i += 2 continue token = tokens[i] if token == "@": skip_param = 1 param = tokens[i + 1] data = tokens[i + 2] statements.append((param, data)) else: if not short: lines = token.splitlines(KEEP_NEWLINES) short = lines[0] if len(lines) > 1: detailed = string.join(lines[1:]) i += 1 return short, detailed, statements def DEB(self, str): """ Print debugging message to stderr if debugging is enabled. @hidden """ if self._debug: print >> sys.stderr, str def warn(self, warning): """ Print a warning to stderr. @hidden """ print >> sys.stderr, warning def mangle(self, str): """ Strip leading and trailing whitespace. Convert URL to hyperlink. @hidden """ str = str.strip() return re.sub(r"\[ (http://.*?) \]", r'\1', str) def detailed(self, str): """ Process detailed descritpion. Split it into paragraphs at empty lines. Return list of the paragraphs. @hidden """ paragraphs = [] rc = re.compile(r"^\s*$", re.MULTILINE) # allow any whitespace for p in rc.split(str): if re.search(r"\S", p): paragraphs.append( {"paragraph": self.mangle(p)} ) return paragraphs htmltmpl-1.22/easydocp.py0100664000076400007640000001313207344152447014223 0ustar triptrip"""Simple code to extract class & function docstrings from a module. This code is used as an example in the library reference manual in the section on using the parser module. Refer to the manual for a thorough discussion of the operation of this code. """ import os import parser import symbol import token import types from types import ListType, TupleType def get_docs(fileName): """Retrieve information from the parse tree of a source file. fileName Name of the file to read Python source code from. """ source = open(fileName).read() basename = os.path.basename(os.path.splitext(fileName)[0]) ast = parser.suite(source) return ModuleInfo(ast.totuple(), basename) class SuiteInfoBase: _docstring = '' _name = '' def __init__(self, tree = None): self._class_info = {} self._function_info = {} if tree: self._extract_info(tree) def _extract_info(self, tree): # extract docstring if len(tree) == 2: found, vars = match(DOCSTRING_STMT_PATTERN[1], tree[1]) else: found, vars = match(DOCSTRING_STMT_PATTERN, tree[3]) if found: self._docstring = eval(vars['docstring']) # discover inner definitions for node in tree[1:]: found, vars = match(COMPOUND_STMT_PATTERN, node) if found: cstmt = vars['compound'] if cstmt[0] == symbol.funcdef: name = cstmt[2][1] self._function_info[name] = FunctionInfo(cstmt) elif cstmt[0] == symbol.classdef: name = cstmt[2][1] self._class_info[name] = ClassInfo(cstmt) def get_docstring(self): return self._docstring def get_name(self): return self._name def get_class_names(self): return self._class_info.keys() def get_class_info(self, name): return self._class_info[name] def __getitem__(self, name): try: return self._class_info[name] except KeyError: return self._function_info[name] class SuiteFuncInfo: # Mixin class providing access to function names and info. def get_function_names(self): return self._function_info.keys() def get_function_info(self, name): return self._function_info[name] class FunctionInfo(SuiteInfoBase, SuiteFuncInfo): def __init__(self, tree = None): self._name = tree[2][1] SuiteInfoBase.__init__(self, tree and tree[-1] or None) class ClassInfo(SuiteInfoBase): def __init__(self, tree = None): self._name = tree[2][1] SuiteInfoBase.__init__(self, tree and tree[-1] or None) def get_method_names(self): return self._function_info.keys() def get_method_info(self, name): return self._function_info[name] class ModuleInfo(SuiteInfoBase, SuiteFuncInfo): def __init__(self, tree = None, name = ""): self._name = name SuiteInfoBase.__init__(self, tree) if tree: found, vars = match(DOCSTRING_STMT_PATTERN, tree[1]) if found: self._docstring = vars["docstring"] def match(pattern, data, vars=None): """Match `data' to `pattern', with variable extraction. pattern Pattern to match against, possibly containing variables. data Data to be checked and against which variables are extracted. vars Dictionary of variables which have already been found. If not provided, an empty dictionary is created. The `pattern' value may contain variables of the form ['varname'] which are allowed to match anything. The value that is matched is returned as part of a dictionary which maps 'varname' to the matched value. 'varname' is not required to be a string object, but using strings makes patterns and the code which uses them more readable. This function returns two values: a boolean indicating whether a match was found and a dictionary mapping variable names to their associated values. """ if vars is None: vars = {} if type(pattern) is ListType: # 'variables' are ['varname'] vars[pattern[0]] = data return 1, vars if type(pattern) is not TupleType: return (pattern == data), vars if len(data) != len(pattern): return 0, vars for pattern, data in map(None, pattern, data): same, vars = match(pattern, data, vars) if not same: break return same, vars # This pattern identifies compound statements, allowing them to be readily # differentiated from simple statements. # COMPOUND_STMT_PATTERN = ( symbol.stmt, (symbol.compound_stmt, ['compound']) ) # This pattern will match a 'stmt' node which *might* represent a docstring; # docstrings require that the statement which provides the docstring be the # first statement in the class or function, which this pattern does not check. # DOCSTRING_STMT_PATTERN = ( symbol.stmt, (symbol.simple_stmt, (symbol.small_stmt, (symbol.expr_stmt, (symbol.testlist, (symbol.test, (symbol.and_test, (symbol.not_test, (symbol.comparison, (symbol.expr, (symbol.xor_expr, (symbol.and_expr, (symbol.shift_expr, (symbol.arith_expr, (symbol.term, (symbol.factor, (symbol.power, (symbol.atom, (token.STRING, ['docstring']) )))))))))))))))), (token.NEWLINE, '') )) htmltmpl-1.22/htmltmpl.py0100664000076400007640000016252107406745220014260 0ustar triptrip """ A templating engine for separation of code and HTML. The documentation of this templating engine is separated to two parts: 1. Description of the templating language. 2. Documentation of classes and API of this module that provides a Python implementation of the templating language. All the documentation can be found in 'doc' directory of the distribution tarball or at the homepage of the engine. Latest versions of this module are also available at that website. You can use and redistribute this module under conditions of the GNU General Public License that can be found either at [ http://www.gnu.org/ ] or in file "LICENSE" contained in the distribution tarball of this module. Copyright (c) 2001 Tomas Styblo, tripie@cpan.org @name htmltmpl @version 1.22 @author-name Tomas Styblo @author-email tripie@cpan.org @website http://htmltmpl.sourceforge.net/ @license-name GNU GPL @license-url http://www.gnu.org/licenses/gpl.html """ __version__ = 1.22 __author__ = "Tomas Styblo (tripie@cpan.org)" # All imported modules are part of the standard Python library. from types import * import re import os import os.path import pprint # only for debugging import sys import copy import cgi # for HTML escaping of variables import urllib # for URL escaping of variables import cPickle # for template compilation import gettext INCLUDE_DIR = "inc" # Total number of possible parameters. # Increment if adding a parameter to any statement. PARAMS_NUMBER = 3 # Relative positions of parameters in TemplateCompiler.tokenize(). PARAM_NAME = 1 PARAM_ESCAPE = 2 PARAM_GLOBAL = 3 PARAM_GETTEXT_STRING = 1 # Find a way to lock files. Currently implemented only for UNIX and windows. LOCKTYPE_FCNTL = 1 LOCKTYPE_MSVCRT = 2 LOCKTYPE = None try: import fcntl except: try: import msvcrt except: LOCKTYPE = None else: LOCKTYPE = LOCKTYPE_MSVCRT else: LOCKTYPE = LOCKTYPE_FCNTL LOCK_EX = 1 LOCK_SH = 2 LOCK_UN = 3 ############################################## # CLASS: TemplateManager # ############################################## class TemplateManager: """ Class that manages compilation and precompilation of templates. You should use this class whenever you work with templates that are stored in a file. The class can create a compiled template and transparently manage its precompilation. It also keeps the precompiled templates up-to-date by modification times comparisons. """ def __init__(self, include=1, max_include=5, precompile=1, comments=1, gettext=0, debug=0): """ Constructor. @header __init__(include=1, max_include=5, precompile=1, comments=1, gettext=0, debug=0) @param include Enable or disable included templates. This optional parameter can be used to enable or disable TMPL_INCLUDE inclusion of templates. Disabling of inclusion can improve performance a bit. The inclusion is enabled by default. @param max_include Maximum depth of nested inclusions. This optional parameter can be used to specify maximum depth of nested TMPL_INCLUDE inclusions. It defaults to 5. This setting prevents infinite recursive inclusions. @param precompile Enable or disable precompilation of templates. This optional parameter can be used to enable or disable creation and usage of precompiled templates. A precompiled template is saved to the same directory in which the main template file is located. You need write permissions to that directory. Precompilation provides a significant performance boost because it's not necessary to parse the templates over and over again. The boost is especially noticeable when templates that include other templates are used. Comparison of modification times of the main template and all included templates is used to ensure that the precompiled templates are up-to-date. Templates are also recompiled if the htmltmpl module is updated. The TemplateErrorexception is raised when the precompiled template cannot be saved. Precompilation is enabled by default. Precompilation is available only on UNIX and Windows platforms, because proper file locking which is necessary to ensure multitask safe behaviour is platform specific and is not implemented for other platforms. Attempts to enable precompilation on the other platforms result in raise of the TemplateError exception. @param comments Enable or disable template comments. This optional parameter can be used to enable or disable template comments. Disabling of the comments can improve performance a bit. Comments are enabled by default. @param gettext Enable or disable gettext support. @param debug Enable or disable debugging messages. This optional parameter is a flag that can be used to enable or disable debugging messages which are printed to the standard error output. The debugging messages are disabled by default. """ # Save the optional parameters. # These values are not modified by any method. self._include = include self._max_include = max_include self._precompile = precompile self._comments = comments self._gettext = gettext self._debug = debug # Find what module to use to lock files. # File locking is necessary for the 'precompile' feature to be # multitask/thread safe. Currently it works only on UNIX # and Windows. Anyone willing to implement it on Mac ? if precompile and not LOCKTYPE: raise TemplateError, "Template precompilation is not "\ "available on this platform." self.DEB("INIT DONE") def prepare(self, file): """ Preprocess, parse, tokenize and compile the template. If precompilation is enabled then this method tries to load a precompiled form of the template from the same directory in which the template source file is located. If it succeeds, then it compares modification times stored in the precompiled form to modification times of source files of the template, including source files of all templates included via the TMPL_INCLUDE statements. If any of the modification times differs, then the template is recompiled and the precompiled form updated. If precompilation is disabled, then this method parses and compiles the template. @header prepare(file) @return Compiled template. The methods returns an instance of the Template class which is a compiled form of the template. This instance can be used as input for the TemplateProcessor. @param file Path to the template file to prepare. The method looks for the template file in current directory if the parameter is a relative path. All included templates must be placed in subdirectory 'inc' of the directory in which the main template file is located. """ compiled = None if self._precompile: if self.is_precompiled(file): try: precompiled = self.load_precompiled(file) except PrecompiledError, template: print >> sys.stderr, "Htmltmpl: bad precompiled "\ "template '%s' removed" % template compiled = self.compile(file) self.save_precompiled(compiled) else: precompiled.debug(self._debug) compile_params = (self._include, self._max_include, self._comments, self._gettext) if precompiled.is_uptodate(compile_params): self.DEB("PRECOMPILED: UPTODATE") compiled = precompiled else: self.DEB("PRECOMPILED: NOT UPTODATE") compiled = self.update(precompiled) else: self.DEB("PRECOMPILED: NOT PRECOMPILED") compiled = self.compile(file) self.save_precompiled(compiled) else: self.DEB("PRECOMPILATION DISABLED") compiled = self.compile(file) return compiled def update(self, template): """ Update (recompile) a compiled template. This method recompiles a template compiled from a file. If precompilation is enabled then the precompiled form saved on disk is also updated. @header update(template) @return Recompiled template. It's ensured that the returned template is up-to-date. @param template A compiled template. This parameter should be an instance of the Template class, created either by the TemplateManager or by the TemplateCompiler. The instance must represent a template compiled from a file on disk. """ self.DEB("UPDATE") updated = self.compile(template.file()) if self._precompile: self.save_precompiled(updated) return updated ############################################## # PRIVATE METHODS # ############################################## def DEB(self, str): """ Print debugging message to stderr if debugging is enabled. @hidden """ if self._debug: print >> sys.stderr, str def lock_file(self, file, lock): """ Provide platform independent file locking. @hidden """ fd = file.fileno() if LOCKTYPE == LOCKTYPE_FCNTL: if lock == LOCK_SH: fcntl.flock(fd, fcntl.LOCK_SH) elif lock == LOCK_EX: fcntl.flock(fd, fcntl.LOCK_EX) elif lock == LOCK_UN: fcntl.flock(fd, fcntl.LOCK_UN) else: raise TemplateError, "BUG: bad lock in lock_file" elif LOCKTYPE == LOCKTYPE_MSVCRT: if lock == LOCK_SH: # msvcrt does not support shared locks :-( msvcrt.locking(fd, msvcrt.LK_LOCK, 1) elif lock == LOCK_EX: msvcrt.locking(fd, msvcrt.LK_LOCK, 1) elif lock == LOCK_UN: msvcrt.locking(fd, msvcrt.LK_UNLCK, 1) else: raise TemplateError, "BUG: bad lock in lock_file" else: raise TemplateError, "BUG: bad locktype in lock_file" def compile(self, file): """ Compile the template. @hidden """ return TemplateCompiler(self._include, self._max_include, self._comments, self._gettext, self._debug).compile(file) def is_precompiled(self, file): """ Return true if the template is already precompiled on the disk. This method doesn't check whether the compiled template is uptodate. @hidden """ filename = file + "c" # "template.tmplc" if os.path.isfile(filename): return 1 else: return 0 def load_precompiled(self, file): """ Load precompiled template from disk. Remove the precompiled template file and recompile it if the file contains corrupted or unpicklable data. @hidden """ filename = file + "c" # "template.tmplc" self.DEB("LOADING PRECOMPILED") try: remove_bad = 0 file = None try: file = open(filename, "rb") self.lock_file(file, LOCK_SH) precompiled = cPickle.load(file) except IOError, (errno, errstr): raise TemplateError, "IO error in load precompiled "\ "template '%s': (%d) %s"\ % (filename, errno, errstr) except cPickle.UnpicklingError: remove_bad = 1 raise PrecompiledError, filename except: remove_bad = 1 raise else: return precompiled finally: if file: self.lock_file(file, LOCK_UN) file.close() if remove_bad and os.path.isfile(filename): # X: We may lose the original exception here, raising OSError. os.remove(filename) def save_precompiled(self, template): """ Save compiled template to disk in precompiled form. Associated metadata is also saved. It includes: filename of the main template file, modification time of the main template file, modification times of all included templates and version of the htmltmpl module which compiled the template. The method removes a file which is saved only partially because of some error. @hidden """ filename = template.file() + "c" # creates "template.tmplc" # Check if we have write permission to the template's directory. template_dir = os.path.dirname(os.path.abspath(filename)) if not os.access(template_dir, os.W_OK): raise TemplateError, "Cannot save precompiled templates "\ "to '%s': write permission denied."\ % template_dir try: remove_bad = 0 file = None try: file = open(filename, "wb") # may truncate existing file self.lock_file(file, LOCK_EX) BINARY = 1 READABLE = 0 if self._debug: cPickle.dump(template, file, READABLE) else: cPickle.dump(template, file, BINARY) except IOError, (errno, errstr): remove_bad = 1 raise TemplateError, "IO error while saving precompiled "\ "template '%s': (%d) %s"\ % (filename, errno, errstr) except cPickle.PicklingError, error: remove_bad = 1 raise TemplateError, "Pickling error while saving "\ "precompiled template '%s': %s"\ % (filename, error) except: remove_bad = 1 raise else: self.DEB("SAVING PRECOMPILED") finally: if file: self.lock_file(file, LOCK_UN) file.close() if remove_bad and os.path.isfile(filename): # X: We may lose the original exception here, raising OSError. os.remove(filename) ############################################## # CLASS: TemplateProcessor # ############################################## class TemplateProcessor: """ Fill the template with data and process it. This class provides actual processing of a compiled template. Use it to set template variables and loops and then obtain result of the processing. """ def __init__(self, html_escape=1, magic_vars=1, global_vars=0, debug=0): """ Constructor. @header __init__(html_escape=1, magic_vars=1, global_vars=0, debug=0) @param html_escape Enable or disable HTML escaping of variables. This optional parameter is a flag that can be used to enable or disable automatic HTML escaping of variables. All variables are by default automatically HTML escaped. The escaping process substitutes HTML brackets, ampersands and double quotes with appropriate HTML entities. @param magic_vars Enable or disable loop magic variables. This parameter can be used to enable or disable "magic" context variables, that are automatically defined inside loops. Magic variables are enabled by default. Refer to the language specification for description of these magic variables. @param global_vars Globally activate global lookup of variables. This optional parameter is a flag that can be used to specify whether variables which cannot be found in the current scope should be automatically looked up in enclosing scopes. Automatic global lookup is disabled by default. Global lookup can be overriden on a per-variable basis by the GLOBAL parameter of a TMPL_VAR statement. @param debug Enable or disable debugging messages. """ self._html_escape = html_escape self._magic_vars = magic_vars self._global_vars = global_vars self._debug = debug # Data structure containing variables and loops set by the # application. Use debug=1, process some template and # then check stderr to see how the structure looks. # It's modified only by set() and reset() methods. self._vars = {} # Following variables are for multipart templates. self._current_part = 1 self._current_pos = 0 def set(self, var, value): """ Associate a value with top-level template variable or loop. A template identifier can represent either an ordinary variable (string) or a loop. To assign a value to a string identifier pass a scalar as the 'value' parameter. This scalar will be automatically converted to string. To assign a value to a loop identifier pass a list of mappings as the 'value' parameter. The engine iterates over this list and assigns values from the mappings to variables in a template loop block if a key in the mapping corresponds to a name of a variable in the loop block. The number of mappings contained in this list is equal to number of times the loop block is repeated in the output. @header set(var, value) @return No return value. @param var Name of template variable or loop. @param value The value to associate. """ # The correctness of character case is verified only for top-level # variables. if self.is_ordinary_var(value): # template top-level ordinary variable if not var.islower(): raise TemplateError, "Invalid variable name '%s'." % var elif type(value) == ListType: # template top-level loop if var != var.capitalize(): raise TemplateError, "Invalid loop name '%s'." % var else: raise TemplateError, "Value of toplevel variable '%s' must "\ "be either a scalar or a list." % var self._vars[var] = value self.DEB("VALUE SET: " + str(var)) def reset(self, keep_data=0): """ Reset the template data. This method resets the data contained in the template processor instance. The template processor instance can be used to process any number of templates, but this method must be called after a template is processed to reuse the instance, @header reset(keep_data=0) @return No return value. @param keep_data Do not reset the template data. Use this flag if you do not want the template data to be erased. This way you can reuse the data contained in the instance of the TemplateProcessor. """ self._current_part = 1 self._current_pos = 0 if not keep_data: self._vars.clear() self.DEB("RESET") def process(self, template, part=None): """ Process a compiled template. Return the result as string. This method actually processes a template and returns the result. @header process(template, part=None) @return Result of the processing as string. @param template A compiled template. Value of this parameter must be an instance of the Template class created either by the TemplateManager or by the TemplateCompiler. @param part The part of a multipart template to process. This parameter can be used only together with a multipart template. It specifies the number of the part to process. It must be greater than zero, because the parts are numbered from one. The parts must be processed in the right order. You cannot process a part which precedes an already processed part. If this parameter is not specified, then the whole template is processed, or all remaining parts are processed. """ self.DEB("APP INPUT:") if self._debug: pprint.pprint(self._vars, sys.stderr) if part != None and (part == 0 or part < self._current_part): raise TemplateError, "process() - invalid part number" # This flag means "jump behind the end of current statement" or # "skip the parameters of current statement". # Even parameters that actually are not present in the template # do appear in the list of tokens as empty items ! skip_params = 0 # Stack for enabling or disabling output in response to TMPL_IF, # TMPL_UNLESS, TMPL_ELSE and TMPL_LOOPs with no passes. output_control = [] ENABLE_OUTPUT = 1 DISABLE_OUTPUT = 0 # Stacks for data related to loops. loop_name = [] # name of a loop loop_pass = [] # current pass of a loop (counted from zero) loop_start = [] # index of loop start in token list loop_total = [] # total number of passes in a loop tokens = template.tokens() len_tokens = len(tokens) out = "" # buffer for processed output # Recover position at which we ended after processing of last part. i = self._current_pos # Process the list of tokens. while 1: if i == len_tokens: break if skip_params: # Skip the parameters following a statement. skip_params = 0 i += PARAMS_NUMBER continue token = tokens[i] if token.startswith("." escape = tokens[i + PARAM_ESCAPE] globalp = tokens[i + PARAM_GLOBAL] skip_params = 1 # If output of current block is not disabled then append # the substitued and escaped variable to the output. if DISABLE_OUTPUT not in output_control: value = str(self.find_value(var, loop_name, loop_pass, loop_total, globalp)) out += self.escape(value, escape) self.DEB("VAR: " + str(var)) elif token == "." skip_params = 1 # Find total number of passes in this loop. passtotal = self.find_value(var, loop_name, loop_pass, loop_total) if not passtotal: passtotal = 0 # Push data for this loop on the stack. loop_total.append(passtotal) loop_start.append(i) loop_pass.append(0) loop_name.append(var) # Disable output of loop block if the number of passes # in this loop is zero. if passtotal == 0: # This loop is empty. output_control.append(DISABLE_OUTPUT) self.DEB("LOOP: DISABLE: " + str(var)) else: output_control.append(ENABLE_OUTPUT) self.DEB("LOOP: FIRST PASS: %s TOTAL: %d"\ % (var, passtotal)) elif token == "." globalp = tokens[i + PARAM_GLOBAL] skip_params = 1 if self.find_value(var, loop_name, loop_pass, loop_total, globalp): output_control.append(ENABLE_OUTPUT) self.DEB("IF: ENABLE: " + str(var)) else: output_control.append(DISABLE_OUTPUT) self.DEB("IF: DISABLE: " + str(var)) elif token == "." globalp = tokens[i + PARAM_GLOBAL] skip_params = 1 if self.find_value(var, loop_name, loop_pass, loop_total, globalp): output_control.append(DISABLE_OUTPUT) self.DEB("UNLESS: DISABLE: " + str(var)) else: output_control.append(ENABLE_OUTPUT) self.DEB("UNLESS: ENABLE: " + str(var)) elif token == "." # If this loop was not disabled, then record the pass. if loop_total[-1] > 0: loop_pass[-1] += 1 if loop_pass[-1] == loop_total[-1]: # There are no more passes in this loop. Pop # the loop from stack. loop_pass.pop() loop_name.pop() loop_start.pop() loop_total.pop() output_control.pop() self.DEB("LOOP: END") else: # Jump to the beggining of this loop block # to process next pass of the loop. i = loop_start[-1] self.DEB("LOOP: NEXT PASS") elif token == "." output_control.pop() self.DEB("IF: END") elif token == "." output_control.pop() self.DEB("UNLESS: END") elif token == "." if output_control[-1] == DISABLE_OUTPUT: # Condition was false, activate the ELSE block. output_control[-1] = ENABLE_OUTPUT self.DEB("ELSE: ENABLE") elif output_control[-1] == ENABLE_OUTPUT: # Condition was true, deactivate the ELSE block. output_control[-1] = DISABLE_OUTPUT self.DEB("ELSE: DISABLE") else: raise TemplateError, "BUG: ELSE: INVALID FLAG" elif token == "

HTMLTMPL WARNING:
Cannot include template: %s


""" % filename self.DEB("CANNOT INCLUDE WARNING") elif token == "." % token elif DISABLE_OUTPUT not in output_control: # Raw textual template data. # If output of current block is not disabled, then # append template data to the output buffer. out += token i += 1 # end of the big while loop # Check whether all opening statements were closed. if loop_name: raise TemplateError, "Missing ." if output_control: raise TemplateError, "Missing or " return out ############################################## # PRIVATE METHODS # ############################################## def DEB(self, str): """ Print debugging message to stderr if debugging is enabled. @hidden """ if self._debug: print >> sys.stderr, str def find_value(self, var, loop_name, loop_pass, loop_total, global_override=None): """ Search the self._vars data structure to find variable var located in currently processed pass of a loop which is currently being processed. If the variable is an ordinary variable, then return it. If the variable is an identificator of a loop, then return the total number of times this loop will be executed. Return an empty string, if the variable is not found at all. @hidden """ # Search for the requested variable in magic vars if the name # of the variable starts with "__" and if we are inside a loop. if self._magic_vars and var.startswith("__") and loop_name: return self.magic_var(var, loop_pass[-1], loop_total[-1]) # Search for an ordinary variable or for a loop. # Recursively search in self._vars for the requested variable. scope = self._vars globals = [] for i in range(len(loop_name)): # If global lookup is on then push the value on the stack. if ((self._global_vars and global_override != "0") or \ global_override == "1") and scope.has_key(var) and \ self.is_ordinary_var(scope[var]): globals.append(scope[var]) # Descent deeper into the hierarchy. if scope.has_key(loop_name[i]) and scope[loop_name[i]]: scope = scope[loop_name[i]][loop_pass[i]] else: return "" if scope.has_key(var): # Value exists in current loop. if type(scope[var]) == ListType: # The requested value is a loop. # Return total number of its passes. return len(scope[var]) else: return scope[var] elif globals and \ ((self._global_vars and global_override != "0") or \ global_override == "1"): # Return globally looked up value. return globals.pop() else: # No value found. if var[0].isupper(): # This is a loop name. # Return zero, because the user wants to know number # of its passes. return 0 else: return "" def magic_var(self, var, loop_pass, loop_total): """ Resolve and return value of a magic variable. Raise an exception if the magic variable is not recognized. @hidden """ self.DEB("MAGIC: '%s', PASS: %d, TOTAL: %d"\ % (var, loop_pass, loop_total)) if var == "__FIRST__": if loop_pass == 0: return 1 else: return 0 elif var == "__LAST__": if loop_pass == loop_total - 1: return 1 else: return 0 elif var == "__INNER__": # If this is neither the first nor the last pass. if loop_pass != 0 and loop_pass != loop_total - 1: return 1 else: return 0 elif var == "__PASS__": # Magic variable __PASS__ counts passes from one. return loop_pass + 1 elif var == "__PASSTOTAL__": return loop_total elif var == "__ODD__": # Internally pass numbers stored in loop_pass are counted from # zero. But the template language presents them counted from one. # Therefore we must add one to the actual loop_pass value to get # the value we present to the user. if (loop_pass + 1) % 2 != 0: return 1 else: return 0 elif var.startswith("__EVERY__"): # Magic variable __EVERY__x is never true in first or last pass. if loop_pass != 0 and loop_pass != loop_total - 1: # Check if an integer follows the variable name. try: every = int(var[9:]) # nine is length of "__EVERY__" except ValueError: raise TemplateError, "Magic variable __EVERY__x: "\ "Invalid pass number." else: if not every: raise TemplateError, "Magic variable __EVERY__x: "\ "Pass number cannot be zero." elif (loop_pass + 1) % every == 0: self.DEB("MAGIC: EVERY: " + str(every)) return 1 else: return 0 else: return 0 else: raise TemplateError, "Invalid magic variable '%s'." % var def escape(self, str, override=""): """ Escape a string either by HTML escaping or by URL escaping. @hidden """ ESCAPE_QUOTES = 1 if (self._html_escape and override != "NONE" and override != "0" and \ override != "URL") or override == "HTML" or override == "1": return cgi.escape(str, ESCAPE_QUOTES) elif override == "URL": return urllib.quote_plus(str) else: return str def is_ordinary_var(self, var): """ Return true if var is a scalar. (not a reference to loop) @hidden """ if type(var) == StringType or type(var) == IntType or \ type(var) == LongType or type(var) == FloatType: return 1 else: return 0 ############################################## # CLASS: TemplateCompiler # ############################################## class TemplateCompiler: """ Preprocess, parse, tokenize and compile the template. This class parses the template and produces a 'compiled' form of it. This compiled form is an instance of the Template class. The compiled form is used as input for the TemplateProcessor which uses it to actually process the template. This class should be used direcly only when you need to compile a template from a string. If your template is in a file, then you should use the TemplateManager class which provides a higher level interface to this class and also can save the compiled template to disk in a precompiled form. """ def __init__(self, include=1, max_include=5, comments=1, gettext=0, debug=0): """ Constructor. @header __init__(include=1, max_include=5, comments=1, gettext=0, debug=0) @param include Enable or disable included templates. @param max_include Maximum depth of nested inclusions. @param comments Enable or disable template comments. @param gettext Enable or disable gettext support. @param debug Enable or disable debugging messages. """ self._include = include self._max_include = max_include self._comments = comments self._gettext = gettext self._debug = debug # This is a list of filenames of all included templates. # It's modified by the include_templates() method. self._include_files = [] # This is a counter of current inclusion depth. It's used to prevent # infinite recursive includes. self._include_level = 0 def compile(self, file): """ Compile template from a file. @header compile(file) @return Compiled template. The return value is an instance of the Template class. @param file Filename of the template. See the prepare() method of the TemplateManager class for exaplanation of this parameter. """ self.DEB("COMPILING FROM FILE: " + file) self._include_path = os.path.join(os.path.dirname(file), INCLUDE_DIR) tokens = self.parse(self.read(file)) compile_params = (self._include, self._max_include, self._comments, self._gettext) return Template(__version__, file, self._include_files, tokens, compile_params, self._debug) def compile_string(self, data): """ Compile template from a string. This method compiles a template from a string. The template cannot include any templates. TMPL_INCLUDE statements are turned into warnings. @header compile_string(data) @return Compiled template. The return value is an instance of the Template class. @param data String containing the template data. """ self.DEB("COMPILING FROM STRING") self._include = 0 tokens = self.parse(data) compile_params = (self._include, self._max_include, self._comments, self._gettext) return Template(__version__, None, None, tokens, compile_params, self._debug) ############################################## # PRIVATE METHODS # ############################################## def DEB(self, str): """ Print debugging message to stderr if debugging is enabled. @hidden """ if self._debug: print >> sys.stderr, str def read(self, filename): """ Read content of file and return it. Raise an error if a problem occurs. @hidden """ self.DEB("READING: " + filename) try: f = None try: f = open(filename, "r") data = f.read() except IOError, (errno, errstr): raise TemplateError, "IO error while reading template '%s': "\ "(%d) %s" % (filename, errno, errstr) else: return data finally: if f: f.close() def parse(self, template_data): """ Parse the template. This method is recursively called from within the include_templates() method. @return List of processing tokens. @hidden """ if self._comments: self.DEB("PREPROCESS: COMMENTS") template_data = self.remove_comments(template_data) tokens = self.tokenize(template_data) if self._include: self.DEB("PREPROCESS: INCLUDES") self.include_templates(tokens) return tokens def remove_comments(self, template_data): """ Remove comments from the template data. @hidden """ pattern = r"### .*" return re.sub(pattern, "", template_data) def include_templates(self, tokens): """ Process TMPL_INCLUDE statements. Use the include_level counter to prevent infinite recursion. Record paths to all included templates to self._include_files. @hidden """ i = 0 out = "" # buffer for output skip_params = 0 # Process the list of tokens. while 1: if i == len(tokens): break if skip_params: skip_params = 0 i += PARAMS_NUMBER continue token = tokens[i] if token == "." self._include_level += 1 if self._include_level > self._max_include: # Do not include the template. # Protection against infinite recursive includes. skip_params = 1 self.DEB("INCLUDE: LIMIT REACHED: " + filename) else: # Include the template. skip_params = 0 include_file = os.path.join(self._include_path, filename) self._include_files.append(include_file) include_data = self.read(include_file) include_tokens = self.parse(include_data) # Append the tokens from the included template to actual # position in the tokens list, replacing the TMPL_INCLUDE # token and its parameters. tokens[i:i+PARAMS_NUMBER+1] = include_tokens i = i + len(include_tokens) self.DEB("INCLUDED: " + filename) continue # Do not increment 'i' below. i += 1 # end of the main while loop if self._include_level > 0: self._include_level -= 1 return out def tokenize(self, template_data): """ Split the template into tokens separated by template statements. The statements itself and associated parameters are also separately included in the resulting list of tokens. Return list of the tokens. @hidden """ self.DEB("TOKENIZING TEMPLATE") # NOTE: The TWO double quotes in character class in the regexp below # are there only to prevent confusion of syntax highlighter in Emacs. pattern = r""" (?:^[ \t]+)? # eat spaces, tabs (opt.) (< (?:!--[ ])? # comment start + space (opt.) /?TMPL_[A-Z]+ # closing slash / (opt.) + statement [ a-zA-Z0-9""/.=:_\\-]* # this spans also comments ending (--) >) [%s]? # eat trailing newline (opt.) """ % os.linesep rc = re.compile(pattern, re.VERBOSE | re.MULTILINE) split = rc.split(template_data) tokens = [] for statement in split: if statement.startswith(" 0 and '=' not in params[0]: # implicit identifier name = params[0] del params[0] else: # explicit identifier as a 'NAME' parameter name = self.find_param("NAME", params) self.DEB("TOKENIZER: NAME: " + str(name)) return name def find_param(self, param, params): """ Extract value of parameter from a statement. @hidden """ for pair in params: name, value = pair.split("=") if not name or not value: raise TemplateError, "Syntax error in template." if name == param: if value[0] == '"': # The value is in double quotes. ret_value = value[1:-1] else: # The value is without double quotes. ret_value = value self.DEB("TOKENIZER: PARAM: '%s' => '%s'" % (param, ret_value)) return ret_value else: self.DEB("TOKENIZER: PARAM: '%s' => NOT DEFINED" % param) return None ############################################## # CLASS: Template # ############################################## class Template: """ This class represents a compiled template. This class provides storage and methods for the compiled template and associated metadata. It's serialized by pickle if we need to save the compiled template to disk in a precompiled form. You should never instantiate this class directly. Always use the TemplateManager or TemplateCompiler classes to create the instances of this class. The only method which you can directly use is the is_uptodate method. """ def __init__(self, version, file, include_files, tokens, compile_params, debug=0): """ Constructor. @hidden """ self._version = version self._file = file self._tokens = tokens self._compile_params = compile_params self._debug = debug self._mtime = None self._include_mtimes = {} if not file: self.DEB("TEMPLATE WAS COMPILED FROM A STRING") return # Save modifitcation time of the main template file. if os.path.isfile(file): self._mtime = os.path.getmtime(file) else: raise TemplateError, "Template: file does not exist: '%s'" % file # Save modificaton times of all included template files. for inc_file in include_files: if os.path.isfile(inc_file): self._include_mtimes[inc_file] = os.path.getmtime(inc_file) else: raise TemplateError, "Template: file does not exist: '%s'"\ % inc_file self.DEB("NEW TEMPLATE CREATED") def is_uptodate(self, compile_params=None): """ Check whether the compiled template is uptodate. Return true if this compiled template is uptodate. Return false, if the template source file was changed on the disk since it was compiled. Works by comparison of modification times. Also takes modification times of all included templates into account. @header is_uptodate(compile_params=None) @return True if the template is uptodate, false otherwise. @param compile_params Only for internal use. Do not use this optional parameter. It's intended only for internal use by the TemplateManager. """ if not self._file: self.DEB("TEMPLATE COMPILED FROM A STRING") return 0 if self._version != __version__: self.DEB("TEMPLATE: VERSION NOT UPTODATE") return 0 if compile_params != None and compile_params != self._compile_params: self.DEB("TEMPLATE: DIFFERENT COMPILATION PARAMS") return 0 # Check modification times of the main template and all included # templates. If the included template no longer exists, then # the problem will be resolved when the template is recompiled. # Main template file. if not (os.path.isfile(self._file) and \ self._mtime == os.path.getmtime(self._file)): self.DEB("TEMPLATE: NOT UPTODATE: " + self._file) return 0 # Included templates. for inc_file in self._include_mtimes.keys(): if not (os.path.isfile(inc_file) and \ self._include_mtimes[inc_file] == \ os.path.getmtime(inc_file)): self.DEB("TEMPLATE: NOT UPTODATE: " + inc_file) return 0 else: self.DEB("TEMPLATE: UPTODATE") return 1 def tokens(self): """ Get tokens of this template. @hidden """ return self._tokens def file(self): """ Get filename of the main file of this template. @hidden """ return self._file def debug(self, debug): """ Get debugging state. @hidden """ self._debug = debug ############################################## # PRIVATE METHODS # ############################################## def __getstate__(self): """ Used by pickle when the class is serialized. Remove the 'debug' attribute before serialization. @hidden """ dict = copy.copy(self.__dict__) del dict["_debug"] return dict def __setstate__(self, dict): """ Used by pickle when the class is unserialized. Add the 'debug' attribute. @hidden """ dict["_debug"] = 0 self.__dict__ = dict def DEB(self, str): """ Print debugging message to stderr. @hidden """ if self._debug: print >> sys.stderr, str ############################################## # EXCEPTIONS # ############################################## class TemplateError(Exception): """ Fatal exception. Raised on runtime or template syntax errors. This exception is raised when a runtime error occurs or when a syntax error in the template is found. It has one parameter which always is a string containing a description of the error. All potential IOError exceptions are handled by the module and are converted to TemplateError exceptions. That means you should catch the TemplateError exception if there is a possibility that for example the template file will not be accesssible. The exception can be raised by constructors or by any method of any class. The instance is no longer usable when this exception is raised. """ def __init__(self, error): """ Constructor. @hidden """ Exception.__init__(self, "Htmltmpl error: " + error) class PrecompiledError(Exception): """ This exception is _PRIVATE_ and non fatal. @hidden """ def __init__(self, template): """ Constructor. @hidden """ Exception.__init__(self, template) htmltmpl-1.22/setup.py0100775000076400007640000000060407406735605013561 0ustar triptrip#!/usr/bin/env python from distutils.core import setup setup(name = "htmltmpl", version = "1.22", description = "Templating engine for separation of code and HTML.", author = "Tomas Styblo", author_email = "tripie@cpan.org", url = "http://htmltmpl.sourceforge.net/", licence = "GNU GPL", py_modules = ['htmltmpl', 'easydoc', 'easydocp'] ) htmltmpl-1.22/test.py0100775000076400007640000000145707362502002013367 0ustar triptrip#!/usr/bin/env python import os import sys import re os.chdir("test") # If this is not a UNIX platform, then # we must convert the .tmpl and .res files to make it compatible # with newline separator used on current platform. if os.linesep != "\n": print "This is not UNIX." print "Converting newline separators in .tmpl and .res files." files = [x for x in os.listdir(".") \ if x.find(".tmpl") != -1 or x.find(".res") != -1] files.sort() for file in files: old = open(file).read() new = re.sub("\n", os.linesep, old) open(file, "w").write(new) # Exec all .py files located in the "test" directory. scripts = [x for x in os.listdir(".") if x.find(".py") != -1] scripts.sort() for i in range(len(scripts)): print i+1, "...", execfile(scripts[i]) htmltmpl-1.22/tmpl-xgettext.pl0100755000076400007640000000647407400400426015223 0ustar triptrip#!/usr/bin/perl # A script to fetch gettext strings from a htmltmpl template. # The strings must be in the special htmltmpl format: # # [string] # # It uses stdin and stdout and takes no parameters. # # Usage: # # cat template.tmpl | perl tmpl-xgettext.pl | xgettext -o file.po - # # Copyright Tomas Styblo, htmltmpl templating engine, 2001 # http://htmltmpl.sourceforge.net/ # tripie@cpan.org # LICENSE: GNU GPL # CVS: $Id: tmpl-xgettext.pl,v 1.1 2001/11/26 08:45:10 tripiecz Exp $ use strict; main(); ################# ### FUNCTIONS ### ################# sub main { my $data = ''; while(<>) { $data .= $_; } my $test = ' [[Pokusny]] [[retezec]]. A ted [[test na vice radcich]]. Eskejpnuta \\[[pitomost]]. Test [[delsi vec [[ test]]. Test [[delsi vec \\[[ test]]. Vnitrni eskejp [[delsi vec test\\]] pokus]] cont. Textik ]]. Textik \\]]. Pokus \a \b. Non \\\\[[eskejp]]. Plain \\eskejp. '; my @gt_strings = (); my $res = parse_gettext($data, \@gt_strings); print "RESULT: $res\n"; my $string; foreach $string (@gt_strings) { $string =~ s/\r?\n/\\n/g; print "gettext(\"$string\")\n"; } } sub parse_gettext { my ($str, $gt_strings) = @_; my @chars = split(//, $str); my $escaped = 0; my $gt_mode = 0; my $gt_index = -1; my $i = 0; my $buf = ''; while(1) { if ($i == @chars) { last; } if ($chars[$i] eq '\\') { $escaped = 0; if ($chars[$i+1] eq '\\') { $buf .= '\\'; $i += 2; next; } elsif ($chars[$i+1] eq '[' || $chars[$i+1] eq ']') { $escaped = 1; } else { $buf .= '\\'; } } elsif ($chars[$i] eq '[' && $chars[$i+1] eq '[') { if ($gt_mode) { if ($escaped) { $escaped = 0; $buf .= '['; $gt_strings->[$gt_index] .= '['; } else { $buf .= '['; $gt_strings->[$gt_index] .= '['; } } else { if ($escaped) { $escaped = 0; $buf .= '['; } else { $gt_mode = 1; $gt_index++; $i += 2; next; } } } elsif ($chars[$i] eq ']' && $chars[$i+1] eq ']') { if ($gt_mode) { if ($escaped) { $escaped = 0; $buf .= ']'; $gt_strings->[$gt_index] .= ']'; } else { $gt_mode = 0; $i += 2; next; } } else { if ($escaped) { $escaped = 0; $buf .= ']'; } else { $buf .= ']'; } } } else { $escaped = 0; if ($gt_mode) { $gt_strings->[$gt_index] .= $chars[$i]; } $buf .= $chars[$i]; } $i++; } return $buf; } htmltmpl-1.22/PKG-INFO0100664000076400007640000000040607407003263013126 0ustar triptripMetadata-Version: 1.0 Name: htmltmpl Version: 1.22 Summary: Templating engine for separation of code and HTML. Home-page: http://htmltmpl.sourceforge.net/ Author: Tomas Styblo Author-email: tripie@cpan.org License: GNU GPL Description: UNKNOWN Platform: UNKNOWN