diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 00000000..fa698fb1 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,54 @@ +# Generated from: +# https://github.com/plone/meta/tree/main/config/default +# See the inline comments on how to expand/tweak this configuration file +# +# EditorConfig Configuration file, for more details see: +# http://EditorConfig.org +# EditorConfig is a convention description, that could be interpreted +# by multiple editors to enforce common coding conventions for specific +# file types + +# top-most EditorConfig file: +# Will ignore other EditorConfig files in Home directory or upper tree level. +root = true + + +[*] # For All Files +# Unix-style newlines with a newline ending every file +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true +# Set default charset +charset = utf-8 +# Indent style default +indent_style = space +# Max Line Length - a hard line wrap, should be disabled +max_line_length = off + +[*.{py,cfg,ini}] +# 4 space indentation +indent_size = 4 + +[*.{yml,zpt,pt,dtml,zcml,html,xml}] +# 2 space indentation +indent_size = 2 + +[*.{json,jsonl,js,jsx,ts,tsx,css,less,scss}] # Frontend development +# 2 space indentation +indent_size = 2 +max_line_length = 80 + +[{Makefile,.gitmodules}] +# Tab indentation (no size specified, but view as 4 spaces) +indent_style = tab +indent_size = unset +tab_width = unset + + +## +# Add extra configuration options in .meta.toml: +# [editorconfig] +# extra_lines = """ +# _your own configuration lines_ +# """ +## diff --git a/.flake8 b/.flake8 new file mode 100644 index 00000000..38918f42 --- /dev/null +++ b/.flake8 @@ -0,0 +1,22 @@ +# Generated from: +# https://github.com/plone/meta/tree/main/config/default +# See the inline comments on how to expand/tweak this configuration file +[flake8] +doctests = 1 +ignore = + # black takes care of line length + E501, + # black takes care of where to break lines + W503, + # black takes care of spaces within slicing (list[:]) + E203, + # black takes care of spaces after commas + E231, + +## +# Add extra configuration options in .meta.toml: +# [flake8] +# extra_lines = """ +# _your own configuration lines_ +# """ +## diff --git a/.github/workflows/meta.yml b/.github/workflows/meta.yml new file mode 100644 index 00000000..1e444065 --- /dev/null +++ b/.github/workflows/meta.yml @@ -0,0 +1,66 @@ +# Generated from: +# https://github.com/plone/meta/tree/main/config/default +# See the inline comments on how to expand/tweak this configuration file +name: Meta +on: + push: + branches: + - master + - main + pull_request: + branches: + - master + - main + workflow_dispatch: + +## +# To set environment variables for all jobs, add in .meta.toml: +# [github] +# env = """ +# debug: 1 +# image-name: 'org/image' +# image-tag: 'latest' +# """ +## + +jobs: + qa: + uses: plone/meta/.github/workflows/qa.yml@main + test: + uses: plone/meta/.github/workflows/test.yml@main + coverage: + uses: plone/meta/.github/workflows/coverage.yml@main + release_ready: + uses: plone/meta/.github/workflows/release_ready.yml@main + circular: + uses: plone/meta/.github/workflows/circular.yml@main + +## +# To modify the list of default jobs being created add in .meta.toml: +# [github] +# jobs = [ +# "qa", +# "test", +# "coverage", +# "dependencies", +# "release_ready", +# "circular", +# ] +## + +## +# To request that some OS level dependencies get installed +# when running tests/coverage jobs, add in .meta.toml: +# [github] +# os_dependencies = "git libxml2 libxslt" +## + + +## +# Specify additional jobs in .meta.toml: +# [github] +# extra_lines = """ +# another: +# uses: org/repo/.github/workflows/file.yml@main +# """ +## diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml deleted file mode 100644 index 7d8005d6..00000000 --- a/.github/workflows/test.yml +++ /dev/null @@ -1,46 +0,0 @@ -name: Test - -on: - push: - branches-ignore: - - "master" - -jobs: - build: - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - python-version: - - "2.7" - - "3.5" - - "3.6" - - "3.7" - - "3.8" - - "3.9" - - "3.10" - - steps: - - uses: actions/checkout@v2 - - - name: Setup Python ${{ matrix.python-version }} - id: setup - uses: actions/setup-python@v2 - with: - python-version: ${{ matrix.python-version }} - - - name: Install package - run: | - pip install -c constraints.txt tox coverage - - - name: Run tests - env: - TOXENV: py${{ matrix.python-version }} - run: | - tox - - - name: Run coverage - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - coverage combine diff --git a/.gitignore b/.gitignore index 282e1642..486392f6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,20 +1,56 @@ -bin -develop-eggs -docs/_build -parts/ -build/ -_build/ -reports/ -dist/ +# Generated from: +# https://github.com/plone/meta/tree/main/config/default +# See the inline comments on how to expand/tweak this configuration file +# python related +*.egg-info *.pyc *.pyo -*.egg-info + +# translation related +*.mo + +# tools related +build/ +.coverage +.*project +coverage.xml +dist/ +docs/_build +__pycache__/ +.tox +.vscode/ +node_modules/ + +# venv / buildout related +bin/ +develop-eggs/ +eggs/ .eggs/ +etc/ .installed.cfg -.tox/ -include -lib/python2.7 -.python-version -.cache/ -coverage* -.coverage* +include/ +lib/ +lib64 +.mr.developer.cfg +parts/ +pyvenv.cfg +var/ +local.cfg + +# mxdev +/instance/ +/.make-sentinels/ +/*-mxdev.txt +/reports/ +/sources/ +/venv/ +.installed.txt + + +## +# Add extra configuration options in .meta.toml: +# [gitignore] +# extra_lines = """ +# _your own configuration lines_ +# """ +## diff --git a/.meta.toml b/.meta.toml new file mode 100644 index 00000000..5978838c --- /dev/null +++ b/.meta.toml @@ -0,0 +1,24 @@ +# Generated from: +# https://github.com/plone/meta/tree/main/config/default +# See the inline comments on how to expand/tweak this configuration file +[meta] +template = "default" +commit-id = "5d3e918e" + +[github] +jobs = [ + "qa", + "test", + "coverage", + "release_ready", + "circular", + ] + +[pre_commit] +zpretty_extra_lines = """ + # Various test failures when we change xml and html. + files: ".*.(zcml)$" +""" + +[pyproject] +codespell_skip = "*.po,*.min.js,*.graffle,src/diazo/tests/conditional-drop-in-append*" diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 00000000..68017b1b --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,96 @@ +# Generated from: +# https://github.com/plone/meta/tree/main/config/default +# See the inline comments on how to expand/tweak this configuration file +ci: + autofix_prs: false + autoupdate_schedule: monthly + +repos: +- repo: https://github.com/asottile/pyupgrade + rev: v3.15.0 + hooks: + - id: pyupgrade + args: [--py38-plus] +- repo: https://github.com/pycqa/isort + rev: 5.13.2 + hooks: + - id: isort +- repo: https://github.com/psf/black + rev: 24.1.1 + hooks: + - id: black +- repo: https://github.com/collective/zpretty + rev: 3.1.0 + hooks: + - id: zpretty + # Various test failures when we change xml and html. + files: ".*.(zcml)$" + +## +# Add extra configuration options in .meta.toml: +# [pre_commit] +# zpretty_extra_lines = """ +# _your own configuration lines_ +# """ +## +- repo: https://github.com/PyCQA/flake8 + rev: 7.0.0 + hooks: + - id: flake8 + +## +# Add extra configuration options in .meta.toml: +# [pre_commit] +# flake8_extra_lines = """ +# _your own configuration lines_ +# """ +## +- repo: https://github.com/codespell-project/codespell + rev: v2.2.6 + hooks: + - id: codespell + additional_dependencies: + - tomli + +## +# Add extra configuration options in .meta.toml: +# [pre_commit] +# codespell_extra_lines = """ +# _your own configuration lines_ +# """ +## +- repo: https://github.com/mgedmin/check-manifest + rev: "0.49" + hooks: + - id: check-manifest +- repo: https://github.com/regebro/pyroma + rev: "4.2" + hooks: + - id: pyroma +- repo: https://github.com/mgedmin/check-python-versions + rev: "0.22.0" + hooks: + - id: check-python-versions + args: ['--only', 'setup.py,pyproject.toml'] +- repo: https://github.com/collective/i18ndude + rev: "6.1.0" + hooks: + - id: i18ndude + + +## +# Add extra configuration options in .meta.toml: +# [pre_commit] +# i18ndude_extra_lines = """ +# _your own configuration lines_ +# """ +## + + +## +# Add extra configuration options in .meta.toml: +# [pre_commit] +# extra_lines = """ +# _your own configuration lines_ +# """ +## diff --git a/MANIFEST.in b/MANIFEST.in index 86944beb..5d5589de 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,28 +1,16 @@ # MANIFEST.in - Definition which files should be included in a release: # Files to include: -include *.txt -global-include *.rst -global-include *.cfg -global-include *.xsl -global-include *.py -global-include *.xsl -global-include *.zcml -global-include *.html -global-include *.css -global-include *.js -global-include *.cfg -global-include *.xml +include *.rst # Whitelist / Include Path completely: graft docs graft examples -graft lib -graft lib* -graft templates +graft src # Blacklist / Exclude Files and Path prune docs/_build +prune .tox global-exclude *pyc global-exclude *pyo global-exclude *pydinclude pyproject.toml diff --git a/bootstrap.py b/bootstrap.py deleted file mode 100755 index ed57894b..00000000 --- a/bootstrap.py +++ /dev/null @@ -1,178 +0,0 @@ -############################################################################## -# -# Copyright (c) 2006 Zope Foundation and Contributors. -# All Rights Reserved. -# -# This software is subject to the provisions of the Zope Public License, -# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. -# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED -# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS -# FOR A PARTICULAR PURPOSE. -# -############################################################################## -"""Bootstrap a buildout-based project - -Simply run this script in a directory containing a buildout.cfg. -The script accepts buildout command-line options, so you can -use the -c option to specify an alternate configuration file. -""" - -import os -import shutil -import sys -import tempfile - -from optparse import OptionParser - -tmpeggs = tempfile.mkdtemp() - -usage = '''\ -[DESIRED PYTHON FOR BUILDOUT] bootstrap.py [options] - -Bootstraps a buildout-based project. - -Simply run this script in a directory containing a buildout.cfg, using the -Python that you want bin/buildout to use. - -Note that by using --find-links to point to local resources, you can keep -this script from going over the network. -''' - -parser = OptionParser(usage=usage) -parser.add_option("-v", "--version", help="use a specific zc.buildout version") - -parser.add_option("-t", "--accept-buildout-test-releases", - dest='accept_buildout_test_releases', - action="store_true", default=False, - help=("Normally, if you do not specify a --version, the " - "bootstrap script and buildout gets the newest " - "*final* versions of zc.buildout and its recipes and " - "extensions for you. If you use this flag, " - "bootstrap and buildout will get the newest releases " - "even if they are alphas or betas.")) -parser.add_option("-c", "--config-file", - help=("Specify the path to the buildout configuration " - "file to be used.")) -parser.add_option("-f", "--find-links", - help=("Specify a URL to search for buildout releases")) -parser.add_option("--allow-site-packages", - action="store_true", default=False, - help=("Let bootstrap.py use existing site packages")) - - -options, args = parser.parse_args() - -###################################################################### -# load/install setuptools - -try: - if options.allow_site_packages: - import setuptools - import pkg_resources - from urllib.request import urlopen -except ImportError: - from urllib2 import urlopen - -ez = {} -exec(urlopen('https://bootstrap.pypa.io/ez_setup.py').read(), ez) - -if not options.allow_site_packages: - # ez_setup imports site, which adds site packages - # this will remove them from the path to ensure that incompatible versions - # of setuptools are not in the path - import site - # inside a virtualenv, there is no 'getsitepackages'. - # We can't remove these reliably - if hasattr(site, 'getsitepackages'): - for sitepackage_path in site.getsitepackages(): - sys.path[:] = [x for x in sys.path if sitepackage_path not in x] - -setup_args = dict(to_dir=tmpeggs, download_delay=0) -ez['use_setuptools'](**setup_args) -import setuptools -import pkg_resources - -# This does not (always?) update the default working set. We will -# do it. -for path in sys.path: - if path not in pkg_resources.working_set.entries: - pkg_resources.working_set.add_entry(path) - -###################################################################### -# Install buildout - -ws = pkg_resources.working_set - -cmd = [sys.executable, '-c', - 'from setuptools.command.easy_install import main; main()', - '-mZqNxd', tmpeggs] - -find_links = os.environ.get( - 'bootstrap-testing-find-links', - options.find_links or - ('http://downloads.buildout.org/' - if options.accept_buildout_test_releases else None) - ) -if find_links: - cmd.extend(['-f', find_links]) - -setuptools_path = ws.find( - pkg_resources.Requirement.parse('setuptools')).location - -requirement = 'zc.buildout' -version = options.version -if version is None and not options.accept_buildout_test_releases: - # Figure out the most recent final version of zc.buildout. - import setuptools.package_index - _final_parts = '*final-', '*final' - - def _final_version(parsed_version): - for part in parsed_version: - if (part[:1] == '*') and (part not in _final_parts): - return False - return True - index = setuptools.package_index.PackageIndex( - search_path=[setuptools_path]) - if find_links: - index.add_find_links((find_links,)) - req = pkg_resources.Requirement.parse(requirement) - if index.obtain(req) is not None: - best = [] - bestv = None - for dist in index[req.project_name]: - distv = dist.parsed_version - if _final_version(distv): - if bestv is None or distv > bestv: - best = [dist] - bestv = distv - elif distv == bestv: - best.append(dist) - if best: - best.sort() - version = best[-1].version -if version: - requirement = '=='.join((requirement, version)) -cmd.append(requirement) - -import subprocess -if subprocess.call(cmd, env=dict(os.environ, PYTHONPATH=setuptools_path)) != 0: - raise Exception( - "Failed to execute command:\n%s" % repr(cmd)[1:-1]) - -###################################################################### -# Import and run buildout - -ws.add_entry(tmpeggs) -ws.require(requirement) -import zc.buildout.buildout - -if not [a for a in args if '=' not in a]: - args.append('bootstrap') - -# if -c was provided, we push it back into args for buildout' main function -if options.config_file is not None: - args[0:0] = ['-c', options.config_file] - -zc.buildout.buildout.main(args) -shutil.rmtree(tmpeggs) diff --git a/buildout.cfg b/buildout.cfg deleted file mode 100644 index 3812ad2d..00000000 --- a/buildout.cfg +++ /dev/null @@ -1,28 +0,0 @@ -[buildout] -extends = versions.cfg -parts = - diazo - test - wsgi - sphinx -develop = . - -[diazo] -recipe = zc.recipe.egg -eggs = diazo -interpreter = py - -[test] -recipe = zc.recipe.testrunner -eggs = diazo [test] -defaults = ['--auto-color'] - -[wsgi] -recipe = zc.recipe.egg -eggs = - diazo [wsgi] - gearbox -scripts = gearbox - -[sphinx] -recipe = zc.recipe.egg diff --git a/checkdocs.cfg b/checkdocs.cfg deleted file mode 100644 index 18afe5a0..00000000 --- a/checkdocs.cfg +++ /dev/null @@ -1,6 +0,0 @@ -[buildout] -extends = buildout.cfg - -[diazo] -eggs += - collective.checkdocs diff --git a/constraints.txt b/constraints.txt deleted file mode 100644 index c6ad05aa..00000000 --- a/constraints.txt +++ /dev/null @@ -1,3 +0,0 @@ -# Constrains for testing Diazo / Plone Packages -# --------------------------------------------- - diff --git a/docs/advanced.rst b/docs/advanced.rst index a14c0abb..b7dd2cb1 100644 --- a/docs/advanced.rst +++ b/docs/advanced.rst @@ -127,7 +127,7 @@ For example, if the transform is set up to receive a string parameter -Use the ``if-not`` attribute to negate the conditon, for example:: +Use the ``if-not`` attribute to negate the condition, for example:: @@ -344,7 +344,7 @@ the included WSGI middleware include a ``doctype`` option which may be set to XInclude -------- -You may wish to re-use elements of your rules file across multiple themes. +You may wish to reuse elements of your rules file across multiple themes. This is particularly useful if you have multiple variations on the same theme used to style different pages on a particular website. diff --git a/docs/conf.py b/docs/conf.py index bb2cc956..ae789c75 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # # Diazo documentation build configuration file, created by # sphinx-quickstart on Tue Nov 2 18:58:07 2010. @@ -11,102 +10,100 @@ # 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.abspath('.')) # -- General configuration ----------------------------------------------------- # If your documentation needs a minimal Sphinx version, state it here. -#needs_sphinx = '1.0' +# 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 = [] # Add any paths that contain templates here, relative to this directory. -templates_path = ['_templates'] +templates_path = ["_templates"] # The suffix of source filenames. -source_suffix = '.rst' +source_suffix = ".rst" # The encoding of source files. -#source_encoding = 'utf-8-sig' +# source_encoding = 'utf-8-sig' # The master toctree document. -master_doc = 'index' +master_doc = "index" # General information about the project. -project = u'Diazo' -copyright = u'2011, Plone Foundation' +project = "Diazo" +copyright = "2011, Plone Foundation" # 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 = '1.0b1' +version = "1.0b1" # The full version, including alpha/beta/rc tags. -release = '1.0b1' +release = "1.0b1" # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. -#language = None +# language = None # There are two options for replacing |today|: either, you set today to some # non-false value, then it is used: -#today = '' +# today = '' # Else, today_fmt is used as the format for a strftime call. -#today_fmt = '%B %d, %Y' +# 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'] +exclude_patterns = ["_build"] # The reST default role (used for this markup: `text`) to use for all documents. -#default_role = None +# default_role = None # If true, '()' will be appended to :func: etc. cross-reference text. -#add_function_parentheses = True +# 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 +# add_module_names = True # If true, sectionauthor and moduleauthor directives will be shown in the # output. They are ignored by default. -#show_authors = False +# show_authors = False # The name of the Pygments (syntax highlighting) style to use. -pygments_style = 'sphinx' +pygments_style = "sphinx" # A list of ignored prefixes for module index sorting. -#modindex_common_prefix = [] +# 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 = 'haiku' +html_theme = "haiku" # 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 = {} +# html_theme_options = {} # Add any paths that contain custom themes here, relative to this directory. -#html_theme_path = [] +# html_theme_path = [] # The name for this set of Sphinx documents. If None, it defaults to # " v documentation". html_title = "Diazo" # A shorter title for the navigation bar. Default is the same as html_title. -#html_short_title = None +# html_short_title = None # The name of an image file (relative to this directory) to place at the top # of the sidebar. @@ -115,102 +112,98 @@ # 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 +# 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'] +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' +# 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 +# html_use_smartypants = True # Custom sidebar templates, maps document names to template names. -#html_sidebars = {} +# html_sidebars = {} # Additional templates that should be rendered to pages, maps page names to # template names. -#html_additional_pages = {} +# html_additional_pages = {} # If false, no module index is generated. -#html_domain_indices = True +# html_domain_indices = True # If false, no index is generated. -#html_use_index = True +# html_use_index = True # If true, the index is split into individual pages for each letter. -#html_split_index = False +# html_split_index = False # If true, links to the reST sources are added to the pages. -#html_show_sourcelink = True +# html_show_sourcelink = True # If true, "Created using Sphinx" is shown in the HTML footer. Default is True. -#html_show_sphinx = True +# html_show_sphinx = True # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. -#html_show_copyright = True +# html_show_copyright = True # If true, an OpenSearch description file will be output, and all pages will # contain a tag referring to it. The value of this option must be the # base URL from which the finished HTML is served. -#html_use_opensearch = '' +# html_use_opensearch = '' # This is the file name suffix for HTML files (e.g. ".xhtml"). -#html_file_suffix = None +# html_file_suffix = None # Output file base name for HTML help builder. -htmlhelp_basename = 'Diazodoc' +htmlhelp_basename = "Diazodoc" # -- Options for LaTeX output -------------------------------------------------- # The paper size ('letter' or 'a4'). -#latex_paper_size = 'letter' +# latex_paper_size = 'letter' # The font size ('10pt', '11pt' or '12pt'). -#latex_font_size = '10pt' +# 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', 'Diazo.tex', u'Diazo Documentation', - u'Plone Foundation', 'manual'), + ("index", "Diazo.tex", "Diazo Documentation", "Plone Foundation", "manual"), ] # The name of an image file (relative to this directory) to place at the top of # the title page. -#latex_logo = None +# latex_logo = None # For "manual" documents, if this is true, then toplevel headings are parts, # not chapters. -#latex_use_parts = False +# latex_use_parts = False # If true, show page references after internal links. -#latex_show_pagerefs = False +# latex_show_pagerefs = False # If true, show URL addresses after external links. -#latex_show_urls = False +# latex_show_urls = False # Additional stuff for the LaTeX preamble. -#latex_preamble = '' +# latex_preamble = '' # Documents to append as an appendix to all manuals. -#latex_appendices = [] +# latex_appendices = [] # If false, no module index is generated. -#latex_domain_indices = True +# 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', 'diazo', u'Diazo Documentation', - [u'Plone Foundation'], 1) -] +man_pages = [("index", "diazo", "Diazo Documentation", ["Plone Foundation"], 1)] diff --git a/docs/deployment.rst b/docs/deployment.rst index 26156496..ff518a9f 100644 --- a/docs/deployment.rst +++ b/docs/deployment.rst @@ -142,12 +142,12 @@ will need to compile Nginx with a special version of the XSLT module that can (optionally) use the HTML parser from libxml2. If you expect the source content to be xhtml well-formed and valid, then you -should be able to avoid the ``xslt_html_parser on;`` directive. You can +should be able to avoid the ``xslt_html_parser on;`` directive. You can achieve this if you generate the source content. -Otherwise, if you expect non-xhtml compliant html, you need to compile Nginx -from source. At the time of this writing, the html-xslt_ project proposes -full Nginx sources for Nginx 0.7 and 0.8, whereas Nginx is now 1.6 and 1.7. +Otherwise, if you expect non-xhtml compliant html, you need to compile Nginx +from source. At the time of this writing, the html-xslt_ project proposes +full Nginx sources for Nginx 0.7 and 0.8, whereas Nginx is now 1.6 and 1.7. Here is an alternative `patch `_ you should be able to apply to any Nginx source code with the command-line @@ -155,7 +155,7 @@ you should be able to apply to any Nginx source code with the command-line In the future, the necessary patches to enable HTML mode parsing will hopefully be part of the standard Nginx distribution. There also is a -`Nginx ticket `_ asking for the +`Nginx ticket `_ asking for the xslt_html_parser in the http_xslt_module. Using a properly patched Nginx, you can configure it with XSLT support like @@ -301,7 +301,7 @@ below uses this parameter to apply a filter:: } In this example the sub-request is set to loop back on itself, so the include -is taken from a themed page. ``filter.xsl`` (in the lib/diazo directory) and +is taken from a themed page. ``filter.xsl`` (in the src/diazo directory) and ``theme.xsl`` should both be placed in the same directory as ``Nginx.conf``. An example buildout is available in ``Nginx.cfg`` in this package. diff --git a/docs/introduction.rst b/docs/introduction.rst index 74655e63..7c3b35a8 100644 --- a/docs/introduction.rst +++ b/docs/introduction.rst @@ -42,7 +42,7 @@ Bear in mind that: be served from a static webserver, which is normally much faster than serving them from a dynamic application. * You can leave the original theme HTML untouched, which makes it easier to - re-use for other scenarios. For example, you can stitch two unrelated + reuse for other scenarios. For example, you can stitch two unrelated applications together by using a single theme file with separate rules files. This would result in two compiled XSLT files. You could use location match rules or similar techniques to choose which one to invoke for a given diff --git a/lib/diazo/runtrace.py b/lib/diazo/runtrace.py deleted file mode 100644 index 44a50c6e..00000000 --- a/lib/diazo/runtrace.py +++ /dev/null @@ -1,137 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -from diazo.rules import process_rules -from diazo.utils import pkg_xsl -from lxml import etree - -import logging - - -logger = logging.getLogger('diazo') - -_runtrace_to_html = pkg_xsl('runtrace_to_html.xsl') - - -def log_to_xml_string(error_log): - msgs = [l.message for l in error_log if l.message.startswith(' - {message:s} - -""".format(message=''.join(msgs)) - - -def generate_runtrace(rules, error_log, rules_parser=None): - """Annotate a rules file with the results of a transformation""" - def condition_name(trace): - """Generate attribute name for this entry""" - for k in trace.attrib.keys(): - if(k == 'theme_xmlid'): - continue - if(k.startswith('{http://namespaces.plone.org/diazo/css}')): - continue - return 'runtrace-' + k - - rules_doc = process_rules( - rules, - rules_parser=rules_parser, - stop='add_identifiers', - ) - trace_doc = etree.XML(log_to_xml_string(error_log)) - - for trace in trace_doc.xpath('/runtrace/runtrace'): - for el in rules_doc.xpath("id('" + trace.attrib['theme_xmlid'] + "')"): - el.set(condition_name(trace), trace.text or '') - return rules_doc - - -def runtrace_to_html(runtrace_doc): - """Convert the runtrace document into HTML""" - return _runtrace_to_html(runtrace_doc) - - -def error_log_to_html(error_log): - """Convert an error log into an HTML representation""" - doc = etree.Element('ul') - for l in error_log: - if l.message.startswith(' 1 and tokens[1] or None - return xsl_params - - -def _createOptionParser(usage): - parser = OptionParser(usage=usage) - parser.add_option( - '-o', - '--output', - metavar='output.xsl', - help='Output filename (instead of stdout)', - dest='output', - default=stdout, - ) - parser.add_option( - '-p', - '--pretty-print', - action='store_true', - help='Pretty print output (may alter rendering in browser)', - dest='pretty_print', - default=False, - ) - parser.add_option( - '--trace', - action='store_true', - help='Compiler trace logging', - dest='trace', - default=False, - ) - parser.add_option( - '-a', - '--absolute-prefix', - metavar='/', - help='relative urls in the theme file will be made into absolute ' - 'links with this prefix.', - dest='absolute_prefix', - default=None, - ) - parser.add_option( - '-i', - '--includemode', - metavar='INC', - help='include mode (document, ssi, ssiwait or esi)', - dest='includemode', - default=None, - ) - parser.add_option( - '-n', - '--network', - action='store_true', - help='Allow reads to the network to fetch resources', - dest='read_network', - default=False, - ) - parser.add_option( - '-t', - '--theme', - metavar='theme.html', - help='Theme file', - dest='theme', - default=None, - ) - parser.add_option( - '-r', - '--rules', - metavar='rules.xml', - help='Diazo rules file', - dest='rules', - default=None, - ) - parser.add_option( - '-c', - '--custom-parameters', - metavar='param1,param2=defaultval', - help='Comma-separated list of custom parameter names with optional ' - 'default values that the compiled theme will be able accept ' - 'when run', - dest='xsl_params', - default=None, - ) - parser.add_option( - '-e', - '--extra', - metavar='extra.xsl', - help='Extra XSL to be included in the transform ' - '(depracated, use inline xsl in the rules instead)', - dest='extra', - default=None, - ) - return parser diff --git a/lxml.cfg b/lxml.cfg deleted file mode 100644 index ebe1c1b7..00000000 --- a/lxml.cfg +++ /dev/null @@ -1,14 +0,0 @@ -[buildout] -extends = buildout.cfg - -# lxml must be first in parts. -parts = - lxml - diazo - test - -[lxml] -recipe = z3c.recipe.staticlxml -egg = lxml -libxml2-url = http://xmlsoft.org/sources/libxml2-2.7.7.tar.gz -libxslt-url = http://xmlsoft.org/sources/libxslt-1.1.26.tar.gz diff --git a/news/23.breaking b/news/23.breaking new file mode 100644 index 00000000..f7b54325 --- /dev/null +++ b/news/23.breaking @@ -0,0 +1,3 @@ +Drop support for Pythons that are end of life. +Support Python 3.8-3.12. +[maurits] diff --git a/news/5d3e918e.internal b/news/5d3e918e.internal new file mode 100644 index 00000000..c08f5399 --- /dev/null +++ b/news/5d3e918e.internal @@ -0,0 +1,2 @@ +Update configuration files. +[plone devs] diff --git a/nginx.cfg b/nginx.cfg deleted file mode 100644 index aa1e9ac9..00000000 --- a/nginx.cfg +++ /dev/null @@ -1,67 +0,0 @@ -[buildout] -extends = lxml.cfg -parts += - nginx - nginx.conf - example-theme - ploneorg-theme - rebuild-themes - -[nginx] -recipe = zc.recipe.cmmi -url = http://html-xslt.googlecode.com/files/nginx-0.7.67-html-xslt-4.tar.gz -# The SSI bug was fixed in nginx-0.7.65-html-xslt-2.tar.gz -extra_options = - --conf-path=${buildout:directory}/etc/nginx.conf - --sbin-path=${buildout:directory}/bin - --error-log-path=${buildout:directory}/var/log/nginx-error.log - --http-log-path=${buildout:directory}/var/log/nginx-access.log - --pid-path=${buildout:directory}/var/nginx.pid - --lock-path=${buildout:directory}/var/nginx.lock - --with-http_stub_status_module - --with-http_xslt_module - --with-libxml2=${buildout:directory}/parts/lxml/libxml2 - --with-libxslt=${buildout:directory}/parts/lxml/libxslt -# --with-debug --with-cc-opt="-O0" # helps debugging with gdb - -[nginx.conf] -recipe = collective.recipe.template -port = 8000 -root = ${buildout:directory}/examples -filter.xsl = ${buildout:directory}/lib/diazo/filter.xsl -example.xsl = ${buildout:directory}/etc/example.xsl -ploneorg.xsl = ${buildout:directory}/etc/ploneorg.xsl -input = ${buildout:directory}/templates/nginx.conf.in -output = ${buildout:directory}/etc/nginx.conf - -[example-theme] -recipe = plone.recipe.command -includemode = ssi -command = - ${buildout:directory}/bin/diazocompiler \ - --includemode=${:includemode} --output=${nginx.conf:example.xsl} \ - ${nginx.conf:root}/rules.xml ${nginx.conf:root}/theme.html -update-command = ${:command} - -[ploneorg-theme] -recipe = plone.recipe.command -includemode = ssi -command = - ${buildout:directory}/bin/diazocompiler \ - --includemode=${:includemode} --output=${nginx.conf:ploneorg.xsl} \ - --extra=${nginx.conf:root}/ploneorg/default-extra.xsl \ - ${nginx.conf:root}/ploneorg/default.xml ${nginx.conf:root}/ploneorg/plone.html -update-command = ${:command} - -[rebuild-themes] -recipe = collective.recipe.template -library-path = ${buildout:directory}/parts/lxml/libxml2/lib:${buildout:directory}/parts/lxml/libxslt/lib -inline = - #!/bin/sh - export LD_LIBRARY_PATH=${:library-path} - export DYLD_LIBRARY_PATH=${:library-path} - ${example-theme:command} && echo example theme rebuilt - ${ploneorg-theme:command} && echo ploneorg theme rebuilt - ${buildout:directory}/bin/nginx -s reload && echo nginx reloaded. -output = ${buildout:directory}/bin/rebuild-themes -mode = 755 diff --git a/pyproject.toml b/pyproject.toml index 05b615de..a4721559 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,12 @@ +# Generated from: +# https://github.com/plone/meta/tree/main/config/default +# See the inline comments on how to expand/tweak this configuration file +[build-system] +requires = ["setuptools>=68.2"] + [tool.towncrier] -filename = "CHANGES.rst" directory = "news/" +filename = "CHANGES.rst" title_format = "{version} ({project_date})" underlines = ["-", ""] @@ -18,3 +24,136 @@ showcontent = true directory = "bugfix" name = "Bug fixes:" showcontent = true + +[[tool.towncrier.type]] +directory = "internal" +name = "Internal:" +showcontent = true + +[[tool.towncrier.type]] +directory = "documentation" +name = "Documentation:" +showcontent = true + +[[tool.towncrier.type]] +directory = "tests" +name = "Tests" +showcontent = true + +## +# Add extra configuration options in .meta.toml: +# [pyproject] +# towncrier_extra_lines = """ +# extra_configuration +# """ +## + +[tool.isort] +profile = "plone" + +## +# Add extra configuration options in .meta.toml: +# [pyproject] +# isort_extra_lines = """ +# extra_configuration +# """ +## + +[tool.black] +target-version = ["py38"] + +## +# Add extra configuration options in .meta.toml: +# [pyproject] +# black_extra_lines = """ +# extra_configuration +# """ +## + +[tool.codespell] +ignore-words-list = "discreet," +skip = "*.po,*.po,*.min.js,*.graffle,src/diazo/tests/conditional-drop-in-append*" +## +# Add extra configuration options in .meta.toml: +# [pyproject] +# codespell_ignores = "foo,bar" +# codespell_skip = "*.po,*.map,package-lock.json" +## + +[tool.dependencychecker] +Zope = [ + # Zope own provided namespaces + 'App', 'OFS', 'Products.Five', 'Products.OFSP', 'Products.PageTemplates', + 'Products.SiteAccess', 'Shared', 'Testing', 'ZPublisher', 'ZTUtils', + 'Zope2', 'webdav', 'zmi', + # ExtensionClass own provided namespaces + 'ExtensionClass', 'ComputedAttribute', 'MethodObject', + # Zope dependencies + 'AccessControl', 'Acquisition', 'AuthEncoding', 'beautifulsoup4', 'BTrees', + 'cffi', 'Chameleon', 'DateTime', 'DocumentTemplate', + 'MultiMapping', 'multipart', 'PasteDeploy', 'Persistence', 'persistent', + 'pycparser', 'python-gettext', 'pytz', 'RestrictedPython', 'roman', + 'soupsieve', 'transaction', 'waitress', 'WebOb', 'WebTest', 'WSGIProxy2', + 'z3c.pt', 'zc.lockfile', 'ZConfig', 'zExceptions', 'ZODB', 'zodbpickle', + 'zope.annotation', 'zope.browser', 'zope.browsermenu', 'zope.browserpage', + 'zope.browserresource', 'zope.cachedescriptors', 'zope.component', + 'zope.configuration', 'zope.container', 'zope.contentprovider', + 'zope.contenttype', 'zope.datetime', 'zope.deferredimport', + 'zope.deprecation', 'zope.dottedname', 'zope.event', 'zope.exceptions', + 'zope.filerepresentation', 'zope.globalrequest', 'zope.hookable', + 'zope.i18n', 'zope.i18nmessageid', 'zope.interface', 'zope.lifecycleevent', + 'zope.location', 'zope.pagetemplate', 'zope.processlifetime', 'zope.proxy', + 'zope.ptresource', 'zope.publisher', 'zope.schema', 'zope.security', + 'zope.sequencesort', 'zope.site', 'zope.size', 'zope.structuredtext', + 'zope.tal', 'zope.tales', 'zope.testbrowser', 'zope.testing', + 'zope.traversing', 'zope.viewlet' +] +'Products.CMFCore' = [ + 'docutils', 'five.localsitemanager', 'Missing', 'Products.BTreeFolder2', + 'Products.GenericSetup', 'Products.MailHost', 'Products.PythonScripts', + 'Products.StandardCacheManagers', 'Products.ZCatalog', 'Record', + 'zope.sendmail', 'Zope' +] +'plone.base' = [ + 'plone.batching', 'plone.registry', 'plone.schema','plone.z3cform', + 'Products.CMFCore', 'Products.CMFDynamicViewFTI', +] +python-dateutil = ['dateutil'] + +## +# Add extra configuration options in .meta.toml: +# [pyproject] +# dependencies_ignores = "['zestreleaser.towncrier']" +# dependencies_mappings = [ +# "gitpython = ['git']", +# "pygithub = ['github']", +# ] +## + +[tool.check-manifest] +ignore = [ + ".editorconfig", + ".meta.toml", + ".pre-commit-config.yaml", + "tox.ini", + ".flake8", + "mx.ini", + +] +## +# Add extra configuration options in .meta.toml: +# [pyproject] +# check_manifest_ignores = """ +# "*.map.js", +# "*.pyc", +# """ +## + + +## +# Add extra configuration options in .meta.toml: +# [pyproject] +# extra_lines = """ +# _your own configuration lines_ +# """ +## diff --git a/setup.cfg b/setup.cfg index fc83f1e5..1adbac30 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,41 +1,15 @@ -[check-manifest] -ignore = - *.cfg - bootstrap.py - tox.ini - -[isort] -# for details see -# http://docs.plone.org/develop/styleguide/python.html#grouping-and-sorting -force_alphabetical_sort = True -force_single_line = True -lines_after_imports = 2 -line_length = 200 - -[flake8] -exclude = - -ignore = - [tool:pytest] addopts = -ra testpaths = # package-tests/ -norecursedirs = fixures - [coverage:run] branch = True -source = lib -omit = - bootstrap.py +source = src [coverage:report] precision = 2 [coverage:html] directory = reports/coverage - -[bdist_wheel] -universal = 1 diff --git a/setup.py b/setup.py index 28c732a6..4e91349d 100644 --- a/setup.py +++ b/setup.py @@ -1,71 +1,64 @@ -# -*- coding: utf-8 -*- - from setuptools import find_packages from setuptools import setup extras_require = { - 'wsgi': [ - 'repoze.xmliter', - 'WebOb', + "wsgi": [ + "repoze.xmliter", + "WebOb", ], - 'test': [ - 'repoze.xmliter', - 'WebOb', - 'py', + "test": [ + "repoze.xmliter", + "WebOb", ], } -readme = open('README.rst').read() -changes = open('CHANGES.rst').read() -long_desc = readme + '\n\n' + changes +readme = open("README.rst").read() +changes = open("CHANGES.rst").read() +long_desc = readme + "\n\n" + changes setup( - name='diazo', - version='1.5.1.dev0', + name="diazo", + version="1.5.1.dev0", description="""Diazo implements a Deliverance like language using a pure XSLT engine. With Diazo, you "compile" your theme and ruleset in one step, then use a superfast/simple transform on each request thereafter. Alternatively, compile your theme during development, check it into version control, and not touch Diazo during deployment.""", - keywords='web theming', + keywords="web theming", long_description=long_desc, - packages=find_packages('lib'), - package_dir={'': 'lib'}, + packages=find_packages("src"), + package_dir={"": "src"}, include_package_data=True, zip_safe=False, - author='Paul Everitt, Laurence Rowe and Martin Aspeli.', - author_email='laurence@lrowe.co.uk', - url='http://diazo.org', - license='New BSD', + author="Paul Everitt, Laurence Rowe and Martin Aspeli.", + author_email="laurence@lrowe.co.uk", + url="http://diazo.org", + license="New BSD", classifiers=[ - 'Development Status :: 6 - Mature', - 'License :: OSI Approved :: BSD License', - 'Programming Language :: Python', - 'Programming Language :: Python :: 2', - 'Programming Language :: Python :: 2.7', - 'Programming Language :: Python :: 3', - 'Programming Language :: Python :: 3.5', - 'Programming Language :: Python :: 3.6', - 'Programming Language :: Python :: 3.7', - 'Programming Language :: Python :: 3.8', - 'Programming Language :: Python :: 3.9', - 'Programming Language :: Python :: 3.10', - 'Topic :: Internet :: WWW/HTTP', - 'Topic :: Internet :: WWW/HTTP :: WSGI', - 'Topic :: Internet :: WWW/HTTP :: WSGI :: Middleware', - 'Topic :: Text Processing :: Markup :: XML', + "Development Status :: 6 - Mature", + "License :: OSI Approved :: BSD License", + "Programming Language :: Python", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Topic :: Internet :: WWW/HTTP", + "Topic :: Internet :: WWW/HTTP :: WSGI", + "Topic :: Internet :: WWW/HTTP :: WSGI :: Middleware", + "Topic :: Text Processing :: Markup :: XML", ], + python_requires=">=3.8", install_requires=[ - # 'setuptools', - 'lxml', - 'cssselect', - 'six', + # 'setuptools', + "lxml", + "cssselect", ], extras_require=extras_require, - test_suite='diazo.tests.alltests', - tests_require=extras_require['test'], + test_suite="diazo.tests.alltests", + tests_require=extras_require["test"], entry_points=""" [console_scripts] diazocompiler = diazo.compiler:main diff --git a/lib/diazo/__init__.py b/src/diazo/__init__.py similarity index 60% rename from lib/diazo/__init__.py rename to src/diazo/__init__.py index f4421686..861028b8 100644 --- a/lib/diazo/__init__.py +++ b/src/diazo/__init__.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- - import logging diff --git a/lib/diazo/annotate-rules.xsl b/src/diazo/annotate-rules.xsl similarity index 100% rename from lib/diazo/annotate-rules.xsl rename to src/diazo/annotate-rules.xsl diff --git a/lib/diazo/annotate-themes.xsl b/src/diazo/annotate-themes.xsl similarity index 100% rename from lib/diazo/annotate-themes.xsl rename to src/diazo/annotate-themes.xsl diff --git a/lib/diazo/apply-conditions.xsl b/src/diazo/apply-conditions.xsl similarity index 100% rename from lib/diazo/apply-conditions.xsl rename to src/diazo/apply-conditions.xsl diff --git a/lib/diazo/apply-rules.xsl b/src/diazo/apply-rules.xsl similarity index 100% rename from lib/diazo/apply-rules.xsl rename to src/diazo/apply-rules.xsl diff --git a/lib/diazo/compiler.py b/src/diazo/compiler.py similarity index 81% rename from lib/diazo/compiler.py rename to src/diazo/compiler.py index 14e692b6..78e63e9b 100644 --- a/lib/diazo/compiler.py +++ b/src/diazo/compiler.py @@ -1,5 +1,4 @@ #!/usr/bin/env python -# -*- coding: utf-8 -*- """\ Usage: %prog [options] [-r] RULES [-t] THEME @@ -18,30 +17,29 @@ from diazo.utils import quote_param from diazo.utils import split_params from lxml import etree -from six import string_types import logging import pkg_resources -logger = logging.getLogger('diazo') +logger = logging.getLogger("diazo") usage = __doc__ def set_parser(stylesheet, parser, compiler_parser=None): - file_obj = pkg_resources.resource_filename('diazo', 'dummy.html') + file_obj = pkg_resources.resource_filename("diazo", "dummy.html") with open(file_obj) as file_handler: dummy_doc = etree.parse( file_handler, parser=parser, ) - name = 'file:///__diazo__' + name = "file:///__diazo__" resolver = CustomResolver({name: stylesheet}) if compiler_parser is None: compiler_parser = etree.XMLParser() compiler_parser.resolvers.add(resolver) - identity = pkg_xsl('identity.xsl', compiler_parser) - output_doc = identity(dummy_doc, docurl="'{name}'".format(name=name)) + identity = pkg_xsl("identity.xsl", compiler_parser) + output_doc = identity(dummy_doc, docurl=f"'{name}'") compiler_parser.resolvers.remove(resolver) return output_doc @@ -49,8 +47,8 @@ def set_parser(stylesheet, parser, compiler_parser=None): def build_xsl_params_document(xsl_params): if xsl_params is None: xsl_params = {} - if 'path' not in xsl_params: - xsl_params['path'] = '' + if "path" not in xsl_params: + xsl_params["path"] = "" known_params = etree.XML( '', @@ -58,14 +56,14 @@ def build_xsl_params_document(xsl_params): for param_name, param_value in xsl_params.items(): param_element = etree.SubElement( known_params, - '{http://www.w3.org/1999/XSL/Transform}param', + "{http://www.w3.org/1999/XSL/Transform}param", ) - param_element.attrib['name'] = param_name - if isinstance(param_value, string_types): + param_element.attrib["name"] = param_name + if isinstance(param_value, str): param_element.text = param_value else: - param_element.attrib['select'] = str(quote_param(param_value)) - param_element.tail = '\n' + param_element.attrib["select"] = str(quote_param(param_value)) + param_element.tail = "\n" return known_params @@ -93,7 +91,7 @@ def compile_theme( * ``rules`` is the rules file * ``theme`` is the theme file - * ``extra`` is an optional XSLT file with Diazo extensions (depracated, use + * ``extra`` is an optional XSLT file with Diazo extensions (deprecated, use inline xsl in the rules instead) * ``css`` can be set to False to disable CSS syntax support (providing a moderate speed gain) @@ -125,7 +123,7 @@ def compile_theme( names. Values are default values. """ if access_control is not None: - read_network = access_control.options['read_network'] + read_network = access_control.options["read_network"] rules_doc = process_rules( rules=rules, theme=theme, @@ -146,23 +144,25 @@ def compile_theme( known_params = build_xsl_params_document(xsl_params) # Create a pseudo resolver for this - known_params_url = 'file:///__diazo_known_params__' - emit_stylesheet_resolver = CustomResolver({ - known_params_url: etree.tostring(known_params), - }) + known_params_url = "file:///__diazo_known_params__" + emit_stylesheet_resolver = CustomResolver( + { + known_params_url: etree.tostring(known_params), + } + ) emit_stylesheet_parser = etree.XMLParser() emit_stylesheet_parser.resolvers.add(emit_stylesheet_resolver) # Set up parameters params = {} if indent is not None: - params['indent'] = indent and "'yes'" or "'no'" - params['known_params_url'] = quote_param(known_params_url) - params['runtrace'] = '1' if runtrace else '0' + params["indent"] = indent and "'yes'" or "'no'" + params["known_params_url"] = quote_param(known_params_url) + params["runtrace"] = "1" if runtrace else "0" # Run the final stage compiler emit_stylesheet = pkg_xsl( - 'emit-stylesheet.xsl', + "emit-stylesheet.xsl", parser=emit_stylesheet_parser, ) compiled_doc = emit_stylesheet(rules_doc, **params) @@ -176,8 +176,7 @@ def compile_theme( def main(): - """Called from console script - """ + """Called from console script""" parser = _createOptionParser(usage=usage) (options, args) = parser.parse_args() @@ -185,11 +184,11 @@ def main(): if len(args) == 2 and options.theme is None: options.rules, options.theme = args elif len(args) == 1: - options.rules, = args + (options.rules,) = args else: - parser.error('Wrong number of arguments.') + parser.error("Wrong number of arguments.") elif args: - parser.error('Wrong number of arguments.') + parser.error("Wrong number of arguments.") if options.trace: logger.setLevel(logging.DEBUG) @@ -210,13 +209,13 @@ def main(): ) root = output_xslt.getroot() if not root.tail: - root.tail = '\n' + root.tail = "\n" output_xslt.write( options.output, - encoding='utf-8', + encoding="utf-8", pretty_print=options.pretty_print, ) -if __name__ == '__main__': +if __name__ == "__main__": main() diff --git a/lib/diazo/cssrules.py b/src/diazo/cssrules.py similarity index 61% rename from lib/diazo/cssrules.py rename to src/diazo/cssrules.py index 34f55ce6..c651c50e 100644 --- a/lib/diazo/cssrules.py +++ b/src/diazo/cssrules.py @@ -1,5 +1,4 @@ #!/usr/bin/env python -# -*- coding: utf-8 -*- """\ Usage: %prog RULES @@ -11,7 +10,6 @@ \ """ -from __future__ import absolute_import from cssselect import GenericTranslator from diazo import utils @@ -22,14 +20,14 @@ import sys -logger = logging.getLogger('diazo') +logger = logging.getLogger("diazo") usage = __doc__ class LocationPathTranslator(GenericTranslator): def xpath_descendant_combinator(self, left, right): """right is a child, grand-child or further descendant of left""" - return left.join('//', right) + return left.join("//", right) _generic_translator = GenericTranslator() @@ -37,50 +35,49 @@ def xpath_descendant_combinator(self, left, right): def convert_css_selectors(rules): - """Convert css rules to xpath rules element tree in place - """ + """Convert css rules to xpath rules element tree in place""" # XXX: There is a :root pseudo-class # NOQA: T000 # http://www.w3.org/TR/css3-selectors/#root-pseudo # We may wish to add support to lxml.cssselect for it some day. for element in rules.xpath( - "//@*[namespace-uri()='{nsp}']/..".format(nsp=utils.namespaces['css']), + "//@*[namespace-uri()='{nsp}']/..".format(nsp=utils.namespaces["css"]), ): tag_namespace = utils.namespace(element.tag) css_prefix = element.attrib.get( utils.fullname( - utils.namespaces['css'], - 'prefix', + utils.namespaces["css"], + "prefix", ), None, ) for name, value in element.attrib.items(): if not name.startswith( - '{%s}' % utils.namespaces['css'], # NOQA: S001 + "{%s}" % utils.namespaces["css"], # NOQA: S001 ): continue localname = utils.localname(name) - if localname == 'prefix': + if localname == "prefix": continue if not value: - element.attrib[localname] = '' + element.attrib[localname] = "" continue if ( - tag_namespace == utils.namespaces['diazo'] and - localname in - ( - 'content', - 'content-children', - 'if-content', - 'if-not-content', - ) or ( - tag_namespace == utils.namespaces['xsl'] and - localname in ('match',) + tag_namespace == utils.namespaces["diazo"] + and localname + in ( + "content", + "content-children", + "if-content", + "if-not-content", + ) + or ( + tag_namespace == utils.namespaces["xsl"] and localname in ("match",) ) ): - prefix = css_prefix or '//' + prefix = css_prefix or "//" tr = _location_path_translator else: - prefix = css_prefix or 'descendant-or-self::' + prefix = css_prefix or "descendant-or-self::" tr = _generic_translator element.attrib[localname] = tr.css_to_xpath(value, prefix=prefix) @@ -88,33 +85,32 @@ def convert_css_selectors(rules): def main(): - """Called from console script - """ + """Called from console script""" parser = OptionParser(usage=usage) parser.add_option( - '-o', - '--output', - metavar='output.html', - help='Output filename (instead of stdout)', - dest='output', + "-o", + "--output", + metavar="output.html", + help="Output filename (instead of stdout)", + dest="output", default=sys.stdout, ) parser.add_option( - '-p', - '--pretty-print', - action='store_true', - help='Pretty print output', - dest='pretty_print', + "-p", + "--pretty-print", + action="store_true", + help="Pretty print output", + dest="pretty_print", default=False, ) (options, args) = parser.parse_args() if len(args) != 1: - parser.error('Invalid number of arguments') + parser.error("Invalid number of arguments") rules = etree.parse(args[0]) convert_css_selectors(rules) rules.write(options.output, pretty_print=options.pretty_print) -if __name__ == '__main__': +if __name__ == "__main__": main() diff --git a/lib/diazo/debug_resources/diazo-debug.css b/src/diazo/debug_resources/diazo-debug.css similarity index 100% rename from lib/diazo/debug_resources/diazo-debug.css rename to src/diazo/debug_resources/diazo-debug.css diff --git a/lib/diazo/debug_resources/diazo-debug.js b/src/diazo/debug_resources/diazo-debug.js similarity index 100% rename from lib/diazo/debug_resources/diazo-debug.js rename to src/diazo/debug_resources/diazo-debug.js diff --git a/lib/diazo/debug_resources/iframe.js b/src/diazo/debug_resources/iframe.js similarity index 100% rename from lib/diazo/debug_resources/iframe.js rename to src/diazo/debug_resources/iframe.js diff --git a/lib/diazo/debug_resources/jquery-1.8.3.min.js b/src/diazo/debug_resources/jquery-1.8.3.min.js similarity index 100% rename from lib/diazo/debug_resources/jquery-1.8.3.min.js rename to src/diazo/debug_resources/jquery-1.8.3.min.js diff --git a/lib/diazo/defaults.xsl b/src/diazo/defaults.xsl similarity index 100% rename from lib/diazo/defaults.xsl rename to src/diazo/defaults.xsl diff --git a/lib/diazo/diazo-debug.zcml b/src/diazo/diazo-debug.zcml similarity index 68% rename from lib/diazo/diazo-debug.zcml rename to src/diazo/diazo-debug.zcml index 285694a6..189dfd82 100644 --- a/lib/diazo/diazo-debug.zcml +++ b/src/diazo/diazo-debug.zcml @@ -2,14 +2,16 @@ xmlns="http://namespaces.zope.org/zope" xmlns:browser="http://namespaces.zope.org/browser" xmlns:gs="http://namespaces.zope.org/genericsetup" - xmlns:zcml="http://namespaces.zope.org/zcml" xmlns:i18n="http://namespaces.zope.org/i18n" xmlns:plone="http://namespaces.plone.org/plone" - i18n_domain="plone"> + xmlns:zcml="http://namespaces.zope.org/zcml" + i18n_domain="plone" + > - - + + diff --git a/lib/diazo/dummy.html b/src/diazo/dummy.html similarity index 100% rename from lib/diazo/dummy.html rename to src/diazo/dummy.html diff --git a/lib/diazo/emit-stylesheet.xsl b/src/diazo/emit-stylesheet.xsl similarity index 100% rename from lib/diazo/emit-stylesheet.xsl rename to src/diazo/emit-stylesheet.xsl diff --git a/lib/diazo/filter.xsl b/src/diazo/filter.xsl similarity index 100% rename from lib/diazo/filter.xsl rename to src/diazo/filter.xsl diff --git a/lib/diazo/filter_html.xsl b/src/diazo/filter_html.xsl similarity index 100% rename from lib/diazo/filter_html.xsl rename to src/diazo/filter_html.xsl diff --git a/lib/diazo/filter_xhtml.xsl b/src/diazo/filter_xhtml.xsl similarity index 100% rename from lib/diazo/filter_xhtml.xsl rename to src/diazo/filter_xhtml.xsl diff --git a/lib/diazo/fixup-themes.xsl b/src/diazo/fixup-themes.xsl similarity index 100% rename from lib/diazo/fixup-themes.xsl rename to src/diazo/fixup-themes.xsl diff --git a/lib/diazo/identity.xsl b/src/diazo/identity.xsl similarity index 100% rename from lib/diazo/identity.xsl rename to src/diazo/identity.xsl diff --git a/lib/diazo/include.xsl b/src/diazo/include.xsl similarity index 100% rename from lib/diazo/include.xsl rename to src/diazo/include.xsl diff --git a/lib/diazo/merge-conditions.xsl b/src/diazo/merge-conditions.xsl similarity index 100% rename from lib/diazo/merge-conditions.xsl rename to src/diazo/merge-conditions.xsl diff --git a/lib/diazo/normalize-rules.xsl b/src/diazo/normalize-rules.xsl similarity index 100% rename from lib/diazo/normalize-rules.xsl rename to src/diazo/normalize-rules.xsl diff --git a/lib/diazo/rules.py b/src/diazo/rules.py similarity index 65% rename from lib/diazo/rules.py rename to src/diazo/rules.py index a42cd427..dfab0e33 100644 --- a/lib/diazo/rules.py +++ b/src/diazo/rules.py @@ -1,5 +1,4 @@ #!/usr/bin/env python -# -*- coding: utf-8 -*- """\ Usage: %prog [-r] RULES @@ -12,15 +11,14 @@ from diazo.utils import namespaces from diazo.utils import pkg_xsl from lxml import etree -from six import string_types -from six.moves.urllib.parse import urljoin -from six.moves.urllib.request import urlopen +from urllib.parse import urljoin +from urllib.request import urlopen import logging import re -logger = logging.getLogger('diazo') +logger = logging.getLogger("diazo") usage = __doc__ IMPORT_STYLESHEET = re.compile( @@ -33,23 +31,23 @@ r"""(?P[^ \t\n\r\f\v>]+)(?P(?P=quote)[^>]*?>)""", re.IGNORECASE, ) -SRCSET = re.compile(r'(?P^\s*|\s*,\s*)(?P[^\s]*)') +SRCSET = re.compile(r"(?P^\s*|\s*,\s*)(?P[^\s]*)") -update_transform = pkg_xsl('update-namespace.xsl') -normalize_rules = pkg_xsl('normalize-rules.xsl') -include = pkg_xsl('include.xsl') -apply_conditions = pkg_xsl('apply-conditions.xsl') -merge_conditions = pkg_xsl('merge-conditions.xsl') -annotate_themes = pkg_xsl('annotate-themes.xsl') -annotate_rules = pkg_xsl('annotate-rules.xsl') -apply_rules = pkg_xsl('apply-rules.xsl') -fixup_themes = pkg_xsl('fixup-themes.xsl') +update_transform = pkg_xsl("update-namespace.xsl") +normalize_rules = pkg_xsl("normalize-rules.xsl") +include = pkg_xsl("include.xsl") +apply_conditions = pkg_xsl("apply-conditions.xsl") +merge_conditions = pkg_xsl("merge-conditions.xsl") +annotate_themes = pkg_xsl("annotate-themes.xsl") +annotate_rules = pkg_xsl("annotate-rules.xsl") +apply_rules = pkg_xsl("apply-rules.xsl") +fixup_themes = pkg_xsl("fixup-themes.xsl") def anchor_safe_urljoin(base, url): """Join the base with the url only when the url doesn't start with '#'""" - if url.startswith('#'): + if url.startswith("#"): return url else: return urljoin(base, url) @@ -59,40 +57,39 @@ def add_identifiers(rules_doc): """Add identifiers to the rules for debugging""" for index, elem in enumerate( rules_doc.xpath( - '//diazo:rules | //diazo:rules/diazo:*' - ' | //old1:rules | //old1:rules/old1:*' - ' | //old2:rules | //old2:rules/old1:*', + "//diazo:rules | //diazo:rules/diazo:*" + " | //old1:rules | //old1:rules/old1:*" + " | //old2:rules | //old2:rules/old1:*", namespaces=namespaces, ), ): elem.set( fullname( - namespaces['xml'], - 'id', + namespaces["xml"], + "id", ), - 'r{index}'.format(index=index), + f"r{index}", ) return rules_doc def update_namespace(rules_doc): - """Convert old namespace to new namespace in place - """ + """Convert old namespace to new namespace in place""" update = False - for ns in (namespaces['old1'], namespaces['old2']): - if rules_doc.xpath("//*[namespace-uri()='{ns:s}']".format(ns=ns)): + for ns in (namespaces["old1"], namespaces["old2"]): + if rules_doc.xpath(f"//*[namespace-uri()='{ns:s}']"): logger.warning( - 'The %s namespace is deprecated, use %s instead.', + "The %s namespace is deprecated, use %s instead.", ns, - namespaces['diazo'], + namespaces["diazo"], ) update = True - for ns in (namespaces['oldcss1'], namespaces['oldcss2']): - if rules_doc.xpath("//@*[namespace-uri()='{ns:s}']".format(ns=ns)): + for ns in (namespaces["oldcss1"], namespaces["oldcss2"]): + if rules_doc.xpath(f"//@*[namespace-uri()='{ns:s}']"): logger.warning( - 'The %s namespace is deprecated, use %s instead.', + "The %s namespace is deprecated, use %s instead.", ns, - namespaces['css'], + namespaces["css"], ) update = True if update: @@ -113,14 +110,14 @@ def update_namespace(rules_doc): def escape_curly_brackets(theme_doc): for node in theme_doc.iter(): for attr in node.attrib: - if '{' in node.attrib[attr]: - node.attrib[attr] = node.attrib[attr].replace('{', '{{') - if '}' in node.attrib[attr]: - node.attrib[attr] = node.attrib[attr].replace('}', '}}') + if "{" in node.attrib[attr]: + node.attrib[attr] = node.attrib[attr].replace("{", "{{") + if "}" in node.attrib[attr]: + node.attrib[attr] = node.attrib[attr].replace("}", "}}") def expand_theme(element, theme_doc, absolute_prefix): - prefix = urljoin(absolute_prefix, element.get('prefix', '')) + prefix = urljoin(absolute_prefix, element.get("prefix", "")) apply_absolute_prefix(theme_doc, prefix) escape_curly_brackets(theme_doc) theme_root = theme_doc.getroot() @@ -138,27 +135,28 @@ def expand_themes( absolute_prefix=None, read_network=False, ): - """Expand nodes with the theme html. - """ + """Expand nodes with the theme html.""" if absolute_prefix is None: - absolute_prefix = '' + absolute_prefix = "" base = rules_doc.docinfo.URL if parser is None: parser = etree.HTMLParser() for element in rules_doc.xpath( - '//diazo:theme[@href]', + "//diazo:theme[@href]", namespaces=namespaces, ): - url = urljoin(base, element.get('href')) - if not read_network and \ - url.startswith(('ftp://', 'ftps://', 'http://', 'https://')): + url = urljoin(base, element.get("href")) + if not read_network and url.startswith( + ("ftp://", "ftps://", "http://", "https://") + ): raise ValueError( "Supplied theme '{url}', but network access denied.".format( url=url, ), ) - elif read_network and \ - url.startswith(('ftp://', 'ftps://', 'http://', 'https://')): + elif read_network and url.startswith( + ("ftp://", "ftps://", "http://", "https://") + ): theme = urlopen(url) else: theme = url @@ -170,51 +168,58 @@ def expand_themes( def apply_absolute_prefix(theme_doc, absolute_prefix): if not absolute_prefix: return - if not absolute_prefix.endswith('/'): - absolute_prefix = absolute_prefix + '/' - for node in theme_doc.xpath('//*[@src]'): - url = urljoin(absolute_prefix, node.get('src')) - node.set('src', url) + if not absolute_prefix.endswith("/"): + absolute_prefix = absolute_prefix + "/" + for node in theme_doc.xpath("//*[@src]"): + url = urljoin(absolute_prefix, node.get("src")) + node.set("src", url) for xlink_attr in theme_doc.xpath('//@*[local-name()="xlink:href"]'): node = xlink_attr.getparent() - url = anchor_safe_urljoin(absolute_prefix, node.get('xlink:href')) - node.set('xlink:href', url) - for node in theme_doc.xpath('//*[@srcset]'): - srcset = node.get('srcset') + url = anchor_safe_urljoin(absolute_prefix, node.get("xlink:href")) + node.set("xlink:href", url) + for node in theme_doc.xpath("//*[@srcset]"): + srcset = node.get("srcset") srcset = SRCSET.sub( - lambda match: match.group('descriptors') + urljoin( + lambda match: match.group("descriptors") + + urljoin( absolute_prefix, - match.group('url'), + match.group("url"), ), srcset, ) - node.set('srcset', srcset) - for node in theme_doc.xpath('//*[@href]'): - url = anchor_safe_urljoin(absolute_prefix, node.get('href')) - node.set('href', url) - for node in theme_doc.xpath('//style'): + node.set("srcset", srcset) + for node in theme_doc.xpath("//*[@href]"): + url = anchor_safe_urljoin(absolute_prefix, node.get("href")) + node.set("href", url) + for node in theme_doc.xpath("//style"): if node.text is None: continue node.text = IMPORT_STYLESHEET.sub( - lambda match: match.group('before') + urljoin( + lambda match: match.group("before") + + urljoin( absolute_prefix, - match.group('url'), - ) + match.group('after'), + match.group("url"), + ) + + match.group("after"), node.text, ) for node in theme_doc.xpath('//comment()[starts-with(., "[if")]'): node.text = IMPORT_STYLESHEET.sub( - lambda match: match.group('before') + urljoin( + lambda match: match.group("before") + + urljoin( absolute_prefix, - match.group('url'), - ) + match.group('after'), + match.group("url"), + ) + + match.group("after"), node.text, ) node.text = CONDITIONAL_SRC.sub( - lambda match: match.group('before') + urljoin( + lambda match: match.group("before") + + urljoin( absolute_prefix, - match.group('url'), - ) + match.group('after'), + match.group("url"), + ) + + match.group("after"), node.text, ) @@ -222,7 +227,7 @@ def apply_absolute_prefix(theme_doc, absolute_prefix): def add_extra(rules_doc, extra): root = rules_doc.getroot() extra_elements = extra.xpath( - '/xsl:stylesheet/xsl:*', + "/xsl:stylesheet/xsl:*", namespaces=namespaces, ) root.extend(extra_elements) @@ -236,20 +241,22 @@ def add_theme( absolute_prefix=None, read_network=False, ): - if not read_network and \ - isinstance(theme, string_types) and \ - theme[:6] in ('ftp://', 'http:/', 'https:'): + if ( + not read_network + and isinstance(theme, str) + and theme[:6] in ("ftp://", "http:/", "https:") + ): raise ValueError( "Supplied theme '{theme}', but network access denied.".format( theme=theme, ), ) if absolute_prefix is None: - absolute_prefix = '' + absolute_prefix = "" if parser is None: parser = etree.HTMLParser() root = rules_doc.getroot() - element = root.makeelement(fullname(namespaces['diazo'], 'theme')) + element = root.makeelement(fullname(namespaces["diazo"], "theme")) root.append(element) theme_doc = etree.parse(theme, parser=parser) expand_theme(element, theme_doc, absolute_prefix) @@ -262,9 +269,9 @@ def fixup_theme_comment_selectors(rules): selector needs rewriting to replace comment() with xsl:comment """ for element in rules.xpath("//@theme[contains(., 'comment()')]/.."): - element.attrib['theme'] = element.attrib['theme'].replace( - 'comment()', - 'xsl:comment', + element.attrib["theme"] = element.attrib["theme"].replace( + "comment()", + "xsl:comment", ) return rules @@ -285,9 +292,9 @@ def process_rules( stop=None, ): if trace: - trace = '1' + trace = "1" else: - trace = '0' + trace = "0" if rules_parser is None: rules_parser = etree.XMLParser(recover=False) rules_doc = etree.parse(rules, parser=rules_parser) @@ -302,7 +309,7 @@ def process_rules( if stop == 1: return rules_doc rules_doc = add_identifiers(rules_doc) - if stop == 2 or stop == 'add_identifiers': + if stop == 2 or stop == "add_identifiers": return rules_doc if update: rules_doc = update_namespace(rules_doc) @@ -327,8 +334,8 @@ def process_rules( if stop == 6: return rules_doc if includemode is None: - includemode = 'document' - includemode = "'{mode:s}'".format(mode=includemode) + includemode = "document" + includemode = f"'{includemode:s}'" rules_doc = normalize_rules(rules_doc, includemode=includemode) if stop == 7: return rules_doc @@ -355,16 +362,15 @@ def process_rules( def main(): - """Called from console script - """ + """Called from console script""" parser = _createOptionParser(usage=usage) parser.add_option( - '-s', - '--stop', - metavar='n', - type='int', - help='Stop preprocessing at stage n', - dest='stop', + "-s", + "--stop", + metavar="n", + type="int", + help="Stop preprocessing at stage n", + dest="stop", default=None, ) (options, args) = parser.parse_args() @@ -373,11 +379,11 @@ def main(): if len(args) == 2 and options.theme is None: options.rules, options.theme = args elif len(args) == 1: - options.rules, = args + (options.rules,) = args else: - parser.error('Wrong number of arguments.') + parser.error("Wrong number of arguments.") elif args: - parser.error('Wrong number of arguments.') + parser.error("Wrong number of arguments.") if options.trace: logger.setLevel(logging.DEBUG) @@ -394,9 +400,9 @@ def main(): ) root = rules_doc.getroot() if not root.tail: - root.tail = '\n' + root.tail = "\n" rules_doc.write(options.output, pretty_print=options.pretty_print) -if __name__ == '__main__': +if __name__ == "__main__": main() diff --git a/lib/diazo/run.py b/src/diazo/run.py similarity index 70% rename from lib/diazo/run.py rename to src/diazo/run.py index 62264a72..5d1a9f5e 100644 --- a/lib/diazo/run.py +++ b/src/diazo/run.py @@ -1,5 +1,4 @@ #!/usr/bin/env python -# -*- coding: utf-8 -*- """\ Usage: %prog -x TRANSFORM CONTENT @@ -16,7 +15,6 @@ from diazo.utils import quote_param from diazo.utils import split_params from lxml import etree -from six import string_types import diazo.runtrace import logging @@ -24,7 +22,7 @@ import sys -logger = logging.getLogger('diazo') +logger = logging.getLogger("diazo") usage = __doc__ @@ -35,7 +33,7 @@ def __init__(self, directory): def resolve(self, url, id, context): # libxml2 does not do this correctly on it's own with the HTMLParser # but it does work in Apache - if '://' in url or url.startswith('/'): + if "://" in url or url.startswith("/"): # It seems we must explicitly resolve the url here return self.resolve_filename(url, context) url = os.path.join(self.directory, url) @@ -43,63 +41,62 @@ def resolve(self, url, id, context): def main(): - """Called from console script - """ + """Called from console script""" op = _createOptionParser(usage=usage) op.add_option( - '-x', - '--xsl', - metavar='transform.xsl', - help='XSL transform', - dest='xsl', + "-x", + "--xsl", + metavar="transform.xsl", + help="XSL transform", + dest="xsl", default=None, ) op.add_option( - '--path', - metavar='PATH', - help='URI path', - dest='path', + "--path", + metavar="PATH", + help="URI path", + dest="path", default=None, ) op.add_option( - '--parameters', - metavar='param1=val1,param2=val2', - help='Set the values of arbitrary parameters', - dest='parameters', + "--parameters", + metavar="param1=val1,param2=val2", + help="Set the values of arbitrary parameters", + dest="parameters", default=None, ) op.add_option( - '--runtrace-xml', - metavar='runtrace.xml', - help='Write an xml format runtrace to file', - dest='runtrace_xml', + "--runtrace-xml", + metavar="runtrace.xml", + help="Write an xml format runtrace to file", + dest="runtrace_xml", default=None, ) op.add_option( - '--runtrace-html', - metavar='runtrace.html', - help='Write an html format runtrace to file', - dest='runtrace_html', + "--runtrace-html", + metavar="runtrace.html", + help="Write an html format runtrace to file", + dest="runtrace_html", default=None, ) (options, args) = op.parse_args() if len(args) > 2: - op.error('Wrong number of arguments.') + op.error("Wrong number of arguments.") elif len(args) == 2: if options.xsl or options.rules: - op.error('Wrong number of arguments.') + op.error("Wrong number of arguments.") path, content = args - if path.lower().endswith('.xsl'): + if path.lower().endswith(".xsl"): options.xsl = path else: options.rules = path elif len(args) == 1: - content, = args + (content,) = args else: - op.error('Wrong number of arguments.') + op.error("Wrong number of arguments.") if options.rules is None and options.xsl is None: - op.error('Must supply either options or rules') + op.error("Must supply either options or rules") if options.trace: logger.setLevel(logging.DEBUG) @@ -131,7 +128,7 @@ def main(): runtrace=runtrace, ) - if content == '-': + if content == "-": content = sys.stdin if options.read_network: @@ -143,15 +140,15 @@ def main(): content_doc = etree.parse(content, parser=parser) params = {} if options.path is not None: - params['path'] = "'{path}'".format(path=options.path) + params["path"] = f"'{options.path}'" if options.parameters: for key, value in split_params(options.parameters).items(): params[key] = quote_param(value) output_html = transform(content_doc, **params) - if isinstance(options.output, string_types): - out = open(options.output, 'wt') + if isinstance(options.output, str): + out = open(options.output, "w") else: out = options.output out.write(str(output_html)) @@ -162,26 +159,26 @@ def main(): error_log=transform.error_log, ) if options.runtrace_xml: - if options.runtrace_xml == '-': + if options.runtrace_xml == "-": out = sys.stdout else: - out = open(options.runtrace_xml, 'wt') + out = open(options.runtrace_xml, "w") runtrace_doc.write( out, - encoding='utf-8', + encoding="utf-8", pretty_print=options.pretty_print, ) if options.runtrace_html: - if options.runtrace_html == '-': + if options.runtrace_html == "-": out = sys.stdout else: - out = open(options.runtrace_html, 'wt') + out = open(options.runtrace_html, "w") out.write(str(diazo.runtrace.runtrace_to_html(runtrace_doc))) for msg in transform.error_log: - if not msg.message.startswith(' + {message:s} + +""".format( + message="".join(msgs) + ) + + +def generate_runtrace(rules, error_log, rules_parser=None): + """Annotate a rules file with the results of a transformation""" + + def condition_name(trace): + """Generate attribute name for this entry""" + for k in trace.attrib.keys(): + if k == "theme_xmlid": + continue + if k.startswith("{http://namespaces.plone.org/diazo/css}"): + continue + return "runtrace-" + k + + rules_doc = process_rules( + rules, + rules_parser=rules_parser, + stop="add_identifiers", + ) + trace_doc = etree.XML(log_to_xml_string(error_log)) + + for trace in trace_doc.xpath("/runtrace/runtrace"): + for el in rules_doc.xpath("id('" + trace.attrib["theme_xmlid"] + "')"): + el.set(condition_name(trace), trace.text or "") + return rules_doc + + +def runtrace_to_html(runtrace_doc): + """Convert the runtrace document into HTML""" + return _runtrace_to_html(runtrace_doc) + + +def error_log_to_html(error_log): + """Convert an error log into an HTML representation""" + doc = etree.Element("ul") + for log in error_log: + if log.message.startswith("Smaller Title content new item from content - Someting very great from last content's DIV + Something very great from last content's DIV
content