readthedocs / recommonmark

A markdown parser for docutils
https://recommonmark.readthedocs.io/
MIT License
340 stars 252 forks source link

auto_toc_tree only works on master doc #156

Closed idnsunset closed 2 years ago

idnsunset commented 5 years ago

Let's suppose the source directory structure as shown below:

source
  |_______ index.md
  |
  |_______ subdir1
                |_______ index.md
                |_______ doc1.md

The master index.md contains:

* [Subdir1](subdir1/index.md)
* [Subdir2](subdir2/index.md)

and subdir1/index.md contains:

* [Doc1](doc1.md)

I expected that a toctree entry linking to doc1.html could be generated in subdir1/index.html, but it does not. auto_toc_tree only works on the master index.md.

By the way, if the title is not specified in [], toctree should use the title of the included document specified in (), which could make it look more similar in behaviour to the RST toctree directive.

danyeaw commented 5 years ago

I also came across this issue. How can I help resolve this?

danyeaw commented 5 years ago

I am still interested in helping resolve this, could someone please point me in the right direction?

vlee-harmonicinc commented 4 years ago

I have a workaround in conf.py.

class AutoStructifyPatch(AutoStructify):
    def parse_ref(self, ref):
        """
        Patch AutoStructify for relative path
        """
        title = None
        if len(ref.children) == 0:
            title = ref['name'] if 'name' in ref else None
        elif isinstance(ref.children[0], nodes.Text):
            title = ref.children[0].astext()
        uri = ref['refuri']
        if uri.find('://') != -1:
            return (title, uri, None)
        anchor = None
        arr = uri.split('#')
        if len(arr) == 2:
            anchor = arr[1]
        if len(arr) > 2 or len(arr[0]) == 0:
            return (title, uri, None)
        uri = arr[0]

        abspath = os.path.abspath(os.path.join(self.file_dir, uri))
        # ** Patch
        if uri[0] != '/': # input uri is relative path
            abspath = '/' + os.path.relpath(abspath, self.root_dir)
        relpath = os.path.relpath(abspath, self.root_dir)

        # use url resolver
        if self.url_resolver:
            uri = self.url_resolver(relpath)
        if anchor:
            uri += '#' + anchor
        return (title, uri, None)

def setup(app):
    app.add_config_value('recommonmark_config', {
             ...
            }, True)
    app.add_transform(AutoStructifyPatch) # replace AutoStructify to patch parse_ref

Probably not a good approach. I not very sure why so many ../../../../../../ in the output of parse_ref. But it works for me. Beside, I don't need to handle installation of recommonmark module when auto-hosting on readthedocs.