#!/usr/bin/env python3 # # Copyright 2017 Ville Rantanen # # This program is free software: you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License as published # by the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . # '''TSV 2 SC convert.''' from __future__ import division from __future__ import print_function from builtins import chr from builtins import str from builtins import range from builtins import object from past.utils import old_div __author__ = "Ville Rantanen" __version__ = "0.2" import sys,os import csv from argparse import ArgumentParser import unicodedata, re import subprocess def which(program): import os def is_exe(fpath): return os.path.isfile(fpath) and os.access(fpath, os.X_OK) fpath, fname = os.path.split(program) if fpath: if is_exe(program): return program else: for path in os.environ["PATH"].split(os.pathsep): exe_file = os.path.join(path, program) if is_exe(exe_file): return exe_file return None class SCWriter(object): """ Class for writing SC files. """ def __init__(self,file,alignright,float_precision): self.file=file self.row=0 self.col=0 self.col_lengths=[] self.col_types=[] self.alignright=alignright self.float_precision=float_precision if self.alignright: self.alignstring="rightstring" else: self.alignstring="leftstring" def parse_row(self,string): self.col=0 for el in row: self.write_element(self.row,self.col,el) if len(self.col_lengths) <= self.col: self.col_lengths.append(2) self.col_types.append('int') el_str=el if self.is_float(el) and not self.is_int(el): self.col_types[self.col]='float' el_str=("%."+str(self.float_precision)+"f")%(float(el),) self.col_lengths[self.col]=max(len(el_str)+1,self.col_lengths[self.col]) self.col+=1 self.row+=1 def write_element(self,row,col,content): colalpha=self.column_to_alpha(col) content=content.strip('"') if self.is_num(content): self.file.write('let '+colalpha+str(row)+' = ' + str(self.to_num(content))+'\n') else: self.file.write(self.alignstring+' '+colalpha+str(row)+' = "' + content + '"\n') def column_to_alpha(self,column): ''' Returns a column alphabet from column number ''' o=chr(column+64+1) if column>25: return self.column_to_alpha((old_div(column, 26)) -1) + self.column_to_alpha(column % 26); return o def write_row(self,row): ''' Writes a row as a SC file part ''' self.parse_row(row) def write_formats(self): for col in range(len(self.col_lengths)): precision="0" if self.col_types[col]=='float': precision=str(self.float_precision) self.file.write('format %s %s %s 0\n'%( self.column_to_alpha(col), str(self.col_lengths[col]), precision)) def is_float(self,string): try: num=float(string) return True except: pass return False def is_int(self,string): try: num=int(string) return True except: pass return False def is_num(self,string): ''' returns the True if string can be converted to number safely ''' if self.is_int(string): return True if self.is_float(string): return True return False def to_num(self,string): ''' returns the number in the correct data type if string can be converted to number safely ''' try: num=int(string) return num except: pass try: num=float(string) return num except: pass return string def setup_options(): ''' Setup the command line options ''' parser=ArgumentParser() parser.add_argument("-v","--version",action='version', version=__version__) parser.add_argument("-f",type=int,dest="precision",default=2, help="Precision for float column format, default: 2") parser.add_argument("-i",type=str,dest="delimiter",default="\t", help="Input delimiter for the TSV, default: [tab]") parser.add_argument("-r",dest="right",default=False,action='store_true', help="Align strings right.") parser.add_argument("tsv",type=str,action="store", help="TSV file to convert") options=parser.parse_args() return options if not which('sc'): print('You don\'t seem to have "sc" installed!') print('sudo apt-get install sc') sys.exit(1) opts=setup_options() csv_reader = csv.reader(open(opts.tsv,'rt'), delimiter=opts.delimiter, doublequote=False, escapechar='\\') sc_writer=SCWriter(sys.stdout,opts.right,opts.precision) for row in csv_reader: if len(row)>0: sc_writer.write_row(row) sc_writer.write_formats()