Skip to content

Commit

Permalink
(FQ) Links Rendering in Graph View #49
Browse files Browse the repository at this point in the history
Began adding markdown postprocessor to remove codeblock dependency
  • Loading branch information
valentine195 committed Jun 21, 2021
1 parent 0a9c678 commit c2359dc
Show file tree
Hide file tree
Showing 3 changed files with 289 additions and 10 deletions.
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,11 @@
"@rollup/plugin-commonjs": "^15.1.0",
"@rollup/plugin-node-resolve": "^9.0.0",
"@rollup/plugin-typescript": "^6.0.0",
"@types/html": "^1.0.0",
"@types/node": "^14.14.2",
"@types/object.fromentries": "^2.0.0",
"html": "^1.0.0",
"nanoid": "^3.1.23",
"object.fromentries": "^2.0.4",
"obsidian": "https://github.com/obsidianmd/obsidian-api/tarball/master",
"rollup": "^2.32.1",
Expand Down
182 changes: 175 additions & 7 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,13 @@ import {
Plugin,
TFile
} from "obsidian";
import { prettyPrint as html } from "html";

import { Admonition, ObsidianAdmonitionPlugin, ISettingsData } from "./@types";
import {
getAdmonitionElement,
getAdmonitionElementAsync,
getID,
getMatches,
getParametersFromSource
} from "./util";
Expand Down Expand Up @@ -82,9 +86,8 @@ export default class ObsidianAdmonition
implements ObsidianAdmonitionPlugin
{
admonitions: { [admonitionType: string]: Admonition } = {};
/* userAdmonitions: { [admonitionType: string]: Admonition } = {};
syntaxHighlight: boolean; */
data: ISettingsData;
contextMap: Map<string, MarkdownPostProcessorContext> = new Map();
get types() {
return Object.keys(this.admonitions);
}
Expand Down Expand Up @@ -179,6 +182,115 @@ export default class ObsidianAdmonition
addIcon(ADD_COMMAND_NAME.toString(), ADD_ADMONITION_COMMAND_ICON);
addIcon(REMOVE_COMMAND_NAME.toString(), REMOVE_ADMONITION_COMMAND_ICON);

const TYPE_REGEX = new RegExp(
`(!{3,}|\\?{3,}\\+?) ad-(${this.types.join("|")})`
);
const END_REGEX = new RegExp(`\\-{3,} admonition`);

let push = false,
id: string;
const elementMap: Map<
MarkdownRenderChild,
{ contentEl: HTMLElement; elements: Element[]; loaded: boolean }
> = new Map();
const childMap: Map<string, MarkdownRenderChild> = new Map();
this.registerMarkdownPostProcessor(async (el, ctx) => {
if (END_REGEX.test(el.textContent) && push) {
push = false;
el.children[0].detach();
return;
}
if (!TYPE_REGEX.test(el.textContent) && !push) return;

if (!push) {
push = true;
let child = new MarkdownRenderChild(el);
id = getID();
childMap.set(id, child);

elementMap.set(child, {
contentEl: null,
elements: [],
loaded: false
});

child.onload = async () => {
const source = el.textContent;

const [, col, type] = source.match(TYPE_REGEX) ?? [];
if (!type) return;
let collapse;
if (/\?{3,}/.test(col)) {
collapse = /\+/.test(col) ? "open" : "closed";
}

const admonitionElement = await getAdmonitionElementAsync(
type,
type,
this.admonitions[type].icon,
this.admonitions[type].color,
collapse
);

const contentEl = admonitionElement.createDiv({
cls: "admonition-content"
});

child.containerEl.appendChild(admonitionElement);

console.log(elementMap.get(child).elements);
for (let element of elementMap.get(child)?.elements) {
contentEl.appendChild(element);
}

elementMap.set(child, {
...elementMap.get(child),
contentEl: contentEl,
loaded: true
});
};

child.onunload = () => {
childMap.delete(id);
elementMap.delete(child);
};

ctx.addChild(child);

el.children[0].detach();

return;
}

if (id && childMap.get(id)) {
const child = childMap.get(id);
elementMap.set(child, {
...elementMap.get(child),
elements: [
...elementMap.get(child).elements,
...Array.from(el.children)
]
});
if (elementMap.get(child)?.loaded) {
for (let element of elementMap.get(child)?.elements) {
elementMap.get(child).contentEl.appendChild(element);
}
}
}

/* const child = elementMap.get(child);
elementMap.set(child, {
...elementMap.get(child),
elements: [
...elementMap.get(child).elements,
...Array.from(el.children)
]
});
console.log(childMap.elements); */
});

Object.keys(this.admonitions).forEach((type) => {
this.registerMarkdownCodeBlockProcessor(
`ad-${type}`,
Expand All @@ -192,15 +304,17 @@ export default class ObsidianAdmonition
this.turnOnSyntaxHighlighting();
}

/** Add generic commands. */
this.addCommand({
id: "collapse-admonitions",
name: "Collapse Admonitions in Note",
callback: () => {
let view = this.app.workspace.getActiveViewOfType(MarkdownView);
if (!view || !(view instanceof MarkdownView)) return;

let admonitions =
view.contentEl.querySelectorAll("details[open]");
let admonitions = view.contentEl.querySelectorAll(
"details[open].admonition-plugin"
);
for (let i = 0; i < admonitions.length; i++) {
let admonition = admonitions[i];
admonition.removeAttribute("open");
Expand All @@ -215,14 +329,58 @@ export default class ObsidianAdmonition
if (!view || !(view instanceof MarkdownView)) return;

let admonitions = view.contentEl.querySelectorAll(
"details:not([open])"
"details:not([open]).admonition-plugin"
);
for (let i = 0; i < admonitions.length; i++) {
let admonition = admonitions[i];
admonition.setAttribute("open", "open");
}
}
});
this.addCommand({
id: "replace-with-html",
name: "Replace Admonitions with HTML",
callback: async () => {
let view = this.app.workspace.getActiveViewOfType(MarkdownView);
if (
!view ||
!(view instanceof MarkdownView) ||
view.getMode() !== "preview"
)
return;

let admonitions =
view.contentEl.querySelectorAll<HTMLElement>(
".admonition-plugin"
);

let content = (
(await this.app.vault.read(view.file)) ?? ""
).split("\n");
if (!content) return;
for (let admonition of Array.from(admonitions).reverse()) {
if (admonition.id && this.contextMap.has(admonition.id)) {
const ctx = this.contextMap.get(admonition.id);
const { lineStart, lineEnd } =
ctx.getSectionInfo(admonition) ?? {};
if (!lineStart || !lineEnd) continue;

const element = admonition.cloneNode(
true
) as HTMLElement;

element.removeAttribute("id");

content.splice(
lineStart,
lineEnd - lineStart + 1,
html(element.outerHTML)
);
}
}
await this.app.vault.modify(view.file, content.join("\n"));
}
});

this.registerEvent(
this.app.metadataCache.on("resolve", (file) => {
Expand Down Expand Up @@ -404,14 +562,16 @@ title:
} else if (collapse && collapse.trim() === "none") {
collapse = "";
}

const id = getID();
let admonitionElement = getAdmonitionElement(
type,
title,
this.admonitions[type].icon,
this.admonitions[type].color,
collapse
collapse,
id
);

/**
* Create a unloadable component.
*/
Expand All @@ -420,6 +580,14 @@ title:
);
markdownRenderChild.containerEl = admonitionElement;

markdownRenderChild.onload = () => {
this.contextMap.set(id, ctx);
};
markdownRenderChild.onunload = () => {
this.contextMap.delete(id);
};
ctx.addChild(markdownRenderChild);

let admonitionContent = admonitionElement.createDiv({
cls: "admonition-content"
});
Expand Down
Loading

0 comments on commit c2359dc

Please sign in to comment.