I have struggled with most solutions to convert and embed Jupyter notebooks into WordPress blog posts since I use Plotly as a graphic lib, as well as many LaTeX equations and images. Finally, I had to code my way through. Here is what I did :
Write the jupyter notebook
Nothing that you don’t know here. If you embed pictures in the notebook though, it would be good to upload them on your WordPress media library, then use the external URL to include them (from your server) in the Markdown cells of Jupyter. Otherwise, you have to put them in the same directory as the notebook and link them with their relative path, it’s less convenent.
Convert the Jupyter notebook to HTML
We convert with a basic template :
1 jupyter nbconvert --to=html --template=basic notebook.ipynb notebook.html
Allow HTML uploads in WordPress
Many security plugins disable this feature so you have to track the culprit if WordPress says “This filetype is forbidden for security reasons” and add this line in your theme
functions.php
or wp-config.php
:
1 define('ALLOW_UNFILTERED_UPLOADS' , true );
Now you can import HTML pages just as any other media type. Be careful, this is a security issue. You need to harden the security of your WordPress install to prevent hackers to login, because they can now embed any kind of deceptive or fraudulent content in your pages.
Create a shortcode to include the page
This sounds worse than it is : we will just add a small shortcode to allow PHP to include the HTML file directly, without iframes or external renderer. Create a plugin, or add this in your functions.php :
1 // Include HTML
2 function include_shortcode ( $atts )
3 {
4 $atts = shortcode_atts( array ('id' => '' ), $atts , 'include' );
5 $uploads = wp_upload_dir();
6
7 // Enqueue maths scripts on HTML includes
8 wp_enqueue_script( 'plotly' );
9 wp_enqueue_script( 'mathjax' );
10 ob_start();
11 include $uploads ["basedir" ].'/' .trim($atts ['id' ]);
12 return ob_get_clean();
13 }
14
15 add_shortcode( 'include' , 'include_shortcode' );
From now on, when in a WordPress post editor, to include the HTML notebook file directly from your WordPress uploads directory (//:your-website.com/wp-content/uploads/ ), you can use the shortcode [include id="2018/05/notebook.html"]
or alternatively [include id="notebook.html"]
if you didn’t activate the date structure.
Notice that we enqueue the maths scripts here (see the next section) manually, the explanation is on the next section.
Load Plotly and MathJax
Exported with the basic template, Plotly javascript libraries are not embedded and neither are these from Mathjax. Some plugins do the work for MathJax but, as we have to code for Plotly, let’s do both. Again, in your functions.php or in a plugin, write :
1 wp_register_script( 'plotly' ,
2 "//cdn.plot.ly/plotly-latest.min.js" ,
3 array (), null , true );
4 wp_register_script( 'mathjax' ,
5 "//cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS_HTML" ,
6 array (), null , true );
7
8 function load_maths ( $content )
9 {
10 if (strpos($content , '$' ) !== false || strpos($content , '[latex]' ) !== false )
11 {
12 wp_enqueue_script( 'plotly' );
13 wp_enqueue_script( 'mathjax' );
14 }
15
16 return $content ;
17 }
18
19 add_filter( 'the_content' , 'load_maths' );
20
21 function my_custom_js () {
22 echo "<script type='text/x-mathjax-config'>
23 MathJax.Hub.Config({
24 tex2jax: {
25 inlineMath: [ ['$','$'], ['[latex]', '[/latex]']],
26 displayMath: [ ['$$','$$'] ],
27 processEscapes: true,
28 processEnvironments: true },
29 // Center justify equations in code and markdown cells. Elsewhere
30 // we use CSS to left justify single line equations in code cells.
31 displayAlign: 'center',
32 'HTML-CSS': {
33 styles: {'.MathJax_Display': {'margin': 0}},
34 linebreaks: { automatic: true },
35 extensions: ['handle-floats.js'],
36 availableFonts: ['STIX','TeX'],
37 preferredFont: 'STIX',
38 webFont:'STIX-Web' } });
39 </script>;" ;
40 }
41
42 // Add hook for front-end <head></head>
43 add_action('wp_head' , 'my_custom_js' );
The first two lines register the scripts and enables footer loading to improve the page loading speed. The function load_maths
parses the post content and enqueue the scripts only if the LaTeX markups are detected on the page, avoiding unnecessary scripts on other posts (keep the web minimalist). We also need to enqueue them manually on the include shortcode (see section 5.) because the WordPress content filter is not able to parse includes, so the on-demand enqueuing only works on posts containing maths in the post entry.
The rest is a bit of configuration of MathJax to match the built-in configuration of Jupyter and the default WordPress LaTeX plugin shortcode for retro-compatibility. We add it on every page header, which is not necessary but does not really affect performance so we don’t need to add a content filter that will make the server work more for no user benefit. Notice that the LaTeX display math mode using [ and ] won’t be available since it conflicts for some reasons with the brackets enclosing the Jupyter cell numbers, so you will have to use $$ instead.
A little bit of styling
Now, everything works except there is no styling. So, I just copy/pasted the CSS from Jupyter :
1 /*!
2 *
3 * IPython notebook
4 *
5 */
6 /* CSS font colors for translated ANSI colors. */
7 .ansibold {
8 font-weight : bold ;
9 }
10 /* use dark versions for foreground, to improve visibility */
11 .ansiblack {
12 color : black ;
13 }
14 .ansired {
15 color : darkred ;
16 }
17 .ansigreen {
18 color : darkgreen ;
19 }
20 .ansiyellow {
21 color : #c4a000 ;
22 }
23 .ansiblue {
24 color : darkblue ;
25 }
26 .ansipurple {
27 color : darkviolet ;
28 }
29 .ansicyan {
30 color : steelblue ;
31 }
32 .ansigray {
33 color : gray ;
34 }
35 /* and light for background, for the same reason */
36 .ansibgblack {
37 background-color : black ;
38 }
39 .ansibgred {
40 background-color : red ;
41 }
42 .ansibggreen {
43 background-color : green ;
44 }
45 .ansibgyellow {
46 background-color : yellow ;
47 }
48 .ansibgblue {
49 background-color : blue ;
50 }
51 .ansibgpurple {
52 background-color : magenta ;
53 }
54 .ansibgcyan {
55 background-color : cyan ;
56 }
57 .ansibggray {
58 background-color : gray ;
59 }
60 div .cell {
61 /* Old browsers */
62 display : -webkit- box;
63 -webkit- box-orient: vertical ;
64 -webkit- box-align: stretch ;
65 display : -moz- box;
66 -moz- box-orient: vertical ;
67 -moz- box-align: stretch ;
68 display : box;
69 box-orient: vertical ;
70 box-align: stretch ;
71 /* Modern browsers */
72 display : flex ;
73 flex-direction : column ;
74 align-items : stretch ;
75 border-radius : 2 px ;
76 box-sizing : border-box ;
77 -moz- box-sizing : border-box ;
78 -webkit- box-sizing : border-box ;
79 border-width : 1 px ;
80 border-style : solid ;
81 border-color : transparent ;
82 width : 100 % ;
83 padding : 5 px ;
84 /* This acts as a spacer between cells, that is outside the border */
85 margin : 0 px ;
86 outline : none ;
87 border-left-width : 1 px ;
88 padding-left : 5 px ;
89 background : linear-gradient (to right , transparent -40 px , transparent 1 px , transparent 1 px , transparent 100 % );
90 }
91 div .cell .jupyter-soft-selected {
92 border-left-color : #90CAF9 ;
93 border-left-color : #E3F2FD ;
94 border-left-width : 1 px ;
95 padding-left : 5 px ;
96 border-right-color : #E3F2FD ;
97 border-right-width : 1 px ;
98 background : #E3F2FD ;
99 }
100 @media print {
101 div .cell .jupyter-soft-selected {
102 border-color : transparent ;
103 }
104 }
105 div .cell .selected {
106 border-color : #ababab ;
107 border-left-width : 0 px ;
108 padding-left : 6 px ;
109 background : linear-gradient (to right , #42A5F5 -40 px , #42A5F5 5 px , transparent 5 px , transparent 100 % );
110 }
111 @media print {
112 div .cell .selected {
113 border-color : transparent ;
114 }
115 }
116 div .cell .selected .jupyter-soft-selected {
117 border-left-width : 0 ;
118 padding-left : 6 px ;
119 background : linear-gradient (to right , #42A5F5 -40 px , #42A5F5 7 px , #E3F2FD 7 px , #E3F2FD 100 % );
120 }
121 .edit_mode div .cell .selected {
122 border-color : #66BB6A ;
123 border-left-width : 0 px ;
124 padding-left : 6 px ;
125 background : linear-gradient (to right , #66BB6A -40 px , #66BB6A 5 px , transparent 5 px , transparent 100 % );
126 }
127 @media print {
128 .edit_mode div .cell .selected {
129 border-color : transparent ;
130 }
131 }
132 .prompt {
133 /* This needs to be wide enough for 3 digit prompt numbers: In[100]: */
134 min-width : 14 ex ;
135 /* This padding is tuned to match the padding on the CodeMirror editor. */
136 padding : 0.4 em ;
137 margin : 0 px ;
138 font-family : monospace ;
139 text-align : right ;
140 /* This has to match that of the the CodeMirror class line-height below */
141 line-height : 1.21429 em ;
142 /* Don't highlight prompt number selection */
143 -webkit- touch-callout: none ;
144 -webkit- user-select : none ;
145 -khtml- user-select : none ;
146 -moz- user-select : none ;
147 -ms- user-select : none ;
148 user-select : none ;
149 /* Use default cursor */
150 cursor : default ;
151 }
152 @media (max-width : 540px ) {
153 .prompt {
154 text-align : left ;
155 }
156 }
157 div .inner_cell {
158 min-width : 0 ;
159 /* Old browsers */
160 display : -webkit- box;
161 -webkit- box-orient: vertical ;
162 -webkit- box-align: stretch ;
163 display : -moz- box;
164 -moz- box-orient: vertical ;
165 -moz- box-align: stretch ;
166 display : box;
167 box-orient: vertical ;
168 box-align: stretch ;
169 /* Modern browsers */
170 display : flex ;
171 flex-direction : column ;
172 align-items : stretch ;
173 /* Old browsers */
174 -webkit- box-flex: 1 ;
175 -moz- box-flex: 1 ;
176 box-flex: 1 ;
177 /* Modern browsers */
178 flex : 1 ;
179 }
180 /* input_area and input_prompt must match in top border and margin for alignment */
181 div .input_area {
182 border : 1 px solid #cfcfcf ;
183 border-radius : 2 px ;
184 background : #f7f7f7 ;
185 line-height : 1.21429 em ;
186 }
187 /* This is needed so that empty prompt areas can collapse to zero height when there
188 is no content in the output_subarea and the prompt. The main purpose of this is
189 to make sure that empty JavaScript output_subareas have no height. */
190 div .prompt :empty {
191 padding-top : 0 ;
192 padding-bottom : 0 ;
193 }
194 div .unrecognized_cell {
195 padding : 5 px 5 px 5 px 0 px ;
196 /* Old browsers */
197 display : -webkit- box;
198 -webkit- box-orient: horizontal ;
199 -webkit- box-align: stretch ;
200 display : -moz- box;
201 -moz- box-orient: horizontal ;
202 -moz- box-align: stretch ;
203 display : box;
204 box-orient: horizontal ;
205 box-align: stretch ;
206 /* Modern browsers */
207 display : flex ;
208 flex-direction : row ;
209 align-items : stretch ;
210 }
211 div .unrecognized_cell .inner_cell {
212 border-radius : 2 px ;
213 padding : 5 px ;
214 font-weight : bold ;
215 color : red ;
216 border : 1 px solid #cfcfcf ;
217 background : #eaeaea ;
218 }
219 div .unrecognized_cell .inner_cell a {
220 color : inherit ;
221 text-decoration : none ;
222 }
223 div .unrecognized_cell .inner_cell a :hover {
224 color : inherit ;
225 text-decoration : none ;
226 }
227 @media (max-width : 540px ) {
228 div .unrecognized_cell > ; div .prompt {
229 display : none ;
230 }
231 }
232 div .code_cell {
233 /* avoid page breaking on code cells when printing */
234 }
235 @media print {
236 div .code_cell {
237 page-break-inside : avoid ;
238 }
239 }
240 /* any special styling for code cells that are currently running goes here */
241 div .input {
242 page-break-inside : avoid ;
243 /* Old browsers */
244 display : -webkit- box;
245 -webkit- box-orient: horizontal ;
246 -webkit- box-align: stretch ;
247 display : -moz- box;
248 -moz- box-orient: horizontal ;
249 -moz- box-align: stretch ;
250 display : box;
251 box-orient: horizontal ;
252 box-align: stretch ;
253 /* Modern browsers */
254 display : flex ;
255 flex-direction : row ;
256 align-items : stretch ;
257 }
258 @media (max-width : 540px ) {
259 div .input {
260 /* Old browsers */
261 display : -webkit- box;
262 -webkit- box-orient: vertical ;
263 -webkit- box-align: stretch ;
264 display : -moz- box;
265 -moz- box-orient: vertical ;
266 -moz- box-align: stretch ;
267 display : box;
268 box-orient: vertical ;
269 box-align: stretch ;
270 /* Modern browsers */
271 display : flex ;
272 flex-direction : column ;
273 align-items : stretch ;
274 }
275 }
276 /* input_area and input_prompt must match in top border and margin for alignment */
277 div .input_prompt {
278 color : #303F9F ;
279 border-top : 1 px solid transparent ;
280 }
281 div .input_area > ; div .highlight {
282 margin : 0.4 em ;
283 border : none ;
284 padding : 0 px ;
285 background-color : transparent ;
286 }
287 div .input_area > ; div .highlight > ; pre {
288 margin : 0 px ;
289 border : none ;
290 padding : 0 px ;
291 background-color : transparent ;
292 }
293 /* The following gets added to theif it is detected that the user has a* monospace font with inconsistent normal/bold/italic height. See* notebookmain.js. Such fonts will have keywords vertically offset with* respect to the rest of the text. The user should select a better font.* See: https://github.com/ipython/ipython/issues/1503** .CodeMirror span {* vertical-align: bottom;* }*/ .CodeMirror {line-height : 1.21429 em ;/* Changed from 1em to our global default */ font-size : 14 px ;height : auto ;/* Changed to auto to autogrow */ background : none ;/* Changed from white to allow our bg to show through */ }.CodeMirror-scroll {/* The CodeMirror docs are a bit fuzzy on if overflow-y should be hidden or visible.*//* We have found that if it is visible, vertical scrollbars appear with font size changes.*/ overflow-y : hidden ;overflow-x : auto ;}.CodeMirror-lines {/* In CM2, this used to be 0.4em, but in CM3 it went to 4px. We need the em value because *//* we have set a different line-height and want this to scale with that. */ padding : 0.4 em ;}.CodeMirror-linenumber {padding : 0 8 px 0 4 px ;}.CodeMirror-gutters {border-bottom-left-radius : 2 px ;border-top-left-radius : 2 px ;}.CodeMirror pre {/* In CM3 this went to 4px from 0 in CM2. We need the 0 value because of how we size *//* .CodeMirror-lines */ padding : 0 ;border : 0 ;border-radius : 0 ;}/*
294
295 Original style from softwaremaniacs.org (c) Ivan Sagalaev <Maniac@SoftwareManiacs.Org>
296 Adapted from GitHub theme
297
298 */
299 .highlight-base {
300 color : #000 ;
301 }
302 .highlight-variable {
303 color : #000 ;
304 }
305 .highlight-variable-2 {
306 color : #1a1a1a ;
307 }
308 .highlight-variable-3 {
309 color : #333333 ;
310 }
311 .highlight-string {
312 color : #BA2121 ;
313 }
314 .highlight-comment {
315 color : #408080 ;
316 font-style : italic ;
317 }
318 .highlight-number {
319 color : #080 ;
320 }
321 .highlight-atom {
322 color : #88F ;
323 }
324 .highlight-keyword {
325 color : #008000 ;
326 font-weight : bold ;
327 }
328 .highlight-builtin {
329 color : #008000 ;
330 }
331 .highlight-error {
332 color : #f00 ;
333 }
334 .highlight-operator {
335 color : #AA22FF ;
336 font-weight : bold ;
337 }
338 .highlight-meta {
339 color : #AA22FF ;
340 }
341 /* previously not defined, copying from default codemirror */
342 .highlight-def {
343 color : #00f ;
344 }
345 .highlight-string-2 {
346 color : #f50 ;
347 }
348 .highlight-qualifier {
349 color : #555 ;
350 }
351 .highlight-bracket {
352 color : #997 ;
353 }
354 .highlight-tag {
355 color : #170 ;
356 }
357 .highlight-attribute {
358 color : #00c ;
359 }
360 .highlight-header {
361 color : blue ;
362 }
363 .highlight-quote {
364 color : #090 ;
365 }
366 .highlight-link {
367 color : #00c ;
368 }
369 /* apply the same style to codemirror */
370 .cm-s-ipython span .cm-keyword {
371 color : #008000 ;
372 font-weight : bold ;
373 }
374 .cm-s-ipython span .cm-atom {
375 color : #88F ;
376 }
377 .cm-s-ipython span .cm-number {
378 color : #080 ;
379 }
380 .cm-s-ipython span .cm-def {
381 color : #00f ;
382 }
383 .cm-s-ipython span .cm-variable {
384 color : #000 ;
385 }
386 .cm-s-ipython span .cm-operator {
387 color : #AA22FF ;
388 font-weight : bold ;
389 }
390 .cm-s-ipython span .cm-variable-2 {
391 color : #1a1a1a ;
392 }
393 .cm-s-ipython span .cm-variable-3 {
394 color : #333333 ;
395 }
396 .cm-s-ipython span .cm-comment {
397 color : #408080 ;
398 font-style : italic ;
399 }
400 .cm-s-ipython span .cm-string {
401 color : #BA2121 ;
402 }
403 .cm-s-ipython span .cm-string-2 {
404 color : #f50 ;
405 }
406 .cm-s-ipython span .cm-meta {
407 color : #AA22FF ;
408 }
409 .cm-s-ipython span .cm-qualifier {
410 color : #555 ;
411 }
412 .cm-s-ipython span .cm-builtin {
413 color : #008000 ;
414 }
415 .cm-s-ipython span .cm-bracket {
416 color : #997 ;
417 }
418 .cm-s-ipython span .cm-tag {
419 color : #170 ;
420 }
421 .cm-s-ipython span .cm-attribute {
422 color : #00c ;
423 }
424 .cm-s-ipython span .cm-header {
425 color : blue ;
426 }
427 .cm-s-ipython span .cm-quote {
428 color : #090 ;
429 }
430 .cm-s-ipython span .cm-link {
431 color : #00c ;
432 }
433 .cm-s-ipython span .cm-error {
434 color : #f00 ;
435 }
436 .cm-s-ipython span .cm-tab {
437 background : url (data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAMCAYAAAAkuj5RAAAAAXNSR0IArs4c6QAAAGFJREFUSMft1LsRQFAQheHPowAKoACx3IgEKtaEHujDjORSgWTH/ZOdnZOcM/sgk/kFFWY0qV8foQwS4MKBCS3qR6ixBJvElOobYAtivseIE120FaowJPN75GMu8j/LfMwNjh4HUpwg4LUAAAAASUVORK5CYII= );
438 background-position : right ;
439 background-repeat : no-repeat ;
440 }
441 div .output_wrapper {
442 /* this position must be relative to enable descendents to be absolute within it */
443 position : relative ;
444 /* Old browsers */
445 display : -webkit- box;
446 -webkit- box-orient: vertical ;
447 -webkit- box-align: stretch ;
448 display : -moz- box;
449 -moz- box-orient: vertical ;
450 -moz- box-align: stretch ;
451 display : box;
452 box-orient: vertical ;
453 box-align: stretch ;
454 /* Modern browsers */
455 display : flex ;
456 flex-direction : column ;
457 align-items : stretch ;
458 z-index : 1 ;
459 }
460 /* class for the output area when it should be height-limited */
461 div .output_scroll {
462 /* ideally, this would be max-height, but FF barfs all over that */
463 height : 24 em ;
464 /* FF needs this *and the wrapper* to specify full width, or it will shrinkwrap */
465 width : 100 % ;
466 overflow : auto ;
467 border-radius : 2 px ;
468 -webkit- box-shadow : inset 0 2 px 8 px rgba (0 , 0 , 0 , 0.8 );
469 box-shadow : inset 0 2 px 8 px rgba (0 , 0 , 0 , 0.8 );
470 display : block ;
471 }
472 /* output div while it is collapsed */
473 div .output_collapsed {
474 margin : 0 px ;
475 padding : 0 px ;
476 /* Old browsers */
477 display : -webkit- box;
478 -webkit- box-orient: vertical ;
479 -webkit- box-align: stretch ;
480 display : -moz- box;
481 -moz- box-orient: vertical ;
482 -moz- box-align: stretch ;
483 display : box;
484 box-orient: vertical ;
485 box-align: stretch ;
486 /* Modern browsers */
487 display : flex ;
488 flex-direction : column ;
489 align-items : stretch ;
490 }
491 div .out_prompt_overlay {
492 height : 100 % ;
493 padding : 0 px 0.4 em ;
494 position : absolute ;
495 border-radius : 2 px ;
496 }
497 div .out_prompt_overlay :hover {
498 /* use inner shadow to get border that is computed the same on WebKit/FF */
499 -webkit- box-shadow : inset 0 0 1 px #000 ;
500 box-shadow : inset 0 0 1 px #000 ;
501 background : rgba (240 , 240 , 240 , 0.5 );
502 }
503 div .output_prompt {
504 color : #D84315 ;
505 }
506 /* This class is the outer container of all output sections. */
507 div .output_area {
508 padding : 0 px ;
509 page-break-inside : avoid ;
510 /* Old browsers */
511 display : -webkit- box;
512 -webkit- box-orient: horizontal ;
513 -webkit- box-align: stretch ;
514 display : -moz- box;
515 -moz- box-orient: horizontal ;
516 -moz- box-align: stretch ;
517 display : box;
518 box-orient: horizontal ;
519 box-align: stretch ;
520 /* Modern browsers */
521 display : flex ;
522 flex-direction : row ;
523 align-items : stretch ;
524 }
525 div .output_area .MathJax_Display {
526 text-align : left !important ;
527 }
528 div .output_area .rendered_html table {
529 margin-left : 0 ;
530 margin-right : 0 ;
531 }
532 div .output_area .rendered_html img {
533 margin-left : 0 ;
534 margin-right : 0 ;
535 }
536 div .output_area img ,
537 div .output_area svg {
538 max-width : 100 % ;
539 height : auto ;
540 }
541 div .output_area img .unconfined ,
542 div .output_area svg .unconfined {
543 max-width : none ;
544 }
545 /* This is needed to protect the pre formating from global settings such
546 as that of bootstrap */
547 .output {
548 /* Old browsers */
549 display : -webkit- box;
550 -webkit- box-orient: vertical ;
551 -webkit- box-align: stretch ;
552 display : -moz- box;
553 -moz- box-orient: vertical ;
554 -moz- box-align: stretch ;
555 display : box;
556 box-orient: vertical ;
557 box-align: stretch ;
558 /* Modern browsers */
559 display : flex ;
560 flex-direction : column ;
561 align-items : stretch ;
562 }
563 @media (max-width : 540px ) {
564 div .output_area {
565 /* Old browsers */
566 display : -webkit- box;
567 -webkit- box-orient: vertical ;
568 -webkit- box-align: stretch ;
569 display : -moz- box;
570 -moz- box-orient: vertical ;
571 -moz- box-align: stretch ;
572 display : box;
573 box-orient: vertical ;
574 box-align: stretch ;
575 /* Modern browsers */
576 display : flex ;
577 flex-direction : column ;
578 align-items : stretch ;
579 }
580 }
581 div .output_area pre {
582 margin : 0 ;
583 padding : 0 ;
584 border : 0 ;
585 vertical-align : baseline ;
586 color : black ;
587 background-color : transparent ;
588 border-radius : 0 ;
589 }
590 /* This class is for the output subarea inside the output_area and after
591 the prompt div. */
592 div .output_subarea {
593 overflow-x : auto ;
594 padding : 0.4 em ;
595 /* Old browsers */
596 -webkit- box-flex: 1 ;
597 -moz- box-flex: 1 ;
598 box-flex: 1 ;
599 /* Modern browsers */
600 flex : 1 ;
601 max-width : calc (100 % - 14 ex );
602 }
603 div .output_scroll div .output_subarea {
604 overflow-x : visible ;
605 }
606 /* The rest of the output_* classes are for special styling of the different
607 output types */
608 /* all text output has this class: */
609 div .output_text {
610 text-align : left ;
611 color : #000 ;
612 /* This has to match that of the the CodeMirror class line-height below */
613 line-height : 1.21429 em ;
614 }
615 /* stdout/stderr are 'text' as well as 'stream', but execute_result/error are *not* streams */
616 div .output_stderr {
617 background : #fdd ;
618 /* very light red background for stderr */
619 }
620 div .output_latex {
621 text-align : left ;
622 }
623 /* Empty output_javascript divs should have no height */
624 div .output_javascript :empty {
625 padding : 0 ;
626 }
627 .js-error {
628 color : darkred ;
629 }
630 /* raw_input styles */
631 div .raw_input_container {
632 line-height : 1.21429 em ;
633 padding-top : 5 px ;
634 }
635 pre .raw_input_prompt {
636 /* nothing needed here. */
637 }
638 input .raw_input {
639 font-family : monospace ;
640 font-size : inherit ;
641 color : inherit ;
642 width : auto ;
643 /* make sure input baseline aligns with prompt */
644 vertical-align : baseline ;
645 /* padding + margin = 0.5em between prompt and cursor */
646 padding : 0 em 0.25 em ;
647 margin : 0 em 0.25 em ;
648 }
649 input .raw_input :focus {
650 box-shadow : none ;
651 }
652 p .p-space {
653 margin-bottom : 10 px ;
654 }
655 div .output_unrecognized {
656 padding : 5 px ;
657 font-weight : bold ;
658 color : red ;
659 }
660 div .output_unrecognized a {
661 color : inherit ;
662 text-decoration : none ;
663 }
664 div .output_unrecognized a :hover {
665 color : inherit ;
666 text-decoration : none ;
667 }
668 .rendered_html pre {
669 margin : 1 em 2 em ;
670 }
671 .rendered_html pre ,
672 .rendered_html code {
673 border : 0 ;
674 background-color : #fff ;
675 color : #000 ;
676 font-size : 100 % ;
677 padding : 0 px ;
678 }
679 .rendered_html blockquote {
680 margin : 1 em 2 em ;
681 }
682 .rendered_html table {
683 margin-left : auto ;
684 margin-right : auto ;
685 border : 1 px solid black ;
686 border-collapse : collapse ;
687 }
688 .rendered_html tr ,
689 .rendered_html th ,
690 .rendered_html td {
691 border : 1 px solid black ;
692 border-collapse : collapse ;
693 margin : 1 em 2 em ;
694 }
695 .rendered_html td ,
696 .rendered_html th {
697 text-align : left ;
698 vertical-align : middle ;
699 padding : 4 px ;
700 }
701 .rendered_html th {
702 font-weight : bold ;
703 }
704 .rendered_html * + table {
705 margin-top : 1 em ;
706 }
707 .rendered_html p {
708 text-align : left ;
709 }
710 .rendered_html * + p {
711 margin-top : 1 em ;
712 }
713 .rendered_html img {
714 display : block ;
715 margin-left : auto ;
716 margin-right : auto ;
717 }
718 .rendered_html * + img {
719 margin-top : 1 em ;
720 }
721 .rendered_html img ,
722 .rendered_html svg {
723 max-width : 100 % ;
724 height : auto ;
725 }
726 .rendered_html img .unconfined ,
727 .rendered_html svg .unconfined {
728 max-width : none ;
729 }
730 div .text_cell {
731 /* Old browsers */
732 display : -webkit- box;
733 -webkit- box-orient: horizontal ;
734 -webkit- box-align: stretch ;
735 display : -moz- box;
736 -moz- box-orient: horizontal ;
737 -moz- box-align: stretch ;
738 display : box;
739 box-orient: horizontal ;
740 box-align: stretch ;
741 /* Modern browsers */
742 display : flex ;
743 flex-direction : row ;
744 align-items : stretch ;
745 }
746 @media (max-width : 540px ) {
747 div .text_cell > ; div .prompt {
748 display : none ;
749 }
750 }
751 div .text_cell_render {
752 /*font-family: "Helvetica Neue", Arial, Helvetica, Geneva, sans-serif;*/
753 outline : none ;
754 resize : none ;
755 width : inherit ;
756 border-style : none ;
757 padding : 0.5 em 0.5 em 0.5 em 0.4 em ;
758 color : #000 ;
759 box-sizing : border-box ;
760 -moz- box-sizing : border-box ;
761 -webkit- box-sizing : border-box ;
762 }
763 a .anchor-link :link {
764 text-decoration : none ;
765 padding : 0 px 20 px ;
766 visibility : hidden ;
767 }
768 h1 :hover .anchor-link ,
769 h2 :hover .anchor-link ,
770 h3 :hover .anchor-link ,
771 h4 :hover .anchor-link ,
772 h5 :hover .anchor-link ,
773 h6 :hover .anchor-link {
774 visibility : visible ;
775 }
776 .text_cell .rendered .input_area {
777 display : none ;
778 }
779 .text_cell .rendered .rendered_html {
780 overflow-x : auto ;
781 overflow-y : hidden ;
782 }
783 .text_cell .unrendered .text_cell_render {
784 display : none ;
785 }
786 .cm-header-1 ,
787 .cm-header-2 ,
788 .cm-header-3 ,
789 .cm-header-4 ,
790 .cm-header-5 ,
791 .cm-header-6 {
792 font-weight : bold ;
793 font-family : "Helvetica Neue" , Helvetica, Arial, sans-serif ;
794 }
795 .cm-header-1 {
796 font-size : 185.7 % ;
797 }
798 .cm-header-2 {
799 font-size : 157.1 % ;
800 }
801 .cm-header-3 {
802 font-size : 128.6 % ;
803 }
804 .cm-header-4 {
805 font-size : 110 % ;
806 }
807 .cm-header-5 {
808 font-size : 100 % ;
809 font-style : italic ;
810 }
811 .cm-header-6 {
812 font-size : 100 % ;
813 font-style : italic ;
814 }
815 .highlight .hll { background-color : #ffffcc }
816 .highlight { background : #f8f8f8 ; }
817 .highlight .c { color : #408080 ; font-style : italic } /* Comment */
818 .highlight .err { border : 1 px solid #FF0000 } /* Error */
819 .highlight .k { color : #008000 ; font-weight : bold } /* Keyword */
820 .highlight .o { color : #666666 } /* Operator */
821 .highlight .ch { color : #408080 ; font-style : italic } /* Comment.Hashbang */
822 .highlight .cm { color : #408080 ; font-style : italic } /* Comment.Multiline */
823 .highlight .cp { color : #BC7A00 } /* Comment.Preproc */
824 .highlight .cpf { color : #408080 ; font-style : italic } /* Comment.PreprocFile */
825 .highlight .c1 { color : #408080 ; font-style : italic } /* Comment.Single */
826 .highlight .cs { color : #408080 ; font-style : italic } /* Comment.Special */
827 .highlight .gd { color : #A00000 } /* Generic.Deleted */
828 .highlight .ge { font-style : italic } /* Generic.Emph */
829 .highlight .gr { color : #FF0000 } /* Generic.Error */
830 .highlight .gh { color : #000080 ; font-weight : bold } /* Generic.Heading */
831 .highlight .gi { color : #00A000 } /* Generic.Inserted */
832 .highlight .go { color : #888888 } /* Generic.Output */
833 .highlight .gp { color : #000080 ; font-weight : bold } /* Generic.Prompt */
834 .highlight .gs { font-weight : bold } /* Generic.Strong */
835 .highlight .gu { color : #800080 ; font-weight : bold } /* Generic.Subheading */
836 .highlight .gt { color : #0044DD } /* Generic.Traceback */
837 .highlight .kc { color : #008000 ; font-weight : bold } /* Keyword.Constant */
838 .highlight .kd { color : #008000 ; font-weight : bold } /* Keyword.Declaration */
839 .highlight .kn { color : #008000 ; font-weight : bold } /* Keyword.Namespace */
840 .highlight .kp { color : #008000 } /* Keyword.Pseudo */
841 .highlight .kr { color : #008000 ; font-weight : bold } /* Keyword.Reserved */
842 .highlight .kt { color : #B00040 } /* Keyword.Type */
843 .highlight .m { color : #666666 } /* Literal.Number */
844 .highlight .s { color : #BA2121 } /* Literal.String */
845 .highlight .na { color : #7D9029 } /* Name.Attribute */
846 .highlight .nb { color : #008000 } /* Name.Builtin */
847 .highlight .nc { color : #0000FF ; font-weight : bold } /* Name.Class */
848 .highlight .no { color : #880000 } /* Name.Constant */
849 .highlight .nd { color : #AA22FF } /* Name.Decorator */
850 .highlight .ni { color : #999999 ; font-weight : bold } /* Name.Entity */
851 .highlight .ne { color : #D2413A ; font-weight : bold } /* Name.Exception */
852 .highlight .nf { color : #0000FF } /* Name.Function */
853 .highlight .nl { color : #A0A000 } /* Name.Label */
854 .highlight .nn { color : #0000FF ; font-weight : bold } /* Name.Namespace */
855 .highlight .nt { color : #008000 ; font-weight : bold } /* Name.Tag */
856 .highlight .nv { color : #19177C } /* Name.Variable */
857 .highlight .ow { color : #AA22FF ; font-weight : bold } /* Operator.Word */
858 .highlight .w { color : #bbbbbb } /* Text.Whitespace */
859 .highlight .mb { color : #666666 } /* Literal.Number.Bin */
860 .highlight .mf { color : #666666 } /* Literal.Number.Float */
861 .highlight .mh { color : #666666 } /* Literal.Number.Hex */
862 .highlight .mi { color : #666666 } /* Literal.Number.Integer */
863 .highlight .mo { color : #666666 } /* Literal.Number.Oct */
864 .highlight .sa { color : #BA2121 } /* Literal.String.Affix */
865 .highlight .sb { color : #BA2121 } /* Literal.String.Backtick */
866 .highlight .sc { color : #BA2121 } /* Literal.String.Char */
867 .highlight .dl { color : #BA2121 } /* Literal.String.Delimiter */
868 .highlight .sd { color : #BA2121 ; font-style : italic } /* Literal.String.Doc */
869 .highlight .s2 { color : #BA2121 } /* Literal.String.Double */
870 .highlight .se { color : #BB6622 ; font-weight : bold } /* Literal.String.Escape */
871 .highlight .sh { color : #BA2121 } /* Literal.String.Heredoc */
872 .highlight .si { color : #BB6688 ; font-weight : bold } /* Literal.String.Interpol */
873 .highlight .sx { color : #008000 } /* Literal.String.Other */
874 .highlight .sr { color : #BB6688 } /* Literal.String.Regex */
875 .highlight .s1 { color : #BA2121 } /* Literal.String.Single */
876 .highlight .ss { color : #19177C } /* Literal.String.Symbol */
877 .highlight .bp { color : #008000 } /* Name.Builtin.Pseudo */
878 .highlight .fm { color : #0000FF } /* Name.Function.Magic */
879 .highlight .vc { color : #19177C } /* Name.Variable.Class */
880 .highlight .vg { color : #19177C } /* Name.Variable.Global */
881 .highlight .vi { color : #19177C } /* Name.Variable.Instance */
882 .highlight .vm { color : #19177C } /* Name.Variable.Magic */
883 .highlight .il { color : #666666 } /* Literal.Number.Integer.Long */
Et voilà ! See the result on my first post … Well, this is sort of depressing… to end up with such a short post whereas I spent 4 hours making everything work.
Edit of 25th, March 2021 : I actually made a WordPress plugin to include maths, Plotly, Bokeh and Jupyter notebooks in WordPress posts in a seamless way : WP Scholar
Edit of 30th, January 2024 : I finally moved this site (and others) from WordPress to Hugo because it is simpler, cleaner and a lot easier on server’s and client’s power than WordPress, and I’m tired of having to work around the design mistakes of WordPress.