Sphinx/RST: Include another RST file without adding it to the TOC? - python-sphinx

I'm improving some technical docs (Sphinx) and would like to include the contents of an RST file in multiple places; however, in doing so, that RST file is being added to the TOC multiple times. How can I include the file where I want but only reference the section in the TOC once?
Here's what the index.rst file looks like:
Documentation
=================
.. toctree::
:maxdepth: 4
../path/to/releasenotes.rst
../path/to/general_api_usage.rst
main_content.rst
Next, here's main_content.rst:
============
Main Content
============
These docs reference:
- :ref:`section-1`.
- :ref:`section-2`.
- :ref:`section-3`.
- :ref:`section-4`.
.. include:: section1.rst
.. include:: section2.rst
.. include:: section3.rst
.. include:: section4.rst
"Section 4" is a reference table; I'd like to include it in "Section 2", for example, but also keep it at the bottom of the docs like an appendix.
Here's what section2.rst looks like:
.. _section-2:
This is Section 2
********************
.. include: section4.rst
Some other Section 2 content.
And finally, what section4.rst might look like:
.. _section-4:
This is Section 4
********************
+------------------+-------------------------+
| Heading | Heading 2 |
+==================+=========================+
| This is what I | want to reference |
+------------------+-------------------------+
| in other rst | files. |
+------------------+-------------------------+
When I do this, my table of contents includes "Section 4" twice. Any insights? Thanks!

Thanks to a suggestion from #sinoroc, I've come up with a solution:
I removed the following from section4.rst, and kept only the table:
.. _section-4:
This is Section 4
********************
I added it to the top of a new file, appendix.rst, and added a reference to section4.rst:
.. _section-4:
This is Section 4
********************
.. include:: section4.rst
I then modified my main_content.rst to refer to appendix.rst instead of section4.rst.
My main learning point: The TOC reflects the headings in the referenced files.

Related

restructuredtext include partial rst directives from other files (i.e. templates)

I'm looking for a way to include partial rst directives from another file.
I have some restructured text files that have repeating table definitions, and I would like to make this a reusable template to avoid redefining the same table again and again.
multiple files list tables that all start like to following (i.e. common settings and header) but the actual data rows afterwards differ.
.. list-table::
:align: left
:header-rows: 1
:width: 100%
:widths: 25 25 25 25
* - ColumnHeader1
- ColumnHeader2
- ColumnHeader3
- ColumnHeader4
The include directive does not seem to work for this, as it will parse the line-table and then include the result, I cannot add additional rows to that line-table afterwards.
Is there any way that I could achieve this?
EDIT:
Forgot to mention that I use restructuredtext as part of sphinx. It seems it is quite easy to extend sphinx: https://www.sphinx-doc.org/en/master/development/tutorials/helloworld.html
EDIT2:
Moved my solution to an answer to this question
I found a way to implement this as a sphinx extension (following this tutorial https://www.sphinx-doc.org/en/master/development/tutorials/helloworld.html)
from docutils.parsers.rst.directives.tables import ListTable
from docutils.statemachine import ViewList
class MyTable(ListTable):
def run(self):
header_rows = ViewList([
'* - ColumnHeader1',
' - ColumnHeader2',
' - ColumnHeader3',
' - ColumnHeader4',
])
self.content = header_rows + self.content
self.options['header-rows'] = 1
self.options['width'] = '100%'
self.options['widths'] = '25 25 25 25'
self.options['align'] = 'left'
return super().run()
def setup(app):
app.add_directive('my-table', MyTable)
return {
'version': '0.1',
'parallel_read_safe': True,
'parallel_write_safe': True,
}
This let's me define tables like this now:
.. my-table::
* - Column 1
- Column 2
- Column 3
- Column 4

sphinx : nested include across nested directories

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.

Link between documents with anchor

I have two rst document, like:
doc1.rst
doc2.rst
doc1.rst
Doc 1 content
*************
Foo bar
=======
baz !
doc2.rst
Doc 2 content
*************
You can see "foo bar" `here <doc1.html#foo-bar>`.
To have a link in doc2 to doc1#foo-bar i can hardcode it. But how do it without hardcoding? Can I do that with sphinx code ?
Define a label for the section in doc1.rst that you want to link to. Then use the :ref: role to create a cross-reference to that section.
doc1.rst:
Doc 1 content
*************
.. _foobar:
Foo bar
=======
baz !
doc2.rst:
Doc 2 content
*************
You can see "foo bar" :ref:`here <foobar>`.

Makefile: $subst in dependency list

I have a Makefile which looks roughly like this:
FIGURES = A1_B1_C1.eps A2_B2_C2.eps A3_B3_C3.eps
NUMBERS = 1 2 3
all : $(FIGURES)
%.eps : $(foreach num, $(NUMBERS), $(subst B, $(num), %).out)
# my_program($+, $#);
%.out :
The point is that the file names of my figures contain certain information (A, B, C) and that each figure is created by my_program from several (in the example 3) files.
While the filename of each figure has the format Ax_Bx_Cx.eps, the names of the data files to create the figures from look like this:
Ax_1x_Cx.out
Ax_2x_Cx.out
Ax_3x_Cx.out
So for each figure, I need a dynamically created dependency list with several file names. In other words, my desired output for the example above would be:
# my_program(A1_11_C1.out A1_21_C1.out A1_31_C1.out, A1_B1_C1.eps);
# my_program(A2_12_C2.out A2_22_C2.out A2_32_C2.out, A2_B2_C2.eps);
# my_program(A3_13_C3.out A3_23_C3.out A3_33_C3.out, A3_B2_C3.eps);
Unfortunately, the subst command seems to be ignored, for the output looks like this:
# my_program(A1_B1_C1.out A1_B1_C1.out A1_B1_C1.out, A1_B1_C1.eps);
# my_program(A2_B2_C2.out A2_B2_C2.out A2_B2_C2.out, A2_B2_C2.eps);
# my_program(A3_B3_C3.out A3_B3_C3.out A3_B3_C3.out, A3_B3_C3.eps);
I had a look at this possible duplicate but figured that the answer cannot help me, since I am using % and not $#, which should be ok in the prerequisites.
Clearly I am getting something wrong here. Any help is greatly appreciated.
To do fancy prerequisite manipulations you need at least make-3.82 which supports Secondary Expansion feature:
FIGURES = A1_B1_C1.eps A2_B2_C2.eps A3_B3_C3.eps
NUMBERS = 1 2 3
all : $(FIGURES)
.SECONDEXPANSION:
$(FIGURES) : %.eps : $$(foreach num,$$(NUMBERS),$$(subst B,$$(num),$$*).out)
#echo "my_program($+, $#)"
%.out :
touch $#
Output:
$ make
touch A1_11_C1.out
touch A1_21_C1.out
touch A1_31_C1.out
my_program(A1_11_C1.out A1_21_C1.out A1_31_C1.out, A1_B1_C1.eps)
touch A2_12_C2.out
touch A2_22_C2.out
touch A2_32_C2.out
my_program(A2_12_C2.out A2_22_C2.out A2_32_C2.out, A2_B2_C2.eps)
touch A3_13_C3.out
touch A3_23_C3.out
touch A3_33_C3.out
my_program(A3_13_C3.out A3_23_C3.out A3_33_C3.out, A3_B3_C3.eps)

Include apsrtable (or stargazer) output in an Rmd file

I tried to include the summary of an lm object in an Rmd file, using code like the following but it didn't work. Could you help me do that?
```{r summary_lm, results='asis', echo=FALSE, comment=NA}
library(apsrtable)
my_model <- lm(y ~ x, data = data.frame(y = rnorm(10), x = 1:10))
res <- apsrtable(my_model) # my_model is a linear regression model (lm)
cat("$$latex \n",res,"\n$$ \n")
```
The $$ syntax only applies to math expressions, and you were trying to put a table in it, which will not work. The apsrtable, as far as I understand, is for LaTeX only, but LaTeX and Markdown are very different -- there is little hope you can redo LaTeX entirely with Markdown. I think people invented the $$ syntax for Markdown due to the fact that it is well supported by MathJax, and also note there are many variants/flavors based on the original Markdown.
At the moment you may consider:
use the xtable or ascii or R2HTML package to generate HTML tables
request the package author of apsrtable to support HTML tables
What about including my_model in Markdown format with `panderĖ™:
> library(pander)
> pander(my_model)
--------------------------------------------------------------
Estimate Std. Error t value Pr(>|t|)
----------------- ---------- ------------ --------- ----------
**x** 0.1174 0.1573 0.7465 0.4767
**(Intercept)** -0.2889 0.9759 -0.296 0.7748
--------------------------------------------------------------
Table: Fitting linear model: y ~ x
Or in PHP MarkdownExtra/rmarkdown format:
> panderOptions('table.style', 'rmarkdown')
> pander(my_model)
| | Estimate | Std. Error | t value | Pr(>|t|) |
|:-----------------:|:----------:|:------------:|:---------:|:----------:|
| **x** | 0.1174 | 0.1573 | 0.7465 | 0.4767 |
| **(Intercept)** | -0.2889 | 0.9759 | -0.296 | 0.7748 |
Table: Fitting linear model: y ~ x
Cross-posting my answer to Table of multiple lm() models using apsrtable in Rmarkdown:
It can be done in a pdf_document with apsrtable and also stargazer, which additionally supports HTML.
---
title: "stargazer"
author: "hplieninger"
date: "3 August 2018"
output: pdf_document
header-includes:
- \usepackage{dcolumn}
---
```{r}
m1 <- lm(Fertility ~ Education , data = swiss)
m2 <- lm(Fertility ~ Education + Agriculture, data = swiss)
m3 <- lm(Fertility ~ . , data = swiss)
```
```{r, results='asis'}
apsrtable::apsrtable(m1, m2, m3, Sweave = TRUE)
```
```{r, results='asis'}
# If output: pdf_document
stargazer::stargazer(m1, m2, m3)
# If output: html_document
# stargazer::stargazer(m1, m2, m3, type = "html")
```

Resources