This commit is contained in:
mayurankv 2025-01-24 23:16:13 +00:00
parent a87708cca9
commit 91d76edf9d
5 changed files with 131 additions and 159 deletions

83
main.js

File diff suppressed because one or more lines are too long

View file

@ -1,16 +1,11 @@
import { ElementContent } from "hast";
import { fromHtml } from "hast-util-from-html";
import { toHtml } from "hast-util-to-html";
import { MarkdownPostProcessorContext, sanitizeHTMLToDom } from "obsidian";
import { DECORATED_ATTRIBUTE, DEFAULT_FOLD_ATTRIBUTE, FOLD_ATTRIBUTE, WRAP_ATTRIBUTE } from "src/Internal/constants/decoration";
import { CONTENT_ATTRIBUTE, DETECTING_CONTEXT, PARAMETERS_ATTRIBUTE } from "src/Internal/constants/detecting";
import { MarkdownRenderer, MarkdownPostProcessorContext, sanitizeHTMLToDom } from "obsidian";
import { DECORATED_ATTRIBUTE, TEMPORARY_SOURCEPATH } from "src/Internal/constants/decoration";
import { CONTENT_ATTRIBUTE, PARAMETERS_ATTRIBUTE } from "src/Internal/constants/detecting";
import { PREFIX } from "src/Internal/constants/general";
import { parseFenceCodeParameters, toDecorateFenceCode } from "src/Internal/Parsing/Fenced";
import { CodeDetectingContext } from "src/Internal/types/detecting";
import { FenceCodeParameters } from "src/Internal/types/parsing";
import { FenceCodeParameters, InlineCodeParameters } from "src/Internal/types/parsing";
import CodeStylerPlugin from "src/main";
import { visitParents } from "unist-util-visit-parents";
import { convertCommentLinks, createFenceHeaderElement, getIndentation, getLineClasses } from "../utils";
import { createFenceHeaderElement, createInlineHeaderElement, getIndentation, getLineClasses } from "../utils";
import { parseInlineCodeParameters, toDecorateInlineCode, toHighlightInlineCode } from "src/Internal/Parsing/Inline";
export async function renderedInlineCodeDecorating(
element: HTMLElement,
@ -24,26 +19,17 @@ export async function renderedInlineCodeDecorating(
return;
const inlineCodeParameters = parseInlineCodeParameters(inlineCodeElement.getAttribute(PARAMETERS_ATTRIBUTE) ?? " ");
const codeDetectingContext = (fenceCodeElement.getAttribute(DETECTING_CONTEXT) ?? "standalone") as CodeDetectingContext
if (!toDecorateFenceCode(fenceCodeParameters))
if (!toDecorateInlineCode(inlineCodeParameters))
return;
const staticRender = codeDetectingContext === "export"
decorateInlineCodeElement(
fenceCodeElement,
fenceCodeParameters,
staticRender,
await decorateInlineCodeElement(
inlineCodeElement,
inlineCodeParameters,
context.sourcePath,
plugin,
)
}
for (const inlineCodeElement of Array.from(element.querySelectorAll(":not(pre) > code"))) {
await remakeInlineCode(inlineCodeElement as HTMLElement,plugin);
}
}
export function renderedInlineCodeUndecorating(): void {
@ -57,136 +43,54 @@ export function renderedInlineCodeUndecorating(): void {
});
}
function decorateInlineCodeElement(
fenceCodeElement: HTMLElement,
fenceCodeParameters: FenceCodeParameters,
staticRender: boolean,
async function decorateInlineCodeElement(
inlineCodeElement: HTMLElement,
inlineCodeParameters: InlineCodeParameters,
sourcePath: string,
plugin: CodeStylerPlugin,
): void {
const fencePreElement = fenceCodeElement.parentElement
if (!fencePreElement)
return;
const fencePreParentElement = fencePreElement.parentElement
if (!fencePreParentElement)
return;
if (!staticRender)
plugin.mutationObservers.executeCode.observe(
fencePreElement,
{
childList: true,
subtree: true,
attributes: true,
characterData: true,
},
)
const fenceHeaderElement = createFenceHeaderElement(
fenceCodeParameters,
): Promise<void> {
const inlineHeaderElement = createInlineHeaderElement(
inlineCodeParameters,
sourcePath,
plugin,
);
markupFenceCodeElement(
fenceCodeElement,
fenceCodeParameters,
await markupInlineCodeElement(
inlineCodeElement,
inlineCodeParameters,
sourcePath,
plugin,
)
fencePreElement.insertBefore(fenceHeaderElement, fencePreElement.childNodes[0]);
inlineCodeElement.insertBefore(inlineHeaderElement, inlineCodeElement.childNodes[0]);
fenceCodeElement.setAttribute(DECORATED_ATTRIBUTE, "true")
inlineCodeElement.setAttribute(DECORATED_ATTRIBUTE, "true")
}
function markupInlineCodeElement(
fenceCodeElement: HTMLElement,
fenceCodeParameters: FenceCodeParameters,
async function markupInlineCodeElement(
inlineCodeElement: HTMLElement,
inlineCodeParameters: InlineCodeParameters,
sourcePath: string,
plugin: CodeStylerPlugin,
): void {
const fenceCodeLines = getFenceCodeLines(fenceCodeElement, sourcePath, plugin)
): Promise<void> {
inlineCodeElement.classList.add(`${PREFIX}code-inline`)
let indentation = 0;
fenceCodeLines.forEach(
(line, idx, fenceCodeLines) => {
const currentIndentation = getIndentation(line);
if (currentIndentation > indentation) {
//TODO (@mayurankv) Add fold start to previous line for indentation level currentIndentation
indentation = currentIndentation;
} else if (currentIndentation < indentation) {
//TODO (@mayurankv) Add fold end to previous line for all indentation levels currentIndentation+1 -> indentation
indentation = currentIndentation;
}
if (currentIndentation > 0) {
//TODO (@mayurankv) Add indentation line element
}
},
);
fenceCodeElement.classList.add(`${PREFIX}code`)
fenceCodeElement.innerHTML = ""
fenceCodeElement.append(
...fenceCodeLines.filter(
(line, idx, fenceCodeLines) => idx !== fenceCodeLines.length - 1,
).map(
(line, idx) => {
const lineNumber = idx + fenceCodeParameters.lineNumbers.offset + 1
const lineContainer = document.createDiv({
cls: getLineClasses(fenceCodeParameters, lineNumber, line)
});
lineContainer.append(
createDiv({ cls: PREFIX + "line-number", text: lineNumber.toString() }),
createDiv({ cls: PREFIX + "line-text", text: sanitizeHTMLToDom(line !== "" ? line : "<br>") }),
);
return lineContainer
},
)
)
}
//TODO: Update
import { MarkdownSectionInformation, CachedMetadata, sanitizeHTMLToDom, FrontMatterCache, MarkdownRenderer, MarkdownView, View } from "obsidian";
import { visitParents } from "unist-util-visit-parents";
import { fromHtml } from "hast-util-from-html";
import { toHtml } from "hast-util-to-html";
import { ElementContent, Element } from "hast";
import CodeStylerPlugin from "./main";
import { SETTINGS_SOURCEPATH_PREFIX, TRANSITION_LENGTH } from "./Settings";
import { CodeblockParameters, getFileContentLines, isCodeblockIgnored, isLanguageIgnored, parseCodeblockSource } from "./Parsing/CodeblockParsing";
import { InlineCodeParameters, parseInlineCode } from "./Parsing/InlineCodeParsing";
import { createHeader, createInlineOpener, getLineClass as getLineClasses } from "./CodeblockDecorating";
async function remakeInlineCode(inlineCodeElement: HTMLElement, plugin: CodeStylerPlugin): Promise<void> {
if (!plugin.settings.currentTheme.settings.inline.syntaxHighlight || inlineCodeElement.classList.contains("code-styler-inline"))
if (!toHighlightInlineCode(plugin))
return;
const inlineCodeText = inlineCodeElement.innerText;
const {parameters,text} = parseInlineCode(inlineCodeText);
if (parameters) {
inlineCodeElement.innerHTML = await getHighlightedHTML(parameters,text,plugin);
inlineCodeElement.innerHTML = inlineCodeElement.innerHTML + "&ZeroWidthSpace;";
inlineCodeElement.classList.add("code-styler-inline");
const parameterString = inlineCodeText.substring(0,inlineCodeText.lastIndexOf(text));
inlineCodeElement.setAttribute("parameters",parameterString); // Store parameter string as attribute so original text can be restored on plugin removal
if (parameters.icon || parameters.title)
inlineCodeElement.insertBefore(createInlineOpener(parameters,plugin.languageIcons),inlineCodeElement.childNodes[0]);
} else if (!parameters && text) {
inlineCodeElement.innerText = text;
inlineCodeElement.classList.add("code-styler-inline");
}
}
async function getHighlightedHTML(parameters: InlineCodeParameters, text: string, plugin: CodeStylerPlugin): Promise<string> {
const temporaryRenderingContainer = createDiv();
MarkdownRenderer.render(plugin.app,["```",parameters.language,"\n",text,"\n","```"].join(""),temporaryRenderingContainer,"",plugin);
await MarkdownRenderer.render(
plugin.app,
["```", inlineCodeParameters.language, "\n", inlineCodeElement.getAttribute(CONTENT_ATTRIBUTE) ?? "", "\n", "```"].join(""),
temporaryRenderingContainer,
TEMPORARY_SOURCEPATH,
plugin,
);
const renderedCodeElement = temporaryRenderingContainer.querySelector("code");
if (!renderedCodeElement)
return "ERROR: Could not render highlighted code";
while(plugin.settings.currentTheme.settings.inline.syntaxHighlight && !renderedCodeElement.classList.contains("is-loaded"))
await sleep(2);
return renderedCodeElement.innerHTML;
throw new Error("Could not render highlighted code");
// while (plugin.settings.currentTheme.settings.inline.syntaxHighlight && !renderedCodeElement.classList.contains("is-loaded")) //TODO: Is needed?
// await sleep(2);
inlineCodeElement.innerHTML = renderedCodeElement.innerHTML + "&ZeroWidthSpace;";
}

View file

@ -2,7 +2,7 @@ import { MarkdownRenderer } from "obsidian";
import { ElementContent, Element } from "hast";
import { fromHtml } from "hast-util-from-html";
import CodeStylerPlugin from "src/main";
import { FenceCodeParameters, Highlights } from "src/Internal/types/parsing";
import { FenceCodeParameters, Highlights, InlineCodeParameters } from "src/Internal/types/parsing";
import { PREFIX } from "../constants/general";
import { toKebabCase } from "../utils/text";
@ -18,6 +18,16 @@ export function createFenceHeaderElement(
return fenceHeaderElement
}
export function createInlineHeaderElement(
inlineCodeParameters: InlineCodeParameters,
sourcePath: string,
plugin: CodeStylerPlugin,
): HTMLElement {
const fenceHeaderElement = createDiv();
// TODO: Create element
return fenceHeaderElement
}
export function getLineClasses(
fenceCodeParameters: FenceCodeParameters,
lineNumber: number,

View file

@ -1,11 +1,26 @@
import CodeStylerPlugin from "src/main";
import { InlineCodeParameters } from "../types/parsing";
export function parseFenceCodeParameters(
export function parseInlineCodeParameters(
inlineCodeParametersLine: string,
): InlineCodeParameters {
}
export function toDecorateInlineCode(
inlineCodeParameters: InlineCodeParameters,
): boolean {
//TODO: Check if language is ignored
//TODO: Check if codeblock arguments contain ignore
return true
}
export function toHighlightInlineCode(
plugin: CodeStylerPlugin,
): boolean {
return plugin.settings.currentTheme.settings.inline.syntaxHighlight
}
export function splitInlineCodeRaw(
inlineCodeRaw: string,
): { inlineCodeParameters: string | null, inlineCodeContent: string } {

View file

@ -12,6 +12,8 @@ export const WRAP_ATTRIBUTE = PREFIX + "wrap"
export const FOLD_PLACEHOLDER = "Folded Code";
export const TEMPORARY_SOURCEPATH = `@${PREFIX}-temporary-sourcepath`
export const GIT_ICONS: { [key: string]: string } = {
"branch": "&#xe0a0;",
"tree": "&#xeafc;", // commit