Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: config for anchor link generation of headings #1564

Merged
merged 9 commits into from
Oct 13, 2022
27 changes: 20 additions & 7 deletions docs/content/4.api/3.configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -163,13 +163,7 @@ Whether MDC syntax should be supported or not.
### `toc`

- Type: `Object`{lang=ts}
- Default
```ts
{
depth: 2,
searchDepth: 2
}
```
- Default: `{ depth: 2, searchDepth: 2 }`{lang="ts"}

Control behavior of Table of Contents generation.

Expand All @@ -194,6 +188,25 @@ export default defineNuxtConfig({
})
```

### `anchorLinks`

- Type: `Boolean | Object`{lang=ts}
- Default: `{depth: 4, exclude: [1]}`{lang=ts}

By default Content module generates anchor links for `h2`, `h3` and `h4` heading. Using this option you can control link generation.

`false`{lang=ts} will disable link generation.

`true`{lang=ts} will enable link generation for all headings.

**options**

| Option | Type | Description |
| ------- | :--------: | :------------------------------------------------------- |
| depth | `number` | Sets the maximal depth for anchor link generation. |
| exclude | `number[]` | A list of which headings to exclude from link generation |


## `highlight`

- Type: `false | Object`{lang=ts}
Expand Down
52 changes: 49 additions & 3 deletions src/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,26 @@ export interface ModuleOptions {
*
* @default []
*/
rehypePlugins?: Array<string | [string, MarkdownPlugin]> | Record<string, false | MarkdownPlugin>
rehypePlugins?: Array<string | [string, MarkdownPlugin]> | Record<string, false | MarkdownPlugin>,
/**
* Anchor link generation config
*
* @default {}
*/
anchorLinks?: boolean | {
/**
* Sets the maximal depth for anchor link generation
*
* @default 4
*/
depth?: number,
/**
* Excludes headings from link generation when they are in the depth range.
*
* @default [1]
*/
exclude?: number[]
}
}
/**
* Content module uses `shiki` to highlight code blocks.
Expand Down Expand Up @@ -223,7 +242,11 @@ export default defineNuxtModule<ModuleOptions>({
defaultLocale: undefined,
highlight: false,
markdown: {
tags: Object.fromEntries(PROSE_TAGS.map(t => [t, `prose-${t}`]))
tags: Object.fromEntries(PROSE_TAGS.map(t => [t, `prose-${t}`])),
anchorLinks: {
depth: 4,
exclude: [1]
}
},
yaml: {},
csv: {
Expand Down Expand Up @@ -504,6 +527,27 @@ export default defineNuxtModule<ModuleOptions>({
])
}

// Register anchor link generation
if (options.markdown.anchorLinks === true) {
options.markdown.anchorLinks = {
depth: 6,
exclude: []
}
} else if (options.markdown.anchorLinks === false) {
options.markdown.anchorLinks = {
depth: 0,
exclude: []
}
} else {
options.markdown.anchorLinks = {
...{
depth: 4,
exclude: [1]
},
...options.markdown.anchorLinks
}
}

// @ts-ignore
await nuxt.callHook('content:context', contentContext)

Expand Down Expand Up @@ -533,7 +577,9 @@ export default defineNuxtModule<ModuleOptions>({
highlight: options.highlight as any,
wsUrl: '',
// Document-driven configuration
documentDriven: options.documentDriven as ModuleOptions['documentDriven']
documentDriven: options.documentDriven as ModuleOptions['documentDriven'],
// Anchor link generation config
anchorLinks: options.markdown.anchorLinks
})

// Context will use in server
Expand Down
14 changes: 13 additions & 1 deletion src/runtime/components/Prose/ProseH1.vue
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
<template>
<h1><slot /></h1>
<h1 :id="id">
<a v-if="generate" :href="`#${id}`">
<slot />
</a>
<slot v-else />
</h1>
</template>

<script setup lang="ts">
defineProps<{ id: string }>()
const heading = 1
const { anchorLinks } = useRuntimeConfig().public.content
const generate = anchorLinks?.depth >= heading && !anchorLinks?.exclude.includes(heading)
</script>
6 changes: 5 additions & 1 deletion src/runtime/components/Prose/ProseH2.vue
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
<template>
<h2 :id="id">
<a :href="`#${id}`">
<a v-if="generate" :href="`#${id}`">
<slot />
</a>
<slot v-else />
</h2>
</template>

<script setup lang="ts">
defineProps<{ id: string }>()
const heading = 2
const { anchorLinks } = useRuntimeConfig().public.content
const generate = anchorLinks?.depth >= heading && !anchorLinks?.exclude.includes(heading)
</script>
6 changes: 5 additions & 1 deletion src/runtime/components/Prose/ProseH3.vue
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
<template>
<h3 :id="id">
<a :href="`#${id}`">
<a v-if="generate" :href="`#${id}`">
<slot />
</a>
<slot v-else />
</h3>
</template>

<script setup lang="ts">
defineProps<{ id: string }>()
const heading = 3
const { anchorLinks } = useRuntimeConfig().public.content
const generate = anchorLinks?.depth >= heading && !anchorLinks?.exclude.includes(heading)
</script>
6 changes: 5 additions & 1 deletion src/runtime/components/Prose/ProseH4.vue
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
<template>
<h4 :id="id">
<a :href="`#${id}`">
<a v-if="generate" :href="`#${id}`">
<slot />
</a>
<slot v-else />
</h4>
</template>

<script setup lang="ts">
defineProps<{ id: string }>()
const heading = 4
const { anchorLinks } = useRuntimeConfig().public.content
const generate = anchorLinks?.depth >= heading && !anchorLinks?.exclude.includes(heading)
</script>
14 changes: 13 additions & 1 deletion src/runtime/components/Prose/ProseH5.vue
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
<template>
<h5><slot /></h5>
<h5 :id="id">
<a v-if="generate" :href="`#${id}`">
<slot />
</a>
<slot v-else />
</h5>
</template>

<script setup lang="ts">
defineProps<{ id: string }>()
const heading = 5
const { anchorLinks } = useRuntimeConfig().public.content
const generate = anchorLinks?.depth >= heading && !anchorLinks?.exclude.includes(heading)
</script>
14 changes: 13 additions & 1 deletion src/runtime/components/Prose/ProseH6.vue
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
<template>
<h6><slot /></h6>
<h6 :id="id">
<a v-if="generate" :href="`#${id}`">
<slot />
</a>
<slot v-else />
</h6>
</template>

<script setup lang="ts">
defineProps<{ id: string }>()
const heading = 6
const { anchorLinks } = useRuntimeConfig().public.content
const generate = anchorLinks?.depth >= heading && !anchorLinks?.exclude.includes(heading)
</script>