Created: June 23, 2025 8:04 PM Tags: tool
内容
✅
太长不读:
-
使用vscode等等你最喜欢的编辑器来编写带有公式的markdown文章;
-
使用martian来将markdown转化为notion格式的内容
-
使用notion api将markdown文件上传到notion
当前notion中输入公式的痛点
我将notion作为主要的内容记录工具,主要是喜欢它时刻在线,随时更换设备都能使用, 以及它提供了很多有效组件,因此可以一站式解决文档记录,项目规划,管理等内容。
但是notion中公式编辑可以说是我见过最麻烦的玩意
- 要进入一个弹出来的小窗口中输入公式,可读性跟可编辑性都贼差

- 不支持自动补全,没有语法高亮
- 特别是中文输入时, 对公式环境的识别可以说做的一塌糊涂。
- 导入效果差: 从其他源复制过来的markdown内容,不管是粘贴,还是导入,经常会显示为源文件格式,而不会进行渲染。
目前的解决方案
✅ vscode中写作 →Markdown文件 → Martian 转换 → Notion API上传
这里需要了解的主要是martian跟notion api两个关键概念。
martian
这是一个能够将md文件转换为notion api能够导入的json格式文件的转换器。
它是使用js语言编写的,这里使用nodejs来运行该项目, 至于nodejs如何安装,使用,请参见
martian安装
在安装了nodejs,npm后,随便建立一个文件夹,这里以 test
文件夹为例:
在 test文件夹下,执行如下安装martian的指令:
bash
npm install @tryfabric/martian
其实这个过程就是将martian包下载到当前文件夹,并进行相应的配置。
martian 使用
我这里写了一个脚本将md文件转化为json文件, 随便给这个脚本取一个名字,然后用如下命令就可以在当前文件夹中将 test.md
文件转化为一个名为 output.json
的文件
bash
node convertToNotion.js test.md ./
具体脚本如下
jsx
const fs = require('fs');
const path = require('path');
const { markdownToBlocks } = require('@tryfabric/martian');
// 获取命令行参数
const args = process.argv.slice(2);
if (args.length < 2) {
console.error('用法: node convertToNotion.js <输入Markdown路径> <输出JSON路径>');
process.exit(1);
}
const mdPath = path.resolve(args[0]);
let outputPath = path.resolve(args[1]);
// 如果输出路径是文件夹,则自动创建 output.json 文件
if (fs.existsSync(outputPath) && fs.lstatSync(outputPath).isDirectory()) {
outputPath = path.join(outputPath, 'output.json');
}
// 如果输出路径不存在但以 / 结尾,也视为文件夹
if (!fs.existsSync(outputPath) && outputPath.endsWith(path.sep)) {
fs.mkdirSync(outputPath, { recursive: true });
outputPath = path.join(outputPath, 'output.json');
}
// 1. 读取 Markdown 文件内容
const mdContent = fs.readFileSync(mdPath, 'utf-8');
// 2. 转换为 Notion Blocks
const notionBlocks = markdownToBlocks(mdContent);
// 3. 保存为 JSON 文件
fs.writeFileSync(outputPath, JSON.stringify(notionBlocks, null, 2), 'utf-8');
console.log('转换完成,已保存为:', outputPath);
上传到notion
获取notion apikey
notion并没有提供手动导入json文件的功能,需要使用notion api来导入, 但步骤也非常简单
- 直接搜索notion api, 进入 www.notion.so/profile/int... 创建一个integration, 也就是配置一个notion api,获取apikey, 并配置拥有这个apikey的脚本的权限,也就是规定它能做哪些事

文件上传位置
在integration配置页面有access栏目,这里就是用于指定上传的文件保存在notion哪个文件夹下面。 建议放在一个单独的notion页面下,这样便于后续在notion中进行后续移动,复制等操作。
上传json文件
首先在本地 test
文件夹下安装notion sdk
bash
npm install @notionhq/client
我这里编写了一个上传json文件的脚本 import_notion.js
:
jsx
require('dotenv').config(); // 加载 .env 文件
const { Client } = require('@notionhq/client');
const fs = require('fs');
// 获取命令行参数中的文件路径
const filePath = process.argv[2];
if (!filePath) {
console.error('请提供要导入的 Notion JSON 文件路径,例如:node import_notion.js <文件路径>');
process.exit(1);
}
// 1. 初始化 Notion 客户端
const notion = new Client({ auth: process.env.NOTION_APIKEY });
// 2. 读取 blocks
const blocks = JSON.parse(fs.readFileSync(filePath, 'utf-8'));
// 3. 指定父页面ID(你要导入到哪个页面下)
const parentPageId = 'xxxxxxxxxxxxxxxxxxxxxxx';
// 4. 批量插入 blocks
async function importBlocks() {
for (const block of blocks) {
await notion.blocks.children.append({
block_id: parentPageId,
children: [block],
});
}
console.log('导入完成!');
}
importBlocks();
apikey 隐藏
注意这里我将我的apikey 保存在 test
文件夹下一个名为 .env
的文件下,这样做的目的是避免在代码中暴露APIKEY, .env
文件的内容为
bash
NOTION_APIKEY = "your apikey"
这样脚本就能通过 dotenv库来读取你的apikey.
获取notion 上传页面 ID
我们要将json文件上传到notion,总要指定一个保存的位置。 也就是这里需要指定的存储父页面ID, 通过去notion中查找刚才access中指定的文件夹的ID(一长串的数字字母字符串), 填入上述脚本中 parentPageId 那里。
然后, 运行脚本就完成上传了。
总结
- 高频使用的场景A,如果有比较麻烦的情况,比如在notion中编写latex公式,最好将其转化为在另外一个比较方便的环境B中完成编写,再使用工具完成从B到A的转化。
- 本地编写md的这个文件夹,建议将其放在诸如坚果云这样的同步盘中