Example #1
0
 def __setitem__(self, item, value):
     if isinstance(value,strTypes):
         # very simple case, no defaults, no empty case
         value = MapNode(asUnicode(value))
     if isinstance(item,strTypes):
         item = asUnicode(item)
     self.nodemappers[item] = value
 def test17(self):
     self.assertEqual(asUnicode(u'abc'),u'abc')
     self.assertEqual(asUnicode(b'abc'),u'abc')
     self.assertRaises(AttributeError,asUnicode,['abc'])
     self.myAssertRaisesRegex(AttributeError,r"asUnicode\(.*'list' object has no attribute 'decode'", asUnicode,['abc'])
     self.assertEqual(asUnicodeEx(u'abc'),u'abc')
     self.assertEqual(asUnicodeEx(b'abc'),u'abc')
     self.assertEqual(asUnicodeEx(123),u'123')
     self.assertEqual(asBytes(u'abc'),b'abc')
     self.assertEqual(asBytes(b'abc'),b'abc')
     self.assertRaises(AttributeError,asBytes,['abc'])
     self.myAssertRaisesRegex(AttributeError,"asBytes\(.*'list' object has no attribute 'encode'", asBytes,['abc'])
    def draw(self):
        # general widget bits
        s = float(self.size)  # abbreviate as we will use this a lot
        g = shapes.Group()
        ig = self.innerGap

        x = self.x + self.dx
        y = self.y + self.dy
        hsize = 0.5 * self.size
        if not ig:
            L = [(x - hsize, y, x + hsize, y), (x, y - hsize, x, y + hsize)]
        else:
            if isStr(ig):
                ig = asUnicode(ig)
                if ig.endswith(u'%'):
                    gs = hsize * float(ig[:-1]) / 100.0
                else:
                    gs = float(ig) * 0.5
            else:
                gs = ig * 0.5
            L = [(x - hsize, y, x - gs, y), (x + gs, y, x + hsize, y),
                 (x, y - hsize, x, y - gs), (x, y + gs, x, y + hsize)]
        P = shapes.Path(strokeWidth=self.strokeWidth,
                        strokeColor=self.strokeColor)
        for x0, y0, x1, y1 in L:
            P.moveTo(x0, y0)
            P.lineTo(x1, y1)
        g.add(P)
        return g
Example #4
0
 def addParas(words):
     words = [asUnicode(w) for w in words]
     txt = u' '.join([(len(w) > 5 and u'<index item=%s/>%s' %
                       (quoteattr(commajoin([w[:2], w[:3], w])), w)
                       or w) for w in words])
     para = Paragraph(txt, makeBodyStyle())
     story.append(para)
Example #5
0
def xhtmlDocFromXhtmlFragment(xhtmlFrag,enc='utf8'):
    r = []
    #r.append('<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">')
    r.append('<html><head><title></title></head><body>')
    xhtmlFrag=xhtmlFrag.replace('<p><table>','<table>').replace('</table></p>','</table>')
    r.append(asUnicode(xhtmlFrag,enc=enc))
    r.append('</body></html>')
    r = ''.join(r)
    return r
Example #6
0
def findImages(xml):
    "Returns lists of all images referred to in markup"
    xml = asUnicode(xml)
    validDoc = xhtmlDocFromXhtmlFragment(xml)  #adds 'html','head etc. to our fragment
    parser = pyRXPU.Parser(ReturnUTF8=1, ExpandCharacterEntities=0, ExpandGeneralEntities=0)
    tree = parser.parse(validDoc)
    walker = ImageFinder(tree)
    walker.go()
    return walker.images
    def _build(self,availWidth,availHeight):
        _tempEntries = [(tuple(asUnicode(t) for t in texts),pageNumbers)
                            for texts, pageNumbers in self._getlastEntries()]
        def getkey(seq):
            return [''.join((c for c in unicodedata.normalize('NFD', x.upper()) if unicodedata.category(c) != 'Mn')) for x in seq[0]]
        _tempEntries.sort(key=getkey)
        leveloffset = self.headers and 1 or 0

        def drawIndexEntryEnd(canvas, kind, label):
            '''Callback to draw dots and page numbers after each entry.'''
            style = self.getLevelStyle(leveloffset)
            pages = [(p[1],k) for p,k in sorted(decode_label(label))]
            drawPageNumbers(canvas, style, pages, availWidth, availHeight, self.dot)
        self.canv.drawIndexEntryEnd = drawIndexEntryEnd

        alpha = ''
        tableData = []
        lastTexts = []
        alphaStyle = self.getLevelStyle(0)
        for texts, pageNumbers in _tempEntries:
            texts = list(texts)
            #track when the first character changes; either output some extra
            #space, or the first letter on a row of its own.  We cannot do
            #widow/orphan control, sadly.
            nalpha = ''.join((c for c in unicodedata.normalize('NFD', texts[0][0].upper()) if unicodedata.category(c) != 'Mn'))
            if alpha != nalpha:
                alpha = nalpha
                if self.headers:
                    header = alpha
                else:
                    header = ' '
                tableData.append([Spacer(1, alphaStyle.spaceBefore),])
                tableData.append([Paragraph(header, alphaStyle),])
                tableData.append([Spacer(1, alphaStyle.spaceAfter),])


            i, diff = listdiff(lastTexts, texts)
            if diff:
                lastTexts = texts
                texts = texts[i:]
            label = encode_label(list(pageNumbers))
            texts[-1] = '%s<onDraw name="drawIndexEntryEnd" label="%s"/>' % (texts[-1], label)
            for text in texts:
                #Platypus and RML differ on how parsed XML attributes are escaped.
                #e.g. <index item="M&S"/>.  The only place this seems to bite us is in
                #the index entries so work around it here.
                text = escapeOnce(text)

                style = self.getLevelStyle(i+leveloffset)
                para = Paragraph(text, style)
                if style.spaceBefore:
                    tableData.append([Spacer(1, style.spaceBefore),])
                tableData.append([para,])
                i += 1

        self._flowable = Table(tableData, colWidths=[availWidth], style=self.tableStyle)
Example #8
0
    def _build(self,availWidth,availHeight):
        _tempEntries = [(tuple(asUnicode(t) for t in texts),pageNumbers)
                            for texts, pageNumbers in self._getlastEntries()]
        def getkey(seq):
            return [''.join((c for c in unicodedata.normalize('NFD', x.upper()) if unicodedata.category(c) != 'Mn')) for x in seq[0]]
        _tempEntries.sort(key=getkey)
        leveloffset = self.headers and 1 or 0

        def drawIndexEntryEnd(canvas, kind, label):
            '''Callback to draw dots and page numbers after each entry.'''
            style = self.getLevelStyle(leveloffset)
            pages = [(p[1],k) for p,k in sorted(decode_label(label))]
            drawPageNumbers(canvas, style, pages, availWidth, availHeight, self.dot)
        self.canv.drawIndexEntryEnd = drawIndexEntryEnd

        alpha = ''
        tableData = []
        lastTexts = []
        alphaStyle = self.getLevelStyle(0)
        for texts, pageNumbers in _tempEntries:
            texts = list(texts)
            #track when the first character changes; either output some extra
            #space, or the first letter on a row of its own.  We cannot do
            #widow/orphan control, sadly.
            nalpha = ''.join((c for c in unicodedata.normalize('NFD', texts[0][0].upper()) if unicodedata.category(c) != 'Mn'))
            if alpha != nalpha:
                alpha = nalpha
                if self.headers:
                    header = alpha
                else:
                    header = ' '
                tableData.append([Spacer(1, alphaStyle.spaceBefore),])
                tableData.append([Paragraph(header, alphaStyle),])
                tableData.append([Spacer(1, alphaStyle.spaceAfter),])


            i, diff = listdiff(lastTexts, texts)
            if diff:
                lastTexts = texts
                texts = texts[i:]
            label = encode_label(list(pageNumbers))
            texts[-1] = '%s<onDraw name="drawIndexEntryEnd" label="%s"/>' % (texts[-1], label)
            for text in texts:
                #Platypus and RML differ on how parsed XML attributes are escaped.
                #e.g. <index item="M&S"/>.  The only place this seems to bite us is in
                #the index entries so work around it here.
                text = escapeOnce(text)

                style = self.getLevelStyle(i+leveloffset)
                para = Paragraph(text, style)
                if style.spaceBefore:
                    tableData.append([Spacer(1, style.spaceBefore),])
                tableData.append([para,])
                i += 1

        self._flowable = Table(tableData, colWidths=[availWidth], style=self.tableStyle)
Example #9
0
 def parse(self, text, style):
     "attempt replacement for parse"
     self._setup_for_parse(style)
     text = asUnicode(text)
     if not(len(text)>=6 and text[0]=='<' and _re_para.match(text)):
         text = u"<para>"+text+u"</para>"
     try:
         self.feed(text)
     except:
         annotateException('paragraph text %s caused exception' % ascii(text))
     return self._complete_parse()
Example #10
0
 def processContent(self, elts, overrides=None, containerdict=None, top_level=1):
     if containerdict is None:
         containerdict = self.topDict
     if overrides is None:
         overrides = {} # no overrides yet
     if isinstance(elts,strTypes):
         return self.processString(asUnicode(elts))
     if isinstance(elts,tuple):
         return self.processTuple(elts, overrides, containerdict)
     else:
         L = []
         for e in elts:
             if isinstance(e,strTypes):
                 e2 = self.processString(asUnicode(e))
             else:
                 if not isinstance(e,tuple):
                     raise ValueError("bad content type %s" % type(e))
                 e2 = self.processTuple(e, overrides, containerdict)
             L.append(e2)
         return self.joinTranslatedContent(L)
Example #11
0
def xhtmlDocFromXhtmlFragment(xhtmlFrag, enc='utf8'):
    r = []
    #r.append('<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">')
    r.append('<html><head><title></title></head><body>')
    xhtmlFrag = xhtmlFrag.replace('<p><table>',
                                  '<table>').replace('</table></p>',
                                                     '</table>')
    r.append(asUnicode(xhtmlFrag, enc=enc))
    r.append('</body></html>')
    r = ''.join(r)
    return r
Example #12
0
def text_decode(source):
    """
    try decoding ``source`` with various known codepoints to unicode

    for more information on the various codepoints, see
    https://docs.python.org/2/library/codecs.html#standard-encodings
    
    :see: https://github.com/prjemian/assign_gup/issues/55
    :see: http://stackoverflow.com/questions/9942594/unicodeencodeerror-ascii-codec-cant-encode-character-u-xa0-in-position-20
    """
    return asUnicode(source)
Example #13
0
 def parse(self, text, style):
     "attempt replacement for parse"
     self._setup_for_parse(style)
     text = asUnicode(text)
     if not(len(text)>=6 and text[0]=='<' and _re_para.match(text)):
         text = u"<para>"+text+u"</para>"
     try:
         self.feed(text)
     except:
         annotateException('paragraph text %s caused exception' % ascii(text))
     return self._complete_parse()
Example #14
0
def run(pagesize=None, verbose=0, outDir=None):
    import sys, os
    from reportlab.lib.utils import open_and_read, asUnicode
    cwd = os.getcwd()
    docsDir = os.path.dirname(os.path.dirname(sys.argv[0]) or cwd)
    topDir = os.path.dirname(docsDir)
    if not outDir: outDir = docsDir
    G = {}
    sys.path.insert(0, topDir)
    from reportlab.pdfbase.pdfmetrics import registerFontFamily
    from reportlab.pdfbase import pdfmetrics
    from reportlab.pdfbase.ttfonts import TTFont
    pdfmetrics.registerFont(TTFont('Vera', 'Vera.ttf'))
    pdfmetrics.registerFont(TTFont('VeraBd', 'VeraBd.ttf'))
    pdfmetrics.registerFont(TTFont('VeraIt', 'VeraIt.ttf'))
    pdfmetrics.registerFont(TTFont('VeraBI', 'VeraBI.ttf'))
    registerFontFamily('Vera',
                       normal='Vera',
                       bold='VeraBd',
                       italic='VeraIt',
                       boldItalic='VeraBI')
    from tools.docco.rl_doc_utils import setStory, getStory, RLDocTemplate, defaultPageSize, H1, H2, H3, H4
    from tools.docco import rl_doc_utils
    exec('from tools.docco.rl_doc_utils import *', G, G)
    destfn = os.path.join(outDir, 'reportlab-userguide.pdf')
    doc = RLDocTemplate(destfn, pagesize=pagesize or defaultPageSize)

    #this builds the story
    setStory()

    for f in (
            'ch1_intro',
            'ch2_graphics',
            'ch2a_fonts',
            'ch3_pdffeatures',
            'ch4_platypus_concepts',
            'ch5_paragraphs',
            'ch6_tables',
            'ch7_custom',
            'graph_intro',
            'graph_concepts',
            'graph_charts',
            'graph_shapes',
            'graph_widgets',
            'app_demos',
    ):
        #python source is supposed to be utf8 these days
        exec(asUnicode(open_and_read(f + '.py')), G, G)
    del G

    story = getStory()
    if verbose: print('Built story contains %d flowables...' % len(story))
    doc.multiBuild(story)
    if verbose: print('Saved "%s"' % destfn)
Example #15
0
def findImages(xml):
    "Returns lists of all images referred to in markup"
    xml = asUnicode(xml)
    validDoc = xhtmlDocFromXhtmlFragment(
        xml)  #adds 'html','head etc. to our fragment
    parser = pyRXPU.Parser(ReturnUTF8=1,
                           ExpandCharacterEntities=0,
                           ExpandGeneralEntities=0)
    tree = parser.parse(validDoc)
    walker = ImageFinder(tree)
    walker.go()
    return walker.images
Example #16
0
def run(pagesize=None, verbose=0, outDir=None):
    import sys,os
    from reportlab.lib.utils import open_and_read, asUnicode
    cwd = os.getcwd()
    docsDir=os.path.dirname(os.path.dirname(sys.argv[0]) or cwd)
    topDir=os.path.dirname(docsDir)
    if not outDir: outDir=docsDir
    G = {}
    sys.path.insert(0,topDir)
    from reportlab.pdfbase.pdfmetrics import registerFontFamily
    from reportlab.pdfbase import pdfmetrics
    from reportlab.pdfbase.ttfonts import TTFont
    pdfmetrics.registerFont(TTFont('Vera', 'Vera.ttf'))
    pdfmetrics.registerFont(TTFont('VeraBd', 'VeraBd.ttf'))
    pdfmetrics.registerFont(TTFont('VeraIt', 'VeraIt.ttf'))
    pdfmetrics.registerFont(TTFont('VeraBI', 'VeraBI.ttf'))
    registerFontFamily('Vera',normal='Vera',bold='VeraBd',italic='VeraIt',boldItalic='VeraBI')
    from tools.docco.rl_doc_utils import setStory, getStory, RLDocTemplate, defaultPageSize, H1, H2, H3, H4
    from tools.docco import rl_doc_utils
    exec('from tools.docco.rl_doc_utils import *', G, G)
    destfn = os.path.join(outDir,'reportlab-userguide.pdf')
    doc = RLDocTemplate(destfn,pagesize = pagesize or defaultPageSize)


    #this builds the story
    setStory()

    for f in (
        'ch1_intro',
        'ch2_graphics',
        'ch2a_fonts',
        'ch3_pdffeatures',
        'ch4_platypus_concepts',
        'ch5_paragraphs',
        'ch6_tables',
        'ch7_custom',
        'graph_intro',
        'graph_concepts',
        'graph_charts',
        'graph_shapes',
        'graph_widgets',
        'app_demos',
        ):
        #python source is supposed to be utf8 these days
        exec(asUnicode(open_and_read(f+'.py')), G, G)
    del G

    story = getStory()
    if verbose: print('Built story contains %d flowables...' % len(story))
    doc.multiBuild(story)
    if verbose: print('Saved "%s"' % destfn)
 def normalizeName(self, name):
     if not isUnicode(name):
         for enc in ('utf8', 'latin1'):
             try:
                 name = asUnicode(name, enc)
                 break
             except:
                 pass
         else:
             raise ValueError('Cannot normalize name %r' % name)
     r = name.strip().lower()
     nns = getattr(self, 'normalizeNameSpaces', None)
     if isStr(nns):
         r = nns.join(filter(None, r.split()))
     return r
Example #18
0
 def drawString(self, x, y, s, angle=0):
     if self._fillColor != None:
         fontSize = self._fontSize
         fontObj = getFont(self._font)
         dynamicFont = fontObj._dynamicFont
         embedding = self._ttf_embed and dynamicFont
         if not embedding and not self.code[self._fontCodeLoc]:
             psName = fontObj.face.name
             self.code[
                 self.
                 _fontCodeLoc] = '(%s) findfont %s scalefont setfont' % (
                     psName, fp_str(fontSize))
             if psName not in self._fontsUsed:
                 self._fontsUsed.append(psName)
         self.setColor(self._fillColor)
         if angle != 0:
             self.code_append('gsave %s translate %s rotate' %
                              (fp_str(x, y), fp_str(angle)))
             x = y = 0
         if embedding:
             i = 0
             s = asUnicode(s)
             for subset, t in fontObj.splitString(s, self):
                 if subset != self._curSubset:
                     psName = fontObj.getSubsetInternalName(subset,
                                                            self)[1:]
                     sf = '(%s) findfont %s scalefont setfont' % (
                         psName, fp_str(fontSize))
                     if not self.code[self._fontCodeLoc]:
                         self.code[self._fontCodeLoc] = sf
                     else:
                         self.code_append(sf)
                     self._curSubset = subset
                 self.code_append('%s m (%s) show ' %
                                  (fp_str(x, y), self._escape(t)))
                 j = i + len(t)
                 x += fontObj.stringWidth(s[i:j], fontSize)
                 i = j
         elif dynamicFont:
             s = self._escape(s)
             self.code_append('%s m (%s) show ' % (fp_str(x, y), s))
         else:
             self._issueT1String(fontObj, x, y, s)
         if angle != 0:
             self.code_append('grestore')
Example #19
0
    def textLines(self, stuff, trim=1):
        """prints multi-line or newlined strings, moving down.  One
        comon use is to quote a multi-line block in your Python code;
        since this may be indented, by default it trims whitespace
        off each line and from the beginning; set trim=0 to preserve
        whitespace."""
        if isStr(stuff):
            lines = asUnicode(stuff).strip().split(u'\n')
            if trim == 1:
                lines = [s.strip() for s in lines]
        elif isinstance(stuff, (tuple, list)):
            lines = stuff
        else:
            assert 1 == 0, "argument to textlines must be string,, list or tuple"

        # Output each line one at a time. This used to be a long-hand
        # copy of the textLine code, now called as a method.
        for line in lines:
            self.textLine(line)
Example #20
0
    def textLines(self, stuff, trim=1):
        """prints multi-line or newlined strings, moving down.  One
        comon use is to quote a multi-line block in your Python code;
        since this may be indented, by default it trims whitespace
        off each line and from the beginning; set trim=0 to preserve
        whitespace."""
        if isStr(stuff):
            lines = asUnicode(stuff).strip().split(u'\n')
            if trim==1:
                lines = [s.strip() for s in lines]
        elif isinstance(stuff,(tuple,list)):
            lines = stuff
        else:
            assert 1==0, "argument to textlines must be string,, list or tuple"

        # Output each line one at a time. This used to be a long-hand
        # copy of the textLine code, now called as a method.
        for line in lines:
            self.textLine(line)
Example #21
0
 def drawString(self, x, y, s, angle=0):
     if self._fillColor != None:
         fontSize = self._fontSize
         fontObj = getFont(self._font)
         dynamicFont = fontObj._dynamicFont
         embedding = self._ttf_embed and dynamicFont
         if not embedding and not self.code[self._fontCodeLoc]:
             psName = fontObj.face.name
             self.code[self._fontCodeLoc]='(%s) findfont %s scalefont setfont' % (psName,fp_str(fontSize))
             if psName not in self._fontsUsed:
                 self._fontsUsed.append(psName)
         self.setColor(self._fillColor)
         if angle!=0:
             self.code_append('gsave %s translate %s rotate' % (fp_str(x,y),fp_str(angle)))
             x = y = 0
         if embedding:
             i = 0
             s = asUnicode(s)
             for subset, t in fontObj.splitString(s, self):
                 if subset!=self._curSubset:
                     psName = fontObj.getSubsetInternalName(subset, self)[1:]
                     sf = '(%s) findfont %s scalefont setfont' % (psName,fp_str(fontSize))
                     if not self.code[self._fontCodeLoc]:
                         self.code[self._fontCodeLoc] = sf
                     else:
                         self.code_append(sf)
                     self._curSubset = subset
                 self.code_append('%s m (%s) show ' % (fp_str(x,y),self._escape(t)))
                 j = i + len(t)
                 x += fontObj.stringWidth(s[i:j],fontSize)
                 i = j
         elif dynamicFont:
             s = self._escape(s)
             self.code_append('%s m (%s) show ' % (fp_str(x,y),s))
         else:
             self._issueT1String(fontObj,x,y,s)
         if angle!=0:
             self.code_append('grestore')
Example #22
0
    def __init__(self,
                target="block",
                breaksAllowed=True,
                stripComments=False,
                stripUnknownEntities=True,
                allowImages=True,
                allowTables=True,
                allowAtags=True,
                allowStyleAttr=True, #passed through to para and headings
                allowAlignAttr=True, #passed through to para and headings  
                aHrefTr=None,
                imgSrcTr=None,
                substitutions=[],
                maxLines=None,
                lineWidth=40,
                entities = known_entities.keys(),
                encoding = None,
                ):
        """Initialising defines your language options.
        You can re-use the same parser many times.
        if breaksAllowed, they will be written to output.
        if not, in inline mode they vanish, and in block
        mode they end the block.

        substitutions is a a singleton or list containing
            pat         pat --> ''
            (pat,str)   pat --> str
            callable    c(src) --> src

        pat may be a str or a compiled pattern. These substitutions
        are done before parsing.
        """
        target = self.asUnicode(target)
        self.stripUnknownEntities = stripUnknownEntities
        self.allowImages = allowImages
        self.allowTables = allowTables
        self.allowAtags = allowAtags
        self.aHrefTr = aHrefTr
        self.imgSrcTr = imgSrcTr
        self.encoding = encoding
        self.allowAlignAttr = allowAlignAttr
        self.allowStyleAttr = allowStyleAttr
        self._setupGrammar()

        assert target in (u"block", u"inline"), "unexpected block '%s', must be 'block' or 'inline'" % target
        self.target = target
        HTMLParser.__init__(self)
        self.breaksAllowed = breaksAllowed
        self.stripComments = stripComments
        self.entities = set(entities).union(('lt', 'gt', 'amp'))

        #prefix up the substitutions list
        if not isinstance(substitutions,(list,tuple)):
            substitutions = (substitutions,)
        S=[].append
        for s in substitutions:
            if isinstance(s,strTypes):
                s = lambda x,pat=re.compile(asUnicode(s)): pat.sub('',x)
            elif hasattr(s,'sub'):
                s = lambda x,pat=s: pat.sub('',x)
            elif isinstance(s,(tuple,list)) and len(s)==2:
                p=s[0]
                if isinstance(p,str):
                    s = lambda x,pat=re.compile(p),s=s[1]: pat.sub(s,x)
                elif hasattr(p,'sub'):
                    s = lambda x,pat=p,s=s[1]: pat.sub(s,x)
                else:
                    raise ValueError('Invalid value %r in substitions list' % s)
            elif not isinstance(s, collections.Callable):
                raise ValueError('Invalid value %r in substitions list' % s)
            S(s)
        self.substitutions = S.__self__
        self.remainingLines = maxLines
        self.lineWidth = lineWidth
        self.textLength = 0
def equalStrings(a,b,enc='utf8'):
    return a==b if type(a)==type(b) else asUnicode(a,enc)==asUnicode(b,enc)
 def addParas(words):
     words = [asUnicode(w) for w in words]
     txt = u' '.join([(len(w) > 5 and u'<index item=%s/>%s' % (quoteattr(commajoin([w[:2], w[:3], w])), w) or w) for w in words])
     para = Paragraph(txt, makeBodyStyle())
     story.append(para)
Example #25
0
def bullet(text):
    text = u'<bullet><font name="Symbol">\u2022</font></bullet>' + asUnicode(quickfix(text))
    P = Paragraph(text, BU)
    getStory().append(P)
Example #26
0
 def uniDict(d):
     r = {}
     for k in d:
         r[asUnicode(k)] = d[k]
     return r
Example #27
0
def _processLine(line, sep=',', conv=0):
    if isUnicode(line):
        space = u' '
        dquot = u'"'
        empty = u''
        speol = u' \r\n'
        sep = asUnicode(sep)
    else:
        space = b' '
        dquot = b'"'
        empty = b''
        speol = b' \r\n'
        sep = asBytes(sep)
    fields = []
    p = 0
    ll = len(line)
    ls = len(sep)
    line += space
    while (ll > 0 and (line[ll-1] in speol)): ll -= 1

    while p < ll:
        #Skip unquoted space at the start of a field
        while p<ll and line[p]==space: p += 1

        field = empty
        ql = 0
        while p < ll:
            #Skip unquoted space at the end of a field
            if ql == 0 and line[p] == space:
                q = p
                while q < ll and line[q] == space:
                    q += 1
                if q >= ll:
                    break
                elif line[q:q+ls] == sep:
                    p = q
            if ql == 0 and line[p:p+ls] == sep:
                break
            elif line[p:p+1] == dquot:
                if ql == 0:
                    ql = 1
                elif line[p+1:p+2]==dquot:
                    field += dquot
                    p += 1
                else:
                    ql = 0
            else:
                field += line[p:p+1]
            p += 1
        p += ls
        if conv:
            try:
                fields.append(int(field))
            except ValueError:
                try:
                    fields.append(float(field))
                except ValueError:
                    fields.append(field)
        else:
            fields.append(field)
    if line[ll-ls:ll]==sep:
        fields.append(empty)    #extra field when there's a separator at the end

    return fields
Example #28
0
def __dict_replace(s, d):
    # This is grabbed from xml.sax.saxutils
    """Replace substrings of a string using a dictionary."""
    for key, value in list(d.items()):
        s = s.replace(asUnicode(key), asUnicode(value))
    return s
Example #29
0
def bullet(text):
    text = u'<bullet><font name="Symbol">\u2022</font></bullet>' + asUnicode(
        quickfix(text))
    P = Paragraph(text, BU)
    getStory().append(P)
Example #30
0
def equalStrings(a, b, enc='utf8'):
    return a == b if type(a) == type(b) else asUnicode(a, enc) == asUnicode(
        b, enc)
Example #31
0
def __dict_replace(s, d):
    # This is grabbed from xml.sax.saxutils
    """Replace substrings of a string using a dictionary."""
    for key, value in list(d.items()):
        s = s.replace(asUnicode(key), asUnicode(value))
    return s