def renderToFile(self, content, imagePath): """ content - текст, описывающий диаграмму imagePath - полный путь до создаваемого файла """ from blockdiag.parser import parse_string from blockdiag.drawer import DiagramDraw from blockdiag.builder import ScreenNodeBuilder from blockdiag.utils.fontmap import FontMap font = os.path.join(os.path.dirname(os.path.abspath(__file__)), u"fonts", self._fontDefault) fontmap = FontMap() fontmap.set_default_font(font) text = u"blockdiag {{ {content} }}".format(content=content) tree = parse_string(text) diagram = ScreenNodeBuilder.build(tree) draw = DiagramDraw("png", diagram, imagePath, fontmap=fontmap, antialias=True) draw.draw() draw.save()
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 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 create_fontmap(options): fontmap = FontMap(options.fontmap) if fontmap.find().path is None or options.font: fontpath = detectfont(options) fontmap.set_default_font(fontpath) return fontmap
def create_fontmap(options): fontmap = FontMap(options.fontmap) if fontmap.find().path is None or options.font: fontpath = detectfont(options) fontmap.set_default_font(fontpath) return fontmap
def on_builder_inited(self): # show deprecated message if self.builder.config.rackdiag_tex_image_format: self.builder.warn('rackdiag_tex_image_format is deprecated. Use rackdiag_latex_image_format.') # initialize fontmap global fontmap try: fontmappath = self.builder.config.rackdiag_fontmap fontmap = FontMap(fontmappath) except: fontmap = FontMap(None) try: fontpath = self.builder.config.rackdiag_fontpath if isinstance(fontpath, string_types): fontpath = [fontpath] if fontpath: config = namedtuple('Config', 'font')(fontpath) fontpath = detectfont(config) fontmap.set_default_font(fontpath) except: pass
def renderToFile(self, content, imagePath): """ content - текст, описывающий диаграмму imagePath - полный путь до создаваемого файла """ from blockdiag.parser import parse_string from blockdiag.drawer import DiagramDraw from blockdiag.builder import ScreenNodeBuilder from blockdiag.utils.fontmap import FontMap font = os.path.join(os.path.dirname(os.path.abspath(__file__)), u"fonts", self._fontDefault) fontmap = FontMap() fontmap.set_default_font(font) text = u"blockdiag {{ {content} }}".format(content=content) tree = parse_string(text) diagram = ScreenNodeBuilder.build(tree) draw = DiagramDraw("png", diagram, imagePath, fontmap=fontmap, antialias=True) draw.draw() draw.save()
def test_fontmap_none_config(self): fmap = FontMap() font1 = fmap.find() self.assertTrue(font1) self.assertEqual('sans-serif', font1.generic_family) self.assertEqual(None, font1.path) self.assertEqual(11, font1.size)
def test_fontmap_none_config(self): fmap = FontMap() font1 = fmap.find() self.assertTrue(font1) self.assertEqual('sans-serif', font1.generic_family) self.assertEqual(None, font1.path) self.assertEqual(11, font1.size)
def test_fontmap_with_nonexistence_fontpath(self): _config = "[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_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 _create_fontmap(fontmap, font): """ Inspired from :epkg:`blockdiag` source file (*_bootstrap.py*). """ from blockdiag.utils.fontmap import FontMap fontmap = FontMap(fontmap) if fontmap.find().path is None or font: fontpath = _detectfont(font) fontmap.set_default_font(fontpath) return fontmap
def test_fontmap_duplicated_fontentry2(self): _config = "[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_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 test_fontmap_using_fontalias(self): _config = ("[fontmap]\nserif-bold: %s\n" + "[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 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 test_fontmap_with_capital_character(self): _config = "[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_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 test_fontmap_duplicated_fontentry1(self): _config = u("[fontmap]\nsansserif: %s\nsansserif: %s\n") % \ (self.fontpath[0], self.fontpath[1]) config = StringIO(_config) if sys.version_info[0] == 2: 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) else: import configparser with self.assertRaises(configparser.DuplicateOptionError): FontMap(config)
def test_fontmap_duplicated_fontentry1(self): _config = u("[fontmap]\nsansserif: %s\nsansserif: %s\n") % \ (self.fontpath[0], self.fontpath[1]) config = StringIO(_config) if sys.version_info[0] == 2: 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) else: import configparser with self.assertRaises(configparser.DuplicateOptionError): FontMap(config)
def flowchartdiag_generate_image(source, format): from blockdiag import parser, builder, drawer from blockdiag.utils.fontmap import FontMap from StringIO import StringIO from flowchartdiag import parse, write_stmt try: ast = parse(source) dot = StringIO() dot.write("{\n") dot.write(" orientation = portrait\n") dot.write(" edge_layout = flowchart\n") dot.write(" node_width = 256\n") write_stmt(dot, ast.body) dot.write("}\n") tree = parser.parse_string(dot.getvalue()) diagram = builder.ScreenNodeBuilder.build(tree) draw = drawer.DiagramDraw(format, diagram, fontmap=FontMap(), ignore_pil=True) draw.draw() image = draw.save() etype = None error = None except Exception, e: image = '' etype = e.__class__.__name__ error = str(e)
def test_fontmap_by_file(self): tmp = tempfile.mkstemp() _config = "[fontmap]\nsansserif: %s\nsansserif-bold: %s\n" % \ (self.fontpath[0], self.fontpath[1]) fp = os.fdopen(tmp[0], 'wt') fp.write(_config) 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) os.unlink(tmp[1])
def test_fontmap_by_file(self): tmp = tempfile.mkstemp() _config = u("[fontmap]\nsansserif: %s\nsansserif-bold: %s\n") % \ (self.fontpath[0], self.fontpath[1]) fp = os.fdopen(tmp[0], 'wt') fp.write(_config) 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) os.unlink(tmp[1])
def get_fontmap(): from StringIO import StringIO from blockdiag.utils.fontmap import FontMap dummy = re.sub('pyc', 'py', __file__) config = open(u"%s/../fontmaprc" % os.path.dirname(dummy)).read() config = re.sub('FILENAME', dummy, config) fmap = FontMap(StringIO(config)) return fmap
def __init__(self, diagram, drawer=None, fontmap=None): self.drawer = drawer if diagram.node_width is not None: self.node_width = diagram.node_width if diagram.node_height is not None: self.node_height = diagram.node_height if diagram.span_width is not None: self.span_width = diagram.span_width if diagram.span_height is not None: self.span_height = diagram.span_height if fontmap is not None: self.fontmap = fontmap else: self.fontmap = FontMap() if diagram.page_padding is not None: self.page_padding = diagram.page_padding if diagram.edge_layout is not None: self.edge_layout = diagram.edge_layout # setup spreadsheet sheet = self.spreadsheet = SpreadSheetMetrics(self) nodes = [n for n in diagram.traverse_nodes() if n.drawable] node_width = self.node_width for x in range(diagram.colwidth): widths = [n.width for n in nodes if n.xy.x == x] if widths: width = max(n or node_width for n in widths) sheet.set_node_width(x, width) node_height = self.node_height for y in range(diagram.colheight): heights = [n.height for n in nodes if n.xy.y == y] if heights: height = max(n or node_height for n in heights) sheet.set_node_height(y, height)
def draw_blockdiag(content, filename=None, font_path=None, output_fmt='png'): diag_type, content = content.split(" ", 1) parser, builder, drawer = DIAG_MODULES[diag_type.strip()] tree = parser.parse_string(content) diagram = builder.ScreenNodeBuilder.build(tree) fontmap = FontMap() if font_path: fontmap.set_default_font(font_path) draw = drawer.DiagramDraw(output_fmt, diagram, filename=filename, antialias=True, fontmap=fontmap) draw.draw() return draw.save()
def test_fontmap_including_bom_by_file(self): tmp = tempfile.mkstemp() _config = ("[fontmap]\nsansserif: %s\n" + "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_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_nodefault_fontentry(self): _config = "[fontmap]\nserif: %s\n" % self.fontpath[0] 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) element = FontElement('serif', 11) font2 = fmap.find(element) self.assertEqual('serif', font2.generic_family) self.assertEqual(self.fontpath[0], font2.path) self.assertEqual(font1.size, font2.size) element = FontElement('fantasy', 20) font3 = fmap.find(element) self.assertEqual('sans-serif', font3.generic_family) self.assertEqual(None, font3.path) self.assertEqual(20, font3.size)
def test_fontmap_with_nodefault_fontentry(self): _config = u("[fontmap]\nserif: %s\n") % self.fontpath[0] 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) element = FontElement('serif', 11) font2 = fmap.find(element) self.assertEqual('serif', font2.generic_family) self.assertEqual(self.fontpath[0], font2.path) self.assertEqual(font1.size, font2.size) element = FontElement('fantasy', 20) font3 = fmap.find(element) self.assertEqual('sans-serif', font3.generic_family) self.assertEqual(None, font3.path) self.assertEqual(20, font3.size)
def draw_diag(path): read_file_and_process(path) diagram_definition = convert_to_origin_seqdiag() print('Converted definition : {}'.format(diagram_definition)) tree = parser.parse_string(diagram_definition) diagram = builder.ScreenNodeBuilder.build(tree) fm = FontMap() fm.set_default_font('./malgun.ttf') draw = drawer.DiagramDraw('PNG', diagram, filename='{}.png'.format( path.split('/\\')[-1].split('.')[0]), fontmap=fm) draw.draw() draw.save() pass
def test_fontmap_empty_config(self): config = StringIO("") 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 on_builder_inited(self): # show deprecated message if self.builder.config.rackdiag_tex_image_format: self.builder.warn( 'rackdiag_tex_image_format is deprecated. Use rackdiag_latex_image_format.' ) # initialize fontmap global fontmap try: fontmappath = self.builder.config.rackdiag_fontmap fontmap = FontMap(fontmappath) except: fontmap = FontMap(None) try: fontpath = self.builder.config.rackdiag_fontpath if isinstance(fontpath, string_types): fontpath = [fontpath] if fontpath: config = namedtuple('Config', 'font')(fontpath) fontpath = detectfont(config) fontmap.set_default_font(fontpath) except: pass
def test_fontmap_normal_config(self): _config = "[fontmap]\nsansserif: %s\nsansserif-bold: %s\n" % \ (self.fontpath[0], self.fontpath[1]) config = StringIO(_config) fmap = FontMap(config) 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) 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) element = FontElement('sansserif-bold', 11) font4 = fmap.find(element) self.assertEqual('sansserif-bold', font4.familyname) self.assertEqual(self.fontpath[1], font4.path) self.assertEqual(font1.size, font4.size) element = FontElement(None, None) font5 = fmap.find(element) self.assertEqual(font1.familyname, font5.familyname) self.assertEqual(font1.path, font5.path) self.assertEqual(font1.size, font5.size) element = object() font6 = fmap.find(element) self.assertEqual(font1.familyname, font6.familyname) self.assertEqual(font1.path, font6.path) self.assertEqual(font1.size, font6.size)
def __init__(self, diagram, drawer=None, fontmap=None): self.drawer = drawer if diagram.node_width is not None: self.node_width = diagram.node_width if diagram.node_height is not None: self.node_height = diagram.node_height if diagram.span_width is not None: self.span_width = diagram.span_width if diagram.span_height is not None: self.span_height = diagram.span_height if fontmap is not None: self.fontmap = fontmap else: self.fontmap = FontMap() if diagram.page_padding is not None: self.page_padding = diagram.page_padding if diagram.edge_layout is not None: self.edge_layout = diagram.edge_layout # setup spreadsheet sheet = self.spreadsheet = SpreadSheetMetrics(self) nodes = [n for n in diagram.traverse_nodes() if n.drawable] node_width = self.node_width for x in range(diagram.colwidth): widths = [n.width for n in nodes if n.xy.x == x] if widths: width = max(n or node_width for n in widths) sheet.set_node_width(x, width) node_height = self.node_height for y in range(diagram.colheight): heights = [n.height for n in nodes if n.xy.y == y] if heights: height = max(n or node_height for n in heights) sheet.set_node_height(y, height)
def test_fontmap_normal_config(self): _config = u("[fontmap]\nsansserif: %s\nsansserif-bold: %s\n") % \ (self.fontpath[0], self.fontpath[1]) config = StringIO(_config) fmap = FontMap(config) 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) 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) element = FontElement('sansserif-bold', 11) font4 = fmap.find(element) self.assertEqual('sansserif-bold', font4.familyname) self.assertEqual(self.fontpath[1], font4.path) self.assertEqual(font1.size, font4.size) element = FontElement(None, None) font5 = fmap.find(element) self.assertEqual(font1.familyname, font5.familyname) self.assertEqual(font1.path, font5.path) self.assertEqual(font1.size, font5.size) element = object() font6 = fmap.find(element) self.assertEqual(font1.familyname, font6.familyname) self.assertEqual(font1.path, font6.path) self.assertEqual(font1.size, font6.size)
def test_fontinfo_parse(self): font = FontInfo("serif", None, 11) @@ -212,15 +212,17 @@ class TestUtilsFontmap(unittest2.TestCas self.assertEqual(11, font1.size) def test_fontmap_duplicated_fontentry1(self): - _config = "[fontmap]\nsansserif: %s\nsansserif-normal: %s\n" % \ - (self.fontpath[0], self.fontpath[1]) - config = StringIO(_config) - fmap = FontMap(config) - - font1 = fmap.find() - self.assertEqual('sansserif', font1.generic_family) - self.assertEqual(self.fontpath[1], font1.path) - self.assertEqual(11, font1.size) + # this testcase is only for python2.6 or later + if sys.version_info > (2, 6): + _config = "[fontmap]\nsansserif: %s\nsansserif-normal: %s\n" % \ + (self.fontpath[0], self.fontpath[1]) + config = StringIO(_config) + fmap = FontMap(config) + + font1 = fmap.find() + self.assertEqual('sansserif', font1.generic_family) + self.assertEqual(self.fontpath[1], font1.path) + self.assertEqual(11, font1.size) @stderr_wrapper def test_fontmap_with_nodefault_fontentry(self):
def test_fontmap_duplicated_fontentry1(self): _config = "[fontmap]\nsansserif: %s\nsansserif: %s\n" % \ (self.fontpath[0], self.fontpath[1]) config = StringIO(_config) with self.assertRaises(configparser.DuplicateOptionError): FontMap(config)
def test_fontmap_switch_defaultfamily(self): _config = "[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 create_fontmap(self, font): fontmap = FontMap() fontmap.set_default_font(font) return fontmap
def create_fontmap(): fontmap = FontMap(None) fontmap.set_default_font( os.path.join(os.getcwd(), 'dummy_font', 'ipag.ttf')) return fontmap
import os import glob from cStringIO import StringIO from optparse import OptionParser from blockdiag import parser from blockdiag import builder from blockdiag import drawer from blockdiag.utils.fontmap import FontMap from blockdiag.utils.config import ConfigParser from blockdiag.utils.bootstrap import Application options = None fontmap = FontMap() #fontmap = FontMap(StringIO("""[fontmap] #sans-bold: dejavu-fonts-ttf-2.33/ttf/DejaVuSans-Bold.ttf #sans-boldoblique: dejavu-fonts-ttf-2.33/ttf/DejaVuSans-BoldOblique.ttf #sans-extralight: dejavu-fonts-ttf-2.33/ttf/DejaVuSans-ExtraLight.ttf #sans-oblique: dejavu-fonts-ttf-2.33/ttf/DejaVuSans-Oblique.ttf #sans-normal: dejavu-fonts-ttf-2.33/ttf/DejaVuSans.ttf""")) ttf_fonts = \ [('sansserif-bold', os.path.abspath( 'dejavu-fonts-ttf-2.33/ttf/DejaVuSans-Bold.ttf')), ('sansserif-oblique', os.path.abspath( 'dejavu-fonts-ttf-2.33/ttf/DejaVuSans-Oblique.ttf')), ('sansserif-normal', os.path.abspath( 'dejavu-fonts-ttf-2.33/ttf/DejaVuSans.ttf'))] fontmap.set_default_fontfamily('sansserif-normal') fontmap.set_default_font(os.path.abspath('dejavu-fonts-ttf-2.33/ttf/DejaVuSans.ttf'))
class PADImageDraw(SVGImageDraw): def __init__(self, *args, **kwargs): super(PADImageDraw, self).__init__(*args, **kwargs) self.fontmap = FontMap() self.fontmap.set_default_font('/Library/Fonts/Hiragino Sans GB W3.otf') self.font = self.fontmap.find() def if_block(self, x, y, stmt): width, height = self.statement(x + 1, y, stmt.body) textbox = box(x, y, height=height + 0.25).shift(y=NODE_HEIGHT / 3) shape = (textbox.topleft, textbox.topright, textbox.right.shift(x=-32), textbox.bottomright, textbox.bottomleft, textbox.topleft) self.line(shape, fill='black') self.textarea(textbox, "".join(stmt.test), self.font, fill='black') self.link(x, textbox.top.y) if stmt.orelse == []: height += 1 else: w, h = self.statement(x + 1, y + height, stmt.orelse) width = max(width, w) height += h self.link(x, textbox.bottom.y) return (width + 1, height) def while_block(self, x, y, stmt): textbox = box(x, y) self.rectangle(textbox, outline='black', fill='white') self.textarea(textbox, "".join(stmt.test), self.font, fill='black') self.line( (textbox.topleft.shift(x=12), textbox.bottomleft.shift(x=12)), fill='black') self.link(x, textbox.right.y) width, height = self.statement(x + 1, y, stmt.body) return (width + 1, height) def for_block(self, x, y, stmt): textbox = box(x, y) label = "for %s in %s" % ("".join(stmt.target), "".join(stmt.iter)) self.rectangle(textbox, outline='black', fill='white') self.textarea(textbox, label, self.font, fill='black') self.line( (textbox.topleft.shift(x=12), textbox.bottomleft.shift(x=12)), fill='black') self.link(x, textbox.right.y) width, height = self.statement(x + 1, y, stmt.body) return (width + 1, height) def render(self, tree): return self.statement(0, 0, tree.body) def statement(self, x, y, statements): height = 0 width = 0 for stmt in statements: if isinstance(stmt, str): w, h = self.process(x, y + height, stmt) elif isinstance(stmt, ast.If): w, h = self.if_block(x, y + height, stmt) elif isinstance(stmt, ast.While): w, h = self.while_block(x, y + height, stmt) elif isinstance(stmt, ast.For): w, h = self.for_block(x, y + height, stmt) else: w, h = (0, 0) height += h width = max(width, w) self.baseline(x, y, height) return (width, height) def process(self, x, y, text): textbox = box(x, y) self.rectangle(textbox, outline='black', fill='white') self.textarea(textbox, text, self.font, fill='black') return (1, 1) def baseline(self, x, y, height): start = box(x, y).shift(y=-SPAN_HEIGHT / 3) end = box(x, y + height - 1).shift(y=SPAN_HEIGHT / 3) self.line((start.topleft, end.bottomleft), fill='black') def link(self, x, py): start = XY(box(x, 0).right.x, py) end = XY(box(x + 1, 0).left.x, py) self.line((start, end), fill='black')
def __init__(self, *args, **kwargs): super(PADImageDraw, self).__init__(*args, **kwargs) self.fontmap = FontMap() self.fontmap.set_default_font('/Library/Fonts/Hiragino Sans GB W3.otf') self.font = self.fontmap.find()
class DiagramMetrics(object): cellsize = cellsize edge_layout = 'normal' node_padding = 4 line_spacing = 2 shadow_offset = XY(3, 6) page_margin = XY(0, 0) page_padding = [0, 0, 0, 0] node_width = cellsize * 16 node_height = cellsize * 5 span_width = cellsize * 8 span_height = cellsize * 5 def __init__(self, diagram, drawer=None, fontmap=None): self.drawer = drawer if diagram.node_width is not None: self.node_width = diagram.node_width if diagram.node_height is not None: self.node_height = diagram.node_height if diagram.span_width is not None: self.span_width = diagram.span_width if diagram.span_height is not None: self.span_height = diagram.span_height if fontmap is not None: self.fontmap = fontmap else: self.fontmap = FontMap() if diagram.page_padding is not None: self.page_padding = diagram.page_padding if diagram.edge_layout is not None: self.edge_layout = diagram.edge_layout # setup spreadsheet sheet = self.spreadsheet = SpreadSheetMetrics(self) nodes = [n for n in diagram.traverse_nodes() if n.drawable] node_width = self.node_width for x in range(diagram.colwidth): widths = [n.width for n in nodes if n.xy.x == x] if widths: width = max(n or node_width for n in widths) sheet.set_node_width(x, width) node_height = self.node_height for y in range(diagram.colheight): heights = [n.height for n in nodes if n.xy.y == y] if heights: height = max(n or node_height for n in heights) sheet.set_node_height(y, height) @property def original_metrics(self): return self def shift(self, x, y): metrics = copy.copy(self) metrics.spreadsheet = copy.copy(self.spreadsheet) metrics.spreadsheet.metrics = metrics metrics.page_margin = XY(x, y) return metrics def textsize(self, string, font=None, width=65535): return self.drawer.textsize(string, font, maxwidth=width) def node(self, node): renderer = noderenderer.get(node.shape) if hasattr(renderer, 'render'): return renderer(node, self) else: return self.cell(node) def cell(self, node, use_padding=True): return self.spreadsheet.node(node, use_padding) def group(self, group): return self.spreadsheet.node(group, use_padding=False) def edge(self, edge): if self.edge_layout == 'flowchart': if edge.node1.group.orientation == 'landscape': return FlowchartLandscapeEdgeMetrics(edge, self) else: return FlowchartPortraitEdgeMetrics(edge, self) else: if edge.node1.group.orientation == 'landscape': return LandscapeEdgeMetrics(edge, self) else: return PortraitEdgeMetrics(edge, self) def font_for(self, element): return self.fontmap.find(element) def pagesize(self, width, height): return self.spreadsheet.pagesize(width, height)
class DiagramMetrics(object): cellsize = cellsize edge_layout = 'normal' node_padding = 4 line_spacing = 2 shadow_offset = XY(3, 6) page_margin = XY(0, 0) page_padding = [0, 0, 0, 0] node_width = cellsize * 16 node_height = cellsize * 5 span_width = cellsize * 8 span_height = cellsize * 5 def __init__(self, diagram, drawer=None, fontmap=None): self.drawer = drawer if diagram.node_width is not None: self.node_width = diagram.node_width if diagram.node_height is not None: self.node_height = diagram.node_height if diagram.span_width is not None: self.span_width = diagram.span_width if diagram.span_height is not None: self.span_height = diagram.span_height if fontmap is not None: self.fontmap = fontmap else: self.fontmap = FontMap() if diagram.page_padding is not None: self.page_padding = diagram.page_padding if diagram.edge_layout is not None: self.edge_layout = diagram.edge_layout # setup spreadsheet sheet = self.spreadsheet = SpreadSheetMetrics(self) nodes = [n for n in diagram.traverse_nodes() if n.drawable] node_width = self.node_width for x in range(diagram.colwidth): widths = [n.width for n in nodes if n.xy.x == x] if widths: width = max(n or node_width for n in widths) sheet.set_node_width(x, width) node_height = self.node_height for y in range(diagram.colheight): heights = [n.height for n in nodes if n.xy.y == y] if heights: height = max(n or node_height for n in heights) sheet.set_node_height(y, height) @property def original_metrics(self): return self def shift(self, x, y): metrics = copy.copy(self) metrics.spreadsheet = copy.copy(self.spreadsheet) metrics.spreadsheet.metrics = metrics metrics.page_margin = XY(x, y) return metrics def textsize(self, string, font=None, width=65535): return self.drawer.textsize(string, font, maxwidth=width) def node(self, node): renderer = noderenderer.get(node.shape) if hasattr(renderer, 'render'): return renderer(node, self) else: return self.cell(node) def cell(self, node, use_padding=True): return self.spreadsheet.node(node, use_padding) def group(self, group): return self.spreadsheet.node(group, use_padding=False) def edge(self, edge): if self.edge_layout == 'flowchart': if edge.node1.group.orientation == 'landscape': return FlowchartLandscapeEdgeMetrics(edge, self) else: return FlowchartPortraitEdgeMetrics(edge, self) else: if edge.node1.group.orientation == 'landscape': return LandscapeEdgeMetrics(edge, self) else: return PortraitEdgeMetrics(edge, self) def font_for(self, element): return self.fontmap.find(element) def pagesize(self, width, height): return self.spreadsheet.pagesize(width, height)
def main(args): print("YASM: Starting...") url_paths = [] root = {} with open(args.file) as json_file: data = json.load(json_file) if args.sdsp: data = rewrite_subdomains_as_slash(data) # Split URL paths into elements along / for item in data: split = item['url'].rstrip("/").split('/') url_paths.append(split[2:]) if args.sdsp: url_paths[-1].append({'title': item['title'], 'url': split[-1], 'subdomain': item['subdomain']}) else: url_paths[-1].append({'title': item['title'], 'url': split[-1]}) # Build tree structure from elements for path in url_paths: # Get element if it exists, set to empty if not branch = root.setdefault(path[0], [{}, []]) for i in path[1:-1]: branch = branch[0].setdefault(i, [{}, []]) branch[1].append(path[-1]) # Delete empty elements delete_empty(root) # Output JSON file (Maybe move to util file) output_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), "output") if not os.path.exists(output_dir): os.makedirs(output_dir) output_file_json = os.path.join(output_dir, os.path.split(args.file)[-1]) with open(output_file_json, 'w') as outfile: json.dump(root, outfile, indent=2, ensure_ascii=False) # To append .gv, .pdf/.png/.svg later output_name = output_file_json[:-len(".json")] if args.depth == 694201337: calc_max_depth = get_max_depth(root) else: calc_max_depth = args.depth # Sitemap via dot or blockdiag if args.engine == "dot": dot = Digraph() dot.graph_attr['rankdir'] = 'TB' dot.graph_attr['splines'] = 'ortho' dot.graph_attr['concentrate'] = 'true' # User formatting options dot.graph_attr['nodesep'] = args.widthpadding dot.graph_attr['ranksep'] = args.heightpadding dot.node_attr['shape'] = 'rect' dot.node_attr['style'] = 'filled' last = create_nodes(root, dot, args.depth, calc_max_depth=calc_max_depth) graphviz_legend(last, dot) # Save to file # GV creates a PDF/SVG and .gv at the same time, need to rename one dot.format = args.type output_file_gv = output_name + ".gv" dot.render(output_name, view=args.instant) os.rename(output_name, output_file_gv) elif args.engine == "blockdiag": dotDiag = Digraph() create_nodes(root, dotDiag, args.depth, blockdiag=True, calc_max_depth=calc_max_depth) source = dotDiag.source source = source.replace("digraph", "blockdiag") # Legend/Key blockdiag_legend = """group { label = "Legend"; color="#808080"; Parent -> Child; } }""" source = source.replace("}", blockdiag_legend) # Colors source = source.replace("subgraph", "group") source = source.replace("fillcolor", ",color") source = source.replace("style=filled", "") # User formatting options source = add_blockdiag_option(source, "orientation", args.orientation) source = add_blockdiag_option(source, "span_width", args.widthpadding) source = add_blockdiag_option(source, "span_height", args.heightpadding) tree = blockdiagParser.parse_string(source) diagram = builder.ScreenNodeBuilder.build(tree) # Font only needed for PDF output # use project specific font file fontname = "DejaVuSans.ttf" fontpath = os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", "util", fontname) fontmap = FontMap() fontmap.set_default_font(fontpath) draw = drawer.DiagramDraw(args.type, diagram, filename=output_name + '.' + args.type, fontmap=fontmap) draw.draw() draw.save() print("YASM: Finished.")