Selaa lähdekoodia

Add missing feature of label offsets to Abstract Syntax, parser and generator.

Joeri Exelmans 2 vuotta sitten
vanhempi
commit
66db52afc5

+ 3 - 2
drawio2py/abstract_syntax.py

@@ -34,6 +34,7 @@ class VertexGeometry(Element):
 	y: Optional[Decimal]
 	width: Decimal
 	height: Decimal
+	offset: Optional[Point] # Relative offset of the Vertex' label
 
 @dataclass(eq=False)
 class Vertex(Cell):
@@ -50,8 +51,8 @@ class EdgeGeometry(Element):
 @dataclass(eq=False)
 class Edge(Cell):
 	geometry: EdgeGeometry
-	source: Vertex
-	target: Vertex
+	source: Optional[Vertex]
+	target: Optional[Vertex]
 
 @dataclass(eq=False)
 class Page(Element):

+ 12 - 6
drawio2py/generator.py

@@ -66,15 +66,23 @@ def generate_diagram(page: Page) -> ET.Element:
 		# Create the actual <mxCell>
 		c = ET.SubElement(par, "mxCell", attrs, **cell.attributes)
 
+		def write_point(parent_xml, point: Point, as_str: Optional[str] = None):
+			attrs = {"x": str(point.x), "y": str(point.y)}
+			if as_str != None:
+				attrs['as'] = as_str
+			return ET.SubElement(parent_xml, "mxPoint", attrs)
+
 		# Geometry
 		if isinstance(cell, Vertex):
-			ET.SubElement(c, "mxGeometry", {
+			g = ET.SubElement(c, "mxGeometry", {
 				"x": str(cell.geometry.x),
 				"y": str(cell.geometry.y),
 				"width": str(cell.geometry.width),
 				"height": str(cell.geometry.height),
 				"as": "geometry"
 			})
+			if cell.geometry.offset != None:
+				write_point(g, cell.geometry.offset, "offset")
 		elif isinstance(cell, Edge):
 			g = ET.SubElement(c, "mxGeometry", {
 				"relative": "1",
@@ -83,13 +91,11 @@ def generate_diagram(page: Page) -> ET.Element:
 			if len(cell.geometry.points) > 0:
 				a = ET.SubElement(g, "Array", {"as": "points"})
 				for p in cell.geometry.points:
-					ET.SubElement(a, "mxPoint", {"x": str(p.x), "y": str(p.y)})
+					write_point(a, p)
 			if cell.geometry.source_point is not None:
-				sp = cell.geometry.source_point
-				ET.SubElement(g, "mxPoint", {"x": str(sp.x), "y": str(sp.y), "as": "sourcePoint"})
+				write_point(g, cell.geometry.source_point, "sourcePoint")
 			if cell.geometry.target_point is not None:
-				tp = cell.geometry.target_point
-				ET.SubElement(g, "mxPoint", {"x": str(tp.x), "y": str(tp.y), "as": "targetPoint"})
+				write_point(g, cell.geometry.target_point, "targetPoint")
 
 		for child in cell.children:
 			write_cell(child)

+ 13 - 8
drawio2py/parser.py

@@ -45,23 +45,28 @@ class Parser:
 		array = groot.find(".//Array")
 		if array is not None:
 			for point in array:
-				pts.append(Point(point.attrib["x"], point.attrib["y"]))
+				pts.append(Parser.parse_point(point))
 
 		# Dangling Edges
-		source = groot.find(".//mxPoint[@as='sourcePoint']")
-		if source is not None:
-			source = Point(source.get("x", None), source.get("y", None))
-		target = groot.find(".//mxPoint[@as='targetPoint']")
-		if target is not None:
-			target = Point(target.get("x", None), target.get("y", None))
+		source_xml = groot.find(".//mxPoint[@as='sourcePoint']")
+		target_xml = groot.find(".//mxPoint[@as='targetPoint']")
+		source = None if source_xml == None else Parser.parse_point(source_xml)
+		target = None if target_xml == None else Parser.parse_point(target_xml)
 
 		return EdgeGeometry(pts, source, target)
 
+	@staticmethod
+	def parse_point(xml_node) -> Point:
+		return Point(xml_node.get("x", None), xml_node.get("y", None))
+
 	@staticmethod
 	def parse_cell_geometry(groot):
 		if groot is None: return None
+		offset_xml = groot.find(".//mxPoint[@as='offset']")
+		offset = None if offset_xml == None else Parser.parse_point(offset_xml)
 		return VertexGeometry(groot.get("x", None), groot.attrib.get("y", None),
-		                    groot.attrib["width"], groot.attrib["height"])
+		                    groot.attrib["width"], groot.attrib["height"],
+		                    offset=offset)
 
 	@staticmethod
 	def parse_object(oroot):

+ 1 - 0
test/data/README.txt

@@ -0,0 +1 @@
+The file 'labelOffset.drawio' was added to test a missing feature of the abstract syntax definition, and hence the parser and generator. The missing feature was the 'offset' position of a vertex' label, which was ignored.

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 1 - 0
test/data/labelOffset.drawio


+ 7 - 0
test/run_tests.py

@@ -39,6 +39,7 @@ def parse_shapelib(filename):
     return shapelib.parse_library(os.path.join(DATADIR,filename))
 
 class Tests(unittest.TestCase):
+
     def test_1(self):
         run_test("test.drawio")
 
@@ -48,6 +49,12 @@ class Tests(unittest.TestCase):
     def test_3(self):
         run_test("TrivialPM.drawio")
 
+    def test_label_offset(self):
+        run_test("labelOffset.drawio")
+        # asyntax = parser.Parser.parse(os.path.join(DATADIR, "labelOffset.drawio"))
+        # with open(os.path.join(DATADIR, "labelOffset-1.drawio"), 'wb') as f:
+        #     generator.generate(asyntax, f)
+
     def test_shapelib(self):
         common_lib = parse_shapelib("shapelibs/common.xml")
         pm_lib = parse_shapelib("shapelibs/pm.xml")