py2html — CGI Version

py2html

#!/usr/bin/python

"""
An HTML pretty printer for Python source code using the GiPSy scanner.

CGI interface.

Version 1.0

Copyright 2013 Paul Griffiths
Email: mail@paulgriffiths.net

Distributed under the terms of the GNU General Public License.
http://www.gnu.org/licenses/
"""

import sys
import os
import cgi
import cgitb
from gipsy import Py2HTMLParser


def output_http_header(outfile):

    """
    Outputs an HTTP header.

    Arguments:
    outfile -- the file-like object to which to write
    """

    outfile.write('Content-type: text/html\n\n')


def output_html_header(outfile, title, lang):

    """
    Outputs an HTML header.

    Arguments:
    outfile -- a file-like object to output to
    title -- a string for the <title> and <h1> tags
    lang -- "xhtml" or "html5"
    """

    pre_title_xhtml = r"""<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" lang="en">

<head>
  <title>"""

    pre_title_html5 = r"""<!DOCTYPE HTML>

<html>

<head>
  <title>"""

    post_title = r"""</title>
  <link rel="stylesheet" href="/css/code2html.css" type="text/css" media="screen" />
  <link rel="stylesheet" href="/css/py2html.css" type="text/css" media="screen" />
</head>

<body>

<h1>"""

    post_heading = r"""</h1>

"""

    if lang == "xhtml":
        pre_title = pre_title_xhtml
    else:
        pre_title = pre_title_html5

    content = pre_title + title + post_title + title + post_heading
    outfile.write(content)


def output_html_footer(outfile):

    """
    Outputs an HTML footer.

    Arguments:
    outfile -- a file-like object to output to
    """

    outfile.write("</body>\n\n</html>\n\n")


def main():

    """
    py2html main() function.
    """

    # Initialize CGI functionality

    cgitb.enable()
    form = cgi.FieldStorage()

    # Get tab setting from form, or set default

    tabitem = form.getvalue("tabs")

    if tabitem == None:
        tabs = None
    else:
        try:
            tabs = int(tabitem)
        except ValueError:
            tabs = None

    # Output HTTP header and HTML header

    output_http_header(sys.stdout)
    output_html_header(sys.stdout, "py2html Output", "xhtml")

    # Get file from form

    fileitem = form['upfile']

    # Output based on whether we have a valid file

    if fileitem.filename:

        # Strip path info from filename

        f_name = os.path.basename(fileitem.filename)

        # Read contents of file, remove carriage return
        # characters, and expand tabs if necessary

        instr = fileitem.file.read()
        instr = instr.translate(None, "\r")

        if tabs:
            instr = instr.expandtabs(tabs)

        # Set up Py2HTMLParser and tokenize

        pyparser = Py2HTMLParser()
        pyparser.tokenize(instr)

        # Output formatted HTML source file

        sys.stdout.write('<div class="sourcefile">\n')
        sys.stdout.write('<h2>%s</h2>\n\n<pre>\n' % f_name)
        sys.stdout.write(pyparser.read(decorated=True, html=True))
        sys.stdout.write('</pre>\n</div>\n\n')

    else:
        sys.stdout.write('<p>No valid file provided!</p>\n\n')

    # Output HTML footer

    output_html_footer(sys.stdout)


# Entry point to main() function

if __name__ == "__main__":
    main()