update at 2025-09-22 16:49:33
This commit is contained in:
@@ -54,6 +54,7 @@ export class ArticleRender implements MDRendererCallback {
|
||||
markedParser: MarkedParser;
|
||||
cachedElements: Map<string, string> = new Map();
|
||||
debouncedRenderMarkdown: (...args: any[]) => void;
|
||||
originalMarkdown: string | null = null; // 保存去除前处理前的原始 Markdown
|
||||
|
||||
constructor(app: App, itemView: ItemView, styleEl: HTMLElement, articleDiv: HTMLDivElement) {
|
||||
this.app = app;
|
||||
@@ -162,10 +163,28 @@ export class ArticleRender implements MDRendererCallback {
|
||||
else {
|
||||
md = '没有可渲染的笔记或文件不支持渲染';
|
||||
}
|
||||
this.originalMarkdown = md; // 保存原始内容(含 frontmatter)供封面/摘要自动提取
|
||||
if (md.startsWith('---')) {
|
||||
md = md.replace(FRONT_MATTER_REGEX, '');
|
||||
}
|
||||
|
||||
// 将标准 markdown 图片语法转为 wikilink 语法,便于现有 LocalImageManager 识别
|
||||
if (this.settings.enableMarkdownImageToWikilink) {
|
||||
// 匹配 ;不跨行;忽略包含空格的 URL 末尾注释
|
||||
// 捕获路径和文件名,文件名取最后一段
|
||||
md = md.replace(/!\[[^\]]*\]\(([^)\s]+)\)/g, (full, p1) => {
|
||||
try {
|
||||
// 去掉可能的 query/hash
|
||||
const clean = p1.split('#')[0].split('?')[0];
|
||||
const filename = clean.split('/').pop();
|
||||
if (!filename) return full; // 无法解析
|
||||
// 仅当是常见图片扩展时才替换
|
||||
if (!filename.match(/\.(png|jpe?g|gif|bmp|webp|svg|tiff)$/i)) return full;
|
||||
return `![[${filename}]]`;
|
||||
} catch { return full; }
|
||||
});
|
||||
}
|
||||
|
||||
this.articleHTML = await this.markedParser.parse(md);
|
||||
this.setStyle(this.getCSS());
|
||||
this.setArticle(this.articleHTML);
|
||||
@@ -233,11 +252,14 @@ export class ArticleRender implements MDRendererCallback {
|
||||
if (metadata?.frontmatter) {
|
||||
const keys = this.assetsManager.expertSettings.frontmatter;
|
||||
const frontmatter = metadata.frontmatter;
|
||||
res.title = this.getFrontmatterValue(frontmatter, keys.title);
|
||||
res.author = this.getFrontmatterValue(frontmatter, keys.author);
|
||||
// frontmatter 优先:如果存在 title/author 则直接取之
|
||||
const fmTitle = this.getFrontmatterValue(frontmatter, keys.title) || frontmatter['title'];
|
||||
const fmAuthor = this.getFrontmatterValue(frontmatter, keys.author) || frontmatter['author'];
|
||||
if (fmTitle) res.title = fmTitle;
|
||||
if (fmAuthor) res.author = fmAuthor;
|
||||
res.digest = this.getFrontmatterValue(frontmatter, keys.digest);
|
||||
res.content_source_url = this.getFrontmatterValue(frontmatter, keys.content_source_url);
|
||||
res.cover = this.getFrontmatterValue(frontmatter, keys.cover);
|
||||
res.cover = this.getFrontmatterValue(frontmatter, keys.cover) || frontmatter['cover'] || frontmatter['image'];
|
||||
res.thumb_media_id = this.getFrontmatterValue(frontmatter, keys.thumb_media_id);
|
||||
res.need_open_comment = frontmatter[keys.need_open_comment] ? 1 : undefined;
|
||||
res.only_fans_can_comment = frontmatter[keys.only_fans_can_comment] ? 1 : undefined;
|
||||
@@ -252,6 +274,41 @@ export class ArticleRender implements MDRendererCallback {
|
||||
res.pic_crop_1_1 = '0_0.525_0.404_1';
|
||||
}
|
||||
}
|
||||
|
||||
// 如果未显式指定封面,尝试从正文首图( markdown 或 wikilink ) 提取,按出现顺序优先
|
||||
if (!res.cover && this.originalMarkdown) {
|
||||
let body = this.originalMarkdown;
|
||||
if (body.startsWith('---')) body = body.replace(FRONT_MATTER_REGEX, '');
|
||||
|
||||
// 同时匹配两种形式并比较 index
|
||||
const mdImgPattern = /!\[[^\]]*\]\(([^)\s]+)\)/g; // group1 为路径
|
||||
const wikilinkPattern = /!\[\[(.+?)\]\]/g; // group1 为文件名或 path
|
||||
interface Candidate { idx:number; basename:string; }
|
||||
const candidates: Candidate[] = [];
|
||||
|
||||
let m: RegExpExecArray | null;
|
||||
while ((m = mdImgPattern.exec(body)) !== null) {
|
||||
const rawPath = m[1];
|
||||
if (/^https?:\/\//i.test(rawPath)) continue; // 跳过远程
|
||||
const clean = rawPath.split('#')[0].split('?')[0];
|
||||
const basename = clean.split('/').pop();
|
||||
if (basename && /\.(png|jpe?g|gif|bmp|webp|svg|tiff)$/i.test(basename)) {
|
||||
candidates.push({ idx: m.index, basename });
|
||||
}
|
||||
}
|
||||
while ((m = wikilinkPattern.exec(body)) !== null) {
|
||||
const inner = m[1].trim();
|
||||
const clean = inner.split('#')[0].split('?')[0];
|
||||
const basename = clean.split('/').pop();
|
||||
if (basename && /\.(png|jpe?g|gif|bmp|webp|svg|tiff)$/i.test(basename)) {
|
||||
candidates.push({ idx: m.index, basename });
|
||||
}
|
||||
}
|
||||
if (candidates.length > 0) {
|
||||
candidates.sort((a,b)=> a.idx - b.idx);
|
||||
res.cover = `![[${candidates[0].basename}]]`;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user