diff --git a/IPython/html/static/notebook/js/cell.js b/IPython/html/static/notebook/js/cell.js
index 4a87ba6..502df10 100644
--- a/IPython/html/static/notebook/js/cell.js
+++ b/IPython/html/static/notebook/js/cell.js
@@ -33,9 +33,9 @@ var IPython = (function (IPython) {
*/
var Cell = function (options) {
- options = this.mergeopt(Cell, options)
+ options = this.mergeopt(Cell, options);
// superclass default overwrite our default
-
+
this.placeholder = options.placeholder || '';
this.read_only = options.cm_config.readOnly;
this.selected = false;
@@ -52,7 +52,7 @@ var IPython = (function (IPython) {
// same order. Easiest is to create and set to null in parent class.
this.element = null;
- this.cell_type = null;
+ this.cell_type = this.cell_type || null;
this.code_mirror = null;
@@ -80,6 +80,7 @@ var IPython = (function (IPython) {
}
Cell.prototype.mergeopt = function(_class, options, overwrite){
+ options = options || {};
overwrite = overwrite || {};
return $.extend(true, {}, _class.options_default, options, overwrite)
@@ -200,6 +201,7 @@ var IPython = (function (IPython) {
Cell.prototype.toJSON = function () {
var data = {};
data.metadata = this.metadata;
+ data.cell_type = this.cell_type;
return data;
};
diff --git a/IPython/html/static/notebook/js/celltoolbar.js b/IPython/html/static/notebook/js/celltoolbar.js
index 74186b1..e320212 100644
--- a/IPython/html/static/notebook/js/celltoolbar.js
+++ b/IPython/html/static/notebook/js/celltoolbar.js
@@ -37,37 +37,39 @@ var IPython = (function (IPython) {
this.inner_element = $('
').addClass('celltoolbar')
this.element = $('').addClass('ctb_hideshow')
.append(this.inner_element);
+ this.show();
};
// The default css style for the outer celltoolbar div
- // (ctb_hideshow) is display: none. We add the ctb_show
- // class to either 1) the body to show all cell's toolbars
- // or 2) to the individual celltoolbar divs to show just one
- // cell's toolbar.
+ // (ctb_hideshow) is display: none.
+ // To show the cell toolbar, *both* of the following conditions must be met:
+ // - A parent container has class `ctb_global_show`
+ // - The celltoolbar has the class `ctb_show`
+ // This allows global show/hide, as well as per-cell show/hide.
CellToolbar.global_hide = function () {
- $('body').removeClass('ctb_show');
- }
+ $('body').removeClass('ctb_global_show');
+ };
CellToolbar.global_show = function () {
- $('body').addClass('ctb_show');
- }
+ $('body').addClass('ctb_global_show');
+ };
CellToolbar.prototype.hide = function () {
this.element.removeClass('ctb_show');
- }
+ };
CellToolbar.prototype.show = function () {
this.element.addClass('ctb_show');
- }
+ };
/**
- * Class variable that should contain a dict of all availlable callback
+ * Class variable that should contain a dict of all available callback
* we need to think of wether or not we allow nested namespace
* @property _callback_dict
* @private
@@ -89,7 +91,7 @@ var IPython = (function (IPython) {
/**
- * Class variable that should contains the CellToolbar instances for each
+ * Class variable that should contain the CellToolbar instances for each
* cell of the notebook
*
* @private
@@ -97,17 +99,17 @@ var IPython = (function (IPython) {
* @static
* @type List
*/
- CellToolbar._instances =[]
+ CellToolbar._instances = [];
/**
- * keep a list of all the availlabel presets for the toolbar
+ * keep a list of all the available presets for the toolbar
* @private
* @property _presets
* @static
* @type Dict
*/
- CellToolbar._presets ={}
+ CellToolbar._presets = {};
// this is by design not a prototype.
@@ -180,7 +182,7 @@ var IPython = (function (IPython) {
* CellToolbar.register_preset('foo.foo_preset2', ['foo.c4', 'foo.c5'])
*/
CellToolbar.register_preset = function(name, preset_list) {
- CellToolbar._presets[name] = preset_list
+ CellToolbar._presets[name] = preset_list;
$([IPython.events]).trigger('preset_added.CellToolbar', {name: name});
};
@@ -217,11 +219,11 @@ var IPython = (function (IPython) {
CellToolbar.activate_preset = function(preset_name){
var preset = CellToolbar._presets[preset_name];
- if(preset != undefined){
+ if(preset !== undefined){
CellToolbar._ui_controls_list = preset;
CellToolbar.rebuild_all();
}
- }
+ };
/**
@@ -235,29 +237,37 @@ var IPython = (function (IPython) {
for(var i in CellToolbar._instances){
CellToolbar._instances[i].rebuild();
}
- }
+ };
/**
- * Rebuild all the button on the toolbar to update it's state.
+ * Rebuild all the button on the toolbar to update its state.
* @method rebuild
*/
CellToolbar.prototype.rebuild = function(){
// strip evrything from the div
- // which is probabli metainner.
+ // which is probably inner_element
// or this.element.
this.inner_element.empty();
- var cdict = CellToolbar._callback_dict;
+ var callbacks = CellToolbar._callback_dict;
var preset = CellToolbar._ui_controls_list;
- // Yes we iterate on the class varaible, not the instance one.
- for ( var index in CellToolbar._ui_controls_list){
+ // Yes we iterate on the class variable, not the instance one.
+ for (var index in preset) {
+ var key = preset[index];
+ var callback = callbacks[key];
+ if (!callback) continue;
+
var local_div = $('').addClass('button_container');
- // Note,
- // do this the other way, wrap in try/catch and don't append if any errors.
- this.inner_element.append(local_div)
- cdict[preset[index]](local_div, this.cell)
+ try {
+ callback(local_div, this.cell, this);
+ } catch (e) {
+ console.log("Error in cell toolbar callback " + key, e);
+ continue;
+ }
+ // only append if callback succeeded.
+ this.inner_element.append(local_div);
}
- }
+ };
/**
@@ -303,8 +313,8 @@ var IPython = (function (IPython) {
*
*/
CellToolbar.utils.checkbox_ui_generator = function(name, setter, getter){
- return function(div, cell) {
- var button_container = $(div)
+ return function(div, cell, celltoolbar) {
+ var button_container = $(div);
var chkb = $('').attr('type', 'checkbox');
var lbl = $('').append($('').text(name));
@@ -315,11 +325,10 @@ var IPython = (function (IPython) {
var v = getter(cell);
setter(cell, !v);
chkb.attr("checked", !v);
- })
- button_container.append($('').append(lbl));
-
- }
- }
+ });
+ button_container.append($('').append(lbl));
+ };
+ };
/**
@@ -365,16 +374,16 @@ var IPython = (function (IPython) {
* CellToolbar.register_callback('slideshow.select', select_type);
*
*/
- CellToolbar.utils.select_ui_generator = function(list_list, setter, getter, label){
- label= label? label: "";
- return function(div, cell) {
- var button_container = $(div)
+ CellToolbar.utils.select_ui_generator = function(list_list, setter, getter, label, cell_types){
+ label = label || "";
+ return function(div, cell, celltoolbar) {
+ var button_container = $(div);
var lbl = $("").append($('').text(label));
var select = $('').addClass('ui-widget ui-widget-content');
for(var itemn in list_list){
- var opt = $('');
- opt.attr('value', list_list[itemn][1])
- opt.text(list_list[itemn][0])
+ var opt = $('')
+ .attr('value', list_list[itemn][1])
+ .text(list_list[itemn][0]);
select.append(opt);
}
select.val(getter(cell));
@@ -382,8 +391,13 @@ var IPython = (function (IPython) {
setter(cell, select.val());
});
button_container.append($('').append(lbl).append(select));
+ if (cell_types && cell_types.indexOf(cell.cell_type) == -1) {
+ celltoolbar.hide();
+ } else {
+ celltoolbar.show();
+ }
- }
+ };
};
diff --git a/IPython/html/static/notebook/js/celltoolbarpresets/default.js b/IPython/html/static/notebook/js/celltoolbarpresets/default.js
index fb1ae46..74210ca 100644
--- a/IPython/html/static/notebook/js/celltoolbarpresets/default.js
+++ b/IPython/html/static/notebook/js/celltoolbarpresets/default.js
@@ -28,7 +28,7 @@
var button_container = div;
var button = $('')
.addClass("btn btn-mini")
- .text("Raw Edit")
+ .text("Edit Metadata")
.click( function () {
raw_edit(cell);
return false;
@@ -40,7 +40,7 @@
var example_preset = [];
example_preset.push('default.rawedit');
- CellToolbar.register_preset('Default', example_preset);
- console.log('Default extension for metadata editing loaded.');
+ CellToolbar.register_preset('Edit Metadata', example_preset);
+ console.log('Default extension for cell metadata editing loaded.');
}(IPython));
diff --git a/IPython/html/static/notebook/js/celltoolbarpresets/rawcell.js b/IPython/html/static/notebook/js/celltoolbarpresets/rawcell.js
new file mode 100644
index 0000000..3d51798
--- /dev/null
+++ b/IPython/html/static/notebook/js/celltoolbarpresets/rawcell.js
@@ -0,0 +1,90 @@
+//----------------------------------------------------------------------------
+// Copyright (C) 2012 The IPython Development Team
+//
+// Distributed under the terms of the BSD License. The full license is in
+// the file COPYING, distributed as part of this software.
+//----------------------------------------------------------------------------
+
+//============================================================================
+// CellToolbar Example
+//============================================================================
+
+(function(IPython) {
+ "use strict";
+
+ var CellToolbar = IPython.CellToolbar;
+ var raw_cell_preset = [];
+ var utils = IPython.utils;
+
+ var select_type = CellToolbar.utils.select_ui_generator([
+ ["None", "-"],
+ ["LaTeX", "text/latex"],
+ ["reST", "text/restructuredtext"],
+ ["HTML", "text/html"],
+ ["Markdown", "text/markdown"],
+ ["Python", "application/x-python"],
+ ["Custom", "dialog"],
+
+ ],
+ // setter
+ function(cell, value) {
+ if (value === "-") {
+ delete cell.metadata.raw_mimetype;
+ } else if (value === 'dialog'){
+ var dialog = $('').append(
+ $("")
+ .html("Set the MIME type of the raw cell:")
+ ).append(
+ $("
")
+ ).append(
+ $('').attr('type','text').attr('size','25')
+ .val(cell.metadata.raw_mimetype || "-")
+ );
+ IPython.dialog.modal({
+ title: "Raw Cell MIME Type",
+ body: dialog,
+ buttons : {
+ "Cancel": {},
+ "OK": {
+ class: "btn-primary",
+ click: function () {
+ console.log(cell);
+ cell.metadata.raw_mimetype = $(this).find('input').val();
+ console.log(cell.metadata);
+ }
+ }
+ },
+ open : function (event, ui) {
+ var that = $(this);
+ // Upon ENTER, click the OK button.
+ that.find('input[type="text"]').keydown(function (event, ui) {
+ if (event.which === utils.keycodes.ENTER) {
+ that.find('.btn-primary').first().click();
+ return false;
+ }
+ });
+ that.find('input[type="text"]').focus().select();
+ }
+ });
+ } else {
+ cell.metadata.raw_mimetype = value;
+ }
+ },
+ //getter
+ function(cell) {
+ return cell.metadata.raw_mimetype || "";
+ },
+ // name
+ "Raw NBConvert Format",
+ // cell_types
+ ["raw"]
+ );
+
+ CellToolbar.register_callback('raw_cell.select', select_type);
+
+ raw_cell_preset.push('raw_cell.select');
+
+ CellToolbar.register_preset('Raw Cell Format', raw_cell_preset);
+ console.log('Raw Cell Format toolbar preset loaded.');
+
+}(IPython));
\ No newline at end of file
diff --git a/IPython/html/static/notebook/js/codecell.js b/IPython/html/static/notebook/js/codecell.js
index 63a4e69..132b3ab 100644
--- a/IPython/html/static/notebook/js/codecell.js
+++ b/IPython/html/static/notebook/js/codecell.js
@@ -445,7 +445,6 @@ var IPython = (function (IPython) {
CodeCell.prototype.toJSON = function () {
var data = IPython.Cell.prototype.toJSON.apply(this);
data.input = this.get_text();
- data.cell_type = 'code';
// is finite protect against undefined and '*' value
if (isFinite(this.input_prompt_number)) {
data.prompt_number = this.input_prompt_number;
diff --git a/IPython/html/static/notebook/js/maintoolbar.js b/IPython/html/static/notebook/js/maintoolbar.js
index 1586055..58e51f7 100644
--- a/IPython/html/static/notebook/js/maintoolbar.js
+++ b/IPython/html/static/notebook/js/maintoolbar.js
@@ -119,7 +119,7 @@ var IPython = (function (IPython) {
// .addClass('ui-widget-content')
.append($('').attr('value','code').text('Code'))
.append($('').attr('value','markdown').text('Markdown'))
- .append($('').attr('value','raw').text('Raw Text'))
+ .append($('').attr('value','raw').text('Raw NBConvert'))
.append($('').attr('value','heading1').text('Heading 1'))
.append($('').attr('value','heading2').text('Heading 2'))
.append($('').attr('value','heading3').text('Heading 3'))
diff --git a/IPython/html/static/notebook/js/textcell.js b/IPython/html/static/notebook/js/textcell.js
index d3e74ff..cf7f003 100644
--- a/IPython/html/static/notebook/js/textcell.js
+++ b/IPython/html/static/notebook/js/textcell.js
@@ -46,11 +46,11 @@ var IPython = (function (IPython) {
options = this.mergeopt(TextCell,options,{cm_config:cm_overwrite_options});
- IPython.Cell.apply(this, [options]);
+ this.cell_type = this.cell_type || 'text';
+ IPython.Cell.apply(this, [options]);
this.rendered = false;
- this.cell_type = this.cell_type || 'text';
};
TextCell.prototype = new IPython.Cell();
@@ -279,8 +279,10 @@ var IPython = (function (IPython) {
*/
TextCell.prototype.toJSON = function () {
var data = IPython.Cell.prototype.toJSON.apply(this);
- data.cell_type = this.cell_type;
data.source = this.get_text();
+ if (data.source == this.placeholder) {
+ data.source = "";
+ }
return data;
};
@@ -291,12 +293,10 @@ var IPython = (function (IPython) {
* @extends IPython.HTMLCell
*/
var MarkdownCell = function (options) {
- var options = options || {};
-
- options = this.mergeopt(MarkdownCell,options);
- TextCell.apply(this, [options]);
+ options = this.mergeopt(MarkdownCell, options);
this.cell_type = 'markdown';
+ TextCell.apply(this, [options]);
};
MarkdownCell.options_default = {
@@ -337,7 +337,7 @@ var IPython = (function (IPython) {
}
this.element.find('div.text_cell_input').hide();
this.element.find("div.text_cell_render").show();
- this.typeset()
+ this.typeset();
this.rendered = true;
}
};
@@ -351,20 +351,21 @@ var IPython = (function (IPython) {
* @extends IPython.TextCell
*/
var RawCell = function (options) {
-
- options = this.mergeopt(RawCell,options)
- TextCell.apply(this, [options]);
-
+ options = this.mergeopt(RawCell, options);
+
this.cell_type = 'raw';
+ TextCell.apply(this, [options]);
- var that = this
+ var that = this;
this.element.focusout(
function() { that.auto_highlight(); }
- );
+ );
};
RawCell.options_default = {
- placeholder : "Type plain text and LaTeX: $\\alpha^2$"
+ placeholder : "Write raw LaTeX or other formats here, for use with nbconvert.\n" +
+ "It will not be rendered in the notebook.\n" +
+ "When passing through nbconvert, a Raw Cell's content is added to the output unmodified."
};
@@ -382,7 +383,10 @@ var IPython = (function (IPython) {
/** @method render **/
RawCell.prototype.render = function () {
this.rendered = true;
- this.edit();
+ var text = this.get_text();
+ if (text === "") { text = this.placeholder; }
+ console.log('rendering', text);
+ this.set_text(text);
};
@@ -415,8 +419,7 @@ var IPython = (function (IPython) {
/** @method select **/
RawCell.prototype.select = function () {
IPython.Cell.prototype.select.apply(this);
- this.code_mirror.refresh();
- this.code_mirror.focus();
+ this.edit();
};
/** @method at_top **/
@@ -451,16 +454,16 @@ var IPython = (function (IPython) {
* @extends IPython.TextCell
*/
var HeadingCell = function (options) {
+ options = this.mergeopt(HeadingCell, options);
- options = this.mergeopt(HeadingCell,options)
+ this.level = 1;
+ this.cell_type = 'heading';
TextCell.apply(this, [options]);
/**
* heading level of the cell, use getter and setter to access
* @property level
*/
- this.level = 1;
- this.cell_type = 'heading';
};
HeadingCell.options_default = {
diff --git a/IPython/html/static/notebook/less/celltoolbar.less b/IPython/html/static/notebook/less/celltoolbar.less
index 4c1ef6b..057b40b 100644
--- a/IPython/html/static/notebook/less/celltoolbar.less
+++ b/IPython/html/static/notebook/less/celltoolbar.less
@@ -1,12 +1,10 @@
-/* Css for the metadata edit area */
-
+/* CSS for the cell toolbar */
.celltoolbar {
border: thin solid #CFCFCF;
border-bottom: none;
background : #EEE;
- border-top-right-radius: 3px;
- border-top-left-radius: 3px;
+ border-radius : 3px 3px 0px 0px;
width:100%;
-webkit-box-pack: end;
height:22px;
@@ -14,20 +12,6 @@
.reverse();
}
-
-.no_input_radius {
- border-top-right-radius: 0px;
- border-top-left-radius: 0px;
-}
-
-.text_cell .ctb_prompt {
- display: none;
-}
-
-.code_cell .ctb_prompt {
- display: block;
-}
-
.ctb_hideshow {
display:none;
vertical-align:bottom;
@@ -38,41 +22,21 @@
padding-top: 0px;
}
-.ctb_area {
- margin:0;
- padding:0;
- width:100%;
-}
-
-
-/*ctb_show is added to either body or the ctb_hideshow div to show
-all or one cell's toolbars.
+/* ctb_show is added to the ctb_hideshow div to show the cell toolbar.
+ Cell toolbars are only shown when the ctb_global_show class is also set.
*/
-.ctb_show.ctb_hideshow, .ctb_show .ctb_hideshow {
- display:block;
+.ctb_global_show .ctb_show.ctb_hideshow {
+ display: block;
}
-.ctb_show .input_area,
-.ctb_show .ctb_hideshow + div.text_cell_input {
+.ctb_global_show .ctb_show + .input_area,
+.ctb_global_show .ctb_show + div.text_cell_input
+{
border-top-right-radius: 0px;
border-top-left-radius: 0px;
}
-.ctb_show > .celltoolbar {
- border-bottom-right-radius: 0px;
- border-bottom-left-radius: 0px;
-}
-
-.button_container {
- margin-top:0;
- margin-bottom:0;
-}
-
-
-.ui-button {
- min-width:30px;
-}
.celltoolbar .button_container select {
margin: 10px;
margin-top: 1px;
@@ -108,4 +72,5 @@ all or one cell's toolbars.
border: none;
vertical-align:top;
height:20px;
+ min-width:30px;
}
diff --git a/IPython/html/static/style/style.min.css b/IPython/html/static/style/style.min.css
index ac1857a..52b6368 100644
--- a/IPython/html/static/style/style.min.css
+++ b/IPython/html/static/style/style.min.css
@@ -1537,23 +1537,16 @@ pre,code,kbd,samp{white-space:pre-wrap;}
#fonttest{font-family:monospace;}
p{margin-bottom:0;}
.end_space{height:200px;}
-.celltoolbar{border:thin solid #CFCFCF;border-bottom:none;background:#EEE;border-top-right-radius:3px;border-top-left-radius:3px;width:100%;-webkit-box-pack:end;height:22px;display:-webkit-box;-webkit-box-orient:horizontal;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:horizontal;-moz-box-align:stretch;display:box;box-orient:horizontal;box-align:stretch;-webkit-box-direction:reverse;-moz-box-direction:reverse;box-direction:reverse;}
-.no_input_radius{border-top-right-radius:0px;border-top-left-radius:0px;}
-.text_cell .ctb_prompt{display:none;}
-.code_cell .ctb_prompt{display:block;}
+.celltoolbar{border:thin solid #CFCFCF;border-bottom:none;background:#EEE;border-radius:3px 3px 0px 0px;width:100%;-webkit-box-pack:end;height:22px;display:-webkit-box;-webkit-box-orient:horizontal;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:horizontal;-moz-box-align:stretch;display:box;box-orient:horizontal;box-align:stretch;-webkit-box-direction:reverse;-moz-box-direction:reverse;box-direction:reverse;}
.ctb_hideshow{display:none;vertical-align:bottom;padding-right:2px;}
.celltoolbar>div{padding-top:0px;}
-.ctb_area{margin:0;padding:0;width:100%;}
-.ctb_show.ctb_hideshow,.ctb_show .ctb_hideshow{display:block;}
-.ctb_show .input_area,.ctb_show .ctb_hideshow+div.text_cell_input{border-top-right-radius:0px;border-top-left-radius:0px;}
-.ctb_show>.celltoolbar{border-bottom-right-radius:0px;border-bottom-left-radius:0px;}
-.button_container{margin-top:0;margin-bottom:0;}
-.ui-button{min-width:30px;}
+.ctb_global_show .ctb_show.ctb_hideshow{display:block;}
+.ctb_global_show .ctb_show+.input_area,.ctb_global_show .ctb_show+div.text_cell_input{border-top-right-radius:0px;border-top-left-radius:0px;}
.celltoolbar .button_container select{margin:10px;margin-top:1px;margin-bottom:0px;padding:0;font-size:87%;width:auto;display:inline-block;height:18px;line-height:18px;vertical-align:top;}
.celltoolbar label{display:inline-block;height:15px;line-height:15px;vertical-align:top;}
.celltoolbar label span{font-size:85%;}
.celltoolbar input[type=checkbox]{margin:0px;margin-left:4px;margin-right:4px;}
-.celltoolbar .ui-button{border:none;vertical-align:top;height:20px;}
+.celltoolbar .ui-button{border:none;vertical-align:top;height:20px;min-width:30px;}
.completions{position:absolute;z-index:10;overflow:hidden;border:1px solid #ababab;border-radius:4px;-webkit-box-shadow:0px 6px 10px -1px #adadad;-moz-box-shadow:0px 6px 10px -1px #adadad;box-shadow:0px 6px 10px -1px #adadad;}
.completions select{background:white;outline:none;border:none;padding:0px;margin:0px;overflow:auto;font-family:monospace;font-size:110%;color:#000000;}
.completions select option.context{color:#0064cd;}
diff --git a/IPython/html/templates/notebook.html b/IPython/html/templates/notebook.html
index 06c699b..ae73841 100644
--- a/IPython/html/templates/notebook.html
+++ b/IPython/html/templates/notebook.html
@@ -157,8 +157,8 @@ class="notebook_app"
title="Contents will be rendered as HTML and serve as explanatory text">
Markdown
- Raw Text
+ title="Contents will pass through nbconvert unmodified">
+ Raw NBConvert
Heading 1
Heading 2
Heading 3
@@ -297,6 +297,7 @@ class="notebook_app"
+
{% endblock %}
diff --git a/IPython/nbconvert/exporters/exporter.py b/IPython/nbconvert/exporters/exporter.py
index 5419965..3a594d0 100644
--- a/IPython/nbconvert/exporters/exporter.py
+++ b/IPython/nbconvert/exporters/exporter.py
@@ -1,5 +1,5 @@
-"""This module defines Exporter, a highly configurable converter
-that uses Jinja2 to export notebook files into different formats.
+"""This module defines a base Exporter class. For Jinja template-based export,
+see templateexporter.py.
"""
#-----------------------------------------------------------------------------
diff --git a/IPython/nbconvert/exporters/html.py b/IPython/nbconvert/exporters/html.py
index f65b65b..bb63397 100644
--- a/IPython/nbconvert/exporters/html.py
+++ b/IPython/nbconvert/exporters/html.py
@@ -1,6 +1,4 @@
-"""
-Exporter that exports Basic HTML.
-"""
+"""HTML Exporter class"""
#-----------------------------------------------------------------------------
# Copyright (c) 2013, the IPython Development Team.
@@ -40,7 +38,10 @@ class HTMLExporter(TemplateExporter):
default_template = Unicode('full', config=True, help="""Flavor of the data
format to use. I.E. 'full' or 'basic'""")
-
+
+ def _raw_mimetype_default(self):
+ return 'text/html'
+
@property
def default_config(self):
c = Config({
diff --git a/IPython/nbconvert/exporters/latex.py b/IPython/nbconvert/exporters/latex.py
index 6d40c5f..a095262 100644
--- a/IPython/nbconvert/exporters/latex.py
+++ b/IPython/nbconvert/exporters/latex.py
@@ -1,9 +1,5 @@
-"""
-Exporter that allows Latex Jinja templates to work. Contains logic to
-appropriately prepare IPYNB files for export to LaTeX. Including but
-not limited to escaping LaTeX, fixing math region tags, using special
-tags to circumvent Jinja/Latex syntax conflicts.
-"""
+"""LaTeX Exporter class"""
+
#-----------------------------------------------------------------------------
# Copyright (c) 2013, the IPython Development Team.
#
@@ -67,6 +63,9 @@ class LatexExporter(TemplateExporter):
#Extension that the template files use.
template_extension = Unicode(".tplx", config=True)
+ def _raw_mimetype_default(self):
+ return 'text/latex'
+
@property
def default_config(self):
diff --git a/IPython/nbconvert/exporters/markdown.py b/IPython/nbconvert/exporters/markdown.py
index b556542..fb38539 100644
--- a/IPython/nbconvert/exporters/markdown.py
+++ b/IPython/nbconvert/exporters/markdown.py
@@ -1,6 +1,5 @@
-"""
-Exporter that will export your ipynb to Markdown.
-"""
+"""Markdown Exporter class"""
+
#-----------------------------------------------------------------------------
# Copyright (c) 2013, the IPython Development Team.
#
@@ -31,6 +30,12 @@ class MarkdownExporter(TemplateExporter):
'md', config=True,
help="Extension of the file that should be written to disk")
+ def _raw_mimetype_default(self):
+ return 'text/markdown'
+
+ def _raw_mimetypes_default(self):
+ return ['text/markdown', 'text/html']
+
@property
def default_config(self):
c = Config({'ExtractOutputPreprocessor':{'enabled':True}})
diff --git a/IPython/nbconvert/exporters/python.py b/IPython/nbconvert/exporters/python.py
index a3b4751..1d13bc3 100644
--- a/IPython/nbconvert/exporters/python.py
+++ b/IPython/nbconvert/exporters/python.py
@@ -1,6 +1,5 @@
-"""
-Python exporter which exports Notebook code into a PY file.
-"""
+"""Python script Exporter class"""
+
#-----------------------------------------------------------------------------
# Copyright (c) 2013, the IPython Development Team.
#
@@ -29,3 +28,7 @@ class PythonExporter(TemplateExporter):
file_extension = Unicode(
'py', config=True,
help="Extension of the file that should be written to disk")
+
+ def _raw_mimetype_default(self):
+ return 'application/x-python'
+
diff --git a/IPython/nbconvert/exporters/rst.py b/IPython/nbconvert/exporters/rst.py
index e9ac174..22dfc82 100644
--- a/IPython/nbconvert/exporters/rst.py
+++ b/IPython/nbconvert/exporters/rst.py
@@ -1,6 +1,5 @@
-"""
-Exporter for exporting notebooks to restructured text.
-"""
+"""restructuredText Exporter class"""
+
#-----------------------------------------------------------------------------
# Copyright (c) 2013, the IPython Development Team.
#
@@ -31,6 +30,9 @@ class RSTExporter(TemplateExporter):
'rst', config=True,
help="Extension of the file that should be written to disk")
+ def _raw_mimetype_default(self):
+ return 'text/restructuredtext'
+
@property
def default_config(self):
c = Config({'ExtractOutputPreprocessor':{'enabled':True}})
diff --git a/IPython/nbconvert/exporters/slides.py b/IPython/nbconvert/exporters/slides.py
index 39b083c..6ecb5a9 100644
--- a/IPython/nbconvert/exporters/slides.py
+++ b/IPython/nbconvert/exporters/slides.py
@@ -1,6 +1,4 @@
-"""
-Contains slide show exporter
-"""
+"""HTML slide show Exporter class"""
#-----------------------------------------------------------------------------
# Copyright (c) 2013, the IPython Development Team.
@@ -19,16 +17,14 @@ from IPython.utils.traitlets import Unicode
from IPython.nbconvert import preprocessors
from IPython.config import Config
-from .templateexporter import TemplateExporter
+from .html import HTMLExporter
#-----------------------------------------------------------------------------
# Classes
#-----------------------------------------------------------------------------
-class SlidesExporter(TemplateExporter):
- """
- Exports slides
- """
+class SlidesExporter(HTMLExporter):
+ """Exports HTML slides with reveal.js"""
file_extension = Unicode(
'slides.html', config=True,
@@ -41,15 +37,9 @@ class SlidesExporter(TemplateExporter):
@property
def default_config(self):
c = Config({
- 'CSSHTMLHeaderPreprocessor':{
- 'enabled':True
+ 'RevealHelpPreprocessor': {
+ 'enabled': True,
},
- 'RevealHelpPreprocessor':{
- 'enabled':True,
- },
- 'HighlightMagicsPreprocessor': {
- 'enabled':True
- }
})
c.merge(super(SlidesExporter,self).default_config)
return c
diff --git a/IPython/nbconvert/exporters/templateexporter.py b/IPython/nbconvert/exporters/templateexporter.py
index cbc80e9..a5eed82 100644
--- a/IPython/nbconvert/exporters/templateexporter.py
+++ b/IPython/nbconvert/exporters/templateexporter.py
@@ -1,4 +1,4 @@
-"""This module defines Exporter, a highly configurable converter
+"""This module defines TemplateExporter, a highly configurable converter
that uses Jinja2 to export notebook files into different formats.
"""
@@ -126,6 +126,13 @@ class TemplateExporter(Exporter):
help="""Dictionary of filters, by name and namespace, to add to the Jinja
environment.""")
+ raw_mimetype = Unicode('')
+ raw_mimetypes = List(config=True,
+ help="""formats of raw cells to be included in this Exporter's output."""
+ )
+ def _raw_mimetypes_default(self):
+ return [self.raw_mimetype]
+
def __init__(self, config=None, extra_loaders=None, **kw):
"""
@@ -202,6 +209,8 @@ class TemplateExporter(Exporter):
preprocessors and filters.
"""
nb_copy, resources = super(TemplateExporter, self).from_notebook_node(nb, resources, **kw)
+ resources.setdefault('raw_mimetype', self.raw_mimetype)
+ resources.setdefault('raw_mimetypes', self.raw_mimetypes)
self._load_template()
diff --git a/IPython/nbconvert/exporters/tests/base.py b/IPython/nbconvert/exporters/tests/base.py
index 18ae21d..9db1caa 100644
--- a/IPython/nbconvert/exporters/tests/base.py
+++ b/IPython/nbconvert/exporters/tests/base.py
@@ -1,6 +1,4 @@
-"""
-Module with tests base for exporters
-"""
+"""Base TestCase class for testing Exporters"""
#-----------------------------------------------------------------------------
# Copyright (c) 2013, the IPython Development Team.
@@ -16,15 +14,41 @@ Module with tests base for exporters
import os
+from IPython.testing.decorators import onlyif_cmds_exist
+
from ...tests.base import TestsBase
#-----------------------------------------------------------------------------
# Class
#-----------------------------------------------------------------------------
+all_raw_mimetypes = {
+ 'application/x-python',
+ 'text/markdown',
+ 'text/html',
+ 'text/restructuredtext',
+ 'text/latex',
+}
+
class ExportersTestsBase(TestsBase):
"""Contains base test functions for exporters"""
-
- def _get_notebook(self):
- return os.path.join(self._get_files_path(), 'notebook2.ipynb')
-
+
+ exporter_class = None
+ should_include_raw = None
+
+ def _get_notebook(self, nb_name='notebook2.ipynb'):
+ return os.path.join(self._get_files_path(), nb_name)
+
+ @onlyif_cmds_exist('pandoc')
+ def test_raw_cell_inclusion(self):
+ """test raw cell inclusion based on raw_mimetype metadata"""
+ if self.should_include_raw is None:
+ return
+ exporter = self.exporter_class()
+ (output, resources) = exporter.from_filename(self._get_notebook('rawtest.ipynb'))
+ for inc in self.should_include_raw:
+ self.assertIn('raw %s' % inc, output, "should include %s" % inc)
+ self.assertIn('no raw_mimetype metadata', output)
+ for exc in all_raw_mimetypes.difference(self.should_include_raw):
+ self.assertNotIn('raw %s' % exc, output, "should exclude %s" % exc)
+ self.assertNotIn('never be included', output)
diff --git a/IPython/nbconvert/exporters/tests/files/rawtest.ipynb b/IPython/nbconvert/exporters/tests/files/rawtest.ipynb
new file mode 100644
index 0000000..667ddbf
--- /dev/null
+++ b/IPython/nbconvert/exporters/tests/files/rawtest.ipynb
@@ -0,0 +1,84 @@
+{
+ "metadata": {
+ "name": ""
+ },
+ "nbformat": 3,
+ "nbformat_minor": 0,
+ "worksheets": [
+ {
+ "cells": [
+ {
+ "cell_type": "raw",
+ "metadata": {
+ "raw_mimetype": "text/html"
+ },
+ "source": [
+ "raw html"
+ ]
+ },
+ {
+ "cell_type": "raw",
+ "metadata": {
+ "raw_mimetype": "text/markdown"
+ },
+ "source": [
+ "* raw markdown\n",
+ "* bullet\n",
+ "* list"
+ ]
+ },
+ {
+ "cell_type": "raw",
+ "metadata": {
+ "raw_mimetype": "text/restructuredtext"
+ },
+ "source": [
+ "``raw rst``\n",
+ "\n",
+ ".. sourcecode:: python\n",
+ "\n",
+ " def foo(): pass\n"
+ ]
+ },
+ {
+ "cell_type": "raw",
+ "metadata": {
+ "raw_mimetype": "application/x-python"
+ },
+ "source": [
+ "def bar():\n",
+ " \"\"\"raw python\"\"\"\n",
+ " pass"
+ ]
+ },
+ {
+ "cell_type": "raw",
+ "metadata": {
+ "raw_mimetype": "text/latex"
+ },
+ "source": [
+ "\\LaTeX\n",
+ "% raw latex"
+ ]
+ },
+ {
+ "cell_type": "raw",
+ "metadata": {},
+ "source": [
+ "# no raw_mimetype metadata, should be included by default"
+ ]
+ },
+ {
+ "cell_type": "raw",
+ "metadata": {
+ "raw_mimetype": "doesnotexist"
+ },
+ "source": [
+ "garbage format defined, should never be included"
+ ]
+ }
+ ],
+ "metadata": {}
+ }
+ ]
+}
\ No newline at end of file
diff --git a/IPython/nbconvert/exporters/tests/test_html.py b/IPython/nbconvert/exporters/tests/test_html.py
index 10c41ba..f2c9f6c 100644
--- a/IPython/nbconvert/exporters/tests/test_html.py
+++ b/IPython/nbconvert/exporters/tests/test_html.py
@@ -1,6 +1,4 @@
-"""
-Module with tests for html.py
-"""
+"""Tests for HTMLExporter"""
#-----------------------------------------------------------------------------
# Copyright (c) 2013, the IPython Development Team.
@@ -23,7 +21,10 @@ from IPython.testing.decorators import onlyif_cmds_exist
#-----------------------------------------------------------------------------
class TestHTMLExporter(ExportersTestsBase):
- """Contains test functions for html.py"""
+ """Tests for HTMLExporter"""
+
+ exporter_class = HTMLExporter
+ should_include_raw = ['html']
def test_constructor(self):
"""
@@ -57,3 +58,4 @@ class TestHTMLExporter(ExportersTestsBase):
"""
(output, resources) = HTMLExporter(template_file='full').from_filename(self._get_notebook())
assert len(output) > 0
+
diff --git a/IPython/nbconvert/exporters/tests/test_latex.py b/IPython/nbconvert/exporters/tests/test_latex.py
index f1dc349..3ddc1b0 100644
--- a/IPython/nbconvert/exporters/tests/test_latex.py
+++ b/IPython/nbconvert/exporters/tests/test_latex.py
@@ -25,6 +25,9 @@ from IPython.testing.decorators import onlyif_cmds_exist
class TestLatexExporter(ExportersTestsBase):
"""Contains test functions for latex.py"""
+ exporter_class = LatexExporter
+ should_include_raw = ['latex']
+
def test_constructor(self):
"""
Can a LatexExporter be constructed?
diff --git a/IPython/nbconvert/exporters/tests/test_markdown.py b/IPython/nbconvert/exporters/tests/test_markdown.py
index 53a8126..1da8ed5 100644
--- a/IPython/nbconvert/exporters/tests/test_markdown.py
+++ b/IPython/nbconvert/exporters/tests/test_markdown.py
@@ -1,6 +1,4 @@
-"""
-Module with tests for markdown.py
-"""
+"""Tests for MarkdownExporter"""
#-----------------------------------------------------------------------------
# Copyright (c) 2013, the IPython Development Team.
@@ -22,7 +20,10 @@ from ..markdown import MarkdownExporter
#-----------------------------------------------------------------------------
class TestMarkdownExporter(ExportersTestsBase):
- """Contains test functions for markdown.py"""
+ """Tests for MarkdownExporter"""
+
+ exporter_class = MarkdownExporter
+ should_include_raw = ['markdown', 'html']
def test_constructor(self):
"""
diff --git a/IPython/nbconvert/exporters/tests/test_python.py b/IPython/nbconvert/exporters/tests/test_python.py
index 3fc4cf6..7798b81 100644
--- a/IPython/nbconvert/exporters/tests/test_python.py
+++ b/IPython/nbconvert/exporters/tests/test_python.py
@@ -1,6 +1,4 @@
-"""
-Module with tests for python.py
-"""
+"""Tests for PythonExporter"""
#-----------------------------------------------------------------------------
# Copyright (c) 2013, the IPython Development Team.
@@ -22,7 +20,10 @@ from ..python import PythonExporter
#-----------------------------------------------------------------------------
class TestPythonExporter(ExportersTestsBase):
- """Contains test functions for python.py"""
+ """Tests for PythonExporter"""
+
+ exporter_class = PythonExporter
+ should_include_raw = ['python']
def test_constructor(self):
"""
diff --git a/IPython/nbconvert/exporters/tests/test_rst.py b/IPython/nbconvert/exporters/tests/test_rst.py
index 6634f7b..99e3e76 100644
--- a/IPython/nbconvert/exporters/tests/test_rst.py
+++ b/IPython/nbconvert/exporters/tests/test_rst.py
@@ -1,6 +1,4 @@
-"""
-Module with tests for rst.py
-"""
+"""Tests for RSTExporter"""
#-----------------------------------------------------------------------------
# Copyright (c) 2013, the IPython Development Team.
@@ -23,7 +21,10 @@ from IPython.testing.decorators import onlyif_cmds_exist
#-----------------------------------------------------------------------------
class TestRSTExporter(ExportersTestsBase):
- """Contains test functions for rst.py"""
+ """Tests for RSTExporter"""
+
+ exporter_class = RSTExporter
+ should_include_raw = ['rst']
def test_constructor(self):
"""
diff --git a/IPython/nbconvert/exporters/tests/test_slides.py b/IPython/nbconvert/exporters/tests/test_slides.py
index 9b2c496..7c7d008 100644
--- a/IPython/nbconvert/exporters/tests/test_slides.py
+++ b/IPython/nbconvert/exporters/tests/test_slides.py
@@ -1,6 +1,4 @@
-"""
-Module with tests for slides.py
-"""
+"""Tests for SlidesExporter"""
#-----------------------------------------------------------------------------
# Copyright (c) 2013, the IPython Development Team.
@@ -23,7 +21,10 @@ from IPython.testing.decorators import onlyif_cmds_exist
#-----------------------------------------------------------------------------
class TestSlidesExporter(ExportersTestsBase):
- """Contains test functions for slides.py"""
+ """Tests for SlidesExporter"""
+
+ exporter_class = SlidesExporter
+ should_include_raw = ['html']
def test_constructor(self):
"""
diff --git a/IPython/nbconvert/templates/html_basic.tpl b/IPython/nbconvert/templates/html_basic.tpl
index fd97f03..543beee 100644
--- a/IPython/nbconvert/templates/html_basic.tpl
+++ b/IPython/nbconvert/templates/html_basic.tpl
@@ -65,10 +65,6 @@ In [{{ cell.prompt_number }}]:
{% endblock headingcell %}
-{% block rawcell scoped %}
-{{ cell.source }}
-{% endblock rawcell %}
-
{% block unknowncell scoped %}
unknown type {{ cell.type }}
{% endblock unknowncell %}
diff --git a/IPython/nbconvert/templates/latex/latex_base.tplx b/IPython/nbconvert/templates/latex/latex_base.tplx
index 0ad51fa..97a67a5 100644
--- a/IPython/nbconvert/templates/latex/latex_base.tplx
+++ b/IPython/nbconvert/templates/latex/latex_base.tplx
@@ -218,11 +218,6 @@ This template does not define a docclass, the inheriting class must define this.
((( cell.source | citation2latex | markdown2latex )))
((* endblock markdowncell *))
-% Spit out the contents of raw cells unmodified
-((* block rawcell scoped *))
- ((( cell.source )))
-((* endblock rawcell *))
-
% Don't display unknown types
((* block unknowncell scoped *))
((* endblock unknowncell *))
diff --git a/IPython/nbconvert/templates/latex/skeleton/null.tplx b/IPython/nbconvert/templates/latex/skeleton/null.tplx
index 33bc591..5f8909b 100644
--- a/IPython/nbconvert/templates/latex/skeleton/null.tplx
+++ b/IPython/nbconvert/templates/latex/skeleton/null.tplx
@@ -80,7 +80,10 @@ consider calling super even if it is a leave block, we might insert more blocks
((*- block headingcell scoped-*))
((*- endblock headingcell -*))
((*- elif cell.cell_type in ['raw'] -*))
- ((*- block rawcell scoped-*))
+ ((*- block rawcell scoped -*))
+ ((* if cell.metadata.get('raw_mimetype', resources.get('raw_mimetype')) == resources.get('raw_mimetype') *))
+ ((( cell.source )))
+ ((* endif *))
((*- endblock rawcell -*))
((*- else -*))
((*- block unknowncell scoped-*))
diff --git a/IPython/nbconvert/templates/markdown.tpl b/IPython/nbconvert/templates/markdown.tpl
index 399c012..0946268 100644
--- a/IPython/nbconvert/templates/markdown.tpl
+++ b/IPython/nbconvert/templates/markdown.tpl
@@ -63,10 +63,6 @@
{{ '#' * cell.level }} {{ cell.source | replace('\n', ' ') }}
{% endblock headingcell %}
-{% block rawcell scoped %}
-{{ cell.source }}
-{% endblock rawcell %}
-
{% block unknowncell scoped %}
unknown type {{ cell.type }}
{% endblock unknowncell %}
\ No newline at end of file
diff --git a/IPython/nbconvert/templates/python.tpl b/IPython/nbconvert/templates/python.tpl
index f619206..c863da7 100644
--- a/IPython/nbconvert/templates/python.tpl
+++ b/IPython/nbconvert/templates/python.tpl
@@ -46,10 +46,6 @@ it introduces a new line
{{ '#' * cell.level }}{{ cell.source | replace('\n', ' ') | comment_lines }}
{% endblock headingcell %}
-{% block rawcell scoped %}
-{{ cell.source | comment_lines }}
-{% endblock rawcell %}
-
{% block unknowncell scoped %}
unknown type {{ cell.type }}
{% endblock unknowncell %}
\ No newline at end of file
diff --git a/IPython/nbconvert/templates/rst.tpl b/IPython/nbconvert/templates/rst.tpl
index d0a7fc2..7f25aca 100644
--- a/IPython/nbconvert/templates/rst.tpl
+++ b/IPython/nbconvert/templates/rst.tpl
@@ -75,10 +75,6 @@
{{ ("#" * cell.level + cell.source) | replace('\n', ' ') | markdown2rst }}
{% endblock headingcell %}
-{% block rawcell scoped %}
-{{ cell.source }}
-{% endblock rawcell %}
-
{% block unknowncell scoped %}
unknown type {{cell.type}}
{% endblock unknowncell %}
diff --git a/IPython/nbconvert/templates/skeleton/null.tpl b/IPython/nbconvert/templates/skeleton/null.tpl
index 24066f2..aec85f4 100644
--- a/IPython/nbconvert/templates/skeleton/null.tpl
+++ b/IPython/nbconvert/templates/skeleton/null.tpl
@@ -76,7 +76,10 @@ consider calling super even if it is a leave block, we might insert more blocks
{%- block headingcell scoped-%}
{%- endblock headingcell -%}
{%- elif cell.cell_type in ['raw'] -%}
- {%- block rawcell scoped-%}
+ {%- block rawcell scoped -%}
+ {% if cell.metadata.get('raw_mimetype', resources.get('raw_mimetype', '')).lower() in resources.get('raw_mimetypes', ['']) %}
+ {{ cell.source }}
+ {% endif %}
{%- endblock rawcell -%}
{%- else -%}
{%- block unknowncell scoped-%}