diff options
| author | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2023-04-27 15:10:17 +0200 |
|---|---|---|
| committer | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2023-04-28 13:21:27 +0200 |
| commit | 70d3268fc36656dc7f6168b90fc1e480f049dcca (patch) | |
| tree | 7342fa9a5263b27e2d37d8125898f456eddc357f | |
| parent | b2e6fabb78836c8f040ddddcce5353ae85b8b15a (diff) | |
example_gallery: Fix literalinclude for project files
Make it possible to reference code snippets from the example
by relative file names. This makes it possible to write tutorial
examples.
Pick-to: 6.5
Task-number: PYSIDE-1106
Change-Id: Ie95d69c3f98be239e210c9c32b8fc9fb484639f4
Reviewed-by: Keith Kyzivat <keith.kyzivat@qt.io>
Reviewed-by: Shyamnath Premnadh <Shyamnath.Premnadh@qt.io>
| -rw-r--r-- | examples/charts/pointconfiguration/doc/pointconfiguration.rst | 18 | ||||
| -rw-r--r-- | sources/pyside6/doc/developer/add_port_example.rst | 7 | ||||
| -rw-r--r-- | tools/example_gallery/main.py | 39 |
3 files changed, 52 insertions, 12 deletions
diff --git a/examples/charts/pointconfiguration/doc/pointconfiguration.rst b/examples/charts/pointconfiguration/doc/pointconfiguration.rst index 9eb42ed57..ffe865d5e 100644 --- a/examples/charts/pointconfiguration/doc/pointconfiguration.rst +++ b/examples/charts/pointconfiguration/doc/pointconfiguration.rst @@ -29,7 +29,7 @@ Subclass QMainWindow Create a subclass of :py:`QMainWindow` to contain the chart and controls. -.. literalinclude:: ../../../../examples/charts/pointconfiguration/chartwindow.py +.. literalinclude:: chartwindow.py :linenos: :lineno-start: 16 :lines: 16-18 @@ -40,7 +40,7 @@ Create a line series Create a :py:`QLineSeries` containing the points to plot. Give it a name and make the points visible. -.. literalinclude:: ../../../../examples/charts/pointconfiguration/chartwindow.py +.. literalinclude:: chartwindow.py :linenos: :lineno-start: 20 :lines: 20-28 @@ -60,7 +60,7 @@ Now, create controls to configure the color, size, and label visibility attribut Do not set initial values for any of the controls, as a point will always be selected showing its current settings. -.. literalinclude:: ../../../../examples/charts/pointconfiguration/chartwindow.py +.. literalinclude:: chartwindow.py :linenos: :lineno-start: 31 :lines: 31-52 @@ -81,11 +81,11 @@ Query the :py:`PointConfigurations`, and use those to find the matching indices Set the current indices of the comboboxes to the corresponding values you looked up. Similarly, look up the values in :py:`PointConfigurations`, and update the checkbox and line edit controls. -.. literalinclude:: ../../../../examples/charts/pointconfiguration/chartwindow.py +.. literalinclude:: chartwindow.py :linenos: :lineno-start: 54 :lines: 54 -.. literalinclude:: ../../../../examples/charts/pointconfiguration/chartwindow.py +.. literalinclude:: chartwindow.py :linenos: :lineno-start: 97 :lines: 97-132 @@ -99,11 +99,11 @@ chosen values in the controls. You can do this by setting the :py:`QXYSeries::Po value that is associated with the control, to the :py:`m_selectedPointConfig` and :py:`PointConfigurations` member variables, and call :py:`QXYSeries::setPointConfiguration`. -.. literalinclude:: ../../../../examples/charts/pointconfiguration/chartwindow.py +.. literalinclude:: chartwindow.py :linenos: :lineno-start: 55 :lines: 55-60 -.. literalinclude:: ../../../../examples/charts/pointconfiguration/chartwindow.py +.. literalinclude:: chartwindow.py :linenos: :lineno-start: 140 :lines: 140-156 @@ -114,7 +114,7 @@ Create the chart and lay out the controls Finally, create the chart and its view, add the series to the chart, create the layout of the window, and select an initial point. -.. literalinclude:: ../../../../examples/charts/pointconfiguration/chartwindow.py +.. literalinclude:: chartwindow.py :linenos: :lineno-start: 62 :lines: 62-95 @@ -122,7 +122,7 @@ window, and select an initial point. In our entrypoint file `pointconfiguration.py`, instantiate the :py:`ChartWindow`, resize it, show it, and start the event loop. -.. literalinclude:: ../../../../examples/charts/pointconfiguration/pointconfiguration.py +.. literalinclude:: pointconfiguration.py :linenos: :lineno-start: 11 :lines: 11-17 diff --git a/sources/pyside6/doc/developer/add_port_example.rst b/sources/pyside6/doc/developer/add_port_example.rst index d599e50bf..6182d26c1 100644 --- a/sources/pyside6/doc/developer/add_port_example.rst +++ b/sources/pyside6/doc/developer/add_port_example.rst @@ -37,6 +37,13 @@ Add a new example - If you want the example to be automatically displayed on the example gallery, include a ``doc`` directory that contains a ``rst`` file and a screenshot. Check other examples for formatting questions. +- When writing the ``rst`` file, you can include code snippets using + the ``literalinclude`` directive specifying the relative path + as listed in the ``.pyproject`` file. The `example_gallery` tool will + expand this (see the `pointconfiguration` example). +- For the code displayed in the tabs, you can create ``rstinc`` files + in the ``doc`` directory containing some description explaining them + (see the `samplebinding` example). Port a Qt example ----------------- diff --git a/tools/example_gallery/main.py b/tools/example_gallery/main.py index 11a3ae159..73d17484c 100644 --- a/tools/example_gallery/main.py +++ b/tools/example_gallery/main.py @@ -14,6 +14,7 @@ since there is no special requirements. import json import math +import os import shutil import zipfile import sys @@ -24,6 +25,9 @@ from textwrap import dedent opt_quiet = False +LITERAL_INCLUDE = ".. literalinclude::" + + IMAGE_SUFFIXES = (".png", ".jpg", ".jpeg", ".gif", ".svg", ".svgz", ".webp") @@ -209,6 +213,37 @@ def get_header_title(example_dir): ) +def rel_path(from_path, to_path): + """Determine relative paths for paths that are not subpaths (where + relative_to() fails) via a common root.""" + common = Path(*os.path.commonprefix([from_path.parts, to_path.parts])) + up_dirs = len(from_path.parts) - len(common.parts) + prefix = up_dirs * "../" + rel_to_common = os.fspath(to_path.relative_to(common)) + return f"{prefix}{rel_to_common}" + + +def read_rst_file(project_dir, project_files, doc_rst): + """Read the example .rst file and expand literal includes to project files + by relative paths to the example directory. Note: sphinx does not + handle absolute paths as expected, they need to be relative.""" + content = "" + with open(doc_rst, encoding="utf-8") as doc_f: + content = doc_f.read() + if LITERAL_INCLUDE not in content: + return content + + result = [] + path_to_example = rel_path(EXAMPLES_DOC, project_dir) + for line in content.split("\n"): + if line.startswith(LITERAL_INCLUDE): + file = line[len(LITERAL_INCLUDE) + 1:].strip() + if file in project_files: + line = f"{LITERAL_INCLUDE} {path_to_example}/{file}" + result.append(line) + return "\n".join(result) + + if __name__ == "__main__": # Only examples with a '.pyproject' file will be listed. DIR = Path(__file__).parent @@ -309,9 +344,7 @@ if __name__ == "__main__": with open(rst_file_full, "w", encoding="utf-8") as out_f: if has_doc: doc_rst = original_doc_dir / f"{example_name}.rst" - - with open(doc_rst, encoding="utf-8") as doc_f: - content_f = doc_f.read() + content_f = read_rst_file(example_dir, files, doc_rst) # Copy other files in the 'doc' directory, but # excluding the main '.rst' file and all the |
