[bin] job.py: if the specified user does not exist in the DB, try with a user named 'admin'; [gen] Calendar: allow to insert additional, custom (XHTML or textual) info in any cell of the calendar, via new attribute Calendar.additionalInfo; [pod] some code refactoring; xhtml2odt: allow, when converting tables, to take into account attributes 'width' of tds; bugfix when converting 'href' attrs of 'a' tags.

This commit is contained in:
Gaetan Delannay 2012-10-26 13:09:44 +02:00
parent ba148c51aa
commit caca61516f
10 changed files with 133 additions and 60 deletions

View file

@ -19,6 +19,7 @@
# ------------------------------------------------------------------------------
import time
from appy.shared.utils import Traceback
from appy.shared.xml_parser import escapeXhtml
# Some POD-specific constants --------------------------------------------------
XHTML_HEADINGS = ('h1', 'h2', 'h3', 'h4', 'h5', 'h6')
@ -27,8 +28,6 @@ XHTML_PARAGRAPH_TAGS = XHTML_HEADINGS + XHTML_LISTS + ('p',)
XHTML_PARAGRAPH_TAGS_NO_LISTS = XHTML_HEADINGS + ('p',)
XHTML_INNER_TAGS = ('b', 'i', 'u', 'em')
XHTML_UNSTYLABLE_TAGS = XHTML_LISTS + ('li', 'a')
XML_SPECIAL_CHARS = {'<': '&lt;', '>': '&gt;', '&': '&amp;', '"': '&quot;',
"'": '&apos;'}
# ------------------------------------------------------------------------------
class PodError(Exception):
@ -83,17 +82,6 @@ class PodError(Exception):
buffer.write('</%s>' % withinElement.OD.elem)
dump = staticmethod(dump)
def convertToXhtml(s):
'''Produces the XHTML-friendly version of p_s.'''
res = ''
for c in s:
if XML_SPECIAL_CHARS.has_key(c):
res += XML_SPECIAL_CHARS[c]
elif c == '\n':
res += '<br/>'
elif c == '\r':
pass
else:
res += c
return res
# XXX To remove, present for backward compatibility only.
convertToXhtml = escapeXhtml
# ------------------------------------------------------------------------------

View file

@ -20,11 +20,11 @@
import re
from xml.sax.saxutils import quoteattr
from appy.pod import PodError, XML_SPECIAL_CHARS
from appy.shared.xml_parser import xmlPrologue, escapeXml
from appy.pod import PodError
from appy.pod.elements import *
from appy.pod.actions import IfAction, ElseAction, ForAction, VariableAction, \
NullAction
from appy.shared import xmlPrologue
# ------------------------------------------------------------------------------
class ParsingError(Exception): pass
@ -157,11 +157,7 @@ class Buffer:
def dumpContent(self, content):
'''Dumps string p_content into the buffer.'''
for c in content:
if XML_SPECIAL_CHARS.has_key(c):
self.write(XML_SPECIAL_CHARS[c])
else:
self.write(c)
self.write(escapeXml(content))
# ------------------------------------------------------------------------------
class FileBuffer(Buffer):

View file

@ -10,8 +10,9 @@ class OdtTable:
tns = 'table:'
txns = 'text:'
def __init__(self, name, paraStyle, cellStyle, nbOfCols,
paraHeaderStyle=None, cellHeaderStyle=None, html=False):
def __init__(self, name, paraStyle='podTablePara', cellStyle='podTableCell',
nbOfCols=1, paraHeaderStyle=None, cellHeaderStyle=None,
html=False):
# An ODT table must have a name. In the case of an HTML table, p_name
# represents the CSS class for the whole table.
self.name = name
@ -24,7 +25,7 @@ class OdtTable:
# The default style of every paragraph within a header cell
self.paraHeaderStyle = paraHeaderStyle or paraStyle
# The default style of every header cell
self.cellHeaderStyle = cellHeaderStyle or cellStyle
self.cellHeaderStyle = cellHeaderStyle or 'podTableHeaderCell'
# The buffer where the resulting table will be rendered
self.res = ''
# Do we need to generate an HTML table instead of an ODT table ?

View file

@ -21,9 +21,9 @@ import os, os.path, sys, zipfile, re, shutil
import appy.shared.test
from appy.shared.test import TesterError
from appy.shared.utils import FolderDeleter
from appy.shared.xml_parser import escapeXml
from appy.pod.odf_parser import OdfEnvironment, OdfParser
from appy.pod.renderer import Renderer
from appy.pod import XML_SPECIAL_CHARS
# TesterError-related constants ------------------------------------------------
TEMPLATE_NOT_FOUND = 'Template file "%s" was not found.'
@ -70,12 +70,7 @@ class AnnotationsRemover(OdfParser):
self.res += '</%s>' % elem
def characters(self, content):
e = OdfParser.characters(self, content)
if not self.ignore:
for c in content:
if XML_SPECIAL_CHARS.has_key(c):
self.res += XML_SPECIAL_CHARS[c]
else:
self.res += c
if not self.ignore: self.res += escapeXml(content)
def getResult(self):
return self.res

View file

@ -10,7 +10,7 @@
# ------------------------------------------------------------------------------
import xml.sax, time, random
from appy.shared.xml_parser import XmlEnvironment, XmlParser
from appy.shared.xml_parser import XmlEnvironment, XmlParser, escapeXml
from appy.pod.odf_parser import OdfEnvironment
from appy.pod.styles_manager import Style
from appy.pod import *
@ -235,6 +235,10 @@ class HtmlTable:
# The following list stores, for every column, the size of the biggest
# content of all its cells.
self.columnContentSizes = []
# The following list stores, for every column, its width, if specified.
# If widths are found, self.columnContentSizes will not be used:
# self.columnWidths will be used instead.
self.columnWidths = []
def computeColumnStyles(self, renderer):
'''Once the table has been completely parsed, self.columnContentSizes
@ -242,22 +246,34 @@ class HtmlTable:
of every column and create the corresponding style declarations, in
p_renderer.dynamicStyles.'''
total = 65000.0 # A number representing the total width of the table
# Ensure first that self.columnContentSizes is correct
if (len(self.columnContentSizes) != self.nbOfColumns) or \
(None in self.columnContentSizes):
# There was a problem while parsing the table. Set every column
# with the same width.
widths = [int(total/self.nbOfColumns)] * self.nbOfColumns
# Use (a) self.columnWidths if complete, or
# (b) self.columnContentSizes if complete, or
# (c) a fixed width else.
if self.columnWidths and (len(self.columnWidths) == self.nbOfColumns) \
and (None not in self.columnWidths):
# Use self.columnWidths
toUse = self.columnWidths
# Use self.columnContentSizes if complete
elif (len(self.columnContentSizes) == self.nbOfColumns) and \
(None not in self.columnContentSizes):
# Use self.columnContentSizes
toUse = self.columnContentSizes
else:
toUse = None
if toUse:
widths = []
# Compute the sum of all column content sizes
contentTotal = 0
for size in self.columnContentSizes: contentTotal += size
for size in toUse: contentTotal += size
contentTotal = float(contentTotal)
for size in self.columnContentSizes:
for size in toUse:
width = int((size/contentTotal) * total)
widths.append(width)
# Compute style declatation corresponding to every column.
else:
# There was a problem while parsing the table. Set every column
# with the same width.
widths = [int(total/self.nbOfColumns)] * self.nbOfColumns
# Compute style declaration corresponding to every column.
s = self.styleNs
i = 0
for width in widths:
@ -321,14 +337,10 @@ class XhtmlEnvironment(XmlEnvironment):
currentElem.addInnerParagraph(self)
# Dump and reinitialize the current content
content = self.currentContent.strip('\n\t')
# We remove leading and trailing carriage returns, but not
# whitespace because whitespace may be part of the text to dump.
contentSize = len(content)
for c in content:
# We remove leading and trailing carriage returns, but not
# whitespace because whitespace may be part of the text to dump.
if XML_SPECIAL_CHARS.has_key(c):
self.dumpString(XML_SPECIAL_CHARS[c])
else:
self.dumpString(c)
self.dumpString(escapeXml(content))
self.currentContent = u''
# If we are within a table cell, update the total size of cell content.
if self.currentTables and self.currentTables[-1].inCell:
@ -444,6 +456,16 @@ class XhtmlEnvironment(XmlEnvironment):
# If we are in the first row of a table, update columns count
if not table.firstRowParsed:
table.nbOfColumns += colspan
if attrs.has_key('width') and (colspan == 1):
# Get the width, keep figures only.
width = ''
for c in attrs['width']:
if c.isdigit(): width += c
width = int(width)
# Ensure self.columnWidths is long enough
while (len(table.columnWidths)-1) < table.cellIndex:
table.columnWidths.append(None)
table.columnWidths[table.cellIndex] = width
return currentElem
def onElementEnd(self, elem):
@ -525,7 +547,8 @@ class XhtmlParser(XmlParser):
elif elem == 'a':
e.dumpString('<%s %s:type="simple"' % (odfTag, e.linkNs))
if attrs.has_key('href'):
e.dumpString(' %s:href="%s"' % (e.linkNs, attrs['href']))
e.dumpString(' %s:href="%s"' % (e.linkNs,
escapeXml(attrs['href'])))
e.dumpString('>')
elif elem in XHTML_LISTS:
prologue = ''