Skip to content

Commit 9a6138e

Browse files
authored
Add support for manual indexing (#177)
- Allow the root api file generation to be skipped. - Allow ``.rst.include`` behavior to be modified. - Release 0.3.6.
1 parent 0cbf655 commit 9a6138e

File tree

7 files changed

+297
-39
lines changed

7 files changed

+297
-39
lines changed

README.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ Exhale Version Compatibility with Python, Sphinx, and Breathe
133133
+----------------+----------------+----------------+-----------------+
134134
| Exhale Version | Python Version | Sphinx Version | Breathe Version |
135135
+================+================+================+=================+
136-
| 0.3.2 -- 0.3.4 | >=3.7 | >=3.0,<5 | >=4.32.0 |
136+
| 0.3.2 -- 0.3.6 | >=3.7 | >=3.0,<5 | >=4.32.0 |
137137
+----------------+----------------+----------------+-----------------+
138138
| 0.3.0 | >=3.6 | >=3.0,<5 | >=4.32.0 |
139139
+----------------+----------------+----------------+-----------------+

docs/changelog.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,12 @@ Changelog
55
:local:
66
:backlinks: none
77

8+
v0.3.6
9+
----------------------------------------------------------------------------------------
10+
11+
- Enable the root document to be excluded, and additional manual indexing control
12+
(:issue:`176`, :pr:`177`).
13+
814
v0.3.5
915
----------------------------------------------------------------------------------------
1016

docs/reference/configs.rst

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,55 @@ that you will link to from your documentation is laid out as follows:
242242

243243
.. autodata:: exhale.configs.unabridgedOrphanKinds
244244

245+
.. _manual_indexing:
246+
247+
Manual Indexing
248+
****************************************************************************************
249+
250+
To compose the different sections of the root document, exhale generates some additional
251+
files to ``.. include::`` them. Depending on the compounds documented in doxygen as
252+
well as other settings different entries in the example below may or may not be
253+
generated.
254+
255+
.. code-block:: rst
256+
257+
=======================
258+
Some Title You Provided
259+
=======================
260+
261+
.. include:: page_index.rst.include
262+
263+
.. include:: page_view_hierarchy.rst.include
264+
265+
.. include:: class_view_hierarchy.rst.include
266+
267+
.. include:: file_view_hierarchy.rst.include
268+
269+
.. include:: unabridged_api.rst.include
270+
271+
These should **not** use a file extension found in :confval:`sphinx:source_suffix`,
272+
since the file ``class_view_hierarchy.rst`` for example will also be processed into
273+
html. This results in warnings between duplicate labels being found in both the root
274+
document and the document being included (`more information here`__).
275+
276+
__ https://github.com/sphinx-doc/sphinx/issues/1668
277+
278+
To manually index through the generated exhale documents, you can set
279+
:data:`~exhale.configs.rootFileName` to ``"EXCLUDE"``. With the root file out of the
280+
picture, you may seek to ``.. include::`` (or add to a ``.. toctree::``) one of the
281+
documents above. In the ``.. toctree::`` scenario, you will want the file extension to
282+
be ``.rst`` so that sphinx will process it.
283+
284+
.. autodata:: exhale.configs.classHierarchyFilename
285+
286+
.. autodata:: exhale.configs.fileHierarchyFilename
287+
288+
.. autodata:: exhale.configs.pageHierarchyFilename
289+
290+
.. autodata:: exhale.configs.unabridgedApiFilename
291+
292+
.. autodata:: exhale.configs.unabridgedOrphanFilename
293+
245294
Clickable Hierarchies
246295
****************************************************************************************
247296

exhale/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
from __future__ import unicode_literals
1010

11-
__version__ = "0.3.6.dev"
11+
__version__ = "0.3.6"
1212

1313

1414
def environment_ready(app):

exhale/configs.py

Lines changed: 49 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,11 @@
104104
documents. Do **not** include the ``containmentFolder`` path in this file name,
105105
Exhale will create the file ``"{contaimentFolder}/{rootFileName}"`` for you.
106106
107+
.. note::
108+
109+
If the value provided is exactly ``"EXCLUDE"`` then the root file will not be
110+
generated. See :ref:`manual_indexing` for more information.
111+
107112
**Value in** ``exhale_args`` (str)
108113
The value of key ``"rootFileName"`` should be a string representing the name of
109114
the file you will be including in your top-level ``toctree`` directive. In order
@@ -490,6 +495,40 @@ class and file hierarchies.
490495
will present classes and structs together.
491496
"""
492497

498+
########################################################################################
499+
# Manual Indexing #
500+
########################################################################################
501+
classHierarchyFilename = "class_view_hierarchy.rst.include"
502+
'''
503+
The name of the file the class hierarchy is generated in saved to
504+
``{containmentFolder}/{classHierarchyFilename}``.
505+
'''
506+
507+
fileHierarchyFilename = "file_view_hierarchy.rst.include"
508+
'''
509+
The name of the file the class hierarchy is generated in saved to
510+
``{containmentFolder}/{fileHierarchyFilename}``.
511+
'''
512+
513+
pageHierarchyFilename = "page_view_hierarchy.rst.include"
514+
'''
515+
The name of the file the class hierarchy is generated in saved to
516+
``{containmentFolder}/{pageHierarchyFilename}``.
517+
'''
518+
519+
unabridgedApiFilename = "unabridged_api.rst.include"
520+
'''
521+
The name of the file the class hierarchy is generated in saved to
522+
``{containmentFolder}/{unabridgedApiFilename}``.
523+
'''
524+
525+
unabridgedOrphanFilename = "unabridged_orphan.rst"
526+
'''
527+
The name of the file the class hierarchy is generated in saved to
528+
``{containmentFolder}/{unabridgedOrphanFilename}``. See also:
529+
:data:`~exhale.configs.unabridgedOrphanKinds`.
530+
'''
531+
493532
########################################################################################
494533
# Clickable Hierarchies <3 #
495534
########################################################################################
@@ -1412,11 +1451,11 @@ def apply_sphinx_configurations(app):
14121451
# We *ONLY* generate reStructuredText, make sure Sphinx is expecting this as well as
14131452
# the to-be-generated library root file is correctly suffixed.
14141453
if not rootFileName.endswith(".rst"):
1415-
raise ConfigError(
1416-
"The given `rootFileName` ({0}) did not end with '.rst'; Exhale is reStructuredText only.".format(
1417-
rootFileName
1454+
if rootFileName != "EXCLUDE":
1455+
raise ConfigError(
1456+
f"The given `rootFileName` ({rootFileName}) did not end with '.rst'; "
1457+
"Exhale is reStructuredText only."
14181458
)
1419-
)
14201459
if ".rst" not in app.config.source_suffix:
14211460
raise ConfigError(
14221461
"Exhale is reStructuredText only, but '.rst' was not found in `source_suffix` list of `conf.py`."
@@ -1447,6 +1486,12 @@ def apply_sphinx_configurations(app):
14471486
("fullToctreeMaxDepth", int),
14481487
("listingExclude", list),
14491488
("unabridgedOrphanKinds", (list, set)),
1489+
# Manual Indexing
1490+
("classHierarchyFilename", six.string_types),
1491+
("fileHierarchyFilename", six.string_types),
1492+
("pageHierarchyFilename", six.string_types),
1493+
("unabridgedApiFilename", six.string_types),
1494+
("unabridgedOrphanFilename", six.string_types),
14501495
# Clickable Hierarchies <3
14511496
("createTreeView", bool),
14521497
("minifyTreeView", bool),

exhale/graph.py

Lines changed: 27 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1061,24 +1061,12 @@ def __init__(self):
10611061
self.root_directory = configs.containmentFolder
10621062
self.root_file_name = configs.rootFileName
10631063
self.full_root_file_path = os.path.join(self.root_directory, self.root_file_name)
1064-
# The {page,class,file}_view_hierarchy files are all `.. include::`ed in the
1065-
# root library document. Though we are generating rst, we will want to use a
1066-
# file extension `.rst.include` to bypass the fact that the sphinx builder will
1067-
# process them separately if we leave them as .rst (via the source_suffix
1068-
# configuration of the sphinx app). If users are getting warnings about it
1069-
# then we can actually check for `.include` in app.config.source_suffix, but
1070-
# it is very unlikely this is going to be a problem.
1071-
# See https://github.com/sphinx-doc/sphinx/issues/1668
1072-
self.page_hierarchy_file = os.path.join(self.root_directory, "page_view_hierarchy.rst.include")
1073-
self.class_hierarchy_file = os.path.join(self.root_directory, "class_view_hierarchy.rst.include")
1074-
self.file_hierarchy_file = os.path.join(self.root_directory, "file_view_hierarchy.rst.include")
1075-
self.unabridged_api_file = os.path.join(self.root_directory, "unabridged_api.rst.include")
1076-
# NOTE: do *NOT* do .rst.include for the unabridged orphan kinds, the purpose of
1077-
# that document is to have it be processed by sphinx with its corresponding
1078-
# .. toctree:: calls to kinds that the user has asked to be excluded. Sphinx
1079-
# processing this document directly is desired (it is also marked :orphan: to
1080-
# avoid a warning on the fact that it is *NOT* included in any exhale toctree).
1081-
self.unabridged_orphan_file = os.path.join(self.root_directory, "unabridged_orphan.rst")
1064+
# These documents are all included in the root file document.
1065+
self.page_hierarchy_file = os.path.join(self.root_directory, configs.pageHierarchyFilename)
1066+
self.class_hierarchy_file = os.path.join(self.root_directory, configs.classHierarchyFilename)
1067+
self.file_hierarchy_file = os.path.join(self.root_directory, configs.fileHierarchyFilename)
1068+
self.unabridged_api_file = os.path.join(self.root_directory, configs.unabridgedApiFilename)
1069+
self.unabridged_orphan_file = os.path.join(self.root_directory, configs.unabridgedOrphanFilename)
10821070

10831071
# whether or not we should generate the raw html tree view
10841072
self.use_tree_view = configs.createTreeView
@@ -2287,18 +2275,6 @@ def generateFullAPI(self):
22872275
2. :func:`~exhale.graph.ExhaleRoot.generateNodeDocuments`
22882276
3. :func:`~exhale.graph.ExhaleRoot.generateAPIRootBody`
22892277
'''
2290-
self.generateAPIRootHeader()
2291-
self.generateNodeDocuments()
2292-
self.generateAPIRootBody()
2293-
2294-
def generateAPIRootHeader(self):
2295-
'''
2296-
This method creates the root library api file that will include all of the
2297-
different hierarchy views and full api listing. If ``self.root_directory`` is
2298-
not a current directory, it is created first. Afterward, the root API file is
2299-
created and its title is written, as well as the value of
2300-
``configs.afterTitleDescription``.
2301-
'''
23022278
try:
23032279
# TODO: update to pathlib everywhere...
23042280
root_directory_path = Path(self.root_directory)
@@ -2307,6 +2283,26 @@ def generateAPIRootHeader(self):
23072283
utils.fancyError(
23082284
"Cannot create the directory {0} {1}".format(self.root_directory, e)
23092285
)
2286+
# TODO: API root body does not need to be separate, but it does need to happen
2287+
# after node documents are generated due to bad design (link names and other
2288+
# items get initialized). Or at least that's what I remember.
2289+
skip_root = self.root_file_name == "EXCLUDE"
2290+
if not skip_root:
2291+
self.generateAPIRootHeader()
2292+
self.generateNodeDocuments()
2293+
self.gerrymanderNodeFilenames()
2294+
self.generateViewHierarchies()
2295+
self.generateUnabridgedAPI()
2296+
if not skip_root:
2297+
self.generateAPIRootBody()
2298+
2299+
def generateAPIRootHeader(self):
2300+
'''
2301+
This method creates the root library api file that will include all of the
2302+
different hierarchy views and full api listing. The root API file is created
2303+
and its title is written, as well as the value of
2304+
``configs.afterTitleDescription``.
2305+
'''
23102306
try:
23112307
with codecs.open(self.full_root_file_path, "w", "utf-8") as generated_index:
23122308
# Add the metadata if they requested it
@@ -3613,9 +3609,7 @@ def generateAPIRootBody(self):
36133609
conditionally use a ``toctree`` if you really need it.
36143610
'''
36153611
try:
3616-
self.gerrymanderNodeFilenames()
3617-
self.generateViewHierarchies()
3618-
self.generateUnabridgedAPI()
3612+
36193613
with codecs.open(self.full_root_file_path, "a", "utf-8") as generated_index:
36203614
# Include index page, if present
36213615
for page in self.pages:

0 commit comments

Comments
 (0)