Repository: pandas-dev/pandas

Issue:
Provide styling option to escape dollar signs
Jupyter Notebooks use MathJax to render text between dollar signs. Sometimes this is appropriate and sometimes it is not.

```python
import pandas as pd
df=pd.DataFrame({'A':['From $200 million to $700 million','$20+']})
df
```
<img src="https://user-images.githubusercontent.com/1804856/36501664-93cd23f6-16fc-11e8-8f74-47a47b14741d.png" width="200">

 It appears that the [official guidance](https://github.com/ipython/ipython/issues/3197/) is to use `$\$$` to render a single `$` symbol.

```python
df.A = df.A.str.replace('$', '$\$$')
df
```
<img src="https://user-images.githubusercontent.com/1804856/36502237-2c8fe2ee-16fe-11e8-8d04-54ecb2407010.png" width="200">

However, editing the data to tune the rendering is messy. I'm hoping this can be incorporated into the new [Pandas styling module](https://pandas.pydata.org/pandas-docs/stable/style.html). Perhaps something like `df.style.escape_dollar()`.

#### Output of ``pd.show_versions()``

<details>

INSTALLED VERSIONS
------------------
commit: None
python: 3.6.4.final.0
python-bits: 64
OS: Linux
OS-release: 2.6.32-696.13.2.el6.x86_64
machine: x86_64
processor: x86_64
byteorder: little
LC_ALL: None
LANG: en_US.UTF-8
LOCALE: en_US.UTF-8

pandas: 0.22.0
pytest: 3.4.0
pip: 9.0.1
setuptools: 38.4.0
Cython: None
numpy: 1.14.0
scipy: None
pyarrow: 0.8.0
xarray: None
IPython: 6.2.1
sphinx: None
patsy: None
dateutil: 2.6.1
pytz: 2017.3
blosc: None
bottleneck: None
tables: None
numexpr: None
feather: 0.4.0
matplotlib: 2.1.2
openpyxl: None
xlrd: None
xlwt: None
xlsxwriter: None
lxml: None
bs4: None
html5lib: 1.0.1
sqlalchemy: None
pymysql: None
psycopg2: None
jinja2: 2.10
s3fs: None
fastparquet: None
pandas_gbq: None
pandas_datareader: None

</details>



Discussion:

Resolving patch:
diff --git a/pandas/core/config_init.py b/pandas/core/config_init.py
--- a/pandas/core/config_init.py
+++ b/pandas/core/config_init.py
@@ -207,6 +207,12 @@ def use_numexpr_cb(key):
 (currently both are identical)
 """
 
+pc_html_use_mathjax_doc = """\
+: boolean
+    When True, Jupyter notebook will process table contents using MathJax,
+    rendering mathematical expressions enclosed by the dollar symbol.
+    (default: True)
+"""
 
 pc_width_doc = """
 : int
@@ -358,6 +364,8 @@ def table_schema_cb(key):
                        validator=is_bool, cb=table_schema_cb)
     cf.register_option('html.border', 1, pc_html_border_doc,
                        validator=is_int)
+    cf.register_option('html.use_mathjax', True, pc_html_use_mathjax_doc,
+                       validator=is_bool)
 
 with cf.config_prefix('html'):
     cf.register_option('border', 1, pc_html_border_doc,
diff --git a/pandas/io/formats/format.py b/pandas/io/formats/format.py
--- a/pandas/io/formats/format.py
+++ b/pandas/io/formats/format.py
@@ -1209,6 +1209,9 @@ def write_result(self, buf):
         frame = self.frame
 
         _classes = ['dataframe']  # Default class.
+        use_mathjax = get_option("display.html.use_mathjax")
+        if not use_mathjax:
+            _classes.append('tex2jax_ignore')
         if self.classes is not None:
             if isinstance(self.classes, str):
                 self.classes = self.classes.split()
diff --git a/pandas/io/formats/style.py b/pandas/io/formats/style.py
--- a/pandas/io/formats/style.py
+++ b/pandas/io/formats/style.py
@@ -325,9 +325,19 @@ def format_attr(pair):
                                   .format(row=r, col=c)})
             body.append(row_es)
 
+        table_attr = self.table_attributes
+        use_mathjax = get_option("display.html.use_mathjax")
+        if not use_mathjax:
+            table_attr = table_attr or ''
+            if 'class="' in table_attr:
+                table_attr = table_attr.replace('class="',
+                                                'class="tex2jax_ignore ')
+            else:
+                table_attr += ' class="tex2jax_ignore"'
+
         return dict(head=head, cellstyle=cellstyle, body=body, uuid=uuid,
                     precision=precision, table_styles=table_styles,
-                    caption=caption, table_attributes=self.table_attributes)
+                    caption=caption, table_attributes=table_attr)
 
     def format(self, formatter, subset=None):
         """


Test patch:
diff --git a/pandas/tests/io/formats/test_format.py b/pandas/tests/io/formats/test_format.py
--- a/pandas/tests/io/formats/test_format.py
+++ b/pandas/tests/io/formats/test_format.py
@@ -1434,6 +1434,13 @@ def test_repr_html(self):
 
         tm.reset_display_options()
 
+    def test_repr_html_mathjax(self):
+        df = DataFrame([[1, 2], [3, 4]])
+        assert 'tex2jax_ignore' not in df._repr_html_()
+
+        with pd.option_context('display.html.use_mathjax', False):
+            assert 'tex2jax_ignore' in df._repr_html_()
+
     def test_repr_html_wide(self):
         max_cols = get_option('display.max_columns')
         df = DataFrame(tm.rands_array(25, size=(10, max_cols - 1)))
diff --git a/pandas/tests/io/formats/test_style.py b/pandas/tests/io/formats/test_style.py
--- a/pandas/tests/io/formats/test_style.py
+++ b/pandas/tests/io/formats/test_style.py
@@ -46,6 +46,13 @@ def test_init_series(self):
     def test_repr_html_ok(self):
         self.styler._repr_html_()
 
+    def test_repr_html_mathjax(self):
+        # gh-19824
+        assert 'tex2jax_ignore' not in self.styler._repr_html_()
+
+        with pd.option_context('display.html.use_mathjax', False):
+            assert 'tex2jax_ignore' in self.styler._repr_html_()
+
     def test_update_ctx(self):
         self.styler._update_ctx(self.attrs)
         expected = {(0, 0): ['color: red'],