多种风格标题及高亮样式

这个超好看,推荐下自制的插件,直接快捷插入标签(主要我搞不懂什么正则之类的,以及highlight插件,所以让deepseek写main.js

const { Plugin, PluginSettingTab, Setting } = require('obsidian');

// 默认标签示例(包含两种输出类型)
const DEFAULT_TAGS = [
  { id: '1', tag: '#green-wavy', outputType: 'tagHighlight' },
  { id: '2', tag: '#red-solid', outputType: 'tagHighlight' },
  { id: '3', tag: 'hp-parch-1', outputType: 'markClass' }
];

class DynamicHighlightPlugin extends Plugin {
  async onload() {
    await this.loadSettings();
    this.registerAllCommands();
    this.addSettingTab(new DynamicHighlightSettingTab(this.app, this));
  }

  async loadSettings() {
    const data = await this.loadData();
    this.settings = data || { tags: DEFAULT_TAGS };
    if (!this.settings.tags) this.settings.tags = [];
    // 确保每个标签有 id 和 outputType
    this.settings.tags.forEach((tag, idx) => {
      if (!tag.id) tag.id = Date.now() + '-' + idx;
      if (!tag.outputType) tag.outputType = 'tagHighlight'; // 默认
    });
  }

  async saveSettings() {
    await this.saveData(this.settings);
    this.registerAllCommands(); // 重新注册命令
  }

  clearAllCommands() {
    const commandIds = this.settings.tags.map(tag => `dynamic-highlight-${tag.id}`);
    commandIds.forEach(id => {
      const cmd = this.app.commands.findCommand(id);
      if (cmd) this.app.commands.removeCommand(id);
    });
  }

  registerAllCommands() {
    this.clearAllCommands();
    for (const tagItem of this.settings.tags) {
      const tag = tagItem.tag;
      const outputType = tagItem.outputType;
      this.addCommand({
        id: `dynamic-highlight-${tagItem.id}`,
        name: `高亮 (${tag})`,
        editorCallback: (editor) => {
          const selection = editor.getSelection();
          if (!selection) return;
          let replacement = '';
          if (outputType === 'tagHighlight') {
            // 输出格式: #tag ==选中文本==
            replacement = ` ${tag}==${selection}==`;
          } else {
            // 输出格式: <mark class="类名">选中文本</mark>
            let className = tag;
            if (className.startsWith('#')) className = className.slice(1);
            replacement = `<mark class="${className}">${selection}</mark>`;
          }
          editor.replaceSelection(replacement);
        },
      });
    }
  }

  addTag(tag, outputType = 'tagHighlight') {
    if (tag && !tag.startsWith('#') && outputType === 'tagHighlight') {
      tag = '#' + tag;
    }
    const newTag = { id: Date.now().toString(), tag: tag, outputType: outputType };
    this.settings.tags.push(newTag);
    this.saveSettings();
  }

  removeTag(id) {
    this.settings.tags = this.settings.tags.filter(t => t.id !== id);
    this.saveSettings();
  }

  updateTag(id, newTag, newOutputType) {
    const index = this.settings.tags.findIndex(t => t.id === id);
    if (index !== -1) {
      if (newTag && !newTag.startsWith('#') && newOutputType === 'tagHighlight') {
        newTag = '#' + newTag;
      }
      this.settings.tags[index].tag = newTag;
      if (newOutputType) this.settings.tags[index].outputType = newOutputType;
      this.saveSettings();
    }
  }

  onunload() {
    this.clearAllCommands();
  }
}

class DynamicHighlightSettingTab extends PluginSettingTab {
  constructor(app, plugin) {
    super(app, plugin);
    this.plugin = plugin;
  }

  display() {
    const { containerEl } = this;
    containerEl.empty();

    containerEl.createEl('h2', { text: '动态高亮 - 标签管理' });
    containerEl.createEl('p', { text: '每个标签生成一个独立命令。选择输出类型:“标签+高亮”用于彩色下划线CSS,“Mark类”用于哈利波特CSS。' });

    // 添加新标签区域
    let newTagValue = '';
    let newOutputType = 'tagHighlight';

    new Setting(containerEl)
      .setName('新增标签')
      .setDesc('输入标签内容(例如 #green-wavy 或 hp-parch-1)')
      .addText(text => {
        text.setPlaceholder('#green-wavy 或 hp-parch-1')
          .onChange(value => newTagValue = value);
      })
      .addDropdown(dropdown => {
        dropdown.addOption('tagHighlight', '标签+高亮 (#tag ==text==)')
          .addOption('markClass', 'Mark类 (<mark class="...">)')
          .setValue('tagHighlight')
          .onChange(value => newOutputType = value);
      })
      .addButton(btn => btn.setButtonText('添加')
        .onClick(() => {
          if (newTagValue && newTagValue.trim()) {
            this.plugin.addTag(newTagValue.trim(), newOutputType);
            this.display();
          }
        }));

    // 现有标签列表
    containerEl.createEl('h3', { text: '现有标签' });
    for (const tagItem of this.plugin.settings.tags) {
      const tagId = tagItem.id;
      let currentTag = tagItem.tag;
      let currentOutputType = tagItem.outputType;

      const setting = new Setting(containerEl)
        .setName(currentTag)
        .addText(text => {
          text.setValue(currentTag)
            .onChange(async (value) => {
              currentTag = value;
              this.plugin.updateTag(tagId, currentTag, currentOutputType);
              this.display();
            });
        })
        .addDropdown(dropdown => {
          dropdown.addOption('tagHighlight', '标签+高亮')
            .addOption('markClass', 'Mark类')
            .setValue(currentOutputType)
            .onChange(async (value) => {
              currentOutputType = value;
              this.plugin.updateTag(tagId, currentTag, currentOutputType);
              this.display();
            });
        })
        .addButton(btn => btn.setButtonText('删除')
          .setWarning()
          .onClick(() => {
            this.plugin.removeTag(tagId);
            this.display();
          }));
    }

    if (this.plugin.settings.tags.length === 0) {
      containerEl.createEl('div', { text: '暂无标签,请添加。' });
    }
  }
}

module.exports = DynamicHighlightPlugin;