Hiding code in jupiter in R - r

I would like to try to produce reports (pdf and probably html) in jupyter using R kernel. However, I would like to hide code in two ways, depending on audience:
all code cells
some code cells
When I have looked for this I found answers for python kernel. Is there a way to this in R (no python code)?

So I have started to combine python's answer:
How to hide code from cells in ipython notebook visualized with nbviewer?
with
How to render LaTeX / HTML in Jupyter (R)?
and it works.
If one puts the following code in a cell, will get a button for hiding code. From here I think I know where to start.
library(IRdisplay)
display_html(
'<script>
code_show=true;
function code_toggle() {
if (code_show){
$(\'div.input\').hide();
} else {
$(\'div.input\').show();
}
code_show = !code_show
}
$( document ).ready(code_toggle);
</script>
<form action="javascript:code_toggle()">
<input type="submit" value="Click here to toggle on/off the raw code.">
</form>'
)

As you're talking about making HTML and PDF reports, you can do this by using a custom template with nbconvert, and using that to hide cells. This will work for any notebook, independent of the kernel you use.
Docs on nbconvert templates: http://nbconvert.readthedocs.org/en/latest/customizing.html
Examples including hiding code cells based on cell metadata: https://github.com/jupyter/ngcm-tutorial/tree/master/Day-2/nbconvert_templates

Add some CSS code in the first cell, change that cell to 'Raw NBConvert' and the format specified in the CSS will be applied to the HTML generated:
To hide input blocks:
<style type="text/css">
.input_hidden{
display: none
}
</style>
Other style definition can also go there.
Then run ipython nbconvert the_name_of_the_stuff.ipynb --to slides to generate the HTML (without the input blocks).

Related

Pandoc Markdown to HTML: how to increase margin of list items?

I am currently using the following setting to convert Markdown to HTML:
-s -t html5
This renders list items too narrow for me and I would like to increase the margin between the list items.
Is there any way to do so?
The simplest way to achieve this is to add additional CSS to the output HTML.
Create style.html file with the following content.
<style>
li:not(:last-child) { margin-bottom: 50px; }
</style>
Add -H style.html to include the file in the HTML header part. For example:
$ pandoc main.md -t html5 -o main.html -H style.html
Note that there are many other ways to include additional CSS to the output HTML file (for example you may simply put the <style> tag inside your markdown file). Check out this question for more info: Inline CSS with Pandoc
Pandoc distinguishes between "tight" and "loose" lists in Markdown:
This list is "tight":
- one
- two
This list is "loose" (note the extra blank line):
- one
- two
See here for a method to switch from loose to tight lists; replace Plain with Para (and vice versa) in the given code to go from tight to loose.

R Markdown Hashtag Hover Output

I am trying to create an R-Markdown document and for some reason on all headers of the document denoted by ### etc..., when I knit to html and hover over each word, an underlined hashtag appears. Is there a way to get rid of this in the output? As an example, below is the standards cars summary.
I tested on another machine and had no issues with the output. Could I be missing a certain package? I'm currently using Rstudio version 1.3.1093 and R version 4.0.3 on the PC that is not showing the correct output.
Thank you in advance
This is a new feature of the latest release of rmarkdown you can disable it by adding anchor_sections: FALSE to the yaml header, it's documented in the release notes
One solution is to override the CSS that is putting that # in there in the first place. Doing this means there will only be a cosmetic change, so no unintended side-effects.
Place a set of style tags after the YAML header and set the content of the a.anchor-section::before element to ''.
<style>
a.anchor-section::before {
content: '';
}
</style>
If you use right-click your output html document and click inspect element you can dive into the CSS that controls each element - the default in this case is a.anchor-section::before {content: '#';}.
You probably also want to add this too
a.anchor-section {
margin-left: 0;
}

How to create a numbered list across cells in jupyter notebook?

I need to create a list of questions in a jupyter notebook. Ideally I would write something like Q#. bla bla in one cell, Q#. bla bla in another cell, and they would be numbered correctly. Is that doable? Many thanks for any hint.
This may achieve what you are looking for, but it is not as clean as using straight markdown. You can initialize q=0 and then put python code inside double braces {{ }} in your markdown cells, so something like:
{{q=q+1}}
Q{{ q }}: Hello World?
BUT, these can get muddled if you don't run your markdown in order.
You could also use display_markdown, but you will have your question show up below the code cell.
Update:
You could use the incremental feature of CSS to generate the numbers for your questions. BUT, you would need to either:
Include the CSS in the first cell of the notebook, which is easy but very visible and would need to be executed by the user
Reference the an external style somehow, which might be complicated if you're sending this to other users.
For the first case you would have the following in your first cell using html magic:
%%html
<style>
body {counter-reset: q-counter;}
h1::before {
counter-increment: q-counter;
content: "Question " counter(q-counter) ". ";
}
</style>
and then for each markdown question cell you would use h1 tag (h2, h3, etc could also be used, just update the CSS accordingly), so something like:
<h1>Hello World?</h1>
Then the following markdown cells:
Would look like:

Puppeteer doesn't respect colors when exporting RMarkdown render to .pdf

I am using puppeteer (headless Chrome) to render an .html generated by an RMarkdown script to .pdf. However, puppeteer doesn't seem to respect my color and background-color style settings. The problem doesn't exist when rendering pages off the web, suggesting it's the interaction between puppeteer and RMarkdown.
Consider the following test.Rmd script:
---
title: "Testing colors"
output: html_document
---
<style>
html {
-webkit-print-color-adjust: exact;
}
h4 {color: blue;}
</style>
#### Blue heading
<div style="color:red">This text is red</div>
<div style="background-color:red">This text has red background</div>
We can render it to test.html by calling rmarkdown::render( "test.Rmd", output_file="test.html" ) in R. Note the -webkit-print-color-adjust setting; it is often recommended as a solution to color-related problems, but I found that it has no effect in my case.
Following puppeteer tutorials, I put together the following render.js:
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.setViewport({width: 400, height: 200});
await page.goto('file:///home/sokolov/test/puppeteer/test.html');
await page.screenshot({path: 'test.png'});
await page.pdf({path: 'test.pdf', printBackground: true});
await browser.close();
})();
Running node render.js from the command line produces test.png and test.pdf. The former looks exactly how you would expect:
However, the .pdf loses all color specifications:
If I replace the url in my render.js with an external page (e.g., https://www.w3schools.com/css/css_background.asp), the page renders correctly in both .png and .pdf formats. Specifying printBackground: true was key to making it work for this external page, but it seems to have no effect of my local test.html.
Any thoughts on how to get the colors working?
P.S. To briefly address the question of why I'm not simply using output: pdf_document in my .Rmd, I wanted to note that the real RMarkdown document I'm working with uses flexdashboard layout, which doesn't play nicely with knitr. Most of the tutorials I've read suggest using a headless browser to render the final .html to .png/.pdf. The solution is working well for me, except for the loss of color styles.
The Simplest Solution
Why not just try removing all !important tags? We're targeting the css embedded by rmarkdown:render. Just run some search and replace code, and puppeteer will correctly colorize a pdf made from the test.html. Run this in a shell with vim installed:
echo "%s/%21important// | w!" | vim -e test.html
And that's it! Below I just document my first attempt to solve this problem, and I explain why it might not be the best solution. Someone else may find it useful.
My first attempt
Run this in a shell with vim installed:
echo "%s/%40media%20print%7B.\{-}%7D// | w!" | vim -e test.html
The above command overwrites test.html with the #media print{} styles partially removed. Though the #media print{} styles are not fully or cleanly removed, the new test.html has the desired effect.
Here is what I'm doing
We're working on url-encoded css, so %s/%40media%20print%7B.\{-}%7D// is needed when I really wish to write this:
%s/#media print{.\{-}}//
The goal is to delete statements like this: #media print {a: ""} entirely. I don't properly handle nested brackets, so this script only partially delete statements like this #media print {.a{a: ""};b{}...} leaving everything after the first closing bracket untouched. That is a bug. I'm removing too little due to non-greedy matching with .\{-} instead of greedy matching with .*, which may remove too much.
Here's what I'm removing
I've URL decoded the actual css in test.html for readability. You can see that I've deleted non-matching braces. Likely, the offending css is not actually deleted, but removing these lines sufficiently breaks the css to disable the offending css whenever #media print is detected. Anyway, removing these 6 matches solves the problem.
#media print{*,:after,:before{color:#000!important;text-
shadow:none!important;background:0 0!important;-webkit-box-
shadow:none!important;box-shadow:none!important}
#media print{.visible-print{display:block!important}
#media print{.visible-print-block{display:block!important}
#media print{.visible-print-inline{display:inline!important}
#media print{.visible-print-inline-block{display:inline-block!important}
#media print{.hidden-print{display:none!important}

Adding custom styled paragraphs in markdown cells

I want to add more formatting elements than provided by the Markdown synthax in an IPython Notebook.
For example, I want to add a "Warning Box" or a "Memo Box" that are basically paragraph with different styles (for example different background color, border, an icon, etc...).
I guess I can add HTML code in the cell, for example a <div> with an inline style. But what is the "proper" way to do that, I mean the one that ipython developer promote?
Examples appreciated.
NB: I'm using the current 1.0dev version from git master.
Answering to my own question...
Other solutions
Jim proposed to add some custom CSS style in a markdown cell of each notebook. This solution works, but is not convenient since you need to embed the style on each notebook. In my case I want a global style and I don't want to modify all the notebooks after every the style modification.
A natural solution would be using a custom file (custom.css) containing the style. However after trying these instructions
the style is not applied to the notebook (it can be downloaded from the server though).
Best solution (so far)
I found a solution looking at this impressive book written as a collection of IPython notebooks. The author adds at the end of each notebook the following code cell:
from IPython.core.display import HTML
def css_styling():
styles = open("./styles/custom.css", "r").read()
return HTML(styles)
css_styling()
Putting a file custom.css in your notebook folder (in the styles subfolder), the style will be loaded after the first cell execution. Moreover the style will be magically loaded every time the notebook is opened, without the need to execute the cell again!
This magic trick works because the style is saved in the ouput cell the first time we execute it, and although being invisible, will be saved like any other output. So when we load the notebook, and conseguentely the output cells, the style will be applied.
Sample CSS
To complete the answer I post a CSS style I used to create a "Warning box":
<style>
div.warn {
background-color: #fcf2f2;
border-color: #dFb5b4;
border-left: 5px solid #dfb5b4;
padding: 0.5em;
}
</style>
Save this style and load it using the code cell shown before. Now, to insert a warning box in your notebook use this syntax:
<div class=warn>
**Warning:** remember to do bookeping
</div>
That will be rendered like this:
For more general notebook styling you can take inspiration from the custom.css
of the book mentioned above.
A simple way to add warning, note, success (etc...) boxes (also called admonition or alert boxes) is simply using the bootstrap classes already included with the notebook. The only caveat is that links and other styles (e.g. bold) must be specified in HTML inside the box.
Example
A markdown cell containing this code:
# Upload data files
<p class="lead">This Jupyter notebook
shows how to upload data files to be converted
to [Photon-HDF5](http://photon-hdf5.org) format. </p>
<i>Please send feedback and report any problems to the
[Photon-HDF5 google group](https://groups.google.com/forum/#!forum/photon-hdf5).</i>
<br>
<div class="alert alert-warning">
<b>NOTE</b> Uploading data files is only necessary when running the notebook online.
</div>
will result in this output:
You can change alert-warning with alert-success, alert-info or alert-danger to get different colors for the box.
Update: This technique no longer works in IPython 4.0 / Jupyter since the way the notebook is rendered has changed.
I believe the best way to do such styling is to create a markdown entry at the top of your document and to collect your styles there. Since a markdown cell can contain any valid HTML code, it could contain (for instance)
<style>
.warning { color: red; }
</style>
See Matt Davis' PyCon 2013 talk, about 22 minutes in during the Q&A for an example of this in use.
These custom css styles are already added in ipython version 2 and higher.
<div class="alert">
As of IPython 2.0, the user interface has changed significantly
</div>
<div class="alert alert-success">
Enter edit mode by pressing `Enter`
</div>
<div class="alert alert-error">
Don't try to type into a cell in command mode
</div>
Just paste this in the cell and change it to markdown type.
Check this for the examples and ipython in depth for the cutting edge features of ipython.
Another mean consists to simply create a style chain and open it with iPython HTML object in a code cell:
from IPython.display import HTML
style = "<style>div.warn { background-color: #fcf2f2;border-color: #dFb5b4; border-left: 5px solid #dfb5b4; padding: 0.5em;}</style>"
HTML(style)
Then use it in a markdown cell:
<div class="warn">Warning!</div>

Resources