diff options
author | Jason Madden <jason+github@nextthought.com> | 2017-11-03 08:35:28 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-11-03 08:35:28 -0500 |
commit | 8269f2c7d418d19bba90a67bd88aa64b8ed5acdc (patch) | |
tree | c8b1cb2f945857e075546584ab719db93583f7a0 | |
parent | 5a2101c0c088bca3f0b50e34166e33451ca73dac (diff) | |
parent | d052e523e766b38c6ba058b7630a99fa36c35719 (diff) | |
download | zope-tal-8269f2c7d418d19bba90a67bd88aa64b8ed5acdc.tar.gz |
Merge pull request #8 from zopefoundation/rtd-docs
Documentation for RTD
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | CHANGES.rst | 2 | ||||
-rw-r--r-- | MANIFEST.in | 6 | ||||
-rw-r--r-- | README.rst | 17 | ||||
-rw-r--r-- | doc-requirements.txt | 1 | ||||
-rw-r--r-- | docs/Makefile | 177 | ||||
-rw-r--r-- | docs/changelog.rst | 1 | ||||
-rw-r--r-- | docs/conf.py | 279 | ||||
-rw-r--r-- | docs/htmltalparser.rst | 5 | ||||
-rw-r--r-- | docs/index.rst | 51 | ||||
-rw-r--r-- | docs/interfaces.rst | 5 | ||||
-rw-r--r-- | docs/make.bat | 242 | ||||
-rw-r--r-- | docs/taldefs.rst | 5 | ||||
-rw-r--r-- | docs/talgenerator.rst | 5 | ||||
-rw-r--r-- | docs/talinterpreter.rst | 5 | ||||
-rw-r--r-- | docs/talparser.rst | 7 | ||||
-rw-r--r-- | setup.py | 6 | ||||
-rw-r--r-- | src/zope/tal/htmltalparser.py | 56 | ||||
-rw-r--r-- | src/zope/tal/interfaces.py | 55 | ||||
-rw-r--r-- | src/zope/tal/taldefs.py | 47 | ||||
-rw-r--r-- | src/zope/tal/talgenerator.py | 21 | ||||
-rw-r--r-- | src/zope/tal/talinterpreter.py | 65 | ||||
-rw-r--r-- | src/zope/tal/talparser.py | 19 | ||||
-rw-r--r-- | src/zope/tal/xmlparser.py | 8 | ||||
-rw-r--r-- | tox.ini | 11 |
25 files changed, 990 insertions, 107 deletions
@@ -9,3 +9,4 @@ develop-eggs/ coverage.xml nosetests.xml htmlcov/ +docs/_build/ diff --git a/CHANGES.rst b/CHANGES.rst index eff5e0a..3abe971 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -5,7 +5,7 @@ 4.3.1 (unreleased) ================== -- Nothing changed yet. +- Host documentation at https://zopetal.readthedocs.io 4.3.0 (2017-08-08) diff --git a/MANIFEST.in b/MANIFEST.in index bb70d98..3b0dece 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,5 +1,6 @@ include *.py include *.rst +include *.txt include buildout.cfg include tox.ini include .coveragerc @@ -8,3 +9,8 @@ include .travis.yml recursive-include src *.pt recursive-include src *.xml recursive-include src *.html + +recursive-include docs *.rst +recursive-include docs *.py +recursive-include docs Makefile +recursive-include docs make.bat @@ -1,6 +1,6 @@ -============== - ``zope.tal`` -============== +========== + zope.tal +========== .. image:: https://img.shields.io/pypi/v/zope.tal.svg :target: https://pypi.python.org/pypi/zope.tal/ @@ -16,6 +16,10 @@ .. image:: https://coveralls.io/repos/github/zopefoundation/zope.tal/badge.svg?branch=master :target: https://coveralls.io/github/zopefoundation/zope.tal?branch=master +.. image:: https://readthedocs.org/projects/zopetal/badge/?version=latest + :target: https://zopetal.readthedocs.io/en/latest/ + :alt: Documentation Status + The Zope3 Template Attribute Languate (TAL) specifies the custom namespace and attributes which are used by the Zope Page Templates renderer to inject dynamic markup into a page. It also includes the Macro Expansion for TAL @@ -24,6 +28,9 @@ dynamic markup into a page. It also includes the Macro Expansion for TAL The dynamic values themselves are specified using a companion language, TALES (see the `zope.tales`_ package for more). -See: http://wiki.zope.org/ZPT/TALSpecification14 +The reference documentation for the TAL language is available at https://docs.zope.org/zope2/zope2book/AppendixC.html + +Detailed documentation for this implementation and its API is available at https://zopetal.readthedocs.io/ + -.. _`zope.tales` : http://pypi.python.org/pypi/zope.tales +.. _`zope.tales` : https://zopetales.readthedocs.io diff --git a/doc-requirements.txt b/doc-requirements.txt new file mode 100644 index 0000000..e9704b8 --- /dev/null +++ b/doc-requirements.txt @@ -0,0 +1 @@ +.[docs] diff --git a/docs/Makefile b/docs/Makefile new file mode 100644 index 0000000..4c2d034 --- /dev/null +++ b/docs/Makefile @@ -0,0 +1,177 @@ +# Makefile for Sphinx documentation +# + +# You can set these variables from the command line. +SPHINXOPTS = +SPHINXBUILD = sphinx-build +PAPER = +BUILDDIR = _build + +# User-friendly check for sphinx-build +ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1) +$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/) +endif + +# Internal variables. +PAPEROPT_a4 = -D latex_paper_size=a4 +PAPEROPT_letter = -D latex_paper_size=letter +ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . +# the i18n builder cannot share the environment and doctrees with the others +I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . + +.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext + +help: + @echo "Please use \`make <target>' where <target> is one of" + @echo " html to make standalone HTML files" + @echo " dirhtml to make HTML files named index.html in directories" + @echo " singlehtml to make a single large HTML file" + @echo " pickle to make pickle files" + @echo " json to make JSON files" + @echo " htmlhelp to make HTML files and a HTML help project" + @echo " qthelp to make HTML files and a qthelp project" + @echo " devhelp to make HTML files and a Devhelp project" + @echo " epub to make an epub" + @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" + @echo " latexpdf to make LaTeX files and run them through pdflatex" + @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx" + @echo " text to make text files" + @echo " man to make manual pages" + @echo " texinfo to make Texinfo files" + @echo " info to make Texinfo files and run them through makeinfo" + @echo " gettext to make PO message catalogs" + @echo " changes to make an overview of all changed/added/deprecated items" + @echo " xml to make Docutils-native XML files" + @echo " pseudoxml to make pseudoxml-XML files for display purposes" + @echo " linkcheck to check all external links for integrity" + @echo " doctest to run all doctests embedded in the documentation (if enabled)" + +clean: + rm -rf $(BUILDDIR)/* + +html: + $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." + +dirhtml: + $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." + +singlehtml: + $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml + @echo + @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." + +pickle: + $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle + @echo + @echo "Build finished; now you can process the pickle files." + +json: + $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json + @echo + @echo "Build finished; now you can process the JSON files." + +htmlhelp: + $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp + @echo + @echo "Build finished; now you can run HTML Help Workshop with the" \ + ".hhp project file in $(BUILDDIR)/htmlhelp." + +qthelp: + $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp + @echo + @echo "Build finished; now you can run "qcollectiongenerator" with the" \ + ".qhcp project file in $(BUILDDIR)/qthelp, like this:" + @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/zopecatalog.qhcp" + @echo "To view the help file:" + @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/zopecatalog.qhc" + +devhelp: + $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp + @echo + @echo "Build finished." + @echo "To view the help file:" + @echo "# mkdir -p $$HOME/.local/share/devhelp/zopecatalog" + @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/zopecatalog" + @echo "# devhelp" + +epub: + $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub + @echo + @echo "Build finished. The epub file is in $(BUILDDIR)/epub." + +latex: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo + @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." + @echo "Run \`make' in that directory to run these through (pdf)latex" \ + "(use \`make latexpdf' here to do that automatically)." + +latexpdf: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo "Running LaTeX files through pdflatex..." + $(MAKE) -C $(BUILDDIR)/latex all-pdf + @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." + +latexpdfja: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo "Running LaTeX files through platex and dvipdfmx..." + $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja + @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." + +text: + $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text + @echo + @echo "Build finished. The text files are in $(BUILDDIR)/text." + +man: + $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man + @echo + @echo "Build finished. The manual pages are in $(BUILDDIR)/man." + +texinfo: + $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo + @echo + @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." + @echo "Run \`make' in that directory to run these through makeinfo" \ + "(use \`make info' here to do that automatically)." + +info: + $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo + @echo "Running Texinfo files through makeinfo..." + make -C $(BUILDDIR)/texinfo info + @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." + +gettext: + $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale + @echo + @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." + +changes: + $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes + @echo + @echo "The overview file is in $(BUILDDIR)/changes." + +linkcheck: + $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck + @echo + @echo "Link check complete; look for any errors in the above output " \ + "or in $(BUILDDIR)/linkcheck/output.txt." + +doctest: + $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest + @echo "Testing of doctests in the sources finished, look at the " \ + "results in $(BUILDDIR)/doctest/output.txt." + +xml: + $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml + @echo + @echo "Build finished. The XML files are in $(BUILDDIR)/xml." + +pseudoxml: + $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml + @echo + @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml." diff --git a/docs/changelog.rst b/docs/changelog.rst new file mode 100644 index 0000000..d9e113e --- /dev/null +++ b/docs/changelog.rst @@ -0,0 +1 @@ +.. include:: ../CHANGES.rst diff --git a/docs/conf.py b/docs/conf.py new file mode 100644 index 0000000..7153fb9 --- /dev/null +++ b/docs/conf.py @@ -0,0 +1,279 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# +# zope.tal documentation build configuration file, created by +# sphinx-quickstart on Thu Jan 29 11:31:12 2015. +# +# 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 +import os +import pkg_resources +sys.path.append(os.path.abspath('../src')) +rqmt = pkg_resources.require('zope.tal')[0] + +# 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('.')) + +# -- General configuration ------------------------------------------------ + +# 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.autodoc', + 'sphinx.ext.doctest', + 'sphinx.ext.intersphinx', + 'sphinx.ext.viewcode', + 'repoze.sphinx.autointerface', +] + +# 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 = 'zope.tal' +copyright = '2015-2017, Zope Foundation and Contributors' + +# 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 = '%s.%s' % tuple(map(int, rqmt.version.split('.')[:2])) +# The full version, including alpha/beta/rc tags. +release = rqmt.version + +# 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 = ['_build'] + +# The reST default role (used for this markup: `text`) to use for all +# documents. +#default_role = None + +# 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 = [] + +# If true, keep warnings as "system message" paragraphs in the built documents. +#keep_warnings = False + + +# -- 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'] + +# Add any extra paths that contain custom files (such as robots.txt or +# .htaccess) here, relative to this directory. These files are copied +# directly to the root of the documentation. +#html_extra_path = [] + +# 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 = 'zopetaldoc' + + +# -- Options for LaTeX output --------------------------------------------- + +latex_elements = { +# The paper size ('letterpaper' or 'a4paper'). +#'papersize': 'letterpaper', + +# The font size ('10pt', '11pt' or '12pt'). +#'pointsize': '10pt', + +# Additional stuff for the LaTeX preamble. +#'preamble': '', +} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, +# author, documentclass [howto, manual, or own class]). +latex_documents = [ + ('index', 'zopetal.tex', 'zope.tal Documentation', + 'Zope Foundation and Contributors', '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 + +# 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', 'zopetal', 'zope.tal Documentation', + ['Zope Foundation and Contributors'], 1) +] + +# If true, show URL addresses after external links. +#man_show_urls = False + + +# -- Options for Texinfo output ------------------------------------------- + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +texinfo_documents = [ + ('index', 'zopetal', 'zope.tal Documentation', + 'Zope Foundation and Contributors', 'zopetal', 'One line description of project.', + 'Miscellaneous'), +] + +# Documents to append as an appendix to all manuals. +#texinfo_appendices = [] + +# If false, no module index is generated. +#texinfo_domain_indices = True + +# How to display URL addresses: 'footnote', 'no', or 'inline'. +#texinfo_show_urls = 'footnote' + +# If true, do not generate a @detailmenu in the "Top" node's menu. +#texinfo_no_detailmenu = False + + +# Example configuration for intersphinx: refer to the Python standard library. +intersphinx_mapping = { + 'https://docs.python.org/': None, + 'https://zopetales.readthedocs.io/en/latest/': None, +} + +autodoc_default_flags = ['members', 'show-inheritance'] +autoclass_content = 'both' +autodoc_member_order = 'bysource' diff --git a/docs/htmltalparser.rst b/docs/htmltalparser.rst new file mode 100644 index 0000000..bf2ac4f --- /dev/null +++ b/docs/htmltalparser.rst @@ -0,0 +1,5 @@ +============================ + Parsing and Compiling HTML +============================ + +.. automodule:: zope.tal.htmltalparser diff --git a/docs/index.rst b/docs/index.rst new file mode 100644 index 0000000..2b80efc --- /dev/null +++ b/docs/index.rst @@ -0,0 +1,51 @@ +.. include:: ../README.rst + +Using ``zope.tal`` requires three steps: choosing an expression engine +(usually :mod:`zope.tales`), creating a generator and parser, and then +interpreting the compiled program:: + + from io import StringIO + from zope.tal.talgenerator import TALGenerator + from zope.tal.htmltalparser import HTMLTALParser + from zope.tal.talinterpreter import TALInterpreter + + compiler = None # Will use a compiler for a dummy language + source_file = '<string>' + source_text = '<html><body><p>Hi</p></body></html>' + gen = TALGenerator(compiler, source_file=source_file) + parser = TALParser(gen) + parser.parseString(source_text) + program, macros = parser.getCode() + + output = StringIO() + context = None # Usually will create a zope.tales context + interpreter = TALInterpreter(self.program, macros, context, stream=output) + interpreter() + result = output.getvalue() + +These aspects are all brought together in :mod:`zope.pagetemplate`. + +API Documentation: + +.. toctree:: + :maxdepth: 2 + + interfaces + taldefs + talgenerator + htmltalparser + talparser + talinterpreter + +.. toctree:: + :maxdepth: 1 + + changelog + + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` diff --git a/docs/interfaces.rst b/docs/interfaces.rst new file mode 100644 index 0000000..fffc139 --- /dev/null +++ b/docs/interfaces.rst @@ -0,0 +1,5 @@ +============ + Interfaces +============ + +.. automodule:: zope.tal.interfaces diff --git a/docs/make.bat b/docs/make.bat new file mode 100644 index 0000000..9372f64 --- /dev/null +++ b/docs/make.bat @@ -0,0 +1,242 @@ +@ECHO OFF
+
+REM Command file for Sphinx documentation
+
+if "%SPHINXBUILD%" == "" (
+ set SPHINXBUILD=sphinx-build
+)
+set BUILDDIR=_build
+set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% .
+set I18NSPHINXOPTS=%SPHINXOPTS% .
+if NOT "%PAPER%" == "" (
+ set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
+ set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS%
+)
+
+if "%1" == "" goto help
+
+if "%1" == "help" (
+ :help
+ echo.Please use `make ^<target^>` where ^<target^> is one of
+ echo. html to make standalone HTML files
+ echo. dirhtml to make HTML files named index.html in directories
+ echo. singlehtml to make a single large HTML file
+ echo. pickle to make pickle files
+ echo. json to make JSON files
+ echo. htmlhelp to make HTML files and a HTML help project
+ echo. qthelp to make HTML files and a qthelp project
+ echo. devhelp to make HTML files and a Devhelp project
+ echo. epub to make an epub
+ echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter
+ echo. text to make text files
+ echo. man to make manual pages
+ echo. texinfo to make Texinfo files
+ echo. gettext to make PO message catalogs
+ echo. changes to make an overview over all changed/added/deprecated items
+ echo. xml to make Docutils-native XML files
+ echo. pseudoxml to make pseudoxml-XML files for display purposes
+ echo. linkcheck to check all external links for integrity
+ echo. doctest to run all doctests embedded in the documentation if enabled
+ goto end
+)
+
+if "%1" == "clean" (
+ for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i
+ del /q /s %BUILDDIR%\*
+ goto end
+)
+
+
+%SPHINXBUILD% 2> nul
+if errorlevel 9009 (
+ echo.
+ echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
+ echo.installed, then set the SPHINXBUILD environment variable to point
+ echo.to the full path of the 'sphinx-build' executable. Alternatively you
+ echo.may add the Sphinx directory to PATH.
+ echo.
+ echo.If you don't have Sphinx installed, grab it from
+ echo.http://sphinx-doc.org/
+ exit /b 1
+)
+
+if "%1" == "html" (
+ %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished. The HTML pages are in %BUILDDIR%/html.
+ goto end
+)
+
+if "%1" == "dirhtml" (
+ %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.
+ goto end
+)
+
+if "%1" == "singlehtml" (
+ %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml.
+ goto end
+)
+
+if "%1" == "pickle" (
+ %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished; now you can process the pickle files.
+ goto end
+)
+
+if "%1" == "json" (
+ %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished; now you can process the JSON files.
+ goto end
+)
+
+if "%1" == "htmlhelp" (
+ %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished; now you can run HTML Help Workshop with the ^
+.hhp project file in %BUILDDIR%/htmlhelp.
+ goto end
+)
+
+if "%1" == "qthelp" (
+ %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished; now you can run "qcollectiongenerator" with the ^
+.qhcp project file in %BUILDDIR%/qthelp, like this:
+ echo.^> qcollectiongenerator %BUILDDIR%\qthelp\zopecatalog.qhcp
+ echo.To view the help file:
+ echo.^> assistant -collectionFile %BUILDDIR%\qthelp\zopecatalog.ghc
+ goto end
+)
+
+if "%1" == "devhelp" (
+ %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished.
+ goto end
+)
+
+if "%1" == "epub" (
+ %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished. The epub file is in %BUILDDIR%/epub.
+ goto end
+)
+
+if "%1" == "latex" (
+ %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished; the LaTeX files are in %BUILDDIR%/latex.
+ goto end
+)
+
+if "%1" == "latexpdf" (
+ %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
+ cd %BUILDDIR%/latex
+ make all-pdf
+ cd %BUILDDIR%/..
+ echo.
+ echo.Build finished; the PDF files are in %BUILDDIR%/latex.
+ goto end
+)
+
+if "%1" == "latexpdfja" (
+ %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
+ cd %BUILDDIR%/latex
+ make all-pdf-ja
+ cd %BUILDDIR%/..
+ echo.
+ echo.Build finished; the PDF files are in %BUILDDIR%/latex.
+ goto end
+)
+
+if "%1" == "text" (
+ %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished. The text files are in %BUILDDIR%/text.
+ goto end
+)
+
+if "%1" == "man" (
+ %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished. The manual pages are in %BUILDDIR%/man.
+ goto end
+)
+
+if "%1" == "texinfo" (
+ %SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo.
+ goto end
+)
+
+if "%1" == "gettext" (
+ %SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished. The message catalogs are in %BUILDDIR%/locale.
+ goto end
+)
+
+if "%1" == "changes" (
+ %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.The overview file is in %BUILDDIR%/changes.
+ goto end
+)
+
+if "%1" == "linkcheck" (
+ %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Link check complete; look for any errors in the above output ^
+or in %BUILDDIR%/linkcheck/output.txt.
+ goto end
+)
+
+if "%1" == "doctest" (
+ %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Testing of doctests in the sources finished, look at the ^
+results in %BUILDDIR%/doctest/output.txt.
+ goto end
+)
+
+if "%1" == "xml" (
+ %SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished. The XML files are in %BUILDDIR%/xml.
+ goto end
+)
+
+if "%1" == "pseudoxml" (
+ %SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml.
+ goto end
+)
+
+:end
diff --git a/docs/taldefs.rst b/docs/taldefs.rst new file mode 100644 index 0000000..ba2f6bd --- /dev/null +++ b/docs/taldefs.rst @@ -0,0 +1,5 @@ +==================== + Common Definitions +==================== + +.. automodule:: zope.tal.taldefs diff --git a/docs/talgenerator.rst b/docs/talgenerator.rst new file mode 100644 index 0000000..35fc115 --- /dev/null +++ b/docs/talgenerator.rst @@ -0,0 +1,5 @@ +========================== + Generating Compiled Code +========================== + +.. automodule:: zope.tal.talgenerator diff --git a/docs/talinterpreter.rst b/docs/talinterpreter.rst new file mode 100644 index 0000000..0f23220 --- /dev/null +++ b/docs/talinterpreter.rst @@ -0,0 +1,5 @@ +============================ + Interpreting Compiled Code +============================ + +.. automodule:: zope.tal.talinterpreter diff --git a/docs/talparser.rst b/docs/talparser.rst new file mode 100644 index 0000000..e7296f9 --- /dev/null +++ b/docs/talparser.rst @@ -0,0 +1,7 @@ +=========================== + Parsing and Compiling XML +=========================== + +.. automodule:: zope.tal.talparser + +.. autoclass:: zope.tal.xmlparser.XMLParser @@ -77,13 +77,17 @@ setup(name='zope.tal', 'Topic :: Internet :: WWW/HTTP', 'Framework :: Zope3', ], - url='http://github.com/zopefoundation/zope.tal', + url='https://github.com/zopefoundation/zope.tal', license='ZPL 2.1', packages=find_packages('src'), package_dir={'': 'src'}, namespace_packages=['zope'], extras_require={ 'test': TESTS_REQUIRE, + 'docs': [ + 'Sphinx', + 'repoze.sphinx.autointerface', + ], }, test_suite="__main__.alltests", # to support "setup.py test" tests_require=TESTS_REQUIRE, diff --git a/src/zope/tal/htmltalparser.py b/src/zope/tal/htmltalparser.py index c79bbea..1761bc7 100644 --- a/src/zope/tal/htmltalparser.py +++ b/src/zope/tal/htmltalparser.py @@ -11,7 +11,9 @@ # FOR A PARTICULAR PURPOSE. # ############################################################################## -"""Parse HTML and compile to TALInterpreter intermediate code. +""" +Parse HTML and compile to :class:`~.TALInterpreter` intermediate code, using +a :class:`~.TALGenerator`. """ # When Python 3 becomes mainstream please swap the try and except parts. @@ -28,6 +30,7 @@ except ImportError: # so here's a copy taken from Python 3.4: class HTMLParseError(Exception): def __init__(self, msg, position=(None, None)): + Exception.__init__(self) assert msg self.msg = msg self.lineno = position[0] @@ -50,30 +53,30 @@ _html_parser_extras = {} if 'convert_charrefs' in HTMLParser.__init__.__code__.co_names: _html_parser_extras['convert_charrefs'] = False # pragma: NO COVER py34 - +#: List of Boolean attributes in HTML that may be given in +#: minimized form (e.g. ``<img ismap>`` rather than ``<img ismap="">``) +#: From http://www.w3.org/TR/xhtml1/#guidelines (C.10) BOOLEAN_HTML_ATTRS = frozenset([ - # List of Boolean attributes in HTML that may be given in - # minimized form (e.g. <img ismap> rather than <img ismap="">) - # From http://www.w3.org/TR/xhtml1/#guidelines (C.10) "compact", "nowrap", "ismap", "declare", "noshade", "checked", "disabled", "readonly", "multiple", "selected", "noresize", "defer" ]) +#: List of HTML tags with an empty content model; these are +#: rendered in minimized form, e.g. ``<img />``. +#: From http://www.w3.org/TR/xhtml1/#dtds EMPTY_HTML_TAGS = frozenset([ - # List of HTML tags with an empty content model; these are - # rendered in minimized form, e.g. <img />. - # From http://www.w3.org/TR/xhtml1/#dtds "base", "meta", "link", "hr", "br", "param", "img", "area", "input", "col", "basefont", "isindex", "frame", ]) +#: List of HTML elements that close open paragraph-level elements +#: and are themselves paragraph-level. PARA_LEVEL_HTML_TAGS = frozenset([ - # List of HTML elements that close open paragraph-level elements - # and are themselves paragraph-level. "h1", "h2", "h3", "h4", "h5", "h6", "p", ]) +#: Tags that automatically close other tags. BLOCK_CLOSING_TAG_MAP = { "tr": frozenset(["tr", "td", "th"]), "td": frozenset(["td", "th"]), @@ -83,12 +86,13 @@ BLOCK_CLOSING_TAG_MAP = { "dt": frozenset(["dd", "dt"]), } +#: List of HTML tags that denote larger sections than paragraphs. BLOCK_LEVEL_HTML_TAGS = frozenset([ - # List of HTML tags that denote larger sections than paragraphs. "blockquote", "table", "tr", "th", "td", "thead", "tfoot", "tbody", "noframe", "ul", "ol", "li", "dl", "dt", "dd", "div", ]) +#: Section level HTML tags SECTION_LEVEL_HTML_TAGS = PARA_LEVEL_HTML_TAGS.union(BLOCK_LEVEL_HTML_TAGS) TIGHTEN_IMPLICIT_CLOSE_TAGS = PARA_LEVEL_HTML_TAGS.union(BLOCK_CLOSING_TAG_MAP) @@ -127,25 +131,37 @@ class OpenTagError(NestingError): HTMLParseError.__init__(self, msg, position) class HTMLTALParser(HTMLParser): + """ + Parser for HTML. + + After you call either :meth:`parseFile` and :meth:`parseString` + you can retrieve the compiled program using :meth:`getCode`. + """ # External API def __init__(self, gen=None): + """ + :keyword TALGenerator gen: The configured (with an expression compiler) + code generator to use. If one is not given, a default will be used. + """ HTMLParser.__init__(self, **_html_parser_extras) if gen is None: gen = TALGenerator(xml=0) self.gen = gen self.tagstack = [] self.nsstack = [] - self.nsdict = {'tal': ZOPE_TAL_NS, - 'metal': ZOPE_METAL_NS, - 'i18n': ZOPE_I18N_NS, - } + self.nsdict = { + 'tal': ZOPE_TAL_NS, + 'metal': ZOPE_METAL_NS, + 'i18n': ZOPE_I18N_NS, + } def parseFile(self, file): - f = open(file) - data = f.read() - f.close() + """Parse data in the given file.""" + with open(file) as f: + data = f.read() + try: self.parseString(data) except TALError as e: @@ -153,6 +169,7 @@ class HTMLTALParser(HTMLParser): raise def parseString(self, data): + """Parse data in the given string.""" self.feed(data) self.close() while self.tagstack: @@ -160,6 +177,9 @@ class HTMLTALParser(HTMLParser): assert self.nsstack == [], self.nsstack def getCode(self): + """ + After parsing, this returns ``(program, macros)``. + """ return self.gen.getCode() # Overriding HTMLParser methods diff --git a/src/zope/tal/interfaces.py b/src/zope/tal/interfaces.py index 8de3819..f6c1aec 100644 --- a/src/zope/tal/interfaces.py +++ b/src/zope/tal/interfaces.py @@ -11,8 +11,16 @@ # FOR A PARTICULAR PURPOSE. # ############################################################################## -"""Interface that a TAL expression implementation provides to the METAL/TAL -implementation. +""" +Interface that a TAL expression implementation provides to the +METAL/TAL implementation. + +This package does not provide an implementation of +:class:`ITALExpressionCompiler`, :class:`ITALExpressionEngine` or +:class:`ITALIterator`. An external package must provide those. The +most commonly used are :class:`zope.tales.tales.ExpressionEngine`, +:class:`zope.tales.tales.Context`, and +:class:`zope.tales.tales.Iterator`, respectively. """ from zope.interface import Attribute, Interface @@ -30,20 +38,20 @@ class ITALExpressionCompiler(Interface): """ def compile(expression): - """Return a compiled form of 'expression' for later evaluation. + """Return a compiled form of *expression* for later evaluation. - 'expression' is the source text of the expression. + *expression* is the source text of the expression. - The return value may be passed to the various evaluate*() - methods of the ITALExpressionEngine interface. No compatibility is + The return value may be passed to the various ``evaluate*()`` + methods of the :class:`ITALExpressionEngine` interface. No compatibility is required for the values of the compiled expression between - different ITALExpressionEngine implementations. + different :class:`ITALExpressionEngine` implementations. """ def getContext(namespace): """Create an expression execution context - The given namespace provides the initial top-level names. + The given *namespace* provides the initial top-level names. """ class ITALExpressionEngine(Interface): @@ -51,20 +59,20 @@ class ITALExpressionEngine(Interface): The TAL interpreter uses this interface to TAL expression to support evaluation of the compiled expressions returned by - ITALExpressionCompiler.compile(). + :meth:`ITALExpressionCompiler.compile`. """ def getDefault(): - """Return the value of the 'default' TAL expression. + """Return the value of the ``default`` TAL expression. - Checking a value for a match with 'default' should be done - using the 'is' operator in Python. + Checking a value for a match with ``default`` should be done + using the ``is`` operator in Python. """ def setPosition(position): """Inform the engine of the current position in the source file. - ``position`` is a tuple (lineno, offset). + *position* is a tuple (lineno, offset). This is used to allow the evaluation engine to report execution errors so that site developers can more easily @@ -105,7 +113,7 @@ class ITALExpressionEngine(Interface): """Evaluate an expression that must return a structured document fragment. - The result of evaluating 'compiled_expression' must be a + The result of evaluating *compiled_expression* must be a string containing a parsable HTML or XML fragment. Any TAL markup contained in the result string will be interpreted. """ @@ -118,10 +126,10 @@ class ITALExpressionEngine(Interface): responsibility of the expression itself. If the expression evaluates to None, then that is returned. It - represents 'nothing' in TALES. - If the expression evaluates to what getDefault() of this interface - returns, by comparison using 'is', then that is returned. It - represents 'default' in TALES. + represents ``nothing`` in TALES. + If the expression evaluates to what :meth:`getDefault()` + returns, by comparison using ``is``, then that is returned. It + represents ``default`` in TALES. """ def evaluateValue(compiled_expression): @@ -131,9 +139,9 @@ class ITALExpressionEngine(Interface): """ def createErrorInfo(exception, position): - """Returns an ITALExpressionErrorInfo object. + """Returns an :class:`ITALExpressionErrorInfo` object. - ``position`` is a tuple (lineno, offset). + *position* is a tuple (lineno, offset). The returned object is used to provide information about the error condition for the on-error handler. @@ -142,13 +150,13 @@ class ITALExpressionEngine(Interface): def setGlobal(name, value): """Set a global variable. - The variable will be named 'name' and have the value 'value'. + The variable will be named *name* and have the value *value*. """ def setLocal(name, value): """Set a local variable in the current scope. - The variable will be named 'name' and have the value 'value'. + The variable will be named *name* and have the value *value*. """ def getValue(name, default=None): @@ -158,7 +166,7 @@ class ITALExpressionEngine(Interface): """ def setRepeat(name, compiled_expression): - """Start a repetition, returning an ITALIterator. + """Start a repetition, returning an :class:`ITALIterator`. The engine is expected to add the a value (typically the returned iterator) for the name to the variable namespace. @@ -195,6 +203,7 @@ class ITALIterator(Interface): class ITALExpressionErrorInfo(Interface): + """Information about an error.""" type = Attribute("type", "The exception class.") diff --git a/src/zope/tal/taldefs.py b/src/zope/tal/taldefs.py index a4aaf61..539e541 100644 --- a/src/zope/tal/taldefs.py +++ b/src/zope/tal/taldefs.py @@ -17,20 +17,26 @@ import re from zope.tal.interfaces import ITALExpressionErrorInfo from zope.interface import implementer - +#: Version of the specification we implement. TAL_VERSION = "1.6" -XML_NS = "http://www.w3.org/XML/1998/namespace" # URI for XML namespace -XMLNS_NS = "http://www.w3.org/2000/xmlns/" # URI for XML NS declarations +#: URI for XML namespace +XML_NS = "http://www.w3.org/XML/1998/namespace" +#: URI for XML NS declarations +XMLNS_NS = "http://www.w3.org/2000/xmlns/" +#: TAL namespace URI ZOPE_TAL_NS = "http://xml.zope.org/namespaces/tal" +#: METAL namespace URI ZOPE_METAL_NS = "http://xml.zope.org/namespaces/metal" +#: I18N namespace URI ZOPE_I18N_NS = "http://xml.zope.org/namespaces/i18n" # This RE must exactly match the expression of the same name in the # zope.i18n.simpletranslationservice module: NAME_RE = "[a-zA-Z_][-a-zA-Z0-9_]*" +#: Known METAL attributes KNOWN_METAL_ATTRIBUTES = frozenset([ "define-macro", "extend-macro", @@ -39,6 +45,7 @@ KNOWN_METAL_ATTRIBUTES = frozenset([ "fill-slot", ]) +#: Known TAL attributes KNOWN_TAL_ATTRIBUTES = frozenset([ "define", "condition", @@ -53,6 +60,7 @@ KNOWN_TAL_ATTRIBUTES = frozenset([ # like <tal:x>, <metal:y>, <i18n:z> ]) +#: Known I18N attributes KNOWN_I18N_ATTRIBUTES = frozenset([ "translate", "domain", @@ -66,8 +74,12 @@ KNOWN_I18N_ATTRIBUTES = frozenset([ ]) class TALError(Exception): + """ + A base exception for errors raised by this implementation. + """ def __init__(self, msg, position=(None, None)): + Exception.__init__(self) assert msg != "" self.msg = msg self.lineno = position[0] @@ -88,17 +100,20 @@ class TALError(Exception): return result class METALError(TALError): - pass + """An error parsing on running METAL macros.""" class TALExpressionError(TALError): - pass + """An error parsing or running a TAL expression.""" class I18NError(TALError): - pass + """An error parsing a I18N expression.""" @implementer(ITALExpressionErrorInfo) class ErrorInfo(object): + """ + Default implementation of :class:`zope.tal.interfaces.ITALExpressionErrorInfo`. + """ def __init__(self, err, position=(None, None)): if isinstance(err, Exception): @@ -115,7 +130,7 @@ _attr_re = re.compile(r"\s*([^\s]+)\s+([^\s].*)\Z", re.S) _subst_re = re.compile(r"\s*(?:(text|structure)\s+)?(.*)\Z", re.S) def parseAttributeReplacements(arg, xml): - dict = {} + attr_dict = {} for part in splitParts(arg): m = _attr_re.match(part) if not m: @@ -123,10 +138,10 @@ def parseAttributeReplacements(arg, xml): name, expr = m.groups() if not xml: name = name.lower() - if name in dict: + if name in attr_dict: raise TALError("Duplicate attribute name in attributes: %r" % part) - dict[name] = expr - return dict + attr_dict[name] = expr + return attr_dict def parseSubstitution(arg, position=(None, None)): m = _subst_re.match(arg) @@ -151,26 +166,26 @@ def isCurrentVersion(program): version = getProgramVersion(program) return version == TAL_VERSION -def isinstance_(ob, type): +def isinstance_(ob, kind): # Proxy-friendly and faster isinstance_ check for new-style objects try: - return type in ob.__class__.__mro__ + return kind in ob.__class__.__mro__ except AttributeError: return False def getProgramMode(program): version = getProgramVersion(program) - if (version == TAL_VERSION and isinstance_(program[1], tuple) and - len(program[1]) == 2): + if (version == TAL_VERSION and isinstance_(program[1], tuple) + and len(program[1]) == 2): opcode, mode = program[1] if opcode == "mode": return mode return None def getProgramVersion(program): - if (len(program) >= 2 and - isinstance_(program[0], tuple) and len(program[0]) == 2): + if (len(program) >= 2 + and isinstance_(program[0], tuple) and len(program[0]) == 2): opcode, version = program[0] if opcode == "version": return version diff --git a/src/zope/tal/talgenerator.py b/src/zope/tal/talgenerator.py index ac77c18..ce7470c 100644 --- a/src/zope/tal/talgenerator.py +++ b/src/zope/tal/talgenerator.py @@ -11,7 +11,8 @@ # FOR A PARTICULAR PURPOSE. # ############################################################################## -"""Code generator for TALInterpreter intermediate code. +""" +Code generator for :class:`~.TALInterpreter` intermediate code. """ import re @@ -37,12 +38,20 @@ except NameError: _name_rx = re.compile(NAME_RE) class TALGenerator(object): + """ + Generate intermediate code. + """ inMacroUse = 0 inMacroDef = 0 source_file = None def __init__(self, expressionCompiler=None, xml=1, source_file=None): + """ + :keyword expressionCompiler: The implementation of + :class:`zope.tal.interfaces.ITALExpressionCompiler` to use. + If not given, we'll use a simple, undocumented, compiler. + """ if not expressionCompiler: from zope.tal.dummyengine import DummyEngine expressionCompiler = DummyEngine() @@ -96,7 +105,7 @@ class TALGenerator(object): if self.optimizeStartTag(collect, item[1], item[2], ">"): continue if opcode == "startEndTag": - endsep = self.xml and "/>" or " />" + endsep = "/>" if self.xml else " />" if self.optimizeStartTag(collect, item[1], item[2], endsep): continue if opcode in ("beginScope", "endScope"): @@ -182,9 +191,9 @@ class TALGenerator(object): output = program[:2] prev2, prev1 = output for item in program[2:]: - if ( item[0] == "beginScope" - and prev1[0] == "setPosition" - and prev2[0] == "rawtextColumn"): + if (item[0] == "beginScope" + and prev1[0] == "setPosition" + and prev2[0] == "rawtextColumn"): position = output.pop()[1] text, column = output.pop()[1] prev1 = None, None @@ -302,7 +311,7 @@ class TALGenerator(object): self.emit("condition", cexpr, program) def emitRepeat(self, arg): - m = re.match("(?s)\s*(%s)\s+(.*)\Z" % NAME_RE, arg) + m = re.match(r"(?s)\s*(%s)\s+(.*)\Z" % NAME_RE, arg) if not m: raise TALError("invalid repeat syntax: " + repr(arg), self.position) diff --git a/src/zope/tal/talinterpreter.py b/src/zope/tal/talinterpreter.py index c2ad97b..82154db 100644 --- a/src/zope/tal/talinterpreter.py +++ b/src/zope/tal/talinterpreter.py @@ -26,10 +26,9 @@ from zope.tal.translationcontext import TranslationContext try: unicode - _BLANK = unicode('') except NameError: unicode = str # Python 3.x - _BLANK = '' +_BLANK = u'' # Avoid constructing this tuple over and over @@ -43,6 +42,7 @@ BOOLEAN_HTML_ATTRS = frozenset([ # From http://www.w3.org/TR/xhtml1/#guidelines (C.10) # TODO: The problem with this is that this is not valid XML and # can't be parsed back! + # XXX: This is an exact duplicate of htmltalparser.BOOLEAN_HTML_ATTRS. Why? "compact", "nowrap", "ismap", "declare", "noshade", "checked", "disabled", "readonly", "multiple", "selected", "noresize", "defer" @@ -116,25 +116,25 @@ class TALInterpreter(object): """TAL interpreter. Some notes on source annotations. They are HTML/XML comments added to the - output whenever sourceFile is changed by a setSourceFile bytecode. Source + output whenever ``sourceFile`` is changed by a ``setSourceFile`` bytecode. Source annotations are disabled by default, but you can turn them on by passing a - sourceAnnotations argument to the constructor. You can change the format + ``sourceAnnotations`` argument to the constructor. You can change the format of the annotations by overriding formatSourceAnnotation in a subclass. The output of the annotation is delayed until some actual text is output for two reasons: - 1. setPosition bytecode follows setSourceFile, and we need position + 1. ``setPosition`` bytecode follows ``setSourceFile``, and we need position information to output the line number. - 2. Comments are not allowed in XML documents before the <?xml?> + 2. Comments are not allowed in XML documents before the ``<?xml?>`` declaration. For performance reasons (TODO: premature optimization?) instead of checking - the value of _pending_source_annotation on every write to the output - stream, the _stream_write attribute is changed to point to - _annotated_stream_write method whenever _pending_source_annotation is + the value of ``_pending_source_annotation`` on every write to the output + stream, the ``_stream_write`` attribute is changed to point to + ``_annotated_stream_write`` method whenever ``_pending_source_annotation`` is set to True, and to _stream.write when it is False. The following - invariant always holds: + invariant always holds:: if self._pending_source_annotation: assert self._stream_write is self._annotated_stream_write @@ -149,36 +149,31 @@ class TALInterpreter(object): sourceAnnotations=0): """Create a TAL interpreter. - Optional arguments: - - stream -- output stream (defaults to sys.stdout). + :param program: A compiled program, as generated + by :class:`zope.tal.talgenerator.TALGenerator` + :param macros: Namespace of macros, usually also from + :class:`~.TALGenerator` - debug -- enable debugging output to sys.stderr (off by default). + Optional arguments: - wrap -- try to wrap attributes on opening tags to this number of + :keyword stream: output stream (defaults to sys.stdout). + :keyword bool debug: enable debugging output to sys.stderr (off by default). + :keyword int wrap: try to wrap attributes on opening tags to this number of column (default: 1023). - - metal -- enable METAL macro processing (on by default). - - tal -- enable TAL processing (on by default). - - showtal -- do not strip away TAL directives. A special value of + :keyword bool metal: enable METAL macro processing (on by default). + :keyword bool tal: enable TAL processing (on by default). + :keyword int showtal: do not strip away TAL directives. A special value of -1 (which is the default setting) enables showtal when TAL processing is disabled, and disables showtal when TAL processing is enabled. Note that you must use 0, 1, or -1; true boolean values - are not supported (TODO: why?). - - strictinsert -- enable TAL processing and stricter HTML/XML + are not supported (for historical reasons). + :keyword bool strictinsert: enable TAL processing and stricter HTML/XML checking on text produced by structure inserts (on by default). Note that Zope turns this value off by default. - - stackLimit -- set macro nesting limit (default: 100). - - i18nInterpolate -- enable i18n translations (default: on). - - sourceAnnotations -- enable source annotations with HTML comments + :keyword int stackLimit: set macro nesting limit (default: 100). + :keyword bool i18nInterpolate: enable i18n translations (default: on). + :keyword bool sourceAnnotations: enable source annotations with HTML comments (default: off). - """ self.program = program self.macros = macros @@ -266,6 +261,11 @@ class TALInterpreter(object): return self.macroStack.pop() def __call__(self): + """ + Interpret the current program. + + :return: Nothing. + """ assert self.level == 0 assert self.scopeLevel == 0 assert self.i18nContext.parent is None @@ -1017,8 +1017,7 @@ class TALInterpreter(object): class FasterStringIO(list): - """Unicode-aware append-only version of StringIO. - """ + # Unicode-aware append-only version of StringIO. write = list.append def __init__(self, value=None): diff --git a/src/zope/tal/talparser.py b/src/zope/tal/talparser.py index 9adba2d..d99fc9f 100644 --- a/src/zope/tal/talparser.py +++ b/src/zope/tal/talparser.py @@ -11,7 +11,9 @@ # FOR A PARTICULAR PURPOSE. # ############################################################################## -"""Parse XML and compile to TALInterpreter intermediate code. +""" +Parse XML and compile to :class:`~.TALInterpreter` intermediate code, +using a :class:`~.TALGenerator`. """ from zope.tal.taldefs import XML_NS, ZOPE_I18N_NS, ZOPE_METAL_NS, ZOPE_TAL_NS from zope.tal.talgenerator import TALGenerator @@ -19,10 +21,22 @@ from zope.tal.xmlparser import XMLParser class TALParser(XMLParser): + """ + Parser for XML. + + After parsing with :meth:`~.XMLParser.parseFile`, + :meth:`~.XMLParser.parseString`, :meth:`~.XMLParser.parseURL` or + :meth:`~.XMLParser.parseStream`, you can call :meth:`getCode` to + retrieve the parsed program and macros. + """ ordered_attributes = 1 def __init__(self, gen=None, encoding=None): # Override + """ + :keyword TALGenerator gen: The configured (with an expression compiler) + code generator to use. If one is not given, a default will be used. + """ XMLParser.__init__(self, encoding) if gen is None: gen = TALGenerator() @@ -32,6 +46,7 @@ class TALParser(XMLParser): self.nsNew = [] def getCode(self): + """Return the compiled program and macros after parsing.""" return self.gen.getCode() def StartNamespaceDeclHandler(self, prefix, uri): @@ -117,7 +132,7 @@ class TALParser(XMLParser): def EndElementHandler(self, name): name = self.fixname(name)[0] - self.gen.emitEndElement(name, position=self.getpos()) + self.gen.emitEndElement(name, position=self.getpos()) def DefaultHandler(self, text): self.gen.emitRawText(text) diff --git a/src/zope/tal/xmlparser.py b/src/zope/tal/xmlparser.py index 9081d37..ca5c216 100644 --- a/src/zope/tal/xmlparser.py +++ b/src/zope/tal/xmlparser.py @@ -32,6 +32,9 @@ except NameError: class XMLParser(object): + """ + Parse XML using :mod:`xml.parsers.expat`. + """ ordered_attributes = 0 @@ -82,10 +85,12 @@ class XMLParser(object): return expat.ParserCreate(encoding, ' ') def parseFile(self, filename): + """Parse from the given filename.""" with open(filename, 'rb') as f: self.parseStream(f) def parseString(self, s): + """Parse the given string.""" if isinstance(s, unicode): # Expat cannot deal with unicode strings, only with # encoded ones. Also, its range of encodings is rather @@ -94,9 +99,11 @@ class XMLParser(object): self.parser.Parse(s, 1) def parseURL(self, url): + """Parse the given URL.""" self.parseStream(urlopen(url)) def parseStream(self, stream): + """Parse the given stream (open file).""" self.parser.ParseFile(stream) def parseFragment(self, s, end=0): @@ -113,4 +120,3 @@ class XMLParser(object): # [1] http://python.org/doc/current/lib/xmlparser-objects.html # [2] http://cvs.sourceforge.net/viewcvs.py/expat/expat/lib/expat.h return (self.parser.ErrorLineNumber, self.parser.ErrorColumnNumber) - @@ -1,6 +1,6 @@ [tox] envlist = - py27,py34,py35,py36,pypy,pypy3,coverage + py27,py34,py35,py36,pypy,pypy3,coverage,docs [testenv] commands = @@ -18,3 +18,12 @@ commands = deps = {[testenv]deps} coverage + +[testenv:docs] +basepython = + python2.7 +commands = + sphinx-build -b html -d docs/_build/doctrees docs docs/_build/html +deps = + {[testenv]deps} + .[docs] |