starlight-obsidian 0.8.2 → 0.9.1

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,39 @@
1
1
  # starlight-obsidian
2
2
 
3
+ ## 0.9.1
4
+
5
+ ### Patch Changes
6
+
7
+ - [#56](https://github.com/HiDeoo/starlight-obsidian/pull/56) [`ff18bbd`](https://github.com/HiDeoo/starlight-obsidian/commit/ff18bbd6b2614e5e817fdca2005825ea1841e0a0) Thanks [@HiDeoo](https://github.com/HiDeoo)! - Fixes a potential syntax issue when converting Obsidian vault files containing void elements to MDX format.
8
+
9
+ ## 0.9.0
10
+
11
+ ### Minor Changes
12
+
13
+ - [#53](https://github.com/HiDeoo/starlight-obsidian/pull/53) [`be89246`](https://github.com/HiDeoo/starlight-obsidian/commit/be8924661655c041a7339d040c4518e74e39defb) Thanks [@HiDeoo](https://github.com/HiDeoo)! - ⚠️ **BREAKING CHANGE:** The minimum supported version of Starlight is now version `0.34.0`.
14
+
15
+ Please use the `@astrojs/upgrade` command to upgrade your project:
16
+
17
+ ```sh
18
+ npx @astrojs/upgrade
19
+ ```
20
+
21
+ - [#53](https://github.com/HiDeoo/starlight-obsidian/pull/53) [`be89246`](https://github.com/HiDeoo/starlight-obsidian/commit/be8924661655c041a7339d040c4518e74e39defb) Thanks [@HiDeoo](https://github.com/HiDeoo)! - Removes the `autoLinkHeadings` option.
22
+
23
+ ⚠️ **BREAKING CHANGE:** The `autoLinkHeadings` option has been removed and this feature is now built-in to Starlight and configurable using the Starlight [`markdown.headingLinks` configuration option](https://starlight.astro.build/reference/configuration/#headinglinks) which is enabled by default.
24
+
25
+ To conserve the previous default behavior of the plugin, set `markdown.headingLinks` to `false` in your Starlight configuration.
26
+
27
+ ```js
28
+ // astro.config.mjs
29
+ starlight({
30
+ markdown: {
31
+ // Disable Starlight’s clickable heading anchor links.
32
+ headingLinks: false,
33
+ },
34
+ }),
35
+ ```
36
+
3
37
  ## 0.8.2
4
38
 
5
39
  ### Patch Changes
package/index.ts CHANGED
@@ -10,12 +10,6 @@ import { throwUserError } from './libs/plugin'
10
10
  import { addObsidianFiles, getSidebarFromConfig, getSidebarGroupPlaceholder, type SidebarGroup } from './libs/starlight'
11
11
 
12
12
  const starlightObsidianConfigSchema = z.object({
13
- /**
14
- * Add links to Starlight headings to make it easier to share a link to a specific section of a page.
15
- *
16
- * @default false
17
- */
18
- autoLinkHeadings: z.boolean().default(false),
19
13
  /**
20
14
  * The name of the Obsidian vault configuration folder if different from the default one.
21
15
  *
@@ -165,18 +159,12 @@ function makeStarlightObsidianPlugin(
165
159
  addRouteMiddleware({ entrypoint: 'starlight-obsidian/middleware' })
166
160
  }
167
161
 
168
- const customCss = [...(starlightConfig.customCss ?? []), 'starlight-obsidian/styles/common']
169
-
170
- if (config.autoLinkHeadings) {
171
- customCss.push('starlight-obsidian/styles/autolinks-headings')
172
- }
173
-
174
162
  const updatedStarlightConfig: Partial<StarlightUserConfig> = {
175
163
  components: {
176
164
  ...starlightConfig.components,
177
165
  ...overrideStarlightComponent(starlightConfig.components, logger, 'PageTitle'),
178
166
  },
179
- customCss,
167
+ customCss: [...(starlightConfig.customCss ?? []), 'starlight-obsidian/styles/common'],
180
168
  sidebar: getSidebarFromConfig(config, starlightConfig.sidebar, sidebarGroup),
181
169
  }
182
170
 
@@ -1,12 +1,10 @@
1
- import { rehypeHeadingIds } from '@astrojs/markdown-remark'
2
1
  import type { AstroIntegration } from 'astro'
3
- import rehypeAutolinkHeadings from 'rehype-autolink-headings'
4
2
  import rehypeKatex from 'rehype-katex'
5
3
  import remarkMath from 'remark-math'
6
4
 
7
5
  import type { StarlightObsidianConfig } from '..'
8
6
 
9
- import { getRehypeAutolinkHeadingsOptions, rehypeStarlightObsidian } from './rehype'
7
+ import { rehypeStarlightObsidian } from './rehype'
10
8
  import { vitePluginStarlightObsidianConfig } from './vite'
11
9
 
12
10
  export function starlightObsidianIntegration(config: StarlightObsidianConfig): AstroIntegration {
@@ -16,13 +14,7 @@ export function starlightObsidianIntegration(config: StarlightObsidianConfig): A
16
14
  'astro:config:setup': ({ updateConfig }) => {
17
15
  updateConfig({
18
16
  markdown: {
19
- rehypePlugins: [
20
- ...(config.autoLinkHeadings
21
- ? [rehypeHeadingIds, [rehypeAutolinkHeadings, getRehypeAutolinkHeadingsOptions()]]
22
- : []),
23
- rehypeStarlightObsidian,
24
- rehypeKatex,
25
- ],
17
+ rehypePlugins: [rehypeStarlightObsidian, rehypeKatex],
26
18
  remarkPlugins: [remarkMath],
27
19
  },
28
20
  vite: {
package/libs/rehype.ts CHANGED
@@ -1,9 +1,5 @@
1
1
  import type { Element, ElementContent, Root } from 'hast'
2
- import { toString } from 'hast-util-to-string'
3
- import { h } from 'hastscript'
4
- import { escape } from 'html-escaper'
5
2
  import type { Literal } from 'mdast'
6
- import type { Options as RehypeAutolinkHeadingsOptions } from 'rehype-autolink-headings'
7
3
  import { CONTINUE, SKIP, visit } from 'unist-util-visit'
8
4
 
9
5
  const blockIdentifierRegex = /(?<identifier> *\^(?<name>[\w-]+))$/
@@ -42,24 +38,6 @@ export function rehypeStarlightObsidian() {
42
38
  }
43
39
  }
44
40
 
45
- // https://hideoo.dev/notes/starlight-heading-links
46
- // https://github.com/withastro/docs/blob/main/plugins/rehype-autolink.ts
47
- // https://amberwilson.co.uk/blog/are-your-anchor-links-accessible/
48
- export function getRehypeAutolinkHeadingsOptions(): RehypeAutolinkHeadingsOptions {
49
- return {
50
- behavior: 'after',
51
- content: (heading) => {
52
- return [
53
- h('span', { ariaHidden: 'true' }, '§'),
54
- h('span', { class: 'sr-only' }, `Section titled ${escape(toString(heading))}`),
55
- ]
56
- },
57
- group: ({ tagName }) =>
58
- h('div', { class: `sl-obs-section sl-obs-section-level-${tagName.slice(1)}`, tabIndex: -1 }),
59
- properties: { class: 'sl-obs-heading-link' },
60
- }
61
- }
62
-
63
41
  function transformBlockIdentifier(reference: Element, node: ElementContent | undefined) {
64
42
  if (!isNodeWithValue(node)) {
65
43
  return CONTINUE
package/libs/remark.ts CHANGED
@@ -50,6 +50,7 @@ const wikilinkReplacementRegex = /!?\[\[(?<url>(?:(?![[\]|]).)+)(?:\|(?<maybeTex
50
50
  const tagReplacementRegex = /(?:^|\s)#(?<tag>[\w/-]+)/g
51
51
  const calloutRegex = /^\[!(?<type>\w+)][+-]? ?(?<title>.*)$/
52
52
  const imageSizeRegex = /^(?:(?<altText>.*)\|)?(?:(?<widthOnly>\d+)|(?:(?<width>\d+)x(?<height>\d+)))$/
53
+ const mdxNonClosingVoidElementRegex = /<(?<tag>br|hr)(?<attrs>[^/>]*)>/g
53
54
 
54
55
  const asideDelimiter = ':::'
55
56
 
@@ -88,6 +89,10 @@ export function remarkStarlightObsidian() {
88
89
 
89
90
  handleFrontmatter(tree, file, obsidianFrontmatter)
90
91
  handleImports(tree, file)
92
+
93
+ if (file.data.isMdx) {
94
+ closeVoidElements(tree)
95
+ }
91
96
  }
92
97
  }
93
98
 
@@ -750,6 +755,19 @@ function createMdxNode(value: string): Html {
750
755
  return { type: 'html', value }
751
756
  }
752
757
 
758
+ // We are not using `remark-mdx` due to the fact that it makes the parsing step way more strict. During our inital
759
+ // testing round, we found out that a few users had pretty poorly formatted Markdown files (usually the result of
760
+ // various Obisidian migration tools) and we wanted to make sure that they could still use Starlight Obsidian.
761
+ // In MDX files, if the source content contains non-closing void elements, we need to convert them to self-closing
762
+ // ones, e.g. `<br>` to `<br/>`.
763
+ // At the moment, we only support `br` and `hr` elements, but based on feedback, we can eventually support all of them.
764
+ function closeVoidElements(tree: Root) {
765
+ visit(tree, 'html', (node) => {
766
+ node.value = node.value.replaceAll(mdxNonClosingVoidElementRegex, '<$<tag>$<attrs>/>')
767
+ return SKIP
768
+ })
769
+ }
770
+
753
771
  function ensureTransformContext(file: VFile): asserts file is VFile & { data: TransformContext; dirname: string } {
754
772
  if (!file.dirname || !file.data.files || file.data.output === undefined || !file.data.vault) {
755
773
  throw new Error('Invalid transform context.')
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "starlight-obsidian",
3
- "version": "0.8.2",
3
+ "version": "0.9.1",
4
4
  "license": "MIT",
5
5
  "description": "Starlight plugin to publish Obsidian vaults.",
6
6
  "author": "HiDeoo <github@hideoo.dev> (https://hideoo.dev)",
@@ -14,27 +14,21 @@
14
14
  "./overrides/PageTitle.astro": "./overrides/PageTitle.astro",
15
15
  "./schema": "./schema.ts",
16
16
  "./styles/common": "./styles/common.css",
17
- "./styles/autolinks-headings": "./styles/autolinks-headings.css",
18
17
  "./package.json": "./package.json"
19
18
  },
20
19
  "dependencies": {
21
20
  "@astro-community/astro-embed-twitter": "^0.5.8",
22
21
  "@astro-community/astro-embed-youtube": "^0.5.6",
23
- "@astrojs/markdown-remark": "^6.0.0",
24
22
  "decode-uri-component": "^0.4.1",
25
23
  "github-slugger": "^2.0.0",
26
24
  "globby": "^14.0.2",
27
25
  "hast-util-to-html": "^9.0.4",
28
- "hast-util-to-string": "^3.0.1",
29
- "hastscript": "^9.0.0",
30
- "html-escaper": "^3.0.3",
31
26
  "is-absolute-url": "^4.0.1",
32
27
  "mdast-util-find-and-replace": "^3.0.1",
33
28
  "mdast-util-from-markdown": "^2.0.2",
34
29
  "mdast-util-to-hast": "^13.2.0",
35
30
  "nanoid": "^5.0.9",
36
31
  "rehype": "^13.0.2",
37
- "rehype-autolink-headings": "^7.1.0",
38
32
  "rehype-katex": "^7.0.1",
39
33
  "rehype-mermaid": "^2.1.0",
40
34
  "remark": "^15.0.1",
@@ -47,7 +41,6 @@
47
41
  },
48
42
  "devDependencies": {
49
43
  "@types/hast": "^3.0.4",
50
- "@types/html-escaper": "^3.0.2",
51
44
  "@types/mdast": "^4.0.4",
52
45
  "@types/node": "^18.19.68",
53
46
  "@types/unist": "^3.0.3",
@@ -55,7 +48,7 @@
55
48
  "vitest": "2.1.6"
56
49
  },
57
50
  "peerDependencies": {
58
- "@astrojs/starlight": ">=0.32.0"
51
+ "@astrojs/starlight": ">=0.34.0"
59
52
  },
60
53
  "engines": {
61
54
  "node": ">=18.17.1"
@@ -1,68 +0,0 @@
1
- .sl-markdown-content :not(.sl-obs-section) + :is(.sl-obs-section):not(:where(.not-content *)) {
2
- margin-top: 1.5em;
3
- }
4
-
5
- .sl-markdown-content .sl-obs-section {
6
- --sl-obs-heading-link-spacing: 0.25em;
7
-
8
- line-height: var(--sl-line-height-headings);
9
- }
10
-
11
- .sl-markdown-content .sl-obs-section.sl-obs-section-level-1 {
12
- font-size: var(--sl-text-h1);
13
- }
14
-
15
- .sl-markdown-content .sl-obs-section.sl-obs-section-level-2 {
16
- font-size: var(--sl-text-h2);
17
- }
18
-
19
- .sl-markdown-content .sl-obs-section.sl-obs-section-level-3 {
20
- font-size: var(--sl-text-h3);
21
- }
22
-
23
- .sl-markdown-content .sl-obs-section.sl-obs-section-level-4 {
24
- font-size: var(--sl-text-h4);
25
- }
26
-
27
- .sl-markdown-content .sl-obs-section.sl-obs-section-level-5 {
28
- font-size: var(--sl-text-h5);
29
- }
30
-
31
- .sl-markdown-content .sl-obs-section.sl-obs-section-level-6 {
32
- font-size: var(--sl-text-h6);
33
- }
34
-
35
- .sl-markdown-content .sl-obs-section > :first-child {
36
- display: inline;
37
- margin-inline-end: var(--sl-obs-heading-link-spacing);
38
- }
39
-
40
- .sl-markdown-content .sl-obs-heading-link {
41
- color: var(--sl-color-gray-3);
42
- text-decoration: none;
43
- }
44
-
45
- .sl-markdown-content .sl-obs-heading-link:is(:hover, :focus) {
46
- color: var(--sl-color-text-accent);
47
- }
48
-
49
- @media (hover: hover) {
50
- .sl-markdown-content .sl-obs-heading-link {
51
- opacity: 0;
52
- }
53
- }
54
-
55
- .sl-markdown-content .sl-obs-section:hover > .sl-obs-heading-link,
56
- .sl-markdown-content .sl-obs-heading-link:focus {
57
- opacity: 1;
58
- }
59
-
60
- @media (min-width: 95em) {
61
- .sl-markdown-content .sl-obs-section {
62
- display: flex;
63
- flex-direction: row-reverse;
64
- gap: var(--sl-obs-heading-link-spacing);
65
- justify-content: flex-end;
66
- margin-inline-start: calc(-1 * (1ch + var(--sl-obs-heading-link-spacing)));
67
- }
68
- }