update at 2025-10-10 21:54:05

This commit is contained in:
douboer
2025-10-10 21:54:05 +08:00
parent 1db58695e8
commit 0ab20de880
9 changed files with 347 additions and 228 deletions

View File

@@ -381,7 +381,9 @@ export class ArticleRender implements MDRendererCallback {
res.cover = undefined; // 忽略 frontmatter
}
res.thumb_media_id = this.getFrontmatterValue(frontmatter, keys.thumb_media_id);
res.need_open_comment = frontmatter[keys.need_open_comment] ? 1 : undefined;
if (frontmatter[keys.need_open_comment] !== undefined) {
res.need_open_comment = frontmatter[keys.need_open_comment] ? 1 : 0;
}
res.only_fans_can_comment = frontmatter[keys.only_fans_can_comment] ? 1 : undefined;
res.appid = this.getFrontmatterValue(frontmatter, keys.appid);
if (res.appid && !res.appid.startsWith('wx')) {
@@ -478,6 +480,9 @@ export class ArticleRender implements MDRendererCallback {
}
}
}
if (res.need_open_comment === undefined) {
res.need_open_comment = this.settings.needOpenComment ? 1 : 0;
}
return res;
}
@@ -717,7 +722,7 @@ export class ArticleRender implements MDRendererCallback {
article_type: 'newspic',
title: metadata.title || this.title,
content: content,
need_open_commnet: metadata.need_open_comment || 0,
need_open_commnet: metadata.need_open_comment ?? 0,
only_fans_can_comment: metadata.only_fans_can_comment || 0,
image_info: {
image_list: imageList,

View File

@@ -8,6 +8,7 @@ import { wxUploadImage } from "./wechat/weixin-api";
import { NMPSettings } from "./settings";
import { IsWasmReady, LoadWasm } from "./wasm/wasm";
import AssetsManager from "./assets";
import { convertJpegIfNeeded } from "./exif-orientation";
declare function GoWebpToJPG(data: Uint8Array): Uint8Array; // wasm 返回 Uint8Array
declare function GoWebpToPNG(data: Uint8Array): Uint8Array;
@@ -37,6 +38,18 @@ export async function UploadImageToWx(data: Blob, filename: string, token: strin
if (!IsImageLibReady()) {
await PrepareImageLib();
}
try {
// 公众号端仍然存在基于 EXIF 的旋转问题:
// 统一将待上传的 JPEG 转为 PNG 并忽略 Orientation避免出现倒置/倾斜。
const converted = await convertJpegIfNeeded(data, filename);
if (converted.changed) {
data = converted.blob;
filename = converted.filename;
}
} catch (error) {
console.warn('[UploadImageToWx] convert to PNG failed, fallback to original', error);
}
const watermark = NMPSettings.getInstance().watermark;
if (watermark != null && watermark != '') {
@@ -44,11 +57,11 @@ export async function UploadImageToWx(data: Blob, filename: string, token: strin
if (watermarkData == null) {
throw new Error('水印图片不存在: ' + watermark);
}
const watermarkImg = AddWatermark(await data.arrayBuffer(), watermarkData);
// AddWatermark 返回 Uint8ArrayBlob 的类型签名对某些 TS 配置可能对 ArrayBufferLike 有严格区分
// 此处使用其底层 ArrayBuffer 来构造 Blob避免类型不兼容错误
const bufferPart = watermarkImg.buffer as ArrayBuffer;
data = new Blob([bufferPart], { type: data.type });
const watermarkImg = AddWatermark(await data.arrayBuffer(), watermarkData);
// AddWatermark 返回 Uint8ArrayBlob 的类型签名对某些 TS 配置可能对 ArrayBufferLike 有严格区分
// 此处使用其底层 ArrayBuffer 来构造 Blob避免类型不兼容错误
const bufferPart = watermarkImg.buffer as ArrayBuffer;
data = new Blob([bufferPart], { type: data.type });
}
return await wxUploadImage(data, filename, token, type);
}

View File

@@ -43,7 +43,7 @@ interface PlatformInfo {
* 支持的平台列表
*/
const SUPPORTED_PLATFORMS: PlatformInfo[] = [
{ value: 'wechat', label: '微信公众号', icon: '📱' },
{ value: 'wechat', label: '公众号', icon: '📱' },
{ value: 'xiaohongshu', label: '小红书', icon: '📔' }
];

View File

@@ -160,99 +160,141 @@ export class NoteToMpSettingTab extends PluginSettingTab {
this.wxInfo = this.parseWXInfo();
const helpEl = containerEl.createEl('div', { cls: 'setting-help-section' });
helpEl.createEl('h2', {text: '帮助文档', cls: 'setting-help-title'});
helpEl.createEl('a', {text: 'https://sunboshi.tech/doc', attr: {href: 'https://sunboshi.tech/doc'}});
const tabs = [
{ id: 'style', label: '样式', render: (panel: HTMLElement) => this.renderStyleTab(panel) },
{ id: 'shortcode', label: '短代码', render: (panel: HTMLElement) => this.renderShortcodeTab(panel) },
{ id: 'theme', label: '主题', render: (panel: HTMLElement) => this.renderThemeTab(panel) },
{ id: 'image', label: '图片', render: (panel: HTMLElement) => this.renderImageTab(panel) },
{ id: 'user', label: '用户信息', render: (panel: HTMLElement) => this.renderUserTab(panel) },
];
containerEl.createEl('h2', {text: '插件设置'});
const tabBar = containerEl.createDiv({ cls: 'nmp-settings-tabs' });
const panelsWrapper = containerEl.createDiv({ cls: 'nmp-settings-panels' });
new Setting(containerEl)
const panelMap = new Map<string, HTMLElement>();
const buttonMap = new Map<string, HTMLButtonElement>();
const activate = (id: string) => {
buttonMap.forEach((btn, key) => btn.toggleClass('is-active', key === id));
panelMap.forEach((panel, key) => panel.toggleClass('is-active', key === id));
};
tabs.forEach((tab) => {
const button = tabBar.createEl('button', { text: tab.label, cls: 'nmp-settings-tab-button' });
button.onclick = () => activate(tab.id);
buttonMap.set(tab.id, button);
const panel = panelsWrapper.createDiv({ cls: 'nmp-settings-panel', attr: { 'data-tab': tab.id } });
panelMap.set(tab.id, panel);
tab.render(panel);
});
if (tabs.length > 0) {
activate(tabs[0].id);
}
}
private renderStyleTab(panel: HTMLElement): void {
new Setting(panel)
.setName('默认样式')
.addDropdown(dropdown => {
const styles = this.plugin.assetsManager.themes;
for (let s of styles) {
dropdown.addOption(s.className, s.name);
}
const styles = this.plugin.assetsManager.themes;
for (const s of styles) {
dropdown.addOption(s.className, s.name);
}
dropdown.setValue(this.settings.defaultStyle);
dropdown.onChange(async (value) => {
dropdown.onChange(async (value) => {
this.settings.defaultStyle = value;
await this.plugin.saveSettings();
});
});
new Setting(containerEl)
.setName('代码高亮')
.addDropdown(dropdown => {
const styles = this.plugin.assetsManager.highlights;
for (let s of styles) {
dropdown.addOption(s.name, s.name);
}
dropdown.setValue(this.settings.defaultHighlight);
dropdown.onChange(async (value) => {
this.settings.defaultHighlight = value;
await this.plugin.saveSettings();
});
});
new Setting(containerEl)
.setName('在工具栏展示样式选择')
.setDesc('建议在移动端关闭,可以增大文章预览区域')
.addToggle(toggle => {
toggle.setValue(this.settings.showStyleUI);
toggle.onChange(async (value) => {
this.settings.showStyleUI = value;
await this.plugin.saveSettings();
});
});
new Setting(containerEl)
new Setting(panel)
.setName('代码高亮')
.addDropdown(dropdown => {
const styles = this.plugin.assetsManager.highlights;
for (const s of styles) {
dropdown.addOption(s.name, s.name);
}
dropdown.setValue(this.settings.defaultHighlight);
dropdown.onChange(async (value) => {
this.settings.defaultHighlight = value;
await this.plugin.saveSettings();
});
});
new Setting(panel)
.setName('链接展示样式')
.addDropdown(dropdown => {
dropdown.addOption('inline', '内嵌');
dropdown.addOption('footnote', '脚注');
dropdown.addOption('footnote', '脚注');
dropdown.setValue(this.settings.linkStyle);
dropdown.onChange(async (value) => {
this.settings.linkStyle = value;
this.settings.linkStyle = value;
await this.plugin.saveSettings();
});
});
new Setting(containerEl)
new Setting(panel)
.setName('文件嵌入展示样式')
.addDropdown(dropdown => {
dropdown.addOption('quote', '引用');
dropdown.addOption('content', '正文');
dropdown.addOption('content', '正文');
dropdown.setValue(this.settings.embedStyle);
dropdown.onChange(async (value) => {
this.settings.embedStyle = value;
this.settings.embedStyle = value;
await this.plugin.saveSettings();
});
});
new Setting(containerEl)
new Setting(panel)
.setName('数学公式语法')
.addDropdown(dropdown => {
dropdown.addOption('latex', 'latex');
dropdown.addOption('asciimath', 'asciimath');
dropdown.addOption('asciimath', 'asciimath');
dropdown.setValue(this.settings.math);
dropdown.onChange(async (value) => {
this.settings.math = value;
this.settings.math = value;
cleanMathCache();
await this.plugin.saveSettings();
});
});
new Setting(containerEl)
new Setting(panel)
.setName('显示代码行号')
.addToggle(toggle => {
toggle.setValue(this.settings.lineNumber);
toggle.setValue(this.settings.lineNumber);
toggle.onChange(async (value) => {
this.settings.lineNumber = value;
this.settings.lineNumber = value;
await this.plugin.saveSettings();
});
})
});
new Setting(containerEl)
new Setting(panel)
.setName('启用空行渲染')
.addToggle(toggle => {
toggle.setValue(this.settings.enableEmptyLine);
toggle.onChange(async (value) => {
this.settings.enableEmptyLine = value;
await this.plugin.saveSettings();
});
});
new Setting(panel)
.setName('默认开启评论')
.setDesc('发布到公众号时默认开启评论,可在 frontmatter 使用 need_open_comment 关闭')
.addToggle(toggle => {
toggle.setValue(this.settings.needOpenComment);
toggle.onChange(async (value) => {
this.settings.needOpenComment = value;
await this.plugin.saveSettings();
});
});
}
private renderShortcodeTab(panel: HTMLElement): void {
new Setting(panel)
.setName('Gallery 根路径')
.setDesc('用于 {{<gallery dir="..."/>}} 短代码解析;需指向本地图片根目录')
.addText(text => {
@@ -265,7 +307,7 @@ export class NoteToMpSettingTab extends PluginSettingTab {
text.inputEl.setAttr('style', 'width: 360px;');
});
new Setting(containerEl)
new Setting(panel)
.setName('Gallery 选取图片数')
.setDesc('每个 gallery 短代码最多替换为前 N 张图片')
.addText(text => {
@@ -281,7 +323,18 @@ export class NoteToMpSettingTab extends PluginSettingTab {
text.inputEl.setAttr('style', 'width: 120px;');
});
new Setting(containerEl)
new Setting(panel)
.setName('忽略 frontmatter 封面')
.setDesc('开启后不使用 frontmatter 中 cover/image 字段封面将按正文首图→gallery→默认封面回退')
.addToggle(toggle => {
toggle.setValue(this.settings.ignoreFrontmatterImage);
toggle.onChange(async (value) => {
this.settings.ignoreFrontmatterImage = value;
await this.plugin.saveSettings();
});
});
new Setting(panel)
.setName('默认封面图片')
.setDesc('当文章无任何图片/短代码时使用;可填 wikilink 文件名或 http(s) URL')
.addText(text => {
@@ -293,33 +346,84 @@ export class NoteToMpSettingTab extends PluginSettingTab {
});
text.inputEl.setAttr('style', 'width: 360px;');
});
}
new Setting(containerEl)
.setName('忽略 frontmatter 封面')
.setDesc('开启后不使用 frontmatter 中 cover/image 字段封面将按正文首图→gallery→默认封面回退')
.addToggle(toggle => {
toggle.setValue(this.settings.ignoreFrontmatterImage);
toggle.onChange(async (value) => {
this.settings.ignoreFrontmatterImage = value;
private renderThemeTab(panel: HTMLElement): void {
new Setting(panel)
.setName('获取更多主题')
.addButton(button => {
button.setButtonText('下载');
button.onClick(async () => {
button.setButtonText('下载中...');
await this.plugin.assetsManager.downloadThemes();
button.setButtonText('下载完成');
});
})
.addButton(button => {
button.setIcon('folder-open');
button.onClick(async () => {
await this.plugin.assetsManager.openAssets();
});
});
new Setting(panel)
.setName('清空主题')
.addButton(button => {
button.setButtonText('清空');
button.onClick(async () => {
await this.plugin.assetsManager.removeThemes();
this.settings.resetStyelAndHighlight();
await this.plugin.saveSettings();
});
});
new Setting(panel)
.setName('全局CSS属性')
.setDesc('只能填写CSS属性不能写选择器')
.addTextArea(text => {
this.wxTextArea = text;
text.setPlaceholder('请输入CSS属性background: #fff;padding: 10px;')
.setValue(this.settings.baseCSS)
.onChange(async (value) => {
this.settings.baseCSS = value;
await this.plugin.saveSettings();
})
.inputEl.setAttr('style', 'width: 520px; height: 60px;');
});
new Setting(containerEl)
.setName('启用空行渲染')
.addToggle(toggle => {
toggle.setValue(this.settings.enableEmptyLine);
toggle.onChange(async (value) => {
this.settings.enableEmptyLine = value;
await this.plugin.saveSettings();
});
})
const customCSSDoc = '使用指南:<a href="https://sunboshi.tech/customcss">https://sunboshi.tech/customcss</a>';
new Setting(panel)
.setName('自定义CSS笔记')
.setDesc(sanitizeHTMLToDom(customCSSDoc))
.addText(text => {
text.setPlaceholder('请输入自定义CSS笔记标题')
.setValue(this.settings.customCSSNote)
.onChange(async (value) => {
this.settings.customCSSNote = value.trim();
await this.plugin.saveSettings();
await this.plugin.assetsManager.loadCustomCSS();
})
.inputEl.setAttr('style', 'width: 320px;');
});
// 切图配置区块
containerEl.createEl('h2', {text: '切图配置'});
const expertDoc = '使用指南:<a href="https://sunboshi.tech/expert">https://sunboshi.tech/expert</a>';
new Setting(panel)
.setName('专家设置笔记')
.setDesc(sanitizeHTMLToDom(expertDoc))
.addText(text => {
text.setPlaceholder('请输入专家设置笔记标题')
.setValue(this.settings.expertSettingsNote)
.onChange(async (value) => {
this.settings.expertSettingsNote = value.trim();
await this.plugin.saveSettings();
await this.plugin.assetsManager.loadExpertSettings();
})
.inputEl.setAttr('style', 'width: 320px;');
});
}
new Setting(containerEl)
private renderImageTab(panel: HTMLElement): void {
new Setting(panel)
.setName('切图保存路径')
.setDesc('切图文件的保存目录,默认:/Users/gavin/note2mp/images/xhs')
.addText(text => {
@@ -332,7 +436,7 @@ export class NoteToMpSettingTab extends PluginSettingTab {
text.inputEl.setAttr('style', 'width: 360px;');
});
new Setting(containerEl)
new Setting(panel)
.setName('切图宽度')
.setDesc('长图及切图的宽度像素默认1080')
.addText(text => {
@@ -348,7 +452,7 @@ export class NoteToMpSettingTab extends PluginSettingTab {
text.inputEl.setAttr('style', 'width: 120px;');
});
new Setting(containerEl)
new Setting(panel)
.setName('切图横竖比例')
.setDesc('格式:宽:高,例如 3:4 表示竖图16:9 表示横图')
.addText(text => {
@@ -360,182 +464,119 @@ export class NoteToMpSettingTab extends PluginSettingTab {
});
text.inputEl.setAttr('style', 'width: 120px;');
});
new Setting(containerEl)
.setName('渲染图片标题')
.addToggle(toggle => {
toggle.setValue(this.settings.useFigcaption);
toggle.onChange(async (value) => {
this.settings.useFigcaption = value;
await this.plugin.saveSettings();
});
})
new Setting(containerEl)
.setName('Excalidraw 渲染为 PNG 图片')
.setDesc('开启:将 Excalidraw 笔记/嵌入转换为位图 PNG 插入;关闭:保持原始 SVG/矢量渲染(更清晰,体积更小)。')
.addToggle(toggle => {
toggle.setValue(this.settings.excalidrawToPNG);
toggle.onChange(async (value) => {
this.settings.excalidrawToPNG = value;
await this.plugin.saveSettings();
new Setting(panel)
.setName('渲染图片标题')
.addToggle(toggle => {
toggle.setValue(this.settings.useFigcaption);
toggle.onChange(async (value) => {
this.settings.useFigcaption = value;
await this.plugin.saveSettings();
});
});
})
new Setting(containerEl)
new Setting(panel)
.setName('Excalidraw 渲染为 PNG 图片')
.setDesc('开启:将 Excalidraw 笔记/嵌入转换为位图 PNG 插入;关闭:保持原始 SVG/矢量渲染。')
.addToggle(toggle => {
toggle.setValue(this.settings.excalidrawToPNG);
toggle.onChange(async (value) => {
this.settings.excalidrawToPNG = value;
await this.plugin.saveSettings();
});
});
new Setting(panel)
.setName('水印图片')
.setDesc('可填写文件名或 URL')
.addText(text => {
text.setPlaceholder('请输入图片名称')
text.setPlaceholder('例如 watermark.png')
.setValue(this.settings.watermark)
.onChange(async (value) => {
this.settings.watermark = value.trim();
this.settings.watermark = value.trim();
await this.plugin.saveSettings();
})
.inputEl.setAttr('style', 'width: 320px;')
})
new Setting(containerEl)
.setName('获取更多主题')
.addButton(button => {
button.setButtonText('下载');
button.onClick(async () => {
button.setButtonText('下载中...');
await this.plugin.assetsManager.downloadThemes();
button.setButtonText('下载完成');
});
})
.addButton(button => {
button.setIcon('folder-open');
button.onClick(async () => {
await this.plugin.assetsManager.openAssets();
});
.inputEl.setAttr('style', 'width: 320px;');
});
}
new Setting(containerEl)
.setName('清空主题')
.addButton(button => {
button.setButtonText('清空');
button.onClick(async () => {
await this.plugin.assetsManager.removeThemes();
this.settings.resetStyelAndHighlight();
await this.plugin.saveSettings();
});
})
new Setting(containerEl)
.setName('全局CSS属性')
.setDesc('只能填写CSS属性不能写选择器')
.addTextArea(text => {
this.wxTextArea = text;
text.setPlaceholder('请输入CSS属性background: #fff;padding: 10px;')
.setValue(this.settings.baseCSS)
.onChange(async (value) => {
this.settings.baseCSS = value;
await this.plugin.saveSettings();
})
.inputEl.setAttr('style', 'width: 520px; height: 60px;');
})
const customCSSDoc = '使用指南:<a href="https://sunboshi.tech/customcss">https://sunboshi.tech/customcss</a>';
new Setting(containerEl)
.setName('自定义CSS笔记')
.setDesc(sanitizeHTMLToDom(customCSSDoc))
.addText(text => {
text.setPlaceholder('请输入自定义CSS笔记标题')
.setValue(this.settings.customCSSNote)
.onChange(async (value) => {
this.settings.customCSSNote = value.trim();
await this.plugin.saveSettings();
await this.plugin.assetsManager.loadCustomCSS();
})
.inputEl.setAttr('style', 'width: 320px;')
});
const expertDoc = '使用指南:<a href="https://sunboshi.tech/expert">https://sunboshi.tech/expert</a>';
new Setting(containerEl)
.setName('专家设置笔记')
.setDesc(sanitizeHTMLToDom(expertDoc))
.addText(text => {
text.setPlaceholder('请输入专家设置笔记标题')
.setValue(this.settings.expertSettingsNote)
.onChange(async (value) => {
this.settings.expertSettingsNote = value.trim();
await this.plugin.saveSettings();
await this.plugin.assetsManager.loadExpertSettings();
})
.inputEl.setAttr('style', 'width: 320px;')
});
private renderUserTab(panel: HTMLElement): void {
let descHtml = '详情说明:<a href="https://sunboshi.tech/subscribe">https://sunboshi.tech/subscribe</a>';
if (this.settings.isVip) {
descHtml = '<span style="color:rgb(245, 70, 85);font-weight: bold;">👑永久会员</span><br/>' + descHtml;
}
else if (this.settings.expireat) {
const timestr = this.settings.expireat.toLocaleString();
descHtml = `有效期至:${timestr} <br/>${descHtml}`
descHtml = `有效期至:${timestr} <br/>${descHtml}`;
}
new Setting(containerEl)
new Setting(panel)
.setName('注册码AuthKey')
.setDesc(sanitizeHTMLToDom(descHtml))
.addText(text => {
text.setPlaceholder('请输入注册码')
.setValue(this.settings.authKey)
.onChange(async (value) => {
.setValue(this.settings.authKey)
.onChange(async (value) => {
this.settings.authKey = value.trim();
this.settings.getExpiredDate();
await this.plugin.saveSettings();
})
.inputEl.setAttr('style', 'width: 320px;')
}).descEl.setAttr('style', '-webkit-user-select: text; user-select: text;')
this.settings.getExpiredDate();
await this.plugin.saveSettings();
})
.inputEl.setAttr('style', 'width: 320px;');
}).descEl.setAttr('style', '-webkit-user-select: text; user-select: text;');
let isClear = this.settings.wxInfo.length > 0;
let isRealClear = false;
const buttonText = isClear ? '清空公众号信息' : '保存公众号信息';
new Setting(containerEl)
new Setting(panel)
.setName('公众号信息')
.addTextArea(text => {
this.wxTextArea = text;
text.setPlaceholder('请输入公众号信息\n格式公众号名称|公众号AppID|公众号AppSecret\n多个公众号请换行输入\n输入完成后点击加密按钮')
.setValue(this.wxInfo)
text.setPlaceholder('请输入公众号信息\n格式公众号名称|公众号AppID|公众号AppSecret\n多个公众号请换行输入\n输入完成后点击加密按钮')
.setValue(this.wxInfo)
.onChange(value => {
this.wxInfo = value;
this.wxInfo = value;
})
.inputEl.setAttr('style', 'width: 520px; height: 120px;');
.inputEl.setAttr('style', 'width: 520px; height: 120px;');
})
new Setting(containerEl).addButton(button => {
button.setButtonText(buttonText);
button.onClick(async () => {
if (isClear) {
isRealClear = true;
isClear = false;
button.setButtonText('确认清空?');
}
else if (isRealClear) {
isRealClear = false;
isClear = false;
this.clear();
button.setButtonText('保存公众号信息');
}
else {
button.setButtonText('保存中...');
if (await this.encrypt()) {
isClear = true;
isRealClear = false;
button.setButtonText('清空公众号信息');
.addButton(button => {
button.setButtonText(buttonText);
button.onClick(async () => {
if (isClear) {
isRealClear = true;
isClear = false;
button.setButtonText('确认清空?');
}
else {
else if (isRealClear) {
isRealClear = false;
isClear = false;
this.clear();
button.setButtonText('保存公众号信息');
}
}
});
})
.addButton(button => {
button.setButtonText('测试公众号');
button.onClick(async () => {
button.setButtonText('测试中...');
await this.testWXInfo();
button.setButtonText('测试公众号');
else {
button.setButtonText('保存中...');
if (await this.encrypt()) {
isClear = true;
isRealClear = false;
button.setButtonText('清空公众号信息');
}
else {
button.setButtonText('保存公众号信息');
}
}
});
})
})
.addButton(button => {
button.setButtonText('测试公众号');
button.onClick(async () => {
button.setButtonText('测试中...');
await this.testWXInfo();
button.setButtonText('测试公众号');
});
});
//
const helpEl = panel.createEl('div', { cls: 'setting-help-section' });
helpEl.createEl('h2', { text: '帮助文档', cls: 'setting-help-title' });
helpEl.createEl('a', { text: 'https://sunboshi.tech/doc', attr: { href: 'https://sunboshi.tech/doc' } });
}
}

View File

@@ -32,6 +32,7 @@ export class NMPSettings {
excalidrawToPNG: boolean;
isLoaded: boolean = false;
enableEmptyLine: boolean = false;
needOpenComment: boolean = true;
enableMarkdownImageToWikilink: boolean = true; // 自动将 ![alt](path/file.ext) 转为 ![[file.ext]]
// gallery 相关配置:根目录前缀 & 选取图片数量
galleryPrePath: string;
@@ -81,6 +82,7 @@ export class NMPSettings {
this.excalidrawToPNG = false;
this.expertSettingsNote = '';
this.enableEmptyLine = false;
this.needOpenComment = true;
this.enableMarkdownImageToWikilink = true;
// 默认值:用户原先硬编码路径 & 前 2 张
this.galleryPrePath = '/Users/gavin/myweb/static';
@@ -131,6 +133,7 @@ export class NMPSettings {
expertSettingsNote,
ignoreEmptyLine,
enableMarkdownImageToWikilink,
needOpenComment,
galleryPrePath,
galleryNumPic,
defaultCoverPic,
@@ -160,6 +163,7 @@ export class NMPSettings {
if (excalidrawToPNG !== undefined) settings.excalidrawToPNG = excalidrawToPNG;
if (expertSettingsNote) settings.expertSettingsNote = expertSettingsNote;
if (ignoreEmptyLine !== undefined) settings.enableEmptyLine = !!ignoreEmptyLine;
if (needOpenComment !== undefined) settings.needOpenComment = !!needOpenComment;
if (enableMarkdownImageToWikilink !== undefined) settings.enableMarkdownImageToWikilink = !!enableMarkdownImageToWikilink;
if (galleryPrePath) settings.galleryPrePath = galleryPrePath;
if (galleryNumPic !== undefined && Number.isFinite(galleryNumPic)) settings.galleryNumPic = Math.max(1, parseInt(galleryNumPic));
@@ -197,6 +201,7 @@ export class NMPSettings {
'excalidrawToPNG': settings.excalidrawToPNG,
'expertSettingsNote': settings.expertSettingsNote,
'ignoreEmptyLine': settings.enableEmptyLine,
'needOpenComment': settings.needOpenComment,
'enableMarkdownImageToWikilink': settings.enableMarkdownImageToWikilink,
'galleryPrePath': settings.galleryPrePath,
'galleryNumPic': settings.galleryNumPic,