Sphinx, reStructuredText show/hide code snippets - code-snippets

I've been documenting a software package using Sphinx and reStructuredText.
Within my documents, there are some long code snippets. I want to be able to have them hidden as default, with a little "Show/Hide" button that would expand them (Example).
Is there a standard way to do that?

You don't need a custom theme. Use the built-in directive container that allows you to add custom css-classes to blocks and override the existsting theme to add some javascript to add the show/hide-functionality.
This is _templates/page.html:
{% extends "!page.html" %}
{% block footer %}
<script type="text/javascript">
$(document).ready(function() {
$(".toggle > *").hide();
$(".toggle .header").show();
$(".toggle .header").click(function() {
$(this).parent().children().not(".header").toggle(400);
$(this).parent().children(".header").toggleClass("open");
})
});
</script>
{% endblock %}
This is _static/custom.css:
.toggle .header {
display: block;
clear: both;
}
.toggle .header:after {
content: " ▶";
}
.toggle .header.open:after {
content: " ▼";
}
This is added to conf.py:
def setup(app):
app.add_css_file('custom.css')
Now you can show/hide a block of code.
.. container:: toggle
.. container:: header
**Show/Hide Code**
.. code-block:: xml
:linenos:
from plone import api
...
I use something very similar for exercises here: https://training.plone.org/5/mastering-plone/about_mastering.html#exercises

You can use the built-in HTML collapsible details tag by wrapping the code in two raw HTML directives
.. raw:: html
<details>
<summary><a>big code</a></summary>
.. code-block:: python
lots_of_code = "this text block"
.. raw:: html
</details>
Produces:
<details>
<summary><a>big code</a></summary>
<pre>lots_of_code = "this text block"</pre>
</details>

I think the easiest way to do this would be to create a custom Sphinx theme in which you tell certain html elements to have this functionality. A little JQuery would go a long way here.
If, however you want to be able to specify this in your reStructuredText markup, you would need to either
get such a thing included in Sphinx itself or
implement it in a Sphinx/docutils extension...and then create a Sphinx theme which knew about this functionality.
This would be a bit more work, but would give you more flexibility.

There is a very simplistic extension providing exactly that feature: https://github.com/scopatz/hiddencode
It works rather well for me.

The cloud sphinx theme has custom directive html-toggle that provides toggleable sections. To quote from their web page:
You can mark sections with .. rst-class:: html-toggle, which will make the section default to being collapsed under html, with a “show section” toggle link to the right of the title.
Here is a link to their test demonstration page.

sphinx-togglebutton
Looks like a new sphinx extension has been made to do just this since this question has been answered.
Run: pip install sphinx-togglebutton
Add to conf.py
extensions = [
...
'sphinx_togglebutton'
...
]
In rst source file:
.. admonition:: Show/Hide
:class: dropdown
hidden message

since none of the above methods seem to work for me, here's how I solved it in the end:
create a file substitutions.rst in your source-directory with the following content:
.. |toggleStart| raw:: html
<details>
<summary><a> the title of the collapse-block </a></summary>
.. |toggleEnd| raw:: html
</details>
<br/>
add the following line at the beginning of every file you want to use add collapsible blocks
..include:: substitutions.rst
now, to make a part of the code collapsible simply use:
|toggleStart|
the text you want to collapse
..code-block:: python
x=1
|toggleEnd|

Another option is the dropdown directive in the sphinx-design extension. From the docs:
Install sphinx-design
pip install sphinx-design
Add the extension to conf.py in the extensions list
extensions = ["sphinx_design"]
Use the dropdown directive in your rst file:
.. dropdown::
Dropdown content

Related

Carrying style IDs/names from HTML to .docx?

Is it possible to somehow tell pandoc to carry the names of styles from original HTML to .docx?
I understand that in order to tune the actual styles, I should be using reference.docx file generated by pandoc. However, reference.docx is limited to what styles it has to: headings, body text, block text, etc.
I'd like to:
specify "myStyle" style in the input HTML (via a "class" attribute, via any other HTML attribute or even via a filter code written in Lua),
<html>
<body>
<p>Hello</p>
<p class="myStyle">World!</p>
</body>
</html>
add a custom "myStyle" to reference.docx using Word,
run a html->docx conversion an expect pandoc generate a paragraph element with "myStyle" (instead of BodyText, which I believe it sets by default), so the end result looks like this (contents of word/document.xml inside the resulting output.docx was cut for brevity):
<w:p>
<w:pPr>
<w:pStyle w:val="BodyText" />
</w:pPr>
<w:r>
<w:txml:space="preserve">Hello</w:t>
</w:r>
</w:p>
<w:p>
<w:pPr>
<w:pStyle w:val="myStyle" />
</w:pPr>
<w:r>
<w:txml:space="preserve">World!</w:t>
</w:r>
</w:p>
There's some evidence styleId can be passed around, but I don't really understand it and am unable to find any documentation about it.
Doc on filtering in Lua states you can access attrs when manipulating a pandoc.div, but it says nothing about whether any of the attrs will be interpreted by pandoc in any meaningful way.
Finally, found what I needed – Custom styles. It's limited, but better than what I arrived earlier, and of course much better than nothing at all :)
I'll leave a step-by-step guide here in case anyone stumbles upon a similar question.
First, generate a reference.docx file like this:
pandoc --print-default-data-file reference.docx > styles.docx
Then open the file in MS Word (I was using a macOS version) you'll see this:
Click the "New style..." button on the right, and create a style to your liking. In my case I made change the style of text to be bold, in blue color:
Since I am converting from HTML to DOCX, here's my input.html:
<html>
<body>
<div>Page 1</div>
<div custom-style="eugene-is-testing">Page 2</div>
<div>Page 3</div>
</body>
</html>
Run:
pandoc --standalone --reference-doc styles.docx --output output.docx input.html
Finally, enjoy the result:

Trouble rendering some latex syntax in MathJax with Jekyll on github pages

I found that some of latex syntaxes are not rendered with MathJax with Jekyll in my git page.
For example, in this post
this line:
$z = \overbrace{\underbrace{x}\text{real} +\underbrace{iy}\text{imaginary}}^\text{complex number}$
should look like this
Some other latex syntax works well, like this
What should I add to solve this problem? I guess MathJax is not loading the required library (e.g. \usepackage{amsmath} in the above case).
The code of the page is here.
The following code shows the my configuration of matjax.
<script type="text/x-mathjax-config"> MathJax.Hub.Config({ TeX: { equationNumbers: { autoNumber: "all" } } }); </script>
<script type="text/x-mathjax-config">
MathJax.Hub.Config({
tex2jax: {
inlineMath: [ ['$','$'], ["\\(","\\)"] ],
processEscapes: true
}
});
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML" type="text/javascript"></script>
Note that in Jekyll's Markdown syntax, underlines are used to indicate italic text, so Jekyll is inserting <em> tags around \text{real} +\underbrace{iy} where the underscores were (notice that the underscores are missing in the output and that the text is in italics). MathJax can't process math that contains HTML tags, so this math equation is skipped.
You need to make sure that Markdown doesn't interfere with your TeX notation. That can be done in several ways. You could use \_ instead of _ in order to prevent the underscores from being interpreted as italics. Alternatively, you could use <span>...</span> around inline math and <div>...</div> around display math, as suggested here.
Just a hunch but looking at the code posted within your question, I think it might be better to keep all the MathJax related stuff within the <script> tags. I write this because I've yet to find the need to wrap anything in a <span>.
Here's what my _includes/mathjax.html file looks like by piecing together two blocks from the docs...
<script type="text/javascript" async
src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js?config=TeX-AMS-MML_HTMLorMML">
MathJax.Hub.Config({
tex2jax: {
inlineMath: [['$','$'], ['\\(','\\)']],
processEscapes: true
}
});
</script>
... and this is how I include it...
---
layout: post
title: Some of Thing
---
{%- include mathjax.html -%}
Notes about $ \sum_{Thing} $
Note how the configs are within the same <script> tag as what is doing the sourcing (src="<url-or-path>"),
For completeness a post source to go with rendered post, which uses the $$ way of doing multi-line formatting within the first thirty lines of the source, and then the $ in line way of doing things just after the first code formatted block (within the notes) of the rendered version.
And (for bonus points I suppose), what I think the corrected code might look like from the question.
<script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML" type="text/javascript">
MathJax.Hub.Config({ TeX: { equationNumbers: { autoNumber: "all" } } });
MathJax.Hub.Config({
tex2jax: {
inlineMath: [ ['$','$'], ["\\(","\\)"] ],
processEscapes: true
}
});
</script>
One other note worthy thing that I found my tests is that the \( ... \sum_{Thing} ... \), in-line syntax did not trigger whatever pre-parser Jekyll's using to add html tags to such things; in other-words I had to use the $ ... \sum_{Thing} ... $ syntax even before adding any configs for MathJax's srcing.
For those that got this far but wanted to cut-down on the CDN usage for some reason, ya may instead be interested in the other answer that I've posted on getting MathJax and Jekyll to play-nice.
And for those that want some Liquid to JavaScript configuration translation liquid-utilities/includes-mathjax is now available; allows for configuring MathJax via _config.yml and individual post/page FrontMatter.

Elements in KSS Styleguide won't get styled

I use kss-node and trying out the simplest project. It just uses the example from the Quickstart guide.
The css is in source/style.css
// Hard rules
//
// Markup: <hr>
//
// Style guide: hard-rule
hr {
border-top: 5px solid #999;
}
I then run
npm-exec kss-node --source source --destination styleguide --css ../source/style.css
The first problem was that the --css option needs the relative path from where the styleguide later is.
But the hr element still looks the same and not 5px thick.
The file is included in the html but Dev Tools says "0 rules" are applied
Could it have something to do with the "//" comments you are using in the css file? Try using a preprocessor and a styles.scss file as the source and then include the styles.css file that sass generates which won't have invalid "//" comments in them.
This seems to working
`
/*
Hard rules
Markup:
Style guide: hard-rule
*/
`
https://github.com/rcaracaus/kss-test
I reread the the documentation to kss-node. The recommended way seems to create a kss template and add the stylesheet in there.
I took the repo of Robert and executed
npm-exec kss-node --init my-template
Then I added following line to my-template/index.html
<link rel="stylesheet" href="../source/styles.css">
Apparently the styles.css file won't be copied to the styleguide directory.
Although this doesn't answer my original question. I feel like it should work without a custom template.
But this works for me.

TinyMCE do not auto convert a URL into a link on Paste

When I paste a URL into a TinyMCE editor it converts the text into a link.
So http://vimeo.com/18150336 would be come http://vimeo.com/18150336. I would like to keep the plain text. Is their a way to configure TinyMCE to keep the link as plain text.
I do not want to strip out tags as adding a hyperlinks should be an option on the toolbar. It should just not happen by default.
You can use the paste plugin and the setting paste_preprocessing in order to keep the plain text. You might need to check inside the function specified using paste_preprocessing if you got a link or not.
It's been 5 years, So I'm probably using a newer version of TinyMCE, anyway this solution worked for me, Just add this option:
paste_preprocess: function(plugin, args) {
args.content += ' ';
}
So when you initialize the tinymce, it should be something like this:
tinymce.init({
selector: "textarea", // change this value according to your HTML
plugins: "paste",
paste_preprocess: function(plugin, args) {
args.content += ' ';
}
});
This is the page of documentation for TinyMCE V4
It is the TinyMCE plugin autolink which is responsible for automatically creating links on paste. (And write).
https://www.tiny.cloud/docs/plugins/opensource/autolink/

Input code in TinyMCE

I'm using TinyMCE on my blog and it seems to be removing the code I'm trying to paste.
I want to add this:
<Files somefile.png>
DefaultType application/x-httpd-php
</Files>
(it's a .htaccess directive)
This gets saved ok (as < and > in the html), but when I reopen my form for editing, it gets transformed as :
DefaultType application/x-httpd-php
Edit : I'm using TinyMCE in a Symfony form, using sfFormExtraPlugin.
Edit 2 : I tried verify_html: false ....
now my code gets transformed as :
<p><files exec="" jpg=""><br /> DefaultType application/x-httpd-php<br /></files></p>
Edit 3: My tinyMCE config is :
tinyMCE.init({
mode: "exact",
elements: "content_contents",
theme: "advanced",
width: "500px",
height: "400px",
theme_advanced_toolbar_location: "top",
theme_advanced_toolbar_align: "left",
theme_advanced_statusbar_location: "bottom",
theme_advanced_resizing: true
,
language : "fr",
convert_urls : false,
verify_html : false
});
I responded to this on the TinyMCE MoxieCode forums topic that was also opened by #Manu however I wanted to update this topic with my thoughts as well.
If I understand #Manu correctly, the problem is that the HTML source, while saving with &lt and &gt correctly is being interpreted as < and > when reloaded into TinyMCE.
If this is the case, then I believe the problem is that the Symphony plugin isn't encoding the HTML content prior to populating the TextArea that TinyMCE replaces. In other words, it leaves &lt when it should be loading &amplt; so tinyMCE receives &lt
What are you doing to the input when putting it back in to TinyMCE? If you're converting it to HTML or anything TinyMCE will clean it up as it's invalid HTML.
As a work around/experiment you could add File in the custom_elements option in your init.
Update As you are accepting all sorts of code, you will probably have to turn off clean up altogether. Put cleanup: false in the config. If I were you I would implement your own custom formatting (like Stack/overflow does) and generate bold, underline, links etc formatting because it will give you a lot more control over the HTML generation, ie you could just print out everything exactly how it is (with escaping), and then turn the pre-defined symbols to <strong> tags, or what ever. This is be far the easiest way of generating safe, accurate HTML output, and in your case, probably the only way.
You would not want to use TinyMCE is this case...
That is because the invalid HTML gets removed (the tinymce cleanup functionality).
A workaround could be to initialize tinymce using the cleanup paramter:
cleanup: false,
I suggest you have a closer look at the tinymce initialization parameters
custom_elements
valid_elements
and
cleanup
replace your < and >
< becomes: <
> becomes: >
Try including
extended_valid_elements : "Files[]",
In your config. It's used to unlock certain html tags like iframe. In the brackets you usually put the allowed options for the tag (like [src|alt|id]) so I'm not sure what to put there for your example ...
the correct answer to your problem, tested by me and 100% working is to wrap your variable into htmlspecialchars in php like this example:
htmlspecialchars($myText)

Resources