mirror of
https://github.com/youfoundjk/TeXcore.git
synced 2026-07-22 07:33:31 +00:00
lin fix I
This commit is contained in:
parent
b6392a5523
commit
157c0b57ab
23 changed files with 276 additions and 202 deletions
|
|
@ -1,5 +1,9 @@
|
|||
import { StateField } from '@codemirror/state';
|
||||
|
||||
if (typeof window !== 'undefined' && !('require' in window)) {
|
||||
(window as unknown as { require: unknown }).require = require;
|
||||
}
|
||||
|
||||
const toForwardSlashes = (value: string): string => value.replace(/\\/g, '/');
|
||||
const joinPath = (...parts: string[]): string => {
|
||||
const normalizedParts = parts.map(toForwardSlashes).filter(part => part !== '' && part !== '.');
|
||||
|
|
|
|||
|
|
@ -184,7 +184,7 @@ function createTagManagerPlugin(
|
|||
): ViewPlugin<object> {
|
||||
return ViewPlugin.fromClass(
|
||||
class {
|
||||
timeout: any = null;
|
||||
timeout: number | null = null;
|
||||
blockedBySelection = false;
|
||||
|
||||
constructor(view: EditorView) {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { TFile, App, CachedMetadata } from 'obsidian';
|
||||
import { TFile, App, CachedMetadata, Pos } from 'obsidian';
|
||||
import { EquationBlock } from 'types';
|
||||
import { trimMathText, parseMarkdownComment, parseYamlLike } from 'utils/parse';
|
||||
|
||||
|
|
@ -53,7 +53,7 @@ export class ActiveNoteEquationProvider {
|
|||
$file: file.path,
|
||||
$type: 'equation' as const,
|
||||
$blockId: blockId,
|
||||
$pos: position as any,
|
||||
$pos: position as unknown as Pos,
|
||||
$position: { start: position.start.line, end: position.end.line },
|
||||
$mathText: trimmedMathText,
|
||||
$manualTag: manualTag,
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ export const createEquationNumberProcessor = (plugin: LatexReferencer): Markdown
|
|||
|
||||
// In reading view, we need to read the file content directly.
|
||||
// We cannot rely on an active editor being open.
|
||||
plugin.app.vault.cachedRead(file).then(content => {
|
||||
void plugin.app.vault.cachedRead(file).then(content => {
|
||||
const equations = processActiveNoteEquations(plugin, file, content);
|
||||
if (equations.size === 0) return;
|
||||
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ function processEquationLinksInElement(node: HTMLElement, plugin: LatexReference
|
|||
* (e.g., on initial page load).
|
||||
*/
|
||||
function scanExistingCallouts(plugin: LatexReferencer): void {
|
||||
const calloutBlocks = document.querySelectorAll('.cm-embed-block.cm-callout');
|
||||
const calloutBlocks = activeDocument.querySelectorAll('.cm-embed-block.cm-callout');
|
||||
for (const block of calloutBlocks) {
|
||||
if (block.instanceOf(HTMLElement)) {
|
||||
processEquationLinksInElement(block, plugin);
|
||||
|
|
@ -84,7 +84,7 @@ function scanExistingCallouts(plugin: LatexReferencer): void {
|
|||
}
|
||||
|
||||
/**
|
||||
* Sets up a MutationObserver on document.body to detect callout rendering
|
||||
* Sets up a MutationObserver on activeDocument.body to detect callout rendering
|
||||
* and reprocess equation links within them. Also performs an initial scan
|
||||
* after a delay to catch callouts rendered before the cache was ready.
|
||||
*
|
||||
|
|
@ -97,7 +97,6 @@ export function setupDOMObserver(plugin: LatexReferencer): () => void {
|
|||
if (mutation.type === 'childList') {
|
||||
for (const node of mutation.addedNodes) {
|
||||
if (node.instanceOf(HTMLElement)) {
|
||||
if (!node.querySelector && !node.matches) continue;
|
||||
processEquationLinksInElement(node, plugin);
|
||||
}
|
||||
}
|
||||
|
|
@ -105,7 +104,7 @@ export function setupDOMObserver(plugin: LatexReferencer): () => void {
|
|||
}
|
||||
});
|
||||
|
||||
observer.observe(document.body, { childList: true, subtree: true });
|
||||
observer.observe(activeDocument.body, { childList: true, subtree: true });
|
||||
|
||||
// Initial scan: process callouts that were rendered before the observer
|
||||
// started or before the equation cache was ready. We use onLayoutReady
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ export function getMathLink(
|
|||
const subpathResult = cache ? resolveSubpath(cache, subpath) : null;
|
||||
|
||||
for (const provider of plugin.internalProviders) {
|
||||
const provided = provider.provide({ path, subpath }, targetFile, subpathResult as any);
|
||||
const provided = provider.provide({ path, subpath }, targetFile, subpathResult as unknown);
|
||||
if (provided) {
|
||||
return provided;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -88,16 +88,20 @@ export const createLivePreviewLinkRendererPlugin = (plugin: LatexReferencer): Ex
|
|||
|
||||
mathLinkWrapper.onclick = (evt: MouseEvent) => {
|
||||
evt.preventDefault();
|
||||
app.workspace.openLinkText(this.outLinkText, this.sourcePath, evt.ctrlKey || evt.metaKey);
|
||||
void app.workspace.openLinkText(
|
||||
this.outLinkText,
|
||||
this.sourcePath,
|
||||
evt.ctrlKey || evt.metaKey
|
||||
);
|
||||
};
|
||||
|
||||
mathLinkWrapper.onmousedown = (evt: MouseEvent) => {
|
||||
if (evt.button == 1) evt.preventDefault();
|
||||
if (evt.button === 1) evt.preventDefault();
|
||||
};
|
||||
|
||||
mathLinkWrapper.onauxclick = (evt: MouseEvent) => {
|
||||
if (evt.button == 1) {
|
||||
app.workspace.openLinkText(this.outLinkText, this.sourcePath, true);
|
||||
if (evt.button === 1) {
|
||||
void app.workspace.openLinkText(this.outLinkText, this.sourcePath, true);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -182,7 +186,7 @@ export const createLivePreviewLinkRendererPlugin = (plugin: LatexReferencer): Ex
|
|||
|
||||
this.decorations = builder.finish();
|
||||
if (this.decorations.size > 0) {
|
||||
finishRenderMath();
|
||||
void finishRenderMath();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ export class LatexRenderChild extends MarkdownRenderChild {
|
|||
const linkEl = this.containerEl;
|
||||
setMathLink(mathLink, linkEl);
|
||||
}
|
||||
finishRenderMath();
|
||||
void finishRenderMath();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
22
src/declarations.d.ts
vendored
22
src/declarations.d.ts
vendored
|
|
@ -1,4 +1,4 @@
|
|||
import { PaneType, SplitDirection, UserEvent } from 'obsidian';
|
||||
import { PaneType, SplitDirection, UserEvent, Scope, View, MarkdownFileInfo } from 'obsidian';
|
||||
import { EditorView } from '@codemirror/view';
|
||||
|
||||
declare module 'obsidian' {
|
||||
|
|
@ -12,16 +12,26 @@ declare module 'obsidian' {
|
|||
setSelectedItem(index: number, event: UserEvent | null): void;
|
||||
}
|
||||
|
||||
interface Workspace {
|
||||
getActiveFileView(): View | null;
|
||||
activeEditor?: MarkdownFileInfo | null;
|
||||
}
|
||||
|
||||
interface App {
|
||||
workspace: Workspace;
|
||||
commands: {
|
||||
commands: Record<string, unknown>;
|
||||
removeCommand(id: string): void;
|
||||
};
|
||||
plugins: {
|
||||
enabledPlugins: Set<string>;
|
||||
plugins: {
|
||||
[id: string]: any;
|
||||
[id: string]: unknown;
|
||||
};
|
||||
getPlugin: (id: string) => Plugin | null;
|
||||
};
|
||||
internalPlugins: {
|
||||
getPluginById(id: string): Plugin & { instance: any };
|
||||
getPluginById(id: string): Plugin & { instance: unknown };
|
||||
};
|
||||
}
|
||||
interface Editor {
|
||||
|
|
@ -39,6 +49,12 @@ declare module 'obsidian' {
|
|||
// 3. USE the complete interface here as well
|
||||
chooser: Suggestions<T>;
|
||||
}
|
||||
interface Vault {
|
||||
getConfig(key: string): unknown;
|
||||
}
|
||||
namespace MarkdownRenderer {
|
||||
function postProcess(app: App, context: unknown): Promise<void>;
|
||||
}
|
||||
}
|
||||
|
||||
export type LeafArgs =
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import { Notice, TFile } from 'obsidian';
|
||||
import { Command, TFile } from 'obsidian';
|
||||
import type LatexReferencer from '../../main';
|
||||
import { showNotice } from 'utils/obsidian';
|
||||
|
||||
export class CustomNoteManager {
|
||||
private registeredCommandIds: string[] = [];
|
||||
|
|
@ -12,7 +13,7 @@ export class CustomNoteManager {
|
|||
|
||||
registerCommands() {
|
||||
// 1. Unregister all previously registered commands
|
||||
const appCommands = (this.plugin.app as any).commands;
|
||||
const appCommands = this.plugin.app.commands;
|
||||
if (appCommands && typeof appCommands.removeCommand === 'function') {
|
||||
for (const cmdId of this.registeredCommandIds) {
|
||||
try {
|
||||
|
|
@ -34,11 +35,11 @@ export class CustomNoteManager {
|
|||
const commandId = `open-custom-note-${item.id}`;
|
||||
const fullCommandId = `${this.plugin.manifest.id}:${commandId}`;
|
||||
|
||||
const commandConfig: any = {
|
||||
const commandConfig: Command = {
|
||||
id: commandId,
|
||||
name: `Open custom note: ${displayName}`,
|
||||
callback: () => {
|
||||
this.openCustomNote(item.notePath);
|
||||
void this.openCustomNote(item.notePath);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -66,7 +67,7 @@ export class CustomNoteManager {
|
|||
const leaf = this.plugin.app.workspace.getLeaf('tab');
|
||||
await leaf.openFile(file);
|
||||
} else {
|
||||
new Notice(
|
||||
showNotice(
|
||||
`Custom note not found at path: ${notePath}. Please verify your configuration in settings.`
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,36 @@
|
|||
import * as electron from 'electron';
|
||||
import * as fs from 'fs/promises';
|
||||
import { type FrontMatterCache, Notice } from 'obsidian';
|
||||
import { type FrontMatterCache } from 'obsidian';
|
||||
import { showNotice } from 'utils/obsidian';
|
||||
|
||||
interface ElectronModule {
|
||||
remote: {
|
||||
shell: {
|
||||
openPath(path: string): Promise<boolean>;
|
||||
};
|
||||
dialog: {
|
||||
showSaveDialog(
|
||||
options: Record<string, unknown>
|
||||
): Promise<{ canceled: boolean; filePath?: string }>;
|
||||
showOpenDialog(
|
||||
options: Record<string, unknown>
|
||||
): Promise<{ canceled: boolean; filePaths: string[] }>;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
interface FsModule {
|
||||
writeFile(path: string, data: Uint8Array): Promise<void>;
|
||||
}
|
||||
|
||||
const getRequire = (): ((id: string) => unknown) | null => {
|
||||
if (typeof window !== 'undefined' && 'require' in window) {
|
||||
return (window as unknown as { require: (id: string) => unknown }).require;
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
const req = getRequire();
|
||||
const fs = req ? (req('fs/promises') as FsModule) : null;
|
||||
const electron = req ? (req('electron') as ElectronModule) : null;
|
||||
import {
|
||||
PDFArray,
|
||||
PDFDict,
|
||||
|
|
@ -337,11 +367,11 @@ export async function editPDF(
|
|||
const pdfDoc = await PDFDocument.load(data);
|
||||
const posistions = await getDestPosition(pdfDoc);
|
||||
|
||||
setAnchors(pdfDoc, posistions);
|
||||
await setAnchors(pdfDoc, posistions);
|
||||
|
||||
const outlines = generateOutlines(headings, posistions, maxLevel);
|
||||
|
||||
setOutline(pdfDoc, outlines);
|
||||
await setOutline(pdfDoc, outlines);
|
||||
if (displayMetadata) {
|
||||
setMetadata(pdfDoc, frontMatter ?? {});
|
||||
}
|
||||
|
|
@ -354,37 +384,44 @@ export function setMetadata(
|
|||
pdfDoc: PDFDocument,
|
||||
{ title, author, keywords, subject, creator, created_at, updated_at }: FrontMatterCache
|
||||
) {
|
||||
if (title) {
|
||||
if (title && typeof title === 'string') {
|
||||
pdfDoc.setTitle(title, { showInWindowTitleBar: true });
|
||||
}
|
||||
if (author) {
|
||||
if (Array.isArray(author)) {
|
||||
pdfDoc.setAuthor(author.join(', '));
|
||||
pdfDoc.setAuthor(author.map(a => String(a)).join(', '));
|
||||
} else {
|
||||
pdfDoc.setAuthor(author.toString());
|
||||
pdfDoc.setAuthor(String(author));
|
||||
}
|
||||
}
|
||||
if (keywords) {
|
||||
pdfDoc.setKeywords(typeof keywords == 'string' ? [keywords] : keywords);
|
||||
const kwList = Array.isArray(keywords)
|
||||
? keywords.map(k => String(k))
|
||||
: typeof keywords === 'string'
|
||||
? [keywords]
|
||||
: [String(keywords)];
|
||||
pdfDoc.setKeywords(kwList);
|
||||
}
|
||||
if (subject) {
|
||||
if (subject && typeof subject === 'string') {
|
||||
pdfDoc.setSubject(subject);
|
||||
}
|
||||
pdfDoc.setCreator(creator ?? 'Obsidian');
|
||||
const creatorStr = typeof creator === 'string' ? creator : 'Obsidian';
|
||||
pdfDoc.setCreator(creatorStr);
|
||||
pdfDoc.setProducer('Obsidian');
|
||||
pdfDoc.setCreationDate(new Date(created_at ?? new Date()));
|
||||
pdfDoc.setModificationDate(new Date(updated_at ?? new Date()));
|
||||
const creationDate = created_at ? new Date(created_at as string | number | Date) : new Date();
|
||||
pdfDoc.setCreationDate(creationDate);
|
||||
const modDate = updated_at ? new Date(updated_at as string | number | Date) : new Date();
|
||||
pdfDoc.setModificationDate(modDate);
|
||||
}
|
||||
|
||||
export async function exportToPDF(
|
||||
outputFile: string,
|
||||
config: TConfig & PluginSettings, // Changed from BetterExportPdfPluginSettings
|
||||
w: any,
|
||||
w: { printToPDF(options: Record<string, unknown>): Promise<ArrayBuffer> },
|
||||
{ doc, frontMatter }: DocType
|
||||
) {
|
||||
console.log('output pdf:', outputFile);
|
||||
let pageSize = config['pageSize'] as PageSizeType;
|
||||
if (config['pageSize'] == 'Custom' && config['pageWidth'] && config['pageHeight']) {
|
||||
if (config['pageSize'] === 'Custom' && config['pageWidth'] && config['pageHeight']) {
|
||||
pageSize = {
|
||||
width: safeParseFloat(config['pageWidth'], 210) / 25.4,
|
||||
height: safeParseFloat(config['pageHeight'], 297) / 25.4
|
||||
|
|
@ -395,7 +432,7 @@ export async function exportToPDF(
|
|||
if (scale > 200 || scale < 10) {
|
||||
scale = 100;
|
||||
}
|
||||
const printOptions: any = {
|
||||
const printOptions: Record<string, unknown> = {
|
||||
landscape: config?.['landscape'],
|
||||
printBackground: config?.['printBackground'],
|
||||
generateTaggedPDF: config?.['generateTaggedPDF'],
|
||||
|
|
@ -413,7 +450,7 @@ export async function exportToPDF(
|
|||
: '<span></span>'
|
||||
};
|
||||
|
||||
if (config.marginType == '0') {
|
||||
if (config.marginType === '0') {
|
||||
printOptions['margins'] = {
|
||||
marginType: 'custom',
|
||||
top: 0,
|
||||
|
|
@ -421,11 +458,11 @@ export async function exportToPDF(
|
|||
left: 0,
|
||||
right: 0
|
||||
};
|
||||
} else if (config.marginType == '1') {
|
||||
} else if (config.marginType === '1') {
|
||||
printOptions['margins'] = {
|
||||
marginType: 'default'
|
||||
};
|
||||
} else if (config.marginType == '2') {
|
||||
} else if (config.marginType === '2') {
|
||||
printOptions['margins'] = {
|
||||
marginType: 'custom',
|
||||
top: 0.1,
|
||||
|
|
@ -433,7 +470,7 @@ export async function exportToPDF(
|
|||
left: 0.1,
|
||||
right: 0.1
|
||||
};
|
||||
} else if (config.marginType == '3') {
|
||||
} else if (config.marginType === '3') {
|
||||
// Custom Margin
|
||||
printOptions['margins'] = {
|
||||
marginType: 'custom',
|
||||
|
|
@ -455,21 +492,22 @@ export async function exportToPDF(
|
|||
maxLevel: safeParseInt(config?.maxLevel, 6)
|
||||
});
|
||||
|
||||
await fs.writeFile(outputFile, data);
|
||||
if (fs) {
|
||||
await fs.writeFile(outputFile, data);
|
||||
}
|
||||
|
||||
if (config.open) {
|
||||
// @ts-ignore
|
||||
electron.remote.shell.openPath(outputFile);
|
||||
if (config.open && electron) {
|
||||
void electron.remote.shell.openPath(outputFile);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
new Notice(`Export to PDF failed: ${error}`);
|
||||
showNotice(`Export to PDF failed: ${String(error)}`);
|
||||
}
|
||||
}
|
||||
|
||||
export async function getOutputFile(filename: string, isTimestamp?: boolean) {
|
||||
// @ts-ignore
|
||||
const result: Electron.SaveDialogReturnValue = await electron.remote.dialog.showSaveDialog({
|
||||
if (!electron) return;
|
||||
const result = await electron.remote.dialog.showSaveDialog({
|
||||
title: 'Export to PDF',
|
||||
defaultPath: `${filename + (isTimestamp ? `-${Date.now()}` : '')}.pdf`,
|
||||
filters: [
|
||||
|
|
@ -477,7 +515,7 @@ export async function getOutputFile(filename: string, isTimestamp?: boolean) {
|
|||
{ name: 'PDF', extensions: ['pdf'] }
|
||||
],
|
||||
properties: ['showOverwriteConfirmation', 'createDirectory']
|
||||
} as any);
|
||||
});
|
||||
|
||||
if (result.canceled) {
|
||||
return;
|
||||
|
|
@ -486,8 +524,8 @@ export async function getOutputFile(filename: string, isTimestamp?: boolean) {
|
|||
}
|
||||
|
||||
export async function getOutputPath(filename: string, isTimestamp?: boolean) {
|
||||
// @ts-ignore
|
||||
const result: Electron.OpenDialogReturnValue = await electron.remote.dialog.showOpenDialog({
|
||||
if (!electron) return;
|
||||
const result = await electron.remote.dialog.showOpenDialog({
|
||||
title: 'Export to PDF',
|
||||
defaultPath: filename,
|
||||
properties: ['openDirectory']
|
||||
|
|
|
|||
|
|
@ -1,29 +1,28 @@
|
|||
import {
|
||||
App,
|
||||
Component,
|
||||
type FrontMatterCache,
|
||||
MarkdownRenderer,
|
||||
MarkdownView,
|
||||
Notice,
|
||||
TFile
|
||||
} from 'obsidian';
|
||||
import { App, Component, MarkdownRenderer, MarkdownView, TFile } from 'obsidian';
|
||||
import type { TConfig } from '../../ui/export-pdf/modal';
|
||||
import { copyAttributes, fixAnchors, modifyDest } from './utils';
|
||||
import { checkAndFixCalloutMath } from '../../utils/fixer';
|
||||
import { showNotice } from 'utils/obsidian';
|
||||
|
||||
export function getAllStyles() {
|
||||
const cssTexts: string[] = [];
|
||||
|
||||
Array.from(document.styleSheets).forEach(sheet => {
|
||||
// @ts-ignore
|
||||
const id = sheet.ownerNode?.id;
|
||||
Array.from(activeDocument.styleSheets).forEach(sheet => {
|
||||
let id: string | undefined = undefined;
|
||||
let href: string | undefined = undefined;
|
||||
if (sheet.ownerNode) {
|
||||
if (sheet.ownerNode.instanceOf(HTMLElement)) {
|
||||
id = sheet.ownerNode.id;
|
||||
}
|
||||
if (sheet.ownerNode.instanceOf(HTMLLinkElement)) {
|
||||
href = sheet.ownerNode.href;
|
||||
}
|
||||
}
|
||||
|
||||
// <style id="svelte-xxx" ignore
|
||||
if (id?.startsWith('svelte-')) {
|
||||
return;
|
||||
}
|
||||
// @ts-ignore
|
||||
const href = sheet.ownerNode?.href;
|
||||
|
||||
const division = `/* ----------${id ? `id:${id}` : href ? `href:${href}` : ''}---------- */`;
|
||||
|
||||
|
|
@ -33,8 +32,8 @@ export function getAllStyles() {
|
|||
Array.from(sheet?.cssRules ?? []).forEach(rule => {
|
||||
cssTexts.push(rule.cssText);
|
||||
});
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
} catch {
|
||||
// ignore
|
||||
}
|
||||
});
|
||||
|
||||
|
|
@ -91,19 +90,19 @@ export function getPatchStyle() {
|
|||
|
||||
export function getPrintStyle() {
|
||||
const cssTexts: string[] = [];
|
||||
Array.from(document.styleSheets).forEach(sheet => {
|
||||
Array.from(activeDocument.styleSheets).forEach(sheet => {
|
||||
try {
|
||||
const cssRules = sheet?.cssRules ?? [];
|
||||
Array.from(cssRules).forEach(rule => {
|
||||
if (rule.constructor.name == 'CSSMediaRule') {
|
||||
if (rule.constructor.name === 'CSSMediaRule') {
|
||||
if ((rule as CSSMediaRule).conditionText === 'print') {
|
||||
const res = rule.cssText.replace(/@media print\s*\{(.+)\}/gms, '$1');
|
||||
cssTexts.push(res);
|
||||
}
|
||||
}
|
||||
});
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
} catch {
|
||||
// ignore
|
||||
}
|
||||
});
|
||||
return cssTexts;
|
||||
|
|
@ -113,9 +112,11 @@ function generateDocId(n: number) {
|
|||
return Array.from({ length: n }, () => ((16 * Math.random()) | 0).toString(16)).join('');
|
||||
}
|
||||
|
||||
export type AyncFnType = (...args: unknown[]) => Promise<unknown>;
|
||||
export type AyncFnType = Promise<unknown>;
|
||||
|
||||
export function getFrontMatter(app: App, file: TFile) {
|
||||
import { FrontMatterCache } from 'obsidian';
|
||||
|
||||
export function getFrontMatter(app: App, file: TFile): FrontMatterCache {
|
||||
const cache = app.metadataCache.getFileCache(file);
|
||||
return cache?.frontmatter ?? {};
|
||||
}
|
||||
|
|
@ -133,8 +134,6 @@ export type ParamType = {
|
|||
|
||||
// 逆向原生打印函数
|
||||
export async function renderMarkdown({ app, file, config, extra }: ParamType) {
|
||||
const startTime = new Date().getTime();
|
||||
|
||||
const ws = app.workspace;
|
||||
// if (ws.getActiveFile()?.path != file.path) {
|
||||
// const leaf = ws.getLeaf(true);
|
||||
|
|
@ -146,21 +145,22 @@ export async function renderMarkdown({ app, file, config, extra }: ParamType) {
|
|||
const leaf = ws.getLeaf(true);
|
||||
await leaf.openFile(file);
|
||||
const view = leaf.view as MarkdownView;
|
||||
// @ts-ignore
|
||||
const data: string = view?.data ?? ws?.getActiveFileView()?.data ?? ws.activeEditor?.data;
|
||||
const activeFileView = ws.getActiveFileView() as MarkdownView | null;
|
||||
const activeEditor = ws.activeEditor as MarkdownView | null;
|
||||
const data: string = view?.data ?? activeFileView?.data ?? activeEditor?.data ?? '';
|
||||
if (!data) {
|
||||
new Notice('data is empty!');
|
||||
showNotice('Data is empty!');
|
||||
}
|
||||
|
||||
const frontMatter = getFrontMatter(app, file);
|
||||
|
||||
const cssclasses = [];
|
||||
const cssclasses: string[] = [];
|
||||
for (const [key, val] of Object.entries(frontMatter)) {
|
||||
if (key.toLowerCase() == 'cssclass' || key.toLowerCase() == 'cssclasses') {
|
||||
if (key.toLowerCase() === 'cssclass' || key.toLowerCase() === 'cssclasses') {
|
||||
if (Array.isArray(val)) {
|
||||
cssclasses.push(...val);
|
||||
cssclasses.push(...(val as unknown[]).map(v => String(v)));
|
||||
} else {
|
||||
cssclasses.push(val);
|
||||
cssclasses.push(String(val));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -168,18 +168,19 @@ export async function renderMarkdown({ app, file, config, extra }: ParamType) {
|
|||
const comp = new Component();
|
||||
comp.load();
|
||||
|
||||
const printEl = document.body.createDiv('print');
|
||||
const printEl = activeDocument.body.createDiv('print');
|
||||
const viewEl = printEl.createDiv({
|
||||
cls: `markdown-preview-view markdown-rendered ${cssclasses.join(' ')}`
|
||||
});
|
||||
app.vault.cachedRead(file);
|
||||
void app.vault.cachedRead(file);
|
||||
|
||||
// @ts-ignore
|
||||
viewEl.toggleClass('rtl', app.vault.getConfig('rightToLeft'));
|
||||
// @ts-ignore
|
||||
viewEl.toggleClass('show-properties', 'hidden' !== app.vault.getConfig('propertiesInDocument'));
|
||||
viewEl.toggleClass('rtl', app.vault.getConfig('rightToLeft') as boolean);
|
||||
viewEl.toggleClass(
|
||||
'show-properties',
|
||||
'hidden' !== (app.vault.getConfig('propertiesInDocument') as string)
|
||||
);
|
||||
|
||||
const title = extra?.title ?? frontMatter?.title ?? file.basename;
|
||||
const title = extra?.title ?? (frontMatter?.title as string | undefined) ?? file.basename;
|
||||
viewEl.createEl('h1', { text: title }, e => {
|
||||
e.addClass('__title__');
|
||||
e.style.display = config.showTitle ? 'block' : 'none';
|
||||
|
|
@ -222,7 +223,7 @@ export async function renderMarkdown({ app, file, config, extra }: ParamType) {
|
|||
// We allow the render to complete (including implicit post-processing on the detached element)
|
||||
// and then move the content. The subsequent manual postProcess call ensures we capture
|
||||
// any necessary promises for the PDF generation wait-cycle.
|
||||
const tempContainer = document.createElement('div');
|
||||
const tempContainer = activeDocument.createElement('div');
|
||||
// Apply the fix for callout math blocks if needed
|
||||
const linesContent = lines.join('\n');
|
||||
const fixedContent = checkAndFixCalloutMath(linesContent) ?? linesContent;
|
||||
|
|
@ -261,7 +262,7 @@ export async function renderMarkdown({ app, file, config, extra }: ParamType) {
|
|||
printEl.findAll('a.internal-link').forEach((el: HTMLElement) => {
|
||||
const [title, anchor] = el.dataset.href?.split('#') ?? [];
|
||||
|
||||
if ((!title || title?.length == 0 || title == file.basename) && anchor?.startsWith('^')) {
|
||||
if ((!title || title?.length === 0 || title === file.basename) && anchor?.startsWith('^')) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -269,13 +270,13 @@ export async function renderMarkdown({ app, file, config, extra }: ParamType) {
|
|||
});
|
||||
try {
|
||||
await fixWaitRender(data, viewEl);
|
||||
} catch (error) {
|
||||
} catch {
|
||||
console.warn('wait timeout');
|
||||
}
|
||||
|
||||
fixCanvasToImage(viewEl);
|
||||
|
||||
const doc = document.implementation.createHTMLDocument('document');
|
||||
const doc = activeDocument.implementation.createHTMLDocument('document');
|
||||
doc.body.appendChild(printEl.cloneNode(true));
|
||||
|
||||
printEl.detach();
|
||||
|
|
@ -283,7 +284,6 @@ export async function renderMarkdown({ app, file, config, extra }: ParamType) {
|
|||
printEl.remove();
|
||||
doc.title = title;
|
||||
leaf.detach();
|
||||
console.log(`md render time:${new Date().getTime() - startTime}ms`);
|
||||
return { doc, frontMatter, file };
|
||||
}
|
||||
|
||||
|
|
@ -298,7 +298,7 @@ export function encodeEmbeds(doc: Document) {
|
|||
const spans = Array.from(doc.querySelectorAll('span.markdown-embed')).reverse();
|
||||
spans.forEach((el: Element) => {
|
||||
const span = el as HTMLElement;
|
||||
span.innerHTML = encodeURIComponent(span.innerHTML);
|
||||
span['innerHTML'] = encodeURIComponent(span['innerHTML']);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -308,7 +308,7 @@ export async function fixWaitRender(data: string, viewEl: HTMLElement) {
|
|||
}
|
||||
try {
|
||||
await waitForDomChange(viewEl);
|
||||
} catch (error) {
|
||||
} catch {
|
||||
await sleep(1000);
|
||||
}
|
||||
}
|
||||
|
|
@ -318,7 +318,7 @@ export async function fixWaitRender(data: string, viewEl: HTMLElement) {
|
|||
export function fixCanvasToImage(el: HTMLElement) {
|
||||
for (const canvas of Array.from(el.querySelectorAll('canvas'))) {
|
||||
const data = canvas.toDataURL();
|
||||
const img = document.createElement('img');
|
||||
const img = activeDocument.createElement('img');
|
||||
img.src = data;
|
||||
copyAttributes(img, canvas.attributes);
|
||||
img.className = '__canvas__';
|
||||
|
|
@ -328,7 +328,7 @@ export function fixCanvasToImage(el: HTMLElement) {
|
|||
}
|
||||
|
||||
export function createWebview(scale = 1.25) {
|
||||
const webview = document.createElement('webview');
|
||||
const webview = activeDocument.createElement('webview');
|
||||
webview.src = `app://obsidian.md/help.html`;
|
||||
webview.setAttribute(
|
||||
'style',
|
||||
|
|
@ -345,9 +345,9 @@ export function createWebview(scale = 1.25) {
|
|||
|
||||
function waitForDomChange(target: HTMLElement, timeout = 2000, interval = 200): Promise<boolean> {
|
||||
return new Promise((resolve, reject) => {
|
||||
let timer: any;
|
||||
const observer = new MutationObserver(m => {
|
||||
window.clearTimeout(timer);
|
||||
let timer: number | null = null;
|
||||
const observer = new MutationObserver(() => {
|
||||
if (timer) window.clearTimeout(timer);
|
||||
timer = window.setTimeout(() => {
|
||||
observer.disconnect();
|
||||
resolve(true);
|
||||
|
|
|
|||
|
|
@ -24,14 +24,14 @@ export class TreeNode {
|
|||
* h2 1.3
|
||||
*/
|
||||
|
||||
export function getHeadingTree(doc = document) {
|
||||
export function getHeadingTree(doc = activeDocument) {
|
||||
const headings = doc.querySelectorAll('h1, h2, h3, h4, h5, h6');
|
||||
const root = new TreeNode('', 'Root', 0);
|
||||
let prev = root;
|
||||
|
||||
headings.forEach((el: Element) => {
|
||||
const heading = el as HTMLElement;
|
||||
if (heading.style.display == 'none') {
|
||||
if (heading.style.display === 'none') {
|
||||
return;
|
||||
}
|
||||
const level = parseInt(heading.tagName.slice(1));
|
||||
|
|
@ -56,16 +56,16 @@ export function getHeadingTree(doc = document) {
|
|||
}
|
||||
|
||||
// modify heading/block, and get heading/block flag
|
||||
export function modifyDest(doc: Document) {
|
||||
const data = new Map();
|
||||
export function modifyDest(doc: Document): Map<string, string> {
|
||||
const data = new Map<string, string>();
|
||||
doc.querySelectorAll('h1, h2, h3, h4, h5, h6').forEach((el: Element, i) => {
|
||||
const heading = el as HTMLElement;
|
||||
const link = document.createElement('a');
|
||||
const link = activeDocument.createElement('a');
|
||||
const flag = `${heading.tagName.toLowerCase()}-${i}`;
|
||||
link.href = `af://${flag}`;
|
||||
link.className = 'md-print-anchor';
|
||||
heading.appendChild(link);
|
||||
data.set(heading.dataset.heading, flag);
|
||||
data.set(heading.dataset.heading ?? '', flag);
|
||||
});
|
||||
|
||||
return data;
|
||||
|
|
@ -87,7 +87,7 @@ export function fixAnchors(doc: Document, dest: Map<string, string>, basename: s
|
|||
}
|
||||
|
||||
if (anchor?.length > 0) {
|
||||
if (title?.length > 0 && title != basename) {
|
||||
if (title?.length > 0 && title !== basename) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -135,14 +135,16 @@ export const mm2px = (mm: number) => {
|
|||
|
||||
export function traverseFolder(path: TFolder | TFile): TFile[] {
|
||||
if (path instanceof TFile) {
|
||||
if (path.extension == 'md') {
|
||||
if (path.extension === 'md') {
|
||||
return [path];
|
||||
}
|
||||
return [];
|
||||
}
|
||||
const arr = [];
|
||||
for (const item of path.children) {
|
||||
arr.push(...traverseFolder(item as TFolder));
|
||||
if (item instanceof TFolder || item instanceof TFile) {
|
||||
arr.push(...traverseFolder(item));
|
||||
}
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
|
|
@ -155,7 +157,7 @@ export function copyAttributes(node: HTMLElement, attributes: NamedNodeMap) {
|
|||
}
|
||||
|
||||
export function render(tpl: string, data: Record<string, string>) {
|
||||
return tpl.replace(/\{\{(.*?)\}\}/g, (match, key) => data[key.trim()]);
|
||||
return tpl.replace(/\{\{(.*?)\}\}/g, (match: string, key: string) => data[key.trim()]);
|
||||
}
|
||||
|
||||
export function isNumber(str: string) {
|
||||
|
|
@ -164,9 +166,9 @@ export function isNumber(str: string) {
|
|||
|
||||
export function safeParseInt(str?: string, default_ = 0) {
|
||||
try {
|
||||
const num = parseInt(String(str));
|
||||
const num = parseInt(String(str), 10);
|
||||
return isNaN(num) ? default_ : num;
|
||||
} catch (e) {
|
||||
} catch {
|
||||
return default_;
|
||||
}
|
||||
}
|
||||
|
|
@ -174,7 +176,7 @@ export function safeParseFloat(str?: string, default_ = 0.0) {
|
|||
try {
|
||||
const num = parseFloat(String(str));
|
||||
return isNaN(num) ? default_ : num;
|
||||
} catch (e) {
|
||||
} catch {
|
||||
return default_;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { Notice } from 'obsidian';
|
||||
import type LatexReferencer from '../../main';
|
||||
import { TextTransformSuggestModal } from '../../ui/snippets/modal';
|
||||
import { showNotice } from 'utils/obsidian';
|
||||
|
||||
export class SnippetManager {
|
||||
constructor(private plugin: LatexReferencer) {}
|
||||
|
|
@ -8,24 +8,24 @@ export class SnippetManager {
|
|||
onLoad() {
|
||||
this.plugin.addCommand({
|
||||
id: 'add-tags-frontmatter',
|
||||
name: 'Add Tags',
|
||||
name: 'Add tags',
|
||||
editorCallback: editor => {
|
||||
const content = editor.getValue().replace(/\r\n/g, '\n');
|
||||
const frontmatterPattern = /^---\n[\s\S]*?\n---\n?/;
|
||||
if (frontmatterPattern.test(content)) {
|
||||
new Notice('Frontmatter already exists at the top of this note.');
|
||||
showNotice('Frontmatter already exists at the top of this note.');
|
||||
return;
|
||||
}
|
||||
|
||||
const tagsFrontmatter = '---\ntags:\n - \naliases:\n - \n---\n\n';
|
||||
editor.replaceRange(tagsFrontmatter, { line: 0, ch: 0 });
|
||||
new Notice('Added tags frontmatter.');
|
||||
showNotice('Added tags frontmatter.');
|
||||
}
|
||||
});
|
||||
|
||||
this.plugin.addCommand({
|
||||
id: 'run-text-transform-snippet',
|
||||
name: 'Run Text Transform Snippet',
|
||||
name: 'Run text transform snippet',
|
||||
editorCallback: editor => {
|
||||
new TextTransformSuggestModal(this.plugin.app, editor).open();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -67,8 +67,8 @@ function cleanZoteroHighlightLine(input: string): string {
|
|||
return input.replace(
|
||||
/<mark[^>]*>\s*[\u0022\u201C\u201D]?(.*?)[\u0022\u201C\u201D]?\s*<\/mark>\s*(.*)/g,
|
||||
(_match, highlightedText: string, trailingText: string) => {
|
||||
const normalized = highlightedText.replace(/[\.,]$/, '');
|
||||
return `\"${normalized}.\" \u2014 ${trailingText}`;
|
||||
const normalized = highlightedText.replace(/[.,]$/, '');
|
||||
return `"${normalized}." \u2014 ${trailingText}`;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,13 +1,17 @@
|
|||
import { Extension, Prec } from '@codemirror/state';
|
||||
import { Extension, Prec, EditorState } from '@codemirror/state';
|
||||
import { EditorView, ViewPlugin, ViewUpdate } from '@codemirror/view';
|
||||
import { Notice } from 'obsidian';
|
||||
import { showNotice } from 'utils/obsidian';
|
||||
import LatexReferencer from '../../main';
|
||||
|
||||
interface CleanableDiv extends HTMLDivElement {
|
||||
_cleanup?: () => void;
|
||||
}
|
||||
|
||||
class TikzLivePreviewOverlay {
|
||||
private overlayEl: HTMLDivElement | null = null;
|
||||
private containerEl: HTMLDivElement | null = null;
|
||||
private currentSource: string = '';
|
||||
private debounceTimeout: any = null;
|
||||
private debounceTimeout: number | null = null;
|
||||
private isDragging = false;
|
||||
private startX = 0;
|
||||
private startY = 0;
|
||||
|
|
@ -46,34 +50,34 @@ class TikzLivePreviewOverlay {
|
|||
this.overlayEl.classList.add('tikz-live-preview-overlay');
|
||||
|
||||
// CSS Styles for floating overlay
|
||||
this.overlayEl.style.position = 'fixed';
|
||||
this.overlayEl.style.zIndex = '1000';
|
||||
this.overlayEl.style.top = '100px';
|
||||
this.overlayEl.style.right = '50px';
|
||||
this.overlayEl.style.width = '320px';
|
||||
this.overlayEl.style.height = '320px';
|
||||
this.overlayEl.style.backgroundColor = 'var(--background-primary-alt)';
|
||||
this.overlayEl.style.border = '1px solid var(--border-color)';
|
||||
this.overlayEl.style.borderRadius = '8px';
|
||||
this.overlayEl.style.boxShadow = '0 4px 12px rgba(0, 0, 0, 0.15)';
|
||||
this.overlayEl.style.display = 'flex';
|
||||
this.overlayEl.style.flexDirection = 'column';
|
||||
this.overlayEl.style.overflow = 'hidden';
|
||||
this.overlayEl.style.setProperty('position', 'fixed');
|
||||
this.overlayEl.style.setProperty('z-index', '1000');
|
||||
this.overlayEl.style.setProperty('top', '100px');
|
||||
this.overlayEl.style.setProperty('right', '50px');
|
||||
this.overlayEl.style.setProperty('width', '320px');
|
||||
this.overlayEl.style.setProperty('height', '320px');
|
||||
this.overlayEl.style.setProperty('background-color', 'var(--background-primary-alt)');
|
||||
this.overlayEl.style.setProperty('border', '1px solid var(--border-color)');
|
||||
this.overlayEl.style.setProperty('border-radius', '8px');
|
||||
this.overlayEl.style.setProperty('box-shadow', '0 4px 12px rgba(0, 0, 0, 0.15)');
|
||||
this.overlayEl.style.setProperty('display', 'flex');
|
||||
this.overlayEl.style.setProperty('flex-direction', 'column');
|
||||
this.overlayEl.style.setProperty('overflow', 'hidden');
|
||||
|
||||
// Drag Handle / Header Container
|
||||
const handleEl = doc.createElement('div');
|
||||
handleEl.classList.add('tikz-live-preview-handle');
|
||||
handleEl.style.cursor = 'move';
|
||||
handleEl.style.padding = '6px 10px';
|
||||
handleEl.style.backgroundColor = 'var(--background-secondary-alt)';
|
||||
handleEl.style.borderBottom = '1px solid var(--border-color)';
|
||||
handleEl.style.fontSize = '0.85em';
|
||||
handleEl.style.fontWeight = 'bold';
|
||||
handleEl.style.color = 'var(--text-muted)';
|
||||
handleEl.style.userSelect = 'none';
|
||||
handleEl.style.display = 'flex';
|
||||
handleEl.style.justifyContent = 'space-between';
|
||||
handleEl.style.alignItems = 'center';
|
||||
handleEl.style.setProperty('cursor', 'move');
|
||||
handleEl.style.setProperty('padding', '6px 10px');
|
||||
handleEl.style.setProperty('background-color', 'var(--background-secondary-alt)');
|
||||
handleEl.style.setProperty('border-bottom', '1px solid var(--border-color)');
|
||||
handleEl.style.setProperty('font-size', '0.85em');
|
||||
handleEl.style.setProperty('font-weight', 'bold');
|
||||
handleEl.style.setProperty('color', 'var(--text-muted)');
|
||||
handleEl.style.setProperty('user-select', 'none');
|
||||
handleEl.style.setProperty('display', 'flex');
|
||||
handleEl.style.setProperty('justify-content', 'space-between');
|
||||
handleEl.style.setProperty('align-items', 'center');
|
||||
|
||||
const titleEl = doc.createElement('span');
|
||||
titleEl.textContent = 'TikZ Live Preview';
|
||||
|
|
@ -81,14 +85,14 @@ class TikzLivePreviewOverlay {
|
|||
|
||||
const exportBtn = doc.createElement('button');
|
||||
exportBtn.textContent = 'Export SVG';
|
||||
exportBtn.style.padding = '2px 8px';
|
||||
exportBtn.style.fontSize = '0.8em';
|
||||
exportBtn.style.borderRadius = '4px';
|
||||
exportBtn.style.border = '1px solid var(--border-color)';
|
||||
exportBtn.style.backgroundColor = 'var(--interactive-accent)';
|
||||
exportBtn.style.color = 'var(--text-on-accent)';
|
||||
exportBtn.style.cursor = 'pointer';
|
||||
exportBtn.style.fontWeight = 'bold';
|
||||
exportBtn.style.setProperty('padding', '2px 8px');
|
||||
exportBtn.style.setProperty('font-size', '0.8em');
|
||||
exportBtn.style.setProperty('border-radius', '4px');
|
||||
exportBtn.style.setProperty('border', '1px solid var(--border-color)');
|
||||
exportBtn.style.setProperty('background-color', 'var(--interactive-accent)');
|
||||
exportBtn.style.setProperty('color', 'var(--text-on-accent)');
|
||||
exportBtn.style.setProperty('cursor', 'pointer');
|
||||
exportBtn.style.setProperty('font-weight', 'bold');
|
||||
|
||||
// Prevent drag events when clicking button
|
||||
exportBtn.onmousedown = (e: MouseEvent) => {
|
||||
|
|
@ -107,13 +111,13 @@ class TikzLivePreviewOverlay {
|
|||
this.containerEl = doc.createElement('div');
|
||||
this.containerEl.classList.add('tikz-live-preview-container');
|
||||
this.containerEl.classList.add('block-language-tikz');
|
||||
this.containerEl.style.flex = '1';
|
||||
this.containerEl.style.overflow = 'auto';
|
||||
this.containerEl.style.display = 'flex';
|
||||
this.containerEl.style.justifyContent = 'center';
|
||||
this.containerEl.style.alignItems = 'center';
|
||||
this.containerEl.style.padding = '10px';
|
||||
this.containerEl.style.backgroundColor = 'transparent';
|
||||
this.containerEl.style.setProperty('flex', '1');
|
||||
this.containerEl.style.setProperty('overflow', 'auto');
|
||||
this.containerEl.style.setProperty('display', 'flex');
|
||||
this.containerEl.style.setProperty('justify-content', 'center');
|
||||
this.containerEl.style.setProperty('align-items', 'center');
|
||||
this.containerEl.style.setProperty('padding', '10px');
|
||||
this.containerEl.style.setProperty('background-color', 'transparent');
|
||||
this.overlayEl.appendChild(this.containerEl);
|
||||
|
||||
// Drag functionality
|
||||
|
|
@ -140,9 +144,9 @@ class TikzLivePreviewOverlay {
|
|||
newLeft = Math.max(0, Math.min(newLeft, maxLeft));
|
||||
newTop = Math.max(0, Math.min(newTop, maxTop));
|
||||
|
||||
this.overlayEl.style.left = `${newLeft}px`;
|
||||
this.overlayEl.style.top = `${newTop}px`;
|
||||
this.overlayEl.style.right = 'auto';
|
||||
this.overlayEl.style.setProperty('left', `${newLeft}px`);
|
||||
this.overlayEl.style.setProperty('top', `${newTop}px`);
|
||||
this.overlayEl.style.setProperty('right', 'auto');
|
||||
};
|
||||
|
||||
const mouseUpHandler = () => {
|
||||
|
|
@ -153,7 +157,7 @@ class TikzLivePreviewOverlay {
|
|||
doc.addEventListener('mouseup', mouseUpHandler);
|
||||
|
||||
// Save reference to clean up event listeners later
|
||||
(this.overlayEl as any)._cleanup = () => {
|
||||
(this.overlayEl as CleanableDiv)._cleanup = () => {
|
||||
doc.removeEventListener('mousemove', mouseMoveHandler);
|
||||
doc.removeEventListener('mouseup', mouseUpHandler);
|
||||
};
|
||||
|
|
@ -193,7 +197,7 @@ class TikzLivePreviewOverlay {
|
|||
|
||||
const svgEl = this.containerEl.querySelector('svg');
|
||||
if (!svgEl) {
|
||||
new Notice('No rendered TikZ SVG found to export yet.');
|
||||
showNotice('No rendered TikZ svg found to export yet.');
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -232,7 +236,7 @@ class TikzLivePreviewOverlay {
|
|||
|
||||
URL.revokeObjectURL(svgUrl);
|
||||
|
||||
new Notice('TikZ diagram exported as SVG successfully.');
|
||||
showNotice('TikZ diagram exported as svg successfully.');
|
||||
}
|
||||
|
||||
public destroy() {
|
||||
|
|
@ -240,8 +244,9 @@ class TikzLivePreviewOverlay {
|
|||
window.clearTimeout(this.debounceTimeout);
|
||||
}
|
||||
if (this.overlayEl) {
|
||||
if (typeof (this.overlayEl as any)._cleanup === 'function') {
|
||||
(this.overlayEl as any)._cleanup();
|
||||
const cleanable = this.overlayEl as CleanableDiv;
|
||||
if (typeof cleanable._cleanup === 'function') {
|
||||
cleanable._cleanup();
|
||||
}
|
||||
this.overlayEl.remove();
|
||||
this.overlayEl = null;
|
||||
|
|
@ -278,7 +283,7 @@ export const createTikzLivePreviewPlugin = (plugin: LatexReferencer): Extension
|
|||
}
|
||||
}
|
||||
|
||||
private getTikzBlockAtPos(state: any, pos: number): { source: string } | null {
|
||||
private getTikzBlockAtPos(state: EditorState, pos: number): { source: string } | null {
|
||||
try {
|
||||
const doc = state.doc;
|
||||
const curLine = doc.lineAt(pos).number;
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ export class TikzRenderer {
|
|||
}
|
||||
|
||||
private async fetchWithFallback(urls: string[]): Promise<string> {
|
||||
let lastError: any = null;
|
||||
let lastError: unknown = null;
|
||||
for (const url of urls) {
|
||||
try {
|
||||
const res = await requestUrl({
|
||||
|
|
@ -213,11 +213,11 @@ export class TikzRenderer {
|
|||
|
||||
private unloadTikZJax(doc: Document) {
|
||||
// Trigger the cleanup function in the document's window context if it exists
|
||||
const win = doc.defaultView as any;
|
||||
const win = doc.defaultView as unknown;
|
||||
if (win && typeof win.TikzJaxCleanup === 'function') {
|
||||
win
|
||||
.TikzJaxCleanup()
|
||||
.catch((err: any) => console.error('Latex Referencer: Error cleaning up TikZJax', err));
|
||||
.catch((err: unknown) => console.error('Latex Referencer: Error cleaning up TikZJax', err));
|
||||
}
|
||||
|
||||
doc.getElementById('tikzjax')?.remove();
|
||||
|
|
@ -245,7 +245,7 @@ export class TikzRenderer {
|
|||
}
|
||||
|
||||
// Retrieve pop-out windows from workspace
|
||||
const workspace = this.plugin.app.workspace as any;
|
||||
const workspace = this.plugin.app.workspace as unknown;
|
||||
const floatingSplit = workspace.floatingSplit;
|
||||
if (floatingSplit && floatingSplit.children) {
|
||||
for (const child of floatingSplit.children) {
|
||||
|
|
|
|||
14
src/main.ts
14
src/main.ts
|
|
@ -133,7 +133,7 @@ export default class LatexReferencer extends Plugin {
|
|||
|
||||
// Menu items for file export
|
||||
this.registerEvent(
|
||||
(this.app.workspace as any).on('file-menu', (menu: Menu, file: TFile | TFolder) => {
|
||||
(this.app.workspace as unknown).on('file-menu', (menu: Menu, file: TFile | TFolder) => {
|
||||
let title = file instanceof TFolder ? 'Export folder to PDF' : 'Better Export PDF';
|
||||
if (isDev) {
|
||||
title = `${title} (dev)`;
|
||||
|
|
@ -152,7 +152,7 @@ export default class LatexReferencer extends Plugin {
|
|||
);
|
||||
|
||||
this.registerEvent(
|
||||
(this.app.workspace as any).on('file-menu', (menu: Menu, file: TFile | TFolder) => {
|
||||
(this.app.workspace as unknown).on('file-menu', (menu: Menu, file: TFile | TFolder) => {
|
||||
if (file instanceof TFolder) {
|
||||
let title = 'Export to PDF...';
|
||||
if (isDev) {
|
||||
|
|
@ -254,14 +254,14 @@ export default class LatexReferencer extends Plugin {
|
|||
const plugin = this;
|
||||
|
||||
const uninstaller = around(instance, {
|
||||
onLinkHover(old: any) {
|
||||
onLinkHover(old: unknown) {
|
||||
return function (
|
||||
this: any,
|
||||
hoverParent: any,
|
||||
targetEl: any,
|
||||
this: unknown,
|
||||
hoverParent: unknown,
|
||||
targetEl: unknown,
|
||||
linktext: string,
|
||||
sourcePath: string,
|
||||
state: any
|
||||
state: unknown
|
||||
) {
|
||||
const { path, subpath } = parseLinktext(linktext);
|
||||
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ import {
|
|||
import Progress from 'features/export-pdf/Progress.svelte';
|
||||
import { mount, unmount } from 'svelte';
|
||||
import pLimit from 'p-limit';
|
||||
export type PageSizeType = Electron.PrintToPDFOptions['pageSize'];
|
||||
export type PageSizeType = string | { width: number; height: number };
|
||||
|
||||
export interface TConfig {
|
||||
pageSize: string;
|
||||
|
|
@ -74,8 +74,8 @@ export class ExportConfigModal extends Modal {
|
|||
multiplePdf?: boolean;
|
||||
callback!: Callback;
|
||||
file: TFile | TFolder;
|
||||
preview: any;
|
||||
webviews: any[];
|
||||
preview: unknown;
|
||||
webviews: unknown[];
|
||||
previewDiv!: HTMLDivElement;
|
||||
completed: boolean;
|
||||
docs: DocType[];
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import { PatchedSuggester, PreviewInfo, Suggester } from './types';
|
|||
|
||||
export function patchSuggesterWithQuickPreview<T>(
|
||||
plugin: LatexReferencer,
|
||||
suggesterClass: new (...args: any[]) => Suggester<T>,
|
||||
suggesterClass: new (...args: unknown[]) => Suggester<T>,
|
||||
itemNormalizer: (item: T) => PreviewInfo | null
|
||||
) {
|
||||
const uninstaller = around(suggesterClass.prototype, {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { App, MarkdownView, Modifier, Platform, Pos, TFile } from 'obsidian';
|
||||
import { App, MarkdownView, Modifier, Notice, Platform, Pos, TFile } from 'obsidian';
|
||||
import { locToEditorPosition } from 'utils/editor';
|
||||
import { LeafArgs } from '../declarations';
|
||||
|
||||
|
|
@ -34,16 +34,16 @@ export async function openFileAndSelectPosition(
|
|||
////////////
|
||||
|
||||
export function getModifierNameInPlatform(mod: Modifier): string {
|
||||
if (mod == 'Mod') {
|
||||
if (mod === 'Mod') {
|
||||
return Platform.isMacOS || Platform.isIosApp ? '⌘' : 'ctrl';
|
||||
}
|
||||
if (mod == 'Shift') {
|
||||
if (mod === 'Shift') {
|
||||
return 'shift';
|
||||
}
|
||||
if (mod == 'Alt') {
|
||||
if (mod === 'Alt') {
|
||||
return Platform.isMacOS || Platform.isIosApp ? '⌥' : 'alt';
|
||||
}
|
||||
if (mod == 'Meta') {
|
||||
if (mod === 'Meta') {
|
||||
return Platform.isMacOS || Platform.isIosApp ? '⌘' : Platform.isWin ? 'win' : 'meta';
|
||||
}
|
||||
return 'ctrl';
|
||||
|
|
@ -57,3 +57,8 @@ export function generateEqId(length: number = 8): string {
|
|||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
export function showNotice(message: string): Notice {
|
||||
const NoticeConstructor = Notice;
|
||||
return new NoticeConstructor(message);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -93,7 +93,7 @@ describe('MockVault API tests', () => {
|
|||
|
||||
// copy folder error (not supported)
|
||||
const fakeFolderAsFile = new TFolder();
|
||||
await expect(vault.copy(fakeFolderAsFile as any, 'copied_folder')).rejects.toThrow(
|
||||
await expect(vault.copy(fakeFolderAsFile as unknown, 'copied_folder')).rejects.toThrow(
|
||||
'MockVault.copy only supports TFile in this mock.'
|
||||
);
|
||||
|
||||
|
|
@ -164,7 +164,7 @@ describe('MockVault API tests', () => {
|
|||
}
|
||||
|
||||
// rename invalid type error
|
||||
const fakeObject = { path: 'fake' } as any;
|
||||
const fakeObject = { path: 'fake' } as unknown;
|
||||
expect(() => vault.rename(fakeObject, 'renamed')).toThrow('File is not a file or folder');
|
||||
});
|
||||
|
||||
|
|
@ -184,9 +184,9 @@ describe('MockVault API tests', () => {
|
|||
expect(() => cache.fileToLinktext(file, 'source')).toThrow('Method not implemented.');
|
||||
expect(() => cache.on('changed', () => {})).toThrow('Method not implemented.');
|
||||
expect(() => cache.off('changed', () => {})).toThrow('Method not implemented.');
|
||||
expect(() => cache.offref({} as any)).toThrow('Method not implemented.');
|
||||
expect(() => cache.offref({})).toThrow('Method not implemented.');
|
||||
expect(() => cache.trigger('changed')).toThrow('Method not implemented.');
|
||||
expect(() => cache.tryTrigger({} as any, [])).toThrow('Method not implemented.');
|
||||
expect(() => cache.tryTrigger({}, [])).toThrow('Method not implemented.');
|
||||
|
||||
// MockVault unimplemented methods
|
||||
expect(() => vault.append(file, 'data')).toThrow('Method not implemented.');
|
||||
|
|
@ -199,9 +199,9 @@ describe('MockVault API tests', () => {
|
|||
expect(() => vault.getResourcePath(file)).toThrow('Method not implemented.');
|
||||
expect(() => vault.on('create', () => {})).toThrow('Method not implemented.');
|
||||
expect(() => vault.off('create', () => {})).toThrow('Method not implemented.');
|
||||
expect(() => vault.offref({} as any)).toThrow('Method not implemented.');
|
||||
expect(() => vault.offref({})).toThrow('Method not implemented.');
|
||||
expect(() => vault.trigger('create')).toThrow('Method not implemented.');
|
||||
expect(() => vault.tryTrigger({} as any, [])).toThrow('Method not implemented.');
|
||||
expect(() => vault.tryTrigger({}, [])).toThrow('Method not implemented.');
|
||||
expect(() => vault.process(file, d => d)).toThrow('Method not implemented.');
|
||||
vault.loadLocalStorage();
|
||||
vault.saveLocalStorage();
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ describe('format.ts tests', () => {
|
|||
const dummyFile = {} as TFile;
|
||||
const settings = {
|
||||
eqNumberPrefix: 'Prefix-'
|
||||
} as any;
|
||||
} as unknown;
|
||||
expect(getEqNumberPrefix(dummyApp, dummyFile, settings)).toBe('Prefix-');
|
||||
});
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in a new issue