- 移除 TodoItem 中的 priority、created_at 和 updated_at 字段 - 强制每个任务都必须有唯一 id,且由用户负责生成 - 修改合并模式逻辑,merge=true 下保留未提及的旧任务 - 支持已完成和已取消任务重新激活(状态改回 pending 或 in_progress) - 禁止 in_progress 状态退回到 pending,必须标记为 completed 或 cancelled - 优化状态转换校验,允许特定状态间合法切换 - 简化任务变更消息,移除详细的新增/更新/移除统计 - 更新文档和示例,明确 id 必须由用户生成和使用 - 修复和补充测试,增强状态转换和合并模式验证 - 调整任务时间戳生成逻辑,统一使用当前时间及索引 - 该变更提供更合理的任务状态机械及管理模式,提升稳定性和易用性
370 lines
8.9 KiB
Markdown
370 lines
8.9 KiB
Markdown
# XML 格式指南
|
||
|
||
本文档基于 [slides_xml_schema_definition.xml](slides_xml_schema_definition.xml) 整理,说明飞书 Slides XML Schema(SML 2.0)的核心结构和常用写法。
|
||
|
||
## 基本结构
|
||
|
||
```xml
|
||
<?xml version="1.0" encoding="UTF-8"?>
|
||
<presentation xmlns="http://www.larkoffice.com/sml/2.0" width="960" height="540">
|
||
<title>演示文稿标题</title>
|
||
<slide>
|
||
<style>
|
||
<fill>
|
||
<fillColor color="rgb(245, 245, 245)"/>
|
||
</fill>
|
||
</style>
|
||
<data>
|
||
<shape type="text" topLeftX="80" topLeftY="80" width="800" height="120">
|
||
<content textType="title">
|
||
<p>主标题</p>
|
||
</content>
|
||
</shape>
|
||
</data>
|
||
<note>
|
||
<content textType="body">
|
||
<p>这是演讲者备注。</p>
|
||
</content>
|
||
</note>
|
||
</slide>
|
||
</presentation>
|
||
```
|
||
|
||
## 根元素
|
||
|
||
### `<presentation>`
|
||
|
||
协议标准写法应带命名空间 `http://www.larkoffice.com/sml/2.0`;当前服务端实现可能兼容不带 `xmlns` 的输入,但不作为协议保证。
|
||
|
||
**属性:**
|
||
|
||
| 属性 | 类型 | 必需 | 说明 |
|
||
|------|------|------|------|
|
||
| `width` | positiveInteger | 是 | 演示文稿宽度,如 `960` |
|
||
| `height` | positiveInteger | 是 | 演示文稿高度,如 `540` |
|
||
| `id` | string | 否 | 演示文稿标识 |
|
||
|
||
**子元素:**
|
||
|
||
| 元素 | 必需 | 说明 |
|
||
|------|------|------|
|
||
| `<title>` | 否 | 演示文稿标题 |
|
||
| `<theme>` | 否 | 全局主题 |
|
||
| `<slide>` | 是 | 幻灯片页面,至少 1 页,最多 100 页 |
|
||
|
||
## 主题
|
||
|
||
### `<theme>`
|
||
|
||
`<theme>` 当前包含两部分:
|
||
|
||
- `<background>`:演示文稿级背景填充
|
||
- `<textStyles>`:主题文本样式集合
|
||
|
||
`<textStyles>` 下可选子元素:
|
||
|
||
- `<title>`
|
||
- `<headline>`
|
||
- `<sub-headline>`
|
||
- `<body>`
|
||
- `<caption>`
|
||
|
||
这些元素定义的是主题默认样式,不是页面结构。常用属性:
|
||
|
||
| 属性 | 说明 |
|
||
|------|------|
|
||
| `fontFamily` | 字体 |
|
||
| `fontSize` | 字号 |
|
||
| `fontColor` | 字体颜色 |
|
||
|
||
## 幻灯片元素
|
||
|
||
### `<slide>`
|
||
|
||
单张幻灯片的结构比较严格。
|
||
|
||
**属性:**
|
||
|
||
| 属性 | 类型 | 必需 | 说明 |
|
||
|------|------|------|------|
|
||
| `id` | string | 否 | 幻灯片标识 |
|
||
|
||
**直接子元素只有:**
|
||
|
||
| 元素 | 必需 | 说明 |
|
||
|------|------|------|
|
||
| `<style>` | 否 | 页面样式 |
|
||
| `<data>` | 否 | 页面元素容器 |
|
||
| `<note>` | 否 | 演讲者备注 |
|
||
|
||
这意味着 `<title>`、`<headline>`、`<body>`、`<caption>` 不能直接放在 `<slide>` 下。
|
||
|
||
## 文本内容模型
|
||
|
||
### `<content>`
|
||
|
||
实际页面文本通常通过 `<content>` 表达,常见位置有:
|
||
|
||
- `shape` 内部
|
||
- `table/td` 内部
|
||
- `note` 内部
|
||
|
||
**常用属性:**
|
||
|
||
| 属性 | 说明 |
|
||
|------|------|
|
||
| `textType` | `title` / `headline` / `sub-headline` / `body` / `caption` |
|
||
| `verticalAlign` | 垂直对齐 |
|
||
| `textAlign` | 水平对齐 |
|
||
| `lineSpacing` | 行间距 |
|
||
| `fontSize` | 字号 |
|
||
| `fontFamily` | 字体 |
|
||
| `color` | 字体颜色 |
|
||
| `bold` / `italic` / `underline` / `strikethrough` | 内容级样式 |
|
||
| `wrap` | 是否自动换行 |
|
||
|
||
**可包含的子元素:**
|
||
|
||
- `<p>`
|
||
- `<ul>`
|
||
- `<ol>`
|
||
|
||
### `<p>`
|
||
|
||
`<p>` 是段落元素,可混排纯文本和内联标签:
|
||
|
||
- `<br/>`
|
||
- `<strong>`
|
||
- `<em>`
|
||
- `<u>`
|
||
- `<span>`
|
||
- `<del>`
|
||
- `<a>`
|
||
- `<shadow>`
|
||
- `<outline>`
|
||
|
||
示例:
|
||
|
||
```xml
|
||
<content textType="body" textAlign="left">
|
||
<p>普通文本 <strong>加粗</strong> <em>斜体</em> <a href="https://example.com">链接</a></p>
|
||
<ul>
|
||
<li><p>列表项 1</p></li>
|
||
<li><p>列表项 2</p></li>
|
||
</ul>
|
||
</content>
|
||
```
|
||
|
||
## 常用页面元素
|
||
|
||
所有页面元素都放在 `<data>` 中。
|
||
|
||
### `<shape>`
|
||
|
||
`shape` 可表示普通形状,也可表示文本框。文本框推荐使用 `type="text"`。
|
||
|
||
```xml
|
||
<shape type="text" topLeftX="80" topLeftY="80" width="800" height="120">
|
||
<content textType="title">
|
||
<p>主标题</p>
|
||
</content>
|
||
</shape>
|
||
```
|
||
|
||
```xml
|
||
<shape type="rect" topLeftX="700" topLeftY="120" width="180" height="120">
|
||
<fill>
|
||
<fillColor color="rgba(100, 149, 237, 0.25)"/>
|
||
</fill>
|
||
<border color="rgb(100, 149, 237)" width="2"/>
|
||
</shape>
|
||
```
|
||
|
||
**属性:**
|
||
|
||
| 属性 | 必需 | 说明 |
|
||
|------|------|------|
|
||
| `type` | 是 | 形状类型,`text` 表示文本框 |
|
||
| `topLeftX` | 是 | 左上角 X 坐标 |
|
||
| `topLeftY` | 是 | 左上角 Y 坐标 |
|
||
| `width` | 是 | 宽度 |
|
||
| `height` | 是 | 高度 |
|
||
| `rotation` | 否 | 旋转角度 |
|
||
| `flipX` / `flipY` | 否 | 翻转 |
|
||
| `alpha` | 否 | 透明度 |
|
||
|
||
**可选子元素:**
|
||
|
||
- `<fill>`
|
||
- `<border>`
|
||
- `<reflection>`
|
||
- `<shadow>`
|
||
- `<content>`
|
||
|
||
### `<line>`
|
||
|
||
```xml
|
||
<line startX="100" startY="200" endX="420" endY="200">
|
||
<border color="rgb(43, 47, 54)" width="2"/>
|
||
</line>
|
||
```
|
||
|
||
`line` 使用的是 `startX` / `startY` / `endX` / `endY`,不是 `x1` / `y1` / `x2` / `y2`。
|
||
|
||
### `<img>`
|
||
|
||
```xml
|
||
<img src="file_token_or_url" topLeftX="100" topLeftY="220" width="320" height="180"/>
|
||
```
|
||
|
||
`img` 使用 `topLeftX` / `topLeftY`,不是 `x` / `y`。
|
||
|
||
`src` 只接受两种值:
|
||
|
||
| `src` 形式 | 说明 |
|
||
|---|---|
|
||
| `file_token`(如 `boxcnXXXXXXXXXXXXXXXXXXXXXX`) | 通过 `slides +media-upload` 上传后返回的 token |
|
||
| `@<本地路径>`(如 `@./assets/chart.png`) | **仅在 `slides +create --slides` 中可用**:CLI 会自动上传该文件并替换为 file_token |
|
||
|
||
> **禁止使用 http(s) 外链 URL**:飞书 slides 渲染端不会代理外链图片,`src="https://..."` 在 PPT 里通常显示破图。要用网图必须先 `curl`/下载到 CWD 内,再走上传流程拿 `file_token`。
|
||
|
||
本地图片的两种姿势:
|
||
|
||
- **新建带图 PPT**:`+create --slides` 里直接写 `src="@./pic.png"`,CLI 在创空白 PPT 后、加 slides 前自动上传并替换 token
|
||
- **给已有 PPT 加带图新页**:先 `slides +media-upload --file ./pic.png --presentation $PID` 拿 token,再用 token 写进 `xml_presentation.slide create` 的 XML
|
||
|
||
### `<icon>`
|
||
|
||
```xml
|
||
<icon iconType="iconpark/Base/setting.svg" topLeftX="440" topLeftY="220" width="32" height="32"/>
|
||
```
|
||
|
||
### `<table>`
|
||
|
||
表格结构为:
|
||
|
||
- `<table>`
|
||
- `<colgroup>` / `<tr>`
|
||
- `<tr>` 内为 `<td>`
|
||
- `<td>` 内可放 `<content>`
|
||
|
||
### `<chart>`
|
||
|
||
图表元素必须至少包含:
|
||
|
||
- `<chartPlotArea>`
|
||
- `<chartData>`
|
||
|
||
同时还可以包含:
|
||
|
||
- `<chartTitle>`
|
||
- `<chartSubTitle>`
|
||
- `<chartStyle>`
|
||
- `<chartLegend>`
|
||
- `<chartTooltip>`
|
||
|
||
如果要写图表 XML,建议直接以 XSD 为准,不要自行发明更简化的 chart DSL。
|
||
|
||
## 样式元素
|
||
|
||
### `<fill>`
|
||
|
||
```xml
|
||
<fill>
|
||
<fillColor color="rgb(100, 149, 237)"/>
|
||
</fill>
|
||
```
|
||
|
||
### `<border>`
|
||
|
||
```xml
|
||
<border color="rgb(0, 0, 0)" width="2" dashArray="solid"/>
|
||
```
|
||
|
||
### 颜色格式
|
||
|
||
```xml
|
||
<fillColor color="rgb(255, 0, 0)"/>
|
||
<fillColor color="rgba(255, 0, 0, 0.5)"/>
|
||
<fillColor color="linear-gradient(90deg, rgb(255,0,0) 0%, rgb(0,0,255) 100%)"/>
|
||
<fillColor color="radial-gradient(circle at 50% 50%, rgb(255,0,0) 0%, rgb(0,0,255) 100%)"/>
|
||
```
|
||
|
||
## 演讲者备注
|
||
|
||
### `<note>`
|
||
|
||
```xml
|
||
<note>
|
||
<content textType="body">
|
||
<p>这是演讲者备注内容。</p>
|
||
</content>
|
||
</note>
|
||
```
|
||
|
||
## 完整示例
|
||
|
||
```xml
|
||
<?xml version="1.0" encoding="UTF-8"?>
|
||
<presentation xmlns="http://www.larkoffice.com/sml/2.0" width="960" height="540">
|
||
<title>季度报告</title>
|
||
<theme>
|
||
<textStyles>
|
||
<title fontFamily="思源黑体" fontSize="54" fontColor="rgba(0, 0, 0, 1)"/>
|
||
<body fontFamily="思源黑体" fontSize="18" fontColor="rgba(43, 47, 54, 1)"/>
|
||
</textStyles>
|
||
</theme>
|
||
<slide>
|
||
<style>
|
||
<fill>
|
||
<fillColor color="rgb(245, 245, 245)"/>
|
||
</fill>
|
||
</style>
|
||
<data>
|
||
<shape type="text" topLeftX="80" topLeftY="72" width="760" height="100">
|
||
<content textType="title">
|
||
<p>2024 年第一季度报告</p>
|
||
</content>
|
||
</shape>
|
||
<shape type="text" topLeftX="80" topLeftY="200" width="520" height="180">
|
||
<content textType="body">
|
||
<p>核心指标</p>
|
||
<ul>
|
||
<li><p>用户增长:+25%</p></li>
|
||
<li><p>收入增长:+30%</p></li>
|
||
<li><p>市场份额:15%</p></li>
|
||
</ul>
|
||
</content>
|
||
</shape>
|
||
<shape type="rect" topLeftX="660" topLeftY="180" width="180" height="140">
|
||
<fill>
|
||
<fillColor color="rgba(100, 149, 237, 0.25)"/>
|
||
</fill>
|
||
<border color="rgb(100, 149, 237)" width="2"/>
|
||
</shape>
|
||
</data>
|
||
<note>
|
||
<content textType="body">
|
||
<p>讲到增长率时补充样本范围。</p>
|
||
</content>
|
||
</note>
|
||
</slide>
|
||
</presentation>
|
||
```
|
||
|
||
## 最佳实践
|
||
|
||
1. 始终带上命名空间 `xmlns="http://www.larkoffice.com/sml/2.0"`
|
||
2. 用 `shape type="text"` + `content` 表达页面文本
|
||
3. 用 `topLeftX` / `topLeftY`、`startX` / `startY` 等 schema 中定义的属性名
|
||
4. 优先使用 `rgb` / `rgba` 颜色格式
|
||
5. 特殊字符按 XML 规则转义
|
||
6. 标准 16:9 页面建议使用 `width="960"` 和 `height="540"`
|
||
|
||
## 参考文档
|
||
|
||
- [xml-schema-quick-ref.md](xml-schema-quick-ref.md)
|
||
- [slides_xml_schema_definition.xml](slides_xml_schema_definition.xml)
|
||
- [examples.md](examples.md)
|
||
- [slides_demo.xml](slides_demo.xml)
|