Implemented queries for tables (#729)

pull/744/head
Michael Kolb 2024-02-23 10:18:47 +01:00 committed by GitHub
parent aaad3dbf0a
commit 4056c4f2f2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 117 additions and 20 deletions

View File

@ -25,11 +25,11 @@ functions:
objectSourceProvider:
path: api.ts:objectSourceProvider
events:
- query:*
- query:*
discoverSources:
path: api.ts:discoverSources
events:
- query_
- query_
clearIndex:
path: api.ts:clearIndex
env: server
@ -40,7 +40,7 @@ functions:
events:
- page:saved
- page:deleted
parseIndexTextRepublish:
path: "./command.ts:parseIndexTextRepublish"
env: server
@ -55,9 +55,9 @@ functions:
processIndexQueue:
path: ./command.ts:processIndexQueue
mqSubscriptions:
- queue: indexQueue
batchSize: 10
autoAck: true
- queue: indexQueue
batchSize: 10
autoAck: true
reindexSpace:
path: "./command.ts:reindexSpace"
env: server
@ -70,45 +70,51 @@ functions:
indexParagraphs:
path: "./paragraph.ts:indexParagraphs"
events:
- page:index
- page:index
# Backlinks
indexLinks:
path: "./page_links.ts:indexLinks"
events:
- page:index
- page:index
attributeComplete:
path: "./attributes.ts:attributeComplete"
events:
- editor:complete
- editor:complete
objectAttributeCompleter:
path: ./attributes.ts:objectAttributeCompleter
events:
- attribute:complete:*
- attribute:complete:*
# Item indexing
indexItem:
path: "./item.ts:indexItems"
events:
- page:index
- page:index
# Anchors
indexAnchors:
path: "./anchor.ts:indexAnchors"
events:
- page:index
- page:index
anchorComplete:
path: "./anchor.ts:anchorComplete"
events:
- editor:complete
# Tables
indexTables:
path: "table.ts:indexTables"
events:
- page:index
# Headers
indexHeaders:
path: header.ts:indexHeaders
events:
- page:index
- page:index
headerComplete:
path: header.ts:headerComplete
events:
@ -118,20 +124,19 @@ functions:
indexData:
path: data.ts:indexData
events:
- page:index
- page:index
# Script
indexSpaceScript:
path: script.ts:indexSpaceScript
events:
- page:index
- page:index
# Hashtags
indexTags:
path: tags.ts:indexTags
events:
- page:index
- page:index
tagComplete:
path: tags.ts:tagComplete
events:
@ -181,7 +186,7 @@ functions:
lintYAML:
path: lint.ts:lintYAML
events:
- editor:lint
- editor:lint
# Tag file system
readFileTag:
@ -205,9 +210,9 @@ functions:
syscallSourceProvider:
path: builtins.ts:syscallSourceProvider
events:
- query:syscall
- query:syscall
commandSourceProvider:
path: builtins.ts:commandSourceProvider
events:
- query:command
- query:command

76
plugs/index/table.ts Normal file
View File

@ -0,0 +1,76 @@
import { CompleteEvent, IndexTreeEvent, ObjectValue } from "$type/types.ts";
import { collectNodesMatching, ParseTree } from "$lib/tree.ts";
import { indexObjects } from "./api.ts";
import { collectNodesOfType } from "$lib/tree.ts";
type TableRowObject =
& ObjectValue<{
tableref: string;
page: string;
pos: number;
}>
& Record<string, any>;
/**
* Replace any invalid characters in a string so it can serve as indexed field name in a query
* @param str the input string
* @returns All lowercase string with special chars replaced with underscore
*/
function cleanHeaderFieldName(str: string): string {
return str.replace(/[\W_]+/g, "_").toLowerCase();
}
/**
* Concat text properties of all child nodes
* @param nodes
* @returns
*/
function concatChildrenTexts(nodes: ParseTree[]): string {
return nodes.map((c) => c.text).join("").trim();
}
export async function indexTables({ name: pageName, tree }: IndexTreeEvent) {
console.log(`Indexing tables in '${pageName}'`);
const result: ObjectValue<TableRowObject>[] = [];
collectNodesMatching(tree, (t) => !!t.type?.startsWith("Table")).forEach(
(table) => {
const rows = collectNodesOfType(table, "TableRow");
const header = collectNodesOfType(table, "TableHeader")[0]; //Use first header. As per markdown spec there can only be exactly one
const headerLabels = collectNodesOfType(header, "TableCell").map((cell) =>
concatChildrenTexts(cell.children!)
).map(cleanHeaderFieldName);
//console.log("Header labels", headerLabels);
for (const row of rows) {
const tags = new Set<string>();
collectNodesOfType(row, "Hashtag").forEach((h) => {
// Push tag to the list, removing the initial #
tags.add(h.children![0].text!.substring(1));
});
const cells = collectNodesOfType(row, "TableCell");
const tableRow: TableRowObject = {
tableref: `${pageName}@${table.from}`,
ref: `${pageName}@${row.from}`,
tag: "table",
tags: [...tags],
page: pageName,
pos: row.from!,
};
cells.forEach((c, i) => {
const content = concatChildrenTexts(c.children!);
const label = headerLabels[i];
tableRow[label!] = content;
});
result.push(tableRow);
//console.log("Cells", cells);
}
},
);
console.log("Found", result.length, "row(s)");
await indexObjects(pageName, result);
}

View File

@ -37,6 +37,22 @@ Note that you can also query this page using the `example-tag` directly:
example-tag
```
## table
Markdown table rows are indexed using the `table` tag, any additional tags can be added using [[Tags]] in any of its cells.
| Title | Description Text |
| --- | ----- |
| This is some key | The value contains a #table-tag |
| Some Row | This is an example row in between two others |
| Another key | This time without a tag |
```query
table
```
Table headers will be normalized by converting them to lowercase and replacing all non alphanumeric characters with `_`.
## task
task