""" io on the clipboard """ from pandas import compat, get_option, option_context, DataFrame from pandas.compat import StringIO, PY2, PY3 import warnings def read_clipboard(sep=r'\s+', **kwargs): # pragma: no cover r""" Read text from clipboard and pass to read_table. See read_table for the full argument list Parameters ---------- sep : str, default '\s+'. A string or regex delimiter. The default of '\s+' denotes one or more whitespace characters. Returns ------- parsed : DataFrame """ encoding = kwargs.pop('encoding', 'utf-8') # only utf-8 is valid for passed value because that's what clipboard # supports if encoding is not None and encoding.lower().replace('-', '') != 'utf8': raise NotImplementedError( 'reading from clipboard only supports utf-8 encoding') from pandas.io.clipboard import clipboard_get from pandas.io.parsers import read_table text = clipboard_get() # try to decode (if needed on PY3) # Strange. linux py33 doesn't complain, win py33 does if PY3: try: text = compat.bytes_to_str( text, encoding=(kwargs.get('encoding') or get_option('display.encoding')) ) except: pass # Excel copies into clipboard with \t separation # inspect no more then the 10 first lines, if they # all contain an equal number (>0) of tabs, infer # that this came from excel and set 'sep' accordingly lines = text[:10000].split('\n')[:-1][:10] # Need to remove leading white space, since read_table # accepts: # a b # 0 1 2 # 1 3 4 counts = {x.lstrip().count('\t') for x in lines} if len(lines) > 1 and len(counts) == 1 and counts.pop() != 0: sep = '\t' # Edge case where sep is specified to be None, return to default if sep is None and kwargs.get('delim_whitespace') is None: sep = r'\s+' # Regex separator currently only works with python engine. # Default to python if separator is multi-character (regex) if len(sep) > 1 and kwargs.get('engine') is None: kwargs['engine'] = 'python' elif len(sep) > 1 and kwargs.get('engine') == 'c': warnings.warn('read_clipboard with regex separator does not work' ' properly with c engine') # In PY2, the c table reader first encodes text with UTF-8 but Python # table reader uses the format of the passed string. For consistency, # encode strings for python engine so that output from python and c # engines produce consistent results if kwargs.get('engine') == 'python' and PY2: text = text.encode('utf-8') return read_table(StringIO(text), sep=sep, **kwargs) def to_clipboard(obj, excel=True, sep=None, **kwargs): # pragma: no cover """ Attempt to write text representation of object to the system clipboard The clipboard can be then pasted into Excel for example. Parameters ---------- obj : the object to write to the clipboard excel : boolean, defaults to True if True, use the provided separator, writing in a csv format for allowing easy pasting into excel. if False, write a string representation of the object to the clipboard sep : optional, defaults to tab other keywords are passed to to_csv Notes ----- Requirements for your platform - Linux: xclip, or xsel (with gtk or PyQt4 modules) - Windows: - OS X: """ encoding = kwargs.pop('encoding', 'utf-8') # testing if an invalid encoding is passed to clipboard if encoding is not None and encoding.lower().replace('-', '') != 'utf8': raise ValueError('clipboard only supports utf-8 encoding') from pandas.io.clipboard import clipboard_set if excel is None: excel = True if excel: try: if sep is None: sep = '\t' buf = StringIO() # clipboard_set (pyperclip) expects unicode obj.to_csv(buf, sep=sep, encoding='utf-8', **kwargs) text = buf.getvalue() if PY2: text = text.decode('utf-8') clipboard_set(text) return except TypeError: warnings.warn('to_clipboard in excel mode requires a single ' 'character separator.') elif sep is not None: warnings.warn('to_clipboard with excel=False ignores the sep argument') if isinstance(obj, DataFrame): # str(df) has various unhelpful defaults, like truncation with option_context('display.max_colwidth', 999999): objstr = obj.to_string(**kwargs) else: objstr = str(obj) clipboard_set(objstr)