Skip to content

Commit c21e6f3

Browse files
committed
moved things, mb table and tests
1 parent 4454f9a commit c21e6f3

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+718
-137
lines changed

exampleVault/Advanced Examples/PF2e Encounter Calculator.md

Lines changed: 66 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,27 @@
11
---
22
playerCount: 6
3-
playerLevel: 2
3+
playerLevel: 4
44
enemy:
5-
- name: Something
6-
level: 3
5+
- name: Someting
6+
level: 4
77
count: 1
8+
variant: 0
89
- name: Some other thing
10+
level: 2
11+
count: 1
12+
variant: 0
13+
- name: dragon
14+
level: 2
15+
count: 2
16+
variant: -1
17+
- name: test
918
level: 1
1019
count: 1
11-
- name: ""
12-
level: 0
13-
count: 0
14-
- name: ""
15-
level: 0
16-
count: 0
17-
- name: ""
18-
level: 0
19-
count: 0
20+
variant: 0
21+
test:
22+
- a
23+
- b
24+
- c
2025
---
2126

2227

@@ -28,14 +33,60 @@ Player Level: `INPUT[number:playerLevel]`
2833

2934
### Enemies
3035

31-
| Name | Level | Count |
36+
%% | Name | Level | Count |
3237
| --------------------------- | ---------------------------- | ---------------------------- |
3338
| `INPUT[text:enemy[0].name]` | `INPUT[number:enemy[0].level]` | `INPUT[number:enemy[0].count]` |
3439
| `INPUT[text:enemy[1].name]` | `INPUT[number:enemy[1].level]` | `INPUT[number:enemy[1].count]` |
3540
| `INPUT[text:enemy[2].name]` | `INPUT[number:enemy[2].level]` | `INPUT[number:enemy[2].count]` |
3641
| `INPUT[text:enemy[3].name]` | `INPUT[number:enemy[3].level]` | `INPUT[number:enemy[3].count]` |
3742
| `INPUT[text:enemy[4].name]` | `INPUT[number:enemy[4].level]` | `INPUT[number:enemy[4].count]` |
3843

44+
```js
45+
const mb = engine.getPlugin('obsidian-meta-bind-plugin').api;
46+
47+
function render(enemies) {
48+
const md = engine.markdown.createBuilder();
49+
md.createTable(
50+
['Name', 'Level', 'Count'],
51+
enemies.map((x, i) => {
52+
return [
53+
`\`INPUT[text:enemy[${i}].name]\``,
54+
`\`INPUT[text:enemy[${i}].level]\``,
55+
`\`INPUT[text:enemy[${i}].count]\``
56+
]
57+
})
58+
);
59+
return md;
60+
}
61+
62+
const signal = mb.createSignal([]);
63+
const unregisterCb = mb.listenToMetadata(signal, context.file.path, ['enemy'], false);
64+
65+
const reactive = engine.reactive(render, signal.get());
66+
67+
component.register(unregisterCb);
68+
69+
return reactive;
70+
```
71+
%%
72+
73+
74+
```js-engine
75+
const mb = engine.getPlugin('obsidian-meta-bind-plugin').api;
76+
77+
const bindTarget = mb.createBindTarget('enemy');
78+
const tableHead = ['Name', 'Level', 'Variant', 'Count'];
79+
const columns = [
80+
mb.inputField.createInputFieldDeclarationFromString('INPUT[text:^.name]'),
81+
mb.inputField.createInputFieldDeclarationFromString('INPUT[number:^.level]'),
82+
mb.inputField.createInputFieldDeclarationFromString('INPUT[inlineSelect(option(-1, weak), option(0, normal), option(1, elite)):^.variant]'),
83+
mb.inputField.createInputFieldDeclarationFromString('INPUT[number:^.count]')
84+
];
85+
86+
mb.createTable(container, context.file.path, component, bindTarget, tableHead, columns);
87+
```
88+
89+
3990
### Encounter Stats
4091

4192
```meta-bind-js-view
@@ -79,11 +130,11 @@ function getXP(enemyLevel) {
79130
function calculateTotalXP() {
80131
let acc = 0;
81132
for (const enemy of context.enemies) {
82-
const xp = getXP(enemy.level);
133+
const xp = getXP((enemy.level ?? 0) + (enemy.variant ?? 0));
83134
if (xp === -1) {
84135
return -1;
85136
}
86-
acc += xp * enemy.count;
137+
acc += xp * (enemy.count ?? 0);
87138
}
88139
return acc;
89140
}

jest.config.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@ module.exports = {
33
testEnvironment: 'jsdom',
44
moduleDirectories: ['node_modules', 'src'],
55
verbose: true,
6+
setupFilesAfterEnv: ['<rootDir>/tests/CustomMatchers/jest.custom_matchers.setup.ts'],
67
};

package-lock.json

Lines changed: 6 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545
},
4646
"dependencies": {
4747
"@codemirror/language": "https://github.com/lishid/cm-language",
48-
"@lemons_dev/parsinom": "^0.0.8",
48+
"@lemons_dev/parsinom": "^0.0.9",
4949
"@opd-libs/opd-metadata-lib": "0.0.4",
5050
"@opd-libs/opd-utils-lib": "0.0.2",
5151
"@popperjs/core": "^2.11.8",

src/api/API.ts

Lines changed: 56 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,28 @@
11
import { InputFieldMDRC, RenderChildType } from '../renderChildren/InputFieldMDRC';
2-
import { JsViewFieldDeclaration, ViewFieldDeclaration, ViewFieldDeclarationParser } from '../parsers/ViewFieldDeclarationParser';
2+
import {
3+
JsViewFieldDeclaration,
4+
UnvalidatedViewFieldDeclaration,
5+
ViewFieldDeclaration,
6+
ViewFieldDeclarationParser,
7+
} from '../parsers/ViewFieldDeclarationParser';
38
import { BindTargetParser } from '../parsers/BindTargetParser';
49
import { ViewFieldMDRC } from '../renderChildren/ViewFieldMDRC';
510
import { JsViewFieldMDRC } from '../renderChildren/JsViewFieldMDRC';
611
import MetaBindPlugin from '../main';
7-
import { NewInputFieldDeclarationParser } from '../parsers/newInputFieldParser/InputFieldParser';
12+
import { InputFieldDeclarationParser } from '../parsers/inputFieldParser/InputFieldParser';
813
import { Component, MarkdownPostProcessorContext } from 'obsidian';
914
import { InputFieldAPI } from './InputFieldAPI';
1015
import { IAPI } from './IAPI';
1116
import { ExcludedMDRC } from '../renderChildren/ExcludedMDRC';
12-
import { InputFieldDeclaration, UnvalidatedInputFieldDeclaration } from '../parsers/newInputFieldParser/InputFieldDeclaration';
17+
import { BindTargetDeclaration, InputFieldDeclaration, UnvalidatedInputFieldDeclaration } from '../parsers/inputFieldParser/InputFieldDeclaration';
18+
import { Signal } from '../utils/Signal';
19+
import { BindTargetScope } from '../metadata/BindTargetScope';
20+
import { MetaBindTable } from '../metaBindTable/MetaBindTable';
1321

1422
export class API implements IAPI {
1523
public plugin: MetaBindPlugin;
1624
// public inputFieldParser: InputFieldDeclarationParser;
17-
public readonly newInputFieldParser: NewInputFieldDeclarationParser;
25+
public readonly inputFieldParser: InputFieldDeclarationParser;
1826
public readonly viewFieldParser: ViewFieldDeclarationParser;
1927
public readonly bindTargetParser: BindTargetParser;
2028

@@ -24,7 +32,7 @@ export class API implements IAPI {
2432
this.plugin = plugin;
2533

2634
// this.inputFieldParser = new InputFieldDeclarationParser();
27-
this.newInputFieldParser = new NewInputFieldDeclarationParser(this.plugin);
35+
this.inputFieldParser = new InputFieldDeclarationParser(this.plugin);
2836
this.viewFieldParser = new ViewFieldDeclarationParser(this.plugin);
2937
this.bindTargetParser = new BindTargetParser(this.plugin);
3038

@@ -42,7 +50,7 @@ export class API implements IAPI {
4250
return this.createExcludedField(containerEl, filePath, component);
4351
}
4452

45-
const declaration = this.newInputFieldParser.validateDeclaration(unvalidatedDeclaration);
53+
const declaration = this.inputFieldParser.validateDeclaration(unvalidatedDeclaration);
4654

4755
const inputField = new InputFieldMDRC(containerEl, renderType, declaration, this.plugin, filePath, self.crypto.randomUUID());
4856
component.addChild(inputField);
@@ -55,13 +63,14 @@ export class API implements IAPI {
5563
renderType: RenderChildType,
5664
filePath: string,
5765
containerEl: HTMLElement,
58-
component: Component | MarkdownPostProcessorContext
66+
component: Component | MarkdownPostProcessorContext,
67+
scope: BindTargetScope
5968
): InputFieldMDRC | ExcludedMDRC {
6069
if (this.plugin.isFilePathExcluded(filePath)) {
6170
return this.createExcludedField(containerEl, filePath, component);
6271
}
6372

64-
const declaration: InputFieldDeclaration = this.newInputFieldParser.parseString(fullDeclaration);
73+
const declaration: InputFieldDeclaration = this.inputFieldParser.parseString(fullDeclaration);
6574

6675
const inputField = new InputFieldMDRC(containerEl, renderType, declaration, this.plugin, filePath, self.crypto.randomUUID());
6776
component.addChild(inputField);
@@ -113,4 +122,43 @@ export class API implements IAPI {
113122

114123
return excludedField;
115124
}
125+
126+
public createSignal<T>(value: T): Signal<T> {
127+
return new Signal<T>(value);
128+
}
129+
130+
/**
131+
* Registers a signal to a metadata property and returns a callback to unregister.
132+
*
133+
* @param signal
134+
* @param filePath
135+
* @param metadataPath
136+
* @param listenToChildren
137+
*/
138+
public listenToMetadata(signal: Signal<unknown>, filePath: string, metadataPath: string[], listenToChildren: boolean = false): () => void {
139+
const uuid = self.crypto.randomUUID();
140+
this.plugin.metadataManager.register(filePath, signal, metadataPath, listenToChildren, uuid);
141+
142+
return () => {
143+
this.plugin.metadataManager.unregister(filePath, uuid);
144+
};
145+
}
146+
147+
public createTable(
148+
containerEl: HTMLElement,
149+
filePath: string,
150+
component: Component | MarkdownPostProcessorContext,
151+
bindTarget: BindTargetDeclaration,
152+
tableHead: string[],
153+
columns: (UnvalidatedInputFieldDeclaration | UnvalidatedViewFieldDeclaration)[]
154+
): MetaBindTable {
155+
const table = new MetaBindTable(containerEl, RenderChildType.INLINE, this.plugin, filePath, self.crypto.randomUUID(), bindTarget, tableHead, columns);
156+
component.addChild(table);
157+
158+
return table;
159+
}
160+
161+
public createBindTarget(fullDeclaration: string): BindTargetDeclaration {
162+
return this.bindTargetParser.parseAndValidateBindTarget(fullDeclaration);
163+
}
116164
}

src/api/IAPI.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
import { NewInputFieldDeclarationParser } from '../parsers/newInputFieldParser/InputFieldParser';
1+
import { InputFieldDeclarationParser } from '../parsers/inputFieldParser/InputFieldParser';
22
import { ViewFieldDeclarationParser } from '../parsers/ViewFieldDeclarationParser';
33
import { BindTargetParser } from '../parsers/BindTargetParser';
44
import { IPlugin } from '../IPlugin';
55
import { InputFieldAPI } from './InputFieldAPI';
66

77
export interface IAPI {
88
readonly plugin: IPlugin;
9-
readonly newInputFieldParser: NewInputFieldDeclarationParser;
9+
readonly inputFieldParser: InputFieldDeclarationParser;
1010
readonly viewFieldParser: ViewFieldDeclarationParser;
1111
readonly bindTargetParser: BindTargetParser;
1212
readonly inputField: InputFieldAPI;

src/api/InputFieldAPI.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import {
55
UnvalidatedBindTargetDeclaration,
66
UnvalidatedInputFieldArgument,
77
UnvalidatedInputFieldDeclaration,
8-
} from '../parsers/newInputFieldParser/InputFieldDeclaration';
8+
} from '../parsers/inputFieldParser/InputFieldDeclaration';
99
import { InputFieldArgumentType, InputFieldType } from '../inputFields/InputFieldConfigs';
1010

1111
export class InputFieldAPI {
@@ -36,7 +36,7 @@ export class InputFieldAPI {
3636
}
3737

3838
public createInputFieldDeclarationFromString(fullDeclaration: string): UnvalidatedInputFieldDeclaration {
39-
return this.api.newInputFieldParser.parseStringWithoutValidation(fullDeclaration);
39+
return this.api.inputFieldParser.parseStringWithoutValidation(fullDeclaration);
4040
}
4141

4242
public setType(unvalidatedDeclaration: UnvalidatedInputFieldDeclaration, inputFieldType: InputFieldType): UnvalidatedInputFieldDeclaration {
@@ -82,7 +82,7 @@ export class InputFieldAPI {
8282
if (unvalidatedDeclaration.bindTarget) {
8383
unvalidatedDeclaration.bindTarget.file = { value: bindTargetFile };
8484
} else {
85-
unvalidatedDeclaration.bindTarget = { file: { value: bindTargetFile }, path: [] };
85+
unvalidatedDeclaration.bindTarget = { file: { value: bindTargetFile }, path: [], boundToLocalScope: false };
8686
}
8787

8888
return unvalidatedDeclaration;
@@ -99,7 +99,7 @@ export class InputFieldAPI {
9999
if (unvalidatedDeclaration.bindTarget) {
100100
unvalidatedDeclaration.bindTarget.path = bindTargetMetadataField.map(x => ({ value: x }));
101101
} else {
102-
unvalidatedDeclaration.bindTarget = { file: undefined, path: bindTargetMetadataField.map(x => ({ value: x })) };
102+
unvalidatedDeclaration.bindTarget = { file: undefined, path: bindTargetMetadataField.map(x => ({ value: x })), boundToLocalScope: false };
103103
}
104104

105105
return unvalidatedDeclaration;
@@ -111,11 +111,11 @@ export class InputFieldAPI {
111111
}
112112

113113
public applyTemplate(unvalidatedDeclaration: UnvalidatedInputFieldDeclaration): UnvalidatedInputFieldDeclaration {
114-
return this.api.newInputFieldParser.applyTemplate(unvalidatedDeclaration);
114+
return this.api.inputFieldParser.applyTemplate(unvalidatedDeclaration);
115115
}
116116

117117
public getTemplate(templateName: string): Readonly<UnvalidatedInputFieldDeclaration> | undefined {
118-
return this.api.newInputFieldParser.getTemplate(templateName);
118+
return this.api.inputFieldParser.getTemplate(templateName);
119119
}
120120

121121
public merge(unvalidatedDeclaration: UnvalidatedInputFieldDeclaration, override: UnvalidatedInputFieldDeclaration): UnvalidatedInputFieldDeclaration {

src/inputFieldArguments/AbstractInputFieldArgument.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { ErrorLevel, MetaBindArgumentError } from '../utils/errors/MetaBindErrors';
2-
import { ParsingResultNode } from '../parsers/newInputFieldParser/InputFieldParser';
2+
import { ParsingResultNode } from '../parsers/inputFieldParser/InputFieldParser';
33
import { InputFieldArgumentConfig, InputFieldArgumentValueConfig, InputFieldType } from '../inputFields/InputFieldConfigs';
44

55
export abstract class AbstractInputFieldArgument {
@@ -34,7 +34,9 @@ export abstract class AbstractInputFieldArgument {
3434
return true;
3535
}
3636

37-
return this.getConfig().allowedInputFieldTypes.contains(inputFieldType);
37+
console.log(this.getConfig().allowedInputFieldTypes);
38+
39+
return this.getConfig().allowedInputFieldTypes.includes(inputFieldType);
3840
}
3941

4042
getAllowedInputFieldsAsString(): string {

src/inputFieldArguments/arguments/AddLabelsInputFieldArgument.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { AbstractInputFieldArgument } from '../AbstractInputFieldArgument';
2-
import { ParsingResultNode } from '../../parsers/newInputFieldParser/InputFieldParser';
2+
import { ParsingResultNode } from '../../parsers/inputFieldParser/InputFieldParser';
33
import { InputFieldArgumentConfig, InputFieldArgumentConfigs, InputFieldArgumentType, InputFieldType } from '../../inputFields/InputFieldConfigs';
44

55
export class AddLabelsInputFieldArgument extends AbstractInputFieldArgument {

src/inputFieldArguments/arguments/ClassInputFieldArgument.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { AbstractInputFieldArgument } from '../AbstractInputFieldArgument';
22

3-
import { ParsingResultNode } from '../../parsers/newInputFieldParser/InputFieldParser';
3+
import { ParsingResultNode } from '../../parsers/inputFieldParser/InputFieldParser';
44
import { InputFieldArgumentConfig, InputFieldArgumentConfigs, InputFieldArgumentType, InputFieldType } from '../../inputFields/InputFieldConfigs';
55

66
export class ClassInputFieldArgument extends AbstractInputFieldArgument {

0 commit comments

Comments
 (0)