Skip to content

Commit

Permalink
Add config option to disable HTML repr (#11159)
Browse files Browse the repository at this point in the history
* Add config option to disable HTML repr

* Add changelog entry

* Refactor into decorator

* Fix style

* Fix docstring style

* Add kwargs

* Add test

* Use lowercase config values
  • Loading branch information
cbrnr authored Sep 15, 2022
1 parent 333fd05 commit 63b430e
Show file tree
Hide file tree
Showing 13 changed files with 71 additions and 9 deletions.
1 change: 1 addition & 0 deletions doc/changes/latest.inc
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ Enhancements
- Parse automatically temperature channel with :func:`mne.io.read_raw_edf` (:gh:`11150` by `Eric Larson`_ and `Alex Gramfort`_)
- Add ``encoding`` parameter to :func:`mne.io.read_raw_edf` and :func:`mne.io.read_raw_bdf` to support custom (non-UTF8) annotation channel encodings (:gh:`11154` by `Clemens Brunner`_)
- :class:`mne.preprocessing.ICA` gained a new method, :meth:`~mne.preprocessing.ICA.get_explained_variance_ratio`, that allows the retrieval of the proportion of variance explained by ICA components (:gh:`11141` by `Richard Höchenberger`_)
- Add config option ``MNE_REPR_HTML`` to disable HTML repr in notebook environments (:gh:`11159` by `Clemens Brunner`_)

Bugs
~~~~
Expand Down
3 changes: 2 additions & 1 deletion mne/epochs.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@
from .time_frequency.spectrum import EpochsSpectrum, SpectrumMixin
from .viz import (plot_epochs, plot_epochs_image,
plot_topo_image_epochs, plot_drop_log)
from .utils import (_check_fname, check_fname, logger, verbose,
from .utils import (_check_fname, check_fname, logger, verbose, repr_html,
check_random_state, warn, _pl,
sizeof_fmt, SizeMixin, copy_function_doc_to_method_doc,
_check_pandas_installed,
Expand Down Expand Up @@ -1594,6 +1594,7 @@ def __repr__(self):
class_name = 'Epochs' if class_name == 'BaseEpochs' else class_name
return '<%s | %s>' % (class_name, s)

@repr_html
def _repr_html_(self):
from .html_templates import repr_templates_env
if self.baseline is None:
Expand Down
3 changes: 2 additions & 1 deletion mne/evoked.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
from .defaults import (_INTERPOLATION_DEFAULT, _EXTRAPOLATE_DEFAULT,
_BORDER_DEFAULT)
from .filter import detrend, FilterMixin, _check_fun
from .utils import (check_fname, logger, verbose, warn, sizeof_fmt,
from .utils import (check_fname, logger, verbose, warn, sizeof_fmt, repr_html,
SizeMixin, copy_function_doc_to_method_doc, _validate_type,
fill_doc, _check_option, _build_data_frame,
_check_pandas_installed, _check_pandas_index_arguments,
Expand Down Expand Up @@ -352,6 +352,7 @@ def __repr__(self): # noqa: D105
s += ", ~%s" % (sizeof_fmt(self._size),)
return "<Evoked | %s>" % s

@repr_html
def _repr_html_(self):
from .html_templates import repr_templates_env
if self.baseline is None:
Expand Down
3 changes: 2 additions & 1 deletion mne/forward/forward.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
from ..utils import (_check_fname, get_subjects_dir, has_mne_c, warn,
run_subprocess, check_fname, logger, verbose, fill_doc,
_validate_type, _check_compensation_grade, _check_option,
_check_stc_units, _stamp_to_dt, _on_missing)
_check_stc_units, _stamp_to_dt, _on_missing, repr_html)
from ..label import Label


Expand Down Expand Up @@ -178,6 +178,7 @@ def __repr__(self):

return entr

@repr_html
def _repr_html_(self):
from ..html_templates import repr_templates_env
good_chs, bad_chs, _, _, = self['info']._get_chs_for_repr()
Expand Down
3 changes: 2 additions & 1 deletion mne/io/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
copy_function_doc_to_method_doc, _validate_type,
_check_preload, _get_argvalues, _check_option,
_build_data_frame, _convert_times, _scale_dataframe_data,
_check_time_format, _arange_div, TimeMixin)
_check_time_format, _arange_div, TimeMixin, repr_html)
from ..defaults import _handle_default
from ..viz import plot_raw, _RAW_CLIP_DEF
from ..event import find_events, concatenate_events
Expand Down Expand Up @@ -1739,6 +1739,7 @@ def __repr__(self): # noqa: D105
size_str))
return "<%s | %s>" % (self.__class__.__name__, s)

@repr_html
def _repr_html_(self, caption=None):
from ..html_templates import repr_templates_env
basenames = [
Expand Down
3 changes: 2 additions & 1 deletion mne/io/meas_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
from ..utils import (logger, verbose, warn, object_diff, _validate_type,
_stamp_to_dt, _dt_to_stamp, _pl, _is_numeric,
_check_option, _on_missing, _check_on_missing, fill_doc,
_check_fname)
_check_fname, repr_html)
from ._digitization import (_format_dig_points, _dig_kind_proper, DigPoint,
_dig_kind_rev, _dig_kind_ints, _read_dig_fif)
from ._digitization import write_dig, _get_data_as_dict_from_dig
Expand Down Expand Up @@ -1174,6 +1174,7 @@ def _get_chs_for_repr(self):

return good_channels, bad_channels, ecg, eog

@repr_html
def _repr_html_(self, caption=None):
"""Summarize info for HTML representation."""
from ..html_templates import repr_templates_env
Expand Down
3 changes: 2 additions & 1 deletion mne/minimum_norm/inverse.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
from ..transforms import _ensure_trans, transform_surface_to
from ..source_estimate import _make_stc, _get_src_type
from ..utils import (check_fname, logger, verbose, warn, _validate_type,
_check_compensation_grade, _check_option,
_check_compensation_grade, _check_option, repr_html,
_check_depth, _check_src_normal, _check_fname)


Expand Down Expand Up @@ -95,6 +95,7 @@ def __repr__(self): # noqa: D105
entr += '>'
return entr

@repr_html
def _repr_html_(self):
from ..html_templates import repr_templates_env
repr_info = self._get_chs_and_src_info_for_repr()
Expand Down
3 changes: 2 additions & 1 deletion mne/preprocessing/ica.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@
from ..io.write import start_and_end_file, write_id
from ..utils import (logger, check_fname, _check_fname, verbose,
_reject_data_segments, check_random_state, _validate_type,
compute_corr, _get_inst_data, _ensure_int,
compute_corr, _get_inst_data, _ensure_int, repr_html,
copy_function_doc_to_method_doc, _pl, warn, Bunch,
_check_preload, _check_compensation_grade, fill_doc,
_check_option, _PCA, int_like, _require_version,
Expand Down Expand Up @@ -513,6 +513,7 @@ def __repr__(self):

return f'<ICA | {s}>'

@repr_html
def _repr_html_(self):
from ..html_templates import repr_templates_env
infos = self._get_infos_for_repr()
Expand Down
3 changes: 2 additions & 1 deletion mne/time_frequency/spectrum.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
from ..defaults import _handle_default
from ..io.meas_info import ContainsMixin
from ..io.pick import _pick_data_channels, _picks_to_idx, pick_info
from ..utils import (GetEpochsMixin, _build_data_frame,
from ..utils import (GetEpochsMixin, _build_data_frame, repr_html,
_check_pandas_index_arguments, _check_pandas_installed,
_check_sphere, _time_mask, _validate_type, fill_doc,
legacy, logger, object_diff, verbose, warn)
Expand Down Expand Up @@ -346,6 +346,7 @@ def __repr__(self):
return (f'<{self._data_type} (from {inst_type_str}, '
f'{self.method} method) | {dims}, {freq_range}>')

@repr_html
def _repr_html_(self, caption=None):
"""Build HTML representation of the Spectrum object."""
from ..html_templates import repr_templates_env
Expand Down
2 changes: 1 addition & 1 deletion mne/utils/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
from .misc import (run_subprocess, _pl, _clean_names, pformat, _file_like,
_explain_exception, _get_argvalues, sizeof_fmt,
running_subprocess, _DefaultEventParser,
_assert_no_instances, _resource_path)
_assert_no_instances, _resource_path, repr_html)
from .progressbar import ProgressBar
from ._testing import (run_command_if_main, requires_sklearn,
requires_version, requires_nibabel, requires_mne,
Expand Down
1 change: 1 addition & 0 deletions mne/utils/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ def set_memmap_min_size(memmap_min_size):
'MNE_KIT2FIFF_STIM_CHANNEL_THRESHOLD',
'MNE_LOGGING_LEVEL',
'MNE_MEMMAP_MIN_SIZE',
'MNE_REPR_HTML',
'MNE_SKIP_FTP_TESTS',
'MNE_SKIP_NETWORK_TESTS',
'MNE_SKIP_TESTING_DATASET_TESTS',
Expand Down
29 changes: 29 additions & 0 deletions mne/utils/misc.py
Original file line number Diff line number Diff line change
Expand Up @@ -406,3 +406,32 @@ def _resource_path(submodule, filename):
except ImportError:
from pkg_resources import resource_filename
return resource_filename(submodule, filename)


def repr_html(f):
"""Decorate _repr_html_ methods.
If a _repr_html_ method is decorated with this decorator, the repr in a
notebook will show HTML or plain text depending on the config value
MNE_REPR_HTML (by default "true", which will render HTML).
Parameters
----------
f : function
The function to decorate.
Returns
-------
wrapper : function
The decorated function.
"""
from ..utils import get_config

def wrapper(*args, **kwargs):
if get_config("MNE_REPR_HTML", "true").lower() == "false":
import html
r = "<pre>" + html.escape(repr(args[0])) + "</pre>"
return r.replace("\n", "<br/>")
else:
return f(*args, **kwargs)
return wrapper
23 changes: 23 additions & 0 deletions mne/utils/tests/test_misc.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import os

import mne
from mne.utils import sizeof_fmt


Expand All @@ -6,3 +9,23 @@ def test_sizeof_fmt():
assert sizeof_fmt(0) == '0 bytes'
assert sizeof_fmt(1) == '1 byte'
assert sizeof_fmt(1000) == '1000 bytes'


def test_html_repr():
"""Test switching _repr_html_ between HTML and plain text."""
key = "MNE_REPR_HTML"
existing_value = os.getenv(key, None)

os.environ[key] = "True" # HTML repr on
info = mne.create_info(10, 256)
r = info._repr_html_()
assert r.startswith("<table")
assert r.endswith("</table>")
os.environ[key] = "False" # HTML repr off
r = info._repr_html_()
assert r.startswith("<pre>")
assert r.endswith("</pre>")

del os.environ[key]
if existing_value is not None:
os.environ[key, existing_value]

0 comments on commit 63b430e

Please sign in to comment.