Skip to content

Commit bea5288

Browse files
Allow rawCharacters to be passed as a string so we can access props (#39)
* Allow rawCharacters to be passed as a string so we can access props * Add error handling for parsing
1 parent e4f583b commit bea5288

4 files changed

Lines changed: 46 additions & 6 deletions

File tree

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@vestaboard/vbml",
3-
"version": "1.3.1",
3+
"version": "1.3.2",
44
"description": "The Vestaboard markup language",
55
"main": "lib/index.js",
66
"scripts": {

src/__tests__/parseComponent.spec.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -471,6 +471,36 @@ describe("Parse Component", () => {
471471
]);
472472
});
473473

474+
it("Should parse a raw component string with inline prop interpolation", () => {
475+
const input: IVBMLComponent = {
476+
rawCharacters: "[[{{a}},{{b}}]]",
477+
};
478+
const result = parseComponent(3, 12, { a: 1, b: 2 })(input);
479+
expect(result).toEqual([[1, 2]]);
480+
});
481+
482+
it("Should parse a raw component string where the grid comes from a prop", () => {
483+
const input: IVBMLComponent = {
484+
rawCharacters: "{{grid}}",
485+
};
486+
const result = parseComponent(3, 12, { grid: "[[1,2],[3,4]]" })(input);
487+
expect(result).toEqual([
488+
[1, 2],
489+
[3, 4],
490+
]);
491+
});
492+
493+
it("Should parse a raw component passed as a JSON string", () => {
494+
const input: IVBMLComponent = {
495+
rawCharacters: "[[1,2],[3,4]]",
496+
};
497+
const result = parseComponent(3, 12)(input);
498+
expect(result).toEqual([
499+
[1, 2],
500+
[3, 4],
501+
]);
502+
});
503+
474504
it("Should convert emoji characters to character codes", () => {
475505
const input: IVBMLComponent = {
476506
template: "🟥🟧🟨🟩🟦🟪⬜⬛",

src/parseComponent.ts

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,17 @@ import { verticalAlign } from "./verticalAlign";
1717
export const parseComponent =
1818
(defaultHeight: number, defaultWidth: number, props?: VBMLProps) =>
1919
(component: IVBMLComponent) => {
20-
if ("rawCharacters" in component) return component.rawCharacters;
20+
if ("rawCharacters" in component) {
21+
const raw = component.rawCharacters;
22+
if (typeof raw === "string") {
23+
try {
24+
return JSON.parse(parseProps(props || {})(raw)) as number[][];
25+
} catch (e) {
26+
return [[]]; // Return an empty board if parsing fails
27+
}
28+
}
29+
return raw;
30+
}
2131

2232
const width = component?.style?.width || defaultWidth;
2333
const height = component?.style?.height || defaultHeight;
@@ -27,7 +37,7 @@ export const parseComponent =
2737
return randomColors(
2838
component?.style?.height || height,
2939
component?.style?.width || width,
30-
colors
40+
colors,
3141
);
3242
}
3343

@@ -44,7 +54,7 @@ export const parseComponent =
4454
map(convertCharactersToCharacterCodes),
4555
verticalAlign(height, component?.style?.align || Align.top),
4656
horizontalAlign(width, component?.style?.justify || Justify.left),
47-
renderComponent(emptyComponent)
57+
renderComponent(emptyComponent),
4858
)(template) as number[][];
4959
};
5060

@@ -55,7 +65,7 @@ export const parseAbsoluteComponent =
5565
characters: parseComponent(
5666
defaultHeight,
5767
defaultWidth,
58-
props
68+
props,
5969
)(component) as number[][],
6070
x: component.style?.absolutePosition?.x || 0,
6171
y: component.style?.absolutePosition?.y || 0,

src/types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ export interface VBMLProps {
3737

3838
export interface IVBMLRawComponent {
3939
style?: IComponentStyle;
40-
rawCharacters?: number[][];
40+
rawCharacters?: number[][] | string;
4141
}
4242

4343
export interface IVBMLCalendarComponent {

0 commit comments

Comments
 (0)