Preserve QPowerPoint image hyperlinks in PPTX
This commit is contained in:
@@ -74,7 +74,7 @@ export async function importPptxFile(file: File): Promise<ImportedPowerPointDeck
|
||||
const slideRelationshipsXml = await readOptionalParsedXml(zip, parser, relationshipsPath);
|
||||
const hyperlinkTargets = relationshipTargetsById(slideRelationshipsXml, hyperlinkRelationshipType, path);
|
||||
const slideTextBlocks = mergeOrderedSlideTextBlocks(extractSlideTextBlocks(parsedSlide, hyperlinkTargets), extractOrderedTextBodyTexts(orderedSlide));
|
||||
const images = await extractSlideImages(zip, parser, parsedSlide, path, index);
|
||||
const images = await extractSlideImages(zip, parser, parsedSlide, path, index, slideRelationshipsXml);
|
||||
const notesPath = await slideNotesPath(zip, parser, path);
|
||||
const notesXml = notesPath ? await readOptionalZipText(zip, notesPath) : await readOptionalZipText(zip, `ppt/notesSlides/notesSlide${index}.xml`);
|
||||
const notes = notesXml
|
||||
@@ -157,13 +157,15 @@ export async function exportPptxBlob(deck: ExportablePowerPointDeck): Promise<Bl
|
||||
return;
|
||||
}
|
||||
|
||||
const imageHyperlink = normalizedExternalHyperlinkTarget(image.hyperlink);
|
||||
slide.addImage({
|
||||
data,
|
||||
x: image.x,
|
||||
y: image.y,
|
||||
w: image.width,
|
||||
h: image.height,
|
||||
altText: image.alt || `Изображение ${index + 1}`
|
||||
altText: image.alt || `Изображение ${index + 1}`,
|
||||
...(imageHyperlink ? { hyperlink: { url: imageHyperlink } } : {})
|
||||
});
|
||||
});
|
||||
slide.addText(sourceSlide.title || "Без заголовка", {
|
||||
@@ -426,14 +428,16 @@ async function extractSlideImages(
|
||||
parser: { parse: (xml: string) => unknown },
|
||||
slideXml: unknown,
|
||||
slidePath: string,
|
||||
slideIndex: number
|
||||
slideIndex: number,
|
||||
relationshipsXml?: unknown
|
||||
): Promise<SlideImage[]> {
|
||||
const relationshipsPath = `${partDirectory(slidePath)}/_rels/${partFileName(slidePath)}.rels`;
|
||||
const relationshipsXml = await readOptionalParsedXml(zip, parser, relationshipsPath);
|
||||
const imageTargets = relationshipTargetsById(relationshipsXml, imageRelationshipType, slidePath);
|
||||
const parsedRelationshipsXml = relationshipsXml ?? (await readOptionalParsedXml(zip, parser, relationshipsPath));
|
||||
const imageTargets = relationshipTargetsById(parsedRelationshipsXml, imageRelationshipType, slidePath);
|
||||
const hyperlinkTargets = relationshipTargetsById(parsedRelationshipsXml, hyperlinkRelationshipType, slidePath);
|
||||
const pictures = recordsByKey(slideXml, "pic");
|
||||
const images = await Promise.all(
|
||||
pictures.map(async (picture, imageIndex) => slideImageFromPicture(zip, picture, imageTargets, slideIndex, imageIndex))
|
||||
pictures.map(async (picture, imageIndex) => slideImageFromPicture(zip, picture, imageTargets, hyperlinkTargets, slideIndex, imageIndex))
|
||||
);
|
||||
|
||||
return images.filter((image): image is SlideImage => Boolean(image));
|
||||
@@ -443,6 +447,7 @@ async function slideImageFromPicture(
|
||||
zip: ZipArchive,
|
||||
picture: Record<string, unknown>,
|
||||
imageTargets: Record<string, string>,
|
||||
hyperlinkTargets: Record<string, string>,
|
||||
slideIndex: number,
|
||||
imageIndex: number
|
||||
): Promise<SlideImage | null> {
|
||||
@@ -453,14 +458,27 @@ async function slideImageFromPicture(
|
||||
return null;
|
||||
}
|
||||
|
||||
const hyperlink = pictureHyperlink(picture, hyperlinkTargets);
|
||||
return {
|
||||
id: `pptx-slide-${slideIndex}-image-${imageIndex + 1}`,
|
||||
src,
|
||||
alt: pictureAltText(picture) || `Изображение ${imageIndex + 1}`,
|
||||
...(hyperlink ? { hyperlink } : {}),
|
||||
...pictureBounds(picture)
|
||||
};
|
||||
}
|
||||
|
||||
function pictureHyperlink(picture: Record<string, unknown>, hyperlinkTargets: Record<string, string>) {
|
||||
return (
|
||||
recordsByKey(picture, "hlinkClick")
|
||||
.map((record) => {
|
||||
const id = relationshipId(record);
|
||||
return id ? normalizedExternalHyperlinkTarget(hyperlinkTargets[id]) : "";
|
||||
})
|
||||
.find(Boolean) ?? ""
|
||||
);
|
||||
}
|
||||
|
||||
function pictureRelationshipId(picture: Record<string, unknown>) {
|
||||
const blip = firstRecordByKey(picture, "blip");
|
||||
return stringValue(
|
||||
|
||||
Reference in New Issue
Block a user