Skip to content

Commit

Permalink
fix: allow ] in filename code block (#2169)
Browse files Browse the repository at this point in the history
Co-authored-by: nobkd <44443899+nobkd@users.noreply.github.com>
  • Loading branch information
Barbapapazes and nobkd committed Jul 24, 2023
1 parent a6c549e commit 7a6ab10
Show file tree
Hide file tree
Showing 13 changed files with 114 additions and 20 deletions.
2 changes: 1 addition & 1 deletion docs/content/2.get-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ The module automatically loads and parses them.

To render content pages, add a [catch-all route](https://nuxt.com/docs/guide/directory-structure/pages/#catch-all-route) using the `ContentDoc` component:

```vue [pages/[...slug].vue]
```vue [pages/[...slug\\].vue]
<template>
<main>
<ContentDoc />
Expand Down
2 changes: 1 addition & 1 deletion docs/content/3.guide/2.displaying/1.rendering.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ The fetching endpoint defaults to the current route (`$route.path`). An explicit

Create a [catch all route](https://nuxt.com/docs/guide/directory-structure/pages/#catch-all-route) named `pages/[...slug].vue` and add the component:

```vue [pages/[...slug].vue]
```vue [pages/[...slug\\].vue]
<template>
<main>
<ContentDoc />
Expand Down
2 changes: 1 addition & 1 deletion docs/content/4.api/1.components/1.content-doc.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ The `empty`{lang=ts} slot can be used to display a default content before render

### Default

```html [pages/[...slug.vue]]
```html [pages/[...slug\\].vue]
<template>
<main>
<!-- Similar to <ContentDoc :path="$route.path" /> -->
Expand Down
6 changes: 3 additions & 3 deletions docs/content/4.api/1.components/2.content-renderer.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ Other types will currently be passed to default slot via `v-slot="{ data }"` or

The `default`{lang=ts} slot can be used to render the content via `v-slot="{ data }"` syntax.

```html [pages/[...slug.vue]]
```html [pages/[...slug\\].vue]
<script setup lang="ts">
const { data } = await useAsyncData('page-data', () => queryContent('/hello').findOne())
</script>
Expand All @@ -44,7 +44,7 @@ const { data } = await useAsyncData('page-data', () => queryContent('/hello').fi

The `empty`{lang=ts} slot can be used to display a default content when the document is empty:

```html [pages/[...slug.vue]]
```html [pages/[...slug\\].vue]
<script setup lang="ts">
const { data } = await useAsyncData('page-data', () => queryContent('/hello').findOne())
</script>
Expand All @@ -63,7 +63,7 @@ const { data } = await useAsyncData('page-data', () => queryContent('/hello').fi
::alert{type="info"}
Note that when you use default slot and `<ContentRendererMarkdown>` in your template you need to pass `components` to `<ContentRendererMarkdown>`.

```html [pages/[...slug].vue]
```html [pages/[...slug\\].vue]
<script setup lang="ts">
const { data } = await useAsyncData('page-data', () => queryContent('/hello').findOne())
Expand Down
4 changes: 2 additions & 2 deletions docs/content/4.api/1.components/4.content-query.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ The `<ContentQuery>`{lang=html} component fetches a document and gives access to

The `default`{lang=ts} slot can be used to render the content via `v-slot="{ data }"`{lang=html} syntax.

```html [pages/[...slug.vue]]
```html [pages/[...slug\\].vue]
<!-- Similar to <ContentDoc :path="$route.path" /> -->
<template>
<main>
Expand All @@ -63,7 +63,7 @@ The `not-found`{lang=ts} slot can be used to display a default content before re
<template>
<main>
<ContentQuery path="/about/authors" :where="{ type: 'csv' }">
<template #default="{ data }">
<template #default="{ data }">
<ul>
<li v-for="author of data" :key="author.name">
{{ author.name }}
Expand Down
4 changes: 4 additions & 0 deletions docs/content/4.api/1.components/7.prose.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,10 @@ Component properties will be:

Check out the [highlight options](/api/configuration#highlight) for more about the syntax highlighting.

::alert{type="warning"}
If you want to use `]` in the filename, you need to escape it with 2 backslashes: `\\]`. This is necessary since JS will automatically escape the backslash in a string so `\]` will be resolved as `]` breaking our regex.
::

## `ProseCodeInline`

[:icon{name="fa-brands:github" class="inline -mt-1 w-6"} Source](https://github.com/nuxt/content/tree/main/src/runtime/components/Prose/ProseCodeInline.vue)
Expand Down
2 changes: 1 addition & 1 deletion docs/content/4.api/2.composables/4.use-document-driven.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ const {

Rendering the current page becomes a bliss with this composable:

```vue [pages/[...slug].vue]
```vue [pages/[...slug\\].vue]
<script setup lang="ts">
const { page } = useContent()
</script>
Expand Down
4 changes: 2 additions & 2 deletions docs/content/6.blog/1.announcing-v2.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ authors:
- name: "Ahad Birang"
avatarUrl: https://pbs.twimg.com/profile_images/780374165136244736/x5HfdWA1_400x400.jpg
link: https://twitter.com/a_birang
- name: "Clément Ollivier"
- name: "Clément Ollivier"
avatarUrl: https://pbs.twimg.com/profile_images/1370286658432724996/ZMSDzzIi_400x400.jpg
link: https://twitter.com/clemcodes
tags:
Expand Down Expand Up @@ -63,7 +63,7 @@ https://content.nuxtjs.org

Create a `pages/[...slug].vue` file with the [`<ContentDoc>`](/guide/displaying/rendering) component inside:

```vue [pages/[...slug].vue]
```vue [pages/[...slug\\].vue]
<template>
<ContentDoc />
</template>
Expand Down
36 changes: 36 additions & 0 deletions playground/basic/components/content/ProseCode.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<script lang="ts" setup>
defineProps<{
code: string,
language?: string,
filename?: string,
highlights: number[],
meta?: string
}>()
</script>

<template>
<div v-if="language">
language <br>
{{ language }}
</div>
<div v-if="filename">
filename <br>
{{ filename }}
</div>
<div v-if="highlights">
highlights <br>
{{ highlights }}
</div>
<div v-if="meta">
meta <br>
{{ meta }}
</div>
<slot />
</template>

<style>
pre code .line {
display: block;
min-height: 1rem;
}
</style>
2 changes: 1 addition & 1 deletion playground/basic/content/1.real-content/content.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export default defineNuxtConfig({
Render any document content.

```vue [pages/[...slug].vue]
```vue [pages/[...slug\\].vue]
<script setup>
const route = useRoute()
const { data } = await useAsyncData(`doc-${route.path}`, () => queryContent(route.path).findOne())
Expand Down
2 changes: 1 addition & 1 deletion playground/basic/content/2.features/3.mdc-highlighter.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ title: title
array:
- item
- itemKey: itemValue
object:
object:
name: object
version: 1
string: "string"
Expand Down
49 changes: 49 additions & 0 deletions playground/basic/content/2.features/8.custom-prose.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
```vue [[...page\\].vue]{1} title="Custom Prose"
<template>
<div>
<h1>Custom Prose</h1>
</div>
</template>
```
```vue [[...page\\].vue] title="Custom Prose"
<template>
<div>
<h1>Custom Prose</h1>
</div>
</template>
```
```vue [[...page\\].vue]{1}
<template>
<div>
<h1>Custom Prose</h1>
</div>
</template>
```
```vue title="Custom Prose"
<template>
<div>
<h1>Custom Prose</h1>
</div>
</template>
```
```vue [file.js] {2-4}title="Custom Prose"
<template>
<div>
<h1>Custom Prose</h1>
</div>
</template>
```
```ts[[...page\\].vue] {4-6,7} other code block info
<template>
<div>
<h1>Custom Prose</h1>
</div>
</template>
```
```[] {4-6,7} other code block info
<template>
<div>
<h1>Custom Prose</h1>
</div>
</template>
```
19 changes: 12 additions & 7 deletions src/runtime/markdown-parser/handler/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,20 @@ export function parseThematicBlock (lang: string) {
}
}

const language = lang.replace(/[{|[](.+)/, '').match(/^[^ \t]+(?=[ \t]|$)/)
const highlightTokens = lang.match(/{([^}]*)}/)
const filenameTokens = lang.match(/\[([^\]]*)\]/)
const meta = lang.replace(/^\w*\s*(\[[^\]]*\]|\{[^}]*\})?\s*(\[[^\]]*\]|\{[^}]*\})?\s*/, '')
const languageMatches = lang.replace(/[{|[](.+)/, '').match(/^[^ \t]+(?=[ \t]|$)/)
const highlightTokensMatches = lang.match(/{([^}]*)}/)
const filenameMatches = lang.match(/\[((\\]|[^\]])*)\]/)

const meta = lang
.replace(languageMatches?.[0] ?? '', '')
.replace(highlightTokensMatches?.[0] ?? '', '')
.replace(filenameMatches?.[0] ?? '', '')
.trim()

return {
language: language ? language[0] : undefined,
highlights: parseHighlightedLines(highlightTokens && highlightTokens[1]),
filename: Array.isArray(filenameTokens) && filenameTokens[1] ? filenameTokens[1] : undefined,
language: languageMatches?.[0] || undefined,
highlights: parseHighlightedLines(highlightTokensMatches?.[1] || undefined),
filename: filenameMatches?.[1].replace(/\\]/g, ']') || undefined,
meta
}
}
Expand Down

0 comments on commit 7a6ab10

Please sign in to comment.