diff --git a/docs/notes/theme/guide/markdown/timeline.md b/docs/notes/theme/guide/markdown/timeline.md
index 3b6b32bd..601a2010 100644
--- a/docs/notes/theme/guide/markdown/timeline.md
+++ b/docs/notes/theme/guide/markdown/timeline.md
@@ -37,11 +37,13 @@ export default defineUserConfig({
```md{1,9} title="timeline.md"
::: timeline 配置
-- 标题 配置
+- 标题
+ 配置
正文内容
-- 标题 配置
+- 标题
+ 配置
正文内容
:::
@@ -49,8 +51,12 @@ export default defineUserConfig({
对于列表的每一个项:
-- __第一行__: 从起始位置定义 __标题__,在标题之后跟着 `key=value` 的格式配置时间点的 __属性__。
-- __后续行__: 正文内容,==请注意添加正确的缩进=={.important}。
+- 从 __首行开始__ 到 __首个空行__,均为 __标题__ ,在标题后紧跟随的一行,用于 __配置__ 当前项的行为
+
+- __首个空行之后__: 正文内容
+
+:::important 请注意添加正确的缩进
+:::
__一个简单的例子:__
@@ -58,15 +64,18 @@ __输入:__
```md
::: timeline
-- 节点一 time=2025-03-20 type=success
+- 节点一
+ time=2025-03-20 type=success
正文内容
-- 节点二 time=2025-02-21 type=warning
+- 节点二
+ time=2025-02-21 type=warning
正文内容
-- 节点三 time=2025-01-22 type=danger
+- 节点三
+ time=2025-01-22 type=danger
正文内容
:::
@@ -76,15 +85,18 @@ __输出:__
::: timeline
-- 节点一 time=2025-03-20 type=success
+- 节点一
+ time=2025-03-20 type=success
正文内容
-- 节点二 time=2025-02-21 type=warning
+- 节点二
+ time=2025-02-21 type=warning
正文内容
-- 节点三 time=2025-01-22 type=danger
+- 节点三
+ time=2025-01-22 type=danger
正文内容
:::
@@ -100,9 +112,17 @@ __时间线__ 支持非常灵活且灵活的配置项,配置主要分为两个
`::: timeline horizontal` 表示 渲染为 水平方向的时间线。
-- __列表项配置__: 在列表的每一个项上的配置,配置项列表项的第一行,跟随在标题之后,如:
+- __列表项配置__: 列表的每一个项的配置,紧跟随在标题之后的一行,如:
- `- 节点一 time=2025-03-20 type=success` 表示 时间点为 `2025-03-20`,节点类型为 `success`。
+ ```md
+ ::: timeline
+ - 标题
+ 也是标题
+ time=2025-03-20 type=success
+
+ 正文内容
+ :::
+ ```
### 容器配置
@@ -202,13 +222,24 @@ __输入:__
```md /horizontal/
::: timeline horizontal
-- 节点一 time=2025-03-20
+- 节点一
+ time=2025-03-20
+
正文内容
-- 节点二 time=2025-04-20 type=success
+
+- 节点二
+ time=2025-04-20 type=success
+
正文内容
-- 节点三 time=2025-01-22 type=danger
+
+- 节点三
+ time=2025-01-22 type=danger
+
正文内容
-- 节点四 time=2025-01-22 type=important
+
+- 节点四
+ time=2025-01-22 type=important
+
正文内容
:::
```
@@ -217,15 +248,25 @@ __输出:__
::: timeline horizontal
-- 节点一 time=2025-03-20
- 正文内容
-- 节点二 time=2025-04-20 type=success
- 正文内容
-- 节点三 time=2025-01-22 type=danger
- 正文内容
-- 节点四 time=2025-01-22 type=important
+- 节点一
+ time=2025-03-20
+
正文内容
+- 节点二
+ time=2025-04-20 type=success
+
+ 正文内容
+
+- 节点三
+ time=2025-01-22 type=danger
+
+ 正文内容
+
+- 节点四
+ time=2025-01-22 type=important
+
+ 正文内容
:::
### 右对齐
@@ -236,13 +277,24 @@ __输入:__
```md /placement="right"/
::: timeline placement="right"
-- 节点一 time=2025-03-20
+- 节点一
+ time=2025-03-20
+
正文内容
-- 节点二 time=2025-04-20 type=success
+
+- 节点二
+ time=2025-04-20 type=success
+
正文内容
-- 节点三 time=2025-01-22 type=danger
+
+- 节点三
+ time=2025-01-22 type=danger
+
正文内容
-- 节点四 time=2025-01-22 type=important
+
+- 节点四
+ time=2025-01-22 type=important
+
正文内容
:::
```
@@ -251,13 +303,24 @@ __输出:__
::: timeline placement="right"
-- 节点一 time=2025-03-20
+- 节点一
+ time=2025-03-20
+
正文内容
-- 节点二 time=2025-04-20 type=success
+
+- 节点二
+ time=2025-04-20 type=success
+
正文内容
-- 节点三 time=2025-01-22 type=danger
+
+- 节点三
+ time=2025-01-22 type=danger
+
正文内容
-- 节点四 time=2025-01-22 type=important
+
+- 节点四
+ time=2025-01-22 type=important
+
正文内容
:::
@@ -271,13 +334,24 @@ __输入:__
```md /placement="between"/ /placement=right/
::: timeline placement="between"
-- 节点一 time=2025-03-20 placement=right
+- 节点一
+ time=2025-03-20 placement=right
+
正文内容
-- 节点二 time=2025-04-20 type=success
+
+- 节点二
+ time=2025-04-20 type=success
+
正文内容
-- 节点三 time=2025-01-22 type=danger placement=right
+
+- 节点三
+ time=2025-01-22 type=danger placement=right
+
正文内容
-- 节点四 time=2025-01-22 type=important
+
+- 节点四
+ time=2025-01-22 type=important
+
正文内容
:::
```
@@ -286,31 +360,53 @@ __输出:__
::: timeline placement="between"
-- 节点一 time=2025-03-20 placement=right
+- 节点一
+ time=2025-03-20 placement=right
+
正文内容
-- 节点二 time=2025-04-20 type=success
+
+- 节点二
+ time=2025-04-20 type=success
+
正文内容
-- 节点三 time=2025-01-22 type=danger placement=right
+
+- 节点三
+ time=2025-01-22 type=danger placement=right
+
正文内容
-- 节点四 time=2025-01-22 type=important
+
+- 节点四
+ time=2025-01-22 type=important
+
正文内容
:::
### 节点类型
-在列表项首行标题之后,添加 `type=节点类型` 可以为当前节点设置节点类型。
+在列表项配置中,添加 `type=节点类型` 可以为当前节点设置节点类型。
__输入:__
```md /type=success/ /type=warning/ /type=danger/ /type=important/
::: timeline
-- 节点一 time=2025-03-20 type=success
+- 节点一
+ time=2025-03-20 type=success
+
正文内容
-- 节点二 time=2025-04-20 type=warning
+
+- 节点二
+ time=2025-04-20 type=warning
+
正文内容
-- 节点三 time=2025-01-22 type=danger
+
+- 节点三
+ time=2025-01-22 type=danger
+
正文内容
-- 节点四 time=2025-01-22 type=important
+
+- 节点四
+ time=2025-01-22 type=important
+
正文内容
:::
```
@@ -319,32 +415,54 @@ __输出:__
::: timeline
-- 节点一 time=2025-03-20 type=success
+- 节点一
+ time=2025-03-20 type=success
+
正文内容
-- 节点二 time=2025-04-20 type=warning
+
+- 节点二
+ time=2025-04-20 type=warning
+
正文内容
-- 节点三 time=2025-01-22 type=danger
+
+- 节点三
+ time=2025-01-22 type=danger
+
正文内容
-- 节点四 time=2025-01-22 type=important
+
+- 节点四
+ time=2025-01-22 type=important
+
正文内容
:::
### 线条风格
- 在容器配置中添加 `line=线条风格` 可以为所有节点设置默认线条风格。
-- 在列表项首行标题之后,添加 `line=线条风格` 可以为节点设置线条风格。
+- 在列表项配置中,添加 `line=线条风格` 可以为节点设置线条风格。
__输入:__
```md /line="dotted"/ /line=solid/ /line=dashed/
::: timeline line="dotted"
-- 节点一 time=2025-03-20
+- 节点一
+ time=2025-03-20
+
正文内容
-- 节点二 time=2025-04-20 type=success
+
+- 节点二
+ time=2025-04-20 type=success
+
正文内容
-- 节点三 time=2025-01-22 type=danger line=dashed
+
+- 节点三
+ time=2025-01-22 type=danger line=dashed
+
正文内容
-- 节点四 time=2025-01-22 type=important line=solid
+
+- 节点四
+ time=2025-01-22 type=important line=solid
+
正文内容
:::
```
@@ -353,19 +471,30 @@ __输出:__
::: timeline line="dotted"
-- 节点一 time=2025-03-20
+- 节点一
+ time=2025-03-20
+
正文内容
-- 节点二 time=2025-04-20 type=success
+
+- 节点二
+ time=2025-04-20 type=success
+
正文内容
-- 节点三 time=2025-01-22 type=danger line=dashed
+
+- 节点三
+ time=2025-01-22 type=danger line=dashed
+
正文内容
-- 节点四 time=2025-01-22 type=important line=solid
+
+- 节点四
+ time=2025-01-22 type=important line=solid
+
正文内容
:::
### 带图标的节点
-在列表项首行标题之后,添加 `icon=图标名称` 可以为节点添加图标。
+在列表项配置中,添加 `icon=图标名称` 可以为节点添加图标。
图标名称支持 [iconify](https://icon-sets.iconify.design/) 的图标名称。
@@ -373,13 +502,24 @@ __输入:__
```md /icon=mdi:balloon/ /icon=mdi:bookmark/
::: timeline placement="between"
-- 节点一 time=2025-03-20 placement=right icon=mdi:balloon
+- 节点一
+ time=2025-03-20 placement=right icon=mdi:balloon
+
正文内容
-- 节点二 time=2025-04-20 type=success icon=mdi:bookmark
+
+- 节点二
+ time=2025-04-20 type=success icon=mdi:bookmark
+
正文内容
-- 节点三 time=2025-01-22 type=danger placement=right icon=mdi:bullhorn-variant-outline
+
+- 节点三
+ time=2025-01-22 type=danger placement=right icon=mdi:bullhorn-variant-outline
+
正文内容
-- 节点四 time=2025-01-22 type=important card=true icon="mdi:cake-variant-outline"
+
+- 节点四
+ time=2025-01-22 type=important card=true icon="mdi:cake-variant-outline"
+
正文内容
:::
```
@@ -388,13 +528,24 @@ __输出:__
::: timeline placement="between"
-- 节点一 time=2025-03-20 placement=right icon=mdi:balloon
+- 节点一
+ time=2025-03-20 placement=right icon=mdi:balloon
+
正文内容
-- 节点二 time=2025-04-20 type=success icon=mdi:bookmark
+
+- 节点二
+ time=2025-04-20 type=success icon=mdi:bookmark
+
正文内容
-- 节点三 time=2025-01-22 type=danger placement=right icon=mdi:bullhorn-variant-outline
+
+- 节点三
+ time=2025-01-22 type=danger placement=right icon=mdi:bullhorn-variant-outline
+
正文内容
-- 节点四 time=2025-01-22 type=important card=true icon="mdi:cake-variant-outline"
+
+- 节点四
+ time=2025-01-22 type=important card=true icon="mdi:cake-variant-outline"
+
正文内容
:::
@@ -403,25 +554,36 @@ __输出:__
卡片节点可以很灵活的进行控制:
- 在 容器配置中添加 `card` 即可使每个列表项都是卡片节点。
-- 在列表项首行标题之后,添加 `card=true` 即可为节点设置为卡片节点。
-- 在列表项首行标题之后,添加 `card=false` 即可为节点设置为非卡片节点。
+- 在列表项配置中,添加 `card=true` 即可为节点设置为卡片节点。
+- 在列表项配置中,添加 `card=false` 即可为节点设置为非卡片节点。
卡片节点的样式会受到 `type` 配置的影响。
-::: tip 在列表项首行标题之后添加 `card=true` / `card=false` 可以覆盖容器节点的 `card` 配置
+::: tip 在列表项配置中添加 `card=true` / `card=false` 可以覆盖容器节点的 `card` 配置
:::
__输入:__
```md{1} /card=false/
::: timeline card
-- 节点一 time=2025-03-20
+- 节点一
+ time=2025-03-20
+
正文内容
-- 节点二 time=2025-04-20 type=success card=false
+
+- 节点二
+ time=2025-04-20 type=success card=false
+
正文内容
-- 节点三 time=2025-01-22 type=danger
+
+- 节点三
+ time=2025-01-22 type=danger
+
正文内容
-- 节点四 time=2025-01-22 type=important
+
+- 节点四
+ time=2025-01-22 type=important
+
正文内容
:::
```
@@ -430,13 +592,24 @@ __输出:__
::: timeline card
-- 节点一 time=2025-03-20
+- 节点一
+ time=2025-03-20
+
正文内容
-- 节点二 time=2025-04-20 type=success card=false
+
+- 节点二
+ time=2025-04-20 type=success card=false
+
正文内容
-- 节点三 time=2025-01-22 type=danger
+
+- 节点三
+ time=2025-01-22 type=danger
+
正文内容
-- 节点四 time=2025-01-22 type=important
+
+- 节点四
+ time=2025-01-22 type=important
+
正文内容
:::
@@ -480,22 +653,38 @@ __示例:__
```md /type=your-type/
::: timeline
-- 节点一 time=2025-03-20
+- 节点一
+ time=2025-03-20
+
正文内容
-- 节点二 time=2025-04-20 type=your-type card=true
+
+- 节点二
+ time=2025-04-20 type=your-type card=true
+
正文内容
-- 节点三 time=2025-01-22 type=danger
+
+- 节点三
+ time=2025-01-22 type=danger
+
正文内容
:::
```
::: timeline
-- 节点一 time=2025-03-20
+- 节点一
+ time=2025-03-20
+
正文内容
-- 节点二 time=2025-04-20 type=your-type card=true
+
+- 节点二
+ time=2025-04-20 type=your-type card=true
+
正文内容
-- 节点三 time=2025-01-22 type=danger
+
+- 节点三
+ time=2025-01-22 type=danger
+
正文内容
:::
diff --git a/plugins/plugin-md-power/__test__/__snapshots__/timelinePlugin.spec.ts.snap b/plugins/plugin-md-power/__test__/__snapshots__/timelinePlugin.spec.ts.snap
index b346d401..1631ade4 100644
--- a/plugins/plugin-md-power/__test__/__snapshots__/timelinePlugin.spec.ts.snap
+++ b/plugins/plugin-md-power/__test__/__snapshots__/timelinePlugin.spec.ts.snap
@@ -1,16 +1,10 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
exports[`timeline > timelinePlugin() > should work 1`] = `
-"
- 这是标题
-
-这是内容
- 这是标题
-
-这是内容
- 这是标题
-
-这是内容
+"这是标题这是内容
+这是标题
+这也是标题这是内容
+这是标题这是内容
- 1
- 2
@@ -21,24 +15,11 @@ exports[`timeline > timelinePlugin() > should work 1`] = `
-
- 这是标题
-
-这是内容
- 这是标题
-
-这是内容
- 这是标题
-
-这是内容
- 这是标题
-
-这是内容
- 这是标题
-
-这是内容
- 这是标题
-
-这是内容
+这是标题这是内容
+这是标题这是内容
+这是标题这是内容
+这是标题这是内容
+这是标题这是内容
+这是标题这是内容
"
`;
diff --git a/plugins/plugin-md-power/__test__/timelinePlugin.spec.ts b/plugins/plugin-md-power/__test__/timelinePlugin.spec.ts
index f08a0cc7..3b94e13e 100644
--- a/plugins/plugin-md-power/__test__/timelinePlugin.spec.ts
+++ b/plugins/plugin-md-power/__test__/timelinePlugin.spec.ts
@@ -4,24 +4,24 @@ import { extractTimelineAttributes, timelinePlugin } from '../src/node/container
describe('timeline > extractTimelineAttributes()', () => {
it('should work', () => {
- const meta = extractTimelineAttributes('这是标题 time=Q1')
- expect(meta).toEqual({ title: '这是标题', time: 'Q1' })
+ const meta = extractTimelineAttributes('这time=Q1')
+ expect(meta).toEqual({ time: 'Q1' })
})
it('should work with multi attrs', () => {
- const meta = extractTimelineAttributes('这是标题 time=Q1 icon=ri:clockwise-line card=true placement=left line=dashed')
- expect(meta).toEqual({ title: '这是标题', time: 'Q1', icon: 'ri:clockwise-line', card: 'true', placement: 'left', line: 'dashed' })
+ const meta = extractTimelineAttributes('time=Q1 icon=ri:clockwise-line card=true placement=left line=dashed')
+ expect(meta).toEqual({ time: 'Q1', icon: 'ri:clockwise-line', card: 'true', placement: 'left', line: 'dashed' })
})
it('should work with title include space', () => {
- const meta = extractTimelineAttributes('这是标题 这也是标题 time=Q1 icon=ri:clockwise-line card=true placement=left line=dashed')
+ const meta = extractTimelineAttributes('time=Q1 icon=ri:clockwise-line card=true placement=left line=dashed')
- expect(meta).toEqual({ title: '这是标题 这也是标题', time: 'Q1', icon: 'ri:clockwise-line', card: 'true', placement: 'left', line: 'dashed' })
+ expect(meta).toEqual({ time: 'Q1', icon: 'ri:clockwise-line', card: 'true', placement: 'left', line: 'dashed' })
})
it('should work with unknown attr', () => {
- const meta = extractTimelineAttributes('这是标题 time=Q1 unknown=true card=true')
- expect(meta).toEqual({ title: '这是标题 unknown=true card=true', time: 'Q1' })
+ const meta = extractTimelineAttributes('time=Q1 unknown=true card=true')
+ expect(meta).toEqual({ time: 'Q1' })
})
})
@@ -33,14 +33,19 @@ describe('timeline > timelinePlugin()', () => {
const source = `\
::: timeline
- 这是标题
+
这是内容
- 这是标题
+ 这也是标题
+
这是内容
:::
::: timeline horizontal line="dashed" card
-- 这是标题 time=q1
+- 这是标题
+ time=q1
+
这是内容
- 1
- 2
@@ -48,23 +53,33 @@ describe('timeline > timelinePlugin()', () => {
- 1.1
- 1.2
-- 这是标题 time=q2 color=red card=false
+- 这是标题
+ time=q2 color=red card=false
+
这是内容
:::
::: timeline placement="right"
-- 这是标题 icon=xxx card=true type=warning
+- 这是标题
+ icon=xxx card=true type=warning
+
这是内容
-- 这是标题 type=danger line=dotted
+- 这是标题
+ type=danger line=dotted
+
这是内容
:::
::: timeline placement="between"
-- 这是标题 card=true placement=right
+- 这是标题
+ card=true placement=right
+
这是内容
-- 这是标题 card=true placement=left
+- 这是标题
+ card=true placement=left
+
这是内容
- 这是标题
diff --git a/plugins/plugin-md-power/package.json b/plugins/plugin-md-power/package.json
index d31c32fb..e68f1b10 100644
--- a/plugins/plugin-md-power/package.json
+++ b/plugins/plugin-md-power/package.json
@@ -77,6 +77,7 @@
"@mdit/plugin-sup": "catalog:prod",
"@mdit/plugin-tab": "catalog:prod",
"@mdit/plugin-tasklist": "catalog:prod",
+ "@pengzhanbo/utils": "catalog:prod",
"@vuepress/helper": "catalog:vuepress",
"@vueuse/core": "catalog:prod",
"chokidar": "catalog:prod",
diff --git a/plugins/plugin-md-power/src/node/container/timeline.ts b/plugins/plugin-md-power/src/node/container/timeline.ts
index ebd4841a..17352a97 100644
--- a/plugins/plugin-md-power/src/node/container/timeline.ts
+++ b/plugins/plugin-md-power/src/node/container/timeline.ts
@@ -1,15 +1,21 @@
/**
* ::: timeline
*
- * - title time="Q1" icon="ri:clockwise-line" line="dashed" type="warning" color="red"
- * xxx
- * - title time="Q2" icon="ri:clockwise-line" line="dashed" type="warning" color="red"
+ * - title
+ * time="Q1" icon="ri:clockwise-line" line="dashed" type="warning" color="red"
+ *
+ * content
+ *
+ * - title
+ * time="Q2" icon="ri:clockwise-line" line="dashed" type="warning" color="red"
+ *
+ * content
* :::
*/
import type Token from 'markdown-it/lib/token.mjs'
import type { Markdown } from 'vuepress/markdown'
+import { isEmptyObject } from '@pengzhanbo/utils'
import { resolveAttrs } from '.././utils/resolveAttrs.js'
-import { cleanMarkdownEnv } from '../utils/cleanMarkdownEnv.js'
import { createContainerPlugin } from './createContainer.js'
export interface TimelineAttrs {
@@ -20,7 +26,6 @@ export interface TimelineAttrs {
}
export interface TimelineItemMeta {
- title: string
time?: string
type?: string
icon?: string
@@ -54,9 +59,9 @@ export function timelinePlugin(md: Markdown) {
after: () => '',
})
- md.renderer.rules.timeline_item_open = (tokens, idx, _, env) => {
+ md.renderer.rules.timeline_item_open = (tokens, idx) => {
const token = tokens[idx]
- const { title, time, type, icon, color, line, card, placement } = token.meta as TimelineItemMeta
+ const { time, type, icon, color, line, card, placement } = token.meta as TimelineItemMeta
return `
- ${md.renderInline(title, cleanMarkdownEnv(env))}
- ${icon ? `` : ''}`
+ }>${icon ? `` : ''}`
}
md.renderer.rules.timeline_item_close = () => ''
+ md.renderer.rules.timeline_item_title_open = () => ''
+ md.renderer.rules.timeline_item_title_close = () => ''
}
function parseTimeline(tokens: Token[], index: number) {
@@ -101,20 +106,27 @@ function parseTimeline(tokens: Token[], index: number) {
// 仅处理根级列表项(层级1)
if (currentLevel === 1) {
token.type = 'timeline_item_open'
- const titleOpenToken = tokens[i + 1]
- const titleCloseToken = tokens[i + 3]
- titleOpenToken.hidden = true
- titleCloseToken.hidden = true
+ tokens[i + 1].type = 'timeline_item_title_open'
+ tokens[i + 3].type = 'timeline_item_title_close'
+
+ // - title
+ // attrs
+ // 列表项 `-` 后面包括紧跟随的后续行均在 type=inline 的 token 中, 并作为 children
const inlineToken = tokens[i + 2]
- const softbreakIndex = inlineToken.children!.findIndex(
+ // 找到最后一个 softbreak,最后一行作为 attrs 进行解析
+ const softbreakIndex = inlineToken.children!.findLastIndex(
token => token.type === 'softbreak',
)
- inlineToken.children = softbreakIndex !== -1
- ? inlineToken.children!.slice(softbreakIndex)
- : []
-
- const content = inlineToken.content.replace(/\n[\s\S]*/, '')
- token.meta = extractTimelineAttributes(content.trim())
+ if (softbreakIndex !== -1) {
+ const lastToken = inlineToken.children![inlineToken.children!.length - 1]
+ token.meta = extractTimelineAttributes(lastToken.content.trim())
+ if (!isEmptyObject(token.meta)) {
+ inlineToken.children = inlineToken.children!.slice(0, softbreakIndex)
+ }
+ }
+ else {
+ token.meta = {}
+ }
}
}
else if (token.type === 'list_item_close') {
@@ -128,27 +140,22 @@ function parseTimeline(tokens: Token[], index: number) {
export function extractTimelineAttributes(rawText: string): TimelineItemMeta {
const attrKeys = ['time', 'type', 'icon', 'line', 'color', 'card', 'placement'] as const
- const attrs: Partial = {}
+ const attrs: TimelineItemMeta = {}
let buffer = rawText.trim()
- const titleSegments: string[] = []
while (buffer.length) {
// 匹配属性键 (支持大小写)
const keyMatch = buffer.match(RE_KEY)
if (!keyMatch) {
- titleSegments.push(buffer)
break
}
// 提取可能的关键字
const matchedKey = keyMatch[1].toLowerCase()
if (!attrKeys.includes(matchedKey as any)) {
- titleSegments.push(buffer)
break
}
const keyStart = keyMatch.index!
- // 记录非属性内容为标题
- titleSegments.push(buffer.slice(0, keyStart).trim())
// 跳过已匹配的 key:
const keyEnd = keyStart + keyMatch[0].length
@@ -167,8 +174,5 @@ export function extractTimelineAttributes(rawText: string): TimelineItemMeta {
buffer = buffer.slice(valueEnd)
}
- return {
- title: titleSegments.join(' ').trim(),
- ...attrs,
- }
+ return attrs
}