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

fix: allow ] in filename code block #2169

Merged
merged 12 commits into from Jul 24, 2023

Conversation

Barbapapazes
Copy link
Contributor

@Barbapapazes Barbapapazes commented Jul 12, 2023

πŸ”— Linked issue

❓ Type of change

  • πŸ“– Documentation (updates to the documentation or readme)
  • 🐞 Bug fix (a non-breaking change that fixes an issue)
  • πŸ‘Œ Enhancement (improving an existing functionality like performance)
  • ✨ New feature (a non-breaking change that adds functionality)
  • ⚠️ Breaking change (fix or feature that would cause existing functionality to change)

πŸ“š Description

fix #2166

For a code block, if filename was [...page].vue, regex was stoping at [...page. This PR fix it.

πŸ“ Checklist

  • I have linked an issue or discussion.
  • I have updated the documentation accordingly.

@netlify
Copy link

netlify bot commented Jul 12, 2023

βœ… Deploy Preview for nuxt-content canceled.

Name Link
πŸ”¨ Latest commit e0ff29c
πŸ” Latest deploy log https://app.netlify.com/sites/nuxt-content/deploys/64be72478514bf000792733f

@Barbapapazes Barbapapazes changed the title fix: allow ] in filename fix: allow ] in filename code block Jul 12, 2023
@@ -20,7 +20,7 @@ export function parseThematicBlock (lang: string) {

const language = lang.replace(/[{|[](.+)/, '').match(/^[^ \t]+(?=[ \t]|$)/)
const highlightTokens = lang.match(/{([^}]*)}/)
const filenameTokens = lang.match(/\[([^\]]*)\]/)
const filenameTokens = lang.match(/\[(.*)\]/) /** Allow ']' in filename. @see https://regex101.com/r/Hm0t5m/1 */
Copy link
Contributor

@nobkd nobkd Jul 12, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we used [^\]] to allow using lists in the meta part.
Here's an example what would not work anymore if we match the longest string.

```language [filename]{hightlights} meta=[...]

It would match this content filename]{hightlights} meta=[... as the filename

Copy link
Contributor

@nobkd nobkd Jul 12, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought we could use something like \] in the markdown and prevent matching those somehow

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oooh I understand. I do it too quickly!

Copy link
Contributor

@nobkd nobkd Jul 12, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think, that this might work: /\[((\\]|[^\]])*)\]/


This part (\\]|[^\]])* matches zero or one or a sequence of: \] or characters that are not ]

Only if our string has no more ] after a \] it terminates the match at a \].

So this works:

```ts [[...slug\].vue] meta=[]

=> [...slug\].vue as the first group match.
Then we only have to replace \] which in reality is \\] with ]

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes but if there is no meta, this regex is not working.

https://regex101.com/r/bG0Net/1

EDIT: User must set a , I understand.

Copy link
Contributor

@nobkd nobkd left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be all the necessary changes, but we'll see...
This is currently not really tested.

I tried both \\] and \] and it seems that we need the first variant with two backslashes to get one real backslash from the Markdown.

So, this works in the playground:

```ts [[...slug\\].vue] ...

@@ -20,7 +20,7 @@ export function parseThematicBlock (lang: string) {

const language = lang.replace(/[{|[](.+)/, '').match(/^[^ \t]+(?=[ \t]|$)/)
const highlightTokens = lang.match(/{([^}]*)}/)
const filenameTokens = lang.match(/\[([^\]]*)\]/)
const filenameTokens = lang.match(/\[(.*)\]/) /** Allow ']' in filename. @see https://regex101.com/r/Hm0t5m/1 */
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
const filenameTokens = lang.match(/\[(.*)\]/) /** Allow ']' in filename. @see https://regex101.com/r/Hm0t5m/1 */
const filenameTokens = lang.match(/\[((\\]|[^\]])*)\]/)

Copy link
Contributor

@nobkd nobkd Jul 12, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And because of GitHub, I'm not allowed to suggest changes out of some range:

Change for L29:

-    filename: Array.isArray(filenameTokens) && filenameTokens[1] ? filenameTokens[1] : undefined,
+    filename: Array.isArray(filenameTokens) && filenameTokens[1] ? filenameTokens[1].replace(/\\]/g, ']') : undefined,

To remove the now redundant backslashes.

@@ -20,7 +20,7 @@ export function parseThematicBlock (lang: string) {

const language = lang.replace(/[{|[](.+)/, '').match(/^[^ \t]+(?=[ \t]|$)/)
const highlightTokens = lang.match(/{([^}]*)}/)
const filenameTokens = lang.match(/\[([^\]]*)\]/)
const filenameTokens = lang.match(/\[(.*)\]/) /** Allow ']' in filename. @see https://regex101.com/r/Hm0t5m/1 */
const meta = lang.replace(/^\w*\s*(\[[^\]]*\]|\{[^}]*\})?\s*(\[[^\]]*\]|\{[^}]*\})?\s*/, '')
Copy link
Contributor

@nobkd nobkd Jul 12, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
const meta = lang.replace(/^\w*\s*(\[[^\]]*\]|\{[^}]*\})?\s*(\[[^\]]*\]|\{[^}]*\})?\s*/, '')
const meta = lang.replace(/^\w*\s*(\[((\\]|[^\]])*)\]|\{[^}]*\})?\s*(\[((\\]|[^\]])*)\]|\{[^}]*\})?\s*/, '')

To replace the correct part, to have the meta left.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I refactor this to be more understandable and to reuse previous regex.

@Barbapapazes
Copy link
Contributor Author

I will also update documentation to add to warning about usage.

@nuxt-studio
Copy link

nuxt-studio bot commented Jul 13, 2023

βœ… Live Preview ready!

Name Edit Preview Latest Commit
content Edit on Studio β†—οΈŽ View Live Preview e0ff29c

@nuxt-studio
Copy link

nuxt-studio bot commented Jul 13, 2023

βœ… Live Preview ready!

Name Edit Preview Latest Commit
content Edit on Studio β†—οΈŽ View Live Preview 3a69417

@Barbapapazes Barbapapazes requested a review from nobkd July 13, 2023 09:18
const meta = lang.replace(/^\w*\s*(\[[^\]]*\]|\{[^}]*\})?\s*(\[[^\]]*\]|\{[^}]*\})?\s*/, '')
const languageMatches = lang.replace(/[{|[](.+)/, '').match(/^[^ \t]+(?=[ \t]|$)/)
const highlightTokensMatches = lang.match(/{([^}]*)}/)
const filenameMatches = lang.match(/\[((\S)*)\]/) /** Allow ']' in filename. */
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can see that you don't want an escape character to have ] in your filename, but we didn't want to depend on spaces. If we now change this, it could be a breaking change.

My variant from before would introduce an escape character (e.g. \\) for ] but

  • would not need spaces after the last ] that belongs to the filename
  • allow spaces in the filename.

You could not do this anymore:

```ts [filename]meta=[]

or

```ts [filename/title with spaces]

Spaces in the filename for example are already used in the nuxt/nuxt docs. Some examples:


#2067 was the last change to this regexes, there should also be some ideas.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you've convinced me. I will update regex to allow esacape ] and update docs in that ways (documenting why we choose this method).

@Barbapapazes Barbapapazes marked this pull request as draft July 13, 2023 10:55
Comment on lines +24 to +28
const meta = lang
.replace(languageMatches?.[0] ?? '', '')
.replace(highlightTokensMatches?.[0] ?? '', '')
.replace(filenameMatches?.[0] ?? '', '')
.trim()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this, it makes this part so much more readable! ❀️

Barbapapazes and others added 2 commits July 15, 2023 15:12
Co-authored-by: nobkd <44443899+nobkd@users.noreply.github.com>
Co-authored-by: nobkd <44443899+nobkd@users.noreply.github.com>
@Barbapapazes
Copy link
Contributor Author

@nobkd we have an issue because a JS string is automatically escape \ in string. So [[...page\].vue] is resolved as [[...page].vue]

image

@Barbapapazes
Copy link
Contributor Author

We will need to use a double \. I'll update PR with this usage.

@nobkd
Copy link
Contributor

nobkd commented Jul 15, 2023

See this #2169 (review)

We need to use double escaping: \\]

There's probably a better escape character, but \ is the generally used one, so I went with it. Do you have a better idea how to escape?

@nobkd
Copy link
Contributor

nobkd commented Jul 15, 2023

We will need to use a double \. I'll update PR with this usage.

Exactly

@Barbapapazes Barbapapazes requested a review from nobkd July 15, 2023 22:11
@Barbapapazes
Copy link
Contributor Author

See this #2169 (review)

We need to use double escaping: \\]

There's probably a better escape character, but \ is the generally used one, so I went with it. Do you have a better idea how to escape?

Oh yes, I've not seen this comment! Thanks

@Barbapapazes Barbapapazes marked this pull request as ready for review July 15, 2023 22:32
nobkd

This comment was marked as resolved.

Co-authored-by: nobkd <44443899+nobkd@users.noreply.github.com>
Copy link
Member

@farnabaz farnabaz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks guys.
You're awesome ❀️

@farnabaz farnabaz merged commit 7a6ab10 into nuxt:main Jul 24, 2023
7 checks passed
@farnabaz farnabaz mentioned this pull request Jul 25, 2023
@nobkd
Copy link
Contributor

nobkd commented Jul 30, 2023

Just to have this in one place, I think this bug was previously introduced with #2067

https://github.com/nuxt/content/pull/2067/files#diff-fd60d817a96ebccaa6b1456127b1e4589b3e10487ddb84362ab6e41ab1ede143L22-R23

I think, there was decided, that we could allow [] and {} in the meta part, and therefore changed the regex...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

in documents, filename "[...slug].vue" above code block display not correctly
3 participants