Commits

Kirill Simonov committed 5f0f0a0

Initial implementation.

Comments (0)

Files changed (13)

+syntax: glob
+*.pyc
+*.pyo
+*.orig
+.*.sw?
+*.html
+*.egg-info
+_build
+build
+dist
+sandbox
+Copyright (c) 2013, Prometheus Research, LLC
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+* Redistributions of source code must retain the above copyright
+  notice, this list of conditions and the following disclaimer.
+
+* Redistributions in binary form must reproduce the above copyright
+  notice, this list of conditions and the following disclaimer in the
+  documentation and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+include README NEWS LICENSE demo/Makefile demo/conf.py demo/*.rst sphinxcontrib/*.js sphinxcontrib/*.css
+
+List of Changes
+===============
+
+
+0.1 (2013-XX-XX)
+----------------
+
+* Initial release.
+
+
+*************************************************************************
+  ``sphinxcontrib-jsdemo`` -- HTML/Javascript Demo extension for Sphinx
+*************************************************************************
+
+Overview
+========
+
+``sphinxcontrib-jsdemo`` is an extension for embedding HTML/Javascript
+demo snippets into Sphinx_ documents.
+
+You can see this extension in action at
+http://htsql.org/htraf/index.html
+
+This software is written by Kirill Simonov (`Prometheus Research, LLC`_)
+and released under BSD license.
+
+
+Usage
+=====
+
+To enable this extension, add the following line to ``conf.py``::
+
+    extensions.append('sphinxcontrib.jsdemo')
+
+Now you can include a snippet of HTML/Javascript code to a Sphinx
+document using ``demo`` directive.  For example::
+
+    .. demo::
+
+       <button>Click me!</button>
+
+The directive renders it content twice: as a raw HTML block (demo) and
+as a literal block (source).
+
+Option ``layout`` allows you to control the relative order of the blocks.
+For example, the following directive renders the source block first,
+then the demo block, which content is initially hidden::
+
+    .. demo::
+       :layout: +source, -demo
+
+       <button>Click me, too!</button>
+
+
+Reference
+=========
+
+Directives
+----------
+
+``demo``
+    Inserts demo and source blocks.
+
+    The directive is rendered as a composite node with two blocks:
+
+    * A *demo* block containing raw HTML content.
+
+    * A *source* block with the same content in literal form.
+
+    Clicking on a block header toggles the block's visibility.
+
+    Options:
+
+    ``layout``
+        This option controls the order of the blocks and their
+        initial visibility.  It must contain comma-separated
+        list of blocks with optional ``+`` or ``-`` indicators
+        specifying the initial visibility.  Examples:
+
+        ``demo, source``
+            Render the *demo* block before the *source* block.
+
+        ``+source, -demo``
+            Render the *source* block before the *demo* block.
+            The *demo* block must be hidden initially.
+
+        ``-demo``
+            Render the *demo* block only, hidden initially.
+
+
+Configuration parameters
+------------------------
+
+CSS classes
+-----------
+
+
+.. _Sphinx: http://sphinx-doc.org/
+.. _Prometheus Research, LLC: http://prometheusresearch.com/
+
+
+.. vim: set spell spelllang=en textwidth=72:
+
+# You can set these variables from the command line.
+SPHINXBUILD   = sphinx-build
+BUILDDIR      = _build
+
+ifeq ($(shell $(SPHINXBUILD) 2> /dev/null; echo $$?), 127)
+define MSG
+
+
+The 'sphinx-build' command was not found. Make sure you have Sphinx
+installed, then set the SPHINXBUILD environment variable to point
+to the full path of the 'sphinx-build' executable. Alternatively you
+may add the Sphinx directory to PATH.
+
+If you don't have Sphinx installed, grab it from
+http://sphinx-doc.org/
+endef
+$(error $(MSG))
+endif
+
+html:
+	$(SPHINXBUILD) -b html . $(BUILDDIR)/html
+	@echo
+	@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
+
+clean:
+	-rm -rf $(BUILDDIR)
+
+
+# Enable `sphinxcontrib-jsdemo` extension.
+extensions = ['sphinxcontrib.jsdemo']
+
+# Standard configuration.
+project = u'A Project with HTML/Javascript Demos'
+master_doc = 'index'
+exclude_patterns = ['_build']
+
+HTML/Javascript Demos
+=====================
+
+This document demonstrates usage of the ``demo`` directive.
+
+Regular layout
+--------------
+
+.. demo::
+
+   <button style="color: green">Regular layout</button>
+
+Source first
+------------
+
+.. demo::
+   :layout: source, demo
+
+   <button style="color: brown">Source first</button>
+
+Hidden source
+-------------
+
+.. demo::
+   :layout: +demo, -source
+
+   <button style="color: red">Hidden source</button>
+
+Hidden demo
+-----------
+
+.. demo::
+   :layout: +source, -demo
+
+   <button style="color: magenta">Hidden demo</button>
+
+No source
+---------
+
+.. demo::
+   :layout: demo
+
+   <button style="color: blue">No source</button>
+
+
+#
+# Copyright (c) 2013, Prometheus Research, LLC
+#
+
+
+from setuptools import setup
+
+
+NAME = "sphinxcontrib-jsdemo"
+VERSION = "0.1"
+DESCRIPTION = "A Sphinx HTML/Javascript Demo Extension"
+LONG_DESCRIPTION = open('README').read()
+AUTHOR = "Kirill Simonov (Prometheus Research, LLC)"
+AUTHOR_EMAIL = "xi@resolvent.net"
+LICENSE = "BSD"
+URL = "http://bitbucket.org/prometheus/sphinxcontrib-jsdemo"
+DOWNLOAD_URL = "http://pypi.python.org/pypi/sphinxcontrib-jsdemo"
+CLASSIFIERS = [
+        'Development Status :: 4 - Beta',
+        'Intended Audience :: Developers',
+        'License :: OSI Approved :: BSD License',
+        'Operating System :: OS Independent',
+        'Programming Language :: Python',
+        'Topic :: Documentation',
+        'Topic :: Text Processing',
+]
+PLATFORMS = 'any'
+REQUIRES = ['Sphinx']
+PACKAGES = ['sphinxcontrib']
+ZIP_SAFE = False
+INCLUDE_PACKAGE_DATA = True
+NAMESPACE_PACKAGES = ['sphinxcontrib']
+
+
+setup(name=NAME,
+      version=VERSION,
+      description=DESCRIPTION,
+      long_description=LONG_DESCRIPTION,
+      author=AUTHOR,
+      author_email=AUTHOR_EMAIL,
+      license=LICENSE,
+      url=URL,
+      download_url=DOWNLOAD_URL,
+      classifiers=CLASSIFIERS,
+      platforms=PLATFORMS,
+      requires=REQUIRES,
+      packages=PACKAGES,
+      zip_safe=ZIP_SAFE,
+      include_package_data=INCLUDE_PACKAGE_DATA,
+      namespace_packages=NAMESPACE_PACKAGES)
+
+

sphinxcontrib/__init__.py

+#
+# Copyright (c) 2013, Prometheus Research, LLC
+#
+
+
+__import__('pkg_resources').declare_namespace(__name__)
+
+

sphinxcontrib/jsdemo.css

+
+
+div.demo-wrapper p.demo-header {
+  font-style: italic;
+  cursor: pointer;
+  -moz-user-select: none;
+  -webkit-user-select: none;
+  user-select: none;
+}
+
+div.demo-wrapper p.demo-header:before {
+  font-style: normal;
+  content: "\25BE\20";
+}
+
+div.demo-wrapper p.demo-header.demo-hide:before {
+  content: "\25B8\20";
+}
+
+div.demo-wrapper p.demo-header.demo-hide+.demo-area,
+div.demo-wrapper p.demo-header.demo-hide+.demo-source {
+  display: none;
+}
+
+

sphinxcontrib/jsdemo.js

+
+
+$(function () {
+    $('.demo-header').click(function () {
+        $(this).toggleClass('demo-hide');
+    });
+});
+
+

sphinxcontrib/jsdemo.py

+#
+# Copyright (c) 2013, Prometheus Research, LLC
+#
+
+
+from docutils import nodes
+from docutils.parsers.rst import Directive, directives
+from sphinx.util.osutil import copyfile
+import re, os.path
+
+
+class DemoDirective(Directive):
+
+    has_content = True
+    option_spec = {
+            'layout': directives.unchanged,
+    }
+
+    layout_re = re.compile(r'^[+-]?demo([,]\s*[+-]?source)?|'
+                          r'[+-]?source([,]\s*[+-]?demo)?$')
+
+    def run(self):
+        doc = self.state.document
+        env = doc.settings.env
+        if 'layout' in self.options:
+            layout = self.options['layout']
+        else:
+            layout = env.config.demo_layout
+        if not self.layout_re.match(layout):
+            return [doc.reporter.error("invalid layout specifier: %s" % layout,
+                                       lineno=self.lineno)]
+        order = []
+        for block in layout.split(','):
+            block = block.strip()
+            is_hidden = block[0] == '-'
+            block = block.lstrip('+-')
+            order.append((block, is_hidden))
+        wrapper = nodes.compound(classes=['demo-wrapper'])
+        data = "\n".join(self.content)
+        for block, is_hidden in order:
+            if block == 'demo':
+                header = nodes.paragraph(classes=['demo-header'])
+                header += nodes.Text("Demo")
+                if is_hidden:
+                    header['classes'].append('demo-hide')
+                demo = nodes.raw(data, data,
+                                 format='html',
+                                 classes=['demo-area'])
+                wrapper += header
+                wrapper += demo
+            elif block == 'source':
+                header = nodes.paragraph(classes=['demo-header'])
+                header += nodes.Text("Source")
+                if is_hidden:
+                    header['classes'].append('demo-hide')
+                source = nodes.literal_block(data, data,
+                                             language='html',
+                                             classes=['demo-source'])
+                wrapper += header
+                wrapper += source
+            else:
+                assert False, block
+        return [wrapper]
+
+
+def copy_static(app, exception):
+    if app.builder.name != 'html' or exception:
+        return
+    for filename in ['jsdemo.js', 'jsdemo.css']:
+        src = os.path.join(os.path.abspath(os.path.dirname(__file__)), filename)
+        dst = os.path.join(app.builder.outdir, '_static', filename)
+        copyfile(src, dst)
+
+
+def setup(app):
+    app.add_config_value('demo_layout', '+demo, +source', 'env')
+    app.add_directive('demo', DemoDirective)
+    app.connect(str('build-finished'), copy_static)
+    app.add_javascript('jsdemo.js')
+    app.add_stylesheet('jsdemo.css')
+
+