Attachment 'sctable-1.5.2-5.py'

Download

   1  
   2 """
   3     MoinMoin - sctable a Processor for spread sheet calculations by sc
   4     @license: GNU GPL, see COPYING for details.
   5 
   6     PURPOSE:
   7         This processor is used to do some spread sheet calculation based on sc in a
   8     regular wiki table. The first column/first line coordinate is A0.
   9 
  10     CALLING SEQUENCE:
  11        {{{
  12        #!sctable [-column_header, -row_header, -show_formular, -format  ]
  13        }}}
  14 
  15     OPTIONAL INPUTS:
  16        -column_header: additional in the result the column header is shown
  17        -row_header: additional in the result the line number header is shown
  18        -show_formular: if set the formular instead of the result is shown,
  19                        data is arranged in textmode. Blanks in formulars are removed
  20        -format: is used to the set the number of digits for the column values
  21 
  22 
  23     EXAMPLE:
  24 {{{
  25 SUM over columns}}}
  26 {{{
  27 #!sctable
  28 ||1||2||=A0+B0||
  29 ||10||20||=@sum(A1:B1)||
  30 }}}
  31 
  32 RESULT:
  33 ||<)>1.00||<)>2.00||<)>3.00||
  34 ||<)>10.00||<)>20.00||<)>30.00||
  35 -----
  36 
  37 {{{
  38 cell B1 no data}}}
  39 
  40 {{{
  41 #!sctable
  42 ||A||B||C||D||
  43 ||1||||2||=A1+C1||
  44 }}}
  45 
  46 RESULT:
  47 ||<(>A||<(>B||<(>C||<(>D||
  48 ||<)>1.00||<)>||<)>2.00||<)>3.00||
  49 
  50 -----
  51 {{{
  52 SUM over rows}}}
  53 {{{
  54 #!sctable
  55 ||1||2||=A0+B0||
  56 ||10||20||30||
  57 ||=@sum(A0:A1)||=@sum(B0:B1)||=@sum(C0:C1)||
  58 }}}
  59 
  60 RESULT:
  61 ||<)>1.00||<)>2.00||<)>3.00||
  62 ||<)>10.00||<)>20.00||<)>30.00||
  63 ||<)>11.00||<)>22.00||<)>33.00||
  64 
  65 -----
  66 {{{
  67 SUM over rows and columns}}}
  68 {{{
  69 #!sctable
  70 ||A||B||C||
  71 ||1||2||=A1+B1||
  72 ||10||20||=@sum(A2:B2)||
  73 ||=@sum(A1:A2)||=@sum(B1:B2)||=@sum(C1:C2)||
  74 }}}
  75 
  76 RESULT:
  77 ||<(>A||<(>B||<(>C||
  78 ||<)>1.00||<)>2.00||<)>3.00||
  79 ||<)>10.00||<)>20.00||<)>30.00||
  80 ||<)>11.00||<)>22.00||<)>33.00||
  81 
  82 -----
  83 {{{
  84 -column_header}}}
  85 {{{
  86 #!sctable  -column_header
  87 ||1||2||
  88 ||3||4||
  89 ||5||6||
  90 }}}
  91 
  92 RESULT:
  93 ||<:#CCCCCC>'''A'''||<:#CCCCCC>'''B'''||
  94 ||<)>1.00||<)>2.00||
  95 ||<)>3.00||<)>4.00||
  96 ||<)>5.00||<)>6.00||
  97 
  98 
  99 -----
 100 {{{
 101 -row_header}}}
 102 {{{
 103 #!sctable -row_header
 104 ||1||2||
 105 ||3||4||
 106 ||5||6||
 107 }}}
 108 
 109 RESULT:
 110 ||<)5%#CCCCCC>'''0'''||<)>1.00||<)>2.00||
 111 ||<)5%#CCCCCC>'''1'''||<)>3.00||<)>4.00||
 112 ||<)5%#CCCCCC>'''2'''||<)>5.00||<)>6.00||
 113 
 114 -----
 115 {{{
 116 -column_header  -row_header}}}
 117 {{{
 118 #!sctable  -column_header  -row_header
 119 ||1||2||
 120 ||3||4||
 121 ||5||6||
 122 }}}
 123 
 124 RESULT:
 125 ||<:5%#CCCCCC> ||<:#CCCCCC>'''A'''||<:#CCCCCC>'''B'''||
 126 ||<)5%#CCCCCC>'''0'''||<)>1.00||<)>2.00||
 127 ||<)5%#CCCCCC>'''1'''||<)>3.00||<)>4.00||
 128 ||<)5%#CCCCCC>'''2'''||<)>5.00||<)>6.00||
 129 
 130 -----
 131 {{{
 132 -show_formular  -column_header  -row_header}}}
 133 {{{
 134 #!sctable -show_formular  -column_header  -row_header
 135 ||m||p||
 136 ||1||=A1 * 5||
 137 ||2||=A2-3||
 138 ||3||4||
 139 }}}
 140 
 141 RESULT:
 142 ||<:5%#CCCCCC> ||<:#CCCCCC>'''A'''||<:#CCCCCC>'''B'''||
 143 ||<)5%#CCCCCC>'''0'''||<(>m||<(>p||
 144 ||<)5%#CCCCCC>'''1'''||<(>1||<(>=A1*5||
 145 ||<)5%#CCCCCC>'''2'''||<(>2||<(>=A2-3||
 146 ||<)5%#CCCCCC>'''3'''||<(>3||<(>4||
 147 
 148 -----
 149 {{{
 150 -column_header and blanks in cells}}}
 151 {{{
 152 #!sctable -column_header
 153 ||Name Vorname||  ||  || 3 || || 5||
 154 ||Name Vorname|| 1 || 2 ||  || 4 || 5||
 155 ||Name Vorname|| 1 || 2 || || || 5||
 156 }}}
 157 
 158 RESULT:
 159 ||<:#CCCCCC>'''A'''||<:#CCCCCC>'''B'''||<:#CCCCCC>'''C'''||<:#CCCCCC>'''D'''||<:#CCCCCC>'''E'''||<:#CCCCCC>'''F'''||
 160 ||<(>Name Vorname||    ||    ||<)>3.00||    ||<)>5.00||
 161 ||<(>Name Vorname||<)>1.00||<)>2.00||    ||<)>4.00||<)>5.00||
 162 ||<(>Name Vorname||<)>1.00||<)>2.00||    ||    ||<)>5.00||
 163 
 164 -----
 165 {{{
 166 -format 1,1}}}
 167 {{{
 168 #!sctable -format 1,1
 169 ||1||2||
 170 ||3||4||
 171 ||=@sum(a0:a1)||=a2*4||
 172 }}}
 173 
 174 RESULT:
 175 ||<)>1.0||<)>2.0||
 176 ||<)>3.0||<)>4.0||
 177 ||<)>4.0||<)>16.0||
 178 
 179 -----
 180 {{{ useage of variable names -show_formular -column_header  -row_header
 181 }}}
 182 {{{#!sctable -show_formular -column_header  -row_header
 183 ||A||B||C||
 184 ||1||{two}2||=A1+two||
 185 ||10||20||=@sum(A2:B2)||
 186 ||=@sum(A1:A2)||=@sum(B1:B2)||=@sum(C1:C2)||
 187 }}}
 188 
 189 
 190 RESULT:
 191 ||<:5%#CCCCCC> ||<:#CCCCCC>'''A'''||<:#CCCCCC>'''B'''||<:#CCCCCC>'''C'''||
 192 ||<)5%#CCCCCC>'''0'''||<(>A||<(>B||<(>C||
 193 ||<)5%#CCCCCC>'''1'''||<(>1||<(>{two}2||<(>=A1+two||
 194 ||<)5%#CCCCCC>'''2'''||<(>10||<(>20||<(>=@sum(A2:B2)||
 195 ||<)5%#CCCCCC>'''3'''||<(>=@sum(A1:A2)||<(>=@sum(B1:B2)||<(>=@sum(C1:C2)||
 196 
 197 and if we calculate [[BR]]
 198 RESULT:
 199 {{{#!sctable -column_header  -row_header
 200 ||A||B||C||
 201 ||1||{two}2||=A1+two||
 202 ||10||20||=@sum(A2:B2)||
 203 ||=@sum(A1:A2)||=@sum(B1:B2)||=@sum(C1:C2)||
 204 }}}
 205 -----
 206 {{{color in cells
 207 }}}
 208 {{{#!sctable
 209 ||<:rowbgcolor=lightcyan>'''A'''||<:>'''B'''||<:>'''C'''||
 210 ||<)#dddddd>1||<)#dddddd>{two}2||<)#cccccc>=A1+two||
 211 ||<(>10||<)>20||<:#dddddd>=@sum(A2:B2)||
 212 ||<rowbgcolor="#cc99ff">=@sum(A1:A2)||=@sum(B1:B2)||<bgcolor=magenta>=@sum(C1:C2)||
 213 }}}
 214 
 215 RESULT:
 216 ||<:rowbgcolor=lightcyan>'''A'''||<:>'''B'''||<:>'''C'''||
 217 ||<)#dddddd>1.00||<)#dddddd>2.00||<)#cccccc>3.00||
 218 ||<(>10.00||<)>20.00||<:#dddddd>30.00||
 219 ||<rowbgcolor="#cc99ff">11.00||22.00||<bgcolor=magenta>33.00||
 220 -----
 221 
 222 
 223     PROCEDURE:
 224       This processor needs the external sc (http://freshmeat.net/projects/sc/) routine.
 225       It is necessary to have a tmp directory in the wiki data dir.
 226       All formulars have to start by a "=" sign.
 227 
 228       Please remove the version number from the routine name!
 229 
 230 
 231     MODIFICATION:
 232        @copyright: 2004-09-19 by Reimar Bauer (R.Bauer@fz-juelich.de) sctable-1.2.3-1
 233        1.2.3-2 : (RB) bug fixed line #!sctable was not found by giving input parameters
 234        1.2.3-3 : (RB) input parameter -show_formular added, column width is set to 200 chars
 235                :      if this parameter is used
 236                : (RB) bug removed (already) #!sctable position could be different from 0
 237            :      but always greater -1
 238       1.2.3-4  : 2004-10-05 RB format always extended for sc call to 200 signs.
 239                  bug with blanks in names removed, more as one blank in a cell handled as one blank.
 240       1.2.3-5  : 2004-10-16 RB format codes for colors and cells removed before calculations
 241                  -format optional input var added
 242 
 243       1.3      : 2004-11-13 RB changed to PARSER
 244                  bug fixed: strings with blanks are formatted to the left
 245          feature added: column width of row numbers is set to 5%
 246          some examples fixed
 247 
 248       1.3.3-2 patch and examples from towi AT geocities DOT SPAM com implemented
 249               : format and colors are used by now!!
 250 
 251           FUNCTIONAL ADDITIONS
 252 
 253       * a cell can now start with an wiki format string that will format
 254           the cell according to wiki table formatting,
 255           examples:
 256           <:>@sum(A3:a6)
 257           <rowbgcolor=cyan>Title
 258 
 259        * you can define a name for a cell and use it later (no range defines yet):
 260          when combinign with <format> the format must come first.
 261          examples:
 262          {income}20000
 263          <:>{outcome}=income/2
 264 
 265     DISCUSSION (need help):
 266       * we need a better routine to destinguish between strings and numbers, i have still some problems with e.g
 267         def is_number(txt):
 268             ItIs = True
 269         try:
 270                 f =float(txt)
 271         except TypeError:
 272                 ItIs = False
 273 
 274         return(ItIs)
 275 
 276     This doesn't work with formulars =@sum(a0:a2)
 277 
 278         what I do at the moment is to scan digits and signs from a string. This does not right identify a dot (.)
 279     in a string. This will be formatted as number. Thats the only bad thing I know on.
 280 
 281     ideas are welcome.
 282 
 283         1.3.5-3: 2005-08-05 RB tmp path set relativ to installation and created if it isn't there
 284                            space before and after a cell entry by now ignored
 285                 
 286 
 287         1.3.5-4:  I had problems running this on FreeBSD. I had to install manually the source because the ports in FreeBSD seem to be out of date (using version 6.x of sc). Furthermore, i had to comment out the f.flush() call that was causing an I/O error for some reason. -- TheAnarcat 2005-12-18 23:34:15      
 288         
 289                
 290         1.5.2-5 : R.Bauer code revised (tabs removed!) 
 291 
 292 """
 293 
 294 Dependencies = []
 295 import sys, os, re, sha, string
 296 from MoinMoin.parser import wiki
 297 from MoinMoin.action import AttachFile
 298 from MoinMoin.Page import Page
 299 
 300 
 301 config_external_sc = "/usr/bin/sc"
 302 
 303 def table2sc(lines,format,show_formular,request):
 304     result = []
 305     formats = {} # { (row,col): '<wikiformat>', ... }
 306     r = 0
 307     name = "=" # searchstring
 308     col_names = ' ABCDEFGHIJKLMNOPQRSTUVWXYZ'
 309 
 310     first_line = lines[0]
 311     col_list = first_line.split('||')
 312     digit = "2"
 313     c = 0
 314     form = []
 315 
 316     col_list = col_list[0:len(col_list)-1]
 317     
 318     for value in col_list:
 319         if len(value.lstrip()) > 0:
 320               if (format == "") :
 321                   digit = "2"
 322               else:
 323                   digit = format[c-1]
 324 
 325         f = "%(command)s %(column)s 200 %(digit)s 0" % {
 326             "command": "format",
 327             "column": col_names[c],
 328             "digit": digit
 329             }
 330         form.append(f)
 331         c += 1
 332     result.append(form)
 333 
 334     for txt in lines:
 335         n_name = txt.count(name)
 336         txt = txt.lstrip()
 337         sargs = txt.split('||')
 338         n = len(sargs)
 339         sargs = sargs[0:n-1]
 340                 
 341         c = 0      # linecounter
 342         digits = "=-.0123456789"
 343         for arg in sargs:
 344             arg = arg.strip()
 345            
 346            # check for wiki formatting string at beginning of sc data: "<format>..."
 347             if arg.startswith('<'):
 348                 p = arg.find('>') + 1
 349                 if p > 1:
 350                     formats[(r,c)] , arg = arg[:p] , arg[p:]
 351                     arg = arg.strip()
 352                  
 353             # check for a sc column name define: "{defname}..."
 354             defname = None
 355             if show_formular == 0:
 356                 if arg.startswith('{'):
 357                     p = arg.find('}')
 358                     if p > 0:
 359                         defname, arg = arg[1:p] , arg[p+1:]
 360                     arg = arg.strip()
 361                     
 362             # sc data
 363             if len(arg) > 0:
 364                 if arg[0] in digits:
 365                     if arg.find(name) == 0:
 366                         if show_formular == 0:
 367                             sargs[c] = '%(command)s %(column)s%(r)s %(arg)s' % {
 368                                        'command': 'let',
 369                                        'column': col_names[c],
 370                                        'r': str(r),
 371                                        'arg': string.strip(arg)
 372                             }
 373                         else:
 374                             arg = string.replace(arg,"="," =")
 375                             sargs[c] = '%(command)s %(column)s%(r)s ="%(arg)s"' % {
 376                                        'command': 'leftstring',
 377                                        'column': col_names[c],
 378                                        'r': str(r),
 379                                        'arg': string.replace(arg,' ','')
 380                             }
 381 
 382                     else:
 383                          if (show_formular == 0):
 384                              sargs[c] = '%(command)s %(column)s%(r)s =%(arg)s' % {
 385                                         'command': 'let',
 386                                         'column': col_names[c],
 387                                         'r': str(r),
 388                                         'arg': string.strip(arg)
 389                              }
 390                          else:
 391                              sargs[c] = '%(command)s %(column)s%(r)s ="%(arg)s"' % {
 392                                         'command': 'leftstring',
 393                                         'column': col_names[c],
 394                                         'r': str(r),
 395                                         'arg': string.replace(arg,' ','')
 396                              }
 397 
 398                 else:
 399                     if c > 0:
 400                         if string.strip(arg) == "":
 401                             arg = "Blank!@"
 402                         else:
 403                             arg = string.strip(arg)
 404                             arg = string.replace(arg," ","Blank!@")
 405                         
 406                         sargs[c] = '%(command)s %(column)s%(r)s ="%(arg)s"' % {
 407                                    'command': 'leftstring',
 408                                    'column': col_names[c],
 409                                    'r': str(r),
 410                                    'arg': arg
 411                         }
 412             else:
 413                 if c > 0:
 414                     sargs[c] = '%(command)s %(column)s%(r)s ="%(arg)s"' % {
 415                                'command': 'leftstring',
 416                                'column': col_names[c],
 417                                'r': str(r),
 418                                'arg': ' Blank!@'
 419                     }
 420             
 421                             
 422             if defname:
 423                 sargs[c] = '%s\ndefine "%s" %s%s' % (sargs[c], defname, col_names[c], r)
 424             c += 1
 425         result.append(sargs)
 426         r += 1
 427     
 428     return(result,formats)
 429 
 430 class Parser:
 431 
 432     extensions = ['.sc']
 433     
 434     def __init__(self, raw, request, **kw):
 435 
 436         self.raw = raw
 437         self.request = request
 438         self.form = request.form
 439         self._ = request.getText
 440         self.kw = []
 441         for arg in kw.get('format_args','').split():
 442             self.kw.append(arg)
 443 
 444             
 445     def format(self, formatter):
 446         config_sc_vartmp_dir = os.path.join(self.request.rootpage.getPagePath(),'tmp')
 447         
 448         if not os.path.exists(config_sc_vartmp_dir):
 449             os.mkdir(config_sc_vartmp_dir)
 450 
 451         lines = self.raw.split('\n')
 452         
 453         kw = self.kw
 454         column_header = 0
 455         row_header = 0
 456         show_formular = 0
 457         format = ''
 458         zt = 0
 459         for test in kw:
 460              if test == '-column_header': column_header = 1
 461              if test == '-row_header': row_header = 1
 462              if test == '-show_formular': show_formular = 1
 463              if test == '-format': format = string.split(kw[zt+1],",")
 464              zt += 1
 465 
 466         matrix = []
 467         textstr = '\n'.join(lines).strip()
 468         tmpname = re.sub('\s+', ' ', textstr)
 469         tmpname = sha.new(tmpname.encode('utf8','replace')).hexdigest().upper()
 470         tmpname = tmpname + "_sc"
 471         tmpfile = "%s/%s.sc" % (config_sc_vartmp_dir, tmpname)
 472         textstr, formats = table2sc(lines,format,show_formular,self.request)
 473         
 474         data = open(tmpfile, "w")
 475         i = 0
 476         for txt in textstr:
 477             if len(textstr[i]) > 0:
 478                 tmpstr = string.join(textstr[i],'\n')
 479                 data.write('%s\n' % tmpstr.encode('latin-1'))
 480             i += 1
 481         data.close()
 482 
 483         cmd = "%(external_sc)s %(argument)s %(file)s " % {
 484                      "external_sc": config_external_sc,
 485                      "argument": " -W% ",
 486                      "file":tmpfile
 487                }
 488         
 489         f = os.popen(cmd,'r') # popen to get the result of the calculation
 490         result = f.readlines()
 491         #f.flush()
 492         os.unlink(tmpfile) # remove the tmpfile
 493 
 494         right_format = '<)>'
 495         left_format = '<(>'
 496 
 497         for txt in result:  
 498             txt = string.join(txt,'')
 499             cells = string.split(txt,' ')
 500             zres = []
 501             c = 1
 502             for value in cells:
 503                 value = string.join(value,'')
 504                 value = string.strip(value)
 505                 strlen = len(value)
 506 
 507                 if strlen > 0:
 508                     v = ord(value[0])
 509                     if ord('a') <= v <= ord('z') or ord('A') <= v <= ord('Z') or value[0] in " ":
 510                        format = left_format
 511                     else:
 512                         if show_formular == 0:
 513                             format = right_format
 514                         else:
 515                             format = left_format
 516 
 517                     if value == "Blank!@":
 518                         value = " "
 519 
 520                     if string.find(value,"Blank!@"):
 521                         value = string.replace(value,"Blank!@", " ")
 522 
 523                     zres.append( [format, value] )
 524 
 525                     c += 1
 526             matrix.append(zres)
 527         # post formatting of cells according to cut out wiki format strings
 528         # - matrix is here: [ [  [format,content], ... ], ... ]
 529                 
 530         for cellname, cellformat in formats.items():
 531             row, col = cellname
 532             m = matrix[row][col-1]
 533             m[0] = str(cellformat)
 534         
 535         matrix = map(lambda row: "||" + "||".join([f+c for f,c in row]) + "||", matrix)
 536     
 537             # post processing of over all matrix
 538             # - matrix is here: [ "||cell||cell||...||", "||cell||...||", ... ]
 539        
 540         if row_header == 1:
 541             y = []
 542             r = len(matrix)
 543             lines = range(r)
 544 
 545             i = 0
 546             for no in lines:
 547                 matrix[i] = "||<)5%#CCCCCC>'''" + str(no) + "'''"+matrix[i]
 548                 i += 1
 549   
 550         if column_header == 1:
 551             col_names = ' ABCDEFGHIJKLMNOPQRSTUVWXYZ'
 552             x = '||'
 553             if row_header == 1:
 554                 start = 0
 555             else:
 556                 start = 1
 557         
 558             for name in col_names[start:c]:
 559                 x = x + '%(format)s %(value)s %(tab)s' % {
 560                             "format": '<:#CCCCCC>',
 561                             "value": "'''"+name+"'''",
 562                             "tab": '||'}
 563 
 564             matrix.insert(0,x)
 565                 
 566         wikiizer = wiki.Parser(unicode(string.join(matrix,"\n"),'latin-1'),self.request) # parser for wiki tabular
 567         wikiizer.format(formatter)
 568 
 569       

Attached Files

To refer to attachments on a page, use attachment:filename, as shown below in the list of files. Do NOT use the URL of the [get] link, since this is subject to change and can break easily.
  • [get | view] (2005-03-01 20:40:25, 14.3 KB) [[attachment:sctable-1.3.3-2.py]]
  • [get | view] (2005-08-05 18:25:35, 15.0 KB) [[attachment:sctable-1.3.5-3.py]]
  • [get | view] (2004-11-13 21:01:43, 11.1 KB) [[attachment:sctable-1.3.py]]
  • [get | view] (2006-03-11 16:11:28, 17.0 KB) [[attachment:sctable-1.5.2-5.py]]
 All files | Selected Files: delete move to page copy to page

You are not allowed to attach a file to this page.