abstract-document 16.0.33 → 16.0.34

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/lib/abstract-document/styles/page-style.d.ts +4 -0
  2. package/lib/abstract-document/styles/page-style.d.ts.map +1 -1
  3. package/lib/abstract-document/styles/page-style.js +3 -1
  4. package/lib/abstract-document/styles/page-style.js.map +1 -1
  5. package/lib/abstract-document-exporters/pdf/measure.d.ts.map +1 -1
  6. package/lib/abstract-document-exporters/pdf/measure.js +13 -1
  7. package/lib/abstract-document-exporters/pdf/measure.js.map +1 -1
  8. package/lib/abstract-document-exporters/pdf/paginate.d.ts +6 -0
  9. package/lib/abstract-document-exporters/pdf/paginate.d.ts.map +1 -1
  10. package/lib/abstract-document-exporters/pdf/paginate.js +39 -8
  11. package/lib/abstract-document-exporters/pdf/paginate.js.map +1 -1
  12. package/lib/abstract-document-exporters/pdf/render.js +7 -6
  13. package/lib/abstract-document-exporters/pdf/render.js.map +1 -1
  14. package/lib/abstract-document-xml/abstract-doc-of-xml/abstract-doc-of-xml.js +11 -2
  15. package/lib/abstract-document-xml/abstract-doc-of-xml/abstract-doc-of-xml.js.map +1 -1
  16. package/lib/abstract-document-xml/xsd-template/elements.d.ts +4 -3
  17. package/lib/abstract-document-xml/xsd-template/elements.d.ts.map +1 -1
  18. package/lib/abstract-document-xml/xsd-template/elements.js +20 -15
  19. package/lib/abstract-document-xml/xsd-template/elements.js.map +1 -1
  20. package/lib/abstract-document-xml/xsd-template/styles.d.ts +1 -1
  21. package/lib/abstract-document-xml/xsd-template/styles.d.ts.map +1 -1
  22. package/lib/abstract-document-xml/xsd-template/styles.js +2 -0
  23. package/lib/abstract-document-xml/xsd-template/styles.js.map +1 -1
  24. package/lib/abstract-document-xml/xsd-template/xsd-template.d.ts +2 -2
  25. package/lib/abstract-document-xml/xsd-template/xsd-template.d.ts.map +1 -1
  26. package/lib/abstract-document-xml/xsd-template/xsd-template.js +1 -0
  27. package/lib/abstract-document-xml/xsd-template/xsd-template.js.map +1 -1
  28. package/package.json +2 -2
  29. package/src/abstract-document/styles/page-style.ts +8 -0
  30. package/src/abstract-document-exporters/pdf/measure.ts +15 -3
  31. package/src/abstract-document-exporters/pdf/paginate.ts +48 -13
  32. package/src/abstract-document-exporters/pdf/render.ts +8 -7
  33. package/src/abstract-document-xml/abstract-doc-of-xml/abstract-doc-of-xml.ts +9 -2
  34. package/src/abstract-document-xml/xsd-template/elements.ts +21 -14
  35. package/src/abstract-document-xml/xsd-template/styles.ts +2 -0
  36. package/src/abstract-document-xml/xsd-template/xsd-template.ts +1 -0
@@ -1,6 +1,6 @@
1
1
  import * as AD from "../../abstract-document/index.js";
2
2
  import { exhaustiveCheck } from "ts-exhaustive-check";
3
- import { Page } from "./paginate.js";
3
+ import { getHeaderAndFooter, Page } from "./paginate.js";
4
4
  import { registerFonts, getFontNameStyle } from "./font.js";
5
5
 
6
6
  //tslint:disable:no-any variable-name
@@ -29,7 +29,7 @@ function measureSection(
29
29
  section: AD.Section.Section,
30
30
  separateHeader?: ReadonlyArray<AD.SectionElement.SectionElement>,
31
31
  separateFooter?: ReadonlyArray<AD.SectionElement.SectionElement>,
32
- separateChildren?: ReadonlyArray<AD.SectionElement.SectionElement>
32
+ separateChildren?: ReadonlyArray<AD.SectionElement.SectionElement>,
33
33
  ): Map<any, AD.Size.Size> {
34
34
  const header = separateHeader || section.page.header;
35
35
  const footer = separateFooter || section.page.footer;
@@ -54,7 +54,19 @@ function measureSection(
54
54
  const footerAvailableSize = AD.Size.create(footerAvailableWidth, pageHeight);
55
55
  const footerSizes = footer.map((e) => measureSectionElement(pdfKit, resources, footerAvailableSize, e));
56
56
 
57
- return mergeMaps([...sectionSizes, ...headerSizes, ...footerSizes]);
57
+ // header and footer sizes for the first page
58
+ const firstPageHeaderAndFooters = getHeaderAndFooter(section, 1);
59
+ const firstPageHeaderAndFootersExtracted: ReadonlyArray<[ReadonlyArray<AD.SectionElement.SectionElement>, AD.LayoutFoundation.LayoutFoundation]> = [
60
+ [firstPageHeaderAndFooters.header, firstPageHeaderAndFooters.headerMargins],
61
+ [firstPageHeaderAndFooters.footer, firstPageHeaderAndFooters.footerMargins]
62
+ ];
63
+ const firstPageHeaderAndFooterSizes = firstPageHeaderAndFootersExtracted.reduce((prev, [sections, margins]) => {
64
+ const availabelWidth = pageWidth - (margins.left + margins.right);
65
+ const availableSizes = AD.Size.create(availabelWidth, pageHeight);
66
+ return [...prev, ...sections.map((e) => measureSectionElement(pdfKit, resources, availableSizes, e))];
67
+ }, []);
68
+
69
+ return mergeMaps([...sectionSizes, ...headerSizes, ...footerSizes, ...firstPageHeaderAndFooterSizes]);
58
70
  }
59
71
 
60
72
  function measureSectionElement(
@@ -42,13 +42,13 @@ function splitSection(
42
42
  ): Array<Page> {
43
43
  const resources = AD.Resources.mergeResources([parentResources, section]);
44
44
  const pages = new Array<Page>();
45
- const contentRect = getPageContentRect(desiredSizes, section);
46
45
 
47
46
  let children = section.children;
48
47
  let elements = new Array<AD.SectionElement.SectionElement>();
49
48
  let elementsHeight = 0;
50
49
  let currentPage = previousPage;
51
50
  for (let i = 0; i < children.length; ++i) {
51
+ const contentRect = getPageContentRect(desiredSizes, section, pages.length + 1);
52
52
  const element = children[i];
53
53
  if (element.type === "PageBreak") {
54
54
  currentPage = createPage(resources, desiredSizes, currentPage, section, elements, pages.length === 0);
@@ -218,7 +218,7 @@ function createPage(
218
218
  const namedDestionations = [...sectionName, ...targetNames];
219
219
 
220
220
  // Ignore leading space by expanding the content rect upwards
221
- const rect = getPageContentRect(desiredSizes, section);
221
+ const rect = getPageContentRect(desiredSizes, section, pageNo);
222
222
  const [leadingSpace] = getLeadingAndTrailingSpace(resources, section, elements);
223
223
  const contentRect = AD.Rect.create(rect.x, rect.y - leadingSpace, rect.width, rect.height + leadingSpace);
224
224
 
@@ -236,32 +236,67 @@ function createPage(
236
236
  };
237
237
  }
238
238
 
239
- function getPageContentRect(desiredSizes: Map<{}, AD.Size.Size>, section: AD.Section.Section): AD.Rect.Rect {
239
+ export function getHeaderAndFooter(section: AD.Section.Section, pageNo: number): {
240
+ readonly header: Array<AD.SectionElement.SectionElement>;
241
+ readonly footer: Array<AD.SectionElement.SectionElement>;
242
+ readonly headerMargins: AD.LayoutFoundation.LayoutFoundation;
243
+ readonly footerMargins: AD.LayoutFoundation.LayoutFoundation;
244
+ } {
245
+ const FIRST_PAGE = 1;
246
+ const EVEN_PAGE = 0;
247
+ const ODD_PAGE = 1;
248
+ switch(true) {
249
+ //first page
250
+ case pageNo === FIRST_PAGE: {
251
+ const normalHeader = section.page.frontHeader === undefined || section.page.frontHeader.length === 0;
252
+ const normalFooter = section.page.frontFooter === undefined || section.page.frontFooter.length === 0;
253
+ return {
254
+ footer: normalFooter ? section.page.footer : section.page.frontFooter,
255
+ header: normalHeader ? section.page.header : section.page.frontHeader,
256
+ headerMargins: normalHeader ? section.page.style.headerMargins : (section.page.style.firstPageHeaderMargins ?? section.page.style.headerMargins),
257
+ footerMargins: normalFooter ? section.page.style.footerMargins : (section.page.style.firstPageFooterMargins ?? section.page.style.footerMargins),
258
+ };
259
+ }
260
+ case pageNo === 0:
261
+ case pageNo % 2 === EVEN_PAGE:
262
+ case pageNo % 2 === ODD_PAGE:
263
+ default: {
264
+ return {
265
+ header: section.page.header,
266
+ footer: section.page.footer,
267
+ headerMargins: section.page.style.headerMargins,
268
+ footerMargins: section.page.style.footerMargins,
269
+ }
270
+ }
271
+ }
272
+ }
273
+
274
+ function getPageContentRect(desiredSizes: Map<{}, AD.Size.Size>, section: AD.Section.Section, pageNo: number): AD.Rect.Rect {
240
275
  const style = section.page.style;
241
276
  const pageWidth = AD.PageStyle.getWidth(style);
242
277
  const pageHeight = AD.PageStyle.getHeight(style);
243
278
 
244
- const headerHeight = section.page.header.reduce(
245
- (a, b) => a + getDesiredSize(b, desiredSizes).height,
246
- style.headerMargins.top + style.headerMargins.bottom
279
+ const { header, footer, headerMargins, footerMargins } = getHeaderAndFooter(section, pageNo);
280
+ const headerHeight = header.reduce(
281
+ (prev, curr) => prev + getDesiredSize(curr, desiredSizes).height,
282
+ headerMargins.top + headerMargins.bottom
247
283
  );
248
- const footerHeight = section.page.footer.reduce(
249
- (a, b) => a + getDesiredSize(b, desiredSizes).height,
250
- style.footerMargins.top + style.footerMargins.bottom
284
+ const footerHeight = footer.reduce(
285
+ (prev, curr) => prev + getDesiredSize(curr, desiredSizes).height,
286
+ footerMargins.top + footerMargins.bottom
251
287
  );
252
288
 
253
- let headerY = style.headerMargins.top;
254
- for (let element of section.page.header) {
289
+ let headerY = headerMargins.top;
290
+ for (let element of header) {
255
291
  const elementSize = getDesiredSize(element, desiredSizes);
256
292
  headerY += elementSize.height;
257
293
  }
258
- headerY += style.headerMargins.bottom;
294
+ headerY += headerMargins.bottom;
259
295
 
260
296
  const rectX = style.contentMargins.left;
261
297
  const rectY = headerY + style.contentMargins.top;
262
298
  const rectWidth = pageWidth - (style.contentMargins.left + style.contentMargins.right);
263
299
  const rectHeight = pageHeight - headerHeight - footerHeight - style.contentMargins.top - style.contentMargins.bottom;
264
-
265
300
  return AD.Rect.create(rectX, rectY, rectWidth, rectHeight);
266
301
  }
267
302
 
@@ -1,7 +1,7 @@
1
1
  import * as AD from "../../abstract-document/index.js";
2
2
  import { preProcess } from "./pre-process.js";
3
3
  import { measure, measurePages } from "./measure.js";
4
- import { paginate, Page } from "./paginate.js";
4
+ import { paginate, Page, getHeaderAndFooter } from "./paginate.js";
5
5
  import { updatePageRefs } from "./update-refs.js";
6
6
  import { renderImage } from "./render-image.js";
7
7
  import { registerFonts, getFontNameStyle } from "./font.js";
@@ -80,8 +80,9 @@ function renderPage(
80
80
  }
81
81
  });
82
82
 
83
- const headerX = style.headerMargins.left;
84
- const headerStart = style.headerMargins.top;
83
+ const { headerMargins, footerMargins } = getHeaderAndFooter(section, page.pageNo);
84
+ const headerX = headerMargins.left;
85
+ const headerStart = headerMargins.top;
85
86
  let headerY = headerStart;
86
87
  for (let element of page.header) {
87
88
  const elementSize = getDesiredSize(element, desiredSizes);
@@ -97,14 +98,14 @@ function renderPage(
97
98
  headerY += elementSize.height;
98
99
  }
99
100
  }
100
- headerY += style.headerMargins.bottom;
101
+ headerY += headerMargins.bottom;
101
102
 
102
103
  const footerHeight = page.footer.reduce(
103
104
  (a, b) => a + (AD.Position.isPositionAbsolute(b) ? 0 : getDesiredSize(b, desiredSizes).height),
104
- style.footerMargins.top + style.footerMargins.bottom
105
+ footerMargins.top + footerMargins.bottom
105
106
  );
106
- const footerX = style.footerMargins.left;
107
- const footerStart = pageHeight - (footerHeight - style.footerMargins.top);
107
+ const footerX = footerMargins.left;
108
+ const footerStart = pageHeight - (footerHeight - footerMargins.top);
108
109
  let footerY = footerStart;
109
110
  for (let element of page.footer) {
110
111
  const elementSize = getDesiredSize(element, desiredSizes);
@@ -36,9 +36,16 @@ function abstractDocXmlRecursive(
36
36
  } else {
37
37
  // For lowercase elements we add them as keys using their name
38
38
  // Some special keys should directly have an array of children as value instead of an object with children key
39
- const arrayedElements = ["frontHeader", "frontFooter", "header", "footer", "headerRows"];
39
+ const arrayedElements = ["header", "footer", "headerRows"];
40
40
  const childrenOnly = arrayedElements.findIndex((e) => e === childName) !== -1;
41
- props[childName] = abstractDocXmlRecursive(creators, childElement, childrenOnly);
41
+ const differentFirstPage = childElement.attributes.differentFirstPage;
42
+ if(differentFirstPage === "true" && childName === "header") {
43
+ props.frontHeader = abstractDocXmlRecursive(creators, childElement, childrenOnly);
44
+ } else if (differentFirstPage === "true" && childName === "footer") {
45
+ props.frontFooter = abstractDocXmlRecursive(creators, childElement, childrenOnly);
46
+ } else {
47
+ props[childName] = abstractDocXmlRecursive(creators, childElement, childrenOnly);
48
+ }
42
49
  }
43
50
  }
44
51
  }
@@ -1,10 +1,10 @@
1
1
  import * as Custom from "./custom-elements.js";
2
2
 
3
3
  export const abstractDoc = `<xs:element name="AbstractDoc">
4
- <xs:complexType>
4
+ <xs:complexType>
5
5
  <xs:sequence>
6
- <xs:element name="StyleNames" type="StyleNames" minOccurs="0"></xs:element>
7
- <xs:element name="Section" type="Section"></xs:element>
6
+ <xs:element name="StyleNames" type="StyleNames" minOccurs="0"></xs:element>
7
+ <xs:element name="Section" type="Section"></xs:element>
8
8
  </xs:sequence>
9
9
  </xs:complexType>
10
10
  </xs:element>`;
@@ -28,23 +28,30 @@ export const page = `<xs:complexType name="page">
28
28
  </xs:annotation>
29
29
  <xs:all>
30
30
  <xs:element name="style" type="MasterPageStyle" />
31
- <xs:element name="header" type="SectionElement" minOccurs="0" />
32
- <xs:element name="footer" type="SectionElement" minOccurs="0" />
33
- <xs:element name="frontHeader" type="SectionElement" minOccurs="0" />
34
- <xs:element name="frontFooter" type="SectionElement" minOccurs="0" />
31
+ <xs:element name="header" type="HeaderFooter" minOccurs="0" />
32
+ <xs:element name="footer" type="HeaderFooter" minOccurs="0" />
35
33
  </xs:all>
36
34
  </xs:complexType>`;
37
35
 
36
+ const sectionElementBody = `<xs:element name="Table" type="Table" minOccurs="0" />
37
+ <xs:element name="Group" type="Group" minOccurs="0" />
38
+ <xs:element name="PageBreak" type="PageBreak" minOccurs="0" />
39
+ <xs:element name="Paragraph" type="Paragraph" minOccurs="0" />
40
+ ${Custom.textParagraphElement}
41
+ ${Custom.imageParagraphElement}
42
+ <xs:element name="Markdown" type="Markdown" minOccurs="0" />`;
43
+
38
44
  export const sectionElement = `<xs:complexType name="SectionElement">
39
45
  <xs:choice maxOccurs="unbounded">
40
- <xs:element name="Table" type="Table" minOccurs="0" />
41
- <xs:element name="Group" type="Group" minOccurs="0" />
42
- <xs:element name="PageBreak" type="PageBreak" minOccurs="0" />
43
- <xs:element name="Paragraph" type="Paragraph" minOccurs="0" />
44
- ${Custom.textParagraphElement}
45
- ${Custom.imageParagraphElement}
46
- <xs:element name="Markdown" type="Markdown" minOccurs="0" />
46
+ ${sectionElementBody}
47
+ </xs:choice>
48
+ </xs:complexType>`;
49
+
50
+ export const headerFooter = `<xs:complexType name="HeaderFooter">
51
+ <xs:choice maxOccurs="unbounded">
52
+ ${sectionElementBody}
47
53
  </xs:choice>
54
+ <xs:attribute name="differentFirstPage" type="xs:boolean" use="optional"/>
48
55
  </xs:complexType>`;
49
56
 
50
57
  export const group = `<xs:complexType name="Group">
@@ -244,6 +244,8 @@ export const masterPageStyle = `<xs:complexType name="MasterPageStyle">
244
244
  <xs:all>
245
245
  <xs:element name="headerMargins" type="LayoutFoundation" />
246
246
  <xs:element name="footerMargins" type="LayoutFoundation" />
247
+ <xs:element name="firstPageHeaderMargins" type="LayoutFoundation" minOccurs="0" />
248
+ <xs:element name="firstPageFooterMargins" type="LayoutFoundation" minOccurs="0" />
247
249
  <xs:element name="contentMargins" type="LayoutFoundation" />
248
250
  </xs:all>
249
251
  <xs:attribute name="paperSize" use="required">
@@ -6,6 +6,7 @@ import { parseXsd } from "handlebars-xml";
6
6
  const commonParts = `${Styles.layoutFoundation}
7
7
  ${Elements.section}
8
8
  ${Elements.sectionElement}
9
+ ${Elements.headerFooter}
9
10
  ${Elements.page}
10
11
  ${Elements.pageBreak}
11
12
  ${Elements.image}