cvdl-ts 1.0.11 → 1.0.13

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.
@@ -1,11 +1,10 @@
1
- import { Box } from "./Box";
2
1
  import { DataSchema } from "./DataSchema";
3
- import { Elem, SectionLayout } from "./Layout";
4
2
  import { LayoutSchema } from "./LayoutSchema";
5
3
  import { Storage } from "./Storage";
6
4
  import { Resume } from "./Resume";
7
5
  import { ResumeLayout } from "./ResumeLayout";
8
6
  import * as fontkit from 'fontkit';
7
+ import { Layout } from ".";
9
8
  export type ElementPath = {
10
9
  tag: 'none';
11
10
  } | {
@@ -21,14 +20,6 @@ export type ElementPath = {
21
20
  item: number;
22
21
  field: string;
23
22
  };
24
- export declare class ElementBox {
25
- bounding_box: Box;
26
- elements: [Box, Elem][];
27
- path?: ElementPath;
28
- constructor(bounding_box: Box, elements: [Box, Elem][]);
29
- move_y_by(y: number): ElementBox;
30
- move_x_by(x: number): ElementBox;
31
- }
32
23
  export type RenderProps = {
33
24
  resume: Resume;
34
25
  layout_schemas: LayoutSchema[];
@@ -43,4 +34,4 @@ export declare class FontDict {
43
34
  load_fonts_from_schema(schema: LayoutSchema, storage: Storage): Promise<void>;
44
35
  get_font(name: string): fontkit.Font;
45
36
  }
46
- export declare function render({ resume, layout_schemas, data_schemas, resume_layout, storage, fontDict }: RenderProps): Promise<[FontDict, ElementBox[][], SectionLayout[]]>;
37
+ export declare function render({ resume, layout_schemas, data_schemas, resume_layout, storage, fontDict }: RenderProps): Promise<[FontDict, Layout.RenderedLayout[]]>;
package/dist/AnyLayout.js CHANGED
@@ -23,45 +23,25 @@ var __importStar = (this && this.__importStar) || function (mod) {
23
23
  return result;
24
24
  };
25
25
  Object.defineProperty(exports, "__esModule", { value: true });
26
- exports.render = exports.FontDict = exports.ElementBox = void 0;
26
+ exports.render = exports.FontDict = void 0;
27
27
  const ResumeLayout_1 = require("./ResumeLayout");
28
28
  const fontkit = __importStar(require("fontkit"));
29
- class ElementBox {
30
- constructor(bounding_box, elements) {
31
- this.bounding_box = bounding_box;
32
- this.elements = elements;
33
- this.path = { tag: 'none' };
34
- }
35
- move_y_by(y) {
36
- this.bounding_box = this.bounding_box.move_y_by(y);
37
- this.elements = this
38
- .elements
39
- .map(([b, e]) => ([b.move_y_by(y), e]));
40
- return this;
41
- }
42
- move_x_by(x) {
43
- this.bounding_box = this.bounding_box.move_x_by(x);
44
- this.elements = this
45
- .elements
46
- .map(([b, e]) => ([b.move_x_by(x), e]));
47
- return this;
48
- }
49
- }
50
- exports.ElementBox = ElementBox;
29
+ const _1 = require(".");
51
30
  class FontDict {
52
31
  constructor() {
53
32
  this.fonts = new Map();
54
33
  }
55
34
  async load_fonts_from_schema(schema, storage) {
56
35
  for (const font of schema.fonts()) {
57
- console.log(`Loading font ${font.full_name()}`);
58
- if (this.fonts.has(font.full_name())) {
59
- console.log(`Font ${font.full_name()} is already loaded`);
36
+ const fontName = _1.Font.full_name(font);
37
+ console.log(`Loading font ${fontName}`);
38
+ if (this.fonts.has(fontName)) {
39
+ console.log(`Font ${fontName} is already loaded`);
60
40
  continue;
61
41
  }
62
42
  const font_data = await storage.load_font(font);
63
43
  const fontkit_font = fontkit.create(font_data);
64
- this.fonts.set(font.full_name(), fontkit_font);
44
+ this.fonts.set(fontName, fontkit_font);
65
45
  }
66
46
  }
67
47
  get_font(name) {
@@ -75,7 +55,6 @@ class FontDict {
75
55
  exports.FontDict = FontDict;
76
56
  async function render({ resume, layout_schemas, data_schemas, resume_layout, storage, fontDict }) {
77
57
  // Each box contains a set of elements(positioned by 0x0 and projected into its bounding box)
78
- const boxes = [];
79
58
  const font_dict = fontDict !== null && fontDict !== void 0 ? fontDict : new FontDict();
80
59
  // Compute the total usable width by subtracting the margins from the document width
81
60
  const width = resume_layout.width - (resume_layout.margin.left + resume_layout.margin.right);
@@ -84,7 +63,9 @@ async function render({ resume, layout_schemas, data_schemas, resume_layout, sto
84
63
  ? width
85
64
  : (width - (0, ResumeLayout_1.vertical_margin)(resume_layout.column_type) / 2.0);
86
65
  const layouts = [];
66
+ console.error("Rendering sections...");
87
67
  for (const section of resume.sections) {
68
+ console.error("Print section:", section);
88
69
  // Render Section Header
89
70
  // 1. Find the layout schema for the section
90
71
  console.info("Computing section: ", section.section_name);
@@ -98,81 +79,28 @@ async function render({ resume, layout_schemas, data_schemas, resume_layout, sto
98
79
  let end_time = Date.now();
99
80
  console.info(`Font loading time: ${end_time - start_time}ms for section ${section.section_name}`);
100
81
  // 2. Find the data schema for the section
101
- const _data_schema = data_schemas.find(s => s.schema_name === section.data_schema);
102
- if (_data_schema === undefined) {
82
+ const data_schema = data_schemas.find(s => s.schema_name === section.data_schema);
83
+ if (data_schema === undefined) {
103
84
  throw new Error(`Could not find data schema ${section.data_schema}`);
104
85
  }
105
86
  start_time = Date.now();
106
87
  // 3. Render the header
107
- const [result, layout] = layout_schema
108
- .header_layout_schema
109
- // .copy()
110
- .instantiate(section.data)
111
- .normalize(column_width, font_dict)
112
- .compute_boxes(font_dict);
113
- console.error("LSH: ", layout);
88
+ const layout = _1.Layout.computeBoxes(_1.Layout.normalize(_1.Layout.instantiate(layout_schema.header_layout_schema, section.data, data_schema.header_schema), column_width, font_dict), font_dict);
89
+ console.error("Header is computed");
114
90
  layouts.push(layout);
115
91
  end_time = Date.now();
116
92
  console.info(`Header rendering time: ${end_time - start_time}ms for section ${section.section_name}`);
117
- result.path = {
118
- tag: 'section',
119
- section: section.section_name
120
- };
121
- boxes.push(result);
122
93
  start_time = Date.now();
123
94
  // Render Section Items
124
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
125
- // @ts-nocheck
126
- for (const [index, item] of section.items.entries()) {
127
- console.log("Computing item");
128
- // 1. Find the layout schema for the section
129
- const layout_schema = layout_schemas
130
- .find((s) => s.schema_name == section.layout_schema);
131
- if (layout_schema == undefined) {
132
- throw new Error(`Could not find layout schema ${section.layout_schema}`);
133
- }
134
- await font_dict.load_fonts_from_schema(layout_schema, storage);
135
- console.log("Fonts are loaded");
136
- // 2. Find the data schema for the section
137
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
138
- const _data_schema = data_schemas
139
- .find((s) => s.schema_name == section.data_schema);
95
+ for (const [, item] of section.items.entries()) {
140
96
  // 3. Render the item
141
- const [result, layout] = layout_schema
142
- .item_layout_schema
143
- // .copy()
144
- .instantiate(item.fields)
145
- .normalize(column_width, font_dict)
146
- .compute_boxes(font_dict);
147
- console.error("LSS: ", layout);
97
+ const layout = _1.Layout.computeBoxes(_1.Layout.normalize(_1.Layout.instantiate(layout_schema.item_layout_schema, item.fields, data_schema.item_schema), column_width, font_dict), font_dict);
148
98
  layouts.push(layout);
149
- result.path = {
150
- tag: 'item',
151
- section: section.section_name,
152
- item: index
153
- };
154
- boxes.push(result);
155
99
  }
156
100
  end_time = Date.now();
157
101
  console.info(`Item rendering time: ${end_time - start_time}ms for section ${section.section_name}`);
158
102
  }
159
- let current_y = resume_layout.margin.top;
160
- let current_x = resume_layout.margin.left;
161
- const pages = [];
162
- pages.push([]);
163
- for (const box of boxes) {
164
- if (current_y + box.bounding_box.height() > resume_layout.height) {
165
- current_y = resume_layout.margin.top;
166
- current_x += column_width + (0, ResumeLayout_1.vertical_margin)(resume_layout.column_type);
167
- if (current_x > width) {
168
- pages.push([]);
169
- current_x = resume_layout.margin.left;
170
- }
171
- }
172
- pages[pages.length - 1].push(box.move_y_by(current_y).move_x_by(current_x));
173
- current_y += box.bounding_box.height();
174
- }
175
103
  console.log("Position calculations are completed.");
176
- return [font_dict, pages, layouts];
104
+ return [font_dict, layouts];
177
105
  }
178
106
  exports.render = render;
@@ -1,32 +1,44 @@
1
- export type DocumentDataType = {
2
- tag: "Date";
3
- } | {
4
- tag: "String";
5
- } | {
6
- tag: "MarkdownString";
7
- } | {
8
- tag: "Type";
9
- value: string;
10
- } | {
11
- tag: "List";
12
- value: DocumentDataType;
13
- } | {
14
- tag: "Types";
15
- value: DocumentDataType[];
16
- };
17
- export type Field = {
18
- name: string;
19
- data_type: DocumentDataType;
20
- };
1
+ export declare namespace DocumentDataType {
2
+ type t = {
3
+ tag: "Date";
4
+ } | {
5
+ tag: "String";
6
+ } | {
7
+ tag: "MarkdownString";
8
+ } | {
9
+ tag: "Number";
10
+ } | {
11
+ tag: "Type";
12
+ value: string;
13
+ } | {
14
+ tag: "List";
15
+ value: t;
16
+ } | {
17
+ tag: "Types";
18
+ value: t[];
19
+ };
20
+ type DocumentDataType = t;
21
+ function parse(s: string): DocumentDataType;
22
+ function print(d: DocumentDataType): string;
23
+ }
24
+ export declare namespace Field {
25
+ type t = {
26
+ name: string;
27
+ type: DocumentDataType.t;
28
+ };
29
+ type Field = t;
30
+ function fromJson(json: unknown): Field;
31
+ function toJson(f: Field): unknown;
32
+ }
21
33
  export declare class DataSchema {
22
34
  schema_name: string;
23
- header_schema: Field[];
24
- item_schema: Field[];
25
- constructor(schema_name: string, header_schema: Field[], item_schema: Field[]);
35
+ header_schema: Field.t[];
36
+ item_schema: Field.t[];
37
+ constructor(schema_name: string, header_schema: Field.t[], item_schema: Field.t[]);
26
38
  static fromJson(json: unknown): DataSchema;
27
39
  toJson(): {
28
40
  schema_name: string;
29
- header_schema: Field[];
30
- item_schema: Field[];
41
+ header_schema: unknown[];
42
+ item_schema: unknown[];
31
43
  };
32
44
  }
@@ -1,6 +1,81 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.DataSchema = void 0;
3
+ exports.DataSchema = exports.Field = exports.DocumentDataType = void 0;
4
+ var DocumentDataType;
5
+ (function (DocumentDataType) {
6
+ function parse(s) {
7
+ if (s === "Date") {
8
+ return { tag: "Date" };
9
+ }
10
+ else if (s === "String") {
11
+ return { tag: "String" };
12
+ }
13
+ else if (s === "MarkdownString") {
14
+ return { tag: "MarkdownString" };
15
+ }
16
+ else if (s === "Number") {
17
+ return { tag: "Number" };
18
+ }
19
+ else if (s.startsWith("List")) {
20
+ return { tag: "List", value: parse(s.slice(5, -1).trim()) };
21
+ }
22
+ else if (s.includes("|")) {
23
+ return { tag: "Types", value: s.split("|").map((s) => s.trim()).map(parse) };
24
+ }
25
+ else {
26
+ throw new Error("Invalid DocumentDataType: " + s);
27
+ }
28
+ }
29
+ DocumentDataType.parse = parse;
30
+ function print(d) {
31
+ switch (d.tag) {
32
+ case "Date":
33
+ return "Date";
34
+ case "String":
35
+ return "String";
36
+ case "MarkdownString":
37
+ return "MarkdownString";
38
+ case "Number":
39
+ return "Number";
40
+ case "Type":
41
+ return d.value;
42
+ case "List":
43
+ return "List<" + print(d.value) + ">";
44
+ case "Types":
45
+ return d.value.map(print).join(" | ");
46
+ }
47
+ }
48
+ DocumentDataType.print = print;
49
+ })(DocumentDataType || (exports.DocumentDataType = DocumentDataType = {}));
50
+ var Field;
51
+ (function (Field) {
52
+ function fromJson(json) {
53
+ if (typeof json !== "object" || json === null) {
54
+ throw new Error("Field must be an object");
55
+ }
56
+ if (!("name" in json) || !("type" in json)) {
57
+ throw new Error("Field must have a name and type");
58
+ }
59
+ if (typeof json.name !== "string") {
60
+ throw new Error("Field name must be a string");
61
+ }
62
+ if (typeof json.type !== "string") {
63
+ throw new Error("Field type must be a string");
64
+ }
65
+ return {
66
+ name: json.name,
67
+ type: DocumentDataType.parse(json.type),
68
+ };
69
+ }
70
+ Field.fromJson = fromJson;
71
+ function toJson(f) {
72
+ return {
73
+ name: f.name,
74
+ type: DocumentDataType.print(f.type),
75
+ };
76
+ }
77
+ Field.toJson = toJson;
78
+ })(Field || (exports.Field = Field = {}));
4
79
  class DataSchema {
5
80
  constructor(schema_name, header_schema, item_schema) {
6
81
  this.schema_name = schema_name;
@@ -14,13 +89,13 @@ class DataSchema {
14
89
  if (!("schema_name" in json) || !("header_schema" in json) || !("item_schema" in json)) {
15
90
  throw new Error("DataSchema must have a schema_name, header_schema, and item_schema");
16
91
  }
17
- return new DataSchema(json.schema_name, json.header_schema, json.item_schema);
92
+ return new DataSchema(json.schema_name, json.header_schema.map(Field.fromJson), json.item_schema.map(Field.fromJson));
18
93
  }
19
94
  toJson() {
20
95
  return {
21
96
  schema_name: this.schema_name,
22
- header_schema: this.header_schema,
23
- item_schema: this.item_schema,
97
+ header_schema: this.header_schema.map(Field.toJson),
98
+ item_schema: this.item_schema.map(Field.toJson),
24
99
  };
25
100
  }
26
101
  }
package/dist/Elem.d.ts ADDED
@@ -0,0 +1,73 @@
1
+ import * as Font from "./Font";
2
+ import { Alignment, Layout, Margin, Width } from ".";
3
+ import { Color } from "./Layout";
4
+ import { FontDict } from "./AnyLayout";
5
+ import * as Row from "./Row";
6
+ import { ItemContent } from "./Resume";
7
+ import { Field } from "./DataSchema";
8
+ import { Optional } from "./Utils";
9
+ import { Box } from "./Box";
10
+ type Span = {
11
+ is_italic: boolean;
12
+ is_bold: boolean;
13
+ is_code: boolean;
14
+ text: string;
15
+ link: string | null;
16
+ font?: Font.t;
17
+ width?: number;
18
+ line?: number;
19
+ bbox?: Box;
20
+ };
21
+ export type t = {
22
+ tag: "Elem";
23
+ item: string;
24
+ spans?: Span[];
25
+ url: string | null;
26
+ is_ref: boolean;
27
+ is_fill: boolean;
28
+ is_markdown: boolean;
29
+ text_width: Width.t;
30
+ font: Font.t;
31
+ margin: Margin.t;
32
+ alignment: Alignment.t;
33
+ width: Width.t;
34
+ background_color: Color;
35
+ };
36
+ type Elem = t;
37
+ export declare function elem(item: string, url: string | null, is_ref: boolean, is_fill: boolean, is_markdown: boolean, text_width: Width.t, font: Font.t, margin: Margin.t, alignment: Alignment.t, width: Width.t, background_color: Color): Elem;
38
+ export declare function copy(e: Elem): {
39
+ tag: "Elem";
40
+ item: string;
41
+ spans?: Span[];
42
+ url: string;
43
+ is_ref: boolean;
44
+ is_fill: boolean;
45
+ is_markdown: boolean;
46
+ text_width: Width.t;
47
+ font: Font.t;
48
+ margin: Margin.t;
49
+ alignment: Alignment.t;
50
+ width: Width.t;
51
+ background_color: Layout.Color;
52
+ };
53
+ export declare function default_(): Elem;
54
+ export declare function from(w: Optional<Elem>): Elem;
55
+ export declare function withItem(e: Elem, item: string): Elem;
56
+ export declare function withUrl(e: Elem, url: string | null): Elem;
57
+ export declare function withIsRef(e: Elem, is_ref: boolean): Elem;
58
+ export declare function asRef(e: Elem): Elem;
59
+ export declare function withIsFill(e: Elem, is_fill: boolean): Elem;
60
+ export declare function withTextWidth(e: Elem, text_width: Width.t): Elem;
61
+ export declare function withFont(e: Elem, font: Font.t): Elem;
62
+ export declare function withMargin(e: Elem, margin: Margin.t): Elem;
63
+ export declare function withAlignment(e: Elem, alignment: Alignment.t): Elem;
64
+ export declare function withWidth(e: Elem, width: Width.t): Elem;
65
+ export declare function withBackgroundColor(e: Elem, background_color: Color): Elem;
66
+ export declare function scaleWidth(e: Elem, scale: number): Elem;
67
+ export declare function parseMarkdownItem(item: string): Span[];
68
+ export declare function fillFonts(e: Elem, fonts: FontDict): Elem;
69
+ export declare function justifiedLines(e: Elem, lines: Elem[], font_dict: FontDict): Row.t[];
70
+ export declare function break_lines(e: Elem, font_dict: FontDict): Layout.t[];
71
+ export declare function boundWidth(e: Elem, width: number): Elem;
72
+ export declare function instantiate(e: Elem, section: Map<string, ItemContent>, fields: Field.t[]): Elem;
73
+ export {};