cvdl-ts 1.0.12 → 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.
package/dist/AnyLayout.js CHANGED
@@ -79,38 +79,22 @@ async function render({ resume, layout_schemas, data_schemas, resume_layout, sto
79
79
  let end_time = Date.now();
80
80
  console.info(`Font loading time: ${end_time - start_time}ms for section ${section.section_name}`);
81
81
  // 2. Find the data schema for the section
82
- const _data_schema = data_schemas.find(s => s.schema_name === section.data_schema);
83
- if (_data_schema === undefined) {
82
+ const data_schema = data_schemas.find(s => s.schema_name === section.data_schema);
83
+ if (data_schema === undefined) {
84
84
  throw new Error(`Could not find data schema ${section.data_schema}`);
85
85
  }
86
86
  start_time = Date.now();
87
87
  // 3. Render the header
88
- const layout = _1.Layout.computeBoxes(_1.Layout.normalize(_1.Layout.instantiate(layout_schema.header_layout_schema, section.data), column_width, font_dict), font_dict);
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
89
  console.error("Header is computed");
90
90
  layouts.push(layout);
91
91
  end_time = Date.now();
92
92
  console.info(`Header rendering time: ${end_time - start_time}ms for section ${section.section_name}`);
93
93
  start_time = Date.now();
94
94
  // Render Section Items
95
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
96
- // @ts-nocheck
97
- for (const [index, item] of section.items.entries()) {
98
- console.log("Computing item");
99
- console.error("Item:", item);
100
- // 1. Find the layout schema for the section
101
- const layout_schema = layout_schemas
102
- .find((s) => s.schema_name == section.layout_schema);
103
- if (layout_schema == undefined) {
104
- throw new Error(`Could not find layout schema ${section.layout_schema}`);
105
- }
106
- await font_dict.load_fonts_from_schema(layout_schema, storage);
107
- console.log("Fonts are loaded");
108
- // 2. Find the data schema for the section
109
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
110
- const _data_schema = data_schemas
111
- .find((s) => s.schema_name == section.data_schema);
95
+ for (const [, item] of section.items.entries()) {
112
96
  // 3. Render the item
113
- const layout = _1.Layout.computeBoxes(_1.Layout.normalize(_1.Layout.instantiate(layout_schema.item_layout_schema, item.fields), column_width, font_dict), font_dict);
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);
114
98
  layouts.push(layout);
115
99
  }
116
100
  end_time = Date.now();
@@ -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 CHANGED
@@ -4,12 +4,28 @@ import { Color } from "./Layout";
4
4
  import { FontDict } from "./AnyLayout";
5
5
  import * as Row from "./Row";
6
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
+ };
7
21
  export type t = {
8
22
  tag: "Elem";
9
23
  item: string;
24
+ spans?: Span[];
10
25
  url: string | null;
11
26
  is_ref: boolean;
12
27
  is_fill: boolean;
28
+ is_markdown: boolean;
13
29
  text_width: Width.t;
14
30
  font: Font.t;
15
31
  margin: Margin.t;
@@ -18,13 +34,15 @@ export type t = {
18
34
  background_color: Color;
19
35
  };
20
36
  type Elem = t;
21
- export declare function elem(item: string, url: string | null, is_ref: boolean, is_fill: boolean, text_width: Width.t, font: Font.t, margin: Margin.t, alignment: Alignment.t, width: Width.t, background_color: Color): Elem;
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;
22
38
  export declare function copy(e: Elem): {
23
39
  tag: "Elem";
24
40
  item: string;
41
+ spans?: Span[];
25
42
  url: string;
26
43
  is_ref: boolean;
27
44
  is_fill: boolean;
45
+ is_markdown: boolean;
28
46
  text_width: Width.t;
29
47
  font: Font.t;
30
48
  margin: Margin.t;
@@ -33,10 +51,6 @@ export declare function copy(e: Elem): {
33
51
  background_color: Layout.Color;
34
52
  };
35
53
  export declare function default_(): Elem;
36
- export type Optional<T> = {
37
- [P in keyof T]?: T[P];
38
- };
39
- export declare function with_(e: Elem, w: Optional<Elem>): Elem;
40
54
  export declare function from(w: Optional<Elem>): Elem;
41
55
  export declare function withItem(e: Elem, item: string): Elem;
42
56
  export declare function withUrl(e: Elem, url: string | null): Elem;
@@ -50,9 +64,10 @@ export declare function withAlignment(e: Elem, alignment: Alignment.t): Elem;
50
64
  export declare function withWidth(e: Elem, width: Width.t): Elem;
51
65
  export declare function withBackgroundColor(e: Elem, background_color: Color): Elem;
52
66
  export declare function scaleWidth(e: Elem, scale: number): Elem;
67
+ export declare function parseMarkdownItem(item: string): Span[];
53
68
  export declare function fillFonts(e: Elem, fonts: FontDict): Elem;
54
69
  export declare function justifiedLines(e: Elem, lines: Elem[], font_dict: FontDict): Row.t[];
55
70
  export declare function break_lines(e: Elem, font_dict: FontDict): Layout.t[];
56
71
  export declare function boundWidth(e: Elem, width: number): Elem;
57
- export declare function instantiate(e: Elem, section: Map<string, ItemContent>): Elem;
72
+ export declare function instantiate(e: Elem, section: Map<string, ItemContent>, fields: Field.t[]): Elem;
58
73
  export {};
package/dist/Elem.js CHANGED
@@ -23,18 +23,30 @@ var __importStar = (this && this.__importStar) || function (mod) {
23
23
  return result;
24
24
  };
25
25
  Object.defineProperty(exports, "__esModule", { value: true });
26
- exports.instantiate = exports.boundWidth = exports.break_lines = exports.justifiedLines = exports.fillFonts = exports.scaleWidth = exports.withBackgroundColor = exports.withWidth = exports.withAlignment = exports.withMargin = exports.withFont = exports.withTextWidth = exports.withIsFill = exports.asRef = exports.withIsRef = exports.withUrl = exports.withItem = exports.from = exports.with_ = exports.default_ = exports.copy = exports.elem = void 0;
26
+ exports.instantiate = exports.boundWidth = exports.break_lines = exports.justifiedLines = exports.fillFonts = exports.parseMarkdownItem = exports.scaleWidth = exports.withBackgroundColor = exports.withWidth = exports.withAlignment = exports.withMargin = exports.withFont = exports.withTextWidth = exports.withIsFill = exports.asRef = exports.withIsRef = exports.withUrl = exports.withItem = exports.from = exports.default_ = exports.copy = exports.elem = void 0;
27
27
  const Font = __importStar(require("./Font"));
28
28
  const _1 = require(".");
29
29
  const Row_1 = require("./Row");
30
30
  const Resume_1 = require("./Resume");
31
- function elem(item, url, is_ref, is_fill, text_width, font, margin, alignment, width, background_color) {
31
+ const marked = __importStar(require("marked"));
32
+ const ts_pattern_1 = require("ts-pattern");
33
+ const Utils_1 = require("./Utils");
34
+ function defaultSpanProps() {
35
+ return {
36
+ is_italic: false,
37
+ is_bold: false,
38
+ is_code: false,
39
+ is_link: false,
40
+ };
41
+ }
42
+ function elem(item, url, is_ref, is_fill, is_markdown, text_width, font, margin, alignment, width, background_color) {
32
43
  return {
33
44
  tag: "Elem",
34
45
  item,
35
46
  url,
36
47
  is_ref,
37
48
  is_fill,
49
+ is_markdown,
38
50
  text_width,
39
51
  font,
40
52
  margin,
@@ -55,6 +67,7 @@ function default_() {
55
67
  url: null,
56
68
  is_ref: false,
57
69
  is_fill: false,
70
+ is_markdown: false,
58
71
  text_width: _1.Width.default_(),
59
72
  font: Font.default_(),
60
73
  margin: _1.Margin.default_(),
@@ -64,10 +77,6 @@ function default_() {
64
77
  };
65
78
  }
66
79
  exports.default_ = default_;
67
- function with_(e, w) {
68
- return { ...e, ...w };
69
- }
70
- exports.with_ = with_;
71
80
  function from(w) {
72
81
  return { ...default_(), ...w };
73
82
  }
@@ -120,13 +129,91 @@ function scaleWidth(e, scale) {
120
129
  return withWidth(e, _1.Width.scale(e.width, scale));
121
130
  }
122
131
  exports.scaleWidth = scaleWidth;
132
+ function flatten(ts, sp) {
133
+ const spans = [];
134
+ for (const t of ts) {
135
+ spans.push(...flattenToken(t, sp));
136
+ }
137
+ return spans;
138
+ }
139
+ function flattenToken(t, sp) {
140
+ return (0, ts_pattern_1.match)(t)
141
+ .returnType()
142
+ .with({ type: "paragraph", tokens: ts_pattern_1.P.select("tokens") }, ({ tokens }) => {
143
+ // console.log("[paragraph]", tokens);
144
+ return flatten(tokens, sp);
145
+ })
146
+ .with({ type: "strong", tokens: ts_pattern_1.P.select("tokens") }, ({ tokens }) => {
147
+ // console.log("[strong]", tokens);
148
+ return flatten(tokens, { ...sp, is_bold: true });
149
+ })
150
+ .with({ type: "em", tokens: ts_pattern_1.P.select("tokens") }, ({ tokens }) => {
151
+ // console.log("[em]", tokens);
152
+ return flatten(tokens, { ...sp, is_italic: true });
153
+ })
154
+ .with({ type: "codespan", text: ts_pattern_1.P.select("text") }, ({ text }) => {
155
+ // console.log("[codespan]", text);
156
+ return [{ ...sp, is_code: true, text, link: null }];
157
+ })
158
+ .with({ type: "text", tokens: ts_pattern_1.P.select("tokens") }, ({ tokens }) => {
159
+ return flatten(tokens, sp);
160
+ })
161
+ .with({ type: "text", text: ts_pattern_1.P.select("text") }, ({ text }) => {
162
+ const result = [];
163
+ if (text.startsWith(" ")) {
164
+ result.push({ ...sp, text: " ", link: null });
165
+ }
166
+ result.push({ ...sp, text: text.trim(), link: null });
167
+ if (text.endsWith(" ")) {
168
+ result.push({ ...sp, text: " ", link: null });
169
+ }
170
+ else if (text.endsWith("\n")) {
171
+ result.push({ ...sp, text: "\n", link: null });
172
+ }
173
+ return result;
174
+ })
175
+ .otherwise((e) => {
176
+ // console.log(`Unknown token type: ${JSON.stringify(e)}`);
177
+ return [{ ...defaultSpanProps(), text: e.raw, link: null }];
178
+ });
179
+ }
180
+ function parseMarkdownItem(item) {
181
+ const spans = [];
182
+ for (const token of marked.lexer(item)) {
183
+ spans.push(...flatten([token], defaultSpanProps()));
184
+ }
185
+ return spans;
186
+ }
187
+ exports.parseMarkdownItem = parseMarkdownItem;
123
188
  function fillFonts(e, fonts) {
124
- const text_width_with_font = Font.get_width(e.font, e.item, fonts);
189
+ const simpleSpans = e.is_markdown ? parseMarkdownItem(e.item) : [{ ...defaultSpanProps(), text: e.item, font: e.font, link: null }];
190
+ const spans = [];
191
+ for (const span of simpleSpans) {
192
+ const font = e.is_markdown ? (0, Utils_1.with_)(e.font, ({
193
+ // style: span.is_italic ? "Italic" : "Normal",
194
+ weight: span.is_bold ? "Bold" : "Medium",
195
+ })) : e.font;
196
+ if (span.text === " " || span.text === "\n") {
197
+ const width = Font.get_width(font, span.text, fonts);
198
+ spans.push({ ...span, font, width });
199
+ continue;
200
+ }
201
+ span.text.split(/\s+/).forEach(word => {
202
+ const width = Font.get_width(font, word, fonts);
203
+ spans.push({ ...span, text: word, font, width });
204
+ spans.push({ ...span, text: " ", font, width: Font.get_width(font, " ", fonts) });
205
+ });
206
+ }
207
+ const text_width = spans.reduce((acc, span) => acc + span.width, 0);
125
208
  if (e.is_fill) {
126
- return withTextWidth(withWidth(e, _1.Width.absolute(Math.min(_1.Width.get_fixed_unchecked(e.width), text_width_with_font))), _1.Width.absolute(text_width_with_font));
209
+ return (0, Utils_1.with_)(e, {
210
+ width: _1.Width.absolute(Math.min(_1.Width.get_fixed_unchecked(e.width), text_width)),
211
+ text_width: _1.Width.absolute(text_width),
212
+ spans
213
+ });
127
214
  }
128
215
  else {
129
- return withTextWidth(e, _1.Width.absolute(text_width_with_font));
216
+ return (0, Utils_1.with_)(e, { text_width: _1.Width.absolute(text_width), spans });
130
217
  }
131
218
  }
132
219
  exports.fillFonts = fillFonts;
@@ -137,7 +224,7 @@ function justifiedLines(e, lines, font_dict) {
137
224
  const r = (0, Row_1.row)([], line.margin, line.alignment, line.width, false, false);
138
225
  words.forEach(word => {
139
226
  const word_width = Font.get_width(e.font, word, font_dict);
140
- r.elements.push(elem(word, null, false, false, _1.Width.absolute(word_width), this.font, _1.Margin.default_(), _1.Alignment.default_(), _1.Width.absolute(word_width), this.background_color));
227
+ r.elements.push(elem(word, null, false, false, false, _1.Width.absolute(word_width), this.font, _1.Margin.default_(), _1.Alignment.default_(), _1.Width.absolute(word_width), this.background_color));
141
228
  });
142
229
  rowLines.push(Row_1.row);
143
230
  }
@@ -189,10 +276,16 @@ function boundWidth(e, width) {
189
276
  }
190
277
  }
191
278
  exports.boundWidth = boundWidth;
192
- function instantiate(e, section) {
279
+ function instantiate(e, section, fields) {
193
280
  if (!e.is_ref) {
194
281
  return e;
195
282
  }
283
+ const itemType = fields.find(f => f.name === e.item);
284
+ console.log(`Found item type: ${JSON.stringify(itemType)}`);
285
+ if (itemType.type.tag === "MarkdownString") {
286
+ console.log(`Found markdown string: ${e.item}`);
287
+ e.is_markdown = true;
288
+ }
196
289
  const text = section.get(e.item);
197
290
  if (text === undefined) {
198
291
  return withIsRef(withItem(e, ""), false);
package/dist/Layout.d.ts CHANGED
@@ -9,6 +9,7 @@ import { Point } from "./Point";
9
9
  import * as Stack from "./Stack";
10
10
  import * as Row from "./Row";
11
11
  import * as Elem from "./Elem";
12
+ import { Field } from "./DataSchema";
12
13
  export type Container = Stack.t | Row.t;
13
14
  export type t = Stack.t | Row.t | Elem.t;
14
15
  type Layout = t;
@@ -39,7 +40,7 @@ export declare function withAlignment(l: Layout, alignment: Alignment.t): Layout
39
40
  export declare function withWidth(l: Layout, width: Width.t): Layout;
40
41
  export declare function totalElementsWidth(l: Layout): number;
41
42
  export declare function isInstantiated(l: Layout): boolean;
42
- export declare function instantiate(l: Layout, section: Map<string, ItemContent>): Layout;
43
+ export declare function instantiate(l: Layout, section: Map<string, ItemContent>, fields: Field.t[]): Layout;
43
44
  export declare function boundWidth(l: Layout, width: number): Layout;
44
45
  export declare function scaleWidth(l: Layout, document_width: number): Layout;
45
46
  export declare function normalize(l: Layout, width: number, font_dict: FontDict): Layout;
package/dist/Layout.js CHANGED
@@ -209,14 +209,14 @@ function isInstantiated(l) {
209
209
  }
210
210
  }
211
211
  exports.isInstantiated = isInstantiated;
212
- function instantiate(l, section) {
212
+ function instantiate(l, section, fields) {
213
213
  switch (l.tag) {
214
214
  case "Stack":
215
- return Stack.instantiate(l, section);
215
+ return Stack.withElements(l, l.elements.map(e => instantiate(e, section, fields)));
216
216
  case "Row":
217
- return Row.instantiate(l, section);
217
+ return Row.withElements(l, l.elements.map(e => instantiate(e, section, fields)));
218
218
  case "Elem":
219
- return Elem.instantiate(l, section);
219
+ return Elem.instantiate(l, section, fields);
220
220
  }
221
221
  }
222
222
  exports.instantiate = instantiate;
@@ -266,9 +266,10 @@ function normalize(l, width, font_dict) {
266
266
  console.debug("Widths are bounded. Filling fonts...");
267
267
  const font_filled_layout = fillFonts(bounded_layout, font_dict);
268
268
  console.debug("Fonts filled. Breaking lines...");
269
- const broken_layout = breakLines(font_filled_layout, font_dict);
269
+ // const broken_layout = breakLines(font_filled_layout, font_dict);
270
270
  console.debug("Lines broken.");
271
- return broken_layout;
271
+ // return broken_layout;
272
+ return font_filled_layout;
272
273
  }
273
274
  exports.normalize = normalize;
274
275
  function fillFonts(l, font_dict) {
@@ -354,7 +355,11 @@ function computeTextboxPositions(l, top_left, font_dict) {
354
355
  top_left = top_left.move_y_to(depth);
355
356
  renderedElements.push(result.renderedLayout);
356
357
  }
357
- return { depth, renderedLayout: { ...l, bounding_box: new Box_1.Box(originalTopLeft, top_left.move_x_by(Width.get_fixed_unchecked(stack.width))), elements: renderedElements } };
358
+ return {
359
+ depth, renderedLayout: {
360
+ ...l, bounding_box: new Box_1.Box(originalTopLeft, top_left.move_x_by(Width.get_fixed_unchecked(stack.width))), elements: renderedElements
361
+ }
362
+ };
358
363
  }
359
364
  case "Row": {
360
365
  const row = l;
@@ -380,19 +385,31 @@ function computeTextboxPositions(l, top_left, font_dict) {
380
385
  top_left.move_x_by(Width.get_fixed_unchecked(element.width) + per_elem_space);
381
386
  renderedElements.push(result.renderedLayout);
382
387
  }
383
- return { depth, renderedLayout: { ...l, bounding_box: new Box_1.Box(originalTopLeft, originalTopLeft.move_y_by(depth).move_x_by(Width.get_fixed_unchecked(row.width))), elements: renderedElements } };
388
+ return {
389
+ depth, renderedLayout: {
390
+ ...l, bounding_box: new Box_1.Box(originalTopLeft, originalTopLeft.move_y_by(depth).move_x_by(Width.get_fixed_unchecked(row.width))), elements: renderedElements
391
+ }
392
+ };
384
393
  }
385
394
  case "Elem": {
386
395
  const elem = l;
387
396
  if (elem.is_ref) {
388
397
  throw new Error("Cannot compute textbox positions of uninstantiated layout");
389
398
  }
390
- if (elem.item === "") {
391
- return { depth, renderedLayout: { ...l, bounding_box: new Box_1.Box(top_left, top_left) } };
392
- }
393
399
  const height = Font.get_height(elem.font, font_dict);
394
400
  const width = Width.get_fixed_unchecked(elem.text_width);
395
401
  top_left = top_left.move_y_by(elem.margin.top).move_x_by(elem.margin.left);
402
+ let line = 1;
403
+ let cursor = top_left.x;
404
+ elem.spans.forEach(span => {
405
+ if (cursor + span.width > Width.get_fixed_unchecked(elem.width) - elem.margin.right) {
406
+ cursor = top_left.x;
407
+ line += 1;
408
+ }
409
+ span.bbox = new Box_1.Box(new Point_1.Point(cursor, (line - 1) * height), new Point_1.Point(cursor + span.width, line * height));
410
+ cursor += span.width;
411
+ console.log(span);
412
+ });
396
413
  switch (elem.alignment) {
397
414
  case "Center":
398
415
  top_left = top_left.move_x_by((Width.get_fixed_unchecked(elem.width) - width) / 2.0);
package/dist/PdfLayout.js CHANGED
@@ -121,10 +121,29 @@ const renderSectionLayout = (layout, resume_layout, current_height, doc) => {
121
121
  }
122
122
  case "Elem": {
123
123
  const elem = layout;
124
- doc.
125
- font(_1.Font.full_name(elem.font)).
126
- fontSize(elem.font.size).
127
- text(elem.item, layout.bounding_box.top_left.x + resume_layout.margin.left, layout.bounding_box.top_left.y + resume_layout.margin.top + current_height, { lineBreak: false });
124
+ elem.spans.forEach((span) => {
125
+ console.log(span);
126
+ if (span.text === "") {
127
+ return;
128
+ }
129
+ doc.
130
+ font(_1.Font.full_name(span.font)).
131
+ fontSize(span.font.size).
132
+ text(span.text, layout.bounding_box.top_left.x + resume_layout.margin.left + span.bbox.top_left.x, layout.bounding_box.top_left.y + resume_layout.margin.top + current_height + span.bbox.top_left.y, { lineBreak: false });
133
+ if (span.is_code) {
134
+ // Add a rounded rectangle around the code
135
+ doc.roundedRect(layout.bounding_box.top_left.x + resume_layout.margin.left + span.bbox.top_left.x - span.font.size / 3, layout.bounding_box.top_left.y + resume_layout.margin.top + current_height + span.bbox.top_left.y, span.bbox.width() + span.font.size / 3 * 2, span.bbox.height(), 5).stroke();
136
+ // Add a background color to the code
137
+ doc.fillColor("black");
138
+ doc.fillOpacity(0.05);
139
+ doc.rect(layout.bounding_box.top_left.x + resume_layout.margin.left + span.bbox.top_left.x - span.font.size / 3, layout.bounding_box.top_left.y + resume_layout.margin.top + current_height + span.bbox.top_left.y, span.bbox.width() + span.font.size / 3 * 2, span.bbox.height()).fill();
140
+ doc.fillOpacity(1);
141
+ }
142
+ });
143
+ // doc.
144
+ // font(Font.full_name(elem.font)).
145
+ // fontSize(elem.font.size).
146
+ // text(elem.item, layout.bounding_box.top_left.x + resume_layout.margin.left, layout.bounding_box.top_left.y + resume_layout.margin.top + current_height, { lineBreak: false });
128
147
  break;
129
148
  }
130
149
  }
package/dist/Row.d.ts CHANGED
@@ -1,8 +1,7 @@
1
1
  import { Alignment, Margin, Width } from ".";
2
2
  import { FontDict } from "./AnyLayout";
3
- import { Optional } from "./Elem";
3
+ import { Optional } from "./Utils";
4
4
  import * as Layout from "./Layout";
5
- import { ItemContent } from "./Resume";
6
5
  export type t = {
7
6
  tag: "Row";
8
7
  elements: Layout.t[];
@@ -13,12 +12,10 @@ export type t = {
13
12
  is_fill: boolean;
14
13
  };
15
14
  type Row = t;
16
- export declare function with_(e: Row, w: Optional<Row>): Row;
17
15
  export declare function from(w: Optional<Row>): Row;
18
16
  export declare function row(elements: Layout.t[], margin: Margin.t, alignment: Alignment.t, width: Width.t, is_frozen: boolean, is_fill: boolean): Row;
19
17
  export declare function copy(r: Row): Row;
20
18
  export declare function default_(): Row;
21
- export declare function instantiate(r: Row, section: Map<string, ItemContent>): Row;
22
19
  export declare function withElements(r: Row, elements: Layout.t[]): Row;
23
20
  export declare function withMargin(r: Row, margin: Margin.t): Row;
24
21
  export declare function withAlignment(r: Row, alignment: Alignment.t): Row;
package/dist/Row.js CHANGED
@@ -23,13 +23,9 @@ var __importStar = (this && this.__importStar) || function (mod) {
23
23
  return result;
24
24
  };
25
25
  Object.defineProperty(exports, "__esModule", { value: true });
26
- exports.breakLines = exports.scaleWidth = exports.boundWidth = exports.elementsWidth = exports.withFill = exports.withFrozen = exports.withWidth = exports.withAlignment = exports.withMargin = exports.withElements = exports.instantiate = exports.default_ = exports.copy = exports.row = exports.from = exports.with_ = void 0;
26
+ exports.breakLines = exports.scaleWidth = exports.boundWidth = exports.elementsWidth = exports.withFill = exports.withFrozen = exports.withWidth = exports.withAlignment = exports.withMargin = exports.withElements = exports.default_ = exports.copy = exports.row = exports.from = void 0;
27
27
  const _1 = require(".");
28
28
  const Layout = __importStar(require("./Layout"));
29
- function with_(e, w) {
30
- return { ...e, ...w };
31
- }
32
- exports.with_ = with_;
33
29
  function from(w) {
34
30
  return { ...default_(), ...w };
35
31
  }
@@ -64,10 +60,6 @@ function default_() {
64
60
  };
65
61
  }
66
62
  exports.default_ = default_;
67
- function instantiate(r, section) {
68
- return withElements(r, r.elements.map(e => Layout.instantiate(e, section)));
69
- }
70
- exports.instantiate = instantiate;
71
63
  function withElements(r, elements) {
72
64
  return {
73
65
  ...r,
package/dist/Stack.d.ts CHANGED
@@ -1,6 +1,5 @@
1
1
  import { Alignment, Layout, Margin, Width } from ".";
2
- import { Optional } from "./Elem";
3
- import { ItemContent } from "./Resume";
2
+ import { Optional } from "./Utils";
4
3
  export type t = {
5
4
  tag: "Stack";
6
5
  elements: Layout.t[];
@@ -10,12 +9,10 @@ export type t = {
10
9
  is_fill: boolean;
11
10
  };
12
11
  type Stack = t;
13
- export declare function with_(e: Stack, w: Optional<Stack>): Stack;
14
12
  export declare function from(w: Optional<Stack>): Stack;
15
13
  export declare function stack(elements: Layout.t[], margin: Margin.t, alignment: Alignment.t, width: Width.t, is_fill: boolean): Stack;
16
14
  export declare function copy(s: Stack): Stack;
17
15
  export declare function default_(): Stack;
18
- export declare function instantiate(s: Stack, section: Map<string, ItemContent>): Stack;
19
16
  export declare function withElements(s: Stack, elements: Layout.t[]): Stack;
20
17
  export declare function withMargin(s: Stack, margin: Margin.t): Stack;
21
18
  export declare function withAlignment(s: Stack, alignment: Alignment.t): Stack;
package/dist/Stack.js CHANGED
@@ -1,11 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.scaleWidth = exports.boundWidth = exports.withIsFill = exports.withWidth = exports.withAlignment = exports.withMargin = exports.withElements = exports.instantiate = exports.default_ = exports.copy = exports.stack = exports.from = exports.with_ = void 0;
3
+ exports.scaleWidth = exports.boundWidth = exports.withIsFill = exports.withWidth = exports.withAlignment = exports.withMargin = exports.withElements = exports.default_ = exports.copy = exports.stack = exports.from = void 0;
4
4
  const _1 = require(".");
5
- function with_(e, w) {
6
- return { ...e, ...w };
7
- }
8
- exports.with_ = with_;
9
5
  function from(w) {
10
6
  return { ...default_(), ...w };
11
7
  }
@@ -38,10 +34,6 @@ function default_() {
38
34
  };
39
35
  }
40
36
  exports.default_ = default_;
41
- function instantiate(s, section) {
42
- return withElements(s, s.elements.map(e => _1.Layout.instantiate(e, section)));
43
- }
44
- exports.instantiate = instantiate;
45
37
  function withElements(s, elements) {
46
38
  return {
47
39
  ...s,
@@ -0,0 +1,4 @@
1
+ export type Optional<T> = {
2
+ [P in keyof T]?: T[P];
3
+ };
4
+ export declare function with_<T>(e: T, w: Optional<T>): T;
package/dist/Utils.js ADDED
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.with_ = void 0;
4
+ function with_(e, w) {
5
+ return { ...e, ...w };
6
+ }
7
+ exports.with_ = with_;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cvdl-ts",
3
- "version": "1.0.12",
3
+ "version": "1.0.13",
4
4
  "description": "Typescript Implementation of CVDL Compiler",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -13,13 +13,19 @@
13
13
  "@types/pdfkit": "^0.13.1",
14
14
  "blob-stream": "^0.1.3",
15
15
  "fontkit": "^2.0.2",
16
- "pdfkit": "^0.13.0"
16
+ "marked": "^13.0.2",
17
+ "pdfkit": "^0.13.0",
18
+ "ts-pattern": "^5.2.0"
17
19
  },
18
20
  "devDependencies": {
21
+ "@eslint/compat": "^1.1.1",
22
+ "@eslint/js": "^9.7.0",
19
23
  "@types/node": "^20.8.7",
20
24
  "@typescript-eslint/eslint-plugin": "^6.8.0",
21
25
  "@typescript-eslint/parser": "^6.8.0",
22
- "eslint": "^8.52.0"
26
+ "eslint-plugin-react": "^7.34.4",
27
+ "globals": "^15.8.0",
28
+ "typescript-eslint": "^7.16.1"
23
29
  },
24
30
  "scripts": {
25
31
  "lint": "eslint . --ext .ts",