dsh-latex-formula-editor 1.0.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.en.md CHANGED
@@ -1,37 +1,146 @@
1
- # dsh-latex-formula-editor
1
+ # DSH LaTeX Formula Editor
2
2
 
3
- > A LaTeX formula editor for the DSH sidebar: offline rendering, tile-based symbol input, formula templates, favourites, image/document OCR, multi-format export and sharing.
3
+ English · [简体中文](README.md)
4
4
 
5
- ![Plugin UI](docs/img/editor.png)
5
+ A free, open-source and fully offline LaTeX formula editor that lives in the **left sidebar** of the DeepSeek Harness Web UI (icon `Σ`).
6
+ Interaction follows [latexlive.com](https://www.latexlive.com/), but everything runs on your own machine: maths is rendered by the
7
+ bundled MathJax, PDFs are parsed by the bundled PDF.js — no account, no quota, no uploads (except the recognition backend you configure).
8
+
9
+ - Sidebar entry → one panel with five views: **Editor / Image OCR / Document OCR / Favourites / Help**
10
+ - Live LaTeX rendering (MathJax 3.2.2, SVG output, offline)
11
+ - UI scale **125%** by default (Settings → UI scale, 100%–200%)
12
+ - Light / dark theme switch (follows the system by default), 简体中文 / 繁體中文 / English
13
+ - Share links encode the formula in the URL hash — nothing goes through a server
14
+ - Nine export formats plus four export menus (image / code / escape / share)
15
+
16
+ ![Editor](docs/img/editor.png)
17
+
18
+ ## Features
19
+
20
+ ### Quick tools
21
+
22
+ Ten tiles above the input: **common symbols / Greek / fractions & calculus / roots & scripts / limits & logs / trigonometry /
23
+ integrals / large operators / brackets & floors / matrices**.
24
+
25
+ - Each tile icon is a live-typeset representative formula, not an image
26
+ - Hovering a tile expands its symbol panel **4px below**, grouped exactly like the palette data (e.g. Greek → lower case 30 / upper case 11); it collapses when the pointer leaves
27
+ - Every symbol has a ☆ in its corner to save it to favourites; clicking the symbol inserts it at the caret
28
+ - The tile strip scrolls horizontally with the mouse wheel (vertical wheel is translated), so the right-most tiles are reachable
29
+
30
+ ![Quick tools](docs/img/hover.png)
31
+
32
+ ### Templates
33
+
34
+ Ten template tiles: **algebra / geometry / inequalities / integrals / matrices / trigonometry / statistics / sequences /
35
+ physics / chemistry** — hover to expand and insert a ready-made snippet (quadratic roots, law of cosines, AM-GM,
36
+ binomial theorem, variance, geometric series, Schrödinger equation, chemical equations …).
37
+
38
+ ![Templates](docs/img/templates.png)
39
+
40
+ ### Format row
41
+
42
+ A separate row below the tiles, divided by a rule, with eight equal 62px icon buttons:
43
+
44
+ | Button | What it does |
45
+ | --- | --- |
46
+ | Colour | Palette icon + colour picker; picking a colour wraps the selection in `\textcolor{#hex}{…}` |
47
+ | Font | Roman / bold / italic / underline / sans / blackboard / calligraphic / fraktur, each rendered in that font inside the menu |
48
+ | Size | Nine steps from tiny to huge, each rendered at that size inside the menu |
49
+ | Environment | align / aligned / gathered / cases / split / array / eqnarray, plus "none" (strips the outer environment); wraps the selection in `\begin{…}…\end{…}` |
50
+ | Clear | Empties the source |
51
+ | Undo | Undo the previous edit (keystrokes within 400 ms merge, up to 120 steps) |
52
+ | Import | Reads `.tex` / `.txt` |
53
+ | Favourite | Saves the current formula to favourites |
54
+
55
+ With a selection the text is wrapped; without one an empty shell is inserted and the caret placed inside.
56
+
57
+ ### Favourites
58
+
59
+ The fifth tab; every favourite is a card:
60
+
61
+ - **Title** ("Untitled formula" by default, click to rename), **timestamp**, **rendered preview**, **LaTeX source** (click to copy)
62
+ - **Insert / Copy / Delete** buttons
63
+ - A search box filters by **title or source**
64
+ - The cap defaults to **10** (Settings → Favourites limit, 1–50); the oldest entry is dropped beyond it
65
+
66
+ ![Favourites](docs/img/favourites.png)
67
+
68
+ ### Output
69
+
70
+ The export bar sits at the top of the preview column, with four menus:
71
+
72
+ | Menu | Options |
73
+ | --- | --- |
74
+ | Image | SVG / PNG / JPG (3× scale) |
75
+ | Code | LaTeX, AsciiMath, Typst, SVG Code, HTML inline, HTML display, MathML, MathML (mml:), MathML (m:), MathML (attr:), OMML |
76
+ | Escape | Escaped backslash, `$…$`, `$$…$$`, `\(…\)`, `\[…\]`, JSON string |
77
+ | Share | Copy the share link (`#tex=` encoded — opening it restores the formula) |
78
+
79
+ AsciiMath and Typst are produced by a real TeX parser and OMML by converting the MathML DOM into Word's formula structure — not by copying the LaTeX source.
80
+
81
+ The canvas background follows the theme: white in the light theme, black in the dark theme (transparent / white / dark can still be picked manually).
82
+
83
+ ### Recognition
84
+
85
+ - **Image OCR**: drop, paste or pick an image; the configured model returns LaTeX and inserts it
86
+ - **Document OCR**: renders each PDF page and recognises it page by page; when done you can **download Word / LaTeX / Markdown**, and results from the last 15 days can be downloaded again without using quota
87
+
88
+ ![Document OCR](docs/img/doc-ocr.png)
89
+
90
+ ### Interface
91
+
92
+ - **125%** scale by default, adjustable 100%–200%; narrow panels switch to a compact layout (tabs wrap, actions become icons, panels scroll internally)
93
+ - Light / dark slider (sun / moon icons), system default
94
+ - Language menu: 简体中文 / 繁體中文 / English (traditional Chinese is derived from the simplified dictionary on the fly)
95
+
96
+ ![Settings](docs/img/settings.png)
6
97
 
7
98
  ## Install
8
99
 
100
+ The plugin is normally mounted from a **local directory** (`link:` dependency), and it is also available on npm:
101
+
9
102
  ```bash
103
+ # local directory
10
104
  git clone https://github.com/jiahui-huang1/dsh-latex-formula-editor.git
11
105
  pnpm dsh plugin add ./dsh-latex-formula-editor
106
+
107
+ # or from npm
108
+ pnpm dsh plugin add dsh-latex-formula-editor
12
109
  ```
13
110
 
14
- Enable **LaTeX Formula Editor** in the DSH sidebar (entry id `latex-editor`).
111
+ Then enable **LaTeX Formula Editor** in the DSH sidebar (entry id `latex-editor`). Restart DSH after changing the plugin.
15
112
 
16
- ## Features
113
+ ## Layout
17
114
 
18
- - **Quick tools** — ten tiles (common symbols, Greek, fractions/calculus, roots, limits & logs, trigonometry, integrals, large operators, brackets, matrices); hover to expand the grouped symbol panel, click to insert.
19
- - **Templates** — algebra, geometry, inequalities, integrals, matrices, trigonometry, statistics, sequences, physics, chemistry.
20
- - **Format row** — colour picker, rendered font menu, rendered size menu, environment wrapper (align/aligned/gathered/cases/split/array/eqnarray/none), clear, undo, import, favourite.
21
- - **Export** — images (SVG/PNG/JPG), code (LaTeX/AsciiMath/Typst/SVG Code/HTML inline & display/MathML variants/OMML), escaping (backslash, `$…$`, `$$…$$`, `\(…\)`, `\[…\]`, JSON) and share links.
22
- - **Favourites** — title, timestamp, render and source per entry; rename, copy, delete, insert; searchable; configurable cap (10 by default).
23
- - **Recognition** — image OCR (drag & paste) and document OCR (page by page, download as Word/LaTeX/Markdown, results kept for 15 days).
24
- - **UI** — 150% default scale, light/dark theme, 简体中文 / 繁體中文 / English.
25
-
26
- ![Document OCR](docs/img/doc-ocr.png)
115
+ ```
116
+ index.js Host half: static asset routes, recognition endpoint, settings persistence, latex_formula tool
117
+ client.js Client entry: registers the sidebar entry (sidebar.panellist) and the main panel (main)
118
+ lib/
119
+ ├─ 00-core.js namespace, i18n, settings store, UI primitives, icons
120
+ ├─ 10-latex.js symbol palette / templates / parser / source utilities
121
+ ├─ 20-render.js MathJax rendering, nine export formats, PDF writer
122
+ ├─ 30-visual.js legacy symbol / template panels and structure tree
123
+ ├─ 35-tiles.js quick-tool and template tiles, favourites, export menus
124
+ ├─ 40-recognition.js recognition backends (harness model / OpenAI-compatible endpoint)
125
+ ├─ 45-convert.js TeX → AsciiMath / Typst, MathML → OMML
126
+ ├─ 50-app.js main UI: editor, preview, export, history, share
127
+ ├─ 56-recognition-panels.js image and document OCR panels
128
+ ├─ 60-settings-help.js settings and help page
129
+ └─ 90-skin.js corporate-clean skin and theme tokens
130
+ vendor/ MathJax 3.2.2 and PDF.js (shipped with the plugin)
131
+ ```
27
132
 
28
133
  ## Settings
29
134
 
30
- Settings → OCR service: use the Harness model or an OpenAI-compatible endpoint. Rendering and export are fully offline; only OCR sends an image.
135
+ - **Editor**: UI scale (125% default), source font size, word wrap, formula numbering, favourites limit
136
+ - **Recognition**: `auto` prefers the harness model; otherwise fill in an OpenAI-compatible endpoint (URL / model / key)
137
+ - Rendering and export are fully offline; only OCR sends the image to your backend
138
+ - Settings live in `<DSH_HOME>/latex-editor/settings.json`
31
139
 
32
140
  ## Requirements
33
141
 
34
- DSH ≥ 1.0 (`dsh.bundle.patch` + `dsh.client`). No build step; MathJax 3 and PDF.js ship with the plugin.
142
+ - DSH ≥ 1.0 (Cordis plugin spec: `dsh.bundle.patch` + `dsh.client`)
143
+ - No build step on the browser side; MathJax and PDF.js ship with the plugin
35
144
 
36
145
  ## Licence
37
146
 
package/README.md CHANGED
@@ -1,40 +1,143 @@
1
- # dsh-latex-formula-editor
1
+ # DSH LaTeX 公式编辑器
2
2
 
3
- > LaTeX 公式编辑器 —— DSH 侧栏插件:离线渲染、磁贴取符号、公式模板、收藏夹、图片/文档识别、多格式导出与分享。
3
+ 简体中文 · [English](README.en.md)
4
4
 
5
- ![插件界面](docs/img/editor.png)
5
+ 一个免费开源、可离线使用的 LaTeX 公式编辑器,挂在 DeepSeek Harness Web UI 的**左侧栏**(图标 `Σ`)。
6
+ 交互参考 [latexlive.com](https://www.latexlive.com/),但**全部在自己的机器上运行**:数学渲染用随包分发的
7
+ MathJax,PDF 解析用随包分发的 PDF.js,没有账号、没有额度、也不会上传(除了你自己配置的识别后端)。
8
+
9
+ - 侧栏入口 → 主面板,五个视图:**编辑器 / 图片识别 / 文档识别 / 收藏夹 / 帮助**
10
+ - LaTeX 实时渲染(MathJax 3.2.2,SVG 输出,离线)
11
+ - 界面缩放默认 **125%**(设置 → 界面缩放可在 100%–200% 之间切换)
12
+ - 浅色 / 深色主题一键切换(默认跟随系统),简体中文 / 繁體中文 / English 三语
13
+ - 分享链接把公式编码进 URL hash,不经过任何服务器
14
+ - 九种导出格式 + 四组导出菜单(图片 / 代码 / 转义 / 分享)
15
+
16
+ ![编辑器](docs/img/editor.png)
17
+
18
+ ## 功能
19
+
20
+ ### 快捷工具
21
+
22
+ 输入区上方是 10 张磁贴:**常用符号 / 希腊字母 / 分数微分 / 根式角标 / 极限对数 / 三角函数 / 积分运算 / 大型运算 / 括号取整 / 数组矩阵**。
23
+
24
+ - 磁贴图标是按分类实时排版的代表公式,不是图片
25
+ - 悬停磁贴在正下方 **4px** 处展开该分类的符号面板,并按数据里的分组分节(如希腊字母 → 小写字母 30 / 大写字母 11),移开自动收拢
26
+ - 面板里每个符号右上角有 ☆,点一下收藏到收藏夹,点击符号本身插入到光标处
27
+ - 磁贴行支持**滚轮横向滚动**(竖向滚轮自动转成横向),最右侧磁贴可滚到
28
+
29
+ ![快捷工具](docs/img/hover.png)
30
+
31
+ ### 公式模板
32
+
33
+ 10 张模板磁贴:**代数 / 几何 / 不等式 / 积分 / 矩阵 / 三角 / 统计 / 数列 / 物理 / 化学**,悬停展开后整条插入现成模板(求根公式、余弦定理、均值不等式、二项式定理、方差、等比数列求和、薛定谔方程、化学方程式等)。
34
+
35
+ ![公式模板](docs/img/templates.png)
36
+
37
+ ### 格式工具
38
+
39
+ 磁贴行下方用分隔线隔开的独立一行,8 个等宽图标按钮(62px):
40
+
41
+ | 按钮 | 说明 |
42
+ | --- | --- |
43
+ | 颜色 | 调色盘图标 + 取色器,选色即把选中文字包进 `\textcolor{#hex}{…}` |
44
+ | 字体 | 正体 / 加粗 / 斜体 / 下划线 / 无衬线 / 黑板粗体 / 手写体 / 德文尖角体,下拉里每项用该字体真实渲染 |
45
+ | 字号 | 极小 → 巨无霸九档,下拉里每项用该字号真实渲染 |
46
+ | 环境 | align / aligned / gathered / cases / split / array / eqnarray,以及「无环境」(拆掉最外层环境);选中即包 `\begin{…}…\end{…}` |
47
+ | 清空 | 清空源码区 |
48
+ | 撤销 | 撤销上一步(连续输入 400ms 合并为一步,最多 120 步) |
49
+ | 导入 | 读取 `.tex` / `.txt` |
50
+ | 收藏 | 把当前公式存进收藏夹 |
51
+
52
+ 有选中文字就包裹选中内容,没有则插入空壳并把光标放进去。
53
+
54
+ ### 收藏夹
55
+
56
+ 顶部第五个页签,每条收藏是一张卡片:
57
+
58
+ - **标题**(默认「未命名公式」,点击即可改名)、**收藏时间**、**渲染结果**、**LaTeX 源码**(点击即复制)
59
+ - **插入 / 复制 / 删除** 三个按钮
60
+ - 顶部搜索框可按**标题或源码**检索
61
+ - 数量上限默认 **10**,在 设置 → 收藏夹上限 调整(1–50),超出时丢弃最旧的一条
62
+
63
+ ![收藏夹](docs/img/favourites.png)
64
+
65
+ ### 输出区域
66
+
67
+ 导出条在预览区顶部,四组菜单:
68
+
69
+ | 菜单 | 选项 |
70
+ | --- | --- |
71
+ | 输出图片 | SVG / PNG / JPG(3× 倍率) |
72
+ | 输出代码 | LaTeX、AsciiMath、Typst、SVG Code、HTML 行内、HTML 独立、MathML、MathML(mml:)、MathML(m:)、MathML(attr:)、OMML |
73
+ | 转义 | 反斜杠转义、`$…$`、`$$…$$`、`\(…\)`、`\[…\]`、JSON 字符串 |
74
+ | 分享 | 复制分享链接(`#tex=` 编码,打开即回填公式) |
75
+
76
+ AsciiMath / Typst 由内置 TeX 解析器真实转换,OMML 由 MathML DOM 转换为 Word 公式结构,不是直接复制 LaTeX。
77
+
78
+ 预览画布底色随主题自动切换:浅色主题白底、深色主题黑底(透明 / 白底 / 深色仍可手动覆盖)。
79
+
80
+ ### 识别
81
+
82
+ - **图片识别**:拖拽、粘贴或选择图片,调用你配置的模型识别为 LaTeX 并插入编辑器
83
+ - **文档识别**:PDF 逐页渲染后识别,可挑页;完成后可**下载 Word / LaTeX / Markdown**,最近 15 天的识别记录可重新下载(不消耗额度)
84
+
85
+ ![文档识别](docs/img/doc-ocr.png)
86
+
87
+ ### 界面
88
+
89
+ - 默认 **125%** 缩放,100%–200% 可调;窄面板自动进入紧凑布局(页签换行、图标化动作、面板内滚动)
90
+ - 浅色 / 深色主题滑块(太阳 / 月亮图标),默认跟随系统
91
+ - 语言菜单:简体中文 / 繁體中文 / English,繁体由简体词表实时转换
92
+
93
+ ![设置](docs/img/settings.png)
6
94
 
7
95
  ## 安装
8
96
 
97
+ 本插件通过**本地目录**挂载到 DSH profile(`link:` 依赖),也可以从 npm 安装:
98
+
9
99
  ```bash
10
- # 1. 取仓库
100
+ # 方式一:本地目录
11
101
  git clone https://github.com/jiahui-huang1/dsh-latex-formula-editor.git
12
- # 2. 以本地插件方式安装(DSH 会自动读取 package.json 里的 dsh.bundle.patch / dsh.client)
13
102
  pnpm dsh plugin add ./dsh-latex-formula-editor
103
+
104
+ # 方式二:npm 包
105
+ pnpm dsh plugin add dsh-latex-formula-editor
14
106
  ```
15
107
 
16
- 安装后在 DSH 左侧栏启用 **公式编辑器**(入口 id `latex-editor`)。
108
+ 安装后在 DSH 左侧栏启用 **公式编辑器**(入口 id `latex-editor`)。修改插件后重启 DSH 即可生效。
17
109
 
18
- ## 功能
110
+ ## 目录结构
19
111
 
20
- - **快捷工具**:常用符号 / 希腊字母 / 分数微分 / 根式角标 / 极限对数 / 三角函数 / 积分运算 / 大型运算 / 括号取整 / 数组矩阵,悬停磁贴展开分组符号面板,点击插入光标处
21
- - **公式模板**:代数 / 几何 / 不等式 / 积分 / 矩阵 / 三角 / 统计 / 数列 / 物理 / 化学,展开即可整条插入
22
- - **格式行**:取色器、真实字体预览、真实字号预览、环境包裹(align / aligned / gathered / cases / split / array / eqnarray / 无环境)、清空、撤销、导入、收藏
23
- - **输出**:输出图片(SVG / PNG / JPG)、输出代码(LaTeX / AsciiMath / Typst / SVG Code / HTML 内联与独立 / MathML / MathML mml: / m: / attr: / OMML)、转义(反斜杠、`$…$`、`$$…$$`、`\(…\)`、`\[…\]`、JSON)、分享链接
24
- - **收藏夹**:标题、时间、渲染结果、源码;可改名 / 复制 / 删除 / 插入;按标题或源码搜索;上限可配(默认 10)
25
- - **识别**:图片识别(拖拽 / 粘贴)、文档识别(逐页 OCR,支持下载 Word / LaTeX / Markdown,最近 15 天记录可重新下载)
26
- - **界面**:默认 150% 缩放、浅色/深色主题、简体中文 / 繁體中文 / English
27
-
28
- ![文档识别](docs/img/doc-ocr.png)
112
+ ```
113
+ index.js Host 半:静态资源路由、识别接口、设置持久化、latex_formula 工具
114
+ client.js 客户端入口:注册侧栏入口(sidebar.panellist)与主面板(main)
115
+ lib/
116
+ ├─ 00-core.js 命名空间、i18n、设置存储、UI 原子组件、图标
117
+ ├─ 10-latex.js 符号表 / 模板 / 解析器 / 源码工具(纯逻辑)
118
+ ├─ 20-render.js MathJax 渲染、九种导出格式、PDF 生成
119
+ ├─ 30-visual.js 旧版符号面板 / 模板面板 / 结构树(新面板见 35-tiles)
120
+ ├─ 35-tiles.js 快捷工具与公式模板磁贴、收藏夹、导出菜单
121
+ ├─ 40-recognition.js 识别后端(Harness 模型 / OpenAI 兼容端点)
122
+ ├─ 45-convert.js TeX → AsciiMath / Typst、MathML → OMML
123
+ ├─ 50-app.js 主界面:编辑器、预览、导出、历史、分享
124
+ ├─ 56-recognition-panels.js 图片识别与文档识别界面
125
+ ├─ 60-settings-help.js 设置面板与帮助页
126
+ └─ 90-skin.js 企业简洁风皮肤与主题变量
127
+ vendor/ MathJax 3.2.2 与 PDF.js(随包分发)
128
+ ```
29
129
 
30
- ## 配置
130
+ ## 设置
31
131
 
32
- 设置 → 识别服务:可选 Harness 内置模型或自建 OpenAI 兼容端点;渲染与导出完全离线,仅识别会发送图片。
132
+ - **编辑器**:界面缩放(默认 125%)、源码字号、自动换行、公式编号、收藏夹上限
133
+ - **识别**:`auto` 优先用 Harness 模型;也可填 OpenAI 兼容端点(URL / 模型 / Key)
134
+ - 渲染与导出完全离线,只有识别会把图片发给你配置的后端
135
+ - 设置保存在本机 `<DSH_HOME>/latex-editor/settings.json`
33
136
 
34
137
  ## 兼容性
35
138
 
36
139
  - DSH ≥ 1.0(Cordis 插件规范:`dsh.bundle.patch` + `dsh.client`)
37
- - 浏览器侧无构建步骤,MathJax 3 与 PDF.js 已随插件内置
140
+ - 浏览器侧没有构建步骤,MathJax 与 PDF.js 已随插件内置
38
141
 
39
142
  ## 许可
40
143
 
package/client.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @local/dsh-latex-editor — Client entry.
2
+ * dsh-latex-formula-editor — Client entry.
3
3
  *
4
4
  * The bundle's `dsh.client` declaration loads this file as the browser half. It
5
5
  * - loads the workbench modules from the Host (`/plugins/latex-editor/lib/*.js`,
@@ -9,7 +9,7 @@
9
9
  * (`main`, keyed by the same id).
10
10
  */
11
11
  window.__ModuleLoader__.load({
12
- id: '@local/dsh-latex-editor',
12
+ id: 'dsh-latex-formula-editor',
13
13
  factory(require) {
14
14
  const React = require('react')
15
15
  const h = React.createElement
@@ -0,0 +1,22 @@
1
+ # Bundle patch layer for the LaTeX formula workbench.
2
+ #
3
+ # The Host row loads ./index.js (static asset routes for the vendored MathJax and
4
+ # PDF.js builds, the recognition endpoint, and the `latex_formula` agent tool).
5
+ # The `dsh.client` declaration in package.json makes the Web app load ./client.js
6
+ # as the browser half, which registers:
7
+ # - sidebar.panellist id=latex-editor (the left-column entry)
8
+ # - main key=latex-editor (the panel it opens)
9
+ - insert:
10
+ - id: latex-editor
11
+ name: 'dsh-latex-formula-editor'
12
+ config:
13
+ # Recognition backend: 'auto' prefers the harness model, then an endpoint.
14
+ backend: auto
15
+ # Optional OpenAI-compatible vision endpoint used when `backend` is
16
+ # 'endpoint' or when the harness model cannot accept images.
17
+ endpointUrl: ''
18
+ endpointModel: ''
19
+ endpointKey: ''
20
+ # Hard caps for one recognition request.
21
+ maxImageBytes: 8388608
22
+ timeoutMs: 120000
Binary file
Binary file
Binary file
package/docs/img/help.png CHANGED
Binary file
Binary file
Binary file
Binary file
package/index.js CHANGED
@@ -17,6 +17,10 @@ import { fileURLToPath } from 'node:url'
17
17
 
18
18
  const HERE = path.dirname(fileURLToPath(import.meta.url))
19
19
  const PREFIX = '/plugins/latex-editor'
20
+ // The web shell addresses a client bundle as /plugins/<package-name>/client.js,
21
+ // while the panel's own assets use the short prefix above; serve both.
22
+ const PREFIX_ALIASES = ['/plugins/dsh-latex-formula-editor']
23
+ const ALL_PREFIXES = [PREFIX].concat(PREFIX_ALIASES)
20
24
  const MAX_JSON_BYTES = 24 * 1024 * 1024
21
25
  const MAX_LATEX_CHARS = 64 * 1024
22
26
 
@@ -25,6 +29,11 @@ const STATIC_ROOTS = {
25
29
  vendor: path.join(HERE, 'vendor'),
26
30
  }
27
31
 
32
+ /** Root-level files the client loader may request (single path segment). */
33
+ const ROOT_FILES = {
34
+ 'client.js': path.join(HERE, 'client.js'),
35
+ }
36
+
28
37
  const CONTENT_TYPES = {
29
38
  '.js': 'text/javascript; charset=utf-8',
30
39
  '.mjs': 'text/javascript; charset=utf-8',
@@ -209,14 +218,22 @@ export function apply(ctx, rawConfig) {
209
218
 
210
219
  async function serveStatic(res, requestPath) {
211
220
  const segments = requestPath.split('/').filter(Boolean)
212
- if (segments.length < 2) return sendError(res, 404, 'NOT_FOUND', 'not found')
213
- const rootName = segments[0]
214
- const rootDir = STATIC_ROOTS[rootName]
215
- if (!rootDir) return sendError(res, 404, 'NOT_FOUND', 'not found')
216
- const relative = segments.slice(1).join('/')
217
- const resolved = path.resolve(rootDir, relative)
218
- if (resolved !== rootDir && !resolved.startsWith(rootDir + path.sep)) {
219
- return sendError(res, 403, 'FORBIDDEN', 'path escapes the plugin directory')
221
+ // The browser half is imported by DSH from /plugins/<id>/client.js, so the
222
+ // root entry has to be served too (it lives next to index.js, not in lib/).
223
+ let resolved
224
+ if (segments.length === 1) {
225
+ const rootFile = ROOT_FILES[segments[0]]
226
+ if (!rootFile) return sendError(res, 404, 'NOT_FOUND', 'not found')
227
+ resolved = rootFile
228
+ } else {
229
+ const rootName = segments[0]
230
+ const rootDir = STATIC_ROOTS[rootName]
231
+ if (!rootDir) return sendError(res, 404, 'NOT_FOUND', 'not found')
232
+ const relative = segments.slice(1).join('/')
233
+ resolved = path.resolve(rootDir, relative)
234
+ if (resolved !== rootDir && !resolved.startsWith(rootDir + path.sep)) {
235
+ return sendError(res, 403, 'FORBIDDEN', 'path escapes the plugin directory')
236
+ }
220
237
  }
221
238
  const ext = path.extname(resolved).toLowerCase()
222
239
  const type = CONTENT_TYPES[ext]
@@ -532,7 +549,14 @@ export function apply(ctx, rawConfig) {
532
549
  sendError(res, 404, 'NOT_FOUND', 'not found')
533
550
  return
534
551
  }
535
- const sub = pathname.slice(PREFIX.length) || '/'
552
+ const matched = ALL_PREFIXES.filter(function (prefix) {
553
+ return pathname === prefix || pathname.indexOf(prefix + '/') === 0
554
+ })[0]
555
+ if (!matched) {
556
+ sendError(res, 404, 'NOT_FOUND', 'not found')
557
+ return
558
+ }
559
+ const sub = pathname.slice(matched.length) || '/'
536
560
  try {
537
561
  if (sub === '/health' && (method === 'GET' || method === 'HEAD')) return await handleHealth(res)
538
562
  if (sub === '/recognize' && method === 'POST') return await handleRecognize(req, res)
@@ -549,7 +573,14 @@ export function apply(ctx, rawConfig) {
549
573
  return undefined
550
574
  }
551
575
  }
552
- disposers.push(ctx.effect(() => webServer.register({ kind: 'prefix', path: PREFIX, handler }), 'latex-editor: asset, health and recognition routes'))
576
+ for (const prefix of ALL_PREFIXES) {
577
+ disposers.push(
578
+ ctx.effect(
579
+ () => webServer.register({ kind: 'prefix', path: prefix, handler }),
580
+ 'latex-editor: routes ' + prefix,
581
+ ),
582
+ )
583
+ }
553
584
  }
554
585
 
555
586
  /* -------------------------------------------------------------- agent tool */
package/lib/00-core.js CHANGED
@@ -407,7 +407,7 @@
407
407
  favoritesLimit: 10,
408
408
  language: 'auto',
409
409
  themeMode: 'auto',
410
- uiScale: 1.5,
410
+ uiScale: 1.25,
411
411
  wrap: true,
412
412
  livePreview: true,
413
413
  extensions: ['ams', 'color', 'newcommand', 'noundefined', 'cancel', 'bbox', 'physics', 'mhchem', 'unicode', 'textmacros'],
@@ -2135,7 +2135,18 @@
2135
2135
  .lx-ocr-page,.lx-doc-tab{display:flex;flex-direction:column;gap:14px;}
2136
2136
  .lx-ocr-fileinput,.lx-doc-fileinput{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0;}
2137
2137
 
2138
- .lx-ocr-status{display:flex;align-items:center;gap:8px;flex-wrap:wrap;min-height:24px;font-size:12px;color:var(--dsw-alias-label-secondary);}
2138
+ .lx-ocr-status{
2139
+ display:flex;align-items:center;gap:10px;flex-wrap:wrap;
2140
+ padding:10px 14px;border:1px solid var(--dsw-alias-border-l1);border-radius:10px;
2141
+ background:var(--dsw-alias-bg-layer-1);
2142
+ font-size:12px;line-height:1.45;color:var(--dsw-alias-label-secondary);
2143
+ }
2144
+ .lx-ocr-status__dot{width:7px;height:7px;border-radius:50%;background:var(--dsw-alias-border-l2);flex:none;}
2145
+ .lx-ocr-status__dot--ok{background:var(--dsw-alias-state-success-primary);}
2146
+ .lx-ocr-status__dot--err{background:var(--dsw-alias-state-error-primary);}
2147
+ .lx-ocr-status__label{flex:none;font-size:12.5px;font-weight:500;line-height:1.45;color:var(--dsw-alias-label-primary);}
2148
+ .lx-ocr-status .lx-badge{height:auto;padding:3px 9px;font-size:11.5px;line-height:1.35;flex:none;}
2149
+ .lx-ocr-status__refresh{margin-left:auto;flex:none;}
2139
2150
  .lx-ocr-status__dot{width:7px;height:7px;border-radius:50%;background:var(--dsw-alias-border-l2);flex:none;}
2140
2151
  .lx-ocr-status__dot--ok{background:var(--dsw-alias-state-success-primary);}
2141
2152
  .lx-ocr-status__dot--err{background:var(--dsw-alias-state-error-primary);}
@@ -154,17 +154,17 @@
154
154
  type: 'select',
155
155
  zh: '界面缩放',
156
156
  en: 'Interface scale',
157
- hintZh: '整个工作台相对 DSH 界面的缩放,默认 150%',
158
- hintEn: 'Scales the whole workbench relative to the DSH shell; 150% by default',
157
+ hintZh: '整个工作台相对 DSH 界面的缩放,默认 125%',
158
+ hintEn: 'Scales the whole workbench relative to the DSH shell; 125% by default',
159
159
  options: [
160
160
  { value: 1, zh: '100%(与 DSH 一致)', en: '100% (matches DSH)' },
161
- { value: 1.25, zh: '125%', en: '125%' },
162
- { value: 1.5, zh: '150%(默认)', en: '150% (default)' },
161
+ { value: 1.25, zh: '125%(默认)', en: '125% (default)' },
162
+ { value: 1.5, zh: '150%', en: '150%' },
163
163
  { value: 1.5, zh: '150%', en: '150%' },
164
164
  { value: 1.75, zh: '175%', en: '175%' },
165
165
  { value: 2, zh: '200%', en: '200%' },
166
166
  ],
167
- default: 1.5,
167
+ default: 1.25,
168
168
  },
169
169
  {
170
170
  key: 'previewScale',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-latex-formula-editor",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "type": "module",
5
5
  "description": "LaTeX formula editor for the DSH sidebar: offline MathJax rendering, symbol tiles, templates, favourites, OCR and multi-format export",
6
6
  "license": "MIT",
@@ -16,8 +16,8 @@
16
16
  "lib/",
17
17
  "vendor/",
18
18
  "icon.svg",
19
+ "cordis.patch.yml",
19
20
  "README.md",
20
- "README.zh.md",
21
21
  "README.en.md",
22
22
  "docs/img/"
23
23
  ],
@@ -42,5 +42,8 @@
42
42
  "type": "git",
43
43
  "url": "git+https://github.com/jiahui-huang1/dsh-latex-formula-editor.git"
44
44
  },
45
- "homepage": "https://github.com/jiahui-huang1/dsh-latex-formula-editor#readme"
45
+ "homepage": "https://github.com/jiahui-huang1/dsh-latex-formula-editor#readme",
46
+ "bugs": {
47
+ "url": "https://github.com/jiahui-huang1/dsh-latex-formula-editor/issues"
48
+ }
46
49
  }
package/README.zh.md DELETED
@@ -1,41 +0,0 @@
1
- # dsh-latex-formula-editor
2
-
3
- > LaTeX 公式编辑器 —— DSH 侧栏插件:离线渲染、磁贴取符号、公式模板、收藏夹、图片/文档识别、多格式导出与分享。
4
-
5
- ![插件界面](docs/img/editor.png)
6
-
7
- ## 安装
8
-
9
- ```bash
10
- # 1. 取仓库
11
- git clone https://github.com/jiahui-huang1/dsh-latex-formula-editor.git
12
- # 2. 以本地插件方式安装(DSH 会自动读取 package.json 里的 dsh.bundle.patch / dsh.client)
13
- pnpm dsh plugin add ./dsh-latex-formula-editor
14
- ```
15
-
16
- 安装后在 DSH 左侧栏启用 **公式编辑器**(入口 id `latex-editor`)。
17
-
18
- ## 功能
19
-
20
- - **快捷工具**:常用符号 / 希腊字母 / 分数微分 / 根式角标 / 极限对数 / 三角函数 / 积分运算 / 大型运算 / 括号取整 / 数组矩阵,悬停磁贴展开分组符号面板,点击插入光标处
21
- - **公式模板**:代数 / 几何 / 不等式 / 积分 / 矩阵 / 三角 / 统计 / 数列 / 物理 / 化学,展开即可整条插入
22
- - **格式行**:取色器、真实字体预览、真实字号预览、环境包裹(align / aligned / gathered / cases / split / array / eqnarray / 无环境)、清空、撤销、导入、收藏
23
- - **输出**:输出图片(SVG / PNG / JPG)、输出代码(LaTeX / AsciiMath / Typst / SVG Code / HTML 内联与独立 / MathML / MathML mml: / m: / attr: / OMML)、转义(反斜杠、`$…$`、`$$…$$`、`\(…\)`、`\[…\]`、JSON)、分享链接
24
- - **收藏夹**:标题、时间、渲染结果、源码;可改名 / 复制 / 删除 / 插入;按标题或源码搜索;上限可配(默认 10)
25
- - **识别**:图片识别(拖拽 / 粘贴)、文档识别(逐页 OCR,支持下载 Word / LaTeX / Markdown,最近 15 天记录可重新下载)
26
- - **界面**:默认 150% 缩放、浅色/深色主题、简体中文 / 繁體中文 / English
27
-
28
- ![文档识别](docs/img/doc-ocr.png)
29
-
30
- ## 配置
31
-
32
- 设置 → 识别服务:可选 Harness 内置模型或自建 OpenAI 兼容端点;渲染与导出完全离线,仅识别会发送图片。
33
-
34
- ## 兼容性
35
-
36
- - DSH ≥ 1.0(Cordis 插件规范:`dsh.bundle.patch` + `dsh.client`)
37
- - 浏览器侧无构建步骤,MathJax 3 与 PDF.js 已随插件内置
38
-
39
- ## 许可
40
-
41
- MIT
Binary file
Binary file