From 1026ea688bb814f7390956d2908953c2aa0b38f9 Mon Sep 17 00:00:00 2001 From: Da Shen Date: Fri, 11 Sep 2026 17:07:02 +0800 Subject: [PATCH 1/3] =?UTF-8?q?[1297]=20=E5=88=9B=E5=BB=BA=E4=BB=BB?= =?UTF-8?q?=E5=8A=A1=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- devel/1297.md | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 devel/1297.md diff --git a/devel/1297.md b/devel/1297.md new file mode 100644 index 0000000000..b8212efd63 --- /dev/null +++ b/devel/1297.md @@ -0,0 +1,56 @@ +# [1297] 仅对文档缓冲区生成 stem-doc-id + +## 1 相关文档 +- [dddd.md](dddd.md) - 任务文档模板 +- [1104.md](1104.md) - 修复新建文档未写入 stem-doc-id 的问题 +- [1131.md](1131.md) - 添加 stem 格式并全量迁移 plugins 下 .ts → .stem +- [1293.md](1293.md) - 草稿文件后缀放开为 .tmu 与 .stem 并导出样式包为 .stem 草稿 +- [200_33.md](200_33.md) - stem-doc-id 自动备份标识机制说明 + +## 2 任务相关的代码文件 +- `TeXmacs/progs/texmacs/texmacs/tm-files.scm` — 定义 `style-buffer?` 与 `document-buffer?` 谓词;在保存文件时对样式 buffer 清除 `stem-doc-id`,对文档 buffer 确保 `stem-doc-id` +- `TeXmacs/plugins/autosave/progs/autosave/plugin.scm` — `auto-backup-buffer-eligible?` 排除样式 buffer;新增 `auto-backup-clear-buffer-doc-id!`;`auto-backup-buffer-doc-id` 对样式 buffer 返回 `#f` +- `TeXmacs/progs/texmacs/texmacs/tm-files-test.scm` — 单元测试:验证样式 buffer 与文档 buffer 判定,以及 `stem-doc-id` 生成与清除 +- `TeXmacs/packages/customize/document/three-columns.ts` — 移除历史遗留误写入的 `stem-doc-id` + +## 3 如何测试 + +### 3.1 单元测试 +```bash +xmake b stem +xmake b tm-files-test && xmake r tm-files-test +``` +预期: +1. `.ts` 文件被判定为样式 buffer(`style-buffer?` 为 `#t`,`document-buffer?` 为 `#f`),不具备自动备份与 `stem-doc-id` 绑定资格; +2. 实际为样式的 `.stem` 文件(包含 `source` 样式或样式声明标记)被判定为样式 buffer,不填入 `stem-doc-id`; +3. 作为普通文档的 `.stem` 文件(非 `source` 样式)被判定为文档 buffer(`document-buffer?` 为 `#t`),正常绑定 `stem-doc-id`; +4. 普通 `.tmu`/`.tm` 文档正常保持绑定 `stem-doc-id` 的行为; +5. 单元测试全部通过。 + +### 3.2 手动测试 +1. 打开一个 `.ts` 样式文件或 `.stem` 样式包(如 `std.stem`),修改后保存: + - 检查保存后的文件内容,确认没有写入 `` 或 `(associate "stem-doc-id" ...)`. +2. 新建或打开一个 `.stem` 文档(如 `test.stem`,样式为 `generic` 或 `article`),修改后保存: + - 检查保存后的文件内容,确认包含 `stem-doc-id`. +3. 新建或打开普通 `.tmu` 文档并保存: + - 确认正常包含 `stem-doc-id`. + +## 4 为什么(Why) +1. `stem-doc-id` 是用于文档追踪和自动备份的稳定唯一标识,仅应存在于文档缓冲区。 +2. `.ts` 文件是 TeXmacs 样式文件,不属于文档;而 `.stem` 扩展名既可用于样式文件(作为 `.ts` 的 S-expression 继任格式),也可用于保存普通文档。 +3. 此前 `auto-backup-buffer-eligible?` 仅依据格式 `in? '("texmacs" "stm" "tmu" "stem")` 进行判断,导致 `.ts` 以及实际上是样式的 `.stem` 在保存或触发自动备份时被误填入 `stem-doc-id`(例如 `three-columns.ts` 中就遗留了误写入的 doc id)。 +4. 不能单纯依靠文件后缀区分样式与文档,需要根据缓冲区实际内容与样式属性(如是否具备 `source` 样式、是否包含宏包标记、是否关联样式包导出目标等)准确判定。 + +## 5 怎么做(How) +1. 在 `tm-files.scm` 中实现 `style-buffer?` 与 `document-buffer?`: + - 识别 `.ts` 后缀; + - 识别通过「导出样式包」创建的关联草稿; + - 检查缓冲区是否具备 `source` 样式包(通过 `get-style-list`、`has-style-package?` 或 buffer tree 的 `style` 元数据); + - 检查缓冲区文档树首部是否包含 `src-title` / `src-package` / `src-style-file` 等样式文件特征标记。 +2. 在 `plugin.scm` 中: + - 将 `auto-backup-buffer-eligible?` 调整为要求 `(not (style-buffer? name))`; + - 实现 `auto-backup-clear-buffer-doc-id!`,在样式缓冲区保存时调用 `(init-default "stem-doc-id")` 重置环境中的 doc id; + - `auto-backup-buffer-doc-id` 对样式缓冲区直接返回 `#f`。 +3. 在 `tm-files.scm` 的 `save-buffer-save-file` 中,针对 `style-buffer?` 调用 `auto-backup-clear-buffer-doc-id!` 清理,非样式缓冲区则继续执行 `auto-backup-ensure-buffer-doc-id!`。 +4. 清理 `three-columns.ts` 中残留的 `stem-doc-id`。 +5. 在 `tm-files-test.scm` 中增加针对样式判定与 doc id 行为的单元测试。 From b0548161771af37449f0b2baa8a1b1f45034d2db Mon Sep 17 00:00:00 2001 From: Da Shen Date: Fri, 11 Sep 2026 17:15:12 +0800 Subject: [PATCH 2/3] =?UTF-8?q?[1297]=20=E4=BB=85=E5=AF=B9=E6=96=87?= =?UTF-8?q?=E6=A1=A3=E7=BC=93=E5=86=B2=E5=8C=BA=E7=94=9F=E6=88=90=20stem-d?= =?UTF-8?q?oc-id?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../customize/document/three-columns.ts | 1 - .../autosave/progs/autosave/plugin.scm | 43 +++++--- .../progs/texmacs/texmacs/tm-files-test.scm | 103 +++++++++++++++++- TeXmacs/progs/texmacs/texmacs/tm-files.scm | 73 ++++++++++++- 4 files changed, 200 insertions(+), 20 deletions(-) diff --git a/TeXmacs/packages/customize/document/three-columns.ts b/TeXmacs/packages/customize/document/three-columns.ts index ab371feb1b..0773dc2744 100644 --- a/TeXmacs/packages/customize/document/three-columns.ts +++ b/TeXmacs/packages/customize/document/three-columns.ts @@ -54,6 +54,5 @@ <\initial> <\collection> - \ No newline at end of file diff --git a/TeXmacs/plugins/autosave/progs/autosave/plugin.scm b/TeXmacs/plugins/autosave/progs/autosave/plugin.scm index c792fdd3c6..48b1577e70 100644 --- a/TeXmacs/plugins/autosave/progs/autosave/plugin.scm +++ b/TeXmacs/plugins/autosave/progs/autosave/plugin.scm @@ -96,6 +96,7 @@ (not (url-rooted-tmfs? name)) (not (auto-backup-texmacs-path-buffer? name)) (in? (url-format name) '("texmacs" "stm" "tmu" "stem")) + (not (and (defined? 'style-buffer?) (style-buffer? name))) ) ;and ) ;tm-define @@ -106,20 +107,22 @@ (tm-define (auto-backup-buffer-doc-id name) (catch #t (lambda () - ;; First try to get from init-env (memory), then from document tree (file) - (with-buffer name - (let* ((from-env (get-init-env "stem-doc-id")) - (doc-id (if (and (string? from-env) (!= from-env "")) - from-env - (let* ((doc (buffer-get name)) (initial (tmfile-extract doc 'initial))) - (and initial (collection-ref initial "stem-doc-id")) - ) ;let* - ) ;if - ) ;doc-id - ) ; - doc-id - ) ;let* - ) ;with-buffer + (and (not (and (defined? 'style-buffer?) (style-buffer? name))) + ;; First try to get from init-env (memory), then from document tree (file) + (with-buffer name + (let* ((from-env (get-init-env "stem-doc-id")) + (doc-id (if (and (string? from-env) (!= from-env "")) + from-env + (let* ((doc (buffer-get name)) (initial (tmfile-extract doc 'initial))) + (and initial (collection-ref initial "stem-doc-id")) + ) ;let* + ) ;if + ) ;doc-id + ) ; + doc-id + ) ;let* + ) ;with-buffer + ) ;and ) ;lambda (lambda args #f) ) ;catch @@ -180,6 +183,13 @@ ) ;catch ) ;tm-define +(tm-define (auto-backup-clear-buffer-doc-id! name) + (catch #t + (lambda () (with-buffer name (init-default "stem-doc-id"))) + (lambda args #f) + ) ;catch +) ;tm-define + (tm-define (auto-backup-trig-payload name kind) (let* ((collab? (collab-buffer? name)) ;; 协作文档:path 指向本地不可见备份文件(collab-silent-backup 已在 save-buffer-save @@ -338,7 +348,10 @@ (tm-define (save-all-buffers) (for-each (lambda (buf) (when (buffer-modified? buf) - (auto-backup-ensure-buffer-doc-id! buf) + (if (and (defined? 'style-buffer?) (style-buffer? buf)) + (auto-backup-clear-buffer-doc-id! buf) + (auto-backup-ensure-buffer-doc-id! buf) + ) ;if (buffer-save buf) ) ;when ) ;lambda diff --git a/TeXmacs/progs/texmacs/texmacs/tm-files-test.scm b/TeXmacs/progs/texmacs/texmacs/tm-files-test.scm index 1603e0a553..b66973f02c 100644 --- a/TeXmacs/progs/texmacs/texmacs/tm-files-test.scm +++ b/TeXmacs/progs/texmacs/texmacs/tm-files-test.scm @@ -12,7 +12,7 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (texmacs-module (texmacs texmacs tm-files-test) - (:use (texmacs texmacs tm-files) (autosave plugin)) + (:use (texmacs texmacs tm-files) (autosave plugin) (utils library cursor)) ) ;texmacs-module (import (liii check)) @@ -139,6 +139,106 @@ ) ;let* ) ;define +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Tests for style-buffer? and stem-doc-id eligibility +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(define (test-style-buffer-and-doc-id) + ;; 1. .ts 后缀 buffer 属于样式 buffer,不生成 stem-doc-id + (let* ((orig (current-buffer)) + (buf (new-buffer ".tmu")) + (ts-url (system->url "/tmp/test_custom_style.ts")) + ) ; + (buffer-rename buf ts-url) + (check (style-buffer? ts-url) => #t) + (check (document-buffer? ts-url) => #f) + (check (auto-backup-buffer-eligible? ts-url) => #f) + (check (auto-backup-ensure-buffer-doc-id! ts-url) => #f) + (buffer-close ts-url) + (switch-to-buffer orig) + ) ;let* + + ;; 2. 实际为样式的 .stem buffer(style 为 source)不生成 stem-doc-id + (let* ((orig (current-buffer)) + (stem-style-buf (new-buffer ".stem")) + (style-doc '(document (TeXmacs "2.1.4") + (style (tuple "source")) + (body (document (active* (src-title (document (src-package "my-pkg" + "1.0"))))))) + ) ;style-doc + ) ; + (buffer-set stem-style-buf style-doc) + (check (style-buffer? stem-style-buf) => #t) + (check (document-buffer? stem-style-buf) => #f) + (check (auto-backup-buffer-eligible? stem-style-buf) => #f) + (check (auto-backup-ensure-buffer-doc-id! stem-style-buf) => #f) + ;; 验证若环境中已存在 doc-id,clear 会将其清除 + (with-buffer stem-style-buf (init-env "stem-doc-id" "test-uuid")) + (auto-backup-clear-buffer-doc-id! stem-style-buf) + (with-buffer stem-style-buf (check (get-init-env "stem-doc-id") => #f)) + (check (auto-backup-buffer-doc-id stem-style-buf) => #f) + (buffer-close stem-style-buf) + (switch-to-buffer orig) + ) ;let* + + ;; 3. 普通文档 .stem buffer(style 为 generic)属于文档 buffer,生成 stem-doc-id + (let* ((orig (current-buffer)) + (stem-doc-buf (new-buffer ".stem")) + (doc '(document (TeXmacs "2.1.4") + (style (tuple "generic")) + (body (document "Hello STEM document"))) + ) ;doc + ) ; + (buffer-set stem-doc-buf doc) + (check (style-buffer? stem-doc-buf) => #f) + (check (document-buffer? stem-doc-buf) => #t) + (check (auto-backup-buffer-eligible? stem-doc-buf) => #t) + (let ((doc-id (auto-backup-ensure-buffer-doc-id! stem-doc-buf))) + (check (string? doc-id) => #t) + (check (!= doc-id "") => #t) + (check (auto-backup-buffer-doc-id stem-doc-buf) => doc-id) + ) ;let + (buffer-close stem-doc-buf) + (switch-to-buffer orig) + ) ;let* + + ;; 4. 普通文档 .tmu 属于文档 buffer,生成 stem-doc-id + (let* ((orig (current-buffer)) + (tmu-buf (new-buffer ".tmu")) + (doc '(document (TeXmacs "2.1.4") + (style (tuple "generic")) + (body (document "Hello TMU document"))) + ) ;doc + ) ; + (buffer-set tmu-buf doc) + (check (style-buffer? tmu-buf) => #f) + (check (document-buffer? tmu-buf) => #t) + (check (auto-backup-buffer-eligible? tmu-buf) => #t) + (let ((doc-id (auto-backup-ensure-buffer-doc-id! tmu-buf))) + (check (string? doc-id) => #t) + (check (!= doc-id "") => #t) + (check (auto-backup-buffer-doc-id tmu-buf) => doc-id) + ) ;let + (buffer-close tmu-buf) + (switch-to-buffer orig) + ) ;let* + + ;; 5. 导出样式包生成的草稿 buffer 属于样式 buffer,不生成 stem-doc-id + (let ((orig-buf (current-buffer))) + (when (defined? 'extract-style-package) + (extract-style-package) + (let ((style-draft (current-buffer))) + (check (style-buffer? style-draft) => #t) + (check (document-buffer? style-draft) => #f) + (check (auto-backup-buffer-eligible? style-draft) => #f) + (check (auto-backup-ensure-buffer-doc-id! style-draft) => #f) + (buffer-close style-draft) + (switch-to-buffer orig-buf) + ) ;let + ) ;when + ) ;let +) ;define + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Test entry point ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -151,5 +251,6 @@ (test-scratch-buffer-title-stem) (test-scratch-buffer-title-old-and-new-stamp) (test-scratch-buffer-title-legacy-one-underscore-this-week) + (test-style-buffer-and-doc-id) (check-report) ) ;tm-define diff --git a/TeXmacs/progs/texmacs/texmacs/tm-files.scm b/TeXmacs/progs/texmacs/texmacs/tm-files.scm index 03ee4aa5bc..bf6056af6b 100644 --- a/TeXmacs/progs/texmacs/texmacs/tm-files.scm +++ b/TeXmacs/progs/texmacs/texmacs/tm-files.scm @@ -215,6 +215,68 @@ ) ;with ) ;tm-define +(define (body-has-source-markup? doc) + (let ((body (and doc (tmfile-extract doc 'body)))) + (and (pair? body) + (== (car body) 'document) + (pair? (cdr body)) + (let ((first (cadr body))) + (or (and (pair? first) (in? (car first) '(src-title src-package + src-style-file))) + (and (pair? first) + (== (car first) 'active*) + (pair? (cdr first)) + (let ((inner (cadr first))) + (or (and (pair? inner) (in? (car inner) '(src-title src-package + src-style-file))) + (and (pair? inner) + (== (car inner) 'document) + (pair? (cdr inner)) + (let ((sub (cadr inner))) + (and (pair? sub) (in? (car sub) '(src-title src-package + src-style-file))) + ) ;let + ) ;and + ) ;or + ) ;let + ) ;and + ) ;or + ) ;let + ) ;and + ) ;let +) ;define + +(tm-define (style-buffer? name) + (catch #t + (lambda () + (and (url? name) + (buffer-exists? name) + (or (== (url-suffix name) "ts") + (and (defined? 'style-package-target-url) + (url? (style-package-target-url name)) + ) ;and + (with-buffer name + (or (and (defined? 'has-style-package?) (has-style-package? "source")) + (and (defined? 'in-source?) (in-source?)) + ) ;or + ) ;with-buffer + (let* ((doc (buffer-get name)) (st (and doc (tmfile-extract doc 'style)))) + (or (equal? st "source") + (and (pair? st) (== (car st) 'tuple) (in? "source" (cdr st))) + (body-has-source-markup? doc) + ) ;or + ) ;let* + ) ;or + ) ;and + ) ;lambda + (lambda args #f) + ) ;catch +) ;tm-define + +(tm-define (document-buffer? name) + (and (url? name) (buffer-exists? name) (not (style-buffer? name))) +) ;tm-define + (tm-define (buffer-set-default-style) (init-style "generic") (with lan @@ -428,9 +490,14 @@ ;; (display* "save-buffer-save " name "\n") (with vname `(verbatim ,(utf8->cork (url->system name))) - (when (defined? 'auto-backup-ensure-buffer-doc-id!) - (auto-backup-ensure-buffer-doc-id! name) - ) ;when + (if (style-buffer? name) + (when (defined? 'auto-backup-clear-buffer-doc-id!) + (auto-backup-clear-buffer-doc-id! name) + ) ;when + (when (defined? 'auto-backup-ensure-buffer-doc-id!) + (auto-backup-ensure-buffer-doc-id! name) + ) ;when + ) ;if (if (buffer-save name) (begin (buffer-pretend-modified name) From 644e7f09581a3bb46ebcf963ee196990de9ec7e2 Mon Sep 17 00:00:00 2001 From: Da Shen Date: Fri, 11 Sep 2026 17:38:44 +0800 Subject: [PATCH 3/3] =?UTF-8?q?[1297]=20=E7=AE=80=E5=8C=96=E6=A0=B7?= =?UTF-8?q?=E5=BC=8F=20buffer=20=E5=88=A4=E5=AE=9A=E5=B9=B6=E6=94=B6?= =?UTF-8?q?=E5=8F=A3=20doc-id=20=E5=90=8C=E6=AD=A5=E7=AD=96=E7=95=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude --- .../autosave/progs/autosave/plugin.scm | 23 ++++-- TeXmacs/plugins/bash/doc/bash.en.tmu | 1 - .../progs/texmacs/texmacs/tm-files-test.scm | 71 +++++++------------ TeXmacs/progs/texmacs/texmacs/tm-files.scm | 66 ++++++----------- devel/1297.md | 23 +++--- 5 files changed, 76 insertions(+), 108 deletions(-) diff --git a/TeXmacs/plugins/autosave/progs/autosave/plugin.scm b/TeXmacs/plugins/autosave/progs/autosave/plugin.scm index 48b1577e70..cc0cb5e2f0 100644 --- a/TeXmacs/plugins/autosave/progs/autosave/plugin.scm +++ b/TeXmacs/plugins/autosave/progs/autosave/plugin.scm @@ -11,7 +11,10 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (texmacs-module (autosave plugin) - (:use (utils library cursor) (texmacs texmacs tm-collab)) + (:use (utils library cursor) + (texmacs texmacs tm-collab) + (texmacs texmacs tm-files) + ) ;:use ) ;texmacs-module (import (liii uuid)) @@ -96,7 +99,7 @@ (not (url-rooted-tmfs? name)) (not (auto-backup-texmacs-path-buffer? name)) (in? (url-format name) '("texmacs" "stm" "tmu" "stem")) - (not (and (defined? 'style-buffer?) (style-buffer? name))) + (not (style-buffer? name)) ) ;and ) ;tm-define @@ -107,7 +110,7 @@ (tm-define (auto-backup-buffer-doc-id name) (catch #t (lambda () - (and (not (and (defined? 'style-buffer?) (style-buffer? name))) + (and (not (style-buffer? name)) ;; First try to get from init-env (memory), then from document tree (file) (with-buffer name (let* ((from-env (get-init-env "stem-doc-id")) @@ -190,6 +193,15 @@ ) ;catch ) ;tm-define +;; 「样式 buffer 清除、文档 buffer 补齐」的 doc id 策略统一收口在这里, +;; 各保存路径只需无条件调用本函数。 +(tm-define (auto-backup-sync-buffer-doc-id! name) + (if (style-buffer? name) + (auto-backup-clear-buffer-doc-id! name) + (auto-backup-ensure-buffer-doc-id! name) + ) ;if +) ;tm-define + (tm-define (auto-backup-trig-payload name kind) (let* ((collab? (collab-buffer? name)) ;; 协作文档:path 指向本地不可见备份文件(collab-silent-backup 已在 save-buffer-save @@ -348,10 +360,7 @@ (tm-define (save-all-buffers) (for-each (lambda (buf) (when (buffer-modified? buf) - (if (and (defined? 'style-buffer?) (style-buffer? buf)) - (auto-backup-clear-buffer-doc-id! buf) - (auto-backup-ensure-buffer-doc-id! buf) - ) ;if + (auto-backup-sync-buffer-doc-id! buf) (buffer-save buf) ) ;when ) ;lambda diff --git a/TeXmacs/plugins/bash/doc/bash.en.tmu b/TeXmacs/plugins/bash/doc/bash.en.tmu index 9a86dfd412..7ba9ac7a70 100644 --- a/TeXmacs/plugins/bash/doc/bash.en.tmu +++ b/TeXmacs/plugins/bash/doc/bash.en.tmu @@ -71,6 +71,5 @@ - diff --git a/TeXmacs/progs/texmacs/texmacs/tm-files-test.scm b/TeXmacs/progs/texmacs/texmacs/tm-files-test.scm index b66973f02c..b56ca589cd 100644 --- a/TeXmacs/progs/texmacs/texmacs/tm-files-test.scm +++ b/TeXmacs/progs/texmacs/texmacs/tm-files-test.scm @@ -151,7 +151,6 @@ ) ; (buffer-rename buf ts-url) (check (style-buffer? ts-url) => #t) - (check (document-buffer? ts-url) => #f) (check (auto-backup-buffer-eligible? ts-url) => #f) (check (auto-backup-ensure-buffer-doc-id! ts-url) => #f) (buffer-close ts-url) @@ -169,7 +168,6 @@ ) ; (buffer-set stem-style-buf style-doc) (check (style-buffer? stem-style-buf) => #t) - (check (document-buffer? stem-style-buf) => #f) (check (auto-backup-buffer-eligible? stem-style-buf) => #f) (check (auto-backup-ensure-buffer-doc-id! stem-style-buf) => #f) ;; 验证若环境中已存在 doc-id,clear 会将其清除 @@ -181,55 +179,36 @@ (switch-to-buffer orig) ) ;let* - ;; 3. 普通文档 .stem buffer(style 为 generic)属于文档 buffer,生成 stem-doc-id - (let* ((orig (current-buffer)) - (stem-doc-buf (new-buffer ".stem")) - (doc '(document (TeXmacs "2.1.4") - (style (tuple "generic")) - (body (document "Hello STEM document"))) - ) ;doc - ) ; - (buffer-set stem-doc-buf doc) - (check (style-buffer? stem-doc-buf) => #f) - (check (document-buffer? stem-doc-buf) => #t) - (check (auto-backup-buffer-eligible? stem-doc-buf) => #t) - (let ((doc-id (auto-backup-ensure-buffer-doc-id! stem-doc-buf))) - (check (string? doc-id) => #t) - (check (!= doc-id "") => #t) - (check (auto-backup-buffer-doc-id stem-doc-buf) => doc-id) - ) ;let - (buffer-close stem-doc-buf) - (switch-to-buffer orig) - ) ;let* - - ;; 4. 普通文档 .tmu 属于文档 buffer,生成 stem-doc-id - (let* ((orig (current-buffer)) - (tmu-buf (new-buffer ".tmu")) - (doc '(document (TeXmacs "2.1.4") - (style (tuple "generic")) - (body (document "Hello TMU document"))) - ) ;doc - ) ; - (buffer-set tmu-buf doc) - (check (style-buffer? tmu-buf) => #f) - (check (document-buffer? tmu-buf) => #t) - (check (auto-backup-buffer-eligible? tmu-buf) => #t) - (let ((doc-id (auto-backup-ensure-buffer-doc-id! tmu-buf))) - (check (string? doc-id) => #t) - (check (!= doc-id "") => #t) - (check (auto-backup-buffer-doc-id tmu-buf) => doc-id) - ) ;let - (buffer-close tmu-buf) - (switch-to-buffer orig) - ) ;let* - - ;; 5. 导出样式包生成的草稿 buffer 属于样式 buffer,不生成 stem-doc-id + ;; 3. 普通文档 buffer(.stem / .tmu,style 为 generic)生成 stem-doc-id + (for-each (lambda (suffix) + (let* ((orig (current-buffer)) + (buf (new-buffer suffix)) + (doc '(document (TeXmacs "2.1.4") + (style (tuple "generic")) + (body (document "Hello document"))) + ) ;doc + ) ; + (buffer-set buf doc) + (check (style-buffer? buf) => #f) + (check (auto-backup-buffer-eligible? buf) => #t) + (let ((doc-id (auto-backup-ensure-buffer-doc-id! buf))) + (check (string? doc-id) => #t) + (check (!= doc-id "") => #t) + (check (auto-backup-buffer-doc-id buf) => doc-id) + ) ;let + (buffer-close buf) + (switch-to-buffer orig) + ) ;let* + ) ;lambda + '(".stem" ".tmu") + ) ;for-each + + ;; 4. 导出样式包生成的草稿 buffer 属于样式 buffer,不生成 stem-doc-id (let ((orig-buf (current-buffer))) (when (defined? 'extract-style-package) (extract-style-package) (let ((style-draft (current-buffer))) (check (style-buffer? style-draft) => #t) - (check (document-buffer? style-draft) => #f) (check (auto-backup-buffer-eligible? style-draft) => #f) (check (auto-backup-ensure-buffer-doc-id! style-draft) => #f) (buffer-close style-draft) diff --git a/TeXmacs/progs/texmacs/texmacs/tm-files.scm b/TeXmacs/progs/texmacs/texmacs/tm-files.scm index bf6056af6b..eefa5344ed 100644 --- a/TeXmacs/progs/texmacs/texmacs/tm-files.scm +++ b/TeXmacs/progs/texmacs/texmacs/tm-files.scm @@ -215,33 +215,31 @@ ) ;with ) ;tm-define +(define (source-markup-tag? t) + (and (pair? t) (in? (car t) '(src-title src-package src-style-file))) +) ;define + (define (body-has-source-markup? doc) (let ((body (and doc (tmfile-extract doc 'body)))) (and (pair? body) (== (car body) 'document) (pair? (cdr body)) - (let ((first (cadr body))) - (or (and (pair? first) (in? (car first) '(src-title src-package - src-style-file))) - (and (pair? first) - (== (car first) 'active*) - (pair? (cdr first)) - (let ((inner (cadr first))) - (or (and (pair? inner) (in? (car inner) '(src-title src-package - src-style-file))) - (and (pair? inner) - (== (car inner) 'document) - (pair? (cdr inner)) - (let ((sub (cadr inner))) - (and (pair? sub) (in? (car sub) '(src-title src-package - src-style-file))) - ) ;let - ) ;and - ) ;or - ) ;let + ;; 导出样式包的草稿把 src-* 标记包在 active* 里,其内还可能再套一层 document + (let* ((first (cadr body)) + (inner (if (and (pair? first) (== (car first) 'active*) (pair? (cdr first))) + (cadr first) + first + ) ;if + ) ;inner + ) ; + (or (source-markup-tag? inner) + (and (pair? inner) + (== (car inner) 'document) + (pair? (cdr inner)) + (source-markup-tag? (cadr inner)) ) ;and ) ;or - ) ;let + ) ;let* ) ;and ) ;let ) ;define @@ -255,17 +253,8 @@ (and (defined? 'style-package-target-url) (url? (style-package-target-url name)) ) ;and - (with-buffer name - (or (and (defined? 'has-style-package?) (has-style-package? "source")) - (and (defined? 'in-source?) (in-source?)) - ) ;or - ) ;with-buffer - (let* ((doc (buffer-get name)) (st (and doc (tmfile-extract doc 'style)))) - (or (equal? st "source") - (and (pair? st) (== (car st) 'tuple) (in? "source" (cdr st))) - (body-has-source-markup? doc) - ) ;or - ) ;let* + (with-buffer name (has-style-package? "source")) + (body-has-source-markup? (buffer-get name)) ) ;or ) ;and ) ;lambda @@ -273,10 +262,6 @@ ) ;catch ) ;tm-define -(tm-define (document-buffer? name) - (and (url? name) (buffer-exists? name) (not (style-buffer? name))) -) ;tm-define - (tm-define (buffer-set-default-style) (init-style "generic") (with lan @@ -490,14 +475,9 @@ ;; (display* "save-buffer-save " name "\n") (with vname `(verbatim ,(utf8->cork (url->system name))) - (if (style-buffer? name) - (when (defined? 'auto-backup-clear-buffer-doc-id!) - (auto-backup-clear-buffer-doc-id! name) - ) ;when - (when (defined? 'auto-backup-ensure-buffer-doc-id!) - (auto-backup-ensure-buffer-doc-id! name) - ) ;when - ) ;if + (when (defined? 'auto-backup-sync-buffer-doc-id!) + (auto-backup-sync-buffer-doc-id! name) + ) ;when (if (buffer-save name) (begin (buffer-pretend-modified name) diff --git a/devel/1297.md b/devel/1297.md index b8212efd63..1b683ee81b 100644 --- a/devel/1297.md +++ b/devel/1297.md @@ -8,10 +8,10 @@ - [200_33.md](200_33.md) - stem-doc-id 自动备份标识机制说明 ## 2 任务相关的代码文件 -- `TeXmacs/progs/texmacs/texmacs/tm-files.scm` — 定义 `style-buffer?` 与 `document-buffer?` 谓词;在保存文件时对样式 buffer 清除 `stem-doc-id`,对文档 buffer 确保 `stem-doc-id` -- `TeXmacs/plugins/autosave/progs/autosave/plugin.scm` — `auto-backup-buffer-eligible?` 排除样式 buffer;新增 `auto-backup-clear-buffer-doc-id!`;`auto-backup-buffer-doc-id` 对样式 buffer 返回 `#f` +- `TeXmacs/progs/texmacs/texmacs/tm-files.scm` — 定义 `style-buffer?` 谓词;保存文件时统一调用 `auto-backup-sync-buffer-doc-id!` +- `TeXmacs/plugins/autosave/progs/autosave/plugin.scm` — `auto-backup-buffer-eligible?` 排除样式 buffer;新增 `auto-backup-clear-buffer-doc-id!` 与 `auto-backup-sync-buffer-doc-id!`(样式 buffer 清除、文档 buffer 补齐的策略收口);`auto-backup-buffer-doc-id` 对样式 buffer 返回 `#f` - `TeXmacs/progs/texmacs/texmacs/tm-files-test.scm` — 单元测试:验证样式 buffer 与文档 buffer 判定,以及 `stem-doc-id` 生成与清除 -- `TeXmacs/packages/customize/document/three-columns.ts` — 移除历史遗留误写入的 `stem-doc-id` +- `TeXmacs/packages/customize/document/three-columns.ts`、`TeXmacs/plugins/bash/doc/bash.en.tmu` — 移除历史遗留误写入的 `stem-doc-id` ## 3 如何测试 @@ -21,9 +21,9 @@ xmake b stem xmake b tm-files-test && xmake r tm-files-test ``` 预期: -1. `.ts` 文件被判定为样式 buffer(`style-buffer?` 为 `#t`,`document-buffer?` 为 `#f`),不具备自动备份与 `stem-doc-id` 绑定资格; +1. `.ts` 文件被判定为样式 buffer(`style-buffer?` 为 `#t`),不具备自动备份与 `stem-doc-id` 绑定资格; 2. 实际为样式的 `.stem` 文件(包含 `source` 样式或样式声明标记)被判定为样式 buffer,不填入 `stem-doc-id`; -3. 作为普通文档的 `.stem` 文件(非 `source` 样式)被判定为文档 buffer(`document-buffer?` 为 `#t`),正常绑定 `stem-doc-id`; +3. 作为普通文档的 `.stem` 文件(非 `source` 样式)被判定为文档 buffer,正常绑定 `stem-doc-id`; 4. 普通 `.tmu`/`.tm` 文档正常保持绑定 `stem-doc-id` 的行为; 5. 单元测试全部通过。 @@ -42,15 +42,16 @@ xmake b tm-files-test && xmake r tm-files-test 4. 不能单纯依靠文件后缀区分样式与文档,需要根据缓冲区实际内容与样式属性(如是否具备 `source` 样式、是否包含宏包标记、是否关联样式包导出目标等)准确判定。 ## 5 怎么做(How) -1. 在 `tm-files.scm` 中实现 `style-buffer?` 与 `document-buffer?`: +1. 在 `tm-files.scm` 中实现 `style-buffer?`: - 识别 `.ts` 后缀; - - 识别通过「导出样式包」创建的关联草稿; - - 检查缓冲区是否具备 `source` 样式包(通过 `get-style-list`、`has-style-package?` 或 buffer tree 的 `style` 元数据); - - 检查缓冲区文档树首部是否包含 `src-title` / `src-package` / `src-style-file` 等样式文件特征标记。 + - 识别通过「导出样式包」创建的关联草稿(`style-package-target-url`); + - 检查缓冲区是否具备 `source` 样式包(`has-style-package?`,读取 buffer 的样式环境); + - 检查缓冲区文档树首部是否包含 `src-title` / `src-package` / `src-style-file` 等样式文件特征标记(`body-has-source-markup?`)。 2. 在 `plugin.scm` 中: - 将 `auto-backup-buffer-eligible?` 调整为要求 `(not (style-buffer? name))`; - 实现 `auto-backup-clear-buffer-doc-id!`,在样式缓冲区保存时调用 `(init-default "stem-doc-id")` 重置环境中的 doc id; + - 新增 `auto-backup-sync-buffer-doc-id!`,把「样式 buffer 清除、文档 buffer 补齐」的策略收口到一处,各保存路径无条件调用; - `auto-backup-buffer-doc-id` 对样式缓冲区直接返回 `#f`。 -3. 在 `tm-files.scm` 的 `save-buffer-save-file` 中,针对 `style-buffer?` 调用 `auto-backup-clear-buffer-doc-id!` 清理,非样式缓冲区则继续执行 `auto-backup-ensure-buffer-doc-id!`。 -4. 清理 `three-columns.ts` 中残留的 `stem-doc-id`。 +3. `tm-files.scm` 的 `save-buffer-save-file` 与 `plugin.scm` 的 `save-all-buffers` 均通过 `auto-backup-sync-buffer-doc-id!` 同步 doc id。 +4. 清理 `three-columns.ts` 与 `bash.en.tmu` 中残留的 `stem-doc-id`。 5. 在 `tm-files-test.scm` 中增加针对样式判定与 doc id 行为的单元测试。