Commits

Anonymous committed 65627c8 Merge

merging the htraf-packaging

Comments (0)

Files changed (116)

+syntax: glob
+build
+.*.sw?
+*.pyc
 and you don't have to notify anyone which license you are using. You are
 free to use HTRAF in commercial projects as long as the copyright header
 is left intact.
+
+HTRAF includes the following external libraries:
+
+    jQuery JavaScript Library
+    http://jquery.com/
+    Copyright 2011, John Resig
+
+    jQuery UI
+    http://jqueryui.com/
+    Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+
+    jQuery blockUI plugin 
+    http://jquery.malsup.com/block/
+    Copyright (c) 2007-2010 M. Alsup
+
+    jqPlot Charts
+    http://www.jqplot.com/
+    Copyright (c) 2009 - 2010 Chris Leonello
+
+    JSON in JavaScript
+    http://www.json.org/js.html
+    Public Domain
+
-.PHONY: demo dist
+.PHONY: build dist doc clean
 
-# The connection URI for regression databases.
-SQLITE_REGRESS_DB?=sqlite:///build/regress/regress-sqlite/htsql_regress.sqlite
-PGSQL_ADDRESS?=${PGHOST}$(if ${PGPORT},:${PGPORT})
-PGSQL_REGRESS_DB?=pgsql://htsql_regress:secret@${PGSQL_ADDRESS}/htsql_regress
+HTRAF_VER=2.0.0b1
 
-# The HTTP server address.
-HTSQL_HOST?=localhost
-HTSQL_PORT?=8080
+JQUERY_VER=1.5.1
+JQUERYUI_VER=1.8.13
+JSONJS_VER=master
+BLOCKUI_VER=master
+JQPLOT_VER=0.9.7r629
 
-demo:
-	python demo/serve.py ${PGSQL_REGRESS_DB} ${HTSQL_HOST} ${HTSQL_PORT}
+JSMIN=python -c 'import sys, jsmin; sys.stdout.write(jsmin.jsmin(sys.stdin.read()))'
 
-dist:
-	# Create build directories
+BUILD=build/htraf-${HTRAF_VER}
+
+dist: build
+	cd build; zip -rq htraf-${HTRAF_VER}.zip htraf-${HTRAF_VER}
+
+build:
+	${MAKE} clean ${BUILD}
+
+doc:
+	mkdir -p build
+	sphinx-build -b html doc build/doc
+
+clean:
 	rm -rf build
-	mkdir -p build/dist build/tmp/htraf
-	mkdir -p build/tmp/htraf/js/lib build/tmp/htraf/css/lib
-	# HTRAF itself
-	cp htraf/htraf.js build/tmp/htraf
-	cp htraf/js/htraf.*.js build/tmp/htraf/js
-	cp htraf/css/htraf*.css build/tmp/htraf/css
-	cp -r htraf/img build/tmp/htraf
-	# JSON-js
-	wget -P build/tmp -q --no-check-certificate \
-		https://raw.github.com/douglascrockford/JSON-js/master/json2.js
-	cp build/tmp/json2.js build/tmp/htraf/js/lib
-	# JQuery
-	wget -P build/tmp -q http://code.jquery.com/jquery-1.4.3.min.js
-	cp build/tmp/jquery-1.4.3.min.js build/tmp/htraf/js/lib
-	# JQPlot
-	wget -P build/tmp -q --no-check-certificate \
-		http://bitbucket.org/cleonello/jqplot/downloads/jquery.jqplot.0.9.7r629.tar.gz
-	mkdir build/tmp/jqplot
-	tar -xz -C build/tmp/jqplot -f build/tmp/jquery.jqplot.0.9.7r629.tar.gz
-	mkdir -p build/tmp/htraf/js/lib/jqplot/plugins
-	cp build/tmp/jqplot/dist/excanvas.min.js build/tmp/htraf/js/lib/jqplot
-	cp build/tmp/jqplot/dist/jquery.jqplot.min.js build/tmp/htraf/js/lib/jqplot
-	cp build/tmp/jqplot/dist/plugins/*.min.js build/tmp/htraf/js/lib/jqplot/plugins
-	cp build/tmp/jqplot/dist/jquery.jqplot.min.css build/tmp/htraf/css/lib
-	# blockUI
-	wget -P build/tmp -q --no-check-certificate \
-		https://raw.github.com/malsup/blockui/master/jquery.blockUI.js
-	cp build/tmp/jquery.blockUI.js build/tmp/htraf/js/lib
-	# JQuery UI
-	wget -P build/tmp -q http://jquery-ui.googlecode.com/files/jquery-ui-1.8.5.zip
-	wget -P build/tmp -q http://jquery-ui.googlecode.com/files/jquery-ui-themes-1.8.5.zip
-	unzip -q build/tmp/jquery-ui-1.8.5.zip -d build/tmp
-	unzip -q build/tmp/jquery-ui-themes-1.8.5.zip -d build/tmp
-	cp build/tmp/jquery-ui-1.8.5/ui/minified/jquery-ui.min.js build/tmp/htraf/js/lib/jquery-ui-1.8.5.custom.min.js
-	cp build/tmp/jquery-ui-themes-1.8.5/themes/base/jquery-ui.css build/tmp/htraf/css/lib/jquery-ui-1.8.5.custom.css
-	cp -r build/tmp/jquery-ui-themes-1.8.5/themes/base/images/ build/tmp/htraf/css/lib
-	# Pack the bundle
-	cd build/tmp; zip -rq ../dist/htraf-bundle.zip htraf
-	rm -rf build/tmp
 
+build/json-js:
+	mkdir -p build/json-js
+	git clone https://github.com/douglascrockford/JSON-js build/json-js
+	cd build/json-js; git checkout ${JSONJS_VER}
+
+build/jquery:
+	mkdir -p build/jquery
+	wget -q -O build/jquery/jquery.min.js http://code.jquery.com/jquery-${JQUERY_VER}.min.js
+
+build/jquery-ui:
+	wget -q -P build http://jquery-ui.googlecode.com/files/jquery-ui-${JQUERYUI_VER}.zip
+	unzip -q build/jquery-ui-${JQUERYUI_VER} -d build
+	rm build/jquery-ui-${JQUERYUI_VER}.zip
+	mv build/jquery-ui-${JQUERYUI_VER} build/jquery-ui
+
+build/blockui:
+	mkdir -p build/blockui
+	git clone https://github.com/malsup/blockui build/blockui
+	cd build/blockui; git checkout ${BLOCKUI_VER}
+
+build/jqplot:
+	mkdir -p build/jqplot
+	wget -P build -q --no-check-certificate \
+		http://bitbucket.org/cleonello/jqplot/downloads/jquery.jqplot.${JQPLOT_VER}.tar.gz
+	tar -xz -C build/jqplot -f build/jquery.jqplot.${JQPLOT_VER}.tar.gz
+	rm build/jquery.jqplot.${JQPLOT_VER}.tar.gz
+
+${BUILD}: build/json-js build/jquery build/jquery-ui build/blockui build/jqplot doc
+	mkdir -p ${BUILD}/htraf
+	cp README LICENSE *-LICENSE ${BUILD}
+	cp -r demo ${BUILD}
+	cp -r build/doc ${BUILD}
+	cp src/*.js src/*.css src/*.gif ${BUILD}/htraf
+	mkdir -p ${BUILD}/htraf/lib
+	cat build/json-js/json2.js | ${JSMIN} > ${BUILD}/htraf/lib/json2.min.js
+	cp build/jquery/jquery.min.js ${BUILD}/htraf/lib/jquery.min.js
+	cat build/jquery-ui/ui/minified/jquery.ui.core.min.js \
+		build/jquery-ui/ui/minified/jquery.ui.position.min.js \
+		build/jquery-ui/ui/minified/jquery.ui.widget.min.js \
+		> ${BUILD}/htraf/lib/jquery-ui.custom.min.js
+	cat build/blockui/jquery.blockUI.js | ${JSMIN} \
+		> ${BUILD}/htraf/lib/jquery.blockUI.min.js
+	cp build/jqplot/dist/excanvas.min.js ${BUILD}/htraf/lib
+	cp build/jqplot/dist/jquery.jqplot.min.js ${BUILD}/htraf/lib
+	cp build/jqplot/dist/plugins/*.min.js ${BUILD}/htraf/lib
+	cp build/jqplot/dist/jquery.jqplot.min.css ${BUILD}/htraf/lib
+
-HTRAF Installation Instructions
-===============================
+****************************************************
+  HTRAF -- A Rapid Application Framework for HTSQL
+****************************************************
 
-HTSQL 2.x
----------
+HTRAF is a Javascript toolkit for embedding data into HTML pages.  HTRAF
+uses HTSQL to fetch data from relational databases.
 
-1. Download HTSQL 2.0
-    $ hg clone https://zindel@bitbucket.org/prometheus/htsql
+To start using HTRAF, copy the content of `htraf` directory to the root
+of your website and add the script `/htraf/htraf.js` to your HTML pages.
+For more information on HTRAF, see documentation in `doc` directory.
+An example of a dynamic HTRAF page is located in `demo` directory.
 
-2. Install HTSQL
-    $ cd path/to/htsql && python setup.py develop
+    http://htraf.org/
+        HTRAF homepage and documentation
 
-3. Run tests
-    $ cd path/to/htsql && make test-pgsql
+    http://bitbucket.org/prometheus/htraf
+        HTRAF source code
 
-4. Start HTRAF demo server
-    $ make demo
+    http://htsql.org/
+        HTSQL database query language
 
-5. Open http://127.0.0.1/ in your browser
+    irc://irc.freenode.net#htsql
+        IRC chat in #htsql on freenode
 
-6. Have fun!
+    http://lists.htsql.org/mailman/listinfo/htsql-users
+        The mailing list for users of HTSQL and HTRAF
 
 
-HTSQL 1.x
----------
+HTRAF is copyright by Prometheus Research, LLC and released under dual
+MIT/GPL license; see file `LICENSE` for more details.  HTRAF is written
+by Oleksiy Golovko and Owen McGettrick.
 
-1. Download HTSQL
-
-2. Install HTSQL
-   $ cd path/to/htsql && python setup.py develop
-
-3. Run tests
-   $ cd path/to/htsql && make test-pgsql
-
-4. Install HTRAF plugin
-   $ cd plugins && python setup.py develop
-
-5. Start HTRAF demo server
-   $ htsql-ctl serve htsql_regress -P "htraf.HTRAF"
-
-6. Open http://127.0.0.1/-/htraf/index.html in your browser
-
-7. Have fun!

demo/css/htraf-01.css

+/* Reset CSS start */
+body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,form,fieldset,input,textarea,p,blockquote,th,td { 
+	margin:0;
+	padding:0;
+}
+table {
+	border-collapse:collapse;
+	border-spacing:0;
+}
+fieldset,img { 
+	border:0;
+}
+address,caption,cite,code,dfn,em,strong,th,var {
+	font-style:normal;
+	font-weight:normal;
+}
+ol,ul {
+	list-style:none;
+}
+caption,th {
+	text-align:left;
+}
+h1,h2,h3,h4,h5,h6 {
+	font-size:100%;
+	font-weight:normal;
+}
+q:before,q:after {
+	content:'';
+}
+abbr,acronym {
+    border:0;
+}
+/* Reset CSS end */
+
+
+body {
+    position: relative;
+    font-family: "Trebuchet MS", Arial, Helvetica, Tahoma, Verdana, sans-serif;
+    font-size: 0.9em;
+    padding: 10px;
+}
+
+div.chart {
+    position: absolute;
+    top: 0px;
+    right: 5px;
+    width: 500px;
+    height: 300px;
+    font-size: 1em;
+}
+
+a {
+	color: #069;
+	text-decoration: none;
+	border-bottom: 1px solid #069;
+}
+
+a:hover {
+	border-bottom: 2px solid #069;
+}
+
+h1 {
+    font-weight: bold;
+    font-size: 2em;
+    color: #069;
+}
+
+h2 {
+	margin: 1em 0 0 0;
+	font-weight: bold;
+	color: #069;
+    font-size: 1.4em;
+}
+
+h3 {
+    margin-top: 0.5em;
+    font-weight: bold;
+    font-size: 1.25em;
+    color: #069;
+}
+
+h3 a {
+	color: #069;
+	font-size: 0.8em;
+	font-weight: bold;
+	text-decoration: none;
+	border-bottom: 1px solid #069;
+}
+
+h3 a:hover {
+	border-bottom: 3px solid #069;
+}
+
+.description {
+	color: #555;
+	margin: 0.2em 0 0.5em 0;
+}
+
+p {
+    margin: 0.25em 0;
+    color: #555;
+}
+
+em.htraf, strong.htraf {
+    color: #900;
+    font-weight: bold;
+}
+
+input {
+    font-family: "Trebuchet MS", Arial, Helvetica, Tahoma, Verdana, sans-serif;
+    color: #555;
+}
+
+table.htraf {
+    border-left: 2px solid #ddd;
+    border-right: 2px solid #ddd;
+    border-bottom: 2px solid #ddd;
+}
+
+table.htraf th, table td {
+    padding: 4px 6px;
+    font-size: 0.9em;
+    vertical-align: top;
+}
+
+table.htraf th {
+    background: #ddd;
+    font-weight: bold;
+    color: #555;
+}
+
+table.htraf td {
+    border-right: 1px solid #ddd;
+    border-bottom: 1px solid #ddd;
+}
+
+.htraf-hover {
+    background: #e4f4fc;
+}
+
+.htraf-selected {
+    background: #aecaff;
+}
+
+ul.htraf li {
+	color: #555;
+	padding: 0 0.3em;
+}
+
+/** error **/
+.error {
+	padding: 0.2em;
+    border: 2px solid #c00;
+    background: #fdc;
+}
+
+.error h3 {
+	margin: 0;
+	color: #900;
+}

demo/css/htraf-02.css

+/* Reset CSS start */
+body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,form,fieldset,input,textarea,p,blockquote,th,td { 
+	margin:0;
+	padding:0;
+}
+table {
+	border-collapse:collapse;
+	border-spacing:0;
+}
+fieldset,img { 
+	border:0;
+}
+address,caption,cite,code,dfn,em,strong,th,var {
+	font-style:normal;
+	font-weight:normal;
+}
+ol,ul {
+	list-style:none;
+}
+caption,th {
+	text-align:left;
+}
+h1,h2,h3,h4,h5,h6 {
+	font-size:100%;
+	font-weight:normal;
+}
+q:before,q:after {
+	content:'';
+}
+abbr,acronym {
+    border:0;
+}
+/* Reset CSS end */
+
+
+body {
+    position: relative;
+    font-family: "Trebuchet MS", Arial, Helvetica, Tahoma, Verdana, sans-serif;
+    font-size: 0.9em;
+    padding: 10px;
+}
+
+div.chart {
+    position: absolute;
+    top: 0px;
+    right: 5px;
+    width: 500px;
+    height: 300px;
+    font-size: 1em;
+}
+
+a {
+	color: #900;
+	text-decoration: none;
+	border-bottom: 1px solid #900;
+}
+
+a:hover {
+	border-bottom: 2px solid #900;
+}
+
+h1 {
+    font-weight: bold;
+    font-size: 2em;
+    color: #900;
+}
+h2 {
+    font-weight: bold;
+    font-size: 1.2em;
+    color: #900;
+}
+
+h3 {
+    margin-top: 0.5em;
+    font-weight: bold;
+    font-size: 1.25em;
+    color: #900;
+}
+
+h3 a {
+	color: #900;
+	font-weight: bold;
+	text-decoration: none;
+	border-bottom: 1px solid #900;
+}
+
+h3 a:hover {
+	border-bottom: 3px solid #900;
+}
+
+.description {
+	color: #555;
+	margin: 0.2em 0 0.5em 0;
+}
+
+p {
+    margin: 0.25em 0;
+    color: #555;
+}
+
+em.htraf, strong.htraf {
+    color: #369;
+    font-weight: bold;
+}
+
+input {
+    font-family: "Trebuchet MS", Arial, Helvetica, Tahoma, Verdana, sans-serif;
+    color: #555;
+}
+
+table.htraf {
+    border-left: 2px solid #ddd;
+    border-right: 2px solid #ddd;
+    border-bottom: 2px solid #ddd;
+}
+
+table.htraf th, table td {
+    padding: 4px 6px;
+    font-size: 0.9em;
+    vertical-align: top;
+}
+
+table.htraf th {
+    background: #ddd;
+    font-weight: bold;
+    color: #555;
+}
+
+table.htraf td {
+    border-right: 1px solid #ddd;
+    border-bottom: 1px solid #ddd;
+}
+
+.htraf-hover {
+    background: #f6ddaf;
+}
+
+.htraf-selected {
+    background: #ffa43f;
+}
+
+ul.htraf li {
+	color: #555;
+	padding: 0 0.3em;
+}
+
+/** error **/
+.error {
+	padding: 0.2em;
+    border: 2px solid #c00;
+    background: #fdc;
+}
+
+.error h3 {
+	margin: 0;
+	color: #900;
+}
+<!DOCTYPE html>
+<html>
+  
+<head>
+    <title> HTRAF Demo </title>
+    <script type="text/javascript" 
+            src="../htraf/htraf.js"
+            data-htsql-version="2"
+            data-htsql-prefix="http://demo.htsql.org">
+    </script>
+    <link rel="stylesheet" type="text/css" href="css/htraf-02.css"/>
+</head>
+
+<body>
+
+<h3>Select a School</h3>
+<select id="school"
+        data-htsql="/school{code, name}?exists(department)">
+</select>
+<div style="width: 500px; height: 350px;"
+     data-htsql="/program{title, count(student)}
+                         ?school_code=$school&count(student)>0"
+     data-ref="school"
+     data-type="pie"
+     data-widget="chart"
+     data-title="Percent of Students by Program">
+</div>
+
+<h3>Departments</h3>
+<p>Filter by name: <input id="department_name"/></p>
+<table id="department" data-hide-column-0="yes"
+       data-htsql="/department{code, name, school.name}
+                              ?school_code=$school&name~$department_name"
+       data-ref="school department_name">
+</table>
+<p>
+    The selected department:
+    <em data-htsql="/department{name}?code=$department"
+        data-ref="department">
+    </em>
+    <br/>
+    The number of courses in the selected department:
+    <strong data-htsql="/department{count(course)}?code=$department"
+            data-ref="department">
+    </strong>
+</p>
+
+</body>
+
+</html>

demo/serve.py

-
-import sys
-import os.path
-import mimetypes
-import wsgiref.simple_server, wsgiref.util
-from htsql import HTSQL
-
-
-class Application(object):
-
-    static = 'htraf'
-    prefix = '/@/'
-    index = 'index20.html'
-
-    def __init__(self, htsql):
-        self.htsql = htsql
-
-    def __call__(self, environ, start_response):
-        if environ['REQUEST_METHOD'] != 'GET':
-            start_response("400 Bad Request",
-                           [('Content-Type', 'text/plain')])
-            return ["Only GET requests are supported.\n"]
-        path = environ['PATH_INFO']
-        if path.startswith(self.prefix):
-            wsgiref.util.shift_path_info(environ)
-            return self.htsql(environ, start_response)
-        if path in ('/index.html', '/'):
-            _environ = dict(environ.items()
-                            + [('PATH_INFO', '/demo/index.html')])
-            uri = wsgiref.util.request_uri(_environ)
-            start_response('303 See Other', [('Location', uri)])
-            return []
-        if path == '/demo/index.html':
-            path = '/demo/index20.html'
-        root = os.path.abspath(self.static)
-        path = os.path.abspath(os.path.join(self.static, path[1:]))
-        if not (path == root or path.startswith(root+os.path.sep)) \
-        or path[len(root):].startswith('/demo/examples10'):
-                start_response("404 Not Found",
-                               [('Content-Type', 'text/plain')])
-                return ["Invalid path.\n"]
-        if os.path.isdir(path) and \
-                os.path.exists(os.path.join(path, self.index)):
-            path = os.path.join(path, self.index)
-        if not os.path.isfile(path):
-            start_response("404 Not Found",
-                           [('Content-Type', 'text/plain')])
-            return ["File not found.\n"]
-        mimetype = mimetypes.guess_type(path)[0]
-        if mimetype is None:
-            mimetype = 'application/octet-stream'
-        stream = open(path, 'rb')
-        data = stream.read()
-        stream.close()
-        start_response('200 OK',
-                       [('Content-Type', mimetype),
-                        ('Content-Length', str(len(data)))])
-        return [data]
-
-    @classmethod
-    def main(cls):
-        if len(sys.argv) != 4:
-            return cls.usage()
-        db, host, port = sys.argv[1:]
-        port = int(port)
-        htsql = HTSQL(db)
-        app = cls(htsql)
-        print >>sys.stderr, "Starting the HTRAF demo on http://%s:%s/" \
-                            % (host, port)
-        httpd = wsgiref.simple_server.make_server(host, port, app)
-        httpd.serve_forever()
-
-    @classmethod
-    def usage(cls):
-        return "Usage: %s DB HOST PORT" % sys.argv[0]
-
-
-if __name__ == '__main__':
-    sys.exit(Application.main())
-
-
+# -*- coding: utf-8 -*-
+#
+# HTRAF documentation build configuration file, created by
+# sphinx-quickstart on Mon Jun 13 16:25:54 2011.
+#
+# This file is execfile()d with the current directory set to its containing dir.
+#
+# Note that not all possible configuration values are present in this
+# autogenerated file.
+#
+# All configuration values have a default; values that are commented out
+# serve to show the default.
+
+import sys, os
+
+# If extensions (or modules to document with autodoc) are in another directory,
+# add these directories to sys.path here. If the directory is relative to the
+# documentation root, use os.path.abspath to make it absolute, like shown here.
+#sys.path.insert(0, os.path.abspath('.'))
+sys.path.insert(0, os.path.join(os.path.abspath('.'), 'extensions'))
+
+# -- General configuration -----------------------------------------------------
+
+# Set when building documentation for htsql.org.
+build_website = False
+
+# If your documentation needs a minimal Sphinx version, state it here.
+#needs_sphinx = '1.0'
+
+# Add any Sphinx extension module names here, as strings. They can be extensions
+# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
+extensions = ['sphinx.ext.ifconfig',
+              'sphinxext_htsqldoc', 'sphinxext_htrafdemo']
+
+# The default URL of an HTSQL service.
+htsql_server = 'http://demo.htsql.org'
+
+# Add any paths that contain templates here, relative to this directory.
+#templates_path = ['_templates']
+
+# The suffix of source filenames.
+source_suffix = '.rst'
+
+# The encoding of source files.
+#source_encoding = 'utf-8-sig'
+
+# The master toctree document.
+master_doc = 'index'
+
+# General information about the project.
+project = u'HTRAF'
+copyright = (u'2006-2011 Prometheus Research, LLC;'
+              ' written by Oleksiy Golovko and Owen McGettrick')
+
+# The version info for the project you're documenting, acts as replacement for
+# |version| and |release|, also used in various other places throughout the
+# built documents.
+#
+# The short X.Y version.
+version = '2.0'
+# The full version, including alpha/beta/rc tags.
+release = '2.0.0b1'
+
+# The language for content autogenerated by Sphinx. Refer to documentation
+# for a list of supported languages.
+#language = None
+
+# There are two options for replacing |today|: either, you set today to some
+# non-false value, then it is used:
+#today = ''
+# Else, today_fmt is used as the format for a strftime call.
+#today_fmt = '%B %d, %Y'
+
+# List of patterns, relative to source directory, that match files and
+# directories to ignore when looking for source files.
+exclude_patterns = []
+
+# The reST default role (used for this markup: `text`) to use for all documents.
+default_role = 'obj'
+
+# If true, '()' will be appended to :func: etc. cross-reference text.
+#add_function_parentheses = True
+
+# If true, the current module name will be prepended to all description
+# unit titles (such as .. function::).
+#add_module_names = True
+
+# If true, sectionauthor and moduleauthor directives will be shown in the
+# output. They are ignored by default.
+#show_authors = False
+
+# The name of the Pygments (syntax highlighting) style to use.
+pygments_style = 'sphinx'
+
+# A list of ignored prefixes for module index sorting.
+#modindex_common_prefix = []
+
+
+# -- Options for HTML output ---------------------------------------------------
+
+# The theme to use for HTML and HTML Help pages.  See the documentation for
+# a list of builtin themes.
+html_theme = 'default'
+
+# Theme options are theme-specific and customize the look and feel of a theme
+# further.  For a list of options available for each theme, see the
+# documentation.
+#html_theme_options = {}
+
+# Add any paths that contain custom themes here, relative to this directory.
+#html_theme_path = []
+
+# The name for this set of Sphinx documents.  If None, it defaults to
+# "<project> v<release> documentation".
+#html_title = None
+
+# A shorter title for the navigation bar.  Default is the same as html_title.
+#html_short_title = None
+
+# The name of an image file (relative to this directory) to place at the top
+# of the sidebar.
+#html_logo = None
+
+# The name of an image file (within the static path) to use as favicon of the
+# docs.  This file should be a Windows icon file (.ico) being 16x16 or 32x32
+# pixels large.
+#html_favicon = None
+
+# Add any paths that contain custom static files (such as style sheets) here,
+# relative to this directory. They are copied after the builtin static files,
+# so a file named "default.css" will overwrite the builtin "default.css".
+#html_static_path = ['_static']
+
+# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
+# using the given strftime format.
+#html_last_updated_fmt = '%b %d, %Y'
+
+# If true, SmartyPants will be used to convert quotes and dashes to
+# typographically correct entities.
+#html_use_smartypants = True
+
+# Custom sidebar templates, maps document names to template names.
+#html_sidebars = {}
+
+# Additional templates that should be rendered to pages, maps page names to
+# template names.
+#html_additional_pages = {}
+
+# If false, no module index is generated.
+#html_domain_indices = True
+
+# If false, no index is generated.
+#html_use_index = True
+
+# If true, the index is split into individual pages for each letter.
+#html_split_index = False
+
+# If true, links to the reST sources are added to the pages.
+#html_show_sourcelink = True
+
+# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
+#html_show_sphinx = True
+
+# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
+#html_show_copyright = True
+
+# If true, an OpenSearch description file will be output, and all pages will
+# contain a <link> tag referring to it.  The value of this option must be the
+# base URL from which the finished HTML is served.
+#html_use_opensearch = ''
+
+# This is the file name suffix for HTML files (e.g. ".xhtml").
+#html_file_suffix = None
+
+# Output file base name for HTML help builder.
+htmlhelp_basename = 'HTRAFdoc'
+
+
+# -- Options for LaTeX output --------------------------------------------------
+
+# The paper size ('letter' or 'a4').
+#latex_paper_size = 'letter'
+
+# The font size ('10pt', '11pt' or '12pt').
+#latex_font_size = '10pt'
+
+# Grouping the document tree into LaTeX files. List of tuples
+# (source start file, target name, title, author, documentclass [howto/manual]).
+latex_documents = [
+  ('index', 'HTRAF.tex', u'HTRAF Documentation',
+   u'2006-2011 Prometheus Reserch', 'manual'),
+]
+
+# The name of an image file (relative to this directory) to place at the top of
+# the title page.
+#latex_logo = None
+
+# For "manual" documents, if this is true, then toplevel headings are parts,
+# not chapters.
+#latex_use_parts = False
+
+# If true, show page references after internal links.
+#latex_show_pagerefs = False
+
+# If true, show URL addresses after external links.
+#latex_show_urls = False
+
+# Additional stuff for the LaTeX preamble.
+#latex_preamble = ''
+
+# Documents to append as an appendix to all manuals.
+#latex_appendices = []
+
+# If false, no module index is generated.
+#latex_domain_indices = True
+
+
+# -- Options for manual page output --------------------------------------------
+
+# One entry per manual page. List of tuples
+# (source start file, name, description, authors, manual section).
+man_pages = [
+    ('index', 'htraf', u'HTRAF Documentation',
+     [u'2006-2011 Prometheus Research'], 1)
+]

doc/extensions/sphinxext_htrafdemo/__init__.py

+
+from docutils import nodes
+from docutils.parsers.rst import Directive, directives
+from sphinx.util.osutil import copyfile
+
+from urllib import urlopen
+import os.path
+
+
+JQUERY_URL = "http://code.jquery.com/jquery-1.5.2.min.js"
+
+
+class DemoDirective(Directive):
+
+    has_content = True
+    option_spec = {
+            'source': directives.flag,
+            'hide': directives.flag,
+    }
+
+    def run(self):
+        wrapper = nodes.compound(classes=['demo-block'])
+        data = "\n".join(self.content)
+        demo = nodes.raw(data, data,
+                         format='html',
+                         classes=['demo-area'])
+        source = nodes.literal_block(data, data,
+                                     language='html',
+                                     classes=['demo-source'])
+        switch = nodes.literal(classes=['demo-switch'])
+        if 'source' not in self.options:
+            if 'hide' not in self.options:
+                switch += nodes.Text("[- view source]")
+            else:
+                switch += nodes.Text("[+ view source]")
+                source['classes'].append('demo-hide')
+            wrapper += demo
+            wrapper += switch
+            wrapper += source
+        else:
+            if 'hide' not in self.options:
+                switch += nodes.Text("[- view demo]")
+            else:
+                switch += nodes.Text("[+ view demo]")
+                demo['classes'].append('demo-hide')
+            wrapper += source
+            wrapper += switch
+            wrapper += demo
+        return [wrapper]
+
+
+def copy_static(app, exception):
+    if app.builder.name != 'html' or exception:
+        return
+    src_dir = os.path.join(os.path.abspath(os.path.dirname(__file__)), 'static')
+    dst_dir = os.path.join(app.builder.outdir, '_static')
+    for filename in os.listdir(src_dir):
+        src = os.path.join(src_dir, filename)
+        if not os.path.isfile(src):
+            continue
+        dst = os.path.join(dst_dir, filename)
+        copyfile(src, dst)
+    data = urlopen(JQUERY_URL).read()
+    open(os.path.join(dst_dir, 'jquery.js'), 'w').write(data)
+
+
+def setup(app):
+    app.add_directive('demo', DemoDirective)
+    app.connect('build-finished', copy_static)
+    app.add_stylesheet('htrafdemo.css')
+    app.add_javascript('htrafdemo.js')
+
+

doc/extensions/sphinxext_htrafdemo/static/htrafdemo.css

+
+div.demo-block {
+  margin: 1em 0 0;
+}
+
+div.demo-block tt.demo-switch {
+  cursor: pointer;
+  font-size: 95%;
+  background-color: inherit;
+}
+
+div.demo-block div.demo-area {
+/*  background-color: yellow; */
+}
+
+/* div.demo-block div.demo-source {
+  display: none;
+}*/
+
+div.demo-block div.demo-hide {
+  display: none;
+}
+
+.demo-area h1,
+.demo-area h2,
+.demo-area h3 {
+  color: #900;
+}
+
+.demo-area em.htraf,
+.demo-area strong.htraf {
+  color: #369;
+}
+
+.demo-area table.htraf {
+	border-collapse: collapse;
+	border-spacing: 0;
+  border-left: 2px solid #ddd;
+  border-right: 2px solid #ddd;
+  border-bottom: 2px solid #ddd;
+}
+
+.demo-area table.htraf th,
+.demo-area table td {
+  padding: 4px 6px;
+  font-size: 90%;
+  vertical-align: top;
+}
+
+.demo-area table.htraf th {
+  background: #ddd;
+  font-weight: bold;
+  color: #555;
+}
+
+.demo-area table.htraf td {
+  border-right: 1px solid #ddd;
+  border-bottom: 1px solid #ddd;
+}
+
+.demo-area ul.htraf,
+.demo-area ol.htraf {
+  background: #ddd;
+}
+
+.demo-area ul.htraf li,
+.demo-area ol.htraf li {
+  margin: 0;
+}
+
+.demo-area .htraf-hover {
+  background: #f6ddaf;
+}
+
+.demo-area .htraf-selected {
+  background: #ffa43f;
+}
+

doc/extensions/sphinxext_htrafdemo/static/htrafdemo.js

+
+
+
+$(function () {
+    $('.demo-switch').click(function () {
+        var text = $(this).text()
+        if (text == '[+ view source]') {
+            $(this).next('.demo-source').slideDown('fast');
+            $(this).text('[- view source]');
+        }
+        else if (text == '[- view source]') {
+            $(this).next('.demo-source').slideUp('fast');
+            $(this).text('[+ view source]');
+        }
+        else if (text == '[+ view demo]') {
+            $(this).next('.demo-area').slideDown('fast');
+            $(this).text('[- view demo]');
+        }
+        else if (text == '[- view demo]') {
+            $(this).next('.demo-area').slideUp('fast');
+            $(this).text('[+ view demo]');
+        }
+    });
+});
+
+
+*******************
+  HTRAF Reference
+*******************
+
+HTRAF is a toolkit for embedding data into HTML pages.  HTRAF lets an
+HTML designer to associate certain HTML elements with data sources; then,
+when the page is opened in a browser, HTRAF automatically fetches the
+data from the database and populates the selected elements.
+
+HTRAF is based upon JQuery_ Javascript framework and relies on an HTSQL_
+service to retrieve data from the database.
+
+.. _HTSQL: http://htsql.org/
+.. _JQuery: http://jquery.org/
+
+HTRAF is written by Oleksiy Golovko and Owen McGettrick and released
+under the same licenses as JQuery_.
+
+
+Overview
+========
+
+Extracting and presenting data from a relational database is one of
+the most common tasks in web development.  The usual approach splits
+this task into several *tiers*:
+
+* a database tier that stores the data;
+* a middleware tier is a server side application that retrieves data
+  from the database and renders it into HTML;
+* a presentation tier is a web browser that displays the rendered
+  page to the users.
+
+While powerful and generic, this approach is quite heavyweight.  HTSQL
+and HTRAF radically simplify it by eliminating the middleware tier;
+instead you embed the data from the database directly to an HTML page.
+
+Take the following use case: allow a user to select a *school* from
+a drop-down list, then, for the selected school, display associated
+*departments* together with the *number of courses* offered by each
+department.
+
+(In all examples below, we use a sample database of a student enrollment
+system in a fictional university.  The database contains schools,
+programs administered by a school, departments associated with a school,
+and courses offered by a department.)
+
+Here is how we implement this use case with HTRAF:
+
+.. demo::
+   :source:
+   :hide:
+
+    <select id="school_1"
+        data-htsql="/school{code, name}?exists(department)">
+    </select>
+
+    <table
+        data-htsql="/department{name, count(course)}?school.code=$school_1"
+        data-ref="school_1">
+    </table>
+
+This HTML fragment contains two elements: ``<select>`` and ``<table>``
+which display a drop-down list of schools and a list of associated
+departments respectively.  The elements (we call them *widgets*) are
+empty, but have some extra attributes.
+
+The ``data-htsql`` attribute contains an HTSQL query; it instructs
+HTRAF to execute the query and use the result to populate the content
+of the widget.  Take a look at the output of the query:
+
+.. htsql:: /school{code, name}?exists(department)
+   :cut: 4
+
+HTRAF renders this output into the following HTML code:
+
+.. sourcecode:: html
+
+    <select id="school_1">
+        <option value="art">School of Art and Design</option>
+        <option value="bus">School of Business</option>
+        <option value="edu">College of Education</option>
+        <option value="eng">School of Engineering</option>
+        ...
+    </select>
+
+The ``<table>`` widget is more interesting.  To indicate that the
+``<table>`` widget depends on the ``<select>`` list and should be
+updated when some row in the list is selected, we assign anchor
+``id="school_1"`` to the ``<select>`` element and add attribute
+``data-ref="school_1"`` to ``<table>``.  The selected value is available
+in HTSQL under the name ``$school_1``.
+
+For example, if the user selects *School of Engineering* in the
+drop-down list, then to update the linked table, HTRAF will execute the
+query:
+
+.. htsql::
+   :cut: 4
+
+    /department{name, count(course)}?school.code=$school_1
+     :where $school_1 := 'eng'
+
+For more information on HTSQL syntax and semantics, see `HTSQL Tutorial
+<http://htsql.org/doc/tutorial.html>`_; this document describes how to use
+HTRAF toolkit to embed results of HTSQL queries into HTML pages.
+
+Prerequisites
+=============
+
+HTRAF uses an HTSQL service to retrieve data from the database; therefore, in
+order to use HTRAF, you need to install HTSQL and deploy it as a web service
+against your database.  See `HTSQL Installation Guide
+<http://htsql.org/doc/install.html>`_ for more details.
+
+It is strongly recommended to configure the HTTP server to serve both
+HTSQL service and HTML pages from the same domain; otherwise browser
+security settings would prevent HTRAF from accessing HTSQL service.
+That could be circumvented by using CORS on the HTSQL service, but note
+that not all browsers support CORS.  For more details on CORS, see `CORS
+W3C specification`_.
+
+.. _CORS W3C specification: http://www.w3.org/TR/cors/
+
+Then download and install HTRAF.  HTRAF is a pure Javascript toolkit, so
+simply unpack the archive to where you keep other static data for your
+website.
+
+To start using HTRAF, include the script ``htraf.js`` to your HTML
+pages.
+
+.. ifconfig:: build_website
+
+    .. demo::
+       :source:
+       :hide:
+
+        <script type="text/javascript"
+            src="/htraf/htraf.js"
+            data-htsql-version="2"
+            data-htsql-prefix="/@demo">
+        </script>
+
+.. ifconfig:: not build_website
+
+    .. demo::
+       :source:
+       :hide:
+
+        <script type="text/javascript"
+            src="../htraf/htraf.js"
+            data-htsql-version="2"
+            data-htsql-prefix="http://demo.htsql.org">
+        </script>
+
+In addition to regular ``<script>`` attributes, we added two extra
+attributes:
+
+`data-htsql-prefix` (absolute or relative URL)
+    This specifies the root of the HTSQL service; in the example above,
+    HTSQL service is located at http://htsql.org/@demo.
+
+    Note that the URL should not include a trailing slash.
+
+`data-htsql-version` (``1`` or ``2``)
+    The major version of HTSQL; currently the only meaningful value
+    is ``2``.  (HTSQL 1 is used for in-house projects of `Prometheus
+    Research`_.)
+
+.. _Prometheus Research: http://prometheusresearch.com/
+
+
+Widgets
+=======
+
+HTML elements controlled by HTRAF are called *widgets*.  HTRAF supports
+a number of different widgets: drop-down and regular lists, tables,
+charts, and also provides an API to define new widget types.
+
+Widget elements should not contain any subelements since the content of
+the widget is populated and maintained by HTRAF.
+
+Linking
+-------
+
+Common Attributes
+-----------------
+
+A widget may possess the following attributes: 
+
+`id` (a unique identifier)
+    Indicates the name of the widget, must be unique across the whole
+    HTML page.  The name is used when declaring widget dependencies,
+    see description of `data-ref` attribute for more details.
+
+`data-widget` (widget type: ``select``, ``table``, ``chart``, etc)
+    HTRAF determines the type of the widget from the value of this
+    attribute.  In the absense of `data-widget`, HTRAF assumes the type
+    coincides with the tag name.  Conveniently, commonly used widget
+    types are called ``select``, ``table``, ``ul``, etc., so often there
+    is no need to specify the widget type explicitly.
+
+`data-htsql` (an HTSQL query)
+    HTSQL query executed to populate the widget.  This is a mandatory
+    attribute since it used by HTRAF to find widgets on the page.
+
+`data-ref` (list of widget identifiers)
+    If present, indicates that the content of the widget depends on
+    other widgets. 
+
+Common Classes
+--------------
+
+`htraf-selected`
+
+`htraf-hover`
+
+
+Now suppose you conjured an HTSQL query that generates the output
+you want and now you want to embed the output to the page.
+
+Let's take the query:
+
+.. htsql:: /department{name, count(course)}?school.code='eng'
+
+That produces the number of course per department in the school
+of *Engineering*.  The following code utilizes HTRAF to embed
+the output of the query as a table:
+
+.. demo::
+   :source:
+   :hide:
+
+    <table data-htsql="/department{name, count(course)}?school.code='eng'">
+    </table>
+
+In this HTML fragment, attribute ``data-htsql`` instructs HTRAF
+to execute the given query and populate the table with the query
+output.
+
+HTRAF is not limited to tables, it could also produce lists,
+charts, etc.  You can also extend HTRAF with your own widgets.
+
+For instance, the following code uses HTRAF to populate a select
+list.
+
+.. demo::
+   :source:
+   :hide:
+
+    <select data-htsql="/school{code, name}?exists(department)">
+    </select>
+
+In this case, the query
+
+.. htsql:: /school{code, name}?exists(department)
+   :cut: 3
+
+lists the code and the name of schools that have at least one
+associated department.  The first column ``code`` is used to populate
+the ``value`` of the select list, the second column ``name`` populates
+the content of the select list.
+
+HTRAF allows you to bind elements together so that selecting
+a value in one element updates another element.  For example,
+we could bind the two elements above so that a choice done
+in a select list updates the table content.
+
+Note the extra attribute `data-ref` on the table widget.  It indicates
+that the widget uses the data from another widget called ``school``
+and should be updated whenever the ``school`` widget is updated.
+
+
+Widgets
+=======
+
+HTML elements that display data are called *HTRAF widgets*.  HTRAF
+recognizes widgets by presence of attribute `data-htsql`.
+
+HTRAF supports a numerous types of widgets and allows one to extend it
+with custom widgets.  The type of a widget is determined as follows:
+
+* The value of attribute `data-widget` if it is set.
+* Otherwise, the name of the tag; if it is a valid widget name.
+* Otherwise, use *singleValue* --- the default widget.
+
+In the following example, the type of the widget is determined
+from value of ``data-widget``:
+
+.. demo::
+   :source:
+   :hide:
+
+    <div width="500" height="400"
+        data-widget="chart"
+        data-htsql="/department{name, count(course)}?school.code='eng'">
+    </div>
+
+
+HTRAF takes over the widget content, preserving the tag itself,
+but replacing the content with generated data.
+
+Some widgets (such as table or select list) allows one to select
+a row in the output.
+
+
+
+Table Widget
+============
+
+Probably the most common widget in HTRAF, *table* renders data using
+HTML ``<table>`` element.
+
+The *table* widget is selectable, when selected, it emits the value
+from the first output column.
+
+Example
+-------
+
+.. demo::
+   :source:
+
+    <table data-htsql="/school">
+    </table>
+
+Attributes
+----------
+
+`data-hide-column-0` (``true``)
+    Do not display the first output column.
+
+    Useful when the first column contains a value of the key to pass to
+    dependent widgets, but the the value itself is not needed in the
+    output.
+
+    Example:
+
+    .. demo::
+       :source:
+       :hide:
+
+        <h3>Select a School</h3>
+        <table id="school_2"
+            data-htsql="/school{code, name}?exists(department)"
+            data-hide-column-0="true">
+        </table>
+
+        <h3>Associated Departments</h3>
+        <table
+            data-htsql="/department{name}?school.code=$school_2"
+            data-ref="school_2">
+        </table>
+
+    Even though the query produces two columns, the first column is
+    hidden from the table.  It is still used to pass the school code to
+    the dependent widget.
+
+CSS Classes
+-----------
+
+`rN` (*N* is integer starting from *0*)
+    Set on *N*-th row (``<tr>``) element of the widget.
+
+`cN` (*N* is integer starting from *0*)
+    Set on each *N*-th column (``<td>``) element of the widget.
+
+`even`, `odd`
+    Set on each even/odd row element.
+
+
+Select Widget
+=============
+
+The *select* widget presents data in the form of a drop-down menu using
+a ``<select>`` element.
+
+The associate HTSQL query should produce two or one columns.  When the
+output has two columns, they are used to populate the value and the label
+of each option; if only one column is available, it is used to populate
+both the value and the label.
+
+Example
+-------
+
+.. demo::
+   :source:
+   :hide:
+
+    <select data-htsql="/school{code}">
+    </select>
+
+    <select data-htsql="/school{code, name}">
+    </select>
+
+Attributes
+----------
+
+`multiple`
+    The select widget admits multiple selections.  When more then one
+    choice is selected, the values are passed to the dependent widgets
+    as a selector.
+
+    Example:
+
+    .. demo::
+       :source:
+       :hide:
+
+        <select id="school_3" size="4" multiple
+            data-htsql="/school{code, name}?exists(department)">
+        </select>
+
+        <table
+            data-htsql="/department{name}?school.code=$school_3"
+            data-ref="school_3">
+        </table>
+
+UL and OL Widgets
+=================
+
+The *ul* and *ol* widgets present data in a form of an unordered and
+ordered lists using ``<ul>`` and ``<ol>`` HTML elements.
+
+Just like select widgets, the ul and ol widgets accept input data with
+one or two columns; when two columns are given, the second column is
+used to populate the content of each entry.
+
+Example
+-------
+
+.. demo::
+   :source:
+
+    <ul data-htsql="/school{code}?exists(department)">
+    </ul>
+
+    <ol data-htsql="/school{code, name}?exists(department)">
+    </ol>
+
+
+IFrame Widget
+=============
+
+The *iframe* widget embeds the response from the HTSQL server into a
+frame.  This is the only widget that does not render JSON data, but
+relies on HTSQL server to send formatted output in HTML.
+
+Example
+-------
+
+.. demo::
+   :source:
+
+    <iframe width="600" height="300"
+        data-htsql="/school{code, name}?exists(department)">
+    </iframe>
+
+
+Chart Widget
+============
+
+The *chart* widget presents data in a graphical form.  The first column
+of the output specifies the chart labels, the remaining columns specify
+the respective values.
+
+Since HTML does not have a ``<chart>`` element, you need to specify the
+widget type using ``data-widget`` attribute.
+
+Example
+-------
+
+.. demo::
+   :source:
+
+    <div style="width: 700px; height: 350px"
+        data-widget="chart"
+        data-yint="true"
+        data-title="Number of Departments by School"
+        data-htsql="/school{code,
+                            num_dept := count(department)}
+                           ?num_dept>0">
+    </div>
+
+Chart Types
+-----------
+
+The widget provides several types of charts: bar chart, pie chart and
+line chart.  The chart type is specified using `data-type` attribute.
+
+Bar Chart
+~~~~~~~~~
+
+To display a bar chart, the input data should contain two or more
+columns: the first column contains the labels, the subsequent
+columns are numeric values.  Each value is represented by the
+height of a rectangular bar.
+
+.. demo::
+   :source:
+   :hide:
+
+    <div style="width: 345px; height: 325px"
+        data-widget="chart"
+        data-type="bar"
+        data-yint="true"
+        data-title="Bar Chart"
+        data-htsql="/school{code,
+                            num_dept := count(department),
+                            num_prog := count(program)}
+                           ?num_dept>2&num_prog>2">
+    </div>
+
+Stacked Bar Chart
+~~~~~~~~~~~~~~~~~
+
+Same as the regular bar chart except that when the data contain two
+or more value columns, the respective bars are stacked in a single
+line.
+
+.. demo::
+   :source:
+   :hide:
+
+    <div style="width: 345px; height: 325px"
+        data-widget="chart"
+        data-type="stack"
+        data-yint="true"
+        data-title="Stacked Bar Chart"
+        data-htsql="/school{code,
+                            num_dept := count(department),
+                            num_prog := count(program)}
+                           ?num_dept>2&num_prog>2">
+    </div>
+
+Pie Chart
+~~~~~~~~~
+
+For a pie chart, the input data should contain two columns: the
+labels and respective numeric values.
+
+.. demo::
+   :source:
+   :hide:
+
+    <div style="width: 345px; height: 325px"
+        data-widget="chart"
+        data-type="pie"
+        data-yint="true"
+        data-title="Pie Chart"
+        data-htsql="/school{code,
+                            num_dept := count(department)}
+                           ?num_dept>2">
+    </div>
+
+Line Chart
+~~~~~~~~~~
+
+To generate a line chart, the input data should contain two or more
+columns: the first column contains (numeric or date) values for the
+*X* axis, the rest contain numeric values for the *Y* axis.
+
+.. demo::
+   :source:
+   :hide:
+
+    <div style="width: 345px; height: 325px"
+        data-widget="chart"
+        data-type="line"
+        data-yint="true"
+        data-title="Line Chart"
+        data-htsql="/(school^{num_dept := count(department)})
+                            {num_dept,
+                             num_school := count(school),
+                             num_prog := count(school.program)}">
+    </div>
+
+Attributes
+----------
+
+`style`
+
+`data-type` (``bar`` (default), ``stack``, ``pie``, ``line``)
+
+`data-legend` (``ne`` (default), ``se``, ``nw``, ``sw``, ``no``)
+
+`data-title` (a string)
+
+`data-show-title` (``true`` (default) or ``false``)
+
+`data-yint` (``true`` or ``false`` (default))
+
+`data-x-vertical` (``true`` or ``false`` (default))
+
+
+
+
+singleValue
+===========
+
+This is a fall-back widget, it is used when the actual widget type is not found.
+The widget replaces the content of the tag with the value from the first row and the
+first column of the output.
+
+Example
+-------
+
+.. demo::
+   :source:
+
+    <p>The database contains
+    <strong data-htsql="/count(school)"></strong>
+    records in the <em>school</em> table and
+    <strong data-htsql="/count(department)"></strong>
+    records in the <em>department</em> table.</p>
+
+
+Common Attributes
+=================
+
+`data-htsql`
+
+`data-widget`
+
+`data-onchange`
+
+`data-onerror`
+
+`data-empty`
+
+`data-onbeforeload`
+
+`data-onafterload`
+
+

htraf/ajax.gif

Removed
Old image

htraf/demo/css/htraf-01.css

-/* Reset CSS start */
-body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,form,fieldset,input,textarea,p,blockquote,th,td { 
-	margin:0;
-	padding:0;
-}
-table {
-	border-collapse:collapse;
-	border-spacing:0;
-}
-fieldset,img { 
-	border:0;
-}
-address,caption,cite,code,dfn,em,strong,th,var {
-	font-style:normal;
-	font-weight:normal;
-}
-ol,ul {
-	list-style:none;
-}
-caption,th {
-	text-align:left;
-}
-h1,h2,h3,h4,h5,h6 {
-	font-size:100%;
-	font-weight:normal;
-}
-q:before,q:after {
-	content:'';
-}
-abbr,acronym {
-    border:0;
-}
-/* Reset CSS end */
-
-
-body {
-    position: relative;
-    font-family: "Trebuchet MS", Arial, Helvetica, Tahoma, Verdana, sans-serif;
-    font-size: 0.9em;
-    padding: 10px;
-}
-
-div.chart {
-    position: absolute;
-    top: 0px;
-    right: 5px;
-    width: 500px;
-    height: 300px;
-    font-size: 1em;
-}
-
-a {
-	color: #069;
-	text-decoration: none;
-	border-bottom: 1px solid #069;
-}
-
-a:hover {
-	border-bottom: 2px solid #069;
-}
-
-h1 {
-    font-weight: bold;
-    font-size: 2em;
-    color: #069;
-}
-
-h2 {
-	margin: 1em 0 0 0;
-	font-weight: bold;
-	color: #069;
-    font-size: 1.4em;
-}
-
-h3 {
-    margin-top: 0.5em;
-    font-weight: bold;
-    font-size: 1.25em;
-    color: #069;
-}
-
-h3 a {
-	color: #069;
-	font-size: 0.8em;
-	font-weight: bold;
-	text-decoration: none;
-	border-bottom: 1px solid #069;
-}
-
-h3 a:hover {
-	border-bottom: 3px solid #069;
-}
-
-.description {
-	color: #555;
-	margin: 0.2em 0 0.5em 0;
-}
-
-p {
-    margin: 0.25em 0;
-    color: #555;
-}
-
-em.htraf, strong.htraf {
-    color: #900;
-    font-weight: bold;
-}
-
-input {
-    font-family: "Trebuchet MS", Arial, Helvetica, Tahoma, Verdana, sans-serif;
-    color: #555;
-}
-
-table.htraf {
-    border-left: 2px solid #ddd;
-    border-right: 2px solid #ddd;
-    border-bottom: 2px solid #ddd;
-}
-
-table.htraf th, table td {
-    padding: 4px 6px;
-    font-size: 0.9em;
-    vertical-align: top;
-}
-
-table.htraf th {
-    background: #ddd;
-    font-weight: bold;
-    color: #555;
-}
-
-table.htraf td {
-    border-right: 1px solid #ddd;
-    border-bottom: 1px solid #ddd;
-}
-
-.htraf-hover {
-    background: #e4f4fc;
-}
-
-.htraf-selected {
-    background: #aecaff;
-}
-
-ul.htraf li {
-	color: #555;
-	padding: 0 0.3em;
-}
-
-/** error **/
-.error {
-	padding: 0.2em;
-    border: 2px solid #c00;
-    background: #fdc;
-}
-
-.error h3 {
-	margin: 0;
-	color: #900;
-}

htraf/demo/css/htraf-02.css

-/* Reset CSS start */
-body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,form,fieldset,input,textarea,p,blockquote,th,td { 
-	margin:0;
-	padding:0;
-}
-table {
-	border-collapse:collapse;
-	border-spacing:0;
-}
-fieldset,img { 
-	border:0;
-}
-address,caption,cite,code,dfn,em,strong,th,var {
-	font-style:normal;
-	font-weight:normal;
-}
-ol,ul {
-	list-style:none;
-}
-caption,th {
-	text-align:left;
-}
-h1,h2,h3,h4,h5,h6 {
-	font-size:100%;
-	font-weight:normal;
-}
-q:before,q:after {
-	content:'';
-}
-abbr,acronym {
-    border:0;
-}
-/* Reset CSS end */
-
-
-body {
-    position: relative;
-    font-family: "Trebuchet MS", Arial, Helvetica, Tahoma, Verdana, sans-serif;
-    font-size: 0.9em;
-    padding: 10px;
-}
-
-div.chart {
-    position: absolute;
-    top: 0px;
-    right: 5px;
-    width: 500px;
-    height: 300px;
-    font-size: 1em;
-}
-
-a {
-	color: #900;
-	text-decoration: none;
-	border-bottom: 1px solid #900;
-}
-
-a:hover {
-	border-bottom: 2px solid #900;
-}
-
-h1 {
-    font-weight: bold;
-    font-size: 2em;
-    color: #900;
-}
-h2 {
-    font-weight: bold;
-    font-size: 1.2em;
-    color: #900;
-}
-
-h3 {
-    margin-top: 0.5em;
-    font-weight: bold;
-    font-size: 1.25em;
-    color: #900;
-}
-
-h3 a {
-	color: #900;
-	font-weight: bold;
-	text-decoration: none;
-	border-bottom: 1px solid #900;
-}
-
-h3 a:hover {
-	border-bottom: 3px solid #900;
-}
-
-.description {
-	color: #555;
-	margin: 0.2em 0 0.5em 0;
-}
-
-p {
-    margin: 0.25em 0;
-    color: #555;
-}
-
-em.htraf, strong.htraf {
-    color: #369;
-    font-weight: bold;
-}
-
-input {
-    font-family: "Trebuchet MS", Arial, Helvetica, Tahoma, Verdana, sans-serif;
-    color: #555;
-}
-
-table.htraf {
-    border-left: 2px solid #ddd;
-    border-right: 2px solid #ddd;
-    border-bottom: 2px solid #ddd;
-}
-
-table.htraf th, table td {
-    padding: 4px 6px;
-    font-size: 0.9em;
-    vertical-align: top;
-}
-
-table.htraf th {
-    background: #ddd;
-    font-weight: bold;
-    color: #555;
-}
-
-table.htraf td {
-    border-right: 1px solid #ddd;
-    border-bottom: 1px solid #ddd;
-}
-
-.htraf-hover {
-    background: #f6ddaf;
-}
-
-.htraf-selected {
-    background: #ffa43f;
-}
-
-ul.htraf li {
-	color: #555;
-	padding: 0 0.3em;
-}
-
-/** error **/
-.error {
-	padding: 0.2em;
-    border: 2px solid #c00;
-    background: #fdc;
-}
-
-.error h3 {
-	margin: 0;
-	color: #900;
-}

htraf/demo/doc.html

-<!DOCTYPE html>
-<html>
-<head>
-    <title>HTRAF Documentation</title>
-    <link type="text/css" rel="stylesheet" href="css/htraf-02.css"/>
-    <script language="JavaScript" src="../js/lib/jquery-1.4.3.js"></script>
-    <script language="JavaScript" src="../js/lib/creole.js"></script>
-    <script language="JavaScript">
-        function id(s) {
-            return $.trim(s).toLowerCase().replace(/[^A-Za-z_-]/g, '_');
-        }
-        Parse.Simple.Doc = function(options) {
-            Parse.Simple.Creole.call(this, options);
-                
-            var g = this.grammar;
-            this.grammar.def = {
-                regex: /\`\`(.+?)\`\`/,