Make plugin list in PDF docs readable (#9241)

The current PDF docs attempt to format the list of all plugins as a
table, without any word-wrapping of the plugin description. That results
in almost all the information getting cut off. This PR formats the same
information into more of a paragraph format for the PDF, with nothing
cut off.

Fixes #451
This commit is contained in:
andrewdotn 2021-10-28 02:31:52 -06:00 committed by GitHub
parent b7fc0003fd
commit bcad6e8e9a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 7608 additions and 956 deletions

View File

@ -31,7 +31,7 @@ jobs:
- name: Install dependencies - name: Install dependencies
run: | run: |
python -m pip install --upgrade pip python -m pip install --upgrade pip
pip install packaging requests tabulate[widechars] pip install packaging requests tabulate[widechars] tqdm
- name: Update Plugin List - name: Update Plugin List
run: python scripts/update-plugin-list.py run: python scripts/update-plugin-list.py

1
changelog/451.doc.rst Normal file
View File

@ -0,0 +1 @@
The PDF documentations list of plugins doesnt run off the page anymore.

File diff suppressed because it is too large Load Diff

View File

@ -1,10 +1,14 @@
import datetime import datetime
import pathlib import pathlib
import re import re
from textwrap import dedent
from textwrap import indent
import packaging.version import packaging.version
import requests import requests
import tabulate import tabulate
import wcwidth
from tqdm import tqdm
FILE_HEAD = r""" FILE_HEAD = r"""
.. _plugin-list: .. _plugin-list:
@ -14,6 +18,11 @@ Plugin List
PyPI projects that match "pytest-\*" are considered plugins and are listed PyPI projects that match "pytest-\*" are considered plugins and are listed
automatically. Packages classified as inactive are excluded. automatically. Packages classified as inactive are excluded.
.. The following conditional uses a different format for this list when
creating a PDF, because otherwise the table gets far too wide for the
page.
""" """
DEVELOPMENT_STATUS_CLASSIFIERS = ( DEVELOPMENT_STATUS_CLASSIFIERS = (
"Development Status :: 1 - Planning", "Development Status :: 1 - Planning",
@ -42,10 +51,15 @@ def escape_rst(text: str) -> str:
def iter_plugins(): def iter_plugins():
regex = r">([\d\w-]*)</a>" regex = r">([\d\w-]*)</a>"
response = requests.get("https://pypi.org/simple") response = requests.get("https://pypi.org/simple")
for match in re.finditer(regex, response.text):
matches = list(
match
for match in re.finditer(regex, response.text)
if match.groups()[0].startswith("pytest-")
)
for match in tqdm(matches, smoothing=0):
name = match.groups()[0] name = match.groups()[0]
if not name.startswith("pytest-"):
continue
response = requests.get(f"https://pypi.org/pypi/{name}/json") response = requests.get(f"https://pypi.org/pypi/{name}/json")
if response.status_code == 404: if response.status_code == 404:
# Some packages, like pytest-azurepipelines42, are included in https://pypi.org/simple but # Some packages, like pytest-azurepipelines42, are included in https://pypi.org/simple but
@ -79,22 +93,47 @@ def iter_plugins():
summary = escape_rst(info["summary"].replace("\n", "")) summary = escape_rst(info["summary"].replace("\n", ""))
yield { yield {
"name": name, "name": name,
"summary": summary, "summary": summary.strip(),
"last release": last_release, "last release": last_release,
"status": status, "status": status,
"requires": requires, "requires": requires,
} }
def plugin_definitions(plugins):
"""Return RST for the plugin list that fits better on a vertical page."""
for plugin in plugins:
yield dedent(
f"""
{plugin['name']}
*last release*: {plugin["last release"]},
*status*: {plugin["status"]},
*requires*: {plugin["requires"]}
{plugin["summary"]}
"""
)
def main(): def main():
plugins = list(iter_plugins()) plugins = list(iter_plugins())
plugin_table = tabulate.tabulate(plugins, headers="keys", tablefmt="rst")
plugin_list = pathlib.Path("doc", "en", "reference", "plugin_list.rst") reference_dir = pathlib.Path("doc", "en", "reference")
plugin_list = reference_dir / "plugin_list.rst"
with plugin_list.open("w") as f: with plugin_list.open("w") as f:
f.write(FILE_HEAD) f.write(FILE_HEAD)
f.write(f"This list contains {len(plugins)} plugins.\n\n") f.write(f"This list contains {len(plugins)} plugins.\n\n")
f.write(plugin_table) f.write(".. only:: not latex\n\n")
f.write("\n")
wcwidth # reference library that must exist for tabulate to work
plugin_table = tabulate.tabulate(plugins, headers="keys", tablefmt="rst")
f.write(indent(plugin_table, " "))
f.write("\n\n")
f.write(".. only:: latex\n\n")
f.write(indent("".join(plugin_definitions(plugins)), " "))
if __name__ == "__main__": if __name__ == "__main__":