File: examples.py

package info (click to toggle)
trimesh 4.5.1-3
  • links: PTS, VCS
  • area: main
  • in suites: sid, trixie
  • size: 33,416 kB
  • sloc: python: 35,596; makefile: 96; javascript: 85; sh: 38
file content (146 lines) | stat: -rw-r--r-- 3,469 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
"""
examples.py
------------

Convert `ipynb` to a web-renderable format from the contents
of `../examples/*.ipynb`
"""

import logging
import os
import sys

log = logging.getLogger("trimesh")
log.addHandler(logging.StreamHandler(sys.stdout))
log.setLevel(logging.DEBUG)

# current working directory
pwd = os.path.abspath(os.path.expanduser(os.path.dirname(__file__)))


def extract_docstring(loaded):
    """
    Given a loaded JSON `ipynb` notebook extract
    the docstring from the first cell and error
    if the first cell doesn't have a docstring.

    Parameters
    ------------
    loaded : dict
      Loaded ipynb format.

    Returns
    ----------
    doc : str
      Cleaned up docstring.
    """

    source = loaded["cells"][0]["source"]

    assert source[0].strip() == '"""'
    assert source[-1].strip() == '"""'

    return " ".join(i.strip() for i in source[1:-1])


base = """
{title} </{file_name}.html>
"""


def generate_index(source: str, target: str) -> str:
    """
    Go through a directory of source `ipynb` files and write
    an RST index with a toctree.

    Also postprocesses the results of `jupyter nbconvert`
    """

    lines = [
        "Examples",
        "===========",
        "Several examples are available as rendered IPython notebooks.",
        "",
        ".. toctree::",
        "   :maxdepth: 2",
        "",
    ]

    target_dir = os.path.dirname(target)

    for fn in os.listdir(source):
        if not fn.lower().endswith(".ipynb"):
            continue

        name = fn.rsplit(".")[0]
        title = name.replace("_", " ").title()
        # notebook converted to RST
        convert = os.path.join(target_dir, f"{name}.rst")
        if not os.path.exists(convert):
            print(f"no RST for {name}.rst")
            continue

        with open(convert) as f:
            doc, post = postprocess(f.read(), title=title)
        with open(convert, "w") as f:
            f.write(post)

        lines.append(f"   {name}")
        # lines.append(doc)
        lines.append("")

    return "\n".join(lines)


def postprocess(text: str, title: str) -> str:
    """
    Postprocess an RST generated from `jupyter nbconvert`
    """
    lines = str.splitlines(text)

    # already has a title so exit
    if "===" in "".join(lines[:4]):
        return "", text

    head = []
    index = 0
    ready = False
    for i, L in enumerate(lines):
        if "parsed-literal" in L:
            ready = True
            continue
        if ready:
            if "code::" in L:
                index = i
                break
            else:
                head.append(L)

    # clean up the "parsed literal"
    docstring = (
        " ".join(" ".join(head).replace("\\n", " ").split()).strip().strip("'").strip()
    )

    # add a title and the docstring as a header
    clip = f"{title}\n=============\n{docstring}\n\n" + "\n".join(lines[index:])

    return docstring, clip


if __name__ == "__main__":
    import argparse

    parser = argparse.ArgumentParser()
    parser.add_argument(
        "--source", type=str, help="a directory containing `ipynb` files", required=True
    )
    parser.add_argument(
        "--target", type=str, help="Where the generated .rst file goes", required=True
    )
    args = parser.parse_args()

    source = os.path.abspath(args.source)
    target = os.path.abspath(args.target)

    with open(target, "w") as f:
        f.write(generate_index(source=source, target=target))