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:
parent
b7fc0003fd
commit
bcad6e8e9a
|
@ -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
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
The PDF documentation’s list of plugins doesn’t run off the page anymore.
|
File diff suppressed because it is too large
Load Diff
|
@ -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__":
|
||||||
|
|
Loading…
Reference in New Issue