Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add support for captions of images #138

Merged
merged 1 commit into from
Dec 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions capella2polarion/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,12 @@ def print_cli_state(capella2polarion_cli: Capella2PolarionCli) -> None:
is_flag=True,
default=True,
)
@click.option(
"--generate-figure-captions",
envvar="CAPELLA2POLARION_GENERATE_FIGURE_CAPTIONS",
is_flag=True,
default=False,
)
@click.pass_context
def synchronize(
ctx: click.core.Context,
Expand All @@ -123,6 +129,7 @@ def synchronize(
type_prefix: str,
role_prefix: str,
grouped_links_custom_fields: bool,
generate_figure_captions: bool,
) -> None:
"""Synchronise model elements."""
capella_to_polarion_cli: Capella2PolarionCli = ctx.obj
Expand Down Expand Up @@ -159,6 +166,7 @@ def synchronize(
generate_links=True,
generate_attachments=True,
generate_grouped_links_custom_fields=grouped_links_custom_fields,
generate_figure_captions=generate_figure_captions,
)

polarion_worker.compare_and_update_work_items(converter.converter_session)
Expand Down
37 changes: 34 additions & 3 deletions capella2polarion/converters/element_converter.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
from capellambse import helpers as chelpers
from capellambse import model as m
from capellambse_context_diagrams import context
from lxml import etree
from lxml import etree, html

from capella2polarion import data_model
from capella2polarion.connectors import polarion_repo
Expand Down Expand Up @@ -69,11 +69,13 @@ def __init__(
capella_polarion_mapping: polarion_repo.PolarionDataRepository,
converter_session: data_session.ConverterSession,
generate_attachments: bool,
generate_figure_captions: bool = False,
):
self.model = model
self.capella_polarion_mapping = capella_polarion_mapping
self.converter_session = converter_session
self.generate_attachments = generate_attachments
self.generate_figure_captions = generate_figure_captions
self.jinja_envs: dict[str, jinja2.Environment] = {}

def serialize_all(self) -> list[data_model.CapellaWorkItem]:
Expand Down Expand Up @@ -144,6 +146,7 @@ def _draw_diagram_svg(
max_width: int,
cls: str,
render_params: dict[str, t.Any] | None = None,
caption: tuple[str, str] | None = None,
) -> tuple[str, data_model.CapellaDiagramAttachment | None]:
file_name = f"{C2P_IMAGE_PREFIX}{file_name}.svg"

Expand All @@ -161,7 +164,7 @@ def _draw_diagram_svg(

return (
polarion_html_helper.generate_image_html(
title, file_name, max_width, cls
title, file_name, max_width, cls, caption
),
attachment,
)
Expand Down Expand Up @@ -201,6 +204,7 @@ def __insert_diagram(
file_name: str,
render_params: dict[str, t.Any] | None = None,
max_width: int = 800,
caption: tuple[str, str] | None = None,
):
if attachment := next(
(
Expand All @@ -216,6 +220,7 @@ def __insert_diagram(
attachment.file_name,
max_width,
JINJA_RENDERED_IMG_CLS,
caption,
)

diagram_html, attachment = self._draw_diagram_svg(
Expand Down Expand Up @@ -246,6 +251,11 @@ def _draw_additional_attributes_diagram(
650,
"additional-attributes-diagram",
render_params,
(
("Figure", f"{title} of {work_item.title}")
if self.generate_figure_captions
else None
),
)
if attachment:
self._add_attachment(work_item, attachment)
Expand Down Expand Up @@ -325,6 +335,17 @@ def repair_images(node: etree._Element) -> None:
# We use the filename here as the ID is unknown here
# This needs to be refactored after updating attachments
node.attrib["src"] = f"workitemimg:{file_name}"
if self.generate_figure_captions:
caption = node.get(
"alt", f'Image "{file_url.stem}" of {obj.name}'
)
node.addnext(
html.fromstring(
polarion_html_helper.POLARION_CAPTION.format(
label="Figure", caption=caption
)
)
)

except FileNotFoundError:
self.converter_session[obj.uuid].errors.add(
Expand Down Expand Up @@ -432,7 +453,17 @@ def _diagram(
work_item_id = converter_data.work_item.id

diagram_html, attachment = self._draw_diagram_svg(
diagram, "diagram", "Diagram", 750, "diagram", render_params
diagram,
"diagram",
"Diagram",
750,
"diagram",
render_params,
(
("Figure", f"Diagram {diagram.name}")
if self.generate_figure_captions
else None
),
)

converter_data.work_item = data_model.CapellaWorkItem(
Expand Down
4 changes: 4 additions & 0 deletions capella2polarion/converters/model_converter.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ def generate_work_items(
generate_links: bool = False,
generate_attachments: bool = False,
generate_grouped_links_custom_fields: bool = False,
generate_figure_captions: bool = False,
) -> dict[str, data_model.CapellaWorkItem]:
"""Return a work items mapping from model elements for Polarion.

Expand All @@ -104,12 +105,15 @@ def generate_work_items(
generate_grouped_links_custom_fields
A boolean flag to control grouped links custom fields
generation.
generate_figure_captions
A boolean flag to enable the generation of figure captions
"""
serializer = element_converter.CapellaWorkItemSerializer(
self.model,
polarion_data_repo,
self.converter_session,
generate_attachments,
generate_figure_captions,
)
work_items = serializer.serialize_all()
for work_item in work_items:
Expand Down
15 changes: 14 additions & 1 deletion capella2polarion/converters/polarion_html_helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@
"params=id={pid}|layout={lid}|{custom_info}external=true"
'|project={project}"></div>'
)
POLARION_CAPTION = (
'<p class="polarion-rte-caption-paragraph">\n '
'{label} <span data-sequence="{label}" '
'class="polarion-rte-caption">#</span> {caption}\n</p>'
)
RE_DESCR_DELETED_PATTERN = re.compile(
f"&lt;deleted element ({chelpers.RE_VALID_UUID.pattern})&gt;"
)
Expand All @@ -52,14 +57,22 @@ def strike_through(string: str) -> str:


def generate_image_html(
title: str, attachment_id: str, max_width: int, cls: str
title: str,
attachment_id: str,
max_width: int,
cls: str,
caption: tuple[str, str] | None = None,
) -> str:
"""Generate an image as HTMl with the given source."""
description = (
f'<span><img title="{title}" class="{cls}" '
f'src="workitemimg:{attachment_id}" '
f'style="max-width: {max_width}px;"/></span>'
)
if caption:
description += POLARION_CAPTION.format(
label=caption[0], caption=caption[1]
)
return description


Expand Down
6 changes: 3 additions & 3 deletions tests/data/model/Melody Model Test.afm
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<metadata:Metadata xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:metadata="http://www.polarsys.org/kitalpha/ad/metadata/1.0.0" id="_-kIvQKDzEeqf7Mw7EIo_Ew">
<viewpointReferences id="_-lINwKDzEeqf7Mw7EIo_Ew" vpId="org.polarsys.capella.core.viewpoint" version="5.2.0"/>
<viewpointReferences id="_4DaT8PHWEeq9N-vcO9FSUw" vpId="org.polarsys.kitalpha.vp.requirements" version="0.12.2"/>
<viewpointReferences id="_4FtaAPHWEeq9N-vcO9FSUw" vpId="org.polarsys.capella.vp.requirements" version="0.12.2"/>
<viewpointReferences id="_-lINwKDzEeqf7Mw7EIo_Ew" vpId="org.polarsys.capella.core.viewpoint" version="7.0.0"/>
<viewpointReferences id="_4DaT8PHWEeq9N-vcO9FSUw" vpId="org.polarsys.kitalpha.vp.requirements" version="0.14.0"/>
<viewpointReferences id="_4FtaAPHWEeq9N-vcO9FSUw" vpId="org.polarsys.capella.vp.requirements" version="0.14.0"/>
</metadata:Metadata>
Loading
Loading