Skip to content

refactor, feat: support notationHightligh (close #50), feat: editing in live preview (close #19, about #44) #51

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 67 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
67 commits
Select commit Hold shift + click to select a range
46988ff
update: shiki version
LincZero May 18, 2025
0a7c48b
style: add notation style
LincZero May 18, 2025
0bd01ce
style: add focused styles
LincZero May 18, 2025
3441347
feat: editing in preview
LincZero May 19, 2025
9323185
feat: editing in preview2, enhance style
LincZero May 19, 2025
2196ed4
feat: editing in preview3, save
LincZero May 20, 2025
6169bf6
ci: add workflow
LincZero May 20, 2025
431eebc
update: new version
LincZero May 20, 2025
21ce5e0
chore: resolve conflict
LincZero May 20, 2025
4eeb6ba
Merge remote-tracking branch 'upstream/master'
LincZero May 20, 2025
1802d57
feat: add setting option: renderMode
LincZero May 20, 2025
5643821
feat: add metaHighlight
LincZero May 20, 2025
ea9f1e0
chore: code comment
LincZero May 20, 2025
1e92382
chore: delete package-lock.json
LincZero May 20, 2025
11ff529
revert: version
LincZero May 20, 2025
8964a56
feat: add min version
LincZero May 21, 2025
36c9636
enhance: use loadPrism
LincZero May 21, 2025
12b21be
fix: allow render when without sectionInfo
LincZero May 21, 2025
2a452d8
fix: last blank line question
LincZero May 21, 2025
0f1897c
feat: editable languageType
LincZero May 21, 2025
1093024
refactor: add CodeblockInfo, feat: save lang type
LincZero May 21, 2025
1ce4827
enhance: indent recognition
LincZero May 22, 2025
277ccc4
fix: render error when readmode codeblock in nest
LincZero May 22, 2025
84e7cd0
chore: update min version
LincZero May 22, 2025
98477cb
chore: lint code
LincZero May 22, 2025
a6e1d36
feat: add setting: renderEngine
LincZero May 22, 2025
2a83c4e
feat: textarea support tab key
LincZero May 23, 2025
e9f4bd8
docs: add more document
LincZero May 23, 2025
cd59a8d
style: simplify
LincZero May 23, 2025
0b18bff
chore: check lint
LincZero May 23, 2025
9dcbacd
docs: settingPanel docs, more docs
LincZero May 23, 2025
d84f859
fix: pdf show metadata, tab-size disunity
LincZero May 23, 2025
d02349f
style: textarea selection color
LincZero May 23, 2025
b02166f
style: uniform font
LincZero May 23, 2025
3a7e4c9
fix: ! save lack '\n'
LincZero May 23, 2025
5c33a0b
feat: arrow cursor from codeblock to root editor
LincZero May 23, 2025
dfafe2c
style: optimize selection color
LincZero May 23, 2025
000c01f
fix: when code include tag
LincZero May 23, 2025
2a26acf
fix: when code include tag2
LincZero May 23, 2025
3cd0282
fix: temp fix error when use custom theme
LincZero May 23, 2025
dc6460e
refactor: add EditableCodeblock, optimize code
LincZero May 24, 2025
e5d61a1
feat: add new renderMode: editable pre
LincZero May 24, 2025
822277a
feat: add languageType arrow event
LincZero May 24, 2025
7d6d684
feat: add a new save cache, debounce save version
LincZero May 24, 2025
621e02f
enhance: ensure editor safe, saveContent faster
LincZero May 24, 2025
0291572
feat: new setting option: saveMode
LincZero May 24, 2025
f5bd349
fix: can't catch transaction fail error
LincZero May 25, 2025
4db8af9
fix: readmode input should readonly
LincZero May 29, 2025
ea4a79d
fix: rerender will affect chinese input method
LincZero May 30, 2025
04bb314
refactor: editablePre support shiki, oninput mode1
LincZero May 31, 2025
2b98541
refactor: editablePre support shiki, oninput mode2
LincZero May 31, 2025
898e1a8
docs: add link: Visual select theme
LincZero May 31, 2025
913a11f
docs: chore comment
LincZero May 31, 2025
64bf58c
refactor: reuse keydown event1
LincZero May 31, 2025
2bd2c59
refactor: reuse keydown event2
LincZero May 31, 2025
04f8b4a
fix: double save cause error when edit last line
LincZero Jun 1, 2025
28fc7cd
enhance: cursor up/down move optimize
LincZero Jun 3, 2025
b7dd8b4
docs: update setting docs
LincZero Jun 4, 2025
2f9b2b6
feat: add renderCallout (beta)
LincZero Jun 6, 2025
6f34e65
feat: add renderCallout (beta)2
LincZero Jun 6, 2025
8c94255
refactor: renderCallout1
LincZero Jun 7, 2025
59962bb
refactor: renderCallout2
LincZero Jun 8, 2025
c16e835
refactor: renderCallout3
LincZero Jun 8, 2025
dd863b1
chore: optimize code, comment
LincZero Jun 8, 2025
ea874d4
feat: add un save flag
LincZero Jun 8, 2025
1f1bf6c
fix: a print error
LincZero Jun 8, 2025
5d2c46d
enhance: code highlight add unsave flag
LincZero Jun 9, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 64 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
name: Node.js CI/CD Pipeline

on:
push:
branches: [master]
pull_request:
branches: [master]
workflow_dispatch:

jobs:
build-obsidian:
runs-on: ubuntu-latest
steps:
- name: checkout repo
uses: actions/checkout@v4
- name: env use node.js
uses: actions/setup-node@v4
with:
node-version: '22'
- name: Install Bun
uses: oven-sh/setup-bun@v1
with:
bun-version: latest
- name: build
run: |
bun install
bun run build
- name: upload build artifact
if: always()
uses: actions/upload-artifact@v4
with:
name: build-artifact
path: |
manifest.json
main.js
styles.css

build-obsidian-min:
runs-on: ubuntu-latest
steps:
- name: checkout repo
uses: actions/checkout@v4
- name: env use node.js
uses: actions/setup-node@v4
with:
node-version: '22'
- name: Install Bun
uses: oven-sh/setup-bun@v1
with:
bun-version: latest
- name: build
run: |
bun install
bun run build-min
mv dist-min/main.js main.js
- name: upload build artifact
if: always()
uses: actions/upload-artifact@v4
with:
name: build-artifact-min
path: |
manifest.json
main.js
styles.css
56 changes: 56 additions & 0 deletions automation/build/esbuild.config.min.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import builtins from 'builtin-modules';
import esbuild from 'esbuild';
import { getBuildBanner } from 'build/buildBanner';
import { nodeModulesPolyfillPlugin } from 'esbuild-plugins-node-modules-polyfill';

const banner = getBuildBanner('Release Build', version => version);

const build = await esbuild.build({
banner: {
js: banner,
},
entryPoints: ['src/main.min.ts'],
bundle: true,
external: [
'obsidian',
'electron',
'@codemirror/autocomplete',
'@codemirror/collab',
'@codemirror/commands',
'@codemirror/language',
'@codemirror/lint',
'@codemirror/search',
'@codemirror/state',
'@codemirror/view',
'@lezer/common',
'@lezer/highlight',
'@lezer/lr',
...builtins,
'shiki', // [!code hl]
],
format: 'cjs',
target: 'es2018',
logLevel: 'info',
sourcemap: false,
treeShaking: true,
outfile: 'dist-min/main.js', // [!code hl]
minify: true,
metafile: true,
define: {
MB_GLOBAL_CONFIG_DEV_BUILD: 'false',
},
plugins: [
nodeModulesPolyfillPlugin({
modules: {
fs: true,
path: true,
url: true,
},
}),
],
});

const file = Bun.file('meta.txt');
await Bun.write(file, JSON.stringify(build.metafile, null, '\t'));

process.exit(0);
90 changes: 90 additions & 0 deletions bun.lock

Large diffs are not rendered by default.

84 changes: 84 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
# More Document

version: v0.5.1

## SettingPanel Document

### Rendering engine

Shiki, PrismJS, CodeMirror

- Shiki: A powerful code highlighting engine.
- More powerful functions, more themes and plugins
- Plugins: meta annotations, annotated annotations. Line highlighting, word highlighting, differentiated annotation, warning/error annotation
- Theme: Nearly 80 color schemes: You can visually select them at https://textmate-grammars-themes.netlify.app
- *The min version does not include this library and the engine cannot be selected*
- PrismJS: The rendering engine that Obsidian uses by default in reading mode.
- When choosing this one, you can also select the min version of this plugin, which has a smaller plugin size and a faster loading speed
- It can be color-matched with code using obsidian themes and can be used in conjunction with some other obsidian stylization plugins
- CodeMirror: Obsidian is the default rendering engine used in real-time mode. The current plugin is not supported
- It is suitable for real-time rendering and has acceptable performance
- However, the code analysis is rather rough, with a small number of highlighting layers and a poor effect

### Rendering method

- textarea (default)
- Advantage:
Allows real-time editing and offers a Typora-like WYSIWYG experience
Support editing annotation-type highlighting
The new version of Obsidian's md table within block editing uses this approach. (However, the ob table editing does not trigger a re-rendering.)
- Disadvantage:
In principle, textarea and pre are perfectly overlapped together, but they are prone to incomplete overlap due to the influence of themes and styles
- pre
- Disadvantage:
Real-time editing is not allowed. The rendering effect is more similar to the textarea method
- editable pre
- Advantage:
Allows real-time editing and offers a Typora-like WYSIWYG experience
In principle, it is `code[contenteditable='true']`
- Disadvantage:
The cursor position needs to be handled manually in the program
*No support editing annotation-type highlighting*
- codemirror
- Disadvantage:
The only supported method for V0.5.0 and earlier versions, which does not allow real-time editing

> [!warning]
>
> If a real-time editable solution is chosen, it is best to use it when the warehouse is regularly backed up to avoid unexpected situations

### AutoSave method

- onchange
- Advantage:
Great performance.
There is no need to manage the cursor position manually
- Disadvantage:
Delay save, change will loss if: the program crashes suddenly. when cursor in codeblock, switch to readmode or close window/tab
- oninput
- Advantage:
Save immediately, data is more secure.
The new version of Obsidian's md table within block editing uses this approach.
- Disadvantage:
Worse performance? The code block needs to be recreated every time it is modified
The cursor position needs to be handled manually. Debounce manually.
It is necessary to pay attention to the input method issue. The `oninput` will also be triggered during the input candidate stage

## Shiki Extend Sytax

see https://shiki.style/packages/transformers for detail

This is a simple summary of grammar:

- notaion
- diff: `// [!code ++]` `// [!code --]`
- highlight: `// [!code hl]` `// [!code highlight]`
- word highlight: `// [!code word:<Word>:<number>]` `// [!code word:Hello:1]`
- focus: `// [!code focus]`
- error level: `// [!code error]` `// [!code warning]`
- (mul line): `// [!code highlight:3]`
- meta
- highlight: `{1,3-4}`
- word highlight `/<Word>/` `/Hello/`

example: see [../README.md](../README.md) or [Shiki document](https://shiki.style/packages/transformers)
84 changes: 84 additions & 0 deletions docs/README.zh.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
# 更多文档

version: v0.5.1

## 设置面板文档

### 渲染引擎

Shiki, PrismJS,CodeMirror

- Shiki: 一个强大的代码高亮引擎。
- 功能更加强大,更多主题和插件
- 插件: meta标注、注释型标注。行高亮、单词高亮、差异化标注、警告/错误标注
- 主题:近80种配色方案:你可以在 https://textmate-grammars-themes.netlify.app 中可视化选择
- *min版不包含该库,无法选用该引擎*
- PrismJS: Obsidian默认在阅读模式中使用的渲染引擎。
- 当选择这个的时候,你也可以选用min版本的本插件,拥有更小的插件体积和更快的加载速度
- 可以与使用obsidian主题的代码配色,可以与一些其他的obsidian风格化插件配合
- CodeMirror: Obsidian默认在实时模式中使用的渲染引擎。当前插件不支持
- 适合实时渲染,性能尚可
- 但代码分析比较粗糙,高亮层数少,效果较差

### 渲染方式

- textarea (默认)
- 优点:
允许实时编辑,typora般的所见即所得的体验
支持编辑注释型高亮
同为块内编辑的obsidian新版本md表格,采用的是这种方式 (但ob表格编辑时不触发重渲染)
- 缺点:
原理上是将textarea和pre完美重叠在一起,但容易受主题和样式影响导致不完全重叠
- pre
- 缺点:
不允许实时编辑
- editable pre
- 优点:
允许实时编辑,typora般的所见即所得的体验
原理上是 `code[contenteditable='true']`
- 缺点:
程序上需要手动处理光标位置
*不支持实时编辑注释型高亮*
- codemirror
- 缺点:
V0.5.0及之前唯一支持的方式,不允许实时编辑

> [!warning]
>
> 如果选用了可实时编辑的方案,最好能在仓库定期备份的情况下使用,避免意外

### 自动保存方式

- onchange
- 优点:
更好的性能
程序实现简单更简单,无需手动管理光标位置
- 缺点:
延时保存,特殊场景可能不会保存修改: 程序突然崩溃。当光标在代码块中时,直接切换到阅读模式,或关闭当前窗口/标签页
- oninput
- 优点:
实时保存,数据更安全
同为块内编辑的obsidian新版本md表格,采用的是这种方式
- 缺点:
性能略差? 每次修改都要重新创建代码块
程序需要手动管理光标位置,手动防抖。
需要注意输入法问题,输入候选阶段也会触发 `oninput`

## Shiki扩展语法

详见: https://shiki.style/packages/transformers (可切换至中文)

这是个简单的语法总结:

- notaion 注释型标注
- diff: `// [!code ++]` `// [!code --]` 差异化
- highlight: `// [!code hl]` `// [!code highlight]` 高亮
- word highlight: `// [!code word:<Word>:<number>]` `// [!code word:Hello:1]` 单词高亮
- focus: `// [!code focus]` 聚焦
- error level: `// [!code error]` `// [!code warning]` 警告/错误
- (mul line): `// [!code highlight:3]` (多行)
- meta 元数据型标注
- highlight: `{1,3-4}`
- word highlight `/<Word>/` `/Hello/`

示例: see [../README.md](../README.md) or [Shiki document](https://shiki.style/packages/transformers)
8 changes: 7 additions & 1 deletion eslint.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,13 @@ export default tseslint.config(
'no-relative-import-paths': no_relative_import_paths,
},
rules: {
'@typescript-eslint/no-explicit-any': ['warn'],
// `any` about
'@typescript-eslint/no-explicit-any': 'off', // ['warn'],
'@typescript-eslint/no-unsafe-call': 'off',
'@typescript-eslint/no-unsafe-assignment': 'off',
'@typescript-eslint/no-unsafe-member-access': 'off',
'@typescript-eslint/no-unsafe-return': 'off',
'@typescript-eslint/no-unsafe-argument': 'off',

'@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_', destructuredArrayIgnorePattern: '^_' }],
'@typescript-eslint/consistent-type-imports': ['error', { prefer: 'type-imports', fixStyle: 'inline-type-imports' }],
Expand Down
7 changes: 6 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"scripts": {
"dev": "bun run automation/build/esbuild.dev.config.ts",
"build": "bun run tsc && bun run automation/build/esbuild.config.ts",
"build-min": "bun run tsc && bun run automation/build/esbuild.config.min.ts",
"tsc": "tsc -noEmit -skipLibCheck",
"test": "bun test",
"test:log": "LOG_TESTS=true bun test",
Expand All @@ -22,6 +23,8 @@
"author": "Moritz Jung",
"license": "MIT",
"devDependencies": {
"@codemirror/basic-setup": "^0.20.0",
"@codemirror/lang-markdown": "^6.3.2",
"@codemirror/language": "^6.11.0",
"@codemirror/state": "^6.5.2",
"@codemirror/view": "^6.36.8",
Expand All @@ -35,8 +38,10 @@
"@happy-dom/global-registrator": "^17.4.7",
"@lemons_dev/parsinom": "^0.0.12",
"@lezer/common": "^1.2.3",
"@shikijs/transformers": "^3.4.2",
"@tsconfig/svelte": "^5.0.4",
"@types/bun": "^1.2.13",
"@types/prismjs": "^1.26.5",
"builtin-modules": "^5.0.0",
"esbuild": "^0.25.4",
"esbuild-plugin-copy-watch": "^2.3.1",
Expand All @@ -53,4 +58,4 @@
"typescript": "^5.8.3",
"typescript-eslint": "^8.32.1"
}
}
}
Loading