Skip to content

Commit

Permalink
0.2.1
Browse files Browse the repository at this point in the history
  • Loading branch information
Michael Brenan committed Mar 23, 2021
1 parent bda0583 commit ab3b2ae
Show file tree
Hide file tree
Showing 9 changed files with 60 additions and 14 deletions.
8 changes: 7 additions & 1 deletion docs/functions.md
Original file line number Diff line number Diff line change
Expand Up @@ -136,4 +136,10 @@ Convert a string to all upper case.
```
upper("Test") = "TEST"
upper("test") = "TEST"
```
```
## Utility Functions
##### `default(field, value)`
If `field` is null, return `value`; otherwise return `field`. Useful for replacing null values with defaults.
2 changes: 1 addition & 1 deletion manifest.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"id": "dataview",
"name": "Dataview",
"version": "0.2.0",
"version": "0.2.1",
"minAppVersion": "0.10.13",
"description": "Complex data views for the data-obsessed.",
"author": "Michael Brenan <[email protected]>",
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "obsidian-dataview",
"version": "0.2.0",
"version": "0.2.1",
"description": "Advanced data views for Obsidian.md.",
"main": "main.js",
"scripts": {
Expand Down
35 changes: 28 additions & 7 deletions src/eval.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ export class Context {
if (!func) return `Function ${field.func} does not exist.`;
return func(args, this);
default:
return `Cannot call field '${field.func}' as a function`;
return `Cannot call field type '${field.func}' as a function`;
}
case "index":
let obj = this.evaluate(field.object);
Expand Down Expand Up @@ -113,6 +113,9 @@ export class Context {
switch (index.value) {
case "year": return Fields.number(obj.value.year);
case "month": return Fields.number(obj.value.month);
case "weekyear": return Fields.number(obj.value.weekNumber);
case "week": return Fields.number(Math.floor(obj.value.day / 7) + 1);
case "weekday": return Fields.number(obj.value.weekday);
case "day": return Fields.number(obj.value.day);
case "hour": return Fields.number(obj.value.hour);
case "minute": return Fields.number(obj.value.minute);
Expand All @@ -125,6 +128,7 @@ export class Context {
switch (index.value) {
case "year": case "years": return Fields.number(obj.value.years);
case "month": case "months": return Fields.number(obj.value.months);
case "weeks": return Fields.number(obj.value.weeks);
case "day": case "days": return Fields.number(obj.value.days);
case "hour": case "hours": return Fields.number(obj.value.hours);
case "minute": case "minutes": return Fields.number(obj.value.minutes);
Expand Down Expand Up @@ -468,17 +472,34 @@ export const FUNCTIONS = new Map<string, FunctionImpl>()

return Fields.string(args[0].value.toLocaleUpperCase());
})
.set("sum", (args, context) => {
if (args.length != 1) return "sum(array) takes exactly 1 array argument";
if (args[0].valueType != "array") return "sum(array) takes exactly 1 array argument";

.set("default", (args, context) => {
if (args.length != 2) return "default(field, defaultvalue) requires 2 arguments";

if (args[0].valueType == 'null') return args[1];
return args[0];
})
.set("reduce", (args, context) => {
if (args.length != 2) return "reduce(array, op) takes 2 arguments";
if (args[0].valueType != "array") return "reduce(array, op) requires an array as the first argument";
if (args[1].valueType != "string") return "reduce(array, op) requires a string operator (like '+') as an argument";
if (args[0].value.length == 0) return Fields.NULL;

let op = args[1].value;
if (op != '+' && op != '-' && op != '*' && op != '/' && op != '&' && op != '|')
return "reduce(array, op) supports '+', '-', '/', '*', '&', and '|'";

let value = args[0].value[0];
for (let index = 1; index < args[0].value.length; index++) {
let next = context.evaluate(Fields.binaryOp(value, '+', args[0].value[index]));
if (typeof next == "string") continue;
let next = context.evaluate(Fields.binaryOp(value, op, args[0].value[index]));
if (typeof next == "string") return next;
value = next;
}

return value;
})
.set("sum", (args, context) => {
if (args.length != 1) return "sum(array) takes exactly 1 array argument";
if (args[0].valueType != "array") return "sum(array) takes exactly 1 array argument";

return context.evaluate(Fields.func(Fields.variable("reduce"), [args[0], Fields.string("+")]));
});
2 changes: 1 addition & 1 deletion src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export default class DataviewPlugin extends Plugin {

this.addSettingTab(new DataviewSettingsTab(this.app, this));

console.log("Dataview Plugin - Version 0.2.0 Loaded");
console.log("Dataview Plugin - Version 0.2.1 Loaded");

if (!this.workspace.layoutReady) {
this.workspace.on("layout-ready", async () => this.prepareIndexes());
Expand Down
6 changes: 4 additions & 2 deletions src/parse.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ interface ExpressionLanguage {
dateField: Field;
durationField: Field;
linkField: Field;
nullField: Field;
negatedField: Field;
atomField: Field;
indexField: Field;
Expand Down Expand Up @@ -155,7 +156,7 @@ export const EXPRESSION = P.createLanguage<ExpressionLanguage>({
identifierDot: q => P.regexp(/[\p{Letter}\p{Emoji_Presentation}][\p{Letter}\p{Emoji_Presentation}\.\w_-]*/u).desc("variable identifier"),

// An Obsidian link of the form [[<link>]].
link: q => P.regexp(/\[\[([\p{Letter}\w\s./-]+)\]\]/u, 1).desc("file link"),
link: q => P.regexp(/\[\[(.*)\]\]/u, 1).desc("file link"),

// Binary plus or minus operator.
binaryPlusMinus: q => P.regexp(/\+|-/).map(str => str as BinaryOp).desc("'+' or '-'"),
Expand Down Expand Up @@ -227,8 +228,9 @@ export const EXPRESSION = P.createLanguage<ExpressionLanguage>({
durationField: q => P.seqMap(P.string("dur("), P.optWhitespace, q.duration, P.optWhitespace, P.string(")"),
(prefix, _1, dur, _2, postfix) => Fields.literal('duration', dur))
.desc("duration"),
nullField: q => P.string("null").map(_ => Fields.NULL),
linkField: q => q.link.map(f => Fields.link(f)),
atomField: q => P.alt(q.negatedField, q.parensField, q.boolField, q.numberField, q.stringField, q.linkField, q.dateField, q.durationField, q.variableField),
atomField: q => P.alt(q.negatedField, q.parensField, q.boolField, q.numberField, q.stringField, q.linkField, q.dateField, q.durationField, q.nullField, q.variableField),
indexField: q => P.seqMap(q.atomField, P.alt(q.dotPostfix, q.indexPostfix, q.functionPostfix).many(), (obj, postfixes) => {
let result = obj;
for (let post of postfixes) {
Expand Down
7 changes: 7 additions & 0 deletions src/test/eval.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,13 @@ test("Evaluate lower()/upper()", () => {
expect(parseEval("upper(\"hello\")")).toEqual(Fields.string("HELLO"));
})

// <-- default() -->

test("Evaluate default()", () => {
expect(parseEval("default(null, 1)")).toEqual(Fields.number(1));
expect(parseEval("default(2, 1)")).toEqual(Fields.number(2));
});

/** Parse a field expression and evaluate it in the simple context. */
function parseEval(text: string): LiteralField {
let field = EXPRESSION.field.tryParse(text);
Expand Down
8 changes: 8 additions & 0 deletions src/test/parse.expression.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,14 @@ test("Parse Link", () => {
expect(EXPRESSION.field.tryParse("[[test/Main.md]]")).toEqual(Fields.link("test/Main.md"));
expect(EXPRESSION.field.tryParse("[[simple0]]")).toEqual(Fields.link("simple0"));
expect(EXPRESSION.field.tryParse("[[2020-08-15]]")).toEqual(Fields.link("2020-08-15"));
expect(EXPRESSION.field.tryParse("[[%Man & Machine + Mind%]]")).toEqual(Fields.link("%Man & Machine + Mind%"));
});

// <-- Null ->

test("Parse Null", () => {
expect(EXPRESSION.field.tryParse("null")).toEqual(Fields.NULL);
expect(EXPRESSION.field.tryParse("\"null\"")).toEqual(Fields.string("null"));
});

// <-- Indexes -->
Expand Down
4 changes: 3 additions & 1 deletion versions.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,7 @@
"0.1.8": "0.10.13",
"0.1.9": "0.10.13",
"0.1.10": "0.10.13",
"0.2.0": "0.10.13"
"0.2.0": "0.10.13",
"": "0.10.13",
"0.2.1": "0.10.13"
}

0 comments on commit ab3b2ae

Please sign in to comment.