Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
15 changes: 15 additions & 0 deletions TeXmacs/plugins/latex/progs/convert/latex/tmtex.scm
Original file line number Diff line number Diff line change
Expand Up @@ -1524,6 +1524,20 @@
(define (tmtex-table l)
(tmtex-table-apply 'tabular '() (cons 'table l)))

(define (tmtex-stack l)
(when (nnull? l)
(let* ((x (car l))
(p (tmtable-parser x))
(rows (p 'rows 'content)))
(latex-add-extra "mathtools")
(tex-apply 'substack
(tex-concat
(list-intersperse
(map (lambda (row)
(tex-concat (map tmtex row)))
rows)
"\\\\"))))))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Local and global environment changes
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Expand Down Expand Up @@ -3090,6 +3104,7 @@
(!arg tmtex-tex-arg))

(logic-dispatcher tmtex-extra-methods%
(stack tmtex-stack)
(wide-float tmtex-wide-float)
(phantom-float tmtex-noop)
((:or marginal-note marginal-normal-note) tmtex-marginal-note)
Expand Down
15 changes: 15 additions & 0 deletions TeXmacs/progs/convert/latex/tmtex.scm
Original file line number Diff line number Diff line change
Expand Up @@ -1524,6 +1524,20 @@
(define (tmtex-table l)
(tmtex-table-apply 'tabular '() (cons 'table l)))

(define (tmtex-stack l)
(when (nnull? l)
(let* ((x (car l))
(p (tmtable-parser x))
(rows (p 'rows 'content)))
(latex-add-extra "mathtools")
(tex-apply 'substack
(tex-concat
(list-intersperse
(map (lambda (row)
(tex-concat (map tmtex row)))
rows)
"\\\\"))))))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Local and global environment changes
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Expand Down Expand Up @@ -3090,6 +3104,7 @@
(!arg tmtex-tex-arg))

(logic-dispatcher tmtex-extra-methods%
(stack tmtex-stack)
(wide-float tmtex-wide-float)
(phantom-float tmtex-noop)
((:or marginal-note marginal-normal-note) tmtex-marginal-note)
Expand Down
31 changes: 31 additions & 0 deletions TeXmacs/tests/0605.scm
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; MODULE : 0605.scm
;; DESCRIPTION : Tests for stack to substack latex export
;; COPYRIGHT : (C) 2026 Jack Yansong Li
;;
;; This software falls under the GNU general public license version 3 or later.
;; It comes WITHOUT ANY WARRANTY WHATSOEVER. For details, see the file LICENSE
;; in the root directory or <http://www.gnu.org/licenses/gpl-3.0.html>.
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(import (liii check))

(load "./TeXmacs/plugins/latex/progs/init-latex.scm")

(define (export-as-latex-and-load path)
(with path (string-append "$TEXMACS_PATH/tests/tmu/" path)
(with tmpfile (url-temp)
(load-buffer path)
(buffer-export path tmpfile "latex")
(string-load tmpfile))))

(define (load-latex path)
(with path (string-append "$TEXMACS_PATH/tests/tex/" path)
(string-replace (string-load path) "\r\n" "\n")))


(define (test_0605)
(check (export-as-latex-and-load "0605.tmu") => (load-latex "0605_stack_export.tex"))
(check-report))
12 changes: 12 additions & 0 deletions TeXmacs/tests/tex/0605_stack_export.tex
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
\documentclass{article}
\usepackage[english]{babel}
\usepackage{mathtools}

\begin{document}

\[ \min_{\substack{x \in X \\ y \in Y}} \]


\

\end{document}
20 changes: 20 additions & 0 deletions TeXmacs/tests/tmu/0605.tmu
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<TMU|<tuple|1.1.0|2026.2.6-rc2>>

<style|<tuple|generic|number-europe|preview-ref>>

<\body>
<\equation*>
min<rsub|<stack|<tformat|<table|<row|<cell|x\<in\>X>>|<row|<cell|y\<in\>Y>>>>>>
</equation*>

\;

\;
</body>

<\initial>
<\collection>
<associate|page-screen-margin|false>
<associate|stem-doc-id|31ED99A3-1867-4900-82D3-0C3CEA54FD10>
</collection>
</initial>
55 changes: 55 additions & 0 deletions devel/0605.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# [0605] 修复 stack 结构的 LaTeX 导出为 \substack

## 相关文档
- [dddd.md](dddd.md) - 任务文档模板

## 任务相关的代码文件
- `TeXmacs/progs/convert/latex/tmtex.scm`
- `TeXmacs/plugins/latex/progs/convert/latex/tmtex.scm`
- `TeXmacs/tests/0605.scm`
- `TeXmacs/tests/tex/0605_stack_export.tex`
- `TeXmacs/tests/tmu/0605.tmu`

## 如何测试

### 确定性测试(单元测试)
```bash
xmake run 0605
```

### 非确定性测试(文档验证)
1. 打开 Mogan STEM,导入 `TeXmacs/tests/tmu/0605.tmu`。
2. 导出为 LaTeX,确认公式中的 stack 结构被正确导出为 `\substack{... \\ ...}`。

## 如何提交

提交前执行以下最少步骤:

```bash
xmake run 0605
```

## What
修复 stack 结构在导出 LaTeX 时错误地使用 `array` 环境的问题,改为正确导出为 `\substack{... \\ ...}` 格式。

1. 在 `tmtex.scm` 中新增 `tmtex-stack` 函数,将 stack 的表格内容转换为 `\substack` 参数格式
2. 在 `tmtex-extra-methods%` 分发表中注册 `stack` 的处理函数
3. 自动添加 `mathtools` 包依赖(`\substack` 需要此包)
4. 添加集成测试 `0605.scm` 和对应的预期输出文件

## Why

`\substack` 是 LaTeX 中表示多行下标/上标的标准命令(由 `mathtools`/`amsmath` 提供),语义上与 TeXmacs 的 stack 结构完全对应。之前导出为 `array` 环境会导致:
- 编译结果与原始排版差异较大
- 不符合数学公式的标准 LaTeX 表达方式
- 部分期刊投稿系统对 `array` 嵌套有兼容性问题

## How

实现思路:

1. 参考已有代码中 `tmtex-table` 的实现,利用 `tmtable-parser` 解析 stack 的表格结构
2. 提取每一行的单元格内容,用 `tmtex` 递归转换每个单元格
3. 用 `\\\\`(即 LaTeX 的 `\\`)作为行分隔符连接各行
4. 使用 `(tex-apply 'substack ...)` 生成最终的 LaTeX AST 节点
5. 调用 `(latex-add-extra "mathtools")` 确保导出的 LaTeX 文档包含所需的宏包
Loading