starlight-heading-badges 0.5.0 → 0.6.0

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/CHANGELOG.md CHANGED
@@ -1,5 +1,15 @@
1
1
  # starlight-heading-badges
2
2
 
3
+ ## 0.6.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#18](https://github.com/HiDeoo/starlight-heading-badges/pull/18) [`261fda4`](https://github.com/HiDeoo/starlight-heading-badges/commit/261fda465d560146c55a2f148f36a28de384fdc8) Thanks [@HiDeoo](https://github.com/HiDeoo)! - Adds support for rendering multiple badges to the same heading.
8
+
9
+ ### Patch Changes
10
+
11
+ - [#16](https://github.com/HiDeoo/starlight-heading-badges/pull/16) [`3a590c7`](https://github.com/HiDeoo/starlight-heading-badges/commit/3a590c7332c0bdaacd6109b5597b84cd5a415daf) Thanks [@HiDeoo](https://github.com/HiDeoo)! - Fixes an issue for heading badges with multiple spaces.
12
+
3
13
  ## 0.5.0
4
14
 
5
15
  ### Minor Changes
@@ -113,7 +113,7 @@ const { toc } = Astro.locals.starlightRoute
113
113
  </style>
114
114
 
115
115
  <script>
116
- import { deserializeBadge } from '../libs/badge'
116
+ import { deserializeBadges } from '../libs/badge'
117
117
  import { StarlightTOC } from '../libs/starlight-toc'
118
118
 
119
119
  class MobileStarlightTOC extends StarlightTOC {
@@ -123,15 +123,18 @@ const { toc } = Astro.locals.starlightRoute
123
123
  if (display) {
124
124
  const heading = link.dataset['shbHeading']
125
125
  if (heading) {
126
- const badge = deserializeBadge(heading)
127
- if (badge) {
126
+ const badges = deserializeBadges(heading)
127
+ if (badges.length > 0) {
128
128
  display.textContent = ''
129
- display.append(document.createTextNode(`${badge.heading} `))
130
- const span = document.createElement('span')
131
- span.textContent = badge.text
132
- span.dataset['shbBadge'] = ''
133
- span.dataset['shbBadgeVariant'] = badge.variant
134
- display.append(span)
129
+ display.append(document.createTextNode(`${badges[0]?.heading} `))
130
+
131
+ for (const badge of badges) {
132
+ const span = document.createElement('span')
133
+ span.textContent = badge.text
134
+ span.dataset['shbBadge'] = ''
135
+ span.dataset['shbBadgeVariant'] = badge.variant
136
+ display.append(span)
137
+ }
135
138
 
136
139
  return
137
140
  }
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  import { Badge } from '@astrojs/starlight/components'
3
3
 
4
- import { deserializeBadge } from '../libs/badge'
4
+ import { deserializeBadges } from '../libs/badge'
5
5
 
6
6
  interface Props {
7
7
  text: string
@@ -9,14 +9,16 @@ interface Props {
9
9
 
10
10
  const { text } = Astro.props
11
11
 
12
- const badge = deserializeBadge(text)
12
+ const badges = deserializeBadges(text)
13
13
  ---
14
14
 
15
15
  {
16
- badge ? (
16
+ badges.length > 0 ? (
17
17
  <span class="shb-heading">
18
- {badge.heading.trim()}&nbsp;
19
- <Badge size="small" text={badge.text} variant={badge.variant} />
18
+ {badges[0]?.heading.trim()}&nbsp;
19
+ {badges.map((badge) => (
20
+ <Badge size="small" text={badge.text} variant={badge.variant} />
21
+ ))}
20
22
  </span>
21
23
  ) : (
22
24
  <span>{text}</span>
package/libs/badge.ts CHANGED
@@ -14,23 +14,34 @@ export function serializeBadge(variant: Variant, text: string) {
14
14
  serializedBadgeDelimiter,
15
15
  variant,
16
16
  serializedBadgeDelimiter,
17
- text.replace(' ', serializedBadgeSpaceDelimiter),
17
+ text.replaceAll(' ', serializedBadgeSpaceDelimiter),
18
18
  serializedBadgeDelimiter,
19
19
  ].join('')
20
20
  }
21
21
 
22
- export function deserializeBadge(value: string): Badge | undefined {
23
- const serializeBadge = value.split(' ').pop()
24
- if (!serializeBadge) return
22
+ export function deserializeBadges(value: string): Badge[] {
23
+ const badges: Badge[] = []
25
24
 
26
- const parts = serializeBadge.split(serializedBadgeDelimiter)
25
+ const parts = value.split(' ').reverse()
26
+
27
+ for (const part of parts) {
28
+ const badge = deserializeBadge(value, part)
29
+ if (!badge) break
30
+ badges.unshift(badge)
31
+ }
32
+
33
+ return badges
34
+ }
35
+
36
+ function deserializeBadge(heading: string, value: string): Badge | undefined {
37
+ const parts = value.split(serializedBadgeDelimiter)
27
38
  const [, variant, text] = parts
28
39
 
29
40
  if (!variant || !isBadgeVariant(variant) || !text) return undefined
30
41
 
31
42
  return {
32
- heading: value.replace(new RegExp(`${serializedBadgeDelimiter}.*${serializedBadgeDelimiter}`), ''),
33
- text: text.replace(serializedBadgeSpaceDelimiter, ' '),
43
+ heading: heading.replace(new RegExp(`${serializedBadgeDelimiter}.*${serializedBadgeDelimiter}`), ''),
44
+ text: text.replaceAll(serializedBadgeSpaceDelimiter, ' '),
34
45
  variant,
35
46
  }
36
47
  }
package/libs/rehype.ts CHANGED
@@ -3,7 +3,7 @@ import 'mdast-util-directive'
3
3
  import type { ElementContent, Root } from 'hast'
4
4
  import { CONTINUE, SKIP, visit } from 'unist-util-visit'
5
5
 
6
- import { deserializeBadge, type Badge } from './badge'
6
+ import { deserializeBadges, type Badge } from './badge'
7
7
 
8
8
  export function rehypeStarlightHeadingBadges() {
9
9
  return function transformer(tree: Root) {
@@ -11,14 +11,16 @@ export function rehypeStarlightHeadingBadges() {
11
11
  if (node.type === 'text') {
12
12
  if (index === undefined || !parent) return CONTINUE
13
13
 
14
- const badge = deserializeBadge(node.value)
15
- if (!badge) return SKIP
14
+ const badges = deserializeBadges(node.value)
15
+ if (badges.length === 0) return SKIP
16
16
 
17
- if (badge.heading) {
18
- node.value = badge.heading
19
- parent.children.splice(index + 1, 0, createBadgeNode(badge))
20
- } else {
21
- parent.children.splice(index, 1, createBadgeNode(badge))
17
+ for (const badge of badges.reverse()) {
18
+ if (badge.heading) {
19
+ node.value = badge.heading
20
+ parent.children.splice(index + 1, 0, ...createBadgeNode(badge))
21
+ } else {
22
+ parent.children.splice(index, 1, ...createBadgeNode(badge))
23
+ }
22
24
  }
23
25
 
24
26
  return SKIP
@@ -29,14 +31,20 @@ export function rehypeStarlightHeadingBadges() {
29
31
  }
30
32
  }
31
33
 
32
- function createBadgeNode(badge: Badge): ElementContent {
33
- return {
34
- type: 'element',
35
- tagName: 'span',
36
- properties: {
37
- 'data-shb-badge': '',
38
- 'data-shb-badge-variant': badge.variant,
34
+ function createBadgeNode(badge: Badge): ElementContent[] {
35
+ return [
36
+ {
37
+ type: 'element',
38
+ tagName: 'span',
39
+ properties: {
40
+ 'data-shb-badge': '',
41
+ 'data-shb-badge-variant': badge.variant,
42
+ },
43
+ children: [{ type: 'text', value: badge.text }],
39
44
  },
40
- children: [{ type: 'text', value: badge.text }],
41
- }
45
+ {
46
+ type: 'text',
47
+ value: ' ',
48
+ },
49
+ ]
42
50
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "starlight-heading-badges",
3
- "version": "0.5.0",
3
+ "version": "0.6.0",
4
4
  "license": "MIT",
5
5
  "description": "Starlight plugin to add badges to your Markdown and MDX headings.",
6
6
  "author": "HiDeoo <github@hideoo.dev> (https://hideoo.dev)",