mirror of
https://github.com/larksuite/cli.git
synced 2026-08-03 08:32:46 +08:00
feat(slides):lint table out of canvas
This commit is contained in:
@@ -867,11 +867,56 @@ def detect_whiteboard_external_overlaps(
|
||||
return issues
|
||||
|
||||
|
||||
def detect_table_out_of_canvas(
|
||||
elements: list[dict[str, Any]], slide_width: int | float, slide_height: int | float
|
||||
) -> list[dict[str, Any]]:
|
||||
issues: list[dict[str, Any]] = []
|
||||
for table in (element for element in elements if element["kind"] == "table"):
|
||||
overflow = {
|
||||
"left": max(-table["x"], 0),
|
||||
"top": max(-table["y"], 0),
|
||||
"right": max(table["x"] + table["width"] - slide_width, 0),
|
||||
"bottom": max(table["y"] + table["height"] - slide_height, 0),
|
||||
}
|
||||
overflow_details = [
|
||||
f"{side} by {amount:g}px" for side, amount in overflow.items() if amount > 0
|
||||
]
|
||||
if not overflow_details:
|
||||
continue
|
||||
issues.append(
|
||||
{
|
||||
"level": "error",
|
||||
"code": "table_out_of_canvas",
|
||||
"elements": [table["id"]],
|
||||
"canvas": {"width": slide_width, "height": slide_height},
|
||||
"bbox": {
|
||||
"x": table["x"],
|
||||
"y": table["y"],
|
||||
"width": table["width"],
|
||||
"height": table["height"],
|
||||
},
|
||||
"overflow": overflow,
|
||||
"message": (
|
||||
f'table {table["id"]} exceeds the {slide_width:g}x{slide_height:g} canvas '
|
||||
f'({", ".join(overflow_details)})'
|
||||
),
|
||||
"hint": (
|
||||
"Move the table inside the canvas, reduce table.width/table.height, or split the table across "
|
||||
"slides."
|
||||
),
|
||||
}
|
||||
)
|
||||
return issues
|
||||
|
||||
|
||||
def lint_slide(
|
||||
slide_xml: str, slide_number: int, slide_width: int | float = 960, slide_height: int | float = 540
|
||||
) -> dict[str, Any]:
|
||||
elements = extract_elements(slide_xml)
|
||||
issues: list[dict[str, Any]] = detect_whiteboard_external_overlaps(elements, slide_width, slide_height)
|
||||
issues: list[dict[str, Any]] = [
|
||||
*detect_whiteboard_external_overlaps(elements, slide_width, slide_height),
|
||||
*detect_table_out_of_canvas(elements, slide_width, slide_height),
|
||||
]
|
||||
|
||||
for index, left in enumerate(elements):
|
||||
for right in elements[index + 1 :]:
|
||||
|
||||
@@ -712,6 +712,63 @@ class XmlTextOverlapLintTest(unittest.TestCase):
|
||||
)
|
||||
self.assertEqual(result["summary"]["error_count"], 0)
|
||||
|
||||
def test_lint_xml_reports_table_bottom_overflow_from_declared_bounds(self) -> None:
|
||||
result = xml_text_overlap_lint.lint_xml(
|
||||
"""
|
||||
<presentation xmlns="http://www.larkoffice.com/sml/2.0" width="960" height="540">
|
||||
<slide xmlns="http://www.larkoffice.com/sml/2.0">
|
||||
<data>
|
||||
<table id="score-table" topLeftX="54" topLeftY="238" width="414" height="385">
|
||||
<tr><td><content><p>Score</p></content></td></tr>
|
||||
</table>
|
||||
</data>
|
||||
</slide>
|
||||
</presentation>
|
||||
"""
|
||||
)
|
||||
issue = result["slides"][0]["issues"][0]
|
||||
self.assertEqual(result["summary"]["error_count"], 1)
|
||||
self.assertEqual(issue["code"], "table_out_of_canvas")
|
||||
self.assertEqual(issue["elements"], ["score-table"])
|
||||
self.assertEqual(issue["overflow"], {"left": 0, "top": 0, "right": 0, "bottom": 83})
|
||||
self.assertEqual(issue["bbox"], {"x": 54, "y": 238, "width": 414, "height": 385})
|
||||
|
||||
def test_lint_xml_reports_table_right_overflow_from_declared_bounds(self) -> None:
|
||||
result = xml_text_overlap_lint.lint_xml(
|
||||
"""
|
||||
<presentation xmlns="http://www.larkoffice.com/sml/2.0" width="960" height="540">
|
||||
<slide xmlns="http://www.larkoffice.com/sml/2.0">
|
||||
<data>
|
||||
<table id="wide-table" topLeftX="850" topLeftY="80" width="180" height="120">
|
||||
<tr><td><content><p>Score</p></content></td></tr>
|
||||
</table>
|
||||
</data>
|
||||
</slide>
|
||||
</presentation>
|
||||
"""
|
||||
)
|
||||
issue = result["slides"][0]["issues"][0]
|
||||
self.assertEqual(result["summary"]["error_count"], 1)
|
||||
self.assertEqual(issue["code"], "table_out_of_canvas")
|
||||
self.assertEqual(issue["overflow"], {"left": 0, "top": 0, "right": 70, "bottom": 0})
|
||||
|
||||
def test_lint_xml_allows_table_with_declared_bounds_inside_canvas(self) -> None:
|
||||
result = xml_text_overlap_lint.lint_xml(
|
||||
"""
|
||||
<presentation xmlns="http://www.larkoffice.com/sml/2.0" width="960" height="540">
|
||||
<slide xmlns="http://www.larkoffice.com/sml/2.0">
|
||||
<data>
|
||||
<table id="inside-table" topLeftX="40" topLeftY="120" width="880" height="360">
|
||||
<tr><td><content><p>Score</p></content></td></tr>
|
||||
</table>
|
||||
</data>
|
||||
</slide>
|
||||
</presentation>
|
||||
"""
|
||||
)
|
||||
self.assertEqual(result["summary"]["error_count"], 0)
|
||||
self.assertEqual(result["summary"]["warning_count"], 0)
|
||||
|
||||
def test_lint_xml_warns_for_whiteboard_external_boundary_overlap(self) -> None:
|
||||
result = xml_text_overlap_lint.lint_xml(
|
||||
"""
|
||||
|
||||
Reference in New Issue
Block a user