Skip to content

Commit d413ca1

Browse files
committed
refactor: separate append from modify
1 parent c1fc962 commit d413ca1

File tree

15 files changed

+441
-185
lines changed

15 files changed

+441
-185
lines changed
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import Automizer from "../src/automizer"
2+
import { setChartData, setSolidFill, setText } from "../src/helper/modify"
3+
4+
test("create presentation, add slide with charts from template and modify existing chart.", async () => {
5+
const automizer = new Automizer({
6+
templateDir: `${__dirname}/pptx-templates`,
7+
outputDir: `${__dirname}/pptx-output`
8+
})
9+
10+
let pres = automizer
11+
.loadRoot(`RootTemplate.pptx`)
12+
.load(`SlideWithCharts.pptx`, 'charts')
13+
14+
let result = await pres
15+
.addSlide('charts', 2, (slide) => {
16+
slide.modifyElement('ColumnChart', [
17+
setChartData({
18+
series: [
19+
{ label: 'series 1' },
20+
{ label: 'series 2' },
21+
{ label: 'series 3' },
22+
],
23+
categories: [
24+
{ label: 'cat 2-1', values: [ 50, 50, 20 ] },
25+
{ label: 'cat 2-2', values: [ 14, 50, 20 ] },
26+
{ label: 'cat 2-3', values: [ 15, 50, 20 ] },
27+
{ label: 'cat 2-4', values: [ 26, 50, 20 ] }
28+
]
29+
})
30+
])
31+
})
32+
.write(`create-presentation-modify-existing-chart.test.pptx`)
33+
34+
expect(result.charts).toBe(3)
35+
})
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import Automizer from "../src/automizer"
2+
import { setPosition } from "../src/helper/modify"
3+
4+
test("create presentation, add slide with shapes from template and modify existing shape.", async () => {
5+
const automizer = new Automizer({
6+
templateDir: `${__dirname}/pptx-templates`,
7+
outputDir: `${__dirname}/pptx-output`
8+
})
9+
10+
let pres = automizer
11+
.loadRoot(`RootTemplate.pptx`)
12+
.load(`SlideWithShapes.pptx`, 'shapes')
13+
14+
let result = await pres
15+
.addSlide('shapes', 2, (slide) => {
16+
slide.modifyElement('Drum', [setPosition({x: 1000000, h:5000000, w:5000000})])
17+
})
18+
.write(`create-presentation-modify-existing-shape.test.pptx`)
19+
20+
expect(result.slides).toBe(2)
21+
})

package.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,11 @@
1616
"test": "npx jest",
1717
"test-coverage": "npx jest --coverage"
1818
},
19+
"jest": {
20+
"collectCoverageFrom": [
21+
"src/helper/{!(pretty),}.js"
22+
]
23+
},
1924
"files": [
2025
"dist",
2126
"README"

src/automizer.ts

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
11
import {
22
AutomizerParams,
33
AutomizerSummary,
4-
IPresentationProps, PresTemplate, RootPresTemplate,
4+
IPresentationProps, PresTemplate, RootPresTemplate,
55
} from './definitions/app'
66

77
import Template from './template'
88
import Slide from './slide'
99
import FileHelper from './helper/file'
1010

1111
export default class Automizer implements IPresentationProps {
12-
rootTemplate: RootPresTemplate
13-
templates: PresTemplate[]
14-
templateDir: string
15-
outputDir: string
16-
timer: number
12+
rootTemplate: RootPresTemplate
13+
templates: PresTemplate[]
14+
templateDir: string
15+
outputDir: string
16+
timer: number
1717
params: AutomizerParams
1818

1919
/**
@@ -31,21 +31,21 @@ export default class Automizer implements IPresentationProps {
3131
this.timer = Date.now()
3232
}
3333

34-
/**
35-
* Load a pptx file and set it as root template.
36-
* @param {string} location - Filename or path to the template. Will be prefixed with 'templateDir'
37-
* @return {Automizer} Instance of Automizer
38-
*/
34+
/**
35+
* Load a pptx file and set it as root template.
36+
* @param {string} location - Filename or path to the template. Will be prefixed with 'templateDir'
37+
* @return {Automizer} Instance of Automizer
38+
*/
3939
public loadRoot(location: string): this {
4040
return this.loadTemplate(location)
4141
}
4242

43-
/**
44-
* Load a template pptx file.
45-
* @param {string} location - Filename or path to the template. Will be prefixed with 'templateDir'
46-
* @param {string} name - Optional: A short name for the template. If skipped, the template will be named by its location.
47-
* @return {Automizer} Instance of Automizer
48-
*/
43+
/**
44+
* Load a template pptx file.
45+
* @param {string} location - Filename or path to the template. Will be prefixed with 'templateDir'
46+
* @param {string} name - Optional: A short name for the template. If skipped, the template will be named by its location.
47+
* @return {Automizer} Instance of Automizer
48+
*/
4949
public load(location: string, name?: string): this {
5050
name = (name === undefined) ? location : name
5151
return this.loadTemplate(location, name)
@@ -69,12 +69,12 @@ export default class Automizer implements IPresentationProps {
6969
return 'name' in template;
7070
}
7171

72-
/**
73-
* Find imported template by given name and return a certain slide by number.
74-
* @param {string} name - Name of template; must be imported by Automizer.importTemplate()
75-
* @param {number} slideNumber - Number of slide in template presentation
76-
* @return {Automizer} Instance of Automizer
77-
*/
72+
/**
73+
* Find imported template by given name and return a certain slide by number.
74+
* @param {string} name - Name of template; must be imported by Automizer.importTemplate()
75+
* @param {number} slideNumber - Number of slide in template presentation
76+
* @return {Automizer} Instance of Automizer
77+
*/
7878
public addSlide(name: string, slideNumber: number, callback?: Function): this {
7979
if(this.rootTemplate === undefined) {
8080
throw new Error('You have to set a root template first.')
@@ -98,13 +98,13 @@ export default class Automizer implements IPresentationProps {
9898
return this
9999
}
100100

101-
public template(name: string): PresTemplate {
102-
let template = this.templates.find(template => template.name === name)
101+
public template(name: string): PresTemplate {
102+
let template = this.templates.find(template => template.name === name)
103103
if(template === undefined) {
104104
throw new Error(`Template not found: ${name}`)
105105
}
106106
return template
107-
}
107+
}
108108

109109
public getLocation(location: string, type?: string): string {
110110
switch(type) {

src/definitions/app.ts

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -83,13 +83,23 @@ export type Target = {
8383
rId?: string
8484
}
8585

86+
export type ImportElement = {
87+
presName: string
88+
slideNumber: number
89+
selector: string
90+
mode:string
91+
callback?: Function | Function[]
92+
}
93+
8694
export type ImportedElement = {
95+
mode: string
96+
name?: string
8797
sourceArchive: JSZip
8898
sourceSlideNumber: number
89-
target?: Target
90-
type?: ElementType
9199
callback?: any
92-
element?: HTMLElement
100+
target?: AnalyzedElementType["target"]
101+
type?: AnalyzedElementType["type"]
102+
sourceElement?: AnalyzedElementType["element"]
93103
}
94104

95105
export type AnalyzedElementType = {

src/definitions/enums.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11

22
export enum ElementType {
3-
Chart,
4-
Image,
5-
Shape
3+
Chart = "Chart",
4+
Image = "Image",
5+
Shape = "Generic"
66
}
77

88
export enum ImageTypeMap {

src/dev.ts

Lines changed: 5 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import Automizer from "./index"
22
import Slide from "./slide"
3-
import { setChartData, setPosition } from "./helper/modify"
3+
import { dump, setPosition } from "./helper/modify"
44

55
const automizer = new Automizer({
66
templateDir: `${__dirname}/../__tests__/pptx-templates`,
@@ -12,48 +12,12 @@ let pres = automizer.loadRoot(`RootTemplate.pptx`)
1212
.load(`SlideWithLink.pptx`, 'link')
1313
.load(`SlideWithCharts.pptx`, 'charts')
1414
.load(`EmptySlide.pptx`, 'empty')
15+
.load(`SlideWithShapes.pptx`, 'shapes')
1516

1617
pres
17-
// .addSlide('images', 2)
18-
.addSlide('empty', 1, (slide: Slide) => {
19-
slide.addElement('charts', 2, 'PieChart', [
20-
setChartData({
21-
series: [
22-
{ label: 'فارسی 1' },
23-
],
24-
categories: [
25-
{ label: 'নাগরিক', values: [ 12.5 ] },
26-
{ label: 'cat 2', values: [ 14 ] },
27-
{ label: 'cat 3', values: [ 15 ] },
28-
{ label: 'cat 4', values: [ 26 ] }
29-
]
30-
}),
31-
setPosition({x: 8000000})
32-
])
33-
34-
slide.addElement('charts', 1, 'StackedBars', [
35-
setChartData({
36-
series: [
37-
{ label: 'series 1' },
38-
],
39-
categories: [
40-
{ label: 'cat 2-1', values: [ 50 ] },
41-
{ label: 'cat 2-2', values: [ 14 ] },
42-
{ label: 'cat 2-3', values: [ 15 ] },
43-
{ label: 'cat 2-4', values: [ 26 ] }
44-
]
45-
}),
46-
setPosition({x: 8000000})
47-
])
48-
49-
// slide.addElement('charts', 2, 'PieChart')
50-
// slide.addElement('charts', 2, 'PieChart')
51-
slide.addElement('images', 2, 'imageSVG', setPosition({x: 8000000}))
52-
// slide.addElement('link', 1, 'Link')
53-
// slide.addElement('images', 2, 'imageSVG')
54-
// slide.addElement('images', 2, 'imageSVG')
55-
// slide.addElement('images', 2, 'imageSVG')
56-
// slide.addElement('charts', 1, 'StackedBars')
18+
.addSlide('shapes', 2, (slide: Slide) => {
19+
20+
slide.modifyElement('Drum', [dump, setPosition({x: 1000000, h:5000000, w:5000000})])
5721
})
5822

5923
.write(`myPresentation.pptx`).then(result => {

src/helper/modify.ts

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,37 @@ export const setText = (text: string) => (element) => {
1313
.data = text
1414
}
1515

16-
export const revertElements = (doc: Document) => {
17-
// console.log(doc)
16+
export const revertElements = (slide: Document) => {
17+
// dump(slide)
1818
}
1919

20+
// e.g. setPosition({x: 8000000, h:5000000})
2021
export const setPosition = (pos: any) => (element: HTMLElement) => {
21-
console.log(element.getElementsByTagName('p:cNvPr')[0].getAttribute('name'))
22+
let map = {
23+
x: { tag: 'a:off', attribute: 'x' },
24+
y: { tag: 'a:off', attribute: 'y' },
25+
w: { tag: 'a:ext', attribute: 'cx' },
26+
h: { tag: 'a:ext', attribute: 'cy' },
27+
}
2228

23-
element.getElementsByTagName('a:off')[0].setAttribute('x', pos.x)
29+
let parent = 'a:xfrm'
30+
31+
for(let key in pos) {
32+
element.getElementsByTagName(parent)[0]
33+
.getElementsByTagName(map[key].tag)[0]
34+
.setAttribute(map[key].attribute, pos[key])
35+
}
36+
}
37+
38+
export const setAttribute = (tagName:string, attribute:string, value: string | number, count?: number) => (element: HTMLElement) => {
39+
element.getElementsByTagName(tagName)[count || 0]
40+
.setAttribute(attribute, String(value))
2441
}
2542

2643
export const setChartData = (data: any) => (element: HTMLElement, chart: Document, workbook: Workbook) => {
2744
XmlHelper.setChartData(chart, workbook, data)
45+
}
46+
47+
export const dump = (element: HTMLElement | Document) => {
48+
XmlHelper.dump(element)
2849
}

0 commit comments

Comments
 (0)