Skip to content

Commit

Permalink
add regex support to 'with text', handle case insensitive regex (#241)
Browse files Browse the repository at this point in the history
* add regex support to 'with text', handle case insensitive regex

* 1.28.0
  • Loading branch information
mdroidian authored Mar 29, 2024
1 parent 7a40cd2 commit 4a9ed9d
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 26 deletions.
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "query-builder",
"version": "1.27.1",
"version": "1.28.0",
"description": "Introduces new user interfaces for building queries in Roam",
"main": "./build/main.js",
"author": {
Expand Down
105 changes: 82 additions & 23 deletions src/utils/conditionToDatalog.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,13 @@ type ConditionToDatalog = (condition: Condition) => DatalogClause[];

const INPUT_REGEX = /^:in /;

const isRegex = (str: string) => /^\/.+\/(i)?$/.test(str);
const regexRePatternValue = (str: string) => {
const isCaseInsensitive = str.endsWith("/i");
return isCaseInsensitive
? `"(?i)${str.slice(1, -2).replace(/\\/g, "\\\\")}"`
: `"${str.slice(1, -1).replace(/\\/g, "\\\\")}"`;
};
const getTitleDatalog = ({
source,
target,
Expand Down Expand Up @@ -100,7 +107,8 @@ const getTitleDatalog = ({
},
];
}
if (target.startsWith("/") && target.endsWith("/")) {
if (isRegex(target)) {
const rePattern = regexRePatternValue(target);
return [
{
type: "data-pattern",
Expand All @@ -116,7 +124,7 @@ const getTitleDatalog = ({
arguments: [
{
type: "constant",
value: `"${target.slice(1, -1).replace(/\\/g, "\\\\")}"`,
value: rePattern,
},
],
binding: {
Expand Down Expand Up @@ -388,37 +396,88 @@ const translator: Record<string, Translator> = {
isVariable: true,
},
"with text": {
callback: ({ source, target }) => [
{
type: "or-clause",
clauses: [
callback: ({ source, target }) => {
if (isRegex(target)) {
const rePattern = regexRePatternValue(target);
return [
{
type: "data-pattern",
type: "or-clause",
clauses: [
{
type: "data-pattern",
arguments: [
{ type: "variable", value: source },
{ type: "constant", value: ":block/string" },
{ type: "variable", value: `${source}-String` },
],
},
{
type: "data-pattern",
arguments: [
{ type: "variable", value: source },
{ type: "constant", value: ":node/title" },
{ type: "variable", value: `${source}-String` },
],
},
],
},
{
type: "fn-expr",
fn: "re-pattern",
arguments: [
{ type: "variable", value: source },
{ type: "constant", value: ":block/string" },
{
type: "constant",
value: rePattern,
},
],
binding: {
type: "bind-scalar",
variable: { type: "variable", value: `${target}-regex` },
},
},
{
type: "pred-expr",
pred: "re-find",
arguments: [
{ type: "variable", value: `${target}-regex` },
{ type: "variable", value: `${source}-String` },
],
},
];
} else {
return [
{
type: "or-clause",
clauses: [
{
type: "data-pattern",
arguments: [
{ type: "variable", value: source },
{ type: "constant", value: ":block/string" },
{ type: "variable", value: `${source}-String` },
],
},
{
type: "data-pattern",
arguments: [
{ type: "variable", value: source },
{ type: "constant", value: ":node/title" },
{ type: "variable", value: `${source}-String` },
],
},
],
},
{
type: "data-pattern",
type: "pred-expr",
pred: "clojure.string/includes?",
arguments: [
{ type: "variable", value: source },
{ type: "constant", value: ":node/title" },
{ type: "variable", value: `${source}-String` },
{ type: "constant", value: `"${normalizePageTitle(target)}"` },
],
},
],
},
{
type: "pred-expr",
pred: "clojure.string/includes?",
arguments: [
{ type: "variable", value: `${source}-String` },
{ type: "constant", value: `"${normalizePageTitle(target)}"` },
],
},
],
];
}
},
placeholder: "Enter any text",
},
"created by": {
Expand Down

0 comments on commit 4a9ed9d

Please sign in to comment.