#756 Adding alt text feature

This commit is contained in:
Dolan
2022-10-26 23:09:36 +01:00
parent ccf66dbd50
commit 522b21862b
13 changed files with 359 additions and 45 deletions

View File

@ -1,4 +1,8 @@
import { assert } from "chai";
import { assert, expect } from "chai";
import { SinonStub, stub } from "sinon";
import { Formatter } from "@export/formatter";
import * as convenienceFunctions from "@util/convenience-functions";
import { Utility } from "tests/utility";
@ -36,6 +40,14 @@ const createAnchor = (drawingOptions: IDrawingOptions): Anchor =>
);
describe("Anchor", () => {
before(() => {
stub(convenienceFunctions, "uniqueNumericId").callsFake(() => 0);
});
after(() => {
(convenienceFunctions.uniqueNumericId as SinonStub).restore();
});
let anchor: Anchor;
describe("#constructor()", () => {
@ -362,5 +374,236 @@ describe("Anchor", () => {
relativeHeight: 120,
});
});
it("should create a Drawing with doc properties", () => {
anchor = createAnchor({
floating: {
verticalPosition: {
offset: 0,
},
horizontalPosition: {
offset: 0,
},
zIndex: 120,
},
docProperties: {
name: "test",
description: "test",
title: "test",
},
});
const tree = new Formatter().format(anchor);
expect(tree).to.deep.equal({
"wp:anchor": [
{
_attr: {
allowOverlap: "1",
behindDoc: "0",
distB: 0,
distL: 0,
distR: 0,
distT: 0,
layoutInCell: "1",
locked: "0",
relativeHeight: 120,
simplePos: "0",
},
},
{
"wp:simplePos": {
_attr: {
x: 0,
y: 0,
},
},
},
{
"wp:positionH": [
{
_attr: {
relativeFrom: "page",
},
},
{
"wp:posOffset": ["0"],
},
],
},
{
"wp:positionV": [
{
_attr: {
relativeFrom: "page",
},
},
{
"wp:posOffset": ["0"],
},
],
},
{
"wp:extent": {
_attr: {
cx: 952500,
cy: 952500,
},
},
},
{
"wp:effectExtent": {
_attr: {
b: 0,
l: 0,
r: 0,
t: 0,
},
},
},
{
"wp:wrapNone": {},
},
{
"wp:docPr": {
_attr: {
descr: "test",
id: 0,
name: "test",
title: "test",
},
},
},
{
"wp:cNvGraphicFramePr": [
{
"a:graphicFrameLocks": {
_attr: {
noChangeAspect: 1,
"xmlns:a": "http://schemas.openxmlformats.org/drawingml/2006/main",
},
},
},
],
},
{
"a:graphic": [
{
_attr: {
"xmlns:a": "http://schemas.openxmlformats.org/drawingml/2006/main",
},
},
{
"a:graphicData": [
{
_attr: {
uri: "http://schemas.openxmlformats.org/drawingml/2006/picture",
},
},
{
"pic:pic": [
{
_attr: {
"xmlns:pic": "http://schemas.openxmlformats.org/drawingml/2006/picture",
},
},
{
"pic:nvPicPr": [
{
"pic:cNvPr": {
_attr: {
descr: "",
id: 0,
name: "",
},
},
},
{
"pic:cNvPicPr": [
{
"a:picLocks": {
_attr: {
noChangeArrowheads: 1,
noChangeAspect: 1,
},
},
},
],
},
],
},
{
"pic:blipFill": [
{
"a:blip": {
_attr: {
cstate: "none",
"r:embed": "rId{test.png}",
},
},
},
{
"a:srcRect": {},
},
{
"a:stretch": [
{
"a:fillRect": {},
},
],
},
],
},
{
"pic:spPr": [
{
_attr: {
bwMode: "auto",
},
},
{
"a:xfrm": [
{
_attr: {},
},
{
"a:off": {
_attr: {
x: 0,
y: 0,
},
},
},
{
"a:ext": {
_attr: {
cx: 952500,
cy: 952500,
},
},
},
],
},
{
"a:prstGeom": [
{
_attr: {
prst: "rect",
},
},
{
"a:avLst": {},
},
],
},
],
},
],
},
],
},
],
},
],
});
});
});
});

View File

@ -90,7 +90,7 @@ export class Anchor extends XmlComponent {
this.root.push(new WrapNone());
}
this.root.push(new DocProperties());
this.root.push(new DocProperties(drawingOptions.docProperties));
this.root.push(new GraphicFrameProperties());
this.root.push(new Graphic(mediaData, transform));
}

View File

@ -1,13 +0,0 @@
import { XmlAttributeComponent } from "@file/xml-components";
export class DocPropertiesAttributes extends XmlAttributeComponent<{
readonly id?: number;
readonly name?: string;
readonly descr?: string;
}> {
protected readonly xmlKeys = {
id: "id",
name: "name",
descr: "descr",
};
}

View File

@ -1,15 +1,36 @@
import { XmlComponent } from "@file/xml-components";
import { DocPropertiesAttributes } from "./doc-properties-attributes";
import { XmlAttributeComponent, XmlComponent } from "@file/xml-components";
import { uniqueNumericId } from "@util/convenience-functions";
class DocPropertiesAttributes extends XmlAttributeComponent<{
readonly id?: number;
readonly name?: string;
readonly description?: string;
readonly title?: string;
}> {
protected readonly xmlKeys = {
id: "id",
name: "name",
description: "descr",
title: "title",
};
}
export interface DocPropertiesOptions {
readonly name: string;
readonly description: string;
readonly title: string;
}
export class DocProperties extends XmlComponent {
public constructor() {
public constructor({ name, description, title }: DocPropertiesOptions = { name: "", description: "", title: "" }) {
super("wp:docPr");
this.root.push(
new DocPropertiesAttributes({
id: 0,
name: "",
descr: "",
id: uniqueNumericId(),
name,
description,
title,
}),
);
}

View File

@ -1,6 +1,8 @@
import { expect } from "chai";
import { SinonStub, stub } from "sinon";
import { Formatter } from "@export/formatter";
import * as convenienceFunctions from "@util/convenience-functions";
import { Drawing, IDrawingOptions } from "./drawing";
@ -26,6 +28,14 @@ const createDrawing = (drawingOptions?: IDrawingOptions): Drawing =>
);
describe("Drawing", () => {
before(() => {
stub(convenienceFunctions, "uniqueNumericId").callsFake(() => 0);
});
after(() => {
(convenienceFunctions.uniqueNumericId as SinonStub).restore();
});
let currentBreak: Drawing;
describe("#constructor()", () => {
@ -68,6 +78,7 @@ describe("Drawing", () => {
descr: "",
id: 0,
name: "",
title: "",
},
},
},
@ -298,6 +309,7 @@ describe("Drawing", () => {
descr: "",
id: 0,
name: "",
title: "",
},
},
},

View File

@ -1,6 +1,8 @@
import { IMediaData } from "@file/media";
import { XmlComponent } from "@file/xml-components";
import { Anchor } from "./anchor";
import { DocPropertiesOptions } from "./doc-properties/doc-properties";
import { IFloating } from "./floating";
import { Inline } from "./inline";
@ -13,6 +15,7 @@ export interface IDistance {
export interface IDrawingOptions {
readonly floating?: IFloating;
readonly docProperties?: DocPropertiesOptions;
}
// <xsd:complexType name="CT_Drawing">
@ -29,7 +32,11 @@ export class Drawing extends XmlComponent {
super("w:drawing");
if (!drawingOptions.floating) {
this.inline = new Inline(imageData, imageData.transformation);
this.inline = new Inline({
mediaData: imageData,
transform: imageData.transformation,
docProperties: drawingOptions.docProperties,
});
this.root.push(this.inline);
} else {
this.root.push(new Anchor(imageData, imageData.transformation, drawingOptions));

View File

@ -1,13 +1,19 @@
// http://officeopenxml.com/drwPicInline.php
import { IMediaData, IMediaDataTransformation } from "@file/media";
import { XmlComponent } from "@file/xml-components";
import { DocProperties } from "./../doc-properties/doc-properties";
import { DocProperties, DocPropertiesOptions } from "./../doc-properties/doc-properties";
import { EffectExtent } from "./../effect-extent/effect-extent";
import { Extent } from "./../extent/extent";
import { GraphicFrameProperties } from "./../graphic-frame/graphic-frame-properties";
import { Graphic } from "./../inline/graphic";
import { InlineAttributes } from "./inline-attributes";
interface InlineOptions {
readonly mediaData: IMediaData;
readonly transform: IMediaDataTransformation;
readonly docProperties?: DocPropertiesOptions;
}
// <xsd:complexType name="CT_Inline">
// <xsd:sequence>
// <xsd:element name="extent" type="a:CT_PositiveSize2D"/>
@ -26,7 +32,7 @@ export class Inline extends XmlComponent {
private readonly extent: Extent;
private readonly graphic: Graphic;
public constructor(mediaData: IMediaData, transform: IMediaDataTransformation) {
public constructor({ mediaData, transform, docProperties }: InlineOptions) {
super("wp:inline");
this.root.push(
@ -43,7 +49,7 @@ export class Inline extends XmlComponent {
this.root.push(this.extent);
this.root.push(new EffectExtent());
this.root.push(new DocProperties());
this.root.push(new DocProperties(docProperties));
this.root.push(new GraphicFrameProperties());
this.root.push(this.graphic);
}