Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Inkmark 墨记

一个所见即所得的 Markdown 编辑器,类 Typora。同一套编辑器内核,三种形态:

形态 怎么跑 适合
桌面 App npm start 日常写作,原生打开/保存、拖拽文件、导出 PDF
网页版 npm run webhttp://localhost:4321 随手改代码、跨平台
双击即用 直接打开 app/index.html 零依赖零服务,拷到 U 盘就能用

网页版在 Chrome / Edge 里还能从地址栏装成 PWA,离线可用、有独立窗口。


下载安装(macOS)

Releases 下载对应的 DMG:

  • Apple 芯片(M1/M2/M3/M4)Inkmark-x.y.z-arm64.dmg
  • Intel 芯片Inkmark-x.y.z-x64.dmg

打开 DMG,把 Inkmark 拖进「应用程序」。

首次打开会被拦下来。 这个应用没有 Apple 开发者证书签名(一年 99 美元), 所以 macOS 会提示「无法验证开发者」。两种办法:

  • 右键点图标 → 打开,在弹窗里再点一次「打开」。之后就正常了。
  • 或者在终端里跑一行:
xattr -dr com.apple.quarantine /Applications/Inkmark.app

应用做过 ad-hoc 自签名,所以不会出现「应用已损坏」那种更吓人的报错。 不放心的话可以自己从源码构建 —— 见下面的「自己构建」。

不想装应用的话,直接用网页版也是完整功能。

快速开始

npm install     # 依赖只有 electron(桌面版)和 electron-builder(打包)
npm start       # 桌面版
npm run web     # 网页版,http://localhost:4321

自己构建

npm run icons   # SVG → .icns(用 Electron 自带的 Chromium 渲染,不需要图形库)
npm run dist    # 出 dist/Inkmark-x.y.z-{arm64,x64}.{dmg,zip}

打包时 scripts/adhoc-sign.js 会给 .app 做一次 ad-hoc 自签名。 这一步不能省:没有开发者证书时 electron-builder 会整个跳过签名, 包里留着 Electron 原始签名却对不上被替换过的资源,macOS 会直接判定「应用已损坏」。


它是怎么做到「所见即所得」的

Typora 的手感来自一个很朴素的想法:语法标记一直都在 DOM 里,只是被 CSS 藏起来了

非激活块:  <h2><span class="mk">## </span>标题</h2>     mk 是 display:none  → 看到「标题」
光标进来:  同一个 DOM,加个 .active 类               mk 变可见  → 看到「## 标题」

于是:

  • 切换渲染态只是加个 class,不重新解析、不重建 DOM
  • 光标偏移量天然一致 —— 源码字符始终在 DOM 里,不需要任何位置映射
  • 读回源码只要 textContent
  • 中文输入法不会被打断 —— 组字期间完全不动 DOM

整个编辑器都建立在这一条不变式上:

块元素.textContent === 该块的 Markdown 源码(逐字符相等)

#>- 这类块级前缀用绝对定位悬挂到正文左侧的边槽里,所以光标移进移出时 正文一个像素都不会跳,这也是 Typora 手感好的关键细节。

代码结构:

app/                   ← 三种形态共用的全部界面与逻辑
  js/markdown.js       块解析 / 行内渲染(不变式在这里)
  js/editor.js         编辑内核:光标、输入、分块、撤销、查找
  js/highlight.js      零依赖代码高亮
  js/exporter.js       导出独立 HTML(摘掉标记、还原 ul/ol 嵌套)
  js/html2md.js        富文本粘贴 → Markdown
  js/platform.js       宿主适配层(浏览器 / Electron 两套实现)
  js/app.js            界面装配,所有能力注册进 CMD 表
electron/main.js       窗口、原生菜单、文件对话框、导出 PDF
scripts/serve.js       零依赖静态服务器

platform.js 是唯一知道「自己跑在哪」的文件。编辑器内核对宿主一无所知, 这就是三种形态能共用一套代码的原因。


支持的语法

标题 1-6、加粗斜体删除线行内代码、==高亮==、链接、图片、 自动链接、脚注引用、$公式$(按等宽显示,不做排版)、 引用、无序/有序列表、任务列表(可直接点勾)、多级缩进、 代码围栏(20+ 语言高亮)、表格(带对齐)、分割线、 以及白名单行内 HTML:<u> <mark> <kbd> <sub> <sup> <b> <i> <s> <del> <ins> <small> <br>


快捷键

和 Typora 基本一致。桌面版由原生菜单提供,网页版由页面接管。

⌘N / ⌘O / ⌘S / ⇧⌘S 新建 / 打开 / 保存 / 另存为
⇧⌘E / ⌘P 导出 HTML / 导出 PDF
⌘B ⌘I ⌘U 加粗 / 斜体 / 下划线
⇧⌘D / ⇧⌘H / ⌘E 删除线 / 高亮 / 行内代码
⌘1…⌘6 / ⌘0 标题 1-6 / 转为正文
⇧⌘8 / ⇧⌘7 / ⇧⌘X / ⇧⌘9 无序 / 有序 / 任务 / 引用
⌘K / ⇧⌘I / ⇧⌘T / ⇧⌘K 链接 / 图片 / 表格 / 代码块
⌘F 查找替换
⌘/ 整篇源码模式
⌘\ 侧边栏(大纲 / 最近打开)
⇧⌘F / ⇧⌘Y / ⇧⌘L 专注模式 / 打字机模式 / 换主题
Tab / ⇧Tab 列表缩进 / 退回
⇧⏎ 段内软换行

注意 ⌘0 是「转为正文」(跟 Typora 一致),恢复字号是 ⌥⌘0。


三种形态的能力差异

桌面版 网页版
原生打开/保存对话框 Chrome/Edge ✅,其他浏览器退化为上传/下载
最近打开真能重新打开 ✅(文件句柄存在 IndexedDB,首次会要一次授权)
拖拽 .md 进窗口
粘贴/拖入图片 存到 文档名.assets/ 目录 内嵌成 data URL
导出 PDF 隐藏窗口渲染后 printToPDF,干净 走系统打印对话框「存储为 PDF」
崩溃/刷新不丢内容 靠系统 + 关窗询问 草稿自动存 localStorage
Finder 双击 .md 打开 ✅(打包后) PWA 装好后可注册为 .md 处理器

已知取舍

这些是有意为之的简化,不是没写完:

  • 表格光标移进去会摊平成源码行,移出来恢复表格。Typora 是保持表格形态另给一个工具条; 摊平的做法更直白,也不会出现「单元格里的换行往哪去」这类歧义。
  • 块级 HTML(<div> 之类)按字面文本显示,不渲染。渲染它会破坏 「textContent === 源码」这条不变式,而整个编辑器都靠它。行内 HTML 走白名单,是安全的。
  • 数学公式只做等宽着色,没有排版引擎(要排版得引入 KaTeX,那就不是零依赖了)。
  • 有序列表编号不自动重排 —— 写 1. / 1. / 1. 就显示 1/1/1。 源码怎么写就怎么显示,回车时会自动递增。
  • Mermaid 图表没做。
  • 桌面版 .app 图标用的是 Electron 默认图标,app/icons/icon.svg 需要转成 .icns 才能在打包时生效。

开发时的一个坑

网页版注册了 Service Worker 做离线缓存,改完代码刷新看不到变化就是它。 调试时用:

http://localhost:4321/?nosw

npm run web 起的服务器已经强制 Cache-Control: no-store,所以只需要绕开 SW。

About

墨记 Inkmark — 所见即所得的 Markdown 编辑器,一套内核三种形态:桌面版 / 网页版 / PWA

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages