././@PaxHeader 0000000 0000000 0000000 00000000033 00000000000 010211 x ustar 00 27 mtime=1722215379.373484
sphinxcontrib_qthelp-2.0.0/CHANGES.rst 0000644 0000000 0000000 00000002271 14651565723 014530 0 ustar 00 Release 2.0.0 (2024-07-28)
==========================
* Adopt Ruff
* Tighten MyPy settings
* Update GitHub actions versions
Release 1.0.8 (2024-07-20)
==========================
* Fix tests for Sphinx 7.4 and later.
Release 1.0.7 (2024-01-13)
==========================
* Remove Sphinx as a required dependency, as circular dependencies may cause
failure with package managers that expect a directed acyclic graph (DAG)
of dependencies.
Release 1.0.6 (2023-08-14)
==========================
* Use ``os.PathLike`` over ``pathlib.Path``
Release 1.0.5 (2023-08-09)
==========================
* Fix tests for Sphinx 7.1 and below
Release 1.0.4 (2023-08-07)
==========================
* Drop support for Python 3.5, 3.6, 3.7, and 3.8
* Raise minimum required Sphinx version to 5.0
Release 1.0.3 (2019-02-29)
==========================
* Fix package metadata has broken
Release 1.0.2 (2019-02-24)
==========================
* #6097: the keyword IDs are not escaped qthelp in .qhp file
Release 1.0.1 (2019-02-15)
==========================
* Fix release package does not contain locale files
Release 1.0.0 (2019-01-18)
==========================
* Initial release (copied from sphinx package)
././@PaxHeader 0000000 0000000 0000000 00000000033 00000000000 010211 x ustar 00 27 mtime=1722215379.373484
sphinxcontrib_qthelp-2.0.0/LICENCE.rst 0000644 0000000 0000000 00000002633 14651565723 014524 0 ustar 00 License for sphinxcontrib-qthelp
================================
Copyright (c) 2007-2019 by the Sphinx team
(see https://github.com/sphinx-doc/sphinx/blob/master/AUTHORS).
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
././@PaxHeader 0000000 0000000 0000000 00000000033 00000000000 010211 x ustar 00 27 mtime=1722215379.373484
sphinxcontrib_qthelp-2.0.0/README.rst 0000644 0000000 0000000 00000000631 14651565723 014413 0 ustar 00 ====================
sphinxcontrib-qthelp
====================
sphinxcontrib-qthelp is a sphinx extension which outputs QtHelp document.
For more details, please visit http://www.sphinx-doc.org/.
Installing
==========
Install from PyPI::
pip install -U sphinxcontrib-qthelp
Contributing
============
See `CONTRIBUTING.rst`__
.. __: https://github.com/sphinx-doc/sphinx/blob/master/CONTRIBUTING.rst
././@PaxHeader 0000000 0000000 0000000 00000000033 00000000000 010211 x ustar 00 27 mtime=1722215379.373484
sphinxcontrib_qthelp-2.0.0/pyproject.toml 0000644 0000000 0000000 00000005272 14651565723 015646 0 ustar 00 [build-system]
requires = ["flit_core>=3.7"]
build-backend = "flit_core.buildapi"
# project metadata
[project]
name = "sphinxcontrib-qthelp"
description = "sphinxcontrib-qthelp is a sphinx extension which outputs QtHelp documents"
readme = "README.rst"
urls.Changelog = "https://github.com/sphinx-doc/sphinxcontrib-qthelp/blob/master/CHANGES.rst"
urls.Code = "https://github.com/sphinx-doc/sphinxcontrib-qthelp/"
urls.Download = "https://pypi.org/project/sphinxcontrib-qthelp/"
urls.Homepage = "https://www.sphinx-doc.org/"
urls."Issue tracker" = "https://github.com/sphinx-doc/sphinx/issues/"
license.text = "BSD-2-Clause"
requires-python = ">=3.9"
# Classifiers list: https://pypi.org/classifiers/
classifiers = [
"Development Status :: 5 - Production/Stable",
"Environment :: Console",
"Environment :: Web Environment",
"Intended Audience :: Developers",
"Intended Audience :: Education",
"License :: OSI Approved :: BSD License",
"Operating System :: OS Independent",
"Programming Language :: Python",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3 :: Only",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Framework :: Sphinx",
"Framework :: Sphinx :: Extension",
"Topic :: Documentation",
"Topic :: Documentation :: Sphinx",
"Topic :: Text Processing",
"Topic :: Utilities",
]
dependencies = []
dynamic = ["version"]
[project.optional-dependencies]
test = [
"pytest",
"defusedxml>=0.7.1", # for secure XML/HTML parsing
]
lint = [
"ruff==0.5.5",
"mypy",
"types-docutils",
]
standalone = [
"Sphinx>=5",
]
[[project.authors]]
name = "Georg Brandl"
email = "georg@python.org"
[tool.flit.module]
name = "sphinxcontrib.qthelp"
[tool.flit.sdist]
include = [
"CHANGES.rst",
"LICENCE.rst",
# Tests
"tests/",
"tox.ini",
]
[tool.mypy]
python_version = "3.9"
packages = [
"sphinxcontrib",
"tests",
]
exclude = [
"tests/roots",
]
check_untyped_defs = true
disallow_any_generics = true
disallow_incomplete_defs = true
disallow_subclassing_any = true
disallow_untyped_calls = true
disallow_untyped_decorators = true
disallow_untyped_defs = true
explicit_package_bases = true
extra_checks = true
no_implicit_reexport = true
show_column_numbers = true
show_error_context = true
strict_optional = true
warn_redundant_casts = true
warn_unused_configs = true
warn_unused_ignores = true
enable_error_code = [
"type-arg",
"redundant-self",
"truthy-iterable",
"ignore-without-code",
"unused-awaitable",
]
././@PaxHeader 0000000 0000000 0000000 00000000033 00000000000 010211 x ustar 00 27 mtime=1722215379.373484
sphinxcontrib_qthelp-2.0.0/sphinxcontrib/qthelp/__init__.py 0000644 0000000 0000000 00000024427 14651565723 021235 0 ustar 00 """Build input files for the Qt collection generator."""
from __future__ import annotations
import html
import os
import posixpath
import re
from collections.abc import Iterable
from os import path
from pathlib import Path
from typing import TYPE_CHECKING, Any, cast
from docutils import nodes
from sphinx import addnodes
from sphinx.builders.html import StandaloneHTMLBuilder
from sphinx.environment.adapters.indexentries import IndexEntries
from sphinx.locale import get_translation
from sphinx.util import logging
from sphinx.util.nodes import NodeMatcher
from sphinx.util.osutil import canon_path, make_filename
from sphinx.util.template import SphinxRenderer
if TYPE_CHECKING:
from docutils.nodes import Node
from sphinx.application import Sphinx
__version__ = '2.0.0'
__version_info__ = (2, 0, 0)
logger = logging.getLogger(__name__)
package_dir = path.abspath(path.dirname(__file__))
__ = get_translation(__name__, 'console')
_idpattern = re.compile(
r'(?P
.+) (\((class in )?(?P[\w\.]+)( (?P\w+))?\))$')
section_template = ''
def render_file(filename: str, **kwargs: Any) -> str:
pathname = path.join(package_dir, 'templates', filename)
return SphinxRenderer.render_from_file(pathname, kwargs)
class QtHelpBuilder(StandaloneHTMLBuilder):
"""
Builder that also outputs Qt help project, contents and index files.
"""
name = 'qthelp'
epilog = __('You can now run "qcollectiongenerator" with the .qhcp '
'project file in %(outdir)s, like this:\n'
'$ qcollectiongenerator %(outdir)s/%(project)s.qhcp\n'
'To view the help file:\n'
'$ assistant -collectionFile %(outdir)s/%(project)s.qhc')
# don't copy the reST source
copysource = False
supported_image_types = ['image/svg+xml', 'image/png', 'image/gif',
'image/jpeg']
# don't add links
add_permalinks = False
# don't add sidebar etc.
embedded = True
# disable download role
download_support = False
# don't generate the search index or include the search page
search = False
def init(self) -> None:
super().init()
# the output files for HTML help must be .html only
self.out_suffix = '.html'
self.link_suffix = '.html'
# self.config.html_style = 'traditional.css'
def get_theme_config(self) -> tuple[str, dict[str, str | int | bool]]:
return self.config.qthelp_theme, self.config.qthelp_theme_options
def handle_finish(self) -> None:
self.epilog = self.epilog % {
'outdir': '%(outdir)s',
'project': self.config.qthelp_basename,
}
self.build_qhp(self.outdir, self.config.qthelp_basename)
def build_qhp(self, outdir: str | os.PathLike[str], outname: str) -> None:
logger.info(__('writing project file...'))
# sections
tocdoc = self.env.get_and_resolve_doctree(self.config.master_doc, self,
prune_toctrees=False)
sections = []
matcher = NodeMatcher(addnodes.compact_paragraph, toctree=True)
for node in tocdoc.findall(matcher):
sections.extend(self.write_toc(node))
for indexname, indexcls, _content, _collapse in self.domain_indices:
item = section_template % {'title': indexcls.localname,
'ref': indexname + self.out_suffix}
sections.append(' ' * 4 * 4 + item)
sections = '\n'.join(sections) # type: ignore[assignment]
# keywords
keywords = []
index = IndexEntries(self.env).create_index(self, group_entries=False)
for (_group_key, group) in index:
for title, (refs, subitems, _category_key) in group:
keywords.extend(self.build_keywords(title, refs, subitems))
keywords = '\n'.join(keywords) # type: ignore[assignment]
# it seems that the "namespace" may not contain non-alphanumeric
# characters, and more than one successive dot, or leading/trailing
# dots, are also forbidden
if self.config.qthelp_namespace:
nspace = self.config.qthelp_namespace
else:
nspace = f'org.sphinx.{outname}.{self.config.version}'
nspace = re.sub(r'[^a-zA-Z0-9.\-]', '', nspace)
nspace = re.sub(r'\.+', '.', nspace).strip('.')
nspace = nspace.lower()
# write the project file
body = render_file('project.qhp', outname=outname,
title=self.config.html_title, version=self.config.version,
project=self.config.project, namespace=nspace,
master_doc=self.config.master_doc,
sections=sections, keywords=keywords,
files=self.get_project_files(outdir))
filename = Path(outdir, f'{outname}.qhp')
filename.write_text(body, encoding='utf-8')
homepage = 'qthelp://' + posixpath.join(
nspace, 'doc', self.get_target_uri(self.config.master_doc))
startpage = 'qthelp://' + posixpath.join(nspace, 'doc', f'index{self.link_suffix}')
logger.info(__('writing collection project file...'))
body = render_file('project.qhcp', outname=outname,
title=self.config.html_short_title,
homepage=homepage, startpage=startpage)
filename = Path(outdir, f'{outname}.qhcp')
filename.write_text(body, encoding='utf-8')
def isdocnode(self, node: Node) -> bool:
if not isinstance(node, nodes.list_item):
return False
if len(node.children) != 2:
return False
if not isinstance(node[0], addnodes.compact_paragraph):
return False
if not isinstance(node[0][0], nodes.reference):
return False
return isinstance(node[1], nodes.bullet_list)
def write_toc(self, node: Node, indentlevel: int = 4) -> list[str]:
parts: list[str] = []
if isinstance(node, nodes.list_item) and self.isdocnode(node):
compact_paragraph = cast(addnodes.compact_paragraph, node[0])
reference = cast(nodes.reference, compact_paragraph[0])
link = reference['refuri']
title = html.escape(reference.astext()).replace('"', '"')
item = f''
parts.append(' ' * 4 * indentlevel + item)
bullet_list = cast(nodes.bullet_list, node[1])
list_items = cast(Iterable[nodes.list_item], bullet_list)
for list_item in list_items:
parts.extend(self.write_toc(list_item, indentlevel + 1))
parts.append(' ' * 4 * indentlevel + '')
elif isinstance(node, nodes.list_item):
for subnode in node:
parts.extend(self.write_toc(subnode, indentlevel))
elif isinstance(node, nodes.reference):
link = node['refuri']
title = html.escape(node.astext()).replace('"', '"')
item = section_template % {'title': title, 'ref': link}
item = ' ' * 4 * indentlevel + item
parts.append(item.encode('ascii', 'xmlcharrefreplace').decode())
elif isinstance(node, (nodes.bullet_list, addnodes.compact_paragraph)):
for subnode in node:
parts.extend(self.write_toc(subnode, indentlevel))
return parts
def keyword_item(self, name: str, ref: Any) -> str:
matchobj = _idpattern.match(name)
if matchobj:
groupdict = matchobj.groupdict()
shortname = groupdict['title']
id = groupdict.get('id')
# descr = groupdict.get('descr')
if shortname.endswith('()'):
shortname = shortname[:-2]
id = html.escape(f'{id}.{shortname}', True)
else:
id = None
nameattr = html.escape(name, quote=True)
refattr = html.escape(ref[1], quote=True)
if id:
item = ' ' * 12 + f''
else:
item = ' ' * 12 + f''
item.encode('ascii', 'xmlcharrefreplace')
return item
def build_keywords(self, title: str, refs: list[Any], subitems: Any) -> list[str]:
keywords: list[str] = []
# if len(refs) == 0: # XXX
# write_param('See Also', title)
if len(refs) == 1:
keywords.append(self.keyword_item(title, refs[0]))
elif len(refs) > 1:
for _i, ref in enumerate(refs): # XXX # NoQA: FURB148
# item = (' '*12 +
# '' % (
# title, i, ref))
# item.encode('ascii', 'xmlcharrefreplace')
# keywords.append(item)
keywords.append(self.keyword_item(title, ref))
if subitems:
for subitem in subitems:
keywords.extend(self.build_keywords(subitem[0], subitem[1], []))
return keywords
def get_project_files(self, outdir: str | os.PathLike[str]) -> list[str]:
project_files = []
staticdir = path.join(outdir, '_static')
imagesdir = path.join(outdir, self.imagedir)
for root, _dirs, files in os.walk(outdir):
resourcedir = root.startswith((staticdir, imagesdir))
for fn in sorted(files):
if (resourcedir and not fn.endswith('.js')) or fn.endswith('.html'):
filename = path.relpath(path.join(root, fn), outdir)
project_files.append(canon_path(filename))
return project_files
def setup(app: Sphinx) -> dict[str, Any]:
app.require_sphinx('5.0')
app.setup_extension('sphinx.builders.html')
app.add_builder(QtHelpBuilder)
app.add_message_catalog(__name__, path.join(package_dir, 'locales'))
app.add_config_value('qthelp_basename', lambda self: make_filename(self.project), 'html')
app.add_config_value('qthelp_namespace', None, 'html', [str])
app.add_config_value('qthelp_theme', 'nonav', 'html')
app.add_config_value('qthelp_theme_options', {}, 'html')
return {
'version': __version__,
'parallel_read_safe': True,
'parallel_write_safe': True,
}
././@PaxHeader 0000000 0000000 0000000 00000000033 00000000000 010211 x ustar 00 27 mtime=1722215379.373484
sphinxcontrib_qthelp-2.0.0/sphinxcontrib/qthelp/locales/.tx/config 0000644 0000000 0000000 00000000332 14651565723 022434 0 ustar 00 [main]
host = https://www.transifex.com
[sphinx-1.sphinxcontrib-qthelp-pot]
file_filter = /LC_MESSAGES/sphinxcontrib.qthelp.po
minimum_perc = 0
source_file = sphinxcontrib.qthelp.pot
source_lang = en
type = PO
././@PaxHeader 0000000 0000000 0000000 00000000033 00000000000 010211 x ustar 00 27 mtime=1722215379.373484
sphinxcontrib_qthelp-2.0.0/sphinxcontrib/qthelp/locales/ar/LC_MESSAGES/sphinxcontrib.qthelp.mo 0000644 0000000 0000000 00000002252 14651565723 027450 0 ustar 00 <