0

Does sphinx allow nested includes ?

I have a hierarchy that looks like that:

~> root
   |_conf.py
   |_index.rst
   |_level1.rst
   |_level2
     |_level2.rst
     |_level3
       |_level3.rst

Files look this way:

~> more conf.py
import os
import sys
sys.path.insert(0, os.path.abspath('.'))
sys.path.insert(0, os.path.abspath('level1'))
sys.path.insert(0, os.path.abspath('level1/level2'))
sys.path.insert(0, os.path.abspath('level1/level2/level3'))
project = 'PM'
copyright = '2020, PM'
author = 'PM'
extensions = [
]
templates_path = ['_templates']
exclude_patterns = ['_build']

Note: all sublevels are added in sys.path.

The index just adds level1.

~> more index.rst
Welcome to PM's documentation!
==============================

.. toctree::
   :maxdepth: 6
   :caption: Contents:

   level1

And the rst files look like :

~> more level1.rst
level1
######

this is level1

.. include:: level2/level2.rst

~> more level2/level2.rst
level2
======

this is level2

.. include:: level3/level3.rst

~> more .\level2\level3\level3.rst
level3
------

this is level3

The compilation emits this warning :

~> make latexpdf
...
reading sources... [100%] level2/level3/level3
level2/level2.rst:6: WARNING: Problems with "include" directive path:
InputError: [Errno 2] No such file or directory: 'level3/level3.rst'.
...

Table of content is OK down to level 2 :

1 level1
  1.1 level2 

But level 3 is missing:

     1.1.1 level3

Level 3 is ignored.

Is there a way to get this to work ? This way or another ? Or any workaround ? For instance is there a way to say "pwd is now level2" in level2.rst ?

UPDATE

Real life application looks more like:

~> root
   |_conf.py
   |_index.rst
   |_level1.rst
   |_level2
   | |_conf.py
   | |_index.rst
   | |_level2.rst
   | |_level3
   |   |_conf.py
   |   |_index.rst
   |   |_level3.rst
   |_level4
     |_conf.py
     |_index.rst
     |_level4.rst
     |_level3
       |_conf.py
       |_index.rst
       |_level3.rst

level3 is actually a git-submodule that is cloned into both level2 and level4 but on different branches where the doc may not be the same.

Ideally, level3 should generate his own doc. level2 and level4 should generate his own doc including the one of level3. level1 should generate his own doc including the ones of both level2 (which embed doc of level3) and level4 (which embed doc of level3).

This is why all paths are relatives in my first simplified attempt.

I try to understand if this (ideal case) could be possible.

fghoussen
  • 393
  • 3
  • 16
  • The problem is in this line `.. include:: level3/level3.rst` should be `.. include:: level2/level3/level3.rst` – bad_coder Nov 20 '20 at 21:01
  • 2
    To add to @bad_coder's comment, I prefer to use root-relative paths where the root is the location of your `conf.py`. – Steve Piercy Nov 21 '20 at 03:26
  • Note that `sys.path` is a list of strings that specify search paths for Python modules. It has nothing to do with the structure of nested `include` directives. – mzjn Nov 21 '20 at 08:55
  • @bad_coder: I understand ``.. include:: level2/level3/level3.rst`` works.In real life, there is a ``level4`` at same level than ``level2``. ``level3`` is actually a ``git-submodule`` that is cloned into both ``level2`` and ``level4`` but on **different** branches where the doc may **not** be the same. I look ideally for a solution with only relative path if possible (not involving "upper information") – fghoussen Nov 21 '20 at 10:22
  • @StevePiercy: in real life, ideally, each ``levelX`` is an independant projet which has his own ``conf.py`` and ``index.rst``. I try to understand if I can reuse the doc of one (lower) level into the doc of another (upper) level. This is why all path are relatives in my attempt. ``level3`` should generate his own doc. ``level2`` should generate his own doc including the one of ``level3``. ``level1`` should generate his own doc including the ones of both ``level2`` and ``level3``. I try to understand if this is possible or not – fghoussen Nov 21 '20 at 10:31
  • Documentation generated from Sphinx uses a single `conf.py` from where it is invoked. See another recent question and [my comment](https://stackoverflow.com/questions/64786355/sphinx-include-documents-from-a-package#comment114597610_64786355) about documenting nested projects. – Steve Piercy Nov 21 '20 at 11:58
  • @StevePiercy: thanks for the tip ! Didn't know about ``intersphinx`` : I will give it a try if I find an example (still looking for it). From what I have read, ``intersphinx`` allow from a given doc to reference something from another doc : this is not really what I had in mind at first (i.e. embedding doc into another one), but, it's worth looking at it – fghoussen Nov 21 '20 at 15:10
  • Yup, it should work. "Each target is the base URI of a foreign Sphinx documentation set and can be a *local path* or an HTTP URI." Most people do remote HTTP URIs, but I reckon you can do the same locally. Build each subproject, then in the parent project use intersphinx. – Steve Piercy Nov 22 '20 at 03:31
  • @StevePiercy : tried intersphinx but without success https://stackoverflow.com/questions/65691569/is-it-possible-to-create-nested-pdf-documentation-with-sphinxintersphinx – fghoussen Jan 12 '21 at 20:28
  • @FGH the local path must be to the build directory `../projectA/_build `, not the source. – Steve Piercy Jan 13 '21 at 04:40
  • @StevePiercy: does not work either, check out updated answer – fghoussen Jan 13 '21 at 06:39
  • Where is your build directory for projectA relative to projectB? – Steve Piercy Jan 13 '21 at 07:05
  • In `conf.py` of projectB, I set `intersphinx_mapping = {'projA': (os.path.join('..', 'projectA', '_build'), None)}` which is the relative path that points at projectA. Main problem seems to be : there is no `objects.inv` file (in projectA) – fghoussen Jan 13 '21 at 07:10

0 Answers0