Skip to content

Commit

Permalink
Fix loading preview; task view renders markdown; frontmatter tags
Browse files Browse the repository at this point in the history
  • Loading branch information
Michael Brenan committed Feb 6, 2021
1 parent 01b5364 commit 9da40c6
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 40 deletions.
55 changes: 39 additions & 16 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,20 +102,34 @@ export class TagIndex {

// First time load...
for (let file of vault.getMarkdownFiles()) {
let tagCache = cache.getFileCache(file).tags;
if (!tagCache) continue;

let fileCache = cache.getFileCache(file);
let allTags = new Set<string>();
for (let tag of tagCache) {
for (let subtag of this.parseSubtags(tag.tag)) {
allTags.add(subtag);

if (!initialMap.has(subtag)) initialMap.set(subtag, new Set<string>());
initialMap.get(subtag).add(file.path);
let tagCache = fileCache.tags;
if (tagCache) {
for (let tag of tagCache) {
this.parseSubtags(tag.tag).forEach(t => allTags.add(t));
for (let subtag of this.parseSubtags(tag.tag)) {
allTags.add(subtag);

}
}
}

let frontCache = fileCache.frontmatter;
if (frontCache && frontCache["tags"] && Array.isArray(frontCache["tags"])) {
for (let tag of frontCache["tags"]) {
if (!tag.startsWith("#")) tag = "#" + tag;
this.parseSubtags(tag).forEach(t => allTags.add(t));
}
}

initialInvMap.set(file.path, allTags);

for (let subtag of allTags) {
if (!initialMap.has(subtag)) initialMap.set(subtag, new Set<string>());
initialMap.get(subtag).add(file.path);
}
}

let totalTimeMs = new Date().getTime() - timeStart;
Expand Down Expand Up @@ -164,19 +178,28 @@ export class TagIndex {
async reloadFile(file: TFile) {
this.clearFile(file.path);

let tagCache = this.cache.getFileCache(file).tags;
if (!tagCache) return;

let fileCache = this.cache.getFileCache(file);
let allTags = new Set<string>();
for (let tag of tagCache) {
for (let subtag of TagIndex.parseSubtags(tag.tag)) {
allTags.add(subtag);

if (!this.map.has(subtag)) this.map.set(subtag, new Set<string>());
this.map.get(subtag).add(file.path);
if (fileCache.tags) {
for (let tag of fileCache.tags) {
TagIndex.parseSubtags(tag.tag).forEach(t => allTags.add(t));
}
}

if (fileCache.frontmatter && fileCache.frontmatter["tags"]
&& Array.isArray(fileCache.frontmatter["tags"])) {
for (let tag of fileCache.frontmatter["tags"]) {
if (!tag.startsWith("#")) tag = "#" + tag;
TagIndex.parseSubtags(tag).forEach(t => allTags.add(t));
}
}

for (let subtag of allTags) {
if (!this.map.has(subtag)) this.map.set(subtag, new Set<string>());
this.map.get(subtag).add(file.path);
}

this.invMap.set(file.path, allTags);
}

Expand Down
47 changes: 30 additions & 17 deletions src/main.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { MarkdownRenderChild, Plugin, Workspace, Vault } from 'obsidian';
import { MarkdownRenderChild, Plugin, Workspace, Vault, MarkdownPostProcessorContext } from 'obsidian';
import { createAnchor, prettifyYamlKey, renderErrorPre, renderList, renderTable } from './render';
import { FullIndex, TaskCache } from './index';
import * as Tasks from './tasks';
Expand All @@ -19,8 +19,10 @@ export default class DataviewPlugin extends Plugin {
async onload() {
this.settings = Object.assign(DEFAULT_SETTINGS, await this.loadData());
this.workspace = this.app.workspace;
this.index = null;
this.tasks = null;

console.log("Dataview Plugin - Version 0.1.0 Loaded");
console.log("Dataview Plugin - Version 0.1.2 Loaded");

if (!this.workspace.layoutReady) {
this.workspace.on("layout-ready", async () => this.prepareIndexes());
Expand Down Expand Up @@ -50,13 +52,13 @@ export default class DataviewPlugin extends Plugin {

switch (query.type) {
case 'task':
ctx.addChild(this.wrapWithEnsureTaskIndex(el, () => new DataviewTaskRenderer(query as Query, el, this.index, this.tasks, this.app.vault)));
ctx.addChild(this.wrapWithEnsureTaskIndex(ctx, el, () => new DataviewTaskRenderer(query as Query, el, this.index, this.tasks, this.app.vault)));
break;
case 'list':
ctx.addChild(this.wrapWithEnsureIndex(el, () => new DataviewListRenderer(query as Query, el, this.index)));
ctx.addChild(this.wrapWithEnsureIndex(ctx, el, () => new DataviewListRenderer(query as Query, el, this.index)));
break;
case 'table':
ctx.addChild(this.wrapWithEnsureIndex(el, () => new DataviewTableRenderer(query as Query, el, this.index)));
ctx.addChild(this.wrapWithEnsureIndex(ctx, el, () => new DataviewTableRenderer(query as Query, el, this.index)));
break;
}
});
Expand All @@ -73,15 +75,13 @@ export default class DataviewPlugin extends Plugin {
this.index.on("reload", file => this.tasks.reloadFile(file));
}

wrapWithEnsureIndex(container: HTMLElement, success: () => MarkdownRenderChild): EnsurePredicateRenderer {
return new EnsurePredicateRenderer(container,
el => this.index !== null || this.index !== undefined,
success);
wrapWithEnsureIndex(ctx: MarkdownPostProcessorContext, container: HTMLElement, success: () => MarkdownRenderChild): EnsurePredicateRenderer {
return new EnsurePredicateRenderer(ctx, container, () => this.index != null, success);
}

wrapWithEnsureTaskIndex(container: HTMLElement, success: () => MarkdownRenderChild): EnsurePredicateRenderer {
return new EnsurePredicateRenderer(container,
el => (this.index !== null || this.index !== undefined) && (this.tasks !== null || this.tasks !== undefined),
wrapWithEnsureTaskIndex(ctx: MarkdownPostProcessorContext, container: HTMLElement, success: () => MarkdownRenderChild): EnsurePredicateRenderer {
return new EnsurePredicateRenderer(ctx, container,
() => (this.index != null) && (this.tasks != null),
success);
}
}
Expand All @@ -90,26 +90,39 @@ export default class DataviewPlugin extends Plugin {
class EnsurePredicateRenderer extends MarkdownRenderChild {
static CHECK_INTERVAL_MS = 1_000;

update: (container: HTMLElement) => boolean;
update: () => boolean;
success: () => MarkdownRenderChild;

ctx: MarkdownPostProcessorContext;
dead: boolean;
container: HTMLElement;

constructor(container: HTMLElement, update: (container: HTMLElement) => boolean, success: () => MarkdownRenderChild) {
constructor(ctx: MarkdownPostProcessorContext,
container: HTMLElement,
update: () => boolean,
success: () => MarkdownRenderChild) {
super();

this.ctx = ctx;
this.container = container;
this.update = update;
this.success = success;
this.dead = false;
}

async onload() {
let loadContainer = renderErrorPre(this.container, "Dataview indices are loading");

// Wait for the given predicate to finally pass...
await waitFor(EnsurePredicateRenderer.CHECK_INTERVAL_MS, () => this.update(this.container), () => this.dead);
await waitFor(EnsurePredicateRenderer.CHECK_INTERVAL_MS,
() => { loadContainer.innerText += "."; return this.update(); },
() => this.dead);

// Clear the container before passing it off to the child.
this.container.innerHTML = "";

// And then pass off rendering to a child context.
this.addChild(this.success());
this.ctx.addChild(this.success());
}

onunload() {
Expand Down Expand Up @@ -198,7 +211,7 @@ class DataviewTaskRenderer extends MarkdownRenderChild {
this.vault = vault;
}

onload() {
async onload() {
let result = executeTask(this.query, this.index, this.tasks);
if (typeof result === 'string') {
renderErrorPre(this.container, "Dataview: " + result);
Expand Down
23 changes: 16 additions & 7 deletions src/tasks.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Vault, App, TFile, MarkdownRenderChild } from 'obsidian';
import { Vault, App, TFile, MarkdownRenderChild, MarkdownRenderer } from 'obsidian';
import { createAnchor } from './render';

/**
Expand Down Expand Up @@ -105,31 +105,40 @@ export async function findTasksInFile(vault: Vault, file: TFile): Promise<Task[]
}

/** Render tasks from multiple files. */
export function renderFileTasks(container: HTMLElement, tasks: Map<string, Task[]>) {
export async function renderFileTasks(container: HTMLElement, tasks: Map<string, Task[]>) {
for (let path of tasks.keys()) {
let basepath = path.replace(".md", "");

let header = container.createEl('h4');
header.appendChild(createAnchor(basepath, basepath, true));
let div = container.createDiv();

renderTasks(div, path, tasks.get(path));
await renderTasks(div, path, tasks.get(path));
}
}

/** Render a list of tasks as a single list. */
export function renderTasks(container: HTMLElement, path: string, tasks: Task[]) {
export async function renderTasks(container: HTMLElement, path: string, tasks: Task[]) {
let ul = container.createEl('ul', { cls: 'contains-task-list' });
for (let task of tasks) {
let li = ul.createEl('li', { cls: 'task-list-item' });
let check = createCheckbox(path, task.line, task.text, task.completed);

if (task.completed) {
li.addClass('is-checked');
}

li.appendChild(check);
li.insertAdjacentText("beforeend", task.text);
// Render the text as markdown so that bolds, links, and other things work properly.
await MarkdownRenderer.renderMarkdown(task.text, li, path, null);

// Unwrap the paragraph element that is created.
let paragraph = li.querySelector("p");
if (paragraph) {
li.innerHTML = paragraph.innerHTML;
paragraph.remove();
}

let check = createCheckbox(path, task.line, task.text, task.completed);
li.prepend(check);

if (task.subtasks.length > 0) {
renderTasks(li, path, task.subtasks);
Expand Down

0 comments on commit 9da40c6

Please sign in to comment.