【工具】轻松转换JSON与Markdown表格——自制Obsidian插件

文章目录

一、插件简介

 JsonMdTableConverter是一款用于Obsidian的插件,它可以帮助用户在JSON格式和Markdown表格之间进行快速转换。这款插件具有以下特点:

  1. 轻松识别并转换JSON与Markdown表格;
  2. 支持通过右键菜单、命令面板和插件图标三种方式调用;
  3. 界面简洁,操作简单。

二、功能详解

  1. JSON转换为Markdown表格
     当我们有一段JSON数据,希望将其转换为Markdown表格以便在Obsidian中查看时,JsonMdTableConverter可以轻松实现。插件会自动识别JSON数据中的字段,并生成对应的Markdown表格。
  2. Markdown表格转换为JSON
     同样地,当我们需要在Markdown表格和JSON之间进行转换时,JsonMdTableConverterPlugin也能轻松应对。只需选中Markdown表格,插件便会将其转换为JSON格式。
  3. 方便的调用方式
     为了满足不同用户的使用习惯,JsonMdTableConverter提供了以下三种调用方式:
    (1)插件图标:在Obsidian的编辑器上方,点击插件图标即可调用;

    (2)命令面板:按下快捷键(如Ctrl+P),输入"JSON/MD Table Converter"即可;

    (3)右键菜单:在编辑器中右键点击,选择"JSON/MD Table Converter"菜单项。

三、使用教程

  1. 安装插件

    1. 在Obsidian仓库文件夹的.obsidian下创建plugins文件夹

    2. 在此文件夹下创建插件的文件夹,随意命名,比如json-md-table-converter
    3. 在插件的路径下创建两个文件main.js和mainfest.json
    4. 将JsonMdTableConverter插件插件代码复制相应的文件中,然后重启Obsidian。
    5. 将插件启动(需要关闭安全模式)
  2. 转换操作

    1. 选中需要转换的JSON或Markdown表格内容;
    2. 选中以下三种方式之一进行转换:
      • 点击插件图标;
      • 按下快捷键(如Ctrl+P),输入"JSON/MD Table Converter";
      • 在编辑器中右键点击,选择"JSON/MD Table Converter"。

四、插件代码

manifest.json

json 复制代码
{
  "id": "json-md-table-converter",
  "name": "JSON to Markdown Table Converter",
  "version": "0.9.0",
  "description": "Convert JSON strings to Markdown tables and vice versa."
}

main.js

js 复制代码
const { Plugin } = require('obsidian');

class JsonMdTableConverterPlugin extends Plugin {
  async onload() {
    // 注册指令
    this.addCommand({
      id: 'convert-json-md-table',
      name: 'JSON/MD Table Converter',
      callback: () => {
        this.convertToJsonOrMd();
      },
    }); 

    // 注册右键菜单
    this.registerEvent(
      this.app.workspace.on('editor-menu', (menu, editor, event) => {
        menu.addItem((item) => {
          item
            .setTitle('JSON/MD Table Converter')
            .setIcon('dice')
            .onClick(() => {
              this.convertToJsonOrMd();
            });
        });
      })
    );
  }

  convertToJsonOrMd() {
    const activeLeaf = this.app.workspace.activeLeaf;
    if (!activeLeaf) return;
    const editor = activeLeaf.view.sourceMode.cmEditor;
    const text = editor.getSelection() || editor.getValue();
    let result = '';
    try {
      // 尝试将文本解析为JSON
      const json = JSON.parse(text);
      if (
        Array.isArray(json) &&
        json.length > 0 &&
        typeof json[0] === 'object'
      ) {
        // 转换为Markdown表格
        result = this.jsonToMdTable(json);
      } else {
        // 如果不是数组或者数组元素不是对象,则提示用户
        return new Notice('Invalid JSON: JSON must be an array of objects.');
      }
    } catch (e) {
      const msg = this.isMarkdownTable(text);
      if (msg !== 'success') {
        return new Notice(msg);
      }
      // 解析失败,可能是Markdown表格
      result = JSON.stringify(this.mdTableToJson(text), null, 2);
    }
    editor.replaceSelection(result);
  }

  jsonToMdTable(json) {
    const fieldSet = new Set(); // 使用Set来存储不重复的字段
    for (let i = 0; i < json.length; i++) {
      const elementKeys = Object.keys(json[i]);
      for (let j = 0; j < elementKeys.length; j++) {
        fieldSet.add(elementKeys[j]); // 将字段添加到Set中
      }
    }
    const headers = Array.from(fieldSet);
    const headerRow = '| ' + headers.join(' | ') + ' |';
    const separatorRow = '| ' + headers.map(() => ':--:').join(' | ') + ' |';
    const bodyRows = json.map(
      (obj) =>
        '| ' + headers.map((header) => obj[header] || '').join(' | ') + ' |'
    );
    return [headerRow, separatorRow, ...bodyRows].join('\n');
  }

  mdTableToJson(mdTable) {
    const rows = mdTable.split('\n').filter((row) => row.trim() !== '');
    for (let i = 0; i < rows.length; i++) {
      rows[i] = rows[i].replace(/^\|+|\|+$/g, '');
    }
    const headers = rows[0].split('|').map((header) => header.trim());
    const jsonArray = rows.slice(2).map((row) => {
      const values = row.split('|').map((value) => value.trim());
      return headers.reduce((obj, header, index) => {
        obj[header] = values[index];
        return obj;
      }, {});
    });
    return jsonArray;
  }

  isMarkdownTable(str) {
    // 去除字符串首尾的空白字符,并按行分割
    const lines = str.trim().split('\n');
    const msg =
      'Conversion failed: The selected text is neither valid JSON nor a Markdown table.';
    // 检查至少有两行
    if (lines.length < 2) {
      return msg;
    }
    // 检查每行是否至少包含一个'|'
    for (let line of lines) {
      if (line.indexOf('|') === -1) {
        return msg;
      }
    }
    let separatorLine = lines[1].replaceAll(' ', '');
    // 分隔符行应该由'-'或':'组成,并且由'|'分隔
    if (separatorLine.startsWith('|')) { // 只去掉首尾的各一个'|'
      separatorLine = separatorLine.slice(1);
    }
    if (separatorLine.endsWith('|')) {
      separatorLine = separatorLine.slice(0, -1);
    }
    const separators = separatorLine.split('|');
    for (let separator of separators) {
      separator = separator.replaceAll(' ', '');
      if (separator.startsWith(':')) {
        separator = separator.slice(1);
      }
      if (separator.endsWith(':')) {
        separator = separator.slice(0, -1);
      }
      if (!/^-+$/.test(separator)) {
        return msg;
      }
    }
    // 检查分隔符行与标题行和内容行的列数是否匹配
    for (let line of lines) {
      line = line.trim()
      if (line.startsWith('|')) {
        line = line.slice(1);
      }
      if (line.endsWith('|')) {
        line = line.slice(0, -1);
      }
      const pipeCount = line.split('|').length;
      if (pipeCount !== separators.length) {
        return msg;
      }
    }
    if (lines.length == 2) {
      return 'Conversion failed: Markdown table should contain at least one row of data.';
    }
    return 'success';
  }
}

module.exports = JsonMdTableConverterPlugin;

五、总结

 JsonMdTableConverter插件极大地简化了JSON与Markdown表格之间的转换操作,提高了我们的工作效率。希望这款插件能为大家带来便利,如有任何建议或疑问,欢迎在评论区留言交流。

相关推荐
胖头鱼的鱼缸(尹海文)15 小时前
胖头鱼的技术专栏-474 从能跑到能上线:PG SplitJSON 0.2.0 和 0.1.0 差在哪(20261008)
postgresql·json
?? Daisy20 小时前
Claude Code 接入 GPT:settings.json 两种配置方法(2026-10)
gpt·json
小静AI工程实验室1 天前
Python 爬虫解析 JSON-LD:多块 script、@graph 与坏数据的 9 个边界
爬虫·python·json
goehou2 天前
LLM 结构化输出全解:从 Prompt 约束到 Schema 硬保证,三层实现怎么选
ai·llm·json·agent·教程·结构化输出
独立开发者阿乐2 天前
结构化数据 JSON-LD 实战:让 AI 读懂你的网页
人工智能·json·结构化数据·geo优化·json-ld·ai收录·faqpage
liangshanbo12154 天前
高级前端面试题:package.json 常见字段
前端·json
梦帮科技4 天前
【3.0修订版】创世与节点工程:genesis.json 与 node.toml 解剖
数据结构·算法·json·去中心化·区块链·智能合约·信任链
weixin_440730505 天前
内置函数、json文本、pickle二进制
开发语言·python·json
念越5 天前
接口自动化测试从入门到实战:接口用例设计、Requests、Pytest、YAML、JSON Schema 与 Allure 报告
python·测试工具·自动化·json·pytest
福兮说6 天前
前后端算的 MD5、SHA-256 对不上?编码、换行、BOM、HMAC、JSON 顺序,八个原因逐个实测
前端·javascript·node.js·json·哈希算法