Repository: ipython/ipython

Issue:
Error in nbconvert - closing </code> tag is not inserted in HTML under some circumstances
Hi folks - I just noticed that under some circumstances, closing tags for &lt;code&gt; blocks aren't applied, which throws off formatting throughout the rest of the notebook. For an example, checkout this notebook that renders fine in IPython Notebook itself, but does not render properly when converted to HTML. (There is a missing &lt;/code&gt; just after "pip install python-linkedin" that's near where you'll see that the example titles start to look funky.)

Source notebook is included in the URL below as a file checked into GitHub that you can reference as well.

http://nbviewer.ipython.org/urls/raw.github.com/ptwobrussell/Mining-the-Social-Web-2nd-Edition/master/ipynb/Chapter%203%20-%20Mining%20LinkedIn.ipynb

Thanks



Discussion:
Weird it does not show with your git hooks [(se here)](https://rawgithub.com/ptwobrussell/Mining-the-Social-Web-2nd-Edition/master/ipynb/html/Chapter%203%20-%20Mining%20LinkedIn.html#Example-1.-Using-LinkedIn-OAuth-credentials-to-receive-an-access-token-suitable-for-development-and-accessing-your-own-data) as we use nbconvert in nbviewer too....

The strip_math_space filter crops the line here, as it starts with `$` and has not more than 2 lines afterwards.
see

``` python
from IPython.nbconvert.filters import strip_math_space
s= "<code>\n$ pip install\n</code>"
strip_math_space(s)
```

gives
`<code>\n`

A simple workaround is to add a new line after the `</code>` block.

``` python
from IPython.nbconvert.filters import strip_math_space
s= "<code>\n$ pip install\n</code>\n"
strip_math_space(s)
```

gives
`<code>\n$ pip install\n</code>\n`

@jdfreder why does the md2html conversion requires the strip_math_space filter but the md2latex does not? I thought this is only a latex requirement?

@Carreau - I manually fixed the html file that I checked in, which is why the one that serves from rawgithub looks ok. (Sorry if that confused you.)

@ptwobrussell I made a quick fix, can you try #4310?


Resolving patch:
diff --git a/IPython/nbconvert/exporters/templateexporter.py b/IPython/nbconvert/exporters/templateexporter.py
--- a/IPython/nbconvert/exporters/templateexporter.py
+++ b/IPython/nbconvert/exporters/templateexporter.py
@@ -56,7 +56,6 @@
         'html2text' : filters.html2text,
         'add_anchor': filters.add_anchor,
         'ansi2latex': filters.ansi2latex,
-        'strip_math_space': filters.strip_math_space,
         'wrap_text': filters.wrap_text,
         'escape_latex': filters.escape_latex,
         'citation2latex': filters.citation2latex,
diff --git a/IPython/nbconvert/filters/latex.py b/IPython/nbconvert/filters/latex.py
--- a/IPython/nbconvert/filters/latex.py
+++ b/IPython/nbconvert/filters/latex.py
@@ -44,8 +44,7 @@
 # Functions
 #-----------------------------------------------------------------------------
 
-__all__ = ['escape_latex',
-           'strip_math_space']
+__all__ = ['escape_latex']
 
 def escape_latex(text):
     """
@@ -61,63 +60,4 @@ def escape_latex(text):
         text = pattern.sub(replacement, text)
 
     return text
-    
-    
-def strip_math_space(text):
-    """
-    Remove the space between latex math commands and enclosing $ symbols.
-    This filter is important because latex isn't as flexible as the notebook
-    front end when it comes to flagging math using ampersand symbols.
-    
-    Parameters
-    ----------
-    text : str
-        Text to filter.
-    """
-
-    # First, scan through the markdown looking for $.  If
-    # a $ symbol is found, without a preceding \, assume
-    # it is the start of a math block.  UNLESS that $ is
-    # not followed by another within two math_lines.
-    math_regions = []
-    math_lines = 0
-    within_math = False
-    math_start_index = 0
-    ptext = ''
-    last_character = ""
-    skip = False
-    for index, char in enumerate(text):
-
-        #Make sure the character isn't preceeded by a backslash
-        if (char == "$" and last_character != "\\"):
-
-            # Close the math region if this is an ending $
-            if within_math:
-                within_math = False
-                skip = True
-                ptext = ptext+'$'+text[math_start_index+1:index].strip()+'$'
-                math_regions.append([math_start_index, index+1])
-            else:
-
-                # Start a new math region
-                within_math = True
-                math_start_index = index
-                math_lines = 0
-
-        # If we are in a math region, count the number of lines parsed.
-        # Cancel the math region if we find two line breaks!
-        elif char == "\n":
-            if within_math:
-                math_lines += 1
-                if math_lines > 1:
-                    within_math = False
-                    ptext = ptext+text[math_start_index:index]
 
-        # Remember the last character so we can easily watch
-        # for backslashes
-        last_character = char
-        if not within_math and not skip:
-            ptext = ptext+char
-        if skip:
-            skip = False
-    return ptext
diff --git a/IPython/nbconvert/preprocessors/latex.py b/IPython/nbconvert/preprocessors/latex.py
--- a/IPython/nbconvert/preprocessors/latex.py
+++ b/IPython/nbconvert/preprocessors/latex.py
@@ -14,27 +14,22 @@
 #-----------------------------------------------------------------------------
 
 from __future__ import print_function, absolute_import
-import os
 
-# Third-party import, needed for Pygments latex definitions.
-from pygments.formatters import LatexFormatter
-
-# ipy imports
-from .base import (Preprocessor)
-from IPython.nbconvert import filters
+from .base import Preprocessor
 
 #-----------------------------------------------------------------------------
 # Classes
 #-----------------------------------------------------------------------------
 
 class LatexPreprocessor(Preprocessor):
-    """
-    Converter for latex destined documents.
+    """Preprocessor for latex destined documents.
+    
+    Mainly populates the `latex` key in the resources dict,
+    adding definitions for pygments highlight styles.
     """
 
     def preprocess(self, nb, resources):
-        """
-        Preprocessing to apply on each notebook.
+        """Preprocessing to apply on each notebook.
         
         Parameters
         ----------
@@ -44,31 +39,9 @@ def preprocess(self, nb, resources):
             Additional resources used in the conversion process.  Allows
             preprocessors to pass variables into the Jinja engine.
         """
-        # Generate Pygments definitions for Latex 
-        resources["latex"] = {}
-        resources["latex"]["pygments_definitions"] = LatexFormatter().get_style_defs()
-        return super(LatexPreprocessor, self).preprocess(nb, resources)
-
-
-    def preprocess_cell(self, cell, resources, index):
-        """
-        Apply a transformation on each cell,
-        
-        Parameters
-        ----------
-        cell : NotebookNode cell
-            Notebook cell being processed
-        resources : dictionary
-            Additional resources used in the conversion process.  Allows
-            preprocessors to pass variables into the Jinja engine.
-        index : int
-            Modified index of the cell being processed (see base.py)
-        """
+        # Generate Pygments definitions for Latex
+        from pygments.formatters import LatexFormatter
         
-        #If the cell is a markdown cell, preprocess the ampersands used to
-        #remove the space between them and their contents.  Latex will complain
-        #if spaces exist between the ampersands and the math content.  
-        #See filters.latex.rm_math_space for more information.
-        if hasattr(cell, "source") and cell.cell_type == "markdown":
-            cell.source = filters.strip_math_space(cell.source)
-        return cell, resources
+        resources.setdefault("latex", {})
+        resources["latex"].setdefault("pygments_definitions", LatexFormatter().get_style_defs())
+        return nb, resources


Test patch:
diff --git a/IPython/nbconvert/filters/tests/test_latex.py b/IPython/nbconvert/filters/tests/test_latex.py
--- a/IPython/nbconvert/filters/tests/test_latex.py
+++ b/IPython/nbconvert/filters/tests/test_latex.py
@@ -15,7 +15,7 @@
 #-----------------------------------------------------------------------------
 
 from ...tests.base import TestsBase
-from ..latex import escape_latex, strip_math_space
+from ..latex import escape_latex
 
 
 #-----------------------------------------------------------------------------
@@ -43,24 +43,3 @@ def _try_escape_latex(self, test, result):
         self.assertEqual(escape_latex(test), result)
 
 
-    def test_strip_math_space(self):
-        """strip_math_space test"""
-        tests = [
-            ('$e$','$e$'),
-            ('$ e $','$e$'),
-            ('xxx$e^i$yyy','xxx$e^i$yyy'),
-            ('xxx$ e^i $yyy','xxx$e^i$yyy'),
-            ('xxx$e^i $yyy','xxx$e^i$yyy'),
-            ('xxx$ e^i$yyy','xxx$e^i$yyy'),
-            ('\$ e $ e $','\$ e $e$'),
-            ('','')]
-
-        for test in tests:
-            self._try_strip_math_space(test[0], test[1])
-
-
-    def _try_strip_math_space(self, test, result):
-        """
-        Try to remove spaces between dollar symbols and contents correctly
-        """
-        self.assertEqual(strip_math_space(test), result)
diff --git a/IPython/nbconvert/preprocessors/tests/test_latex.py b/IPython/nbconvert/preprocessors/tests/test_latex.py
--- a/IPython/nbconvert/preprocessors/tests/test_latex.py
+++ b/IPython/nbconvert/preprocessors/tests/test_latex.py
@@ -47,5 +47,5 @@ def test_output(self):
         # Make sure the code cell wasn't modified.
         self.assertEqual(nb.worksheets[0].cells[0].input, '$ e $')
 
-        # Verify that the markdown cell was processed.
-        self.assertEqual(nb.worksheets[0].cells[1].source, '$e$')
+        # Verify that the markdown cell wasn't processed.
+        self.assertEqual(nb.worksheets[0].cells[1].source, '$ e $')