|
29 | 29 | raise RuntimeError("Sphinx 1.0.1 or newer is required")
|
30 | 30 |
|
31 | 31 | from .docscrape_sphinx import get_doc_object, SphinxDocString
|
32 |
| -from sphinx.util.compat import Directive |
33 | 32 |
|
34 | 33 | if sys.version_info[0] >= 3:
|
35 | 34 | sixu = lambda s: s
|
@@ -132,7 +131,7 @@ def setup(app, get_doc_object_=get_doc_object):
|
132 | 131 | # Extra mangling domains
|
133 | 132 | app.add_domain(NumpyPythonDomain)
|
134 | 133 | app.add_domain(NumpyCDomain)
|
135 |
| - |
| 134 | + |
136 | 135 | metadata = {'parallel_read_safe': True}
|
137 | 136 | return metadata
|
138 | 137 |
|
@@ -184,15 +183,46 @@ class NumpyCDomain(ManglingDomainBase, CDomain):
|
184 | 183 |
|
185 | 184 |
|
186 | 185 | def match_items(lines, content_old):
|
187 |
| - """Create the right items for lines. |
188 |
| -
|
189 |
| - This tries to recover where a line in ``lines`` |
190 |
| - came from before mangling. |
| 186 | + """Create items for mangled lines. |
| 187 | +
|
| 188 | + This function tries to match the lines in ``lines`` |
| 189 | + with the items (source file references and line numbers) |
| 190 | + in ``content_old``. The ``mangle_docstrings`` function |
| 191 | + changes the actual docstrings, but doesn't keep track of |
| 192 | + where each line came from. The manging does many operations |
| 193 | + on the original lines, which are hard to track afterwards. |
| 194 | +
|
| 195 | + Many of the line changes come from deleting or inserting |
| 196 | + blank lines. This function tries to match lines by ignoring |
| 197 | + blank lines. All other changes (such as inserting figures |
| 198 | + or changes in the references) are compeltely ignored, so |
| 199 | + the generated line numbers will be off if ``mangle_docstrings`` |
| 200 | + does anything non-trivial. |
| 201 | +
|
| 202 | + This is a best-effort function and the real fix would be |
| 203 | + to make ``mangle_docstrings`` actually keep track of the |
| 204 | + ``items`` together with the ``lines``. |
| 205 | +
|
| 206 | + Examples |
| 207 | + -------- |
| 208 | + >>> lines = ['', 'A', '', 'B', ' ', '', 'C', 'D'] |
| 209 | + >>> lines_old = ['a', '', '', 'b', '', 'c'] |
| 210 | + >>> items_old = [('file1.py', 0), ('file1.py', 1), ('file1.py', 2), |
| 211 | + ... ('file2.py', 0), ('file2.py', 1), ('file2.py', 2)] |
| 212 | + >>> content_old = ViewList(lines_old, items=items_old) |
| 213 | + >>> match_items(lines, content_old) # doctest: +NORMALIZE_WHITESPACE |
| 214 | + [('file1.py', 0), ('file1.py', 0), ('file2.py', 0), ('file2.py', 0), |
| 215 | + ('file2.py', 2), ('file2.py', 2), ('file2.py', 2), ('file2.py', 2)] |
| 216 | + >>> # first 2 ``lines`` are matched to 'a', second 2 to 'b', rest to 'c' |
| 217 | + >>> # actual content is completely ignored. |
| 218 | +
|
| 219 | + Notes |
| 220 | + ----- |
| 221 | + The algorithm tries to match any line in ``lines`` with one in |
| 222 | + ``lines_old``. It skips over all empty lines in ``lines_old`` and assigns |
| 223 | + this line number to all lines in ``lines``, unless a non-empty line is |
| 224 | + found in ``lines`` in which case it goes to the next line in ``lines_old``. |
191 | 225 |
|
192 |
| - It assumes that missing or new lines are always empty. |
193 |
| - In reality, much more complicated things can happen, so |
194 |
| - this function is only a very coarse heuristic and the |
195 |
| - results are likely wrong, though possibly helpful as a guess. |
196 | 226 | """
|
197 | 227 | items_new = []
|
198 | 228 | lines_old = content_old.data
|
|
0 commit comments