From f4475e3e0fc36542e70c16888e7d20a40e3680b1 Mon Sep 17 00:00:00 2001 From: Walter Bender Date: Fri, 19 Nov 2010 14:16:38 +0000 Subject: adding RTF support for show_description --- diff --git a/TurtleArt/RtfParser.py b/TurtleArt/RtfParser.py new file mode 100644 index 0000000..4b1f1dc --- /dev/null +++ b/TurtleArt/RtfParser.py @@ -0,0 +1,156 @@ +#Copyright (c) 2010, Loic Fejoz +#Copyright (c) 2010, Walter Bender + +# 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. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the +# Free Software Foundation, Inc., 59 Temple Place - Suite 330, +# Boston, MA 02111-1307, USA. + + +import sys + +class RtfException(Exception): + pass + +plaintext = 1 +control = 2 +argument = 3 +backslash = 4 +escapedChar = 5 + +class RtfParser(object): + + def __init__(self, unicode=False): + self.state = plaintext + self.arg = '' + self.token = '' + self.unicode = unicode + self.par = False + self.output = '' + + def getChar(self, code): + """ called when an escaped char is found """ + return chr(code) + + def getNonBreakingSpace(self): + return ' ' + + def pushState(self): + pass + + def popState(self): + pass + + def putChar(self): + pass + + def doControl(self,token,arg): + pass + + def feed(self,txt): + for c in txt: + self.feedChar(c) + + def feedChar(self,char): + if self.state == plaintext: # this is just normal user content + if char == '\\': + self.state = backslash + elif char == '{': + self.pushState() + elif char == '}': + self.popState() + else: + self.putChar(char) + elif self.state == backslash: # a command or escape + if char == '\\' or char == '{' or char == '}': + self.putChar(char) + self.state = plaintext + else: + if char.isalpha() or char in ('*', '-', '|'): + self.state = control + self.token = char + elif char == "'": + self.state = escapedChar + self.escapedChar = '' + elif char in ['\\', '{','}']: + self.putChar(char) + self.state = plaintext + elif char == "~": # non breaking space + self.putChar(self.getNonBreakingSpace()) + self.state = plaintext + else: + raise RtfException,'unexpected %s after \\' % char + elif self.state == escapedChar: + self.escapedChar = self.escapedChar + char + if len(self.escapedChar) == 2: + char = self.getChar(int(self.escapedChar,16)) + self.putChar(char) + self.state = plaintext + elif self.state == control: # collecting the command token + if char.isalpha(): + self.token = self.token + char + elif char.isdigit() or char== '-': + self.state = argument + self.arg = char + else: + self.doControl(self.token,self.arg) + self.state = plaintext + if char == '\\': + self.state = backslash + elif char == '{': + self.pushState() + elif char == '}': + self.popState() + else: + if not char.isspace(): + self.putChar(char) + elif self.state == argument: # collecting the optional command argument + if char.isdigit(): + self.arg = self.arg + char + else: + self.state = plaintext + self.doControl(self.token,self.arg) + if char == '\\': + self.state = backslash + elif char == '{': + self.pushState() + elif char == '}': + self.popState() + else: + if not char.isspace(): + self.putChar(char) + + +class RtfTextOnly(RtfParser): + def __init__(self): + RtfParser.__init__(self) + self.level = 0 + + def pushState(self): + self.level = self.level + 1 + + def popState(self): + self.level = self.level - 1 + + def putChar(self,ch): + if self.par: + self.output += ch + + def doControl(self,token,arg): + if token[0:3] == 'par': + self.par = True + pass + +if __name__ == '__main__': + text_only = RtfTextOnly() + if len(sys.argv) != 2: + print 'Usage : %s file.rtf' % sys.argv[0] + else: + for line in open(sys.argv[1], 'r'): + text_only.feed(line) + print text_only.output diff --git a/TurtleArt/talogo.py b/TurtleArt/talogo.py index 2e172f4..30fd617 100644 --- a/TurtleArt/talogo.py +++ b/TurtleArt/talogo.py @@ -22,12 +22,14 @@ #THE SOFTWARE. import gtk + from time import clock, sleep from math import sqrt from numpy import append from numpy.fft import rfft from random import uniform from operator import isNumberType + from UserDict import UserDict try: @@ -37,12 +39,17 @@ except: from taconstants import PALETTES, PALETTE_NAMES, TAB_LAYER, BLACK, WHITE, \ DEFAULT_SCALE, ICON_SIZE, BLOCK_NAMES, CONSTANTS, SENSOR_DC_NO_BIAS, \ - SENSOR_DC_BIAS + SENSOR_DC_BIAS, XO1, XO15 from tagplay import play_audio, play_movie_from_file, stop_media from tajail import myfunc, myfunc_import from tautils import get_pixbuf_from_journal, movie_media_type, convert, \ audio_media_type, text_media_type, round_int, chr_to_ord, \ - strtype + strtype, data_from_file + +from RtfParser import RtfTextOnly + +from ringbuffer import RingBuffer1d + from gettext import gettext as _ VALUE_BLOCKS = ['box1', 'box2', 'color', 'shade', 'gray', 'scale', 'pensize', @@ -468,6 +475,7 @@ class LogoCode: self.heap = [] self.iresults = None self.step = None + self.bindex = None self.hidden_turtle = None @@ -487,9 +495,14 @@ class LogoCode: self.max_samples = 1500 self.input_step = 1 - from ringbuffer import RingBuffer1d + self.ringbuffer = RingBuffer1d(self.max_samples, dtype='int16') - self.audio_mode = None + if self.tw.hw == XO1: + self.voltage_gain = 0.00002225 + self.voltage_bias = 1.140 + elif self.tw.hw == XO15: + self.voltage_gain = -0.0001471 + self.voltage_bias = 1.695 def _def_prim(self, name, args, fcn, rprim=False): """ Define the primitives associated with the blocks """ @@ -671,18 +684,19 @@ class LogoCode: self.arglist = None while self.iline: token = self.iline[0] - bindex = None + self.bindex = None if type(token) == tuple: - (token, bindex) = self.iline[0] + (token, self.bindex) = self.iline[0] # If the blocks are visible, highlight the current block. - if not self.tw.hide and bindex is not None: - self.tw.block_list.list[bindex].highlight() + if not self.tw.hide and self.bindex is not None: + self.tw.block_list.list[self.bindex].highlight() # In debugging modes, we pause between steps and show the turtle. if self.tw.step_time > 0: self.tw.active_turtle.show() endtime = _millisecond() + self._int(self.tw.step_time) * 100 + sleep(self.tw.step_time / 10) while _millisecond() < endtime: yield True self.tw.active_turtle.hide() @@ -691,23 +705,23 @@ class LogoCode: if token == self.symopar: token = self.iline[1] if type(token) == tuple: - (token, bindex) = self.iline[1] + (token, self.bindex) = self.iline[1] # Process the token and any arguments. self._icall(self._eval) yield True # Time to unhighlight the current block. - if not self.tw.hide and bindex is not None: - self.tw.block_list.list[bindex].unhighlight() + if not self.tw.hide and self.bindex is not None: + self.tw.block_list.list[self.bindex].unhighlight() if self.procstop: break if self.iresult == None: continue - if bindex is not None: - self.tw.block_list.list[bindex].highlight() + if self.bindex is not None: + self.tw.block_list.list[self.bindex].highlight() raise logoerror(str(self.iresult)) self.iline = oldiline self._ireturn() @@ -725,7 +739,6 @@ class LogoCode: # Either we are processing a symbol or a value. if type(token) == self.symtype: # We highlight blocks here in case an error occurs... - # print "> ", token if not self.tw.hide and bindex is not None: self.tw.block_list.list[bindex].highlight() self._icall(self._evalsym, token) @@ -735,7 +748,6 @@ class LogoCode: self.tw.block_list.list[bindex].unhighlight() res = self.iresult else: - # print ": ", token res = token self._ireturn(res) @@ -1027,17 +1039,14 @@ class LogoCode: def _prim_myblock(self, x): """ Run Python code imported from Journal """ - if self.tw.myblock is not None: + if self.bindex is not None and self.bindex in self.tw.myblock: try: if len(x) == 1: - y = myfunc_import(self, self.tw.myblock, x[0]) + y = myfunc_import(self, self.tw.myblock[self.bindex], x[0]) else: - y = myfunc_import(self, self.tw.myblock, x) + y = myfunc_import(self, self.tw.myblock[self.bindex], x) except: raise logoerror("#syntaxerror") - else: - raise logoerror("#nocode") - return def _prim_print(self, n, flag): """ Print n """ @@ -1089,15 +1098,12 @@ class LogoCode: for name in ['sound', 'volume', 'pitch']: if len(self.value_blocks[name]) > 0: self.tw.audiograb.set_sensor_type() - self.audio_mode = 'sound' return if len(self.value_blocks['resistance']) > 0: self.tw.audiograb.set_sensor_type(SENSOR_DC_BIAS) - self.audio_mode = 'resistance' return elif len(self.value_blocks['voltage']) > 0: self.tw.audiograb.set_sensor_type(SENSOR_DC_NO_BIAS) - self.audio_mode = 'voltage' return def update_label_value(self, name, value=None): @@ -1180,6 +1186,14 @@ class LogoCode: self.update_label_value('pop', self.heap[-2]) return self.heap.pop(-1) + def push_file_data_to_heap(self, dsobject): + """ push contents of a data store object (assuming json encoding) """ + data = data_from_file(dsobject.file_path) + if data is not None: + for val in data: + self.heap.append(val) + self.update_label_value('pop', val) + def _empty_heap(self): """ Empty FILO """ self.heap = [] @@ -1347,11 +1361,17 @@ class LogoCode: if self.tw.running_sugar: try: dsobject = datastore.get(media[6:]) - # TODO: handle rtf, pdf, etc. (See #893) + # TODO: handle doc, odt, pdf (See #893) if text_media_type(dsobject.file_path): - f = open(dsobject.file_path, 'r') - text = f.read() - f.close() + if dsobject.metadata['mime_type'] == 'application/rtf': + text_only = RtfTextOnly() + for line in open(dsobject.file_path, 'r'): + text_only.feed(line) + text = text_only.output + else: + f = open(dsobject.file_path, 'r') + text = f.read() + f.close() else: text = str(dsobject.metadata['description']) dsobject.destroy() @@ -1359,9 +1379,15 @@ class LogoCode: _logger.debug("no description in %s" % (media[6:])) else: try: - f = open(media[6:], 'r') - text = f.read() - f.close() + if media.endswith(('rtf')): + text_only = RtfTextOnly() + for line in open(media[6:], 'r'): + text_only.feed(line) + text = text_only.output + else: + f = open(media[6:], 'r') + text = f.read() + f.close() except: _logger.debug("no text in %s?" % (media[6:])) if text is not None: @@ -1426,7 +1452,15 @@ class LogoCode: if len(buf) > 0: # See # TODO: test this calibration on XO 1.5 - resistance = 2.718 ** ((float(_avg(buf)) * 0.000045788) + 8.0531) + if self.tw.hw == XO1: + resistance = 2.718 ** ((float(_avg(buf)) * 0.000045788) + \ + 8.0531) + else: + avg_buf = float(_avg(buf)) + if avg_buf > 0: + resistance = (420000000 / avg_buf) - 13500 + else: + resistance = 420000000 self.update_label_value('resistance', resistance) return resistance else: @@ -1437,8 +1471,7 @@ class LogoCode: buf = self.ringbuffer.read(None, self.input_step) if len(buf) > 0: # See - # TODO: test this calibration on XO 1.5 - voltage = float(_avg(buf)) * 0.00002225 + 1.140 + voltage = float(_avg(buf)) * self.voltage_gain + self.voltage_bias self.update_label_value('voltage', voltage) return voltage else: diff --git a/TurtleArt/tautils.py b/TurtleArt/tautils.py index f6d410b..2bd03c2 100644 --- a/TurtleArt/tautils.py +++ b/TurtleArt/tautils.py @@ -316,7 +316,7 @@ def image_media_type(name): def text_media_type(name): """ Is it text media? """ - return name.endswith(('.txt', '.py', '.lg', '.doc', '.rtf')) + return name.endswith(('.txt', '.py', '.lg', '.rtf')) def round_int(num): -- cgit v0.9.1