Skip to content

Commit 93202c3

Browse files
authored
feat(block-attributes): attach trailing {attr} to nearest block element (#214)
1 parent cf09f58 commit 93202c3

30 files changed

Lines changed: 1262 additions & 47 deletions

docs/app/pages/compare.vue

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
<script setup lang="ts">
2+
import { useLocalStorage } from '@vueuse/core'
3+
import { allFeaturesMarkdown } from '~/constants'
4+
5+
definePageMeta({ footer: false })
6+
7+
useSeoMeta({
8+
title: 'Compare - Comark',
9+
description: 'Compare multiple Comark documents side by side.',
10+
})
11+
12+
interface Col {
13+
id: string
14+
content: string
15+
}
16+
17+
const defaultCols: Col[] = [
18+
{ id: '1', content: allFeaturesMarkdown },
19+
{ id: '2', content: allFeaturesMarkdown },
20+
]
21+
22+
const cols = useLocalStorage<Col[]>('comark:compare-cols', defaultCols, {
23+
serializer: {
24+
read: (v) => {
25+
try {
26+
const parsed = JSON.parse(v)
27+
return Array.isArray(parsed) && parsed.length >= 2 ? parsed : defaultCols
28+
} catch {
29+
return defaultCols
30+
}
31+
},
32+
write: (v) => JSON.stringify(v),
33+
},
34+
})
35+
36+
// nextId must be higher than any existing id to avoid collisions after reload
37+
let nextId = cols.value.reduce((max, c) => Math.max(max, Number(c.id) || 0), 0) + 1
38+
39+
function addCol() {
40+
cols.value = [...cols.value, { id: String(nextId++), content: '' }]
41+
}
42+
43+
function removeCol(id: string) {
44+
if (cols.value.length <= 2) return
45+
cols.value = cols.value.filter((c) => c.id !== id)
46+
}
47+
</script>
48+
49+
<template>
50+
<ClientOnly>
51+
<div class="flex h-[calc(100vh-64px)] overflow-hidden">
52+
<!-- Editor columns -->
53+
<div
54+
v-for="(col, i) in cols"
55+
:key="col.id"
56+
class="flex min-w-0 flex-1 flex-col border-l border-default first:border-l-0"
57+
>
58+
<div class="flex h-9 shrink-0 items-center gap-2 border-b border-default bg-elevated px-3">
59+
<span class="text-xs text-muted">Editor {{ i + 1 }}</span>
60+
<UButton
61+
v-if="cols.length > 2"
62+
icon="i-lucide-x"
63+
variant="ghost"
64+
color="neutral"
65+
size="xs"
66+
class="ml-auto -mr-1"
67+
@click="removeCol(col.id)"
68+
/>
69+
</div>
70+
<div class="min-h-0 flex-1">
71+
<Editor v-model="col.content" />
72+
</div>
73+
</div>
74+
75+
<!-- Add column -->
76+
<div class="flex w-10 shrink-0 items-center justify-center border-l border-default bg-elevated">
77+
<UTooltip text="Add editor">
78+
<UButton
79+
icon="i-lucide-plus"
80+
variant="ghost"
81+
color="neutral"
82+
size="sm"
83+
@click="addCol"
84+
/>
85+
</UTooltip>
86+
</div>
87+
</div>
88+
89+
<template #fallback>
90+
<div class="flex h-[calc(100vh-64px)] overflow-hidden">
91+
<div
92+
v-for="i in 2"
93+
:key="i"
94+
class="flex flex-1 flex-col border-l border-default first:border-l-0"
95+
>
96+
<div class="h-9 border-b border-default bg-elevated" />
97+
<div class="flex-1 p-4">
98+
<USkeleton class="h-full w-full" />
99+
</div>
100+
</div>
101+
<div class="w-10 shrink-0 border-l border-default bg-elevated" />
102+
</div>
103+
</template>
104+
</ClientOnly>
105+
</template>
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
## Input
2+
3+
```md
4+
> Blockquote paragraph 1 {attr="value"}
5+
>
6+
> Blockquote paragraph 2 {attr2="value2"}
7+
```
8+
9+
## AST
10+
11+
```json
12+
{
13+
"frontmatter": {},
14+
"meta": {},
15+
"nodes": [
16+
[
17+
"blockquote",
18+
{},
19+
[
20+
"p",
21+
{
22+
"attr": "value"
23+
},
24+
"Blockquote paragraph 1"
25+
],
26+
[
27+
"p",
28+
{
29+
"attr2": "value2"
30+
},
31+
"Blockquote paragraph 2"
32+
]
33+
]
34+
]
35+
}
36+
```
37+
38+
## HTML
39+
40+
```html
41+
<blockquote>
42+
<p attr="value">Blockquote paragraph 1</p>
43+
<p attr2="value2">Blockquote paragraph 2</p>
44+
</blockquote>
45+
```
46+
47+
## Markdown
48+
49+
```md
50+
> Blockquote paragraph 1 {attr="value"}
51+
>
52+
> Blockquote paragraph 2 {attr2="value2"}
53+
```
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
## Input
2+
3+
```md
4+
> Blockquote {attr="value"}
5+
```
6+
7+
## AST
8+
9+
```json
10+
{
11+
"frontmatter": {},
12+
"meta": {},
13+
"nodes": [
14+
[
15+
"blockquote",
16+
{
17+
"attr": "value"
18+
},
19+
"Blockquote"
20+
]
21+
]
22+
}
23+
```
24+
25+
## HTML
26+
27+
```html
28+
<blockquote attr="value">
29+
Blockquote
30+
</blockquote>
31+
```
32+
33+
## Markdown
34+
35+
```md
36+
> Blockquote {attr="value"}
37+
```
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
## Input
2+
3+
```md
4+
- a list item {attr="value"}
5+
- another list item {attr2="value2"}
6+
```
7+
8+
## AST
9+
10+
```json
11+
{
12+
"frontmatter": {},
13+
"meta": {},
14+
"nodes": [
15+
[
16+
"ul",
17+
{},
18+
[
19+
"li",
20+
{
21+
"attr": "value"
22+
},
23+
"a list item"
24+
],
25+
[
26+
"li",
27+
{
28+
"attr2": "value2"
29+
},
30+
"another list item"
31+
]
32+
]
33+
]
34+
}
35+
```
36+
37+
## HTML
38+
39+
```html
40+
<ul>
41+
<li attr="value">a list item</li>
42+
<li attr2="value2">another list item</li>
43+
</ul>
44+
```
45+
46+
## Markdown
47+
48+
```md
49+
- a list item {attr="value"}
50+
- another list item {attr2="value2"}
51+
```
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
## Input
2+
3+
```md
4+
# h1 {attr="value"}
5+
6+
## h2 {attr="value"}
7+
8+
### h3 {attr="value"}
9+
10+
#### h4 {attr="value"}
11+
12+
##### h5 {attr="value"}
13+
14+
###### h6 {attr="value"}
15+
```
16+
17+
## AST
18+
19+
```json
20+
{
21+
"frontmatter": {},
22+
"meta": {},
23+
"nodes": [
24+
[
25+
"h1",
26+
{
27+
"id": "h1",
28+
"attr": "value"
29+
},
30+
"h1"
31+
],
32+
[
33+
"h2",
34+
{
35+
"id": "h2",
36+
"attr": "value"
37+
},
38+
"h2"
39+
],
40+
[
41+
"h3",
42+
{
43+
"id": "h2-h3",
44+
"attr": "value"
45+
},
46+
"h3"
47+
],
48+
[
49+
"h4",
50+
{
51+
"id": "h2-h3-h4",
52+
"attr": "value"
53+
},
54+
"h4"
55+
],
56+
[
57+
"h5",
58+
{
59+
"id": "h2-h3-h4-h5",
60+
"attr": "value"
61+
},
62+
"h5"
63+
],
64+
[
65+
"h6",
66+
{
67+
"id": "h2-h3-h4-h5-h6",
68+
"attr": "value"
69+
},
70+
"h6"
71+
]
72+
]
73+
}
74+
```
75+
76+
## HTML
77+
78+
```html
79+
<h1 id="h1" attr="value">h1</h1>
80+
<h2 id="h2" attr="value">h2</h2>
81+
<h3 id="h2-h3" attr="value">h3</h3>
82+
<h4 id="h2-h3-h4" attr="value">h4</h4>
83+
<h5 id="h2-h3-h4-h5" attr="value">h5</h5>
84+
<h6 id="h2-h3-h4-h5-h6" attr="value">h6</h6>
85+
```
86+
87+
## Markdown
88+
89+
```md
90+
# h1 {attr="value"}
91+
92+
## h2 {attr="value"}
93+
94+
### h3 {attr="value"}
95+
96+
#### h4 {attr="value"}
97+
98+
##### h5 {attr="value"}
99+
100+
###### h6 {attr="value"}
101+
```

0 commit comments

Comments
 (0)