starlight-obsidian 0.7.0 → 0.8.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,25 @@
1
1
  # starlight-obsidian
2
2
 
3
+ ## 0.8.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#45](https://github.com/HiDeoo/starlight-obsidian/pull/45) [`8d1b58c`](https://github.com/HiDeoo/starlight-obsidian/commit/8d1b58cc761ccf380f1dfad25f9b784a7ae4f6bf) Thanks [@HiDeoo](https://github.com/HiDeoo)! - ⚠️ **BREAKING CHANGE:** The minimum supported version of Starlight is now version `0.32.0`.
8
+
9
+ Please use the `@astrojs/upgrade` command to upgrade your project:
10
+
11
+ ```sh
12
+ npx @astrojs/upgrade
13
+ ```
14
+
15
+ - [#45](https://github.com/HiDeoo/starlight-obsidian/pull/45) [`8d1b58c`](https://github.com/HiDeoo/starlight-obsidian/commit/8d1b58cc761ccf380f1dfad25f9b784a7ae4f6bf) Thanks [@HiDeoo](https://github.com/HiDeoo)! - ⚠️ **BREAKING CHANGE:** The Starlight Obsidian plugin no longer [overrides](https://starlight.astro.build/guides/overriding-components/) the [`<PageSidebar>` component](https://starlight.astro.build/reference/overrides/#pagesidebar). If you were manually rendering `starlight-obsidian/overrides/PageSidebar.astro` in a custom override, you can now remove it.
16
+
17
+ ## 0.7.1
18
+
19
+ ### Patch Changes
20
+
21
+ - [#41](https://github.com/HiDeoo/starlight-obsidian/pull/41) [`ab86671`](https://github.com/HiDeoo/starlight-obsidian/commit/ab8667139930cad8322ed494a760547e896e7a27) Thanks [@HiDeoo](https://github.com/HiDeoo)! - Fixes an issue with custom aside titles including links.
22
+
3
23
  ## 0.7.0
4
24
 
5
25
  ### Minor Changes
@@ -0,0 +1,11 @@
1
+ ---
2
+ import Tags from '../Tags.astro'
3
+
4
+ const { entry } = Astro.locals.starlightRoute
5
+
6
+ // @ts-expect-error - This plugin does not extend Starlight's schema so tags are unknown.
7
+ const tags = entry['data']['tags']
8
+ const showTags = tags !== undefined && tags.length > 0
9
+ ---
10
+
11
+ {showTags && <Tags {tags} />}
package/index.ts CHANGED
@@ -106,7 +106,7 @@ const starlightObsidianConfigSchema = z.object({
106
106
  vault: z.string(),
107
107
  })
108
108
 
109
- let pluginsCount = 0
109
+ let overridesInjected = false
110
110
 
111
111
  export const obsidianSidebarGroup = getSidebarGroupPlaceholder()
112
112
 
@@ -122,7 +122,7 @@ export function createStarlightObsidianPlugin(): [plugin: typeof starlightObsidi
122
122
  function makeStarlightObsidianPlugin(
123
123
  sidebarGroup: SidebarGroup,
124
124
  ): (userConfig: StarlightObsidianUserConfig) => StarlightPlugin {
125
- pluginsCount++
125
+ overridesInjected = true
126
126
 
127
127
  return function starlightObsidianPlugin(userConfig) {
128
128
  const parsedConfig = starlightObsidianConfigSchema.safeParse(userConfig)
@@ -149,11 +149,22 @@ function makeStarlightObsidianPlugin(
149
149
  return {
150
150
  name: 'starlight-obsidian-plugin',
151
151
  hooks: {
152
- async setup({ addIntegration, command, config: starlightConfig, logger, updateConfig }) {
152
+ async 'config:setup'({
153
+ addIntegration,
154
+ addRouteMiddleware,
155
+ command,
156
+ config: starlightConfig,
157
+ logger,
158
+ updateConfig,
159
+ }) {
153
160
  if (command !== 'build' && command !== 'dev') {
154
161
  return
155
162
  }
156
163
 
164
+ if (config.tableOfContentsOverview === 'title') {
165
+ addRouteMiddleware({ entrypoint: 'starlight-obsidian/middleware' })
166
+ }
167
+
157
168
  const customCss = [...(starlightConfig.customCss ?? []), 'starlight-obsidian/styles/common']
158
169
 
159
170
  if (config.autoLinkHeadings) {
@@ -161,29 +172,14 @@ function makeStarlightObsidianPlugin(
161
172
  }
162
173
 
163
174
  const updatedStarlightConfig: Partial<StarlightUserConfig> = {
164
- components: starlightConfig.components,
175
+ components: {
176
+ ...starlightConfig.components,
177
+ ...overrideStarlightComponent(starlightConfig.components, logger, 'PageTitle'),
178
+ },
165
179
  customCss,
166
180
  sidebar: getSidebarFromConfig(config, starlightConfig.sidebar, sidebarGroup),
167
181
  }
168
182
 
169
- if (!updatedStarlightConfig.components) {
170
- updatedStarlightConfig.components = {}
171
- }
172
-
173
- if (starlightConfig.components?.PageTitle) {
174
- logComponentOverrideWarning(logger, 'PageTitle')
175
- } else {
176
- updatedStarlightConfig.components.PageTitle = 'starlight-obsidian/overrides/PageTitle.astro'
177
- }
178
-
179
- if (config.tableOfContentsOverview === 'title') {
180
- if (starlightConfig.components?.PageSidebar) {
181
- logComponentOverrideWarning(logger, 'PageSidebar')
182
- } else {
183
- updatedStarlightConfig.components.PageSidebar = 'starlight-obsidian/overrides/PageSidebar.astro'
184
- }
185
- }
186
-
187
183
  if (config.skipGeneration) {
188
184
  logger.warn(
189
185
  `Skipping generation of Starlight pages from Obsidian vault as the 'skipGeneration' option is enabled.`,
@@ -214,10 +210,26 @@ function makeStarlightObsidianPlugin(
214
210
  }
215
211
  }
216
212
 
217
- function logComponentOverrideWarning(logger: AstroIntegrationLogger, component: string) {
218
- if (pluginsCount < 2) {
219
- logger.warn(`It looks like you already have a \`${component}\` component override in your Starlight configuration.`)
220
- logger.warn(`To use \`starlight-obsidian\`, remove the override for the \`${component}\` component.\n`)
213
+ function overrideStarlightComponent(
214
+ components: StarlightUserConfig['components'],
215
+ logger: AstroIntegrationLogger,
216
+ component: keyof NonNullable<StarlightUserConfig['components']>,
217
+ ) {
218
+ if (components?.[component]) {
219
+ if (!overridesInjected) {
220
+ logger.warn(
221
+ `It looks like you already have a \`${component}\` component override in your Starlight configuration.`,
222
+ )
223
+ logger.warn(
224
+ `To use \`starlight-obsidian\`, either remove your override or update it to render the content from \`starlight-obsidian/components/${component}.astro\`.`,
225
+ )
226
+ }
227
+
228
+ return {}
229
+ }
230
+
231
+ return {
232
+ [component]: `starlight-obsidian/overrides/${component}.astro`,
221
233
  }
222
234
  }
223
235
 
package/libs/remark.ts CHANGED
@@ -5,7 +5,18 @@ import twitterMatcher from '@astro-community/astro-embed-twitter/matcher'
5
5
  import youtubeMatcher from '@astro-community/astro-embed-youtube/matcher'
6
6
  import { toHtml } from 'hast-util-to-html'
7
7
  import isAbsoluteUrl from 'is-absolute-url'
8
- import type { BlockContent, Blockquote, Code, Html, Image, Link, Parent, Root, RootContent } from 'mdast'
8
+ import type {
9
+ BlockContent,
10
+ Blockquote,
11
+ Code,
12
+ Html,
13
+ Image,
14
+ Link,
15
+ Parent,
16
+ PhrasingContent,
17
+ Root,
18
+ RootContent,
19
+ } from 'mdast'
9
20
  import { findAndReplace } from 'mdast-util-find-and-replace'
10
21
  import { toHast } from 'mdast-util-to-hast'
11
22
  import { customAlphabet } from 'nanoid'
@@ -385,7 +396,23 @@ function handleBlockquotes(node: Blockquote, context: VisitorContext) {
385
396
  return SKIP
386
397
  }
387
398
 
388
- const asideTitle = title && title.length > 0 ? `[${title.trim()}]` : ''
399
+ const hasTitle = title && title.length > 0
400
+ const asideTitle = hasTitle ? `[${title.trim()}` : ''
401
+ let didEndAsideTitle = false
402
+
403
+ let asideFirstLine = `${asideDelimiter}${getStarlightCalloutType(type)}${asideTitle}`
404
+ if (otherLines.length > 0) {
405
+ if (hasTitle) {
406
+ asideFirstLine += ']'
407
+ didEndAsideTitle = true
408
+ }
409
+ asideFirstLine += `\n${otherLines.join('\n')}`
410
+ } else if (otherGrandChildren.length === 0) {
411
+ asideFirstLine += ']\n'
412
+ didEndAsideTitle = true
413
+ } else {
414
+ asideFirstLine += ' '
415
+ }
389
416
 
390
417
  const aside: RootContent[] = [
391
418
  {
@@ -393,9 +420,22 @@ function handleBlockquotes(node: Blockquote, context: VisitorContext) {
393
420
  children: [
394
421
  {
395
422
  type: 'html',
396
- value: `${asideDelimiter}${getStarlightCalloutType(type)}${asideTitle}\n${otherLines.join('\n')}`,
423
+ value: asideFirstLine,
397
424
  },
398
- ...otherGrandChildren,
425
+ ...(hasTitle
426
+ ? otherGrandChildren.flatMap<PhrasingContent>((otherGrandChild) => {
427
+ if (didEndAsideTitle) return otherGrandChild
428
+ if (otherGrandChild.type !== 'text') return otherGrandChild
429
+ const containsNewLine = /\r?\n/.test(otherGrandChild.value)
430
+ if (!containsNewLine) return otherGrandChild
431
+ const [firstLine, ...otherLines] = otherGrandChild.value.split(/\r?\n/)
432
+ didEndAsideTitle = true
433
+ return [
434
+ { type: 'text', value: `${firstLine}]\n` },
435
+ { type: 'text', value: otherLines.join('\n') },
436
+ ]
437
+ })
438
+ : otherGrandChildren),
399
439
  ...(otherChildren.length === 0 ? [{ type: 'html', value: `\n${asideDelimiter}` } satisfies RootContent] : []),
400
440
  ],
401
441
  },
package/middleware.ts ADDED
@@ -0,0 +1,14 @@
1
+ import { defineRouteMiddleware } from '@astrojs/starlight/route-data'
2
+ import config from 'virtual:starlight-obsidian-config'
3
+
4
+ export const onRequest = defineRouteMiddleware((context) => {
5
+ const { entry, toc } = context.locals.starlightRoute
6
+
7
+ if (config.tableOfContentsOverview === 'title' && toc) {
8
+ const firstTocItem = toc.items.at(0)
9
+
10
+ if (firstTocItem) {
11
+ firstTocItem.text = entry['data'].title
12
+ }
13
+ }
14
+ })
@@ -1,15 +1,8 @@
1
1
  ---
2
2
  import Default from '@astrojs/starlight/components/PageTitle.astro'
3
- import type { Props } from '@astrojs/starlight/props'
4
3
 
5
- import Tags from '../components/Tags.astro'
6
-
7
- const { entry } = Astro.props
8
-
9
- // @ts-expect-error - This plugin does not extend Starlight's schema so tags are unknown.
10
- const tags = entry['data']['tags']
11
- const showTags = tags !== undefined && tags.length > 0
4
+ import StarlightObsidianPageTitle from '../components/starlight/PageTitle.astro'
12
5
  ---
13
6
 
14
- <Default {...Astro.props}><slot /></Default>
15
- {showTags && <Tags {tags} />}
7
+ <Default><slot /></Default>
8
+ <StarlightObsidianPageTitle><slot /></StarlightObsidianPageTitle>
package/package.json CHANGED
@@ -1,15 +1,16 @@
1
1
  {
2
2
  "name": "starlight-obsidian",
3
- "version": "0.7.0",
3
+ "version": "0.8.0",
4
4
  "license": "MIT",
5
5
  "description": "Starlight plugin to publish Obsidian vaults.",
6
6
  "author": "HiDeoo <github@hideoo.dev> (https://hideoo.dev)",
7
7
  "type": "module",
8
8
  "exports": {
9
9
  ".": "./index.ts",
10
+ "./components/PageTitle.astro": "./components/starlight/PageTitle.astro",
10
11
  "./components/Twitter.astro": "./components/Twitter.astro",
11
12
  "./components/Youtube.astro": "./components/Youtube.astro",
12
- "./overrides/PageSidebar.astro": "./overrides/PageSidebar.astro",
13
+ "./middleware": "./middleware.ts",
13
14
  "./overrides/PageTitle.astro": "./overrides/PageTitle.astro",
14
15
  "./schema": "./schema.ts",
15
16
  "./styles/common": "./styles/common.css",
@@ -54,7 +55,7 @@
54
55
  "vitest": "2.1.6"
55
56
  },
56
57
  "peerDependencies": {
57
- "@astrojs/starlight": ">=0.30.0"
58
+ "@astrojs/starlight": ">=0.32.0"
58
59
  },
59
60
  "engines": {
60
61
  "node": ">=18.17.1"
@@ -1,67 +0,0 @@
1
- ---
2
- import MobileTableOfContents from '@astrojs/starlight/components/MobileTableOfContents.astro'
3
- import TableOfContents from '@astrojs/starlight/components/TableOfContents.astro'
4
- import type { Props } from '@astrojs/starlight/props'
5
- import config from 'virtual:starlight-obsidian-config'
6
-
7
- const toc = Astro.props.toc
8
-
9
- if (config.tableOfContentsOverview === 'title' && toc) {
10
- const firstTocItem = toc.items.at(0)
11
-
12
- if (firstTocItem) {
13
- firstTocItem.text = Astro.props.entry['data'].title
14
- }
15
- }
16
- ---
17
-
18
- {
19
- Astro.props.toc && (
20
- <>
21
- <div class="lg:sl-hidden">
22
- <MobileTableOfContents {...Astro.props} {toc} />
23
- </div>
24
- <div class="right-sidebar-panel sl-hidden lg:sl-block">
25
- <div class="sl-container">
26
- <TableOfContents {...Astro.props} {toc} />
27
- </div>
28
- </div>
29
- </>
30
- )
31
- }
32
-
33
- <style>
34
- .right-sidebar-panel {
35
- padding: 1rem var(--sl-sidebar-pad-x);
36
- }
37
- .sl-container {
38
- width: calc(var(--sl-sidebar-width) - 2 * var(--sl-sidebar-pad-x));
39
- }
40
- .right-sidebar-panel :global(h2) {
41
- color: var(--sl-color-white);
42
- font-size: var(--sl-text-h5);
43
- font-weight: 600;
44
- line-height: var(--sl-line-height-headings);
45
- margin-bottom: 0.5rem;
46
- }
47
- .right-sidebar-panel :global(:where(a)) {
48
- display: block;
49
- font-size: var(--sl-text-xs);
50
- text-decoration: none;
51
- color: var(--sl-color-gray-3);
52
- overflow-wrap: anywhere;
53
- }
54
- .right-sidebar-panel :global(:where(a):hover) {
55
- color: var(--sl-color-white);
56
- }
57
- @media (min-width: 72rem) {
58
- .sl-container {
59
- max-width: calc(
60
- (
61
- (100vw - var(--sl-sidebar-width) - 2 * var(--sl-content-pad-x) - 2 * var(--sl-sidebar-pad-x)) * 0.25
62
- /* MAGIC NUMBER 🥲 */
63
- )
64
- );
65
- }
66
- }
67
- </style>