diff --git a/bin/sc2tsv b/bin/sc2tsv new file mode 120000 index 0000000..3019f8e --- /dev/null +++ b/bin/sc2tsv @@ -0,0 +1 @@ +../tsv/sc2tsv.py \ No newline at end of file diff --git a/bin/tsv2sc b/bin/tsv2sc new file mode 120000 index 0000000..f3f6ab3 --- /dev/null +++ b/bin/tsv2sc @@ -0,0 +1 @@ +../tsv/tsv2sc.py \ No newline at end of file diff --git a/tsv/sc2tsv.py b/tsv/sc2tsv.py new file mode 100755 index 0000000..d465d29 --- /dev/null +++ b/tsv/sc2tsv.py @@ -0,0 +1,134 @@ +#!/usr/bin/env python +# +# 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 . +# + +'''SC to TSV convert.''' + +__author__ = "Ville Rantanen" + +__version__ = "0.1" + +import sys +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 SCReader: + """ Class for reading SC files. + + """ + def __init__(self,data): + self.data=data.split('\n') + self.parserre=re.compile('.* ([A-Z]+)([0-9]+) = (.*)') + + def _parse_row(self,string): + col=None + row=None + content=None + m=self.parserre.match(string.strip()) + if m: + col=self.alpha_to_column(m.group(1)) + row=self.try_int(m.group(2)) + content=m.group(3) + return col,row,content + + def try_int(self,string): + + try: + return int(string) + except: + return string + + def alpha_to_column(self,alpha): + ''' Returns a column number from spreadsheet column alphabet ''' + n=0 + o=0 + for char in alpha[::-1]: + o+=(ord(char.upper())-64)*(26**n) + n+=1 + return int(o-1) + + def next(self): + ''' Returns the next row in the table, three items: column, row, content''' + return self._parse_row(self.reader.next()) + + def __iter__(self): + for row in self.data: + yield self._parse_row(row) + +def setup_options(): + ''' Setup the command line options ''' + + parser=ArgumentParser() + parser.add_argument("-v","--version",action='version', version=__version__) + parser.add_argument("-d",type=str,dest="delimiter",default="\t", + help="Delimiter for the TSV, default: [tab]") + parser.add_argument("sc",type=str,action="store", + help="SC file to convert") + options=parser.parse_args() + return options + +def tsv_write(screader,fileout,delim): + ''' writes a TSV from SCReader iterator ''' + content=[] + rows=0 + cols=0 + for row in screader: + if row[0]!=None: + content.append(row) + rows=max(row[1],rows) + cols=max(row[0],cols) + table=[] + for r in range(rows+1): + table.append([]) + for c in range(cols+1): + table[r].append('') + for e in content: + table[e[1]][e[0]]=e[2] + for row in table: + fileout.write(delim.join(row)+'\n') + +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() +proc=subprocess.Popen(['sc','-v','-P','%',opts.sc], stdout=subprocess.PIPE) +sc=proc.stdout.read() +sc_reader=SCReader(sc) +tsv_write(sc_reader,sys.stdout,opts.delimiter) + + + diff --git a/tsv/tsv2sc.py b/tsv/tsv2sc.py new file mode 100755 index 0000000..8854ace --- /dev/null +++ b/tsv/tsv2sc.py @@ -0,0 +1,188 @@ +#!/usr/bin/env python +# +# 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.''' + +__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: + """ 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((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() + +