webtex-cn 0.1.0 → 0.1.1
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.md +184 -2
- package/dist/base.css +4 -4
- package/dist/webtex-cn.css +4 -4
- package/dist/webtex-cn.esm.js +4 -1
- package/dist/webtex-cn.js +4 -1
- package/dist/webtex-cn.min.js +11 -11
- package/package.json +1 -1
- package/src/layout/grid-layout.js +1 -1
- package/src/renderer/html-renderer.js +4 -0
- package/src/templates/base.css +4 -4
package/README.md
CHANGED
|
@@ -1,2 +1,184 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
1
|
+
# WebTeX-CN
|
|
2
|
+
|
|
3
|
+
将 [luatex-cn](https://github.com/open-guji/luatex-cn) 兼容的 `.tex` 文件转换为 HTML+CSS,在浏览器中实现传统古籍竖排效果。
|
|
4
|
+
|
|
5
|
+
## 特性
|
|
6
|
+
|
|
7
|
+
- 竖排排版(`writing-mode: vertical-rl`),从右到左阅读
|
|
8
|
+
- 自动分页:内容超出一个 spread 时自动创建新页
|
|
9
|
+
- 版心(鱼尾、书名、章节信息)
|
|
10
|
+
- 夹注:双行小字注释,自动分列平衡,长夹注跨页拆分
|
|
11
|
+
- 列表、段落缩进、眉批、侧批、批注
|
|
12
|
+
- 圈点、专名号、书名号等装饰标记
|
|
13
|
+
- 多模板:四库全书(黑白/彩色)、红楼梦甲戌本、极简
|
|
14
|
+
- 纯 JavaScript,零依赖,浏览器和 Node.js 均可运行
|
|
15
|
+
- 60+ TeX 命令支持
|
|
16
|
+
|
|
17
|
+
## 安装
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npm install webtex-cn
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## 快速开始
|
|
24
|
+
|
|
25
|
+
### 浏览器
|
|
26
|
+
|
|
27
|
+
```html
|
|
28
|
+
<link rel="stylesheet" href="node_modules/webtex-cn/src/templates/base.css">
|
|
29
|
+
<link rel="stylesheet" href="node_modules/webtex-cn/src/templates/siku-quanshu-colored.css">
|
|
30
|
+
|
|
31
|
+
<div id="viewer"></div>
|
|
32
|
+
|
|
33
|
+
<script type="module">
|
|
34
|
+
import { renderToDOM } from 'webtex-cn';
|
|
35
|
+
|
|
36
|
+
const tex = `\\documentclass[四库全书彩色]{ltc-guji}
|
|
37
|
+
\\title{欽定四庫全書}
|
|
38
|
+
\\chapter{史記\\\\卷一}
|
|
39
|
+
|
|
40
|
+
\\begin{document}
|
|
41
|
+
\\begin{正文}
|
|
42
|
+
天地玄黃宇宙洪荒\\夹注{千字文开篇}日月盈昃辰宿列張
|
|
43
|
+
\\end{正文}
|
|
44
|
+
\\end{document}`;
|
|
45
|
+
|
|
46
|
+
renderToDOM(tex, '#viewer');
|
|
47
|
+
</script>
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### Node.js
|
|
51
|
+
|
|
52
|
+
```js
|
|
53
|
+
import { renderToHTML } from 'webtex-cn';
|
|
54
|
+
import { readFileSync, writeFileSync } from 'fs';
|
|
55
|
+
|
|
56
|
+
const tex = readFileSync('input.tex', 'utf8');
|
|
57
|
+
const html = renderToHTML(tex);
|
|
58
|
+
writeFileSync('output.html', html);
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### CLI
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
# 构建静态 HTML
|
|
65
|
+
npx webtex-cn build input.tex -o output/
|
|
66
|
+
|
|
67
|
+
# 启动预览服务器
|
|
68
|
+
npx webtex-cn serve input.tex -p 8080
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## API
|
|
72
|
+
|
|
73
|
+
### `renderToHTML(texSource: string): string`
|
|
74
|
+
|
|
75
|
+
解析 TeX 源码,经过布局引擎分页后渲染为 HTML 字符串。返回多个 `<div class="wtc-page">` 拼接的 HTML。
|
|
76
|
+
|
|
77
|
+
### `renderToDOM(texSource: string, container: HTMLElement | string, options?)`
|
|
78
|
+
|
|
79
|
+
解析并渲染到指定 DOM 容器中。`container` 可以是 DOM 元素或 CSS 选择器。
|
|
80
|
+
|
|
81
|
+
options:
|
|
82
|
+
- `cssBasePath`: CSS 文件的基础路径,设置后自动加载模板 CSS
|
|
83
|
+
|
|
84
|
+
### `render(url: string, container: HTMLElement | string, options?)`
|
|
85
|
+
|
|
86
|
+
从 URL 获取 `.tex` 文件后渲染到 DOM 容器。
|
|
87
|
+
|
|
88
|
+
### `renderToPage(texSource: string): string`
|
|
89
|
+
|
|
90
|
+
渲染为完整的 HTML 页面(含 `<html>`, `<head>` 等)。
|
|
91
|
+
|
|
92
|
+
### `getTemplates(): Array<{id, name}>`
|
|
93
|
+
|
|
94
|
+
获取可用模板列表。
|
|
95
|
+
|
|
96
|
+
### `setTemplate(templateId: string, basePath?: string)`
|
|
97
|
+
|
|
98
|
+
动态切换 CSS 模板(仅浏览器环境)。
|
|
99
|
+
|
|
100
|
+
### 底层 API
|
|
101
|
+
|
|
102
|
+
```js
|
|
103
|
+
import { parse } from 'webtex-cn';
|
|
104
|
+
import { layout } from 'webtex-cn';
|
|
105
|
+
import { HTMLRenderer } from 'webtex-cn';
|
|
106
|
+
|
|
107
|
+
const { ast, warnings } = parse(texSource);
|
|
108
|
+
const layoutResult = layout(ast);
|
|
109
|
+
const renderer = new HTMLRenderer(ast);
|
|
110
|
+
const pageHTMLs = renderer.renderFromLayout(layoutResult);
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## 模板
|
|
114
|
+
|
|
115
|
+
| 模板 ID | 名称 | 说明 |
|
|
116
|
+
|---------|------|------|
|
|
117
|
+
| `siku-quanshu` | 四库全书 | 黑白经典样式 |
|
|
118
|
+
| `siku-quanshu-colored` | 四库全书彩色 | 彩色仿古纸背景 |
|
|
119
|
+
| `honglou` | 红楼梦甲戌本 | 红楼梦甲戌本样式 |
|
|
120
|
+
| `minimal` | 极简 | 最小化样式,适合自定义 |
|
|
121
|
+
|
|
122
|
+
在 `.tex` 文件中通过 `\documentclass` 选择模板:
|
|
123
|
+
|
|
124
|
+
```latex
|
|
125
|
+
\documentclass[四库全书彩色]{ltc-guji}
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
## TeX 语法示例
|
|
129
|
+
|
|
130
|
+
```latex
|
|
131
|
+
\documentclass[四库全书彩色]{ltc-guji}
|
|
132
|
+
\title{欽定四庫全書}
|
|
133
|
+
\chapter{史記\\卷一}
|
|
134
|
+
|
|
135
|
+
\begin{document}
|
|
136
|
+
\begin{正文}
|
|
137
|
+
欽定四庫全書
|
|
138
|
+
|
|
139
|
+
\begin{列表}
|
|
140
|
+
\item 史記卷一
|
|
141
|
+
\item 五帝本紀第一
|
|
142
|
+
\end{列表}
|
|
143
|
+
|
|
144
|
+
\begin{段落}[indent=3]
|
|
145
|
+
集解裴駰曰凡是徐氏義稱徐姓名以别之
|
|
146
|
+
\end{段落}
|
|
147
|
+
|
|
148
|
+
黄帝者\夹注{集解徐廣曰號有熊}少典之子
|
|
149
|
+
\end{正文}
|
|
150
|
+
\end{document}
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
完整命令参考请见 [doc/05-command-reference.md](doc/05-command-reference.md)。
|
|
154
|
+
|
|
155
|
+
## 架构
|
|
156
|
+
|
|
157
|
+
```
|
|
158
|
+
TeX 源码 → Parser → AST → Layout Engine → LayoutResult → HTML Renderer → HTML+CSS
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
三阶段管线:
|
|
162
|
+
1. **解析**:递归下降解析器,将 TeX 源码转为 AST
|
|
163
|
+
2. **布局**:虚拟网格布局引擎,计算每个节点的页/列/行坐标,处理分页和夹注分段
|
|
164
|
+
3. **渲染**:将布局结果转为 HTML,支持跨页标签平衡
|
|
165
|
+
|
|
166
|
+
详细架构文档见 [doc/](doc/) 目录。
|
|
167
|
+
|
|
168
|
+
## 开发
|
|
169
|
+
|
|
170
|
+
```bash
|
|
171
|
+
git clone https://github.com/open-guji/webtex-cn.git
|
|
172
|
+
cd webtex-cn
|
|
173
|
+
npm install
|
|
174
|
+
|
|
175
|
+
npm test # 运行测试
|
|
176
|
+
npm run build # 构建 dist/
|
|
177
|
+
npm run dev # 启动示例预览
|
|
178
|
+
npm run lint # ESLint 检查
|
|
179
|
+
npm run format # Prettier 格式化
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
## 许可证
|
|
183
|
+
|
|
184
|
+
[Apache-2.0](LICENSE)
|
package/dist/base.css
CHANGED
|
@@ -40,10 +40,10 @@
|
|
|
40
40
|
/* Jiazhu: visually smaller chars but same grid-cell height as main text.
|
|
41
41
|
font-size < 1em for smaller glyphs; letter-spacing compensates to match grid height.
|
|
42
42
|
Grid height per char = font-size × (1 + ls-ratio). Jiazhu needs same total.
|
|
43
|
-
jiazhu-ls = (grid-height - jiazhu-font-size) = font-size×(1+ls-ratio) - font-size×0.
|
|
44
|
-
= font-size × (0.15 + ls-ratio). In em: (0.15+ls-ratio)/0.
|
|
45
|
-
--wtc-jiazhu-font-size: 0.
|
|
46
|
-
--wtc-jiazhu-letter-spacing: calc((0.
|
|
43
|
+
jiazhu-ls = (grid-height - jiazhu-font-size) = font-size×(1+ls-ratio) - font-size×0.7
|
|
44
|
+
= font-size × (0.15 + ls-ratio). In em: (0.15+ls-ratio)/0.7 */
|
|
45
|
+
--wtc-jiazhu-font-size: 0.7em;
|
|
46
|
+
--wtc-jiazhu-letter-spacing: calc((0.3 + var(--wtc-letter-spacing-ratio)) / 0.7 * 1em);
|
|
47
47
|
--wtc-jiazhu-line-height: calc(var(--wtc-line-height) / 2);
|
|
48
48
|
--wtc-jiazhu-color: inherit;
|
|
49
49
|
--wtc-jiazhu-gap: 0px;
|
package/dist/webtex-cn.css
CHANGED
|
@@ -43,10 +43,10 @@
|
|
|
43
43
|
/* Jiazhu: visually smaller chars but same grid-cell height as main text.
|
|
44
44
|
font-size < 1em for smaller glyphs; letter-spacing compensates to match grid height.
|
|
45
45
|
Grid height per char = font-size × (1 + ls-ratio). Jiazhu needs same total.
|
|
46
|
-
jiazhu-ls = (grid-height - jiazhu-font-size) = font-size×(1+ls-ratio) - font-size×0.
|
|
47
|
-
= font-size × (0.15 + ls-ratio). In em: (0.15+ls-ratio)/0.
|
|
48
|
-
--wtc-jiazhu-font-size: 0.
|
|
49
|
-
--wtc-jiazhu-letter-spacing: calc((0.
|
|
46
|
+
jiazhu-ls = (grid-height - jiazhu-font-size) = font-size×(1+ls-ratio) - font-size×0.7
|
|
47
|
+
= font-size × (0.15 + ls-ratio). In em: (0.15+ls-ratio)/0.7 */
|
|
48
|
+
--wtc-jiazhu-font-size: 0.7em;
|
|
49
|
+
--wtc-jiazhu-letter-spacing: calc((0.3 + var(--wtc-letter-spacing-ratio)) / 0.7 * 1em);
|
|
50
50
|
--wtc-jiazhu-line-height: calc(var(--wtc-line-height) / 2);
|
|
51
51
|
--wtc-jiazhu-color: inherit;
|
|
52
52
|
--wtc-jiazhu-gap: 0px;
|
package/dist/webtex-cn.esm.js
CHANGED
|
@@ -1083,7 +1083,7 @@ var GridLayoutEngine = class {
|
|
|
1083
1083
|
if (!isFirst) {
|
|
1084
1084
|
this.advanceColumn();
|
|
1085
1085
|
}
|
|
1086
|
-
this.placeMarker(LayoutMarker.LIST_ITEM_START);
|
|
1086
|
+
this.placeMarker(LayoutMarker.LIST_ITEM_START, { isFirstListItem: isFirst });
|
|
1087
1087
|
this.walkChildren(node.children);
|
|
1088
1088
|
this.placeMarker(LayoutMarker.LIST_ITEM_END);
|
|
1089
1089
|
}
|
|
@@ -1358,6 +1358,9 @@ ${floatsHTML}<div class="wtc-half-page wtc-half-right"><div class="wtc-content-b
|
|
|
1358
1358
|
for (const item of items) {
|
|
1359
1359
|
const type = item.node.type;
|
|
1360
1360
|
if (this.isOpenMarker(type)) {
|
|
1361
|
+
if (type === LayoutMarker.LIST_ITEM_START && !item.isFirstListItem) {
|
|
1362
|
+
html += '<br class="wtc-newline">';
|
|
1363
|
+
}
|
|
1361
1364
|
html += this.markerOpenTag(item);
|
|
1362
1365
|
stack.push(item);
|
|
1363
1366
|
} else if (this.matchingOpenMarker(type)) {
|
package/dist/webtex-cn.js
CHANGED
|
@@ -1116,7 +1116,7 @@ var WebTeX = (() => {
|
|
|
1116
1116
|
if (!isFirst) {
|
|
1117
1117
|
this.advanceColumn();
|
|
1118
1118
|
}
|
|
1119
|
-
this.placeMarker(LayoutMarker.LIST_ITEM_START);
|
|
1119
|
+
this.placeMarker(LayoutMarker.LIST_ITEM_START, { isFirstListItem: isFirst });
|
|
1120
1120
|
this.walkChildren(node.children);
|
|
1121
1121
|
this.placeMarker(LayoutMarker.LIST_ITEM_END);
|
|
1122
1122
|
}
|
|
@@ -1391,6 +1391,9 @@ ${floatsHTML}<div class="wtc-half-page wtc-half-right"><div class="wtc-content-b
|
|
|
1391
1391
|
for (const item of items) {
|
|
1392
1392
|
const type = item.node.type;
|
|
1393
1393
|
if (this.isOpenMarker(type)) {
|
|
1394
|
+
if (type === LayoutMarker.LIST_ITEM_START && !item.isFirstListItem) {
|
|
1395
|
+
html += '<br class="wtc-newline">';
|
|
1396
|
+
}
|
|
1394
1397
|
html += this.markerOpenTag(item);
|
|
1395
1398
|
stack.push(item);
|
|
1396
1399
|
} else if (this.matchingOpenMarker(type)) {
|
package/dist/webtex-cn.min.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
var WebTeX=(()=>{var S=Object.defineProperty;var W=Object.getOwnPropertyDescriptor;var Z=Object.getOwnPropertyNames;var V=Object.prototype.hasOwnProperty;var Y=(i,e)=>{for(var t in e)S(i,t,{get:e[t],enumerable:!0})},Q=(i,e,t,
|
|
1
|
+
var WebTeX=(()=>{var S=Object.defineProperty;var W=Object.getOwnPropertyDescriptor;var Z=Object.getOwnPropertyNames;var V=Object.prototype.hasOwnProperty;var Y=(i,e)=>{for(var t in e)S(i,t,{get:e[t],enumerable:!0})},Q=(i,e,t,s)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of Z(e))!V.call(i,r)&&r!==t&&S(i,r,{get:()=>e[r],enumerable:!(s=W(e,r))||s.enumerable});return i};var ee=i=>Q(S({},"__esModule",{value:!0}),i);var ie={};Y(ie,{HTMLRenderer:()=>w,getTemplates:()=>J,layout:()=>y,parse:()=>E,render:()=>K,renderToDOM:()=>B,renderToHTML:()=>F,renderToPage:()=>U,setTemplate:()=>L});var l={COMMAND:"COMMAND",OPEN_BRACE:"OPEN_BRACE",CLOSE_BRACE:"CLOSE_BRACE",OPEN_BRACKET:"OPEN_BRACKET",CLOSE_BRACKET:"CLOSE_BRACKET",TEXT:"TEXT",NEWLINE:"NEWLINE",COMMENT:"COMMENT",BEGIN:"BEGIN",END:"END",MATH:"MATH",PARAGRAPH_BREAK:"PARAGRAPH_BREAK",EOF:"EOF"};function O(i){return/[a-zA-Z]/.test(i)}function b(i){let e=i.codePointAt(0);return e>=19968&&e<=40959||e>=13312&&e<=19903||e>=63744&&e<=64255}function te(i){return O(i)||b(i)||i==="@"||i==="*"}var v=class{constructor(e){this.source=e,this.pos=0,this.tokens=[]}peek(){return this.pos>=this.source.length?null:this.source[this.pos]}advance(){let e=this.source[this.pos];return this.pos++,e}tokenize(){for(;this.pos<this.source.length;){let e=this.peek();if(e==="%"){this.skipComment();continue}if(e==="$"){this.readMath();continue}if(e==="\\"){this.readCommand();continue}if(e==="{"){this.tokens.push({type:l.OPEN_BRACE,value:"{"}),this.advance();continue}if(e==="}"){this.tokens.push({type:l.CLOSE_BRACE,value:"}"}),this.advance();continue}if(e==="["){this.tokens.push({type:l.OPEN_BRACKET,value:"["}),this.advance();continue}if(e==="]"){this.tokens.push({type:l.CLOSE_BRACKET,value:"]"}),this.advance();continue}this.readText()}return this.tokens.push({type:l.EOF,value:""}),this.tokens}skipComment(){for(;this.pos<this.source.length&&this.source[this.pos]!==`
|
|
2
2
|
`;)this.pos++;this.pos<this.source.length&&this.pos++}readCommand(){if(this.advance(),this.pos>=this.source.length){this.tokens.push({type:l.TEXT,value:"\\"});return}let e=this.peek();if(e==="\\"){this.advance(),this.tokens.push({type:l.NEWLINE,value:"\\\\"});return}if("{}[]%$&#_~^".includes(e)){this.advance(),this.tokens.push({type:l.TEXT,value:e});return}if(e===" "||e===`
|
|
3
|
-
`){this.advance(),this.tokens.push({type:l.TEXT,value:" "});return}if(!te(e)){this.advance(),this.tokens.push({type:l.COMMAND,value:e});return}let t=O(e)||e==="@"||e==="*",n=b(e),r="";if(t){for(;this.pos<this.source.length&&(O(this.peek())||this.peek()==="@"||this.peek()==="*");)r+=this.advance();for(;this.pos<this.source.length&&this.source[this.pos]===" ";)this.pos++}else if(n)for(;this.pos<this.source.length&&b(this.peek());)r+=this.advance();r==="begin"?this.tokens.push({type:l.BEGIN,value:"begin"}):r==="end"?this.tokens.push({type:l.END,value:"end"}):this.tokens.push({type:l.COMMAND,value:r})}readMath(){this.advance();let e="";for(;this.pos<this.source.length;){if(this.peek()==="$"){this.advance(),this.tokens.push({type:l.MATH,value:e});return}e+=this.advance()}this.tokens.push({type:l.TEXT,value:"$"+e})}readText(){let e="";for(;this.pos<this.source.length;){let t=this.peek();if(t==="\\"||t==="{"||t==="}"||t==="["||t==="]"||t==="%"||t==="$")break;e+=this.advance()}if(e){let t=e.split(/\n[ \t]*\n/);for(let n=0;n<t.length;n++){n>0&&this.tokens.push({type:l.PARAGRAPH_BREAK,value:""});let r=t[n].replace(/[ \t]+/g," ");(r.trim()||r===" ")&&this.tokens.push({type:l.TEXT,value:r})}}}};var z={documentclass:{args:["optional","required"]},title:{args:["required"]},chapter:{args:["required"]},\u5939\u6CE8:{args:["optional","required"],node:"jiazhu"},JiaZhu:{alias:"\u5939\u6CE8"},\u5355\u884C\u5939\u6CE8:{args:["optional","required"],node:"jiazhu",single:!0},DanHangJiaZhu:{alias:"\u5355\u884C\u5939\u6CE8"},\u4FA7\u6279:{args:["optional","required"],node:"sidenote"},SideNode:{alias:"\u4FA7\u6279"},CePi:{alias:"\u4FA7\u6279"},\u7709\u6279:{args:["optional","required"],node:"meipi"},MeiPi:{alias:"\u7709\u6279"},\u6279\u6CE8:{args:["optional","required"],node:"pizhu"},PiZhu:{alias:"\u6279\u6CE8"},\u6587\u672C\u6846:{args:["optional","required"],node:"textbox"},TextBox:{alias:"\u6587\u672C\u6846"},\u586B\u5145\u6587\u672C\u6846:{args:["optional","required"],node:"fillTextbox"},FillTextBox:{alias:"\u586B\u5145\u6587\u672C\u6846"},\u5708\u70B9:{args:["optional","required"],node:"emphasis"},EmphasisMark:{alias:"\u5708\u70B9"},\u88C5\u9970:{args:["optional","required"],node:"decorate"},decorate:{alias:"\u88C5\u9970"},\u4E13\u540D\u53F7:{args:["optional","required"],node:"properName"},ProperNameMark:{alias:"\u4E13\u540D\u53F7"},\u4E66\u540D\u53F7:{args:["optional","required"],node:"bookTitle"},BookTitleMark:{alias:"\u4E66\u540D\u53F7"},\u4E0B\u5212\u7EBF:{alias:"\u4E13\u540D\u53F7"},Underline:{alias:"\u4E13\u540D\u53F7"},\u6CE2\u6D6A\u7EBF:{alias:"\u4E66\u540D\u53F7"},WavyUnderline:{alias:"\u4E66\u540D\u53F7"},\u53CD\u767D:{args:["required"],node:"inverted"},inverted:{alias:"\u53CD\u767D"},\u516B\u89D2\u6846:{args:["required"],node:"octagon"},octagon:{alias:"\u516B\u89D2\u6846"},\u5E26\u5708:{args:["required"],node:"circled"},circled:{alias:"\u5E26\u5708"},\u53CD\u767D\u516B\u89D2\u6846:{args:["required"],node:"invertedOctagon"},invertedOctagon:{alias:"\u53CD\u767D\u516B\u89D2\u6846"},\u6539:{args:["required"],node:"fix"},fix:{alias:"\u6539"},\u7A7A\u683C:{args:["optional"],node:"space"},Space:{alias:"\u7A7A\u683C"},\u8BBE\u7F6E\u7F29\u8FDB:{args:["required"],node:"setIndent"},SetIndent:{alias:"\u8BBE\u7F6E\u7F29\u8FDB"},\u6362\u884C:{args:[],node:"columnBreak"},\u62AC\u5934:{args:["optional"],node:"taitou"},\u5E73\u62AC:{args:[],node:"taitou",defaultOpt:"0"},\u5355\u62AC:{args:[],node:"taitou",defaultOpt:"1"},\u53CC\u62AC:{args:[],node:"taitou",defaultOpt:"2"},\u4E09\u62AC:{args:[],node:"taitou",defaultOpt:"3"},\u632A\u62AC:{args:["optional"],node:"nuotai"},\u7A7A\u62AC:{args:[],node:"nuotai",defaultOpt:"1"},\u76F8\u5BF9\u62AC\u5934:{args:["optional"],node:"relativeTaitou"},contentSetup:{args:["required"],node:"setupCmd",setupType:"content"},pageSetup:{args:["required"],node:"setupCmd",setupType:"page"},banxinSetup:{args:["required"],node:"setupCmd",setupType:"banxin"},sidenodeSetup:{args:["required"],node:"setupCmd",setupType:"sidenode"},jiazhuSetup:{args:["required"],node:"setupCmd",setupType:"jiazhu"},pizhuSetup:{args:["required"],node:"setupCmd",setupType:"pizhu"},meipiSetup:{args:["required"],node:"setupCmd",setupType:"meipi"},gujiSetup:{args:["required"],node:"setupCmd",setupType:"guji"},judouSetup:{args:["required"],node:"setupCmd",setupType:"judou"},\u53E5\u8BFB\u6A21\u5F0F:{args:["optional"],node:"setupCmd",setupType:"judou-on"},JudouOn:{alias:"\u53E5\u8BFB\u6A21\u5F0F"},\u6B63\u5E38\u6807\u70B9\u6A21\u5F0F:{args:["optional"],node:"setupCmd",setupType:"judou-off"},JudouOff:{alias:"\u6B63\u5E38\u6807\u70B9\u6A21\u5F0F"},\u65E0\u6807\u70B9\u6A21\u5F0F:{args:["optional"],node:"setupCmd",setupType:"judou-none"},NonePunctuationMode:{alias:"\u65E0\u6807\u70B9\u6A21\u5F0F"},usepackage:{args:["optional","required"],ignore:!0},RequirePackage:{alias:"usepackage"},setmainfont:{args:["optional","required"],ignore:!0},pagestyle:{args:["required"],ignore:!0},noindent:{args:[],ignore:!0},par:{args:[],ignore:!0},relax:{args:[],ignore:!0},ignorespaces:{args:[],ignore:!0},definecolor:{args:["required","required","required"],ignore:!0},AddToHook:{args:["required","required"],ignore:!0},\u7981\u7528\u5206\u9875\u88C1\u526A:{args:[],ignore:!0},\u663E\u793A\u5750\u6807:{args:[],ignore:!0},LtcDebugOn:{args:[],ignore:!0},LtcDebugOff:{args:[],ignore:!0},\u5370\u7AE0:{args:["optional","required"],node:"stamp"}},H={document:{node:"body"},\u6B63\u6587:{node:"contentBlock"},BodyText:{alias:"\u6B63\u6587"},\u6BB5\u843D:{node:"paragraph",hasOptions:!0},Paragraph:{alias:"\u6BB5\u843D"},\u5217\u8868:{node:"list"},\u5939\u6CE8\u73AF\u5883:{node:"jiazhu"},JiaZhuEnv:{alias:"\u5939\u6CE8\u73AF\u5883"}};function j(i){let e=z[i],t=new Set;for(;e&&e.alias&&!t.has(e.alias);)t.add(i),i=e.alias,e=z[i];return e||null}function q(i){let e=H[i],t=new Set;for(;e&&e.alias&&!t.has(e.alias);)t.add(i),i=e.alias,e=H[i];return e||null}var s={DOCUMENT:"document",CONTENT_BLOCK:"contentBlock",PARAGRAPH:"paragraph",TEXT:"text",NEWLINE:"newline",JIAZHU:"jiazhu",SIDENOTE:"sidenote",MEIPI:"meipi",PIZHU:"pizhu",TEXTBOX:"textbox",FILL_TEXTBOX:"fillTextbox",SPACE:"space",COLUMN_BREAK:"columnBreak",TAITOU:"taitou",NUOTAI:"nuotai",SET_INDENT:"setIndent",EMPHASIS:"emphasis",PROPER_NAME:"properName",BOOK_TITLE:"bookTitle",INVERTED:"inverted",OCTAGON:"octagon",CIRCLED:"circled",INVERTED_OCTAGON:"invertedOctagon",FIX:"fix",DECORATE:"decorate",LIST:"list",LIST_ITEM:"listItem",SETUP:"setup",STAMP:"stamp",MATH:"math",PARAGRAPH_BREAK:"paragraphBreak",UNKNOWN:"unknown"};function g(i,e={}){return{type:i,children:[],...e}}function C(i){if(!i||!i.trim())return{};let e={},t=0,n="",r="",a=!1;for(let o=0;o<i.length;o++){let h=i[o];if(h==="{"&&t++,h==="}"&&t--,t===0&&h===","){n.trim()&&(e[n.trim()]=a?r.trim():"true"),n="",r="",a=!1;continue}else t===0&&h==="="&&!a?a=!0:a?r+=h:n+=h}return n.trim()&&(a?e[n.trim()]=r.trim():e[n.trim()]="true"),e}var A=class i{constructor(e){this.tokens=e,this.pos=0,this.warnings=[]}peek(){return this.pos>=this.tokens.length?{type:l.EOF,value:""}:this.tokens[this.pos]}advance(){let e=this.tokens[this.pos];return this.pos++,e}expect(e){let t=this.peek();return t.type!==e?(this.warnings.push(`Expected ${e} but got ${t.type} ("${t.value}") at token ${this.pos}`),null):this.advance()}readBraceGroup(){if(this.peek().type!==l.OPEN_BRACE)return"";this.advance();let e="",t=1;for(;this.pos<this.tokens.length&&t>0;){let n=this.peek();if(n.type===l.OPEN_BRACE)t++,e+="{",this.advance();else if(n.type===l.CLOSE_BRACE)t--,t>0&&(e+="}"),this.advance();else{if(n.type===l.EOF)break;e+=n.value,this.advance()}}return e}readBracketGroup(){if(this.peek().type!==l.OPEN_BRACKET)return null;this.advance();let e="",t=1;for(;this.pos<this.tokens.length&&t>0;){let n=this.peek();if(n.type===l.OPEN_BRACKET)t++,e+="[",this.advance();else if(n.type===l.CLOSE_BRACKET)t--,t>0&&(e+="]"),this.advance();else{if(n.type===l.EOF)break;e+=n.value,this.advance()}}return e}readBraceGroupAsNodes(){if(this.peek().type!==l.OPEN_BRACE)return[];this.advance();let e=[];for(;this.pos<this.tokens.length;){let t=this.peek();if(t.type===l.CLOSE_BRACE){this.advance();break}if(t.type===l.EOF)break;let n=this.parseToken();n&&e.push(n)}return e}parseCommandArgs(e){let t=null,n=[];if(!e.args)return{optionalArg:t,requiredArgs:n};for(let r of e.args)if(r==="optional")t=this.readBracketGroup();else if(r==="required"){let a=this.readBraceGroup();n.push(a)}return{optionalArg:t,requiredArgs:n}}parse(){let e=g(s.DOCUMENT);for(e.template="",e.documentClass="",e.title="",e.chapter="",e.setupCommands=[];this.pos<this.tokens.length&&this.peek().type!==l.EOF;){let n=this.parseToken(e);n&&e.children.push(n)}return e}parseToken(e){let t=this.peek();switch(t.type){case l.TEXT:return this.advance(),g(s.TEXT,{value:t.value});case l.NEWLINE:return this.advance(),g(s.NEWLINE);case l.MATH:return this.advance(),g(s.MATH,{value:t.value});case l.PARAGRAPH_BREAK:return this.advance(),g(s.PARAGRAPH_BREAK);case l.COMMAND:return this.parseCommand(e);case l.BEGIN:return this.parseEnvironment(e);case l.END:return null;case l.OPEN_BRACE:return this.parseBareGroup();default:return this.advance(),null}}parseBareGroup(){let e=this.readBraceGroupAsNodes();if(e.length===0)return null;if(e.length===1)return e[0];let t=g("group");return t.children=e,t}parseCommand(e){let n=this.advance().value,r=j(n);if(n==="documentclass"){let p=this.readBracketGroup(),f=this.readBraceGroup();return e&&(e.documentClass=f,e.template=p||""),null}if(n==="title"){let p=this.readBraceGroup();return e&&(e.title=p),null}if(n==="chapter"){let p=this.readBraceGroup();return e&&(e.chapter=p),null}if(n==="item")return g(s.LIST_ITEM);if(!r){this.warnings.push(`Unknown command: \\${n} at token ${this.pos}`);let p="";return this.peek().type===l.OPEN_BRACE&&(p=this.readBraceGroup()),g(s.TEXT,{value:p})}if(r.ignore)return this.parseCommandArgs(r),null;if(r.node==="setupCmd"){let{optionalArg:p,requiredArgs:f}=this.parseCommandArgs(r),T=C(f[0]||p||""),R=g(s.SETUP,{setupType:r.setupType,params:T});return e&&e.setupCommands.push(R),null}let{optionalArg:a,requiredArgs:o}=this.parseCommandArgs(r),h=C(a||""),c=this.mapNodeType(r.node),u=g(c,{options:h});if(r.defaultOpt!==void 0&&a===null&&(u.options={value:r.defaultOpt}),o.length>0&&r.node!=="stamp"){let{Tokenizer:p}=ne(),f=new p(o[0]).tokenize(),T=new i(f);for(;T.pos<T.tokens.length&&T.peek().type!==l.EOF;){let x=T.parseToken();x&&u.children.push(x)}}return(r.node==="space"||r.node==="taitou"||r.node==="nuotai"||r.node==="relativeTaitou")&&(u.value=a||r.defaultOpt||"1"),r.node==="setIndent"&&(u.value=o[0]||"0"),r.node==="stamp"&&(u.options=C(a||""),u.src=o[0]||""),u}parseEnvironment(e){this.advance();let t=this.readBraceGroup(),n=q(t);if(!n){this.warnings.push(`Unknown environment: ${t}`);let h=this.parseUntilEnd(t,e),c=g(s.UNKNOWN,{envName:t});return c.children=h,c}let r={};if(n.hasOptions){let h=this.readBracketGroup();h&&(r=C(h))}let a=this.mapNodeType(n.node),o=g(a,{options:r});return n.node==="body"?(o.children=this.parseUntilEnd(t,e),o):(o.children=this.parseUntilEnd(t,e),n.node==="list"&&(o.children=this.groupListItems(o.children)),o)}parseUntilEnd(e,t){let n=[];for(;this.pos<this.tokens.length;){let r=this.peek();if(r.type===l.EOF){this.warnings.push(`Unclosed environment: ${e}`);break}if(r.type===l.END){this.advance();let o=this.readBraceGroup();if(o===e)break;this.warnings.push(`Mismatched \\end{${o}}, expected \\end{${e}}`);continue}let a=this.parseToken(t);a&&n.push(a)}return n}groupListItems(e){let t=[],n=null;for(let r of e)r.type===s.LIST_ITEM?(n=g(s.LIST_ITEM),t.push(n)):(n||(n=g(s.LIST_ITEM),t.push(n)),n.children.push(r));return t}mapNodeType(e){return{contentBlock:s.CONTENT_BLOCK,paragraph:s.PARAGRAPH,jiazhu:s.JIAZHU,sidenote:s.SIDENOTE,meipi:s.MEIPI,pizhu:s.PIZHU,textbox:s.TEXTBOX,fillTextbox:s.FILL_TEXTBOX,space:s.SPACE,columnBreak:s.COLUMN_BREAK,taitou:s.TAITOU,nuotai:s.NUOTAI,setIndent:s.SET_INDENT,emphasis:s.EMPHASIS,properName:s.PROPER_NAME,bookTitle:s.BOOK_TITLE,inverted:s.INVERTED,octagon:s.OCTAGON,circled:s.CIRCLED,invertedOctagon:s.INVERTED_OCTAGON,fix:s.FIX,decorate:s.DECORATE,list:s.LIST,body:"body",stamp:s.STAMP,relativeTaitou:s.TAITOU}[e]||s.UNKNOWN}},I=null;function ne(){return I||(I={Tokenizer:null}),I}function G(i){I||(I={}),I.Tokenizer=i}G(v);function E(i){let t=new v(i).tokenize(),n=new A(t);return{ast:n.parse(),warnings:n.warnings}}var D={\u56DB\u5E93\u5168\u4E66:"siku-quanshu",\u56DB\u5EAB\u5168\u66F8:"siku-quanshu",\u56DB\u5E93\u5168\u4E66\u5F69\u8272:"siku-quanshu-colored",\u56DB\u5EAB\u5168\u66F8\u5F69\u8272:"siku-quanshu-colored",\u7EA2\u697C\u68A6\u7532\u620C\u672C:"honglou",\u7D05\u6A13\u5922\u7532\u620C\u672C:"honglou",\u6781\u7B80:"minimal",\u6975\u7C21:"minimal",default:"siku-quanshu"},se={"siku-quanshu":{nRows:21,nCols:8},"siku-quanshu-colored":{nRows:21,nCols:8},honglou:{nRows:20,nCols:9},minimal:{nRows:21,nCols:8}};function N(i){let e=D[i.template]||"siku-quanshu";for(let t of i.setupCommands||[])if(t.setupType==="guji"&&t.params?.template){let n=D[t.params.template];n&&(e=n)}return e}function P(i){return se[i]||{nRows:21,nCols:8}}function k(i){let e="";for(let t of i)t.type===s.TEXT?e+=t.value:t.children&&t.children.length>0&&(e+=k(t.children));return e}function M(i,e="outward"){let t=[...i];if(t.length===0)return{col1:"",col2:""};if(t.length===1)return{col1:t[0],col2:""};let n=e==="inward"?Math.floor(t.length/2):Math.ceil(t.length/2);return{col1:t.slice(0,n).join(""),col2:t.slice(n).join("")}}function B(i,e=20,t="outward",n=0){let r=n>0?n:e,a=[...i],o=r*2;if(a.length<=o)return[M(i,t)];let h=[],c=a.slice(0,o).join("");h.push(M(c,t));let u=e*2;for(let p=o;p<a.length;p+=u){let f=a.slice(p,p+u).join("");h.push(M(f,t))}return h}var d={PARAGRAPH_START:"_paragraphStart",PARAGRAPH_END:"_paragraphEnd",LIST_START:"_listStart",LIST_END:"_listEnd",LIST_ITEM_START:"_listItemStart",LIST_ITEM_END:"_listItemEnd"};function X(){return{items:[],floats:[],halfBoundary:null}}var $=class{constructor(e,t){this.nRows=e,this.nCols=t,this.colsPerSpread=2*t,this.currentCol=0,this.currentRow=0,this.currentIndent=0,this.pages=[X()]}get currentPage(){return this.pages[this.pages.length-1]}get effectiveRows(){return this.nRows-this.currentIndent}checkHalfBoundary(){this.currentPage.halfBoundary===null&&this.currentCol>=this.nCols&&(this.currentPage.halfBoundary=this.currentPage.items.length)}advanceColumn(){this.currentCol++,this.currentRow=0,this.checkHalfBoundary(),this.currentCol>=this.colsPerSpread&&this.newPageBreak()}newPageBreak(){this.currentPage.halfBoundary===null&&(this.currentPage.halfBoundary=this.currentPage.items.length),this.pages.push(X()),this.currentCol=0,this.currentRow=0}placeItem(e,t={}){this.checkHalfBoundary(),this.currentPage.items.push({node:e,col:this.currentCol,row:this.currentRow,indent:this.currentIndent,...t})}placeMarker(e,t={}){this.checkHalfBoundary(),this.currentPage.items.push({node:{type:e},col:this.currentCol,row:this.currentRow,indent:this.currentIndent,...t})}walkChildren(e){for(let t of e)this.walkNode(t)}advanceRows(e){for(this.currentRow+=e;this.currentRow>=this.effectiveRows;)if(this.currentRow-=this.effectiveRows,this.currentCol++,this.checkHalfBoundary(),this.currentCol>=this.colsPerSpread){let t=this.currentRow;this.newPageBreak(),this.currentRow=t}}walkNode(e){if(e)switch(e.type){case"body":this.walkChildren(e.children);break;case s.CONTENT_BLOCK:this.walkContentBlock(e);break;case s.PARAGRAPH:this.walkParagraph(e);break;case s.TEXT:this.walkText(e);break;case s.NEWLINE:case s.PARAGRAPH_BREAK:case s.COLUMN_BREAK:this.placeItem(e),this.advanceColumn();break;case s.JIAZHU:this.walkJiazhu(e);break;case s.SPACE:case s.NUOTAI:{let t=parseInt(e.value,10)||1;this.placeItem(e),this.advanceRows(t);break}case s.TAITOU:{this.advanceColumn();let t=parseInt(e.value,10)||0;this.currentRow=t,this.placeItem(e);break}case s.LIST:this.walkList(e);break;case s.LIST_ITEM:this.walkListItem(e);break;case s.MEIPI:case s.PIZHU:case s.STAMP:this.currentPage.floats.push(e);break;case s.EMPHASIS:case s.PROPER_NAME:case s.BOOK_TITLE:case s.INVERTED:case s.OCTAGON:case s.CIRCLED:case s.INVERTED_OCTAGON:case s.FIX:case s.DECORATE:this.placeItem(e),this.advanceRowsByNodeText(e);break;case s.SIDENOTE:this.placeItem(e);break;case s.TEXTBOX:case s.FILL_TEXTBOX:{this.placeItem(e);let t=parseInt(e.options?.height||e.options?.value||"1",10);this.advanceRows(t);break}case s.MATH:case s.SET_INDENT:this.placeItem(e);break;default:e.children&&e.children.length>0&&this.walkChildren(e.children);break}}walkContentBlock(e){for(let t of e.children)t.type===s.MEIPI||t.type===s.PIZHU||t.type===s.STAMP?this.currentPage.floats.push(t):this.walkNode(t)}walkParagraph(e){let t=parseInt(e.options?.indent||"0",10),n=this.currentIndent;this.currentIndent=t,this.placeMarker(d.PARAGRAPH_START,{paragraphNode:e}),this.walkChildren(e.children),this.placeMarker(d.PARAGRAPH_END),this.currentIndent=n}walkList(e){this.placeMarker(d.LIST_START);let t=!0;for(let n of e.children)n.type===s.LIST_ITEM?(this.walkListItem(n,t),t=!1):this.walkNode(n);this.placeMarker(d.LIST_END)}walkListItem(e,t=!1){t||this.advanceColumn(),this.placeMarker(d.LIST_ITEM_START),this.walkChildren(e.children),this.placeMarker(d.LIST_ITEM_END)}walkText(e){let t=[...e.value||""];this.placeItem(e),this.advanceRows(t.length)}advanceRowsByNodeText(e){let n=[...k(e.children||[])].length;this.advanceRows(n)}walkJiazhu(e){let t=e.children.some(u=>u.type!==s.TEXT),n=k(e.children),r=e.options?.align||"outward",a=this.effectiveRows,o=a-this.currentRow,h=o>0&&o<a?o:a;if(t){this.placeItem(e,{jiazhuSegments:null});let u=[...n].length;this.advanceRows(Math.ceil(u/2));return}let c=B(n,a,r,h);if(c.length<=1){this.placeItem(e,{jiazhuSegments:c});let u=[...n].length;this.advanceRows(Math.ceil(u/2));return}this.placeItem(e,{jiazhuSegments:[c[0]],jiazhuSegmentIndex:0,jiazhuTotalSegments:c.length}),this.advanceRows(h);for(let u=1;u<c.length;u++){let p=c[u],f=Math.max([...p.col1].length,[...p.col2].length);this.placeItem(e,{jiazhuSegments:[p],jiazhuSegmentIndex:u,jiazhuTotalSegments:c.length}),this.advanceRows(f)}}};function y(i){let e=N(i),{nRows:t,nCols:n}=P(e),r=new $(t,n);for(let h of i.children)h.type==="body"&&r.walkNode(h);let a=r.currentPage;a.halfBoundary===null&&(a.halfBoundary=a.items.length);let o={title:i.title||"",chapter:i.chapter||"",setupCommands:i.setupCommands||[]};return{pages:r.pages,gridConfig:{nRows:t,nCols:n},templateId:e,meta:o}}var re={content:{"font-size":"--wtc-font-size","line-height":"--wtc-line-height","letter-spacing":"--wtc-letter-spacing","font-color":"--wtc-font-color","border-color":"--wtc-border-color","border-thickness":"--wtc-border-thickness"},page:{"page-width":"--wtc-page-width","page-height":"--wtc-page-height","margin-top":"--wtc-margin-top","margin-bottom":"--wtc-margin-bottom","margin-left":"--wtc-margin-left","margin-right":"--wtc-margin-right",background:"--wtc-page-background"},banxin:{width:"--wtc-banxin-width","font-size":"--wtc-banxin-font-size"},jiazhu:{"font-size":"--wtc-jiazhu-font-size",color:"--wtc-jiazhu-color","line-height":"--wtc-jiazhu-line-height",gap:"--wtc-jiazhu-gap"},sidenode:{"font-size":"--wtc-sidenote-font-size",color:"--wtc-sidenote-color"},meipi:{"font-size":"--wtc-meipi-font-size",color:"--wtc-meipi-color"},pizhu:{"font-size":"--wtc-pizhu-font-size",color:"--wtc-pizhu-color"}};function m(i){return i.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")}var w=class{constructor(e){this.ast=e,this.templateId=N(e),this.meipiCount=0;let t=P(this.templateId);this.nRows=t.nRows,this.nCols=t.nCols,this.currentIndent=0,this.colPos=0}getSetupStylesFromCommands(e){let t=[];for(let n of e||[]){let r=re[n.setupType];if(!(!r||!n.params))for(let[a,o]of Object.entries(n.params)){let h=r[a];h&&t.push(`${h}: ${o}`)}}return t.length>0?` style="${t.join("; ")}"`:""}getSetupStyles(){return this.getSetupStylesFromCommands(this.ast.setupCommands)}render(){let e="";for(let t of this.ast.children)e+=this.renderNode(t);return e}renderPage(){let e=this.render();return`<!DOCTYPE html>
|
|
3
|
+
`){this.advance(),this.tokens.push({type:l.TEXT,value:" "});return}if(!te(e)){this.advance(),this.tokens.push({type:l.COMMAND,value:e});return}let t=O(e)||e==="@"||e==="*",s=b(e),r="";if(t){for(;this.pos<this.source.length&&(O(this.peek())||this.peek()==="@"||this.peek()==="*");)r+=this.advance();for(;this.pos<this.source.length&&this.source[this.pos]===" ";)this.pos++}else if(s)for(;this.pos<this.source.length&&b(this.peek());)r+=this.advance();r==="begin"?this.tokens.push({type:l.BEGIN,value:"begin"}):r==="end"?this.tokens.push({type:l.END,value:"end"}):this.tokens.push({type:l.COMMAND,value:r})}readMath(){this.advance();let e="";for(;this.pos<this.source.length;){if(this.peek()==="$"){this.advance(),this.tokens.push({type:l.MATH,value:e});return}e+=this.advance()}this.tokens.push({type:l.TEXT,value:"$"+e})}readText(){let e="";for(;this.pos<this.source.length;){let t=this.peek();if(t==="\\"||t==="{"||t==="}"||t==="["||t==="]"||t==="%"||t==="$")break;e+=this.advance()}if(e){let t=e.split(/\n[ \t]*\n/);for(let s=0;s<t.length;s++){s>0&&this.tokens.push({type:l.PARAGRAPH_BREAK,value:""});let r=t[s].replace(/[ \t]+/g," ");(r.trim()||r===" ")&&this.tokens.push({type:l.TEXT,value:r})}}}};var z={documentclass:{args:["optional","required"]},title:{args:["required"]},chapter:{args:["required"]},\u5939\u6CE8:{args:["optional","required"],node:"jiazhu"},JiaZhu:{alias:"\u5939\u6CE8"},\u5355\u884C\u5939\u6CE8:{args:["optional","required"],node:"jiazhu",single:!0},DanHangJiaZhu:{alias:"\u5355\u884C\u5939\u6CE8"},\u4FA7\u6279:{args:["optional","required"],node:"sidenote"},SideNode:{alias:"\u4FA7\u6279"},CePi:{alias:"\u4FA7\u6279"},\u7709\u6279:{args:["optional","required"],node:"meipi"},MeiPi:{alias:"\u7709\u6279"},\u6279\u6CE8:{args:["optional","required"],node:"pizhu"},PiZhu:{alias:"\u6279\u6CE8"},\u6587\u672C\u6846:{args:["optional","required"],node:"textbox"},TextBox:{alias:"\u6587\u672C\u6846"},\u586B\u5145\u6587\u672C\u6846:{args:["optional","required"],node:"fillTextbox"},FillTextBox:{alias:"\u586B\u5145\u6587\u672C\u6846"},\u5708\u70B9:{args:["optional","required"],node:"emphasis"},EmphasisMark:{alias:"\u5708\u70B9"},\u88C5\u9970:{args:["optional","required"],node:"decorate"},decorate:{alias:"\u88C5\u9970"},\u4E13\u540D\u53F7:{args:["optional","required"],node:"properName"},ProperNameMark:{alias:"\u4E13\u540D\u53F7"},\u4E66\u540D\u53F7:{args:["optional","required"],node:"bookTitle"},BookTitleMark:{alias:"\u4E66\u540D\u53F7"},\u4E0B\u5212\u7EBF:{alias:"\u4E13\u540D\u53F7"},Underline:{alias:"\u4E13\u540D\u53F7"},\u6CE2\u6D6A\u7EBF:{alias:"\u4E66\u540D\u53F7"},WavyUnderline:{alias:"\u4E66\u540D\u53F7"},\u53CD\u767D:{args:["required"],node:"inverted"},inverted:{alias:"\u53CD\u767D"},\u516B\u89D2\u6846:{args:["required"],node:"octagon"},octagon:{alias:"\u516B\u89D2\u6846"},\u5E26\u5708:{args:["required"],node:"circled"},circled:{alias:"\u5E26\u5708"},\u53CD\u767D\u516B\u89D2\u6846:{args:["required"],node:"invertedOctagon"},invertedOctagon:{alias:"\u53CD\u767D\u516B\u89D2\u6846"},\u6539:{args:["required"],node:"fix"},fix:{alias:"\u6539"},\u7A7A\u683C:{args:["optional"],node:"space"},Space:{alias:"\u7A7A\u683C"},\u8BBE\u7F6E\u7F29\u8FDB:{args:["required"],node:"setIndent"},SetIndent:{alias:"\u8BBE\u7F6E\u7F29\u8FDB"},\u6362\u884C:{args:[],node:"columnBreak"},\u62AC\u5934:{args:["optional"],node:"taitou"},\u5E73\u62AC:{args:[],node:"taitou",defaultOpt:"0"},\u5355\u62AC:{args:[],node:"taitou",defaultOpt:"1"},\u53CC\u62AC:{args:[],node:"taitou",defaultOpt:"2"},\u4E09\u62AC:{args:[],node:"taitou",defaultOpt:"3"},\u632A\u62AC:{args:["optional"],node:"nuotai"},\u7A7A\u62AC:{args:[],node:"nuotai",defaultOpt:"1"},\u76F8\u5BF9\u62AC\u5934:{args:["optional"],node:"relativeTaitou"},contentSetup:{args:["required"],node:"setupCmd",setupType:"content"},pageSetup:{args:["required"],node:"setupCmd",setupType:"page"},banxinSetup:{args:["required"],node:"setupCmd",setupType:"banxin"},sidenodeSetup:{args:["required"],node:"setupCmd",setupType:"sidenode"},jiazhuSetup:{args:["required"],node:"setupCmd",setupType:"jiazhu"},pizhuSetup:{args:["required"],node:"setupCmd",setupType:"pizhu"},meipiSetup:{args:["required"],node:"setupCmd",setupType:"meipi"},gujiSetup:{args:["required"],node:"setupCmd",setupType:"guji"},judouSetup:{args:["required"],node:"setupCmd",setupType:"judou"},\u53E5\u8BFB\u6A21\u5F0F:{args:["optional"],node:"setupCmd",setupType:"judou-on"},JudouOn:{alias:"\u53E5\u8BFB\u6A21\u5F0F"},\u6B63\u5E38\u6807\u70B9\u6A21\u5F0F:{args:["optional"],node:"setupCmd",setupType:"judou-off"},JudouOff:{alias:"\u6B63\u5E38\u6807\u70B9\u6A21\u5F0F"},\u65E0\u6807\u70B9\u6A21\u5F0F:{args:["optional"],node:"setupCmd",setupType:"judou-none"},NonePunctuationMode:{alias:"\u65E0\u6807\u70B9\u6A21\u5F0F"},usepackage:{args:["optional","required"],ignore:!0},RequirePackage:{alias:"usepackage"},setmainfont:{args:["optional","required"],ignore:!0},pagestyle:{args:["required"],ignore:!0},noindent:{args:[],ignore:!0},par:{args:[],ignore:!0},relax:{args:[],ignore:!0},ignorespaces:{args:[],ignore:!0},definecolor:{args:["required","required","required"],ignore:!0},AddToHook:{args:["required","required"],ignore:!0},\u7981\u7528\u5206\u9875\u88C1\u526A:{args:[],ignore:!0},\u663E\u793A\u5750\u6807:{args:[],ignore:!0},LtcDebugOn:{args:[],ignore:!0},LtcDebugOff:{args:[],ignore:!0},\u5370\u7AE0:{args:["optional","required"],node:"stamp"}},H={document:{node:"body"},\u6B63\u6587:{node:"contentBlock"},BodyText:{alias:"\u6B63\u6587"},\u6BB5\u843D:{node:"paragraph",hasOptions:!0},Paragraph:{alias:"\u6BB5\u843D"},\u5217\u8868:{node:"list"},\u5939\u6CE8\u73AF\u5883:{node:"jiazhu"},JiaZhuEnv:{alias:"\u5939\u6CE8\u73AF\u5883"}};function j(i){let e=z[i],t=new Set;for(;e&&e.alias&&!t.has(e.alias);)t.add(i),i=e.alias,e=z[i];return e||null}function q(i){let e=H[i],t=new Set;for(;e&&e.alias&&!t.has(e.alias);)t.add(i),i=e.alias,e=H[i];return e||null}var n={DOCUMENT:"document",CONTENT_BLOCK:"contentBlock",PARAGRAPH:"paragraph",TEXT:"text",NEWLINE:"newline",JIAZHU:"jiazhu",SIDENOTE:"sidenote",MEIPI:"meipi",PIZHU:"pizhu",TEXTBOX:"textbox",FILL_TEXTBOX:"fillTextbox",SPACE:"space",COLUMN_BREAK:"columnBreak",TAITOU:"taitou",NUOTAI:"nuotai",SET_INDENT:"setIndent",EMPHASIS:"emphasis",PROPER_NAME:"properName",BOOK_TITLE:"bookTitle",INVERTED:"inverted",OCTAGON:"octagon",CIRCLED:"circled",INVERTED_OCTAGON:"invertedOctagon",FIX:"fix",DECORATE:"decorate",LIST:"list",LIST_ITEM:"listItem",SETUP:"setup",STAMP:"stamp",MATH:"math",PARAGRAPH_BREAK:"paragraphBreak",UNKNOWN:"unknown"};function g(i,e={}){return{type:i,children:[],...e}}function C(i){if(!i||!i.trim())return{};let e={},t=0,s="",r="",a=!1;for(let o=0;o<i.length;o++){let h=i[o];if(h==="{"&&t++,h==="}"&&t--,t===0&&h===","){s.trim()&&(e[s.trim()]=a?r.trim():"true"),s="",r="",a=!1;continue}else t===0&&h==="="&&!a?a=!0:a?r+=h:s+=h}return s.trim()&&(a?e[s.trim()]=r.trim():e[s.trim()]="true"),e}var A=class i{constructor(e){this.tokens=e,this.pos=0,this.warnings=[]}peek(){return this.pos>=this.tokens.length?{type:l.EOF,value:""}:this.tokens[this.pos]}advance(){let e=this.tokens[this.pos];return this.pos++,e}expect(e){let t=this.peek();return t.type!==e?(this.warnings.push(`Expected ${e} but got ${t.type} ("${t.value}") at token ${this.pos}`),null):this.advance()}readBraceGroup(){if(this.peek().type!==l.OPEN_BRACE)return"";this.advance();let e="",t=1;for(;this.pos<this.tokens.length&&t>0;){let s=this.peek();if(s.type===l.OPEN_BRACE)t++,e+="{",this.advance();else if(s.type===l.CLOSE_BRACE)t--,t>0&&(e+="}"),this.advance();else{if(s.type===l.EOF)break;e+=s.value,this.advance()}}return e}readBracketGroup(){if(this.peek().type!==l.OPEN_BRACKET)return null;this.advance();let e="",t=1;for(;this.pos<this.tokens.length&&t>0;){let s=this.peek();if(s.type===l.OPEN_BRACKET)t++,e+="[",this.advance();else if(s.type===l.CLOSE_BRACKET)t--,t>0&&(e+="]"),this.advance();else{if(s.type===l.EOF)break;e+=s.value,this.advance()}}return e}readBraceGroupAsNodes(){if(this.peek().type!==l.OPEN_BRACE)return[];this.advance();let e=[];for(;this.pos<this.tokens.length;){let t=this.peek();if(t.type===l.CLOSE_BRACE){this.advance();break}if(t.type===l.EOF)break;let s=this.parseToken();s&&e.push(s)}return e}parseCommandArgs(e){let t=null,s=[];if(!e.args)return{optionalArg:t,requiredArgs:s};for(let r of e.args)if(r==="optional")t=this.readBracketGroup();else if(r==="required"){let a=this.readBraceGroup();s.push(a)}return{optionalArg:t,requiredArgs:s}}parse(){let e=g(n.DOCUMENT);for(e.template="",e.documentClass="",e.title="",e.chapter="",e.setupCommands=[];this.pos<this.tokens.length&&this.peek().type!==l.EOF;){let s=this.parseToken(e);s&&e.children.push(s)}return e}parseToken(e){let t=this.peek();switch(t.type){case l.TEXT:return this.advance(),g(n.TEXT,{value:t.value});case l.NEWLINE:return this.advance(),g(n.NEWLINE);case l.MATH:return this.advance(),g(n.MATH,{value:t.value});case l.PARAGRAPH_BREAK:return this.advance(),g(n.PARAGRAPH_BREAK);case l.COMMAND:return this.parseCommand(e);case l.BEGIN:return this.parseEnvironment(e);case l.END:return null;case l.OPEN_BRACE:return this.parseBareGroup();default:return this.advance(),null}}parseBareGroup(){let e=this.readBraceGroupAsNodes();if(e.length===0)return null;if(e.length===1)return e[0];let t=g("group");return t.children=e,t}parseCommand(e){let s=this.advance().value,r=j(s);if(s==="documentclass"){let p=this.readBracketGroup(),f=this.readBraceGroup();return e&&(e.documentClass=f,e.template=p||""),null}if(s==="title"){let p=this.readBraceGroup();return e&&(e.title=p),null}if(s==="chapter"){let p=this.readBraceGroup();return e&&(e.chapter=p),null}if(s==="item")return g(n.LIST_ITEM);if(!r){this.warnings.push(`Unknown command: \\${s} at token ${this.pos}`);let p="";return this.peek().type===l.OPEN_BRACE&&(p=this.readBraceGroup()),g(n.TEXT,{value:p})}if(r.ignore)return this.parseCommandArgs(r),null;if(r.node==="setupCmd"){let{optionalArg:p,requiredArgs:f}=this.parseCommandArgs(r),T=C(f[0]||p||""),R=g(n.SETUP,{setupType:r.setupType,params:T});return e&&e.setupCommands.push(R),null}let{optionalArg:a,requiredArgs:o}=this.parseCommandArgs(r),h=C(a||""),c=this.mapNodeType(r.node),u=g(c,{options:h});if(r.defaultOpt!==void 0&&a===null&&(u.options={value:r.defaultOpt}),o.length>0&&r.node!=="stamp"){let{Tokenizer:p}=se(),f=new p(o[0]).tokenize(),T=new i(f);for(;T.pos<T.tokens.length&&T.peek().type!==l.EOF;){let x=T.parseToken();x&&u.children.push(x)}}return(r.node==="space"||r.node==="taitou"||r.node==="nuotai"||r.node==="relativeTaitou")&&(u.value=a||r.defaultOpt||"1"),r.node==="setIndent"&&(u.value=o[0]||"0"),r.node==="stamp"&&(u.options=C(a||""),u.src=o[0]||""),u}parseEnvironment(e){this.advance();let t=this.readBraceGroup(),s=q(t);if(!s){this.warnings.push(`Unknown environment: ${t}`);let h=this.parseUntilEnd(t,e),c=g(n.UNKNOWN,{envName:t});return c.children=h,c}let r={};if(s.hasOptions){let h=this.readBracketGroup();h&&(r=C(h))}let a=this.mapNodeType(s.node),o=g(a,{options:r});return s.node==="body"?(o.children=this.parseUntilEnd(t,e),o):(o.children=this.parseUntilEnd(t,e),s.node==="list"&&(o.children=this.groupListItems(o.children)),o)}parseUntilEnd(e,t){let s=[];for(;this.pos<this.tokens.length;){let r=this.peek();if(r.type===l.EOF){this.warnings.push(`Unclosed environment: ${e}`);break}if(r.type===l.END){this.advance();let o=this.readBraceGroup();if(o===e)break;this.warnings.push(`Mismatched \\end{${o}}, expected \\end{${e}}`);continue}let a=this.parseToken(t);a&&s.push(a)}return s}groupListItems(e){let t=[],s=null;for(let r of e)r.type===n.LIST_ITEM?(s=g(n.LIST_ITEM),t.push(s)):(s||(s=g(n.LIST_ITEM),t.push(s)),s.children.push(r));return t}mapNodeType(e){return{contentBlock:n.CONTENT_BLOCK,paragraph:n.PARAGRAPH,jiazhu:n.JIAZHU,sidenote:n.SIDENOTE,meipi:n.MEIPI,pizhu:n.PIZHU,textbox:n.TEXTBOX,fillTextbox:n.FILL_TEXTBOX,space:n.SPACE,columnBreak:n.COLUMN_BREAK,taitou:n.TAITOU,nuotai:n.NUOTAI,setIndent:n.SET_INDENT,emphasis:n.EMPHASIS,properName:n.PROPER_NAME,bookTitle:n.BOOK_TITLE,inverted:n.INVERTED,octagon:n.OCTAGON,circled:n.CIRCLED,invertedOctagon:n.INVERTED_OCTAGON,fix:n.FIX,decorate:n.DECORATE,list:n.LIST,body:"body",stamp:n.STAMP,relativeTaitou:n.TAITOU}[e]||n.UNKNOWN}},I=null;function se(){return I||(I={Tokenizer:null}),I}function G(i){I||(I={}),I.Tokenizer=i}G(v);function E(i){let t=new v(i).tokenize(),s=new A(t);return{ast:s.parse(),warnings:s.warnings}}var D={\u56DB\u5E93\u5168\u4E66:"siku-quanshu",\u56DB\u5EAB\u5168\u66F8:"siku-quanshu",\u56DB\u5E93\u5168\u4E66\u5F69\u8272:"siku-quanshu-colored",\u56DB\u5EAB\u5168\u66F8\u5F69\u8272:"siku-quanshu-colored",\u7EA2\u697C\u68A6\u7532\u620C\u672C:"honglou",\u7D05\u6A13\u5922\u7532\u620C\u672C:"honglou",\u6781\u7B80:"minimal",\u6975\u7C21:"minimal",default:"siku-quanshu"},ne={"siku-quanshu":{nRows:21,nCols:8},"siku-quanshu-colored":{nRows:21,nCols:8},honglou:{nRows:20,nCols:9},minimal:{nRows:21,nCols:8}};function N(i){let e=D[i.template]||"siku-quanshu";for(let t of i.setupCommands||[])if(t.setupType==="guji"&&t.params?.template){let s=D[t.params.template];s&&(e=s)}return e}function P(i){return ne[i]||{nRows:21,nCols:8}}function k(i){let e="";for(let t of i)t.type===n.TEXT?e+=t.value:t.children&&t.children.length>0&&(e+=k(t.children));return e}function M(i,e="outward"){let t=[...i];if(t.length===0)return{col1:"",col2:""};if(t.length===1)return{col1:t[0],col2:""};let s=e==="inward"?Math.floor(t.length/2):Math.ceil(t.length/2);return{col1:t.slice(0,s).join(""),col2:t.slice(s).join("")}}function _(i,e=20,t="outward",s=0){let r=s>0?s:e,a=[...i],o=r*2;if(a.length<=o)return[M(i,t)];let h=[],c=a.slice(0,o).join("");h.push(M(c,t));let u=e*2;for(let p=o;p<a.length;p+=u){let f=a.slice(p,p+u).join("");h.push(M(f,t))}return h}var d={PARAGRAPH_START:"_paragraphStart",PARAGRAPH_END:"_paragraphEnd",LIST_START:"_listStart",LIST_END:"_listEnd",LIST_ITEM_START:"_listItemStart",LIST_ITEM_END:"_listItemEnd"};function X(){return{items:[],floats:[],halfBoundary:null}}var $=class{constructor(e,t){this.nRows=e,this.nCols=t,this.colsPerSpread=2*t,this.currentCol=0,this.currentRow=0,this.currentIndent=0,this.pages=[X()]}get currentPage(){return this.pages[this.pages.length-1]}get effectiveRows(){return this.nRows-this.currentIndent}checkHalfBoundary(){this.currentPage.halfBoundary===null&&this.currentCol>=this.nCols&&(this.currentPage.halfBoundary=this.currentPage.items.length)}advanceColumn(){this.currentCol++,this.currentRow=0,this.checkHalfBoundary(),this.currentCol>=this.colsPerSpread&&this.newPageBreak()}newPageBreak(){this.currentPage.halfBoundary===null&&(this.currentPage.halfBoundary=this.currentPage.items.length),this.pages.push(X()),this.currentCol=0,this.currentRow=0}placeItem(e,t={}){this.checkHalfBoundary(),this.currentPage.items.push({node:e,col:this.currentCol,row:this.currentRow,indent:this.currentIndent,...t})}placeMarker(e,t={}){this.checkHalfBoundary(),this.currentPage.items.push({node:{type:e},col:this.currentCol,row:this.currentRow,indent:this.currentIndent,...t})}walkChildren(e){for(let t of e)this.walkNode(t)}advanceRows(e){for(this.currentRow+=e;this.currentRow>=this.effectiveRows;)if(this.currentRow-=this.effectiveRows,this.currentCol++,this.checkHalfBoundary(),this.currentCol>=this.colsPerSpread){let t=this.currentRow;this.newPageBreak(),this.currentRow=t}}walkNode(e){if(e)switch(e.type){case"body":this.walkChildren(e.children);break;case n.CONTENT_BLOCK:this.walkContentBlock(e);break;case n.PARAGRAPH:this.walkParagraph(e);break;case n.TEXT:this.walkText(e);break;case n.NEWLINE:case n.PARAGRAPH_BREAK:case n.COLUMN_BREAK:this.placeItem(e),this.advanceColumn();break;case n.JIAZHU:this.walkJiazhu(e);break;case n.SPACE:case n.NUOTAI:{let t=parseInt(e.value,10)||1;this.placeItem(e),this.advanceRows(t);break}case n.TAITOU:{this.advanceColumn();let t=parseInt(e.value,10)||0;this.currentRow=t,this.placeItem(e);break}case n.LIST:this.walkList(e);break;case n.LIST_ITEM:this.walkListItem(e);break;case n.MEIPI:case n.PIZHU:case n.STAMP:this.currentPage.floats.push(e);break;case n.EMPHASIS:case n.PROPER_NAME:case n.BOOK_TITLE:case n.INVERTED:case n.OCTAGON:case n.CIRCLED:case n.INVERTED_OCTAGON:case n.FIX:case n.DECORATE:this.placeItem(e),this.advanceRowsByNodeText(e);break;case n.SIDENOTE:this.placeItem(e);break;case n.TEXTBOX:case n.FILL_TEXTBOX:{this.placeItem(e);let t=parseInt(e.options?.height||e.options?.value||"1",10);this.advanceRows(t);break}case n.MATH:case n.SET_INDENT:this.placeItem(e);break;default:e.children&&e.children.length>0&&this.walkChildren(e.children);break}}walkContentBlock(e){for(let t of e.children)t.type===n.MEIPI||t.type===n.PIZHU||t.type===n.STAMP?this.currentPage.floats.push(t):this.walkNode(t)}walkParagraph(e){let t=parseInt(e.options?.indent||"0",10),s=this.currentIndent;this.currentIndent=t,this.placeMarker(d.PARAGRAPH_START,{paragraphNode:e}),this.walkChildren(e.children),this.placeMarker(d.PARAGRAPH_END),this.currentIndent=s}walkList(e){this.placeMarker(d.LIST_START);let t=!0;for(let s of e.children)s.type===n.LIST_ITEM?(this.walkListItem(s,t),t=!1):this.walkNode(s);this.placeMarker(d.LIST_END)}walkListItem(e,t=!1){t||this.advanceColumn(),this.placeMarker(d.LIST_ITEM_START,{isFirstListItem:t}),this.walkChildren(e.children),this.placeMarker(d.LIST_ITEM_END)}walkText(e){let t=[...e.value||""];this.placeItem(e),this.advanceRows(t.length)}advanceRowsByNodeText(e){let s=[...k(e.children||[])].length;this.advanceRows(s)}walkJiazhu(e){let t=e.children.some(u=>u.type!==n.TEXT),s=k(e.children),r=e.options?.align||"outward",a=this.effectiveRows,o=a-this.currentRow,h=o>0&&o<a?o:a;if(t){this.placeItem(e,{jiazhuSegments:null});let u=[...s].length;this.advanceRows(Math.ceil(u/2));return}let c=_(s,a,r,h);if(c.length<=1){this.placeItem(e,{jiazhuSegments:c});let u=[...s].length;this.advanceRows(Math.ceil(u/2));return}this.placeItem(e,{jiazhuSegments:[c[0]],jiazhuSegmentIndex:0,jiazhuTotalSegments:c.length}),this.advanceRows(h);for(let u=1;u<c.length;u++){let p=c[u],f=Math.max([...p.col1].length,[...p.col2].length);this.placeItem(e,{jiazhuSegments:[p],jiazhuSegmentIndex:u,jiazhuTotalSegments:c.length}),this.advanceRows(f)}}};function y(i){let e=N(i),{nRows:t,nCols:s}=P(e),r=new $(t,s);for(let h of i.children)h.type==="body"&&r.walkNode(h);let a=r.currentPage;a.halfBoundary===null&&(a.halfBoundary=a.items.length);let o={title:i.title||"",chapter:i.chapter||"",setupCommands:i.setupCommands||[]};return{pages:r.pages,gridConfig:{nRows:t,nCols:s},templateId:e,meta:o}}var re={content:{"font-size":"--wtc-font-size","line-height":"--wtc-line-height","letter-spacing":"--wtc-letter-spacing","font-color":"--wtc-font-color","border-color":"--wtc-border-color","border-thickness":"--wtc-border-thickness"},page:{"page-width":"--wtc-page-width","page-height":"--wtc-page-height","margin-top":"--wtc-margin-top","margin-bottom":"--wtc-margin-bottom","margin-left":"--wtc-margin-left","margin-right":"--wtc-margin-right",background:"--wtc-page-background"},banxin:{width:"--wtc-banxin-width","font-size":"--wtc-banxin-font-size"},jiazhu:{"font-size":"--wtc-jiazhu-font-size",color:"--wtc-jiazhu-color","line-height":"--wtc-jiazhu-line-height",gap:"--wtc-jiazhu-gap"},sidenode:{"font-size":"--wtc-sidenote-font-size",color:"--wtc-sidenote-color"},meipi:{"font-size":"--wtc-meipi-font-size",color:"--wtc-meipi-color"},pizhu:{"font-size":"--wtc-pizhu-font-size",color:"--wtc-pizhu-color"}};function m(i){return i.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")}var w=class{constructor(e){this.ast=e,this.templateId=N(e),this.meipiCount=0;let t=P(this.templateId);this.nRows=t.nRows,this.nCols=t.nCols,this.currentIndent=0,this.colPos=0}getSetupStylesFromCommands(e){let t=[];for(let s of e||[]){let r=re[s.setupType];if(!(!r||!s.params))for(let[a,o]of Object.entries(s.params)){let h=r[a];h&&t.push(`${h}: ${o}`)}}return t.length>0?` style="${t.join("; ")}"`:""}getSetupStyles(){return this.getSetupStylesFromCommands(this.ast.setupCommands)}render(){let e="";for(let t of this.ast.children)e+=this.renderNode(t);return e}renderPage(){let e=this.render();return`<!DOCTYPE html>
|
|
4
4
|
<html lang="zh">
|
|
5
5
|
<head>
|
|
6
6
|
<meta charset="UTF-8">
|
|
@@ -13,10 +13,10 @@ var WebTeX=(()=>{var S=Object.defineProperty;var W=Object.getOwnPropertyDescript
|
|
|
13
13
|
${e}
|
|
14
14
|
</div>
|
|
15
15
|
</body>
|
|
16
|
-
</html>`}renderFromLayout(e){let t=this.getSetupStylesFromCommands(e.meta.setupCommands),
|
|
16
|
+
</html>`}renderFromLayout(e){let t=this.getSetupStylesFromCommands(e.meta.setupCommands),s=this.renderBanxinFromMeta(e.meta),r=[];return e.pages.map(a=>{let o=a.halfBoundary??a.items.length,h=a.items.slice(0,o),c=a.items.slice(o),u=this.renderLayoutItems(h,r),p=this.renderLayoutItems(c,u.openStack);r=p.openStack;let f=u.html,T=p.html,R=a.floats.map(x=>this.renderNode(x)).join(`
|
|
17
17
|
`);return`<div class="wtc-spread"${t}>
|
|
18
|
-
${R}<div class="wtc-half-page wtc-half-right"><div class="wtc-content-border"><div class="wtc-content">${f}</div></div></div>${
|
|
19
|
-
</div>`})}markerOpenTag(e){let t=e.node.type;if(t===d.PARAGRAPH_START){let
|
|
18
|
+
${R}<div class="wtc-half-page wtc-half-right"><div class="wtc-content-border"><div class="wtc-content">${f}</div></div></div>${s}<div class="wtc-half-page wtc-half-left"><div class="wtc-content-border"><div class="wtc-content">${T}</div></div></div>
|
|
19
|
+
</div>`})}markerOpenTag(e){let t=e.node.type;if(t===d.PARAGRAPH_START){let s=parseInt(e.paragraphNode?.options?.indent||"0",10);return s>0?`<span class="wtc-paragraph wtc-paragraph-indent" style="--wtc-paragraph-indent: calc(${s} * var(--wtc-grid-height)); --wtc-paragraph-indent-height: calc((var(--wtc-n-rows) - ${s}) * var(--wtc-grid-height))">`:'<span class="wtc-paragraph">'}return t===d.LIST_START?'<span class="wtc-list">':t===d.LIST_ITEM_START?'<span class="wtc-list-item">':""}markerCloseTag(e){return e===d.PARAGRAPH_START||e===d.LIST_START||e===d.LIST_ITEM_START?"</span>":""}isOpenMarker(e){return e===d.PARAGRAPH_START||e===d.LIST_START||e===d.LIST_ITEM_START}matchingOpenMarker(e){return e===d.PARAGRAPH_END?d.PARAGRAPH_START:e===d.LIST_END?d.LIST_START:e===d.LIST_ITEM_END?d.LIST_ITEM_START:null}renderLayoutItems(e,t=[]){let s="";for(let o of t)s+=this.markerOpenTag(o);let r=[...t];for(let o of e){let h=o.node.type;if(this.isOpenMarker(h))h===d.LIST_ITEM_START&&!o.isFirstListItem&&(s+='<br class="wtc-newline">'),s+=this.markerOpenTag(o),r.push(o);else if(this.matchingOpenMarker(h)){s+=this.markerCloseTag(this.matchingOpenMarker(h));for(let c=r.length-1;c>=0;c--)if(r[c].node.type===this.matchingOpenMarker(h)){r.splice(c,1);break}}else s+=this.renderLayoutItem(o)}let a=[...r];for(let o=r.length-1;o>=0;o--)s+=this.markerCloseTag(r[o].node.type);return{html:s,openStack:a}}renderLayoutItem(e){return e.jiazhuSegments&&e.node.type===n.JIAZHU?this.renderJiazhuFromSegments(e.node,e.jiazhuSegments):this.renderNode(e.node)}renderJiazhuFromSegments(e,t){return e.children.some(r=>r.type!==n.TEXT)?this.renderJiazhuComplex(e):t.map(({col1:r,col2:a})=>`<span class="wtc-jiazhu"><span class="wtc-jiazhu-col">${m(r)}</span><span class="wtc-jiazhu-col">${m(a)}</span></span>`).join("")}renderBanxinFromMeta(e){if(!e.title&&!e.chapter)return"";let t=m(e.title||""),r=(e.chapter||"").split(/\\\\|\n/).map(a=>a.trim()).filter(Boolean).map(a=>`<span class="wtc-banxin-chapter-part">${m(a)}</span>`).join("");return`<div class="wtc-banxin">
|
|
20
20
|
<div class="wtc-banxin-section wtc-banxin-upper">
|
|
21
21
|
<span class="wtc-banxin-book-name">${t}</span>
|
|
22
22
|
<div class="wtc-yuwei wtc-yuwei-upper"></div>
|
|
@@ -27,20 +27,20 @@ ${R}<div class="wtc-half-page wtc-half-right"><div class="wtc-content-border"><d
|
|
|
27
27
|
<div class="wtc-banxin-section wtc-banxin-lower">
|
|
28
28
|
<div class="wtc-yuwei wtc-yuwei-lower"></div>
|
|
29
29
|
</div>
|
|
30
|
-
</div>`}renderNode(e){if(!e)return"";switch(e.type){case"body":return this.renderChildren(e.children);case
|
|
30
|
+
</div>`}renderNode(e){if(!e)return"";switch(e.type){case"body":return this.renderChildren(e.children);case n.CONTENT_BLOCK:return this.renderContentBlock(e);case n.PARAGRAPH:return this.renderParagraph(e);case n.TEXT:{let t=e.value||"";return this.colPos+=[...t].length,m(t)}case n.NEWLINE:return this.colPos=0,'<br class="wtc-newline">';case n.MATH:return`<span class="wtc-math">${m(e.value||"")}</span>`;case n.PARAGRAPH_BREAK:return this.colPos=0,'<br class="wtc-paragraph-break">';case n.JIAZHU:return this.renderJiazhu(e);case n.SIDENOTE:return this.renderSidenote(e);case n.MEIPI:return this.renderMeipi(e);case n.PIZHU:return this.renderPizhu(e);case n.TEXTBOX:return this.renderTextbox(e);case n.FILL_TEXTBOX:return this.renderFillTextbox(e);case n.SPACE:return this.renderSpace(e);case n.COLUMN_BREAK:return this.colPos=0,'<br class="wtc-column-break">';case n.TAITOU:return this.renderTaitou(e);case n.NUOTAI:return this.renderNuotai(e);case n.SET_INDENT:return`<span class="wtc-set-indent" data-indent="${e.value||0}"></span>`;case n.EMPHASIS:return`<span class="wtc-emphasis">${this.renderChildren(e.children)}</span>`;case n.PROPER_NAME:return`<span class="wtc-proper-name">${this.renderChildren(e.children)}</span>`;case n.BOOK_TITLE:return`<span class="wtc-book-title-mark">${this.renderChildren(e.children)}</span>`;case n.INVERTED:return`<span class="wtc-inverted">${this.renderChildren(e.children)}</span>`;case n.OCTAGON:return`<span class="wtc-octagon">${this.renderChildren(e.children)}</span>`;case n.CIRCLED:return`<span class="wtc-circled">${this.renderChildren(e.children)}</span>`;case n.INVERTED_OCTAGON:return`<span class="wtc-inverted wtc-octagon">${this.renderChildren(e.children)}</span>`;case n.FIX:return`<span class="wtc-fix">${this.renderChildren(e.children)}</span>`;case n.DECORATE:return`<span class="wtc-decorate">${this.renderChildren(e.children)}</span>`;case n.LIST:return this.renderList(e);case n.LIST_ITEM:return`<div class="wtc-list-item">${this.renderChildren(e.children)}</div>`;case n.STAMP:return this.renderStamp(e);default:return e.children&&e.children.length>0?this.renderChildren(e.children):""}}renderChildren(e){return e.map(t=>this.renderNode(t)).join("")}renderContentBlock(e){let t=[],s=[];for(let c of e.children)c.type===n.MEIPI||c.type===n.PIZHU||c.type===n.STAMP?t.push(this.renderNode(c)):s.push(c);let r=s.map(c=>this.renderNode(c)).join(""),a=t.join(`
|
|
31
31
|
`),o=this.renderBanxin();return`<div class="wtc-spread"${this.getSetupStyles()}>
|
|
32
32
|
${a}<div class="wtc-half-page wtc-half-right"><div class="wtc-content-border"><div class="wtc-content">${r}</div></div></div>${o}<div class="wtc-half-page wtc-half-left"><div class="wtc-content-border"><div class="wtc-content"></div></div></div>
|
|
33
|
-
</div>`}renderBanxin(){if(!this.ast.title&&!this.ast.chapter)return"";let e=m(this.ast.title||""),
|
|
33
|
+
</div>`}renderBanxin(){if(!this.ast.title&&!this.ast.chapter)return"";let e=m(this.ast.title||""),s=(this.ast.chapter||"").split(/\\\\|\n/).map(r=>r.trim()).filter(Boolean).map(r=>`<span class="wtc-banxin-chapter-part">${m(r)}</span>`).join("");return`<div class="wtc-banxin">
|
|
34
34
|
<div class="wtc-banxin-section wtc-banxin-upper">
|
|
35
35
|
<span class="wtc-banxin-book-name">${e}</span>
|
|
36
36
|
<div class="wtc-yuwei wtc-yuwei-upper"></div>
|
|
37
37
|
</div>
|
|
38
38
|
<div class="wtc-banxin-section wtc-banxin-middle">
|
|
39
|
-
<div class="wtc-banxin-chapter">${
|
|
39
|
+
<div class="wtc-banxin-chapter">${s}</div>
|
|
40
40
|
</div>
|
|
41
41
|
<div class="wtc-banxin-section wtc-banxin-lower">
|
|
42
42
|
<div class="wtc-yuwei wtc-yuwei-lower"></div>
|
|
43
43
|
</div>
|
|
44
|
-
</div>`}renderParagraph(e){let t=parseInt(e.options?.indent||"0",10);if(t>0){let
|
|
45
|
-
`)}function U(i){let{ast:e,warnings:t}=E(i);return t.length>0&&console.warn("[WebTeX-CN] Parse warnings:",t),new w(e).renderPage()}function
|
|
46
|
-
`)}async function K(i,e,t={}){let
|
|
44
|
+
</div>`}renderParagraph(e){let t=parseInt(e.options?.indent||"0",10);if(t>0){let s=this.currentIndent;this.currentIndent=t;let r=this.renderChildren(e.children);return this.currentIndent=s,`<span class="wtc-paragraph wtc-paragraph-indent" style="--wtc-paragraph-indent: calc(${t} * var(--wtc-grid-height)); --wtc-paragraph-indent-height: calc((var(--wtc-n-rows) - ${t}) * var(--wtc-grid-height))">${r}</span>`}return`<span class="wtc-paragraph">${this.renderChildren(e.children)}</span>`}renderJiazhu(e){if(e.children.some(f=>f.type!==n.TEXT))return this.renderJiazhuComplex(e);let s=k(e.children),r=e.options?.align||"outward",a=this.nRows-this.currentIndent,o=a-this.colPos%a,h=o>0&&o<a?o:a,c=_(s,a,r,h),u=[...s].length,p=h*2;if(u<=p)this.colPos+=Math.ceil(u/2);else{let f=c[c.length-1];this.colPos=Math.max([...f.col1].length,[...f.col2].length)}return c.map(({col1:f,col2:T})=>`<span class="wtc-jiazhu"><span class="wtc-jiazhu-col">${m(f)}</span><span class="wtc-jiazhu-col">${m(T)}</span></span>`).join("")}renderJiazhuComplex(e){let t=k(e.children),s=Math.ceil([...t].length/2),r=0,a=e.children.length;for(let c=0;c<e.children.length;c++){let u=k([e.children[c]]);if(r+=[...u].length,r>=s){a=c+1;break}}let o=e.children.slice(0,a).map(c=>this.renderNode(c)).join(""),h=e.children.slice(a).map(c=>this.renderNode(c)).join("");return`<span class="wtc-jiazhu"><span class="wtc-jiazhu-col">${o}</span><span class="wtc-jiazhu-col">${h}</span></span>`}renderSidenote(e){let t=e.options||{},s=this.buildStyleFromOptions(t,{color:"--wtc-sidenote-color","font-size":"--wtc-sidenote-font-size"});return t.yoffset&&(s+=`margin-block-start: ${t.yoffset};`),`<span class="wtc-sidenote"${s?` style="${s}"`:""}>${this.renderChildren(e.children)}</span>`}renderMeipi(e){let t=e.options||{},s="";if(t.x)s+=`right: ${t.x};`;else{let r=this.meipiCount*2;s+=`right: ${r}em;`,this.meipiCount++}return t.y&&(s+=`top: ${t.y};`),t.height&&(s+=`height: ${t.height};`),t.color&&(s+=`color: ${this.parseColor(t.color)};`),t["font-size"]&&(s+=`font-size: ${t["font-size"]};`),`<div class="wtc-meipi"${s?` style="${s}"`:""}>${this.renderChildren(e.children)}</div>`}renderPizhu(e){let t=e.options||{},s="";return t.x&&(s+=`right: ${t.x};`),t.y&&(s+=`top: ${t.y};`),t.color&&(s+=`color: ${this.parseColor(t.color)};`),t["font-size"]&&(s+=`font-size: ${t["font-size"]};`),`<div class="wtc-pizhu"${s?` style="${s}"`:""}>${this.renderChildren(e.children)}</div>`}renderTextbox(e){let t=e.options||{},s="";if(t.height){let r=t.height;/^\d+$/.test(r)?s+=`--wtc-textbox-height: ${r};`:s+=`inline-size: ${r};`}return t.border==="true"&&(s+="border: 1px solid var(--wtc-border-color);"),t["background-color"]&&(s+=`background-color: ${this.parseColor(t["background-color"])};`),t["font-color"]&&(s+=`color: ${this.parseColor(t["font-color"])};`),t["font-size"]&&(s+=`font-size: ${t["font-size"]};`),`<span class="wtc-textbox"${s?` style="${s}"`:""}>${this.renderChildren(e.children)}</span>`}renderFillTextbox(e){let t=e.options||{},s="";return t.height&&(s+=`--wtc-textbox-height: ${t.height};`),t.value&&/^\d+$/.test(t.value)&&(s+=`--wtc-textbox-height: ${t.value};`),`<span class="wtc-textbox wtc-textbox-fill"${s?` style="${s}"`:""}>${this.renderChildren(e.children)}</span>`}renderSpace(e){let t=parseInt(e.value,10)||1;return"\u3000".repeat(t)}renderTaitou(e){return`<br class="wtc-newline"><span class="wtc-taitou" data-level="${e.value||"0"}"></span>`}renderNuotai(e){let t=parseInt(e.value,10)||1;return"\u3000".repeat(t)}renderList(e){return`<div class="wtc-list">${this.renderChildren(e.children)}</div>`}renderStamp(e){let t=e.options||{},s="position: absolute;";return t.xshift&&(s+=`right: ${t.xshift};`),t.yshift&&(s+=`top: ${t.yshift};`),t.width&&(s+=`width: ${t.width};`),t.opacity&&(s+=`opacity: ${t.opacity};`),`<img class="wtc-stamp" src="${m(e.src||"")}" style="${s}" alt="stamp">`}parseColor(e){if(!e)return"inherit";if(e=e.replace(/[{}]/g,"").trim(),/^[a-zA-Z]+$/.test(e))return e;let t=e.split(/[\s,]+/).map(Number);if(t.length===3){if(t.every(s=>s>=0&&s<=1))return`rgb(${Math.round(t[0]*255)}, ${Math.round(t[1]*255)}, ${Math.round(t[2]*255)})`;if(t.every(s=>s>=0&&s<=255))return`rgb(${t[0]}, ${t[1]}, ${t[2]})`}return e}buildStyleFromOptions(e,t){if(!e)return"";let s="";for(let[r,a]of Object.entries(t))e[r]&&a&&(s+=`${a}: ${e[r]};`);return s}};function F(i){let{ast:e,warnings:t}=E(i);t.length>0&&console.warn("[WebTeX-CN] Parse warnings:",t);let s=y(e);return new w(e).renderFromLayout(s).map(o=>`<div class="wtc-page" data-template="${s.templateId}">${o}</div>`).join(`
|
|
45
|
+
`)}function U(i){let{ast:e,warnings:t}=E(i);return t.length>0&&console.warn("[WebTeX-CN] Parse warnings:",t),new w(e).renderPage()}function B(i,e,t={}){let{cssBasePath:s}=t,{ast:r,warnings:a}=E(i);a.length>0&&console.warn("[WebTeX-CN] Parse warnings:",a);let o=y(r),c=new w(r).renderFromLayout(o),u=typeof e=="string"?document.querySelector(e):e;if(!u)throw new Error(`[WebTeX-CN] Container not found: ${e}`);s&&typeof document<"u"&&L(o.templateId,s),u.innerHTML=c.map(p=>`<div class="wtc-page" data-template="${o.templateId}">${p}</div>`).join(`
|
|
46
|
+
`)}async function K(i,e,t={}){let s=await fetch(i);if(!s.ok)throw new Error(`[WebTeX-CN] Failed to fetch ${i}: ${s.status}`);let r=await s.text();B(r,e,t)}function J(){return[{id:"siku-quanshu",name:"\u56DB\u5E93\u5168\u4E66 (\u9ED1\u767D)"},{id:"siku-quanshu-colored",name:"\u56DB\u5E93\u5168\u4E66 (\u5F69\u8272)"},{id:"honglou",name:"\u7EA2\u697C\u68A6\u7532\u620C\u672C"},{id:"minimal",name:"\u6781\u7B80"}]}function L(i,e=""){if(typeof document>"u")return;let t=document.querySelector("link[data-wtc-template]");t&&t.remove();let s=document.createElement("link");s.rel="stylesheet",s.href=`${e}${i}.css`,s.dataset.wtcTemplate=i,document.head.appendChild(s)}typeof window<"u"&&(window.WebTeX={render:K,renderToDOM:B,renderToHTML:F,renderToPage:U,parse:E,getTemplates:J,setTemplate:L});return ee(ie);})();
|
package/package.json
CHANGED
|
@@ -364,7 +364,7 @@ export class GridLayoutEngine {
|
|
|
364
364
|
if (!isFirst) {
|
|
365
365
|
this.advanceColumn();
|
|
366
366
|
}
|
|
367
|
-
this.placeMarker(LayoutMarker.LIST_ITEM_START);
|
|
367
|
+
this.placeMarker(LayoutMarker.LIST_ITEM_START, { isFirstListItem: isFirst });
|
|
368
368
|
this.walkChildren(node.children);
|
|
369
369
|
this.placeMarker(LayoutMarker.LIST_ITEM_END);
|
|
370
370
|
}
|
|
@@ -224,6 +224,10 @@ ${floatsHTML}<div class="wtc-half-page wtc-half-right"><div class="wtc-content-b
|
|
|
224
224
|
for (const item of items) {
|
|
225
225
|
const type = item.node.type;
|
|
226
226
|
if (this.isOpenMarker(type)) {
|
|
227
|
+
// Non-first list items need a column break to match layout engine's advanceColumn()
|
|
228
|
+
if (type === LayoutMarker.LIST_ITEM_START && !item.isFirstListItem) {
|
|
229
|
+
html += '<br class="wtc-newline">';
|
|
230
|
+
}
|
|
227
231
|
html += this.markerOpenTag(item);
|
|
228
232
|
stack.push(item);
|
|
229
233
|
} else if (this.matchingOpenMarker(type)) {
|
package/src/templates/base.css
CHANGED
|
@@ -40,10 +40,10 @@
|
|
|
40
40
|
/* Jiazhu: visually smaller chars but same grid-cell height as main text.
|
|
41
41
|
font-size < 1em for smaller glyphs; letter-spacing compensates to match grid height.
|
|
42
42
|
Grid height per char = font-size × (1 + ls-ratio). Jiazhu needs same total.
|
|
43
|
-
jiazhu-ls = (grid-height - jiazhu-font-size) = font-size×(1+ls-ratio) - font-size×0.
|
|
44
|
-
= font-size × (0.15 + ls-ratio). In em: (0.15+ls-ratio)/0.
|
|
45
|
-
--wtc-jiazhu-font-size: 0.
|
|
46
|
-
--wtc-jiazhu-letter-spacing: calc((0.
|
|
43
|
+
jiazhu-ls = (grid-height - jiazhu-font-size) = font-size×(1+ls-ratio) - font-size×0.7
|
|
44
|
+
= font-size × (0.15 + ls-ratio). In em: (0.15+ls-ratio)/0.7 */
|
|
45
|
+
--wtc-jiazhu-font-size: 0.7em;
|
|
46
|
+
--wtc-jiazhu-letter-spacing: calc((0.3 + var(--wtc-letter-spacing-ratio)) / 0.7 * 1em);
|
|
47
47
|
--wtc-jiazhu-line-height: calc(var(--wtc-line-height) / 2);
|
|
48
48
|
--wtc-jiazhu-color: inherit;
|
|
49
49
|
--wtc-jiazhu-gap: 0px;
|