docs: def to_string_monkey(df, highlight_cols=None, latex=False):
      """  monkey patch to pandas to highlight the maximum value in specified
      cols of a row
  
      Example:
          >>> from utool.experimental.pandas_highlight import *
          >>> import pandas as pd
          >>> df = pd.DataFrame(
          >>>     np.array([[ 0.9,         0.86886931,  0.86842073,  0.9       ],
          >>>               [ 0.34196218,  0.34289191,  0.34206377,  0.34252863],
          >>>               [ 0.34827074,  0.34827074,  0.34827074,  0.34827074],
          >>>               [ 0.76979453,  0.77214855,  0.77547518,  0.38850962]]),
          >>>     columns=['sum(fgweights)', 'sum(weighted_ratio)', 'len(matches)', 'score_lnbnn_1vM'],
          >>>     index=['match_state(match-v-rest)', 'match_state(nomatch-v-rest)', 'match_state(notcomp-v-rest)', 'photobomb_state']
          >>> )
          >>> highlight_cols = 'all'
          >>> print(to_string_monkey(df, highlight_cols))
          >>> print(to_string_monkey(df, highlight_cols, latex=True))
  
      ut.editfile(pd.io.formats.printing.adjoin)
      """
      try:
          import pandas as pd
          import utool as ut
          import numpy as np
          import six
          if isinstance(highlight_cols, six.string_types) and highlight_cols == 'all':
              highlight_cols = np.arange(len(df.columns))
          # kwds = dict(buf=None, columns=None, col_space=None, header=True,
          #             index=True, na_rep='NaN', formatters=None,
          #             float_format=None, sparsify=None, index_names=True,
          #             justify=None, line_width=None, max_rows=None,
          #             max_cols=None, show_dimensions=False)
          # self = pd.formats.format.DataFrameFormatter(df, **kwds)
          try:
              self = pd.formats.format.DataFrameFormatter(df)
          except AttributeError:
              self = pd.io.formats.format.DataFrameFormatter(df)
  
          self.highlight_cols = highlight_cols
  
          def monkey(self):
              return monkey_to_str_columns(self, latex=latex)
  
          ut.inject_func_as_method(self, monkey, '_to_str_columns', override=True, force=True)
  
          def strip_ansi(text):
              import re
              ansi_escape = re.compile(r'\x1b[^m]*m')
              return ansi_escape.sub('', text)
  
          def justify_ansi(self, texts, max_len, mode='right'):
              if mode == 'left':
                  return [x.ljust(max_len + (len(x) - len(strip_ansi(x)))) for x in texts]
              elif mode == 'center':
                  return [x.center(max_len + (len(x) - len(strip_ansi(x)))) for x in texts]
              else:
                  return [x.rjust(max_len + (len(x) - len(strip_ansi(x)))) for x in texts]
          ut.inject_func_as_method(self.adj, justify_ansi, 'justify', override=True, force=True)
  
          def strlen_ansii(self, text):
              return pd.compat.strlen(strip_ansi(text), encoding=self.encoding)
          ut.inject_func_as_method(self.adj, strlen_ansii, 'len', override=True, force=True)
  
          if False:
              strlen = ut.partial(strlen_ansii, self.adj)  # NOQA
              justfunc = ut.partial(justify_ansi, self.adj)  # NOQA
              # Essentially what to_string does
              strcols = monkey_to_str_columns(self)
              # texts = strcols[2]
              space = 1
              lists = strcols
              str_ = self.adj.adjoin(space, *lists)
              print(str_)
              print(strip_ansi(str_))
          self.to_string()
          result = self.buf.getvalue()
          # hack because adjoin is not working correctly with injected strlen
          result = '\n'.join([x.rstrip() for x in result.split('\n')])
          return result
      except Exception as ex:
          ut.printex('pandas monkey-patch is broken: {}'.format(str(ex)),
                     tb=True, iswarning=True)
          return str(df)