pythonmarkdownpython-sphinxrestructuredtext

Include my markdown README into Sphinx


I would like to include my project's README.md into my Sphinx documentation like in Can sphinx link to documents that are not located in directories below the root document? - which is that in the resulting Sphinx html documentation I click on a link in the table of contents on the welcome page and get to the README.md.

For that a document readme_link.rst is created which contains the lines

Readme File
-----------

.. include:: ../../README.md

and I add the line

README <readme_link>

into the toctree of index.rst. Going with that, my README.md is not parsed as Markdown, but just printed onto the page as-is-text.

I thought an alternative idea might be to have a markdown file readme_link.md instead, but there is no way to include files with markdown.

How can I have my README.md parsed as markdown?

(Of course I don't want to rewrite it as .rst.)

Why m2r is not working

I tried to follow Render output from markdown file inside .rst file, but this is not working. My README.md has some headings like

# First heading

some text

## Second heading 1

some text

## Second heading 2

some text

and I get the error WARNING: ../README.md:48: (SEVERE/4) Title level inconsistent:. I understand from What does "Title level inconsistent" mean? that I need to use other symbols - but reading into them I realized that the answer refers to rst symbols. That would mean that my markdown readme actually wasn't transformed into rst.

PS: Someone else who tried something like that is https://muffinresearch.co.uk/selectively-including-parts-readme-rst-in-your-docs/


Solution

  • You need to edit your readme_link.rst as follows:

    Readme File
    ===========
    
    .. mdinclude:: ../../README.md
    

    Note that the section header is designated with = characters rather than - characters.

    There are two factors that contribute to that.

    How include works

    Standard include (not mdinclude) actually reads the content of the source file and simply copies the raw text in place of the directive. M2R's mdinclude first converts the source Markdown text to rst, and then, like include, copies that test in place of the directive.

    Therefore, by the time the rst document is parsed, you have one complete rst document from both the parent and included files. That one complete document needs to be a valid rst document, which takes us to the second point...

    Header levels must be consistent.

    As a reminder, the reStructuredText Spec explains:

    Rather than imposing a fixed number and order of section title adornment styles, the order enforced will be the order as encountered. The first style encountered will be an outermost title (like HTML H1), the second style will be a subtitle, the third will be a subsubtitle, and so on.

    ...

    All section title styles need not be used, nor need any specific section title style be used. However, a document must be consistent in its use of section titles: once a hierarchy of title styles is established, sections must use that hierarchy.

    Therefore, the header levels in the included child must be consistent with the header levels in the parent. As M2R generates a rst document, you (as the end user) don't get to specificity which character is used to define each section level. Therefore, to maintain consistency, you need to use the scheme defined by M2R:

    • Rst heading marks are currently hard-coded and unchangeable.
      • H1: =, H2: -, H3: ^, H4: ~, H5: ", H6: #

    As you can see, level 1 headers use the = character and level 2 headers use the - character. Therefore, the same scheme needs to be used in the parent readme_link.rst file (you were using the reverse).

    An alternate solution

    The reStructuredText spec also states:

    Underline-only adornment styles are distinct from overline-and-underline styles that use the same character.

    Therefore, you could use overline-and-underline styles in your parent document and it wouldn't matter which characters you used for which level as M2R only appears to use underline-only styles. So this would have worked as well:

    -----------
    Readme File
    -----------
    
    .. mdinclude:: ../../README.md
    

    This has the added benefit (or negative -- depending on your point of view) that all headers in the included child document will now be one level lower that they would on their own. Therefore, the child is more semantically "nested" in the parent (more than one h1 in a single HTML document is often considered to not be semantic although it is technically "valid"). Of course, this may or may not be what you want, which is why it is labeled an "alternate solution".