Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
133 changes: 83 additions & 50 deletions main.js

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions src/ApplyStyling.ts
Original file line number Diff line number Diff line change
Expand Up @@ -130,9 +130,9 @@ function styleThemeSettings (themeSettings: CodeStylerThemeSettings, currentThem
}
${THEME_STYLES?.[currentTheme]?.border?`
.markdown-source-view :not(pre.code-styler-pre) > .code-styler-header-container {
--code-styler-header-border:`+ //@ts-expect-error Does Exist
--code-styler-header-border:`+
THEME_STYLES[currentTheme].border.style+`;
--header-separator-width-padding: calc(var(--header-separator-width) - `+ //@ts-expect-error Does Exist
--header-separator-width-padding: calc(var(--header-separator-width) - `+
THEME_STYLES[currentTheme].border.size+`px);
--folded-bottom-border: var(--code-styler-header-border);
}
Expand Down Expand Up @@ -161,7 +161,7 @@ function styleLanguageColours (themeSettings: CodeStylerThemeSettings, redirectL
if (THEME_STYLES?.[currentTheme]?.border) {
result += `
.markdown-source-view :not(pre.code-styler-pre) > .code-styler-header-container.language-${languageName} {
--language-border-width: ${ //@ts-expect-error Does exist
--language-border-width: ${
themeSettings.advanced.languageBorderColour?themeSettings.advanced.languageBorderWidth+THEME_STYLES[currentTheme].border.size:0}px;
}`;
}
Expand Down
30 changes: 25 additions & 5 deletions src/EditingView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { Extension, EditorState, StateField, StateEffect, StateEffectType, Range
import { syntaxTree, tokenClassNodeProp } from "@codemirror/language";
import { SyntaxNodeRef } from "@lezer/common";

import { CodeStylerSettings, CodeStylerThemeSettings, SPECIAL_LANGUAGES } from "./Settings";
import { CodeStylerSettings, CodeStylerThemeSettings, SPECIAL_LANGUAGES, EXECUTE_CODE_SUPPORTED_LANGUAGES } from "./Settings";
import { CodeblockParameters, parseCodeblockParameters, testOpeningLine, trimParameterLine, isCodeblockIgnored, isLanguageIgnored } from "./Parsing/CodeblockParsing";
import { InlineCodeParameters, parseInlineCode } from "./Parsing/InlineCodeParsing";
import { createHeader, createInlineOpener, getLanguageIcon, getLineClass, isHeaderHidden } from "./CodeblockDecorating";
Expand Down Expand Up @@ -344,6 +344,15 @@ export function createCodeblockCodeMirrorExtensions(settings: CodeStylerSettings
if (syntaxNode.type.name.includes("HyperMD-codeblock-begin")) {
const startLine = state.doc.lineAt(syntaxNode.from);
codeblockParameters = parseCodeblockParameters(trimParameterLine(startLine.text.toString()),settings.currentTheme);

// Apply run-* language transformation BEFORE ignore check
if (/run-\w*/.test(codeblockParameters.language)) {
const baseLanguage = codeblockParameters.language.slice(4);
if (EXECUTE_CODE_SUPPORTED_LANGUAGES.includes(baseLanguage)) {
codeblockParameters.language = baseLanguage;
}
}

if (!isLanguageIgnored(codeblockParameters.language,settings.excludedLanguages) && !isCodeblockIgnored(codeblockParameters.language,settings.processedCodeblocksWhitelist) && !codeblockParameters.ignore) {
if (!SPECIAL_LANGUAGES.some(regExp => new RegExp(regExp).test(codeblockParameters.language)))
builder.add(startLine.from,startLine.from,Decoration.widget({widget: new HeaderWidget(codeblockParameters,foldValue(startLine.from,codeblockParameters.fold.enabled),settings.currentTheme.settings,sourcePath,plugin), block: true, side: -1}));
Expand All @@ -368,7 +377,8 @@ export function createCodeblockCodeMirrorExtensions(settings: CodeStylerSettings
maxLineNum = foldEnd.to-foldStart.from-1+codeblockParameters.lineNumbers.offset;
});
const lineNumberMargin = (maxLineNum.toString().length > 2)?maxLineNum.toString().length * state.field(charWidthState):undefined;
builder.add(foldStart.from,foldStart.from,Decoration.line({attributes: {style: `--line-number-gutter-width: ${lineNumberMargin?lineNumberMargin+"px":"calc(var(--line-number-gutter-min-width) - 12px)"};`, class: "code-styler-line"+(["^$"].concat(SPECIAL_LANGUAGES).some(regExp => new RegExp(regExp).test(codeblockParameters.language))?"":` language-${codeblockParameters.language}`)}}));
const effectiveLanguage = codeblockParameters.language;
builder.add(foldStart.from,foldStart.from,Decoration.line({attributes: {style: `--line-number-gutter-width: ${lineNumberMargin?lineNumberMargin+"px":"calc(var(--line-number-gutter-min-width) - 12px)"};`, class: "code-styler-line"+(["^$"].concat(SPECIAL_LANGUAGES).some(regExp => new RegExp(regExp).test(effectiveLanguage))?"":` language-${effectiveLanguage}`)}}));
if (showLineNumbers)
builder.add(foldStart.from,foldStart.from,Decoration.widget({widget: new LineNumberWidget(0,codeblockParameters,maxLineNum,true)}));
for (let i = foldStart.number+1; i <= state.doc.lines; i++) {
Expand All @@ -380,15 +390,24 @@ export function createCodeblockCodeMirrorExtensions(settings: CodeStylerSettings
foldEnd = line;
break;
}
builder.add(line.from,line.from,Decoration.line({attributes: {style: `--line-number-gutter-width: ${lineNumberMargin?lineNumberMargin+"px":"calc(var(--line-number-gutter-min-width) - 12px)"};`, class: ((SPECIAL_LANGUAGES.some(regExp => new RegExp(regExp).test((iter.value as Decoration).spec.widget.codeblockParameters.language)))?"code-styler-line":getLineClass(codeblockParameters,i-foldStart.number,line.text).join(" "))+(["^$"].concat(SPECIAL_LANGUAGES).some(regExp => new RegExp(regExp).test(codeblockParameters.language))?"":` language-${codeblockParameters.language}`)}}));
const lineClasses = SPECIAL_LANGUAGES.some(regExp => new RegExp(regExp).test(effectiveLanguage))
? "code-styler-line"
: getLineClass(codeblockParameters,i-foldStart.number,line.text).join(" ");
const languageClass = ["^$"].concat(SPECIAL_LANGUAGES).some(regExp => new RegExp(regExp).test(effectiveLanguage))
? ""
: ` language-${effectiveLanguage}`;
builder.add(line.from,line.from,Decoration.line({attributes: {
style: `--line-number-gutter-width: ${lineNumberMargin?lineNumberMargin+"px":"calc(var(--line-number-gutter-min-width) - 12px)"};`,
class: lineClasses + languageClass
}}));
if (showLineNumbers)
builder.add(line.from,line.from,Decoration.widget({widget: new LineNumberWidget(i - foldStart.number, codeblockParameters, maxLineNum)}));
if (codeblockParameters.language === "markdown")
if (effectiveLanguage === "markdown")
continue;
convertCommentLinks(state, line, sourcePath, builder, sourceMode);
}
if (foldEnd !== null) {
builder.add(foldEnd.from,foldEnd.from,Decoration.line({attributes: {style: `--line-number-gutter-width: ${lineNumberMargin?lineNumberMargin+"px":"calc(var(--line-number-gutter-min-width) - 12px)"};`, class: "code-styler-line"+(["^$"].concat(SPECIAL_LANGUAGES).some(regExp => new RegExp(regExp).test(codeblockParameters.language))?"":` language-${codeblockParameters.language}`)}}));
builder.add(foldEnd.from,foldEnd.from,Decoration.line({attributes: {style: `--line-number-gutter-width: ${lineNumberMargin?lineNumberMargin+"px":"calc(var(--line-number-gutter-min-width) - 12px)"};`, class: "code-styler-line"+(["^$"].concat(SPECIAL_LANGUAGES).some(regExp => new RegExp(regExp).test(effectiveLanguage))?"":` language-${effectiveLanguage}`)}}));
if (showLineNumbers)
builder.add(foldEnd.from,foldEnd.from,Decoration.widget({widget: new LineNumberWidget(0,codeblockParameters,maxLineNum,true)}));
}
Expand Down Expand Up @@ -491,6 +510,7 @@ export function createCodeblockCodeMirrorExtensions(settings: CodeStylerSettings
return addEffects;
}


return [
interaction,
ignoreListener,ignoreFileListener,
Expand Down
13 changes: 8 additions & 5 deletions src/Parsing/CodeblockParsing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -218,9 +218,12 @@ function pluginAdjustExecuteCode(codeblockParameters: CodeblockParameters, plugi
return codeblockParameters;
}
function pluginAdjustExecuteCodeRun(codeblockParameters: CodeblockParameters, plugin: CodeStylerPlugin, plugins: Record<string,ExternalPlugin>): CodeblockParameters {
if ("execute-code" in plugins) {
if (EXECUTE_CODE_SUPPORTED_LANGUAGES.includes(codeblockParameters.language.slice(4)) && !isCodeblockIgnored(codeblockParameters.language,plugin.settings.processedCodeblocksWhitelist))
codeblockParameters.language = codeblockParameters.language.slice(4);
// Transform run-* languages regardless of whether execute-code is present
if (/run-\w*/.test(codeblockParameters.language)) {
const baseLanguage = codeblockParameters.language.slice(4);
if (EXECUTE_CODE_SUPPORTED_LANGUAGES.includes(baseLanguage) && !isCodeblockIgnored(codeblockParameters.language,plugin.settings.processedCodeblocksWhitelist)) {
codeblockParameters.language = baseLanguage;
}
}
return codeblockParameters;
}
Expand All @@ -242,7 +245,7 @@ function parseCodeblockParameterString(parameterString: string, codeblockParamet
addHighlights(parameterString,codeblockParameters,theme);
}
function manageTitle(parameterString: string, codeblockParameters: CodeblockParameters) {
const titleMatch = /(["']?)([^\1]+)\1/.exec(parameterString.slice("title:".length));
const titleMatch = /(["']?)([^"']+)\1/.exec(parameterString.slice("title:".length));
if (titleMatch)
codeblockParameters.title = titleMatch[2].trim();
parameterString = parameterString.slice("title:".length);
Expand Down Expand Up @@ -287,7 +290,7 @@ function manageFolding(parameterString: string, codeblockParameters: CodeblockPa
placeholder: "",
};
} else {
const foldPlaceholderMatch = /(["']?)([^\1]+)\1/.exec(parameterString.slice("fold:".length));
const foldPlaceholderMatch = /(["']?)([^"']+)\1/.exec(parameterString.slice("fold:".length));
if (foldPlaceholderMatch) {
codeblockParameters.fold = {
enabled: true,
Expand Down
2 changes: 1 addition & 1 deletion src/Parsing/InlineCodeParsing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ function parseInlineCodeParameters(parameterLine: string): InlineCodeParameters
}
function parseInlineCodeParameterString(parameterString: string, inlineCodeParameters: InlineCodeParameters): void {
if (parameterString.startsWith("title:") || parameterString.startsWith("title=")) {
const titleMatch = /(["']?)([^\1]+)\1/.exec(parameterString.slice("title:".length));
const titleMatch = /(["']?)([^"']+)\1/.exec(parameterString.slice("title:".length));
if (titleMatch)
inlineCodeParameters.title = titleMatch[2].trim().replace(/\\{/g, "{");
} else if (parameterString === "icon" || (parameterString.startsWith("icon:") && parameterString.toLowerCase() === "icon:true"))
Expand Down
19 changes: 17 additions & 2 deletions src/ReadingView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ 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 { CodeblockParameters, getFileContentLines, isCodeblockIgnored, isLanguageIgnored, parseCodeblockSource, parseCodeblockParameters } from "./Parsing/CodeblockParsing";
import { InlineCodeParameters, parseInlineCode } from "./Parsing/InlineCodeParsing";
import { createHeader, createInlineOpener, getLineClass as getLineClasses } from "./CodeblockDecorating";

Expand Down Expand Up @@ -93,7 +93,22 @@ async function renderSettings(codeblockPreElements: Array<HTMLElement>, sourcePa
await remakeCodeblocks(codeblockPreElements,codeblocksParameters,sourcePath,true,false,plugin);
}
async function renderDocument(codeblockPreElements: Array<HTMLElement>, sourcePath: string, cache: CachedMetadata | null, editingEmbeds: boolean, printing: boolean, plugin: CodeStylerPlugin) {
const codeblocksParameters: Array<CodeblockParameters> = await getCodeblocksParameters(sourcePath,cache,plugin,editingEmbeds);
let codeblocksParameters: Array<CodeblockParameters> = await getCodeblocksParameters(sourcePath,cache,plugin,editingEmbeds);

// Handle case where execute-code has transformed run-* blocks
if (codeblocksParameters.length !== codeblockPreElements.length) {
// Fallback: infer parameters from actual DOM elements
codeblocksParameters = codeblockPreElements.map(preElement => {
const codeElement = preElement.querySelector("code");
const classList = Array.from(codeElement?.classList || []);
const languageClass = classList.find(cls => cls.startsWith("language-"));
const language = languageClass ? languageClass.replace("language-", "") : "";

// Create full parameters with proper defaults from theme
return parseCodeblockParameters(`${language}`, plugin.settings.currentTheme);
});
}

await remakeCodeblocks(codeblockPreElements,codeblocksParameters,sourcePath,!printing,true,plugin);
}
async function retriggerProcessor(element: HTMLElement, context: {sourcePath: string, getSectionInfo: (element: HTMLElement) => MarkdownSectionInformation | null, frontmatter: FrontMatterCache | undefined}, plugin: CodeStylerPlugin, editingEmbeds: boolean) {
Expand Down