pythonreports-checkins Mailing List for PythonReports (Page 2)
Brought to you by:
a1s
You can subscribe to this list here.
2006 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
(45) |
Dec
(56) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2007 |
Jan
|
Feb
(2) |
Mar
|
Apr
|
May
(1) |
Jun
(4) |
Jul
|
Aug
|
Sep
|
Oct
|
Nov
(1) |
Dec
(6) |
2009 |
Jan
|
Feb
|
Mar
(5) |
Apr
(1) |
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2010 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
(5) |
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2011 |
Jan
(10) |
Feb
(1) |
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
(5) |
Oct
(1) |
Nov
(3) |
Dec
|
2012 |
Jan
|
Feb
|
Mar
(10) |
Apr
|
May
(18) |
Jun
(6) |
Jul
|
Aug
|
Sep
|
Oct
|
Nov
(1) |
Dec
|
From: alexander s. <a1...@us...> - 2012-03-30 09:06:44
|
Update of /cvsroot/pythonreports/htdocs In directory vz-cvs-3.sog:/tmp/cvs-serv20272 Modified Files: header.shtml style.css Log Message: Source code repository changed to Bazaar Index: style.css =================================================================== RCS file: /cvsroot/pythonreports/htdocs/style.css,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -C2 -d -r1.1.1.1 -r1.2 *** style.css 25 Feb 2007 05:42:26 -0000 1.1.1.1 --- style.css 30 Mar 2012 09:06:40 -0000 1.2 *************** *** 57,61 **** padding-top: 1em; /* must be wider than p.logos which includes 125px-wide sf logo */ ! width: 135px; } --- 57,61 ---- padding-top: 1em; /* must be wider than p.logos which includes 125px-wide sf logo */ ! width: 140px; } Index: header.shtml =================================================================== RCS file: /cvsroot/pythonreports/htdocs/header.shtml,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** header.shtml 11 Mar 2009 07:33:19 -0000 1.3 --- header.shtml 30 Mar 2012 09:06:40 -0000 1.4 *************** *** 13,17 **** <ul> <li class="menul1"><a href="http://sourceforge.net/project/showfiles.php?group_id=181233">Download</a></li> ! <li class="menul1"><a href="http://pythonreports.cvs.sourceforge.net/pythonreports/">Browse CVS</a></li> <li class="menul1"><a href="http://sourceforge.net/projects/pythonreports/">Project page</a></li> <li class="menul1"><hr /></li> --- 13,17 ---- <ul> <li class="menul1"><a href="http://sourceforge.net/project/showfiles.php?group_id=181233">Download</a></li> ! <li class="menul1"><a href="http://pythonreports.bzr.sourceforge.net/bzr/pythonreports/files">Browse sources</a></li> <li class="menul1"><a href="http://sourceforge.net/projects/pythonreports/">Project page</a></li> <li class="menul1"><hr /></li> |
From: KACAH <ka...@us...> - 2012-03-09 10:57:08
|
Update of /cvsroot/pythonreports/PythonReports/test/tester/tests/General/Empty In directory vz-cvs-3.sog:/tmp/cvs-serv30560/test/tester/tests/General/Empty Added Files: data.in template.prt valid_printout.prp Log Message: Added automatic tests: Empty report, Empty field --- NEW FILE: valid_printout.prp --- <printout> <page bottommargin="3" height="842" leftmargin="57" rightmargin="28" topmargin="3" width="595" /> </printout> --- NEW FILE: data.in --- --- NEW FILE: template.prt --- <report> <layout pagesize="A4" leftmargin="2.0cm" rightmargin="1.0cm" topmargin="0.1cm" bottommargin="0.1cm"> <detail> </detail> </layout> </report> |
From: KACAH <ka...@us...> - 2012-03-09 10:57:07
|
Update of /cvsroot/pythonreports/PythonReports/test/tester/tests In directory vz-cvs-3.sog:/tmp/cvs-serv30560/test/tester/tests Added Files: tests.cfg Log Message: Added automatic tests: Empty report, Empty field --- NEW FILE: tests.cfg --- General: - name: Empty folder: General/Empty description: Test minimal template complect without data fail_message: Reports don't work at all Fields: - name: Empty Field folder: Fields\EmptyField description: Test empty field fail_message: Empty field don't work |
From: KACAH <ka...@us...> - 2012-03-09 10:47:55
|
Update of /cvsroot/pythonreports/PythonReports/test/tester/tests/Fields/EmptyField In directory vz-cvs-3.sog:/tmp/cvs-serv30306/test/tester/tests/Fields/EmptyField Log Message: Directory /cvsroot/pythonreports/PythonReports/test/tester/tests/Fields/EmptyField added to the repository |
From: KACAH <ka...@us...> - 2012-03-09 10:47:33
|
Update of /cvsroot/pythonreports/PythonReports/test/tester/tests/General/Empty In directory vz-cvs-3.sog:/tmp/cvs-serv30296/test/tester/tests/General/Empty Log Message: Directory /cvsroot/pythonreports/PythonReports/test/tester/tests/General/Empty added to the repository |
From: KACAH <ka...@us...> - 2012-03-09 10:47:01
|
Update of /cvsroot/pythonreports/PythonReports/test/tester/tests/Fields In directory vz-cvs-3.sog:/tmp/cvs-serv30273/test/tester/tests/Fields Log Message: Directory /cvsroot/pythonreports/PythonReports/test/tester/tests/Fields added to the repository |
From: KACAH <ka...@us...> - 2012-03-09 10:46:39
|
Update of /cvsroot/pythonreports/PythonReports/test/tester/tests/General In directory vz-cvs-3.sog:/tmp/cvs-serv30257/test/tester/tests/General Log Message: Directory /cvsroot/pythonreports/PythonReports/test/tester/tests/General added to the repository |
From: KACAH <ka...@us...> - 2012-03-09 10:45:41
|
Update of /cvsroot/pythonreports/PythonReports/test/tester/tests In directory vz-cvs-3.sog:/tmp/cvs-serv30226/test/tester/tests Log Message: Directory /cvsroot/pythonreports/PythonReports/test/tester/tests added to the repository |
From: KACAH <ka...@us...> - 2012-03-09 10:42:54
|
Update of /cvsroot/pythonreports/PythonReports/test/tester In directory vz-cvs-3.sog:/tmp/cvs-serv30139/test/tester Added Files: run_tests.py Log Message: Added automatic tester template+data -> printout --- NEW FILE: run_tests.py --- """PythonReports automatic unit tester Read Tests/tests.cfg and test all tests from all categories """ """ 28-feb-2012 [kacah] created """ import os import PythonReports.builder import PythonReports.template import yaml def build_printout(template_file, data): """Build printout using PythonReports""" _template = PythonReports.template.load(template_file) _builder = PythonReports.builder.Builder(_template) return _builder.run(data) def get_differences_list(file1, file2): """Get list of differences in files""" import difflib _differences = difflib.unified_diff( open(file1).readlines(), open(file2).readlines()) return list(_differences) def load_data(test): """Load data from data.in file in yaml format""" _data = [] try: with open(os.path.join("tests", test["folder"], "data.in")) as _f: _data = yaml.load(_f) if not _data: _data = [] except IOError, _err: print "Warning, data.in file not found" except Exception, _err: print "data.in file has invalid yaml syntax", _err return _data def write_result(test, defferences, error=None): """Write result of test to diff.txt file""" _diff_file = os.path.join("tests", test["folder"], "diff.txt") with open(_diff_file, "w") as _f: if defferences is None: print >> _f, error else: for _str in defferences: _f.write(_str) return _diff_file def print_result_message(test, differences, diff_file): """Print result of test to screen""" if differences is None: print test.get("fail_message") print "Error! Please check", diff_file elif len(differences): print test.get("fail_message") print "There are some differences, please check", diff_file else: print "Successful" def run_test(test): """Run single unit test""" print print "Starting test %s from %s" % (test["name"], test["folder"]) if test.get("description"): print " ", test["description"] _template_file = os.path.join("tests", test["folder"], "template.prt") _data = load_data(test) _error = None _differences = None try: _printout = build_printout(_template_file, _data) _output_file = os.path.join("tests", test["folder"], "last_printout.prp") _printout.write(_output_file) _valid_file = os.path.join("tests", test["folder"], "valid_printout.prp") _differences = get_differences_list(_output_file, _valid_file) except Exception, _err: _error = _err _diff_file = write_result(test, _differences, _error) print_result_message(test, _differences, _diff_file) def test_groups(groups): """Test all categories in tests.cfg""" for _group_name, _group in groups.iteritems(): print "----------------------------------" print "Testing", _group_name for _test in _group: run_test(_test) def main(): with open("Tests/tests.cfg", "r") as _f: _tests = yaml.load(_f) test_groups(_tests) print "----------------------------------" if __name__ == "__main__": main() |
From: KACAH <ka...@us...> - 2012-03-09 10:40:50
|
Update of /cvsroot/pythonreports/PythonReports/test/tester In directory vz-cvs-3.sog:/tmp/cvs-serv30059/test/tester Log Message: Directory /cvsroot/pythonreports/PythonReports/test/tester added to the repository |
From: Alexey L. <a-...@us...> - 2011-11-25 10:14:12
|
Update of /cvsroot/pythonreports/PythonReports/PythonReports In directory vz-cvs-3.sog:/tmp/cvs-serv17797 Modified Files: pdf.py Log Message: priority to embedded images instead of external files Index: pdf.py =================================================================== RCS file: /cvsroot/pythonreports/PythonReports/PythonReports/pdf.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** pdf.py 11 Oct 2011 14:50:19 -0000 1.5 --- pdf.py 25 Nov 2011 10:14:10 -0000 1.6 *************** *** 2,5 **** --- 2,6 ---- """PDF output for PythonReports""" """History (most recent first): + 25-oct-2011 [luch] priority to embedded images instead of external files 11-oct-2011 [luch] adapted to PIL 1.1.7 07-dec-2006 [als] fix: diagonal lines were offset down by the box height *************** *** 308,325 **** """Draw an image""" _scale = image.get("scale", True) ! _img = image.get("file") ! if _img: # it is better to use filename unless we have to cut the image # (scale will be done by reportlab) if not _scale: _img = Image.open(_img) - else: - _data = image.get("data") - if _data: - _img = self.named_images[_data] - else: - # image data must be child element - _data = StringIO(Data.get_data(image.find("data"))) - _img = Image.open(_data) (_x, _y, _width, _height) = self.getDimensions(image) if _scale: --- 309,324 ---- """Draw an image""" _scale = image.get("scale", True) ! # actually, builder embeds all images into the printout ! if image.find("data") is not None: ! _data = StringIO(Data.get_data(image.find("data"))) ! _img = Image.open(_data) ! elif image.get("data"): ! _img = self.named_images[image.get("data")] ! else: ! _img = image.get("file") # it is better to use filename unless we have to cut the image # (scale will be done by reportlab) if not _scale: _img = Image.open(_img) (_x, _y, _width, _height) = self.getDimensions(image) if _scale: |
From: Alexey L. <a-...@us...> - 2011-11-25 10:06:48
|
Update of /cvsroot/pythonreports/PythonReports/PythonReports In directory vz-cvs-3.sog:/tmp/cvs-serv15647 Modified Files: template.py Log Message: explicitly set Report.filename Index: template.py =================================================================== RCS file: /cvsroot/pythonreports/PythonReports/PythonReports/template.py,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** template.py 19 Dec 2006 14:44:56 -0000 1.9 --- template.py 25 Nov 2011 10:06:46 -0000 1.10 *************** *** 1,4 **** --- 1,5 ---- """PythonReports Template (PRT) structures""" """History (most recent first): + 25-nov-2011 [luch] explicitly set Report.filename 19-dec-2006 [als] fix: Arg value is expression 15-dec-2006 [als] added Arg and Subreport *************** *** 38,41 **** --- 39,44 ---- ] + import os + from PythonReports.datatypes import * *************** *** 384,387 **** --- 387,391 ---- tree.groups = {} tree.fonts = {} + tree.filename = None # don't create datablocks here - will be done in Layout prevalidator *************** *** 404,410 **** def load(source): ! """Load printout file, return ElementTree""" _et = ElementTree(Report) _et.parse(source) return _et --- 408,417 ---- def load(source): ! """Load template file, return ElementTree""" _et = ElementTree(Report) _et.parse(source) + if os.path.exists(source): + # XXX bad heuristics + _et.filename = source return _et |
From: Alexey L. <a-...@us...> - 2011-11-25 10:01:58
|
Update of /cvsroot/pythonreports/PythonReports/PythonReports In directory vz-cvs-3.sog:/tmp/cvs-serv13830 Modified Files: printout.py Log Message: comment added Index: printout.py =================================================================== RCS file: /cvsroot/pythonreports/PythonReports/PythonReports/printout.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** printout.py 6 Dec 2006 16:54:39 -0000 1.2 --- printout.py 25 Nov 2011 10:01:56 -0000 1.3 *************** *** 118,122 **** "version": (String, None), "author": (String, None), ! "basedir": (String, None), # TODO: "built": (Timestamp, None), }, children=( --- 118,122 ---- "version": (String, None), "author": (String, None), ! "basedir": (String, None), # WARNING useless, always None actually # TODO: "built": (Timestamp, None), }, children=( |
From: Alexey L. <a-...@us...> - 2011-10-11 14:50:23
|
Update of /cvsroot/pythonreports/PythonReports/PythonReports In directory vz-cvs-3.sog:/tmp/cvs-serv17881/PythonReports Modified Files: pdf.py Log Message: adapted to PIL 1.1.7 Index: pdf.py =================================================================== RCS file: /cvsroot/pythonreports/PythonReports/PythonReports/pdf.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** pdf.py 7 Dec 2006 12:21:50 -0000 1.4 --- pdf.py 11 Oct 2011 14:50:19 -0000 1.5 *************** *** 2,5 **** --- 2,6 ---- """PDF output for PythonReports""" """History (most recent first): + 11-oct-2011 [luch] adapted to PIL 1.1.7 07-dec-2006 [als] fix: diagonal lines were offset down by the box height 05-dec-2006 [als] sweep pylint warnings; *************** *** 326,331 **** else: (_img_width, _img_height) = _img.size ! _img = _img.crop( ! (0, 0, min(_width, _img_width), min(_height, _img_height))) self.canvas.drawImage(ImageReader(_img), _x, _y) --- 327,332 ---- else: (_img_width, _img_height) = _img.size ! _img = _img.crop((0, 0, int(min(_width, _img_width)), ! int(min(_height, _img_height)))) self.canvas.drawImage(ImageReader(_img), _x, _y) |
From: alexander s. <a1...@us...> - 2011-09-26 17:51:32
|
Update of /cvsroot/pythonreports/PythonReports In directory vz-cvs-3.sog:/tmp/cvs-serv27681 Modified Files: CHANGES Log Message: version 0.5.0 Index: CHANGES =================================================================== RCS file: /cvsroot/pythonreports/PythonReports/CHANGES,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** CHANGES 22 Jul 2010 06:08:48 -0000 1.9 --- CHANGES 26 Sep 2011 17:51:30 -0000 1.10 *************** *** 2,5 **** --- 2,15 ---- ============================= + version 0.5.0 (26-sep-2011) + --------------------------- + + Features (thanks Alexey Luchko): + + - implemented floating elements + - on Windows, search unknown font names in the Windows fonts registry + + Fix XML escaping for data blocks. + version 0.4.0 (22-jul-2010) --------------------------- |
From: alexander s. <a1...@us...> - 2011-09-26 17:50:01
|
Update of /cvsroot/pythonreports/PythonReports/PythonReports In directory vz-cvs-3.sog:/tmp/cvs-serv26543 Modified Files: version.py Log Message: version 0.5.0 Index: version.py =================================================================== RCS file: /cvsroot/pythonreports/PythonReports/PythonReports/version.py,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** version.py 22 Jul 2010 06:08:19 -0000 1.9 --- version.py 26 Sep 2011 17:49:59 -0000 1.10 *************** *** 7,12 **** # wouldn't datetime.date object be better? ! __version__ = "0.4.0" ! __date__ = "2010-07-22" __all__ = ["__version__", "__date__"] --- 7,12 ---- # wouldn't datetime.date object be better? ! __version__ = "0.5.0" ! __date__ = "2011-09-26" __all__ = ["__version__", "__date__"] |
From: alexander s. <a1...@us...> - 2011-09-26 17:48:55
|
Update of /cvsroot/pythonreports/PythonReports In directory vz-cvs-3.sog:/tmp/cvs-serv26465 Modified Files: setup.py Log Message: update URL for the downloads page Index: setup.py =================================================================== RCS file: /cvsroot/pythonreports/PythonReports/setup.py,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** setup.py 22 Jul 2010 06:31:40 -0000 1.6 --- setup.py 26 Sep 2011 17:48:52 -0000 1.7 *************** *** 3,6 **** --- 3,7 ---- # FIXME! generate_docs() must be reimplemented as a distutils command """History: + 26-sep-2011 [als] update URL for the downloads page 22-jul-2010 [als] development status set to Beta 07-nov-2006 [als] data_files include source (*.txt) documents *************** *** 95,103 **** url="http://pythonreports.sourceforge.net/", download_url= ! "http://sourceforge.net/project/showfiles.php?group_id=181233", description="Database report generator", long_description=DESCRIPTION, author="alexander smishlajev", ! author_email="al...@Ty...", # XXX maintainer_email always overwrites author_email. # (good thing too, but PyPI has two slots, and i'd like to --- 96,104 ---- url="http://pythonreports.sourceforge.net/", download_url= ! "http://sourceforge.net/projects/pythonreports/files/", description="Database report generator", long_description=DESCRIPTION, author="alexander smishlajev", ! author_email="al...@go...", # XXX maintainer_email always overwrites author_email. # (good thing too, but PyPI has two slots, and i'd like to |
From: alexander s. <a1...@us...> - 2011-09-26 16:43:21
|
Update of /cvsroot/pythonreports/PythonReports/PythonReports In directory vz-cvs-3.sog:/tmp/cvs-serv18242 Modified Files: builder.py Log Message: check_printable: return bool Index: builder.py =================================================================== RCS file: /cvsroot/pythonreports/PythonReports/PythonReports/builder.py,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** builder.py 28 Feb 2011 14:11:32 -0000 1.12 --- builder.py 26 Sep 2011 16:43:19 -0000 1.13 *************** *** 594,599 **** for _style in self.iter_styles() if context.eval(_style.get("when")) and _style.get("printwhen")) ! self.printable = not _printwhen or context.eval(_printwhen[0]) ! return self.printable @staticmethod --- 594,599 ---- for _style in self.iter_styles() if context.eval(_style.get("when")) and _style.get("printwhen")) ! self.printable = (not _printwhen) or context.eval(_printwhen[0]) ! return bool(self.printable) @staticmethod |
From: alexander s. <a1...@us...> - 2011-09-26 16:02:01
|
Update of /cvsroot/pythonreports/PythonReports/PythonReports In directory vz-cvs-3.sog:/tmp/cvs-serv12146 Modified Files: segment_layout.py Log Message: cosmetic changes Index: segment_layout.py =================================================================== RCS file: /cvsroot/pythonreports/PythonReports/PythonReports/segment_layout.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** segment_layout.py 26 Jan 2011 13:47:27 -0000 1.1 --- segment_layout.py 26 Sep 2011 16:01:59 -0000 1.2 *************** *** 16,21 **** actual width of segments after stretching. ! Layout is based on segment dependency DAG -- directed acyclic graph. ! All segments, that a segment depends on, should be wholly at its left. Each segment has a non-negative gap to the nearest segment of those --- 16,21 ---- actual width of segments after stretching. ! Layout is based on segment dependency DAG (Directed Acyclic Graph). ! All segments that a segment depends on should be wholly at its left. Each segment has a non-negative gap to the nearest segment of those *************** *** 23,27 **** width is positive. Zero width segments are considered meaningless. ! Example: 1 depend on A and B, 2 depends on 1, Z depends 1, 3 depends on 2 and Z. --- 23,27 ---- width is positive. Zero width segments are considered meaningless. ! Example: 1 depend on A and B, 2 depends on 1, Z depends on 1, 3 depends on 2 and Z. *************** *** 44,52 **** :bbbbbb zzz ! - A and B collapses:: : 1111 222222 333 : zzz ! At present there is no other way avoid leading gap when A and B collapes, other than make zero gap. --- 44,52 ---- :bbbbbb zzz ! - A and B collapse:: : 1111 222222 333 : zzz ! At present there is no way to avoid leading gap when A and B collapse other than make zero gap. *************** *** 221,225 **** ! def toposort(direcred_graph): """@return: vertexes of directed acyclic graph in C{toposort} order --- 221,225 ---- ! def toposort(directed_graph): """@return: vertexes of directed acyclic graph in C{toposort} order *************** *** 242,250 **** if vertex not in _visited: _visited.add(vertex) ! for child in direcred_graph[vertex]: _walk(child) _vertex_order.append(vertex) ! for _vertex in direcred_graph: _walk(_vertex) return _vertex_order --- 242,250 ---- if vertex not in _visited: _visited.add(vertex) ! for child in directed_graph[vertex]: _walk(child) _vertex_order.append(vertex) ! for _vertex in directed_graph: _walk(_vertex) return _vertex_order |
From: Alexey L. <a-...@us...> - 2011-02-28 14:11:34
|
Update of /cvsroot/pythonreports/PythonReports/PythonReports In directory vz-cvs-2.sog:/tmp/cvs-serv11993 Modified Files: builder.py Log Message: negative-height items do not affect section height Index: builder.py =================================================================== RCS file: /cvsroot/pythonreports/PythonReports/PythonReports/builder.py,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -d -r1.11 -r1.12 *** builder.py 26 Jan 2011 13:49:06 -0000 1.11 --- builder.py 28 Feb 2011 14:11:32 -0000 1.12 *************** *** 2,5 **** --- 2,6 ---- # FIXME: column-based variables are not intelligible """History (most recent first): + 28-feb-2011 [luch] negative-height items do not affect section height 26-jan-2011 [luch] added floating boxes processing 18-jan-2011 [luch] removed extra empty horizontal pixel line between sections *************** *** 747,750 **** --- 748,752 ---- """ + # TODO convert it to element's or template's property or method return item.tag in ("field", "line", "rectangle", "image", "barcode") *************** *** 867,875 **** _elem_height = _bbox.y + _bbox.height else: # fixed space from top and bottom, unknown size _elem_height = _bbox.y + 1 - _bbox.height if _elem_height > _height: _height = _elem_height ! _sbox.height = round(_height) # fix vertical dimensions for elements for _element in self: --- 869,878 ---- _elem_height = _bbox.y + _bbox.height else: + # FIXME is it for _bbox.height < 0? # fixed space from top and bottom, unknown size _elem_height = _bbox.y + 1 - _bbox.height if _elem_height > _height: _height = _elem_height ! _sbox.height = round(_height) if _height > 0 else 0 # fix vertical dimensions for elements for _element in self: *************** *** 1075,1079 **** return "<%s@%X%s: %.1f, %.1f, %.1f, %.1f>" % ( self.__class__.__name__, id(self), _col, ! self.x, self.top, self.width, self.bottom - self.top) def make_child(self, **kwargs): --- 1078,1087 ---- return "<%s@%X%s: %.1f, %.1f, %.1f, %.1f>" % ( self.__class__.__name__, id(self), _col, ! self.x, self.top, self.width, self.height) ! ! @property ! def height(self): ! """Read-only height of frame""" ! return self.bottom - self.top def make_child(self, **kwargs): *************** *** 1206,1209 **** --- 1214,1221 ---- self.find_layout_parents() + def __repr__(self): + return "<%s@%x:%r>" % (self.__class__.__name__, id(self), + os.path.basename(self.template.filename)) + def filepath(self, *path): """Return normalized absolute pathname *************** *** 1629,1633 **** self.end_group(_group) _columns = _layout.find("columns") ! if _columns: self.add_section(self.build_section(_columns.find("footer"))) self.resolve_eval("column") --- 1641,1645 ---- self.end_group(_group) _columns = _layout.find("columns") ! if _columns is not None: self.add_section(self.build_section(_columns.find("footer"))) self.resolve_eval("column") |
From: Alexey L. <a-...@us...> - 2011-01-26 13:54:07
|
Update of /cvsroot/pythonreports/PythonReports/PythonReports In directory sfp-cvsdas-2.v30.ch3.sourceforge.com:/tmp/cvs-serv8666/PythonReports Modified Files: fonts.py Log Message: try to load windows fonts once when a font is missing Index: fonts.py =================================================================== RCS file: /cvsroot/pythonreports/PythonReports/PythonReports/fonts.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** fonts.py 26 Jan 2011 07:43:39 -0000 1.4 --- fonts.py 26 Jan 2011 13:53:59 -0000 1.5 *************** *** 1,4 **** --- 1,5 ---- """Fonts registry""" """History (most recent first): + 26-jan-2011 [luch] try to load windows fonts once when a font is missing 26-jan-2011 [als] more well-known font file names; add Mac OS X font paths *************** *** 16,19 **** --- 17,22 ---- import os, sys + import windows_fonts + # well-known font files FONTS = { *************** *** 77,80 **** --- 80,85 ---- } + WINDOWS_FONTS_ADDED = False + # paths to look for TrueType fonts SYSFONTPATHS = [] *************** *** 89,95 **** "/usr/share/fonts/truetype/msttcorefonts", # Ubuntu (Feisty) ]) ! if sys.platform == "darwin": ! SYSFONTPATHS.extend(map(itemgetter(0), os.walk("/Library/Fonts"))) ! FONTS[None] = "Courier New.ttf" def fontfile(typeface, bold=False, italic=False): --- 94,100 ---- "/usr/share/fonts/truetype/msttcorefonts", # Ubuntu (Feisty) ]) ! if sys.platform == "darwin": ! SYSFONTPATHS.extend(map(itemgetter(0), os.walk("/Library/Fonts"))) ! FONTS[None] = "Courier New.ttf" def fontfile(typeface, bold=False, italic=False): *************** *** 102,109 **** """ try: ! _file = FONTS[(typeface, bool(bold), bool(italic))] except KeyError: ! _file = FONTS[None] if os.path.dirname(_file) == "": # file name does not contain directory path. --- 107,119 ---- """ + _font_key = (typeface, bool(bold), bool(italic)) try: ! _file = FONTS[_font_key] except KeyError: ! add_windows_fonts() ! try: ! _file = FONTS[_font_key] ! except: ! _file = FONTS[None] if os.path.dirname(_file) == "": # file name does not contain directory path. *************** *** 117,121 **** # WARNING: this will populate the registry # with default font for each unknown typeface ! FONTS[(typeface, bool(bold), bool(italic))] = _file break else: --- 127,131 ---- # WARNING: this will populate the registry # with default font for each unknown typeface ! FONTS[_font_key] = _file break else: *************** *** 124,127 **** --- 134,144 ---- return _file + def add_windows_fonts(): + """Register installed windows fonts""" + global WINDOWS_FONTS_ADDED + if not WINDOWS_FONTS_ADDED: + FONTS.update(windows_fonts.ls_ttf()) + WINDOWS_FONTS_ADDED = True + def register(filename, typeface, bold=False, italic=False): """Register non-standard TTF file |
From: Alexey L. <a-...@us...> - 2011-01-26 13:51:07
|
Update of /cvsroot/pythonreports/PythonReports/PythonReports In directory sfp-cvsdas-2.v30.ch3.sourceforge.com:/tmp/cvs-serv8154/PythonReports Added Files: windows_fonts.py Log Message: created --- NEW FILE: windows_fonts.py --- """List installed TTF fonts on windows platform""" """History (most recent first): 26-jan-2011 [luch] created """ __version__ = "$Revision: 1.1 $"[11:-2] __date__ = "$Date: 2011/01/26 13:50:57 $"[7:-2] def ls_ttf(): """@return: mapping of C{(font name, bold, italic)} to C{TTF file name}. TTF font name ends with "(TrueType)" suffix and contains 0, 1 or 2 flags before it. C{bold} and C{italic} are boolean flags. C{font name} itself does not contain C{"Bold"} or C{"Italic"} words. C{TTF file name} is name under windows system fonts catalog without a path. """ _rv = {} for (_name, _fn) in ls_fonts_key(): _name = _name.split() if _name[-1] != "(TrueType)": continue del _name[-1] _italic = (_name[-1] in ("Italic", "Oblique")) if _italic: del _name[-1] _bold = (_name[-1] == "Bold") if _bold: del _name[-1] _rv[(" ".join(_name), _bold, _italic)] = _fn return _rv try: import _winreg except ImportError: def ls_fonts_key(): return [] else: def ls_fonts_key(): """@return: list of C{(font name, file name)} pairs from registry""" _FONTS_KEY = "SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts" _key = None try: _key = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, _FONTS_KEY) _nn = _winreg.QueryInfoKey(_key)[1] return [_winreg.EnumValue(_key, _ii)[:2] for _ii in xrange(_nn)] except WindowsError: if _key: _winreg.CloseKey(_key) return [] if __name__ == "__main__": import sys for ((_name, _bold, _italic), _ttf) in sorted(ls_ttf().iteritems()): sys.stdout.write("%s %s %s %s\n" % ( _bold and "B" or " ", _italic and "I" or " ", _name.ljust(40, " "), _ttf)) # vim: set et sts=4 sw=4 : |
From: Alexey L. <a-...@us...> - 2011-01-26 13:49:14
|
Update of /cvsroot/pythonreports/PythonReports/PythonReports In directory sfp-cvsdas-2.v30.ch3.sourceforge.com:/tmp/cvs-serv7500/PythonReports Modified Files: builder.py Log Message: added floating boxes processing Index: builder.py =================================================================== RCS file: /cvsroot/pythonreports/PythonReports/PythonReports/builder.py,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -d -r1.10 -r1.11 *** builder.py 18 Jan 2011 16:00:25 -0000 1.10 --- builder.py 26 Jan 2011 13:49:06 -0000 1.11 *************** *** 2,5 **** --- 2,6 ---- # FIXME: column-based variables are not intelligible """History (most recent first): + 26-jan-2011 [luch] added floating boxes processing 18-jan-2011 [luch] removed extra empty horizontal pixel line between sections 07-jan-2011 [als] fix py2.7 FutureWarnings for "if section" *************** *** 73,76 **** --- 74,78 ---- __all__ = ["Builder"] + import itertools import math import os *************** *** 81,84 **** --- 83,87 ---- from PythonReports import template as prt from PythonReports import printout as prp + from PythonReports import segment_layout from PythonReports.datatypes import * *************** *** 396,410 **** # Printout classes and attributes to copy from templates ! PRINTOUTS = {} ! for (_prt, _prp) in ( ! (prt.Field, prp.Text), ! (prt.Line, prp.Line), ! (prt.Rectangle, prp.Rectangle), ! (prt.Image, prp.Image), ! (prt.BarCode, prp.BarCode), ! ): ! PRINTOUTS[_prt.tag] = (_prp, ! set(_prt.attributes) & set(_prp.attributes)) ! del _prt, _prp # Bar Code drivers --- 399,411 ---- # Printout classes and attributes to copy from templates ! PRINTOUTS = dict( ! (_prt.tag, (_prp, set(_prt.attributes) & set(_prp.attributes))) ! for (_prt, _prp) in ( ! (prt.Field, prp.Text), ! (prt.Line, prp.Line), ! (prt.Rectangle, prp.Rectangle), ! (prt.Image, prp.Image), ! (prt.BarCode, prp.BarCode), ! )) # Bar Code drivers *************** *** 418,421 **** --- 419,440 ---- printable = None + # map template items to self's elements + # for floating segment layout calculation + template2element = None + + # TODO create specific class for template's section elements + + # mark whether the section has floating boxes or not + has_floating_boxes = False + + # the vertical layout of floating boxes is 1D problem, so + # boxes become segments. Each segment has + # C{(template y, template height, floating mark, + # segment number for debug, + # template item that produced the segment)} + # The last segment's item is used as index in C{template2element} + # for calculating actual segment height. + vertical_segment_layout = None + def __init__(self, builder, template, context=None): """Create Section instance *************** *** 437,443 **** --- 456,561 ---- self.resizeable = False self.subreports_before = self.subreports_after = () # filled by .build + self.template2element = {} + self.vertical_segment_layout = self.has_floating_boxes = None + self.create_vertical_segment_layout(template) if context: self.build(context) + def create_vertical_segment_layout(self, template): + """Set C{template}'s C{vertical_segment_layout} if missing. + + Also sets C{has_floating_boxes}. + + """ + _elements = [(_item, Box.from_element(_item.find("box"))) + for _item in template if self.is_body_element(_item)] + + self.has_floating_boxes = any(_it[1].float and + (_it[1].y >= 0) and (_it[1].height >= 0) for _it in _elements) + if not self.has_floating_boxes: + template.vertical_segment_layout = (lambda *args: None) + return + + # non-floating segments should precede floating ones + _segments = [(_box.y, _box.height, _box.float, _nn, _item) + for (_nn, (_item, _box)) in enumerate(_elements) + if (_box.y >= 0) and (_box.height >= 0)] + + _graph = self.arrange_segments(_segments) + + #template.vertical_segment_layout + self.vertical_segment_layout = \ + segment_layout.SegmentLayout(dict(_graph)) + + @staticmethod + def arrange_segments(segments): + """@return: minimal DAG of floating segment dependencies. + + @param segments: tuple, where first 3 items are C{(y, height, + floating)}, where C{floating} is boolean flag that the segment + should float depending on segments wholly above the segment. + + Segments precede other when it is wholly above it concerning + - a static segment precede a floating segment, because third + segment's item is boolean; + - a floating segment precede other floating segment only when + it starts earlier for the case when the second floating segment + has zero height. + + Dependency is transitive. Minimal dependency is one that does not + contain items that are implied by other dependency items. Examle: + when B depends on A and C depends on A and B, minimal dependency for C + will contain B only. + + About segments minimal dependency should be much smaller than full one. + + >>> arrange = Section.arrange_segments + >>> arrange([]) + [] + + >>> arrange([(0, 1, False)]) + [((0, 1, False), [])] + + >>> arrange([(0, 1, True), (2, 1, False)]) + [((0, 1, True), []), ((2, 1, False), [])] + + >>> arrange([(0, 1, True), (2, 1, True)]) + [((0, 1, True), []), ((2, 1, True), [(0, 1, True)])] + + >>> val = arrange([(0, 1, False), (2, 1, True), (4, 1, True)]) + >>> print "\\n".join(repr(it) for it in val) + ((0, 1, False), []) + ((2, 1, True), [(0, 1, False)]) + ((4, 1, True), [(2, 1, True)]) + + >>> val = arrange([(0, 0, False, 1), (0, 0, False, 2), + ... (0, 0, True, 3), (0, 0, True, 4), (10, 0, True, 5), + ... (5, 20, True, 6)]) + >>> print "\\n".join(repr((s, sorted(p))) for (s, p) in sorted(val)) + ((0, 0, False, 1), []) + ((0, 0, False, 2), []) + ((0, 0, True, 3), [(0, 0, False, 1), (0, 0, False, 2)]) + ((0, 0, True, 4), [(0, 0, False, 1), (0, 0, False, 2)]) + ((5, 20, True, 6), [(0, 0, True, 3), (0, 0, True, 4)]) + ((10, 0, True, 5), [(0, 0, True, 3), (0, 0, True, 4)]) + + """ + _rv = dict((_seg, []) for _seg in segments) + for (_seg, _pre) in segment_layout.preceding_segments(segments): + if _seg[2]: + # floating segments with the same starting point + # has *no* influence to the current segment + _pre = [_sp for _sp in _pre + if not _sp[2] or (_sp[0] < _seg[0])] + # remove extra dependencies, + # i.e. dependencies of preceding floating segments + _remove = itertools.chain(*( + _rv[_sp] for _sp in _pre if _sp[2])) + _pre = list(set(_pre) - set(_remove)) + else: + _pre = [] + _rv[_seg] = _pre + return _rv.items() + def iter_styles(self): """Iterate over all styles for the section (both direct and inherited) *************** *** 470,482 **** """ ! _rv = True ! for _style in self.iter_styles(): ! if context.eval(_style.get("when")): ! _printwhen = _style.get("printwhen") ! if _printwhen: ! _rv = bool(context.eval(_printwhen)) ! break ! self.printable = _rv ! return _rv @staticmethod --- 588,598 ---- """ ! def _ifirst(seq, N=1): ! return list(itertools.islice(seq, N)) ! _printwhen = _ifirst(_style.get("printwhen") ! for _style in self.iter_styles() ! if context.eval(_style.get("when")) and _style.get("printwhen")) ! self.printable = not _printwhen or context.eval(_printwhen[0]) ! return self.printable @staticmethod *************** *** 593,610 **** _subreports.append((_item.get("seq"), _item)) continue ! # ignore children that are not known body elements ! if _item.tag not in ( ! "field", "line", "rectangle", "image", "barcode", ! ): continue _element = ReportElement(section=self, template=_item) _element.style = self.compose_style(context, ("printwhen", "font", "color", "bgcolor"), _item.findall("style") + _default_element_style) _printwhen = _element.style.get("printwhen") ! if _printwhen: ! _element.printable = context.eval(_printwhen) ! else: ! _element.printable = True # must not evaluate expressions for suspended elements. # skip elements that are not printable. --- 709,721 ---- _subreports.append((_item.get("seq"), _item)) continue ! if not self.is_body_element(_item): continue _element = ReportElement(section=self, template=_item) + self.template2element[_item] = _element _element.style = self.compose_style(context, ("printwhen", "font", "color", "bgcolor"), _item.findall("style") + _default_element_style) _printwhen = _element.style.get("printwhen") ! _element.printable = not _printwhen or context.eval(_printwhen) # must not evaluate expressions for suspended elements. # skip elements that are not printable. *************** *** 629,632 **** --- 740,752 ---- if _item[0] > 0) + @staticmethod + def is_body_element(item): + """@return: whether item represents body element or not. + + @param item: template section element. + + """ + return item.tag in ("field", "line", "rectangle", "image", "barcode") + def build_barcode(self, element): """Compute sripe widths and box size/position for barcode element *************** *** 723,729 **** _bbox.y = _element.tbox.y _element.bbox = _bbox ! ### ! ### TODO: Move floating boxes ! ### # fix section height (may not be computed from total available height) if self.resizeable: --- 843,849 ---- _bbox.y = _element.tbox.y _element.bbox = _bbox ! ! self.move_floating_elements() ! # fix section height (may not be computed from total available height) if self.resizeable: *************** *** 781,784 **** --- 901,916 ---- self.refill() + def move_floating_elements(self): + """Move floating boxes using C{vertical_segment_layout}""" + if not self.has_floating_boxes: + return + def _height(segment): + _element = self.template2element[segment[-1]] + return _element.bbox.height if _element.printable else 0 + for (_seg, _y) in self.vertical_segment_layout(_height).iteritems(): + _element = self.template2element[_seg[-1]] + if _element.printable: + _element.bbox.y = _y + def refill(self, new_y=None): """Update section element placements. *************** *** 1428,1432 **** else: _layout_header = _layout.find("header") ! if _layout_title: if _layout_title.get("swapheader"): _section = self.build_section(_layout_title) --- 1560,1564 ---- else: _layout_header = _layout.find("header") ! if _layout_title is not None: if _layout_title.get("swapheader"): _section = self.build_section(_layout_title) |
From: Alexey L. <a-...@us...> - 2011-01-26 13:47:39
|
Update of /cvsroot/pythonreports/PythonReports/PythonReports In directory sfp-cvsdas-2.v30.ch3.sourceforge.com:/tmp/cvs-serv7225/PythonReports Added Files: segment_layout.py Log Message: created --- NEW FILE: segment_layout.py --- """1-dimension segment layout""" """History (most recent first): 21-jan-2011 [luch] created """ __version__ = "$Revision: 1.1 $"[11:-2] __date__ = "$Date: 2011/01/26 13:47:27 $"[7:-2] from operator import itemgetter class SegmentLayout(object): """1-dimension stretchable segment layout C{SegmentLayout} calculates actual segment position depending on actual width of segments after stretching. Layout is based on segment dependency DAG -- directed acyclic graph. All segments, that a segment depends on, should be wholly at its left. Each segment has a non-negative gap to the nearest segment of those it depends on. The gap is taken into account when the segment's actual width is positive. Zero width segments are considered meaningless. Example: 1 depend on A and B, 2 depends on 1, Z depends 1, 3 depends on 2 and Z. Initial layout:: |gap| |g| |g| :aaaa 1111 222222 333 :bbbbbb zzz |gap| - A can become longer than B, gaps are the same:: :aaaaaaa 1111 222222 333 :b zzz - 2 collapses:: :aaaa 1111 333 :bbbbbb zzz - 1 collapses:: :aaaa 222222 333 :bbbbbb zzz - A and B collapses:: : 1111 222222 333 : zzz At present there is no other way avoid leading gap when A and B collapes, other than make zero gap. >>> SegmentLayout({})() {} >>> SegmentLayout({(0, 1):[]})() {(0, 1): 0} >>> sl = SegmentLayout({(0, 1):[], (0, 2):[]}) >>> sorted(sl().items()) [((0, 1), 0), ((0, 2), 0)] >>> map_indexes = lambda items, indexes: dict( ... (items[i], [items[j] for j in indexes.get(i, [])]) ... for i in xrange(len(items))) >>> sl = SegmentLayout(map_indexes([(0, 1), (1, 1)], {1:[0]})) >>> sorted(sl().items()) [((0, 1), 0), ((1, 1), 1)] >>> sorted(sl(lambda s: s[1] * 2).items()) [((0, 1), 0), ((1, 1), 2)] >>> sl = SegmentLayout(map_indexes([(0, 1), (2, 1)], {1:[0]})) >>> sorted(sl().items()) [((0, 1), 0), ((2, 1), 2)] >>> sorted(sl(lambda s: s[1] * 2).items()) [((0, 1), 0), ((2, 1), 3)] >>> sl = SegmentLayout(map_indexes([(0, 1, 4), (1, 1, 1)], {1:[0]})) >>> sorted(sl(lambda s: s[2]).items()) [((0, 1, 4), 0), ((1, 1, 1), 4)] >>> sl = SegmentLayout(map_indexes([(0, 4, 1), (5, 1, 1)], {1:[0]})) >>> sorted(sl(lambda s: s[2]).items()) [((0, 4, 1), 0), ((5, 1, 1), 2)] >>> sl = SegmentLayout(map_indexes( ... [(0, 2, 5), (1, 3, 1), (5, 1, 1)], {2:[0, 1]})) >>> sorted(sl(lambda s: s[2]).items()) [((0, 2, 5), 0), ((1, 3, 1), 1), ((5, 1, 1), 6)] >>> sl = SegmentLayout(map_indexes( ... [(0, 1, 5), (1, 3, 0), (5, 1, 1)], {2:[0, 1]})) >>> sorted(sl(lambda s: s[2]).items()) [((0, 1, 5), 0), ((1, 3, 0), 1), ((5, 1, 1), 6)] @ivar segments: list of C{(segment, leading gap, leading segments)}, where - C{segment} is tuple that contents depends on C{__call__}'s argument C{actual_width_func}, but 0-element must be segment's left point position. - C{leading segments} is list of segments that the segment's position depends on. - C{leading gap} is distance from the segment's left point to the right point of the nearest leading segment at left. """ def __init__(self, segments_graph): """Initialize C{segments} from C{segments_graph} @param segments_graph: maps a segment to list of segments that lead the segment, it is the segment left point depends on actual width and position of these segments. It is DAG. There must be entry for every segment. """ _gap = dict(leading_gaps(segments_graph.iterkeys())) self.segments = [ (_segment, segments_graph[_segment], _gap[_segment]) for _segment in toposort(segments_graph)] def __call__(self, actual_width_func=(lambda segment: segment[1])): """@return: map segments to their actual position @param actual_width_func: a function that returns actual width of every segment by the segment itself. """ _x_left = {} _x_right = {} for (_seg, _pre, _gap) in self.segments: _width = actual_width_func(_seg) if _pre: _x = max(_x_right[_sp] for _sp in _pre) \ + (_gap if _width > 0 else 0) else: _x = _seg[0] _x_left[_seg] = _x _x_right[_seg] = _x + _width return _x_left def leading_gaps(segments, x0=0): """@return: segment to leading gap mapping Leading gap for a segment is distance to the nearest whole segment at its left. For segments that have no whole segments at their left the leading gap is a distance to C{x0}. @param segments: sequence of C{(x, width)} pairs. C{width} should not be negative. @param x0: point 0 on the X axis. >>> leading_gaps([]) [] >>> leading_gaps([(0, 0)]) [((0, 0), 0)] >>> leading_gaps([(0, 0)], -1) [((0, 0), 1)] >>> leading_gaps([(0, 1), (1, 1)]) [((0, 1), 0), ((1, 1), 0)] >>> leading_gaps([(1, 0), (2, 0)]) [((1, 0), 1), ((2, 0), 1)] >>> leading_gaps([(0, 5), (1, 3), (2, 1)]) [((0, 5), 0), ((1, 3), 1), ((2, 1), 2)] >>> leading_gaps([(0, 2), (1, 0), (3, 1)]) [((0, 2), 0), ((1, 0), 1), ((3, 1), 1)] """ segments = list(segments) if segments: x0 = min(x0, min(map(itemgetter(0), segments))) - 1 _bound = (x0, 1) segments.append(_bound) _rv = [(_this, _this[0] - (_pre[-1][0] + _pre[-1][1])) for (_this, _pre) in preceding_segments(segments) if _pre and (_this is not _bound)] else: _rv = [] return _rv def preceding_segments(segments): """For each segment list of segments wholly at its left @param segments: tuple with at least 2 items -- C{x} and C{width}. @return: list of C{(segments, preceding segment list)} in order of C{(segment left point, segment right point)} pairs. >>> preceding_segments([]) [] >>> preceding_segments([(0, 1)]) [] >>> preceding_segments([(0, 1), (0, 1)]) [] >>> preceding_segments([(0, 1), (0, 2)]) [] >>> preceding_segments([(0, 2), (0, 1)]) [] >>> preceding_segments([(0, 1), (1, 1)]) [((1, 1), [(0, 1)])] >>> preceding_segments([(0, 1), (0, 2), (3, 1)]) [((3, 1), [(0, 1), (0, 2)])] """ _events = [(_seg[0], _seg, 0) for _seg in segments] \ + [(_seg[0] + _seg[1], _seg, 1) for _seg in segments] _events.sort() _last_finished_x = None _finished_segmets = [] _rv = [] for (_x, _seg, _finished) in _events: if _finished: _last_finished_x = _x _finished_segmets.append(_seg) elif _last_finished_x is not None: _rv.append((_seg, list(_finished_segmets))) return _rv def toposort(direcred_graph): """@return: vertexes of directed acyclic graph in C{toposort} order Directions should go from a dependent vertext to a vertex it depends on. >>> toposort({}) [] >>> toposort({0:[]}) [0] >>> toposort({0:[1], 1:[]}) [1, 0] >>> toposort({0:[1, 2], 1:[3], 2:[3], 3:[4, 5, 6], 4:[6], 5:[6], 6:[]}) [6, 4, 5, 3, 1, 2, 0] """ _vertex_order = [] _visited = set() def _walk(vertex): if vertex not in _visited: _visited.add(vertex) for child in direcred_graph[vertex]: _walk(child) _vertex_order.append(vertex) for _vertex in direcred_graph: _walk(_vertex) return _vertex_order # vim: set et sts=4 sw=4 : |
From: Alexey L. <a-...@us...> - 2011-01-26 13:36:34
|
Update of /cvsroot/pythonreports/PythonReports/PythonReports In directory sfp-cvsdas-2.v30.ch3.sourceforge.com:/tmp/cvs-serv4942/PythonReports Modified Files: datatypes.py Log Message: fix after review Index: datatypes.py =================================================================== RCS file: /cvsroot/pythonreports/PythonReports/PythonReports/datatypes.py,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** datatypes.py 7 Jan 2011 10:33:32 -0000 1.8 --- datatypes.py 26 Jan 2011 13:36:24 -0000 1.9 *************** *** 1198,1202 **** _indent2 = "" # there are no children for this element, just text - # (the text, if any, must be already encoded by .make_element) _text = u"%s<%s>%s%s</%s>%s" % (indent, self.starttag(element), saxutils.escape(_text), _indent2, self.tag, newl) --- 1198,1201 ---- |