Skip to content

Commit fcb9646

Browse files
committed
feat: Allow embedding block links in inline rant blocks
1 parent 856c5dc commit fcb9646

File tree

3 files changed

+99
-35
lines changed

3 files changed

+99
-35
lines changed

src/main.ts

+13-13
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,15 @@ import {
1313
CodeblockRantProcessor,
1414
InlineRantProcessor,
1515
BaseRantProcessor,
16-
Customization,
16+
BlockLinkRantProcessor,
17+
BLOCK_LINK_REGEX,
1718
} from "./processor";
1819
import SettingTab, { DEFAULT_SETTINGS, RantLangSettings } from "./settings";
1920

2021
export default class RantLangPlugin extends Plugin {
2122
settings: RantLangSettings;
2223
fileMap: Map<TFile, BaseRantProcessor[]> = new Map();
24+
rantBlockStore: Map<string, TFile> = new Map();
2325

2426
async onload() {
2527
// Load WebAssembly Rust plugin to have access to the Rust Rant crate.
@@ -37,19 +39,12 @@ export default class RantLangPlugin extends Plugin {
3739
const file = this.app.vault.getAbstractFileByPath(ctx.sourcePath);
3840
if (!file || !(file instanceof TFile)) return;
3941

40-
let customizations: Customization[] = [];
41-
let lines = source.split("\n");
42-
while (lines.length > 0 && ["bold", "italic"].contains(lines[0])) {
43-
customizations.push(lines.shift() as Customization);
44-
}
45-
const input = lines.join("\n");
46-
4742
const processor = new CodeblockRantProcessor(
48-
input,
43+
this,
44+
source,
4945
el,
5046
this.settings,
51-
ctx.sourcePath,
52-
customizations
47+
ctx.sourcePath
5348
);
5449
ctx.addChild(processor);
5550

@@ -69,11 +64,16 @@ export default class RantLangPlugin extends Plugin {
6964
const codeblock = codeblocks.item(index);
7065
const text = codeblock.innerText.trim();
7166
if (text.startsWith(inlineRantQueryPrefix)) {
72-
const code = text.substring(inlineRantQueryPrefix.length).trim();
7367
const container = el.createSpan();
7468
codeblock.replaceWith(container);
7569

76-
const processor = new InlineRantProcessor(
70+
const code = text.substring(inlineRantQueryPrefix.length).trim();
71+
const processorClass = code.match(BLOCK_LINK_REGEX)
72+
? BlockLinkRantProcessor
73+
: InlineRantProcessor;
74+
75+
const processor = new processorClass(
76+
this,
7777
code,
7878
container,
7979
this.settings,

src/processor.ts

+86-14
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,43 @@
1-
import { MarkdownRenderChild, MarkdownRenderer } from "obsidian";
1+
import { MarkdownRenderChild, MarkdownRenderer, TFile } from "obsidian";
22
import { rant } from "../pkg/obsidian_rantlang_plugin.js";
3-
import { RantLangSettings } from "./settings.js";
4-
import { randomSeed } from "./utils.js";
3+
import type RantLangPlugin from "./main";
4+
import { RantLangSettings } from "./settings";
5+
import { randomSeed } from "./utils";
6+
7+
export const BLOCK_LINK_REGEX =
8+
/\[\[(?<link>[\s\S]+?)#?\^(?<block>[\s\S]+?)\]\]/;
59

610
export abstract class BaseRantProcessor extends MarkdownRenderChild {
711
result: string = "";
812

913
constructor(
14+
public plugin: RantLangPlugin,
1015
public input: string,
1116
public container: HTMLElement,
1217
public settings: RantLangSettings,
13-
public sourcePath: string,
14-
public customizations: Customization[] = []
18+
public sourcePath: string
1519
) {
1620
super(container);
1721
this.rant();
1822
}
1923

2024
abstract renderResult(): void;
2125

22-
processInput(seed: number) {
26+
processInput(input: string, seed: number) {
2327
try {
24-
this.result = rant(this.input, seed);
28+
this.result = rant(input, seed);
2529
} catch (error) {
2630
this.result = "ERROR processing Rant block (see console for details)";
2731
console.error(error);
2832
}
2933
}
3034

31-
rant(seed?: number) {
32-
this.processInput(seed ?? randomSeed());
35+
rant(input?: string, seed?: number) {
36+
this.processInput(input ?? this.input, seed ?? randomSeed());
3337
this.renderResult();
3438
}
3539
}
3640

37-
export type Customization = "bold" | "italic";
38-
3941
export class CodeblockRantProcessor extends BaseRantProcessor {
4042
renderResult() {
4143
this.container.empty();
@@ -53,9 +55,6 @@ export class CodeblockRantProcessor extends BaseRantProcessor {
5355
if (this.settings.highlight) {
5456
cls.push("rant-highlight");
5557
}
56-
this.customizations.forEach((style) => {
57-
cls.push(`rant-${style}`);
58-
});
5958
return cls;
6059
}
6160
}
@@ -83,3 +82,76 @@ export class InlineRantProcessor extends BaseRantProcessor {
8382
return cls;
8483
}
8584
}
85+
86+
export class BlockLinkRantProcessor extends BaseRantProcessor {
87+
loaded: boolean = false;
88+
path: string;
89+
block: string;
90+
91+
constructor(
92+
plugin: RantLangPlugin,
93+
input: string,
94+
container: HTMLElement,
95+
settings: RantLangSettings,
96+
sourcePath: string
97+
) {
98+
super(plugin, input, container, settings, sourcePath);
99+
this.parseBlockLink(input);
100+
this.rant();
101+
}
102+
103+
parseBlockLink(blockLink: string) {
104+
const { groups } = blockLink.match(BLOCK_LINK_REGEX);
105+
this.path = groups.link.replace(/(\[|\])/g, "");
106+
this.block = groups.block.replace(/(\^|#)/g, "").trim();
107+
this.loaded = true;
108+
}
109+
110+
rant() {
111+
if (!this.loaded) {
112+
return;
113+
}
114+
115+
const file = this.plugin.app.metadataCache.getFirstLinkpathDest(
116+
this.path,
117+
this.sourcePath
118+
);
119+
120+
if (!file || !(file instanceof TFile)) {
121+
throw new Error("Could not load file.");
122+
}
123+
124+
const cache = this.plugin.app.metadataCache.getFileCache(file);
125+
const position = cache.blocks[this.block].position;
126+
127+
this.plugin.app.vault.cachedRead(file).then((content) => {
128+
const rantProgram = content
129+
.split("\n")
130+
.slice(position.start.line + 1, position.end.line)
131+
.join("\n");
132+
super.rant(rantProgram);
133+
});
134+
}
135+
136+
renderResult() {
137+
let temp = createEl("div");
138+
MarkdownRenderer.renderMarkdown(this.result, temp, this.sourcePath, this);
139+
140+
this.container.empty();
141+
this.container.className = this.getStyles().join(" ");
142+
143+
temp.childNodes.forEach((paragraph) => {
144+
paragraph.childNodes.forEach((node) => {
145+
this.container.appendChild(node.cloneNode(true));
146+
});
147+
});
148+
}
149+
150+
getStyles() {
151+
let cls = ["rant-inline"];
152+
if (this.settings.highlight) {
153+
cls.push("rant-highlight");
154+
}
155+
return cls;
156+
}
157+
}

styles.css

-8
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,3 @@
99
.rant-highlight.rant-block {
1010
padding: 0px 8px;
1111
}
12-
13-
.rant-bold {
14-
font-weight: bold;
15-
}
16-
17-
.rant-italic {
18-
font-style: italic;
19-
}

0 commit comments

Comments
 (0)