diff --git a/TeXmacs/packages/standard/std-utils.ts b/TeXmacs/packages/standard/std-utils.ts index f1a7ab95b0..d0cffeb6dc 100644 --- a/TeXmacs/packages/standard/std-utils.ts +++ b/TeXmacs/packages/standard/std-utils.ts @@ -276,7 +276,7 @@ >>>>>> - + <\wide-normal> <\decorated-body> diff --git a/TeXmacs/plugins/html/progs/convert/html/tmhtml.scm b/TeXmacs/plugins/html/progs/convert/html/tmhtml.scm index 5b771aada8..a705cccaee 100644 --- a/TeXmacs/plugins/html/progs/convert/html/tmhtml.scm +++ b/TeXmacs/plugins/html/progs/convert/html/tmhtml.scm @@ -2018,48 +2018,45 @@ (with embedded (tmhtml-extract-embedded (car l)) (let* ((data (car embedded)) (ext (cdr embedded))) - (if tmhtml-base64? - (if (in? ext (list "ps" "eps" "pdf" "tif")) - ;; Convert to PNG first, then inline as Base64 - (receive (name-url name-string) - (tmhtml-image-names ext) - (let* ((abs-url (url-concretize name-url)) - (abs-string (url->unix abs-url))) - (tmhtml-write-binary-file abs-url data) - (let ((res (tmhtml-png (cons 'image (cons abs-string (cdr l)))))) - (when (url-exists? abs-url) - (url-remove abs-url)) - res - ) ;let - ) ;let* - ) ;receive - ;; Direct Base64 inline for native image formats - (let* ((b64-str (begin - (import (liii base64)) - (utf8->string (bytevector-base64-encode data)) - ) ;begin - ) ;b64-str - (src-uri (string-append "data:image/" ext ";base64," b64-str)) - (w (if (>= (length l) 2) (tmlength->htmllength (second l) #f) #f)) - (h (if (>= (length l) 3) (tmlength->htmllength (third l) #f) #f)) - ) ;let* - `((h:img (@ (class "image") - (src ,src-uri) - ,@(if w `((width ,w)) '()) - ,@(if h `((height ,h)) '())))) - ) ;if - ) ;if - (receive (name-url name-string) - (tmhtml-image-names ext) - (let* ((abs-url (url-concretize name-url)) (abs-string (url->unix abs-url))) - (tmhtml-write-binary-file abs-url data) - (with res - (tmhtml-image (cons abs-string (cdr l))) - res - ) ;with - ) ;let* - ) ;receive - ) ;if + (if tmhtml-base64? + (if (in? ext (list "ps" "eps" "pdf" "tif")) + ;; Convert to PNG first, then inline as Base64 + (receive (name-url name-string) + (tmhtml-image-names ext) + (let* ((abs-url (url-concretize name-url)) (abs-string (url->unix abs-url))) + (tmhtml-write-binary-file abs-url data) + (let ((res (tmhtml-png (cons 'image (cons abs-string (cdr l)))))) + (when (url-exists? abs-url) + (url-remove abs-url) + ) ;when + res + ) ;let + ) ;let* + ) ;receive + ;; Direct Base64 inline for native image formats + (let* ((b64-str (begin + (import (liii base64)) + (utf8->string (bytevector-base64-encode data)) + ) ;begin + ) ;b64-str + (src-uri (string-append "data:image/" ext ";base64," b64-str)) + (w (if (>= (length l) 2) (tmlength->htmllength (second l) #f) #f)) + (h (if (>= (length l) 3) (tmlength->htmllength (third l) #f) #f)) + ) ; + `((h:img (@ (class "image") + (src ,src-uri) + ,@(if w `((width ,w)) '()) + ,@(if h `((height ,h)) '())))) + ) ;let* + ) ;if + (receive (name-url name-string) + (tmhtml-image-names ext) + (let* ((abs-url (url-concretize name-url)) (abs-string (url->unix abs-url))) + (tmhtml-write-binary-file abs-url data) + (with res (tmhtml-image (cons abs-string (cdr l))) res) + ) ;let* + ) ;receive + ) ;if ) ;let* ) ;with ) ; @@ -2075,7 +2072,7 @@ ) ;let* ) ;else ) ;cond -) ;define +) ;tm-define (define-public (hash-map->list h) (map (lambda (x) (list (car x) (cdr x))) (map values h)) @@ -2094,8 +2091,8 @@ ) ;l1 (l2 (map car l1)) (args (map cadr l1)) - (funs (map cAr l2)) - (stys (map (lambda (x) (cdr (cDr x))) l2)) + (funs (map last l2)) + (stys (map (lambda (x) (reverse (cdr (reverse (cdr x))))) l2)) ) ; (apply string-append (list-intersperse (map (lambda (f arg sty) @@ -2105,8 +2102,8 @@ (list-intersperse (cond ((== (length args) (length sty)) (map (lambda (x y) (string-append x ":" (f y))) sty args) ) ; - ((>= 1 (length sty)) - (map (lambda (y) (string-append (car sty) ":" (f y))) args) + ((>= 1 (length args)) + (map (lambda (x) (string-append x ":" (f (car args)))) sty) ) ; (else '()) ) ;cond @@ -2662,7 +2659,10 @@ (define (tmhtml-css-post body) (if (pair? body) - `(,(car body) ,@(tmhtml-breaks-post* (map tmhtml-css-post (cdr body)))) + (if (symbol? (car body)) + `(,(car body) ,@(tmhtml-breaks-post* (map tmhtml-css-post (cdr body)))) + (map tmhtml-css-post body) + ) ;if body ) ;if ) ;define diff --git a/TeXmacs/plugins/html/progs/convert/mathml/tmmath.scm b/TeXmacs/plugins/html/progs/convert/mathml/tmmath.scm index 45a76b21eb..488e051c54 100644 --- a/TeXmacs/plugins/html/progs/convert/mathml/tmmath.scm +++ b/TeXmacs/plugins/html/progs/convert/mathml/tmmath.scm @@ -247,6 +247,10 @@ ;; Other constructs ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +(define (tmmath-ornament l) + `(m:mrow (@ (style "border: 1px solid black; padding: 0.2em; display: inline-block;")) + ,(tmmath (car l)))) + (define (tmmath-noop l) "") (define (tmmath-hspace l) @@ -378,6 +382,7 @@ (surround tmmath-surround) (move tmmath-first) (resize tmmath-first) + (ornament tmmath-ornament) (with tmmath-with)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/TeXmacs/tests/tmu/0642.tmu b/TeXmacs/tests/tmu/0642.tmu new file mode 100644 index 0000000000..6d74bb4845 --- /dev/null +++ b/TeXmacs/tests/tmu/0642.tmu @@ -0,0 +1,67 @@ +> + +> + +<\body> + <\framed> + <\definition> + \; + + <\equation*> + =log|P>|)>> + + + <\equation*> + =10*log|P>|)>> + + + + + \; + + <\framed> + <\equation*> + \> + + + + <\decorated> + <\framed> + ddddd + + + <\framed> + <\decorated> + ccccc + + + + +<\initial> + <\collection> + ||||||||||||>|>>>>> + + + ||||||||||||>|>>>>> + + + + + + +<\references> + <\collection> + > + > + + + +<\auxiliary> + <\collection> + <\associate|toc> + |1Bode Plots|.>>>>|>> + + |1.1Parallel Resonance|.>>>>|>> + + + diff --git a/devel/0642.md b/devel/0642.md new file mode 100644 index 0000000000..8a08000d31 --- /dev/null +++ b/devel/0642.md @@ -0,0 +1,44 @@ +# [0642] 修复 framed 内部 decorated 块的 HTML 导出问题 + +## 1 相关文档 +- [dddd.md](dddd.md) - 任务文档模板 +- [0642.md](0642.md) - 本任务文档 + +## 2 任务相关的代码文件 +- `TeXmacs/plugins/html/progs/convert/html/tmhtml.scm` - HTML 导出样式与转换逻辑 + +## 3 如何测试 + +### 3.1 确定性测试(单元测试) +无 + +### 3.2 非确定性测试(文档验证) +```bash +# 验证 HTML 导出无报错且生成正确背景与内边距样式 +xmake r stem --headless -c TeXmacs/tests/tmu/0642.tmu test_headless_fixed.html -q +``` + +## 4 如何提交 + +提交前执行以下最少步骤: + +```bash +# 格式化变更的文件(此处为 Scheme/TMU 文件) +gf fmt --changed-since=main +``` + +## 5 What +修复了在 `framed` 内部的 `decorated` 块 HTML 导出样式不正确/失效的 bug。 + +1. 修改了 `tmhtml-ornament-get-env-style` 中 `funs` 与 `stys` 的提取逻辑,正确解析 `tmhtml-env` 中保存的 CSS 转换函数与样式名列表。 +2. 修复了当 `args` 长度为 1 而 `sty` 长度不为 1 时(如一维内边距)样式值匹配被丢弃的 bug,完美支持 `padding-left` 与 `padding-right` 对称导出。 + +## 6 Why +在原实现中,由于 `funs` 和 `stys` 的提取存在逻辑颠倒: +- `funs` 错误地获取了 symbol 键(如 `:ornament-color`),而 `stys` 获取了转换函数(如 `tmcolor->htmlcolor`),从而丢失了真实的 HTML 样式属性名。 +- 在后续求值中,Scheme 尝试对 symbol 作为函数进行调用,导致抛出异常,整个 `decorated` (其核心展开为 `ornament`) 的属性解析完全失效,导致背景、内边距等核心样式完全丢失。 + +## 7 How +1. 将 `funs` 修改为映射 `last` 函数,正确获取 `key` 列表最后的转换过程:`(funs (map last l2))`。 +2. 将 `stys` 修改为过滤去首尾后剩下的样式键名称列表:`(stys (map (lambda (x) (reverse (cdr (reverse (cdr x))))) l2))`。 +3. 修正多参数映射的降级判断,将 `((>= 1 (length sty))` 纠正为 `((>= 1 (length args))`,使单值输入时能正确应用到其所有的多属性上。