def tokenize(string): """str -> Sequence(Token)""" # flake8: NOQA specs = [ # NOQA ('Comment', (r'/\*(.|[\r\n])*?\*/', MULTILINE)), # NOQA ('Comment', (r'(//|#).*', )), # NOQA ('NL', (r'[\r\n]+', )), # NOQA ('QuotedRackItem', (r'(?<=[:*\-])\s*(?P<quote>"|\').*?(?<!\\)(?P=quote)', DOTALL)), # NOQA ('RackItem', (r'(?<=[:*\-])[^\r\n\[;}]+', )), # NOQA ('Space', (r'[ \t\r\n]+', )), # NOQA ('RackHeight', (r'[0-9]+U', )), # NOQA ('Units', (r'[0-9]+(?:\.[0-9]+)?(A|kg)', )), # NOQA ('Number', (r'[0-9]+', )), # NOQA ( 'Name', ( u('[A-Za-z_0-9\u0080-\uffff]') + # NOQA u('[A-Za-z_\\-.0-9\u0080-\uffff]*'), )), # NOQA ('Op', (r'[{}:;,*\-=\[\]]', )), # NOQA ('String', (r'(?P<quote>"|\').*?(?<!\\)(?P=quote)', DOTALL)), # NOQA ] useless = ['Comment', 'NL', 'Space'] t = make_tokenizer(specs) return [x for x in t(string) if x.type not in useless]
def test_zenkaku_len(self): # abc self.assertEqual(0, zenkaku_len(u("abc"))) # あいう self.assertEqual(3, zenkaku_len(u("\u3042\u3044\u3046"))) # あいc self.assertEqual(2, zenkaku_len(u("\u3042\u3044c")))
def test_string_width(self): # abc self.assertEqual(3, string_width(u("abc"))) # あいう self.assertEqual(6, string_width(u("\u3042\u3044\u3046"))) # あいc self.assertEqual(5, string_width(u("\u3042\u3044c")))
def test_hankaku_len(self): # abc self.assertEqual(3, hankaku_len(u("abc"))) # あいう self.assertEqual(0, hankaku_len(u("\u3042\u3044\u3046"))) # あいc self.assertEqual(1, hankaku_len(u("\u3042\u3044c")))
def description_table(self, diagram): nodes = diagram.traverse_nodes widths = [25] + [50] * (len(RackItem.desctable) - 1) headers = [RackItem.attrname[name] for name in RackItem.desctable] descriptions = [n.to_desctable() for n in nodes()] descriptions.sort(key=cmp_to_key(directives.cmp_node_number)) # records for total total = ['-', 'Total'] + [''] * (len(RackItem.desctable) - 2) total[2] = u("%dU") % sum(n.colheight for n in nodes() if n.colheight) total[3] = u("%.1fA") % sum(n.ampere for n in nodes() if n.ampere) total[4] = u("%.1fkg") % sum(n.weight for n in nodes() if n.weight) descriptions.append(total) for i in range(len(headers) - 1, -1, -1): if any(desc[i] for desc in descriptions): pass else: widths.pop(i) headers.pop(i) for desc in descriptions: desc.pop(i) return self._description_table(descriptions, widths, headers)
def open(url, mode='Pillow'): if hasattr(url, 'read') or isinstance(url, Image.Image): stream = url elif not urlutil.isurl(url): stream = io.open(url, 'rb') else: try: # wrap BytesIO for rewind stream stream = io.BytesIO(urlopen(url).read()) except: warning(u("Could not retrieve: %s"), url) raise IOError image = pillow_open(url, stream) if mode.lower() == 'pillow': # stream will be closed by GC return image else: # mode == 'png' try: png_image = io.BytesIO() image.save(png_image, 'PNG') if hasattr(stream, 'close'): # close() is implemented on Pillow stream.close() except: warning(u("Could not convert image: %s"), url) raise IOError png_image.seek(0) return png_image
def save(self, filename, size, _format): if filename: self.filename = filename with io.open(self.filename, 'w', encoding='utf-8') as fd: fd.write(u("%!PS-Adobe-3.0 EPSF-3.0\n")) fd.write(u("%%%%BoundingBox: 0 0 %d %d\n") % self.size) fd.write(u("%%%%HiResBoundingBox: 0 0 %f %f\n") % self.size) for line in self.buffer: fd.write(line)
def test_fontmap_using_fontalias(self): _config = (u("[fontmap]\nserif-bold: %s\n") + u("[fontalias]\ntest = serif-bold\n")) % self.fontpath[0] config = StringIO(_config) fmap = FontMap(config) element = FontElement('test', 20) font1 = fmap.find(element) self.assertEqual('serif-bold', font1.familyname) self.assertEqual(self.fontpath[0], font1.path) self.assertEqual(20, font1.size)
def display_label(self): attrs = [] if self.description or attrs: attrs.insert(0, u("%dU") % self.colheight) labels = [] if self.description: labels.append(self.description) if attrs: labels.append(u("[%s]") % u("/").join(attrs)) return u("\n").join(labels)
def to_xml(self): io = StringIO() if not self.nodoctype: url = "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd" io.write(u("<?xml version='1.0' encoding='UTF-8'?>\n")) io.write(u('<!DOCTYPE svg PUBLIC ') + u('"-//W3C//DTD SVG 1.0//EN" "%s">\n') % url) super(svg, self).to_xml(io) return io.getvalue()
def to_desctable(self): attrs = [] for name in self.desctable: if name == 'units': attrs.append(u("%dU") % self.colheight) elif name == 'ampere': if self.ampere is None: attrs.append(u("")) else: attrs.append((u("%.1fA") % self.ampere) or u("")) elif name == 'weight': if self.weight is None: attrs.append(u("")) else: attrs.append((u("%.1fkg") % self.weight) or u("")) else: value = getattr(self, name) if value is None: attrs.append(u("")) elif isinstance(value, int): attrs.append(str(value)) else: attrs.append(getattr(self, name)) return attrs
def test_fontmap_empty_config(self): config = StringIO(u("")) fmap = FontMap(config) font1 = fmap.find() self.assertTrue(font1) self.assertEqual('sans-serif', font1.generic_family) self.assertEqual(None, font1.path) self.assertEqual(11, font1.size) element = FontElement('sansserif', 11) font2 = fmap.find(element) self.assertEqual(font1.familyname, font2.familyname) self.assertEqual(font1.path, font2.path) self.assertEqual(font1.size, font2.size) element = FontElement('sansserif-normal', 11) font3 = fmap.find(element) self.assertEqual(font1.familyname, font3.familyname) self.assertEqual(font1.path, font3.path) self.assertEqual(font1.size, font3.size) # non-registered familyname element = FontElement('my-sansserif-normal', 11) font4 = fmap.find(element) self.assertEqual(font1.familyname, font4.familyname) self.assertEqual(font1.path, font4.path) self.assertEqual(font1.size, font4.size)
def _draw_elements(self, **kwargs): default_font = self.metrics.font_for(self.diagram) for rack in self.diagram.racks: frame = self.metrics.cell(rack, use_padding=False).box self.drawer.rectangle(frame, fill='white', outline=self.diagram.linecolor) for i in range(rack.colheight): box = self.metrics.racknumber(rack, i) number = u("%d") % (i + 1) self.drawer.textarea(box, number, default_font, halign='right', fill=self.diagram.textcolor) if rack.display_label: box = self.metrics.racklabel(rack) self.drawer.textarea(box, rack.display_label, self.metrics.font_for(rack), fill=rack.textcolor) super(DiagramDraw, self)._draw_elements(**kwargs)
def test_fontmap_switch_defaultfamily(self): _config = u("[fontmap]\nserif-bold: %s\n") % self.fontpath[0] config = StringIO(_config) fmap = FontMap(config) font1 = fmap.find() self.assertEqual('sansserif-normal', font1.familyname) self.assertEqual(None, font1.path) self.assertEqual(11, font1.size) fmap.set_default_fontfamily('serif-bold') font2 = fmap.find() self.assertEqual('serif-bold', font2.familyname) self.assertEqual(self.fontpath[0], font2.path) self.assertEqual(11, font2.size) fmap.set_default_fontfamily('fantasy-italic') font3 = fmap.find() self.assertEqual('fantasy-italic', font3.familyname) self.assertEqual(None, font3.path) self.assertEqual(11, font3.size) fmap.fontsize = 20 font4 = fmap.find() self.assertEqual('fantasy-italic', font4.familyname) self.assertEqual(None, font4.path) self.assertEqual(20, font4.size)
def _draw_elements(self, **kwargs): m = self.metrics # render label of lanes for i, lane in enumerate(self.diagram.lanes): if lane.label: label = lane.label elif isinstance(lane.id, string_types): label = lane.id else: label = u('Lane %d') % (i + 1) if lane.href and self.format == 'SVG': drawer = self.drawer.anchor(lane.href) else: drawer = self.drawer headerbox = m.lane_headerbox(lane) drawer.rectangle(headerbox, fill=lane.color, outline=lane.color) textbox = m.lane_textbox(lane) drawer.textarea(textbox, label, fill=self.fill, font=self.metrics.font_for(lane)) # render frame of activity lanes frame = m.frame(self.diagram.lanes) self.drawer.rectangle(frame.outline, outline='gray') for xy in frame.separators: self.drawer.line(xy, fill='gray') super(DiagramDraw, self)._draw_elements(**kwargs)
def test_font_settings_error(self, app, draw): draw.side_effect = UnicodeEncodeError("", u(""), 0, 0, "") app.builder.warn = Mock() app.builder.build_all() self.assertIn('UnicodeEncodeError caught (check your font settings)', app.builder.warn.call_args_list[0][0][0])
def append_font(self, fontfamily, path): _path, _ = parse_fontpath(path) if path is None or os.path.isfile(_path): font = FontInfo(fontfamily, path, self.fontsize) self.fonts[font.familyname] = font else: msg = 'fontfile `%s` is not found: %s' % (fontfamily, path) sys.stderr.write(u("WARNING: %s\n") % msg)
def test_setup_inline_svg_is_true_with_multibytes(self): directives.setup(format='SVG', outputdir=self.tmpdir) text = u(".. blockdiag::\n" "\n" " あ -> い") doctree = publish_doctree(text) self.assertEqual(1, len(doctree)) self.assertEqual(nodes.image, type(doctree[0]))
def tokenize(string): """str -> Sequence(Token)""" # flake8: NOQA specs = [ # NOQA ('Comment', (r'/\*(.|[\r\n])*?\*/', MULTILINE)), # NOQA ('Comment', (r'(//|#).*',)), # NOQA ('NL', (r'[\r\n]+',)), # NOQA ('Space', (r'[ \t\r\n]+',)), # NOQA ('Name', (u('[A-Za-z_0-9\u0080-\uffff]') + # NOQA u('[A-Za-z_\\-.0-9\u0080-\uffff]*'),)), # NOQA ('Op', (r'[{};,=\[\]]|(<->)|(<-)|(--)|(->)|(>-<)|(-<)|(>-)',)), # NOQA ('Number', (r'-?(\.[0-9]+)|([0-9]+(\.[0-9]*)?)',)), # NOQA ('String', (r'(?P<quote>"|\').*?(?<!\\)(?P=quote)', DOTALL)), # NOQA ] useless = ['Comment', 'NL', 'Space'] t = make_tokenizer(specs) return [x for x in t(string) if x.type not in useless]
def tokenize(string): """str -> Sequence(Token)""" # flake8: NOQA specs = [ # NOQA ('Comment', (r'/\*(.|[\r\n])*?\*/', MULTILINE)), # NOQA ('Comment', (r'(//|#).*',)), # NOQA ('NL', (r'[\r\n]+',)), # NOQA ('Space', (r'[ \t\r\n]+',)), # NOQA ('Name', (u('[A-Za-z_0-9\u0080-\uffff]') + # NOQA u('[A-Za-z_\\-.0-9\u0080-\uffff]*'),)), # NOQA ('Op', (r'[{};,=\[\]]|(<->)|(<-)|(--)|(->)',)), # NOQA ('Number', (r'-?(\.[0-9]+)|([0-9]+(\.[0-9]*)?)',)), # NOQA ('String', (r'(?P<quote>"|\').*?(?<!\\)(?P=quote)', DOTALL)), # NOQA ] useless = ['Comment', 'NL', 'Space'] t = make_tokenizer(specs) return [x for x in t(string) if x.type not in useless]
def test_setup_inline_svg_is_true_with_multibytes(self): directives.setup(format='SVG', outputdir=self.tmpdir, inline_svg=True) text = u(".. seqdiag::\n" "\n" " あ -> い") doctree = publish_doctree(text) self.assertEqual(1, len(doctree)) self.assertEqual(nodes.raw, type(doctree[0]))
def test_fontmap_with_nonexistence_fontpath(self): _config = u("[fontmap]\nserif: unknown_file\n") config = StringIO(_config) fmap = FontMap(config) font1 = fmap.find() self.assertEqual('sans-serif', font1.generic_family) self.assertEqual(None, font1.path) self.assertEqual(11, font1.size)
def test_test_textsize(self): from blockdiag.utils.fontmap import FontInfo font = FontInfo('serif', None, 11) # abc self.assertEqual((19, 11), textsize(u("abc"), font)) # あいう self.assertEqual((33, 11), textsize(u("\u3042\u3044\u3046"), font)) # あいc self.assertEqual((29, 11), textsize(u("\u3042\u3044c"), font)) # abc font = FontInfo('serif', None, 24) self.assertEqual((40, 24), textsize(u("abc"), font)) # あいう font = FontInfo('serif', None, 18) self.assertEqual((54, 18), textsize(u("\u3042\u3044\u3046"), font))
def test_setup_inline_svg_is_true_with_multibytes(self): directives.setup(format='SVG', outputdir=self.tmpdir, inline_svg=True) text = u(".. rackdiag::\n" "\n" " 1: サーバ\n" " 2: データベース\n") doctree = publish_doctree(text) self.assertEqual(1, len(doctree)) self.assertEqual(nodes.raw, type(doctree[0]))
def to_desctable(self): attrs = [] for name in self.desctable: value = getattr(self, name) if value is None: attrs.append(u("")) else: attrs.append(value) return attrs
def set_edge_layout(self, value): value = value.lower() if value in ('normal', 'flowchart'): msg = u("WARNING: edge_layout is very experimental feature!\n") sys.stderr.write(msg) self.edge_layout = value else: msg = "WARNING: unknown edge layout: %s\n" % value raise AttributeError(msg)
def tokenize(string): """str -> Sequence(Token)""" # flake8: NOQA specs = [ # NOQA ('Comment', (r'/\*(.|[\r\n])*?\*/', MULTILINE)), # NOQA ('Comment', (r'(//|#).*',)), # NOQA ('NL', (r'[\r\n]+',)), # NOQA ('Number', (r'[0-9]+',)), # NOQA ('QuotedFieldItem', (r'(?<=[:*\-])\s*(?P<quote>"|\').*?(?<!\\)(?P=quote)',)), # NOQA ('FieldItem', (r'(?<=[:*\-])\s*[^\r\n\[;}]+',)), # NOQA ('Space', (r'[ \t\r\n]+',)), # NOQA ('Name', (u('[A-Za-z_0-9\u0080-\uffff]') + # NOQA u('[A-Za-z_\\-.0-9\u0080-\uffff]*'),)), # NOQA ('Op', (r'[{}:;,*\-=\[\]]',)), # NOQA ('String', (r'(?P<quote>"|\').*?(?<!\\)(?P=quote)', DOTALL)), # NOQA ] useless = ['Comment', 'NL', 'Space'] t = make_tokenizer(specs) return [x for x in t(string) if x.type not in useless]
def test_fontmap_duplicated_fontentry2(self): _config = u("[fontmap]\nsansserif: %s\nsansserif-normal: %s\n") % \ (self.fontpath[0], self.fontpath[1]) config = StringIO(_config) fmap = FontMap(config) font1 = fmap.find() self.assertEqual('sans-serif', font1.generic_family) self.assertEqual(self.fontpath[1], font1.path) self.assertEqual(11, font1.size)
def test_config_option_with_bom(self): try: tmp = tempfile.mkstemp() fp = io.open(tmp[0], 'wt', encoding='utf-8-sig') fp.write(u("[blockdiag]\n")) fp.close() self.parser.parse(['-c', tmp[1], 'input.diag']) finally: os.unlink(tmp[1])
def test_config_option_fontpath(self): try: tmp = tempfile.mkstemp() config = u("[blockdiag]\nfontpath = /path/to/font\n") io.open(tmp[0], 'wt', encoding='utf-8-sig').write(config) options = self.parser.parse(['-c', tmp[1], 'input.diag']) self.assertEqual(options.font, ['/path/to/font']) finally: os.unlink(tmp[1])
def test_fontmap_including_bom_by_file(self): tmp = tempfile.mkstemp() _config = (u("[fontmap]\nsansserif: %s\n") + u("sansserif-bold: %s\n")) % \ (self.fontpath[0], self.fontpath[1]) try: fp = os.fdopen(tmp[0], 'wb') fp.write(_config.encode('utf-8-sig')) fp.close() fmap = FontMap(tmp[1]) font1 = fmap.find() self.assertTrue(font1) self.assertEqual('sans-serif', font1.generic_family) self.assertEqual(self.fontpath[0], font1.path) self.assertEqual(11, font1.size) finally: os.unlink(tmp[1])
def test_fontmap_with_capital_character(self): _config = u("[fontmap]\nCapitalCase-sansserif: %s\n") % \ self.fontpath[0] config = StringIO(_config) fmap = FontMap(config) element = FontElement('CapitalCase-sansserif', 11) font1 = fmap.find(element) self.assertEqual('sans-serif', font1.generic_family) self.assertEqual('capitalcase-sansserif-normal', font1.familyname) self.assertEqual(self.fontpath[0], font1.path) self.assertEqual(11, font1.size)
def test_fontmap_duplicated_fontentry2(self): # this testcase is only for python2.6 or later if sys.version_info > (2, 6): _config = u("[fontmap]\nsansserif: %s\nsansserif-normal: %s\n") % \ (self.fontpath[0], self.fontpath[1]) config = StringIO(_config) fmap = FontMap(config) font1 = fmap.find() self.assertEqual('sans-serif', font1.generic_family) self.assertEqual(self.fontpath[1], font1.path) self.assertEqual(11, font1.size)
def run(self, args): try: self.parse_options(args) self.create_fontmap() parsed = self.parse_diagram() return self.build_diagram(parsed) except SystemExit as e: return e except UnicodeEncodeError as e: msg = u("ERROR: UnicodeEncodeError caught " "(check your font settings)\n") sys.stderr.write(msg) return -1 except Exception as e: if self.options and self.options.debug: import traceback traceback.print_exc() else: sys.stderr.write(u("ERROR: %s\n") % e) return -1
def image(self, box, url): if urlutil.isurl(url): from reportlab.lib.utils import ImageReader try: url = ImageReader(url) except: msg = u("WARNING: Could not retrieve: %s\n") % url sys.stderr.write(msg) return y = self.size[1] - box[3] self.canvas.drawImage(url, box.x1, y, box.width, box.height, mask='auto', preserveAspectRatio=True)
def set_style(self, style, thick): if thick is None: thick = 1 if style == 'dotted': self.write("[%d %d] 0 setdash", 2 * thick, 2 * thick) elif style == 'dashed': self.write("[%d %d] 0 setdash", 4 * thick, 4 * thick) elif style == 'none': self.buffer.append(u("[0 65535] 0 setdash\n")) elif re.search('^\d+(,\d+)*$', style or ""): pattern = [int(n) * thick for n in style.split(',')] self.write("[%s] 0 setdash", " ".join(pattern))
def test_splitlabel(self): # single line text text = "abc" self.assertEqual(['abc'], list(splitlabel(text))) # text include \n (as char a.k.a. \x5c) text = "abc\ndef" self.assertEqual(['abc', 'def'], list(splitlabel(text))) # text include \n (as mac yensign a.k.a. \xa5) text = "abc\xa5ndef" self.assertEqual(['abc', 'def'], list(splitlabel(text))) # text includes \n (as text) text = "abc\\ndef" self.assertEqual(['abc', 'def'], list(splitlabel(text))) # text includes escaped \n text = "abc\\\\ndef" self.assertEqual(['abc\\ndef'], list(splitlabel(text))) # text includes escaped \n (\x5c and mac yensign mixed) if sys.version_info[0] == 2: text = u("abc\xa5\\\\ndef") else: text = u("abc\xa5\\ndef") self.assertEqual(['abc\\ndef'], list(splitlabel(text))) # text include \n and spaces text = " abc \n def " self.assertEqual(['abc', 'def'], list(splitlabel(text))) # text starts empty line text = " \nabc\ndef" self.assertEqual(['abc', 'def'], list(splitlabel(text))) # text starts empty line with \n (as text) text = " \\nabc\\ndef" self.assertEqual(['', 'abc', 'def'], list(splitlabel(text)))
def _draw_background(self): # do not call blockdiag.DiagramDraw#_draw_background() scale_interval = self.diagram.scale_interval if scale_interval is None: scale_interval = self.diagram.colwidth / 2 # draw measure lines and labels font = self.metrics.font_for(None) for i in range(self.diagram.colwidth + 1): line = self.metrics.measure_line(i) self.drawer.line(line, fill=self.diagram.linecolor) if (i % scale_interval) == 0: box = self.metrics.measure_label(i) if self.diagram.scale_direction == "left_to_right": label = u(str(i)) else: label = u(str(self.diagram.colwidth - i)) self.drawer.textarea(box, label, font, fill=self.diagram.textcolor)