How to render HTML from markdown, which contains tables, using Sphinx - python

I have a *.md files which I am going to put into documentation with help of Sphinx. These files contains tables.
The documentation said to do the following:
pip install recommonmark
add:
source_parsers = {
'.md': 'recommonmark.parser.CommonMarkParser',
}
source_suffix = ['.rst', '.md']
to the conf.py
As a result the tables do not rendered normally. Rest of the md syntax rendered ok.

It looks like recommonmark does not support tables, as noted in issue #3 and PR #68.

Related

Inline Code Link in Sphinx + reStructuredText

In Markdown, one can create an inline code link like so
[`dict.update`](https://docs.python.org/3/library/stdtypes.html#dict.update)
Which renders like dict.update. How can get a similar behaviour in reStructuredText / Sphinx? I tried (1) using a converter but it never results in something similar (2) nesting external link `link <link>`_ and inline code block :code:`dict.update`, but that din't work either.
The right way to do this is using the sphinx.ext.intersphinx extension.
In your conf.py add
extensions = [
'sphinx.ext.intersphinx', # the last entry does not use a comma.
# 'sphinx.ext.autodoc', # just for example so there is more than 1 line.
]
intersphinx_mapping = {'python': ('https://docs.python.org/3', None)}
# If you having an `objects.inv` for local builds
# intersphinx_mapping = {"python": ("https://docs.python.org/3", 'objects.inv'),}
Then in your .rst file or in the docstrings in the .py files write a simple cross-reference. Notice that dict.update is a method thus the right role (:py:meth:) should be used when cross-referencing. The following example
A simple text to :meth:`dict.update`
Would give the below HTML output (the tooltip and link of the cross-reference also included in the screenshot)

Python library for dynamic documents

I want to write a script that generates reports for each team in my unit where each report uses the same template, but where the numbers specific to each team is used for each report. The report should be in a format like .pdf that non-programmers know how to open and read. This is in many ways similar to rmarkdown for R, but the reports I want to generate are based on data from code already written in python.
The solution I am looking for does not need to export directly to pdf. It can export to markdown and then I know how to convert. I do not need any fancier formatting than what markdown provides. It does not need to be markdown, but I know how to do everything else in markdown, if I only find a way to dynamically populate numbers and text in a markdown template from python code.
What I need is something that is similar to the code block below, but on a bigger scale and instead of printing output on screen this would saved to a file (.md or .pdf) that can then be shared with each team.
user = {'name':'John Doe', 'email':'jd#example.com'}
print('Name is {}, and email is {}'.format(user["name"], user["email"]))
So the desired functionality heavily influenced by my previous experience using rmarkdown would look something like the code block below, where the the template is a string or a file read as a string, with placeholders that will be populated from variables (or Dicts or objects) from the python code. Then the output can be saved and shared with the teams.
user = {'name':'John Doe', 'email':'jd#example.com'}
template = 'Name is `user["name"]`, and email is `user["email"]`'
output = render(template, user)
When trying to find a rmarkdown equivalent in python, I have found a lot of pointers to Jupyter Notebook which I am familiar with, and very much like, but it is not what I am looking for, as the point is not to share the code, only a rendered output.
Since this question was up-voted I want to answer my own question, as I found a solution that was perfect for me. In the end I shared these reports in a repo, so I write the reports in markdown and do not convert them to PDF. The reason I still think this is an answer to my original quesiton is that this works similar to creating markdown in Rmarkdown which was the core of my question, and markdown can easily be converted to PDF.
I solved this by using a library for backend generated HTML pages. I happened to use jinja2 but there are many other options.
First you need a template file in markdown. Let say this is template.md:
## Overview
**Name:** {{repo.name}}<br>
**URL:** {{repo.url}}
| Branch name | Days since last edit |
|---|---|
{% for branch in repo.branches %}
|{{branch[0]]}}|{{branch[1]}}|
{% endfor %}
And then you have use this in your python script:
from jinja2 import Template
import codecs
#create an dict will all data that will be populate the template
repo = {}
repo.name = 'training-kit'
repo.url = 'https://github.com/github/training-kit'
repo.branches = [
['master',15],
['dev',2]
]
#render the template
with open('template.md', 'r') as file:
template = Template(file.read(),trim_blocks=True)
rendered_file = template.render(repo=repo)
#output the file
output_file = codecs.open("report.md", "w", "utf-8")
output_file.write(rendered_file)
output_file.close()
If you are OK with your dynamic doc being in markdown you are done and the report is written to report.py. If you want PDF you can use pandoc to convert.
I would strongly recommend to install and use the pyFPDF Library, that enables you to write and export PDF files directly from python. The Library was ported from php and offers the same functionality as it's php-variant.
1.) Clone and install pyFPDF
Git-Bash:
git clone https://github.com/reingart/pyfpdf.git
cd pyfpdf
python setup.py install
2.) After successfull installation, you can use python code similar as if you'd work with fpdf in php like:
from fpdf import FPDF
pdf = FPDF()
pdf.add_page()
pdf.set_xy(0, 0)
pdf.set_font('arial', 'B', 13.0)
pdf.cell(ln=0, h=5.0, align='L', w=0, txt="Hello", border=0)
pdf.output('myTest.pdf', 'F')
For more Information, take a look at:
https://pypi.org/project/fpdf/
To work with pyFPDF clone repo from: https://github.com/reingart/pyfpdf
pyFPDF Documentation:
https://pyfpdf.readthedocs.io/en/latest/Tutorial/index.html

python-docx does not add picture

I'm trying to insert a picture into a Word document using python-docx but running into errors.
The code is simply:
document.add_picture("test.jpg", width = Cm(2.0))
From looking at the python-docx documentation I can see that the following XML should be generated:
<pic:pic xmlns:pic="http://schemas.openxmlformats.org/drawingml/2006/picture">
<pic:nvPicPr>
<pic:cNvPr id="1" name="python-powered.png"/>
<pic:cNvPicPr/>
</pic:nvPicPr>
<pic:blipFill>
<a:blip r:embed="rId7"/>
<a:stretch>
<a:fillRect/>
</a:stretch>
</pic:blipFill>
<pic:spPr>
<a:xfrm>
<a:off x="0" y="0"/>
<a:ext cx="859536" cy="343814"/>
</a:xfrm>
<a:prstGeom prst="rect"/>
</pic:spPr>
</pic:pic>
This does in fact get generated in my document.xml file. (When unzipping the docx file). However looking into the OOXML format I can see that the image should also be saved under the media folder and the relationship should be mapped in word/_rels/document.xml:
<Relationship Id="rId20"
Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/image"
Target="media/image20.png"/>
None of this is happens however, and when I open the Word document I'm met with a "The picture can't be displayed" placeholder.
Can anyone help me understand what is going on?
It looks like the image is not embedded the way it should be and I need to insert it in the media folder and add the mapping for it, however as a well documented feature this should be working as expected.
UPDATE:
Testing it out with an empty docx file that image does get added as expected which leads me to believe it might have something to do with the python-docx-template library. (https://github.com/elapouya/python-docx-template)
It uses python-docx and jinja to allow templating capabilities but runs and works the same way python-docx should. I added the image to a subdoc which then gets inserted into a full document at a given place.
A sample code can be seen below (from https://github.com/elapouya/python-docx-template/blob/master/tests/subdoc.py):
from docxtpl import DocxTemplate
from docx.shared import Inches
tpl=DocxTemplate('test_files/subdoc_tpl.docx')
sd = tpl.new_subdoc()
sd.add_paragraph('A picture :')
sd.add_picture('test_files/python_logo.png', width=Inches(1.25))
context = {
'mysubdoc' : sd,
}
tpl.render(context)
tpl.save('test_files/subdoc.docx')
I'll keep this up in case anyone else manages to make the same mistake as I did :) I managed to debug it in the end.
The problem was in how I used the python-docx-template library. I opened up a DocxTemplate like so:
report_output = DocxTemplate(template_path)
DoThings(value,template_path)
report_output.render(dictionary)
report_output.save(output_path)
But I accidentally opened it up twice. Instead of passing the template to a function, when working with it, I passed a path to it and opened it again when creating subdocs and building them.
def DoThings(data,template_path):
doc = DocxTemplate(template_path)
temp_finding = doc.new_subdoc()
#DO THINGS
Finally after I had the subdocs built, I rendered the first template which seemed to work fine for paragraphs and such but I'm guessing the images were added to the "second" opened template and not to the first one that I was actually rendering. After passing the template to the function it started working as expected!
I came acrossed with this problem and it was solved after the parameter width=(1.0) in method add_picture removed.
when parameter width=(1.0) was added, I could not see the pic in test.docx
so, it MIGHT BE resulted from an unappropriate size was set to the picture,
to add pictures, headings, paragraphs to existing document:
doc = Document(full_path) # open an existing document with existing styles
for row in tableData: # list from the json api ...
print ('row {}'.format(row))
level = row['level']
levelStyle = 'Heading ' + str(level)
title = row['title']
heading = doc.add_heading( title , level)
heading.style = doc.styles[levelStyle]
p = doc.add_paragraph(row['description'])
if row['img_http_path']:
ip = doc.add_paragraph()
r = ip.add_run()
r.add_text(row['img_name'])
r.add_text("\n")
r.add_picture(row['img_http_path'], width = Cm(15.0))
doc.save(full_path)

sphinx - several files in a chapter and clean html-navigation with rtd-theme possible?

I'm using sphinx 1.3.4¹ to write my documentation, make html uses the „read the docs“ theme².
When I include a file chaper1.rst in index.rst with headings from Lv 1 to Lv3 in this document, I see
heading lv 1 in my resulting navigation-sidebar. After clicking this Heading,
It collapses and shows heading lv2 -lv3. Fine, that`s ok.
When I split my chapter1 in several files, I can use chaper1/* in index.rst and in my
resulting html-documentation every file is included. BUT each files heading
- also those with beginning lv2 - shows in the central navigation-sidebar
collapse as separate chapter. No collapsing chapter headings anymore. :-/
How can I use several files for each chapter and achive a clean navigation on the left side?
tia!
Edit
I did a backport of rtd-theme Version 0.1.9 - no change. So it seems to be a sphinx problem. How do I proper include several files to one chapter?
[1] https://packages.debian.org/jessie-backports/python3-sphinx
[2] https://packages.debian.org/jessie/python3-sphinx-rtd-theme
Found the solution. I have to write a heading before .. toctree:: so sphinx knows how to arrange the following files and headings…

MkDocs and MathJax

I'm new to MkDocs and am writing some technical documentation that requires latex. I've successfully built a small website with one of the MkDocs themes, however it won't properly display the latex equations. I followed the instructions at:
http://www.vlfeat.org/matconvnet/developers/
as well as the instructions following the python-markdown-mathjax link from that page. I have also tinkered with adding appropriate lines to my mkdocs.yaml file, similar to:
https://github.com/EdyJ/vehicle-physics-docs/blob/master/mkdocs.yml
However, issuing the command 'mkdocs build' still results in a site that doesn't render the equations. I've also tried adding a -x mathjax flag with the mkdocs build command.
I've scoured the web and have been tinkering for quite a bit of time now. Can anyone shed light on what I need to do to get these two playing together?
This is actually easier than I expected. First I installed the Python-Markdown-Math Extension:
pip install https://github.com/mitya57/python-markdown-math/archive/master.zip
Then I created a new MkDocs project:
mkdocs new test_math
Next I edited the test_math/docs/index.md file to be as follows (sample borrowed from the MathJax documentation):
# MathJax Test Page
When \(a \ne 0\), there are two solutions to \(ax^2 + bx + c = 0\) and they are
$$x = {-b \pm \sqrt{b^2-4ac} \over 2a}.$$
Finally, I edited the test_math/config.yaml file to be as follows:
site_name: Test Math
extra_javascript:
- https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-AMS-MML_HTMLorMML
markdown_extensions:
- mdx_math
I was unsure if this would work, but I ran the test server to see:
mkdocs serve
I then opened my browser and loaded http://127.0.0.1:8000/. The page displayed with the sample equations properly formatted:
Then I remembered that the OP asked for this to work with ReadTheDocs, so I added the following line to the config:
theme: readthedocs
My browser reloaded and the following (properly formatted equations) displayed:
I should note that I'm getting some weird error about fontawesome not loading. With the MkdDocs' theme, the equations disappear after a minute (when the error appears in the browser's console). However, in the ReadTheDocs theme, the equations display properly, even with the error. Either way, I believe this error is related to some other issue on my local machine.
Finally, the Bounty is...
Looking for an answer drawing from credible and/or official sources
I don't normally advertise this, but since you asked, I am the lead developer of Python-Markdown, I work regularly with mitya57 (the creator of Python-Markdown-Math Extension) as he is one of two other developers with commit access to Python-Markdown, and I am a contributor to MkDocs (one of those contributions being support for Python-Markdown Extensions).
You will need to install the extension as indicated in the github README. It sounds as if you have already done that.
Then you need to tell Mkdocs that you are using this Python Markdown extension. You would do this by having a line such as this in your mkdocs.yaml:
markdown_extensions: [mathjax]
The YAML configuration documentation can be found at:
http://www.mkdocs.org/user-guide/configuration/#formatting-options
I am no expert on any of this but the below is what worked for me. One of my needs was to have the $...$ notation work for inline Latex, instead of \(..\) because the $ notation works directly in Jupyter notebooks and you can see what your text will look like without first running mkdocs.
For both $..$ and $$..$$ styles to work, first install pip install --upgrade python-markdown-math. Then do the following:
Put a text file called mathjaxhelper.js in the /docs folder, and it should contain only the following:
MathJax.Hub.Config({
config: ["MMLorHTML.js"],
jax: ["input/TeX", "output/HTML-CSS", "output/NativeMML"],
extensions: ["MathMenu.js", "MathZoom.js"]
});
The project.yml file should contain the following. (replace project.yml with your actual yml file)
markdown_extensions:
- extra
- tables
- mdx_math:
enable_dollar_delimiter: True
- fenced_code
theme: readthedocs
extra_javascript:
- https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.4/MathJax.js?config=TeX-AMS-MML_HTMLorMML
I will admit I am no expert and really only cared about what worked. It took me several hours to figure out what combination of things in the .yml and the mathjaxhelper.js file will get both $ and $$ to work. Hope this helps someone else.
It looks like be that this extension is not required:
docs/mathjaxhelper.js
MathJax.Hub.Config({
"tex2jax": { inlineMath: [ [ '$', '$' ] ] }
});
MathJax.Hub.Config({
config: ["MMLorHTML.js"],
jax: ["input/TeX", "output/HTML-CSS", "output/NativeMML"],
extensions: ["MathMenu.js", "MathZoom.js"]
});
mkdocs.yml
markdown_extensions:
- extra
- tables
- fenced_code
extra_javascript:
- https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS_HTML
- mathjaxhelper.js
Seems to do the trick.
Here is a way to get LaTeX in MkDocs with the extension arithmatex.
I'm answering again because I want to document a solution that doesn't link to third party sites like Cloudflare and Google.
I'm going the way with the theme named mkdocs-material but you can replace theme: ...school with theme: readthedocs.
First install MkDocs and create a project:
https://www.mkdocs.org/#installation.
Then install mkdocs-material and MathJax as follows.
Say the project is called my-project.
Use downloads and not pip because you want to change the CDN to Cloudflare and the link to google.
cd my-project
git clone https://github.com/squidfunk/mkdocs-material.git
git clone https://github.com/mathjax/MathJax.git MathJax
Edit mkdocs.yml like described under "Usage", for example:
site_name: My Project
pages:
- Home: index.md
theme:
name: null
custom_dir: 'mkdocs-material/material'
palette:
primary: amber
accent: pink
language: de
feature:
tabs: true
font: false
logo:
icon: school
markdown_extensions:
- pymdownx.arithmatex
extra_javascript:
- ../MathJax/MathJax.js?config=TeX-AMS-MML_HTMLorMML
You can insert some TeX in index.md, build the site (mkdocs build) and open the index.html to check that MathJax works.
Because it doesn't work with mkdocs serve I uploaded the MathJax folder and linking to it instead of the link to the local path.
extra_javascript:
- https://mysite/MathJax/MathJax.js?config=TeX-AMS-MML_HTMLorMML
To activate TeX inline with $...$ you have to create an extra JS-file
cd docs
mkdir assets
touch extra.js
Insert the following text into extra.js:
window.MathJax = {
tex2jax: {
inlineMath: [ ["$","$"], ["\\(","\\)"] ],
displayMath: [ ["\\[","\\]"] ]
},
TeX: {
TagSide: "right",
TagIndent: ".8em",
MultLineWidth: "85%",
equationNumbers: {
autoNumber: "AMS",
},
unicode: {
fonts: "STIXGeneral,'Arial Unicode MS'"
}
},
displayAlign: "center",
showProcessingMessages: false,
messageStyle: "none"
};
and link to it in mkdocs.yml. Finaly the extra_javascript section can like this:
extra_javascript:
- https://mysite/MathJax/MathJax.js?config=TeX-AMS-MML_HTMLorMML
- assets/extra.js
Because we don't want to use CDN you can edit mkdocs-material/material/base.html and delete/uncomment the line with <link href="https://fonts.gstatic.com" rel="preconnect" crossorigin>.
Font-awesome and material-icons are already on board within mkdocs-material.

Categories

Resources