I tried replacing the @gridsome/source-filesystem with the new @gridsome/vue-remark, but ran into issues with remark plugins.
When using the @gridsome/vue-remark with @gridsome/remark-prismjs the prism plugin is not working (not tokenizing the html output to apply styling to).
In gridsome.config.js
module.exports = {
plugins: [
{
// Create posts from markdown files
use: "@gridsome/vue-remark",
options: {
typeName: "Post",
path: "content/posts/*.md",
baseDir: "./content/posts",
template: "./src/templates/Post.vue",
remark: {
plugins: ["@gridsome/remark-prismjs"]
}
}
},
],
transformers: {
remark: {
plugins: ["@gridsome/remark-prismjs"]
}
}
};
The prism plugin should add additional token classes to the html generated when using code blocks in markdown.
The actual html looks like this (no tokenized output):
<pre><code class="language-css">
.test {
background: none;
}
</code></pre>
Libs:
- gridsome version: 0.7.5
- @gridsome/cli version: 0.2.3
For Tooling issues:
- Node version: 11.14.0
- Platform: Windows
Can you try to move the plugins option out of the remark object? And make sure you have the latest version of @gridsome/remark-prismjs.
@kai-oswald try this:
plugins: [
{
// Create posts from markdown files
use: "@gridsome/vue-remark",
options: {
typeName: "Post",
path: "content/posts/*.md",
baseDir: "./content/posts",
template: "./src/templates/Post.vue",
plugins: ["@gridsome/remark-prismjs"], // <-- move `plugins` here
// remark: {
// plugins: ["@gridsome/remark-prismjs"]
// }
}
},
],
I've noticed the remark plugins aren't running at the right time.
I'm using remark-code-extra to customize <pre> elements. In my transformer, I have a console.log statement to show me the contents of each <pre> element.
I'm expecting the output of each console.log statement to occur as the plugin is finding each <pre> element.
What's actually happening is the output of each console.log statement occurs when I navigate to a route that has <pre> elements.
It appears that markdown is being processed _first_, and _then_ the remark plugins are running after the fact.
Also, the console.log statements are only appearing when I pass the plugins directly to vue-remark:
plugins: [{
use: '@gridsome/vue-remark',
options: {
...
plugins: [ 'remark-code-extra', { ... } ]
}
}]
The console.log statements do not appear when I pass the plugins to the transformers.remark option in gridsome.config.js:
plugins: [{
use: '@gridsome/vue-remark',
options: {
...
}
}],
transformers: {
remark: {
...
plugins: [ 'remark-code-extra', { ... } ]
}
},
Can you try to move the
pluginsoption out of theremarkobject? And make sure you have the latest version of@gridsome/remark-prismjs.
This doesn't fix it :( - Same behaviour as described
I have a feeling that the issue is likely due to VueRemarkContent being an async component.
Damn :/
Any infos for future plans regarding this? Is this going to be addressed?
@kai-oswald I have been looking into this a few times, but I haven't been able to reproduce the behavior. Just tried with @gridsome/[email protected] and @gridsome/[email protected] again now and it worked as expected. Code blocks are getting tokenized. Do you use any other remark plugins that can cause this in your project?
Here is my config file:
module.exports = {
plugins: [
{
use: '@gridsome/vue-remark',
options: {
typeName: 'Post',
baseDir: './content',
template: './src/templates/Post.vue',
plugins: [
'@gridsome/remark-prismjs'
]
}
}
]
}
And the Markdown looks like this:
````
.test {
background: none;
}
````
Which produces this markup:
<pre class="language-css">
<code class="language-css">
<span class="token selector">.test</span>
<span class="token punctuation">{</span>
<span class="token property">background</span>
<span class="token punctuation">:</span> none
<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code>
</pre>
I think I've found the issue, but it looks like a bug to me.
I have 2 different types that use the @gridsome/vue-remark plugin, but only the type Post needs the @gridsome/remark-prismjs plugin. So I didn't add it in the Project type.
module.exports = {
templates: {
Tag: "/tag/:id"
},
plugins: [
{
use: "@gridsome/vue-remark",
options: {
typeName: "Post",
baseDir: "content/posts",
pathPrefix: "/blog",
template: "./src/templates/Post.vue",
plugins: ["@gridsome/remark-prismjs"],
refs: {
tags: {
typeName: "Tag",
create: true
}
}
}
},
{
use: "@gridsome/vue-remark",
options: {
typeName: "Project",
baseDir: "content/projects",
pathPrefix: "/projects",
template: "./src/templates/Project.vue",
plugins: ["@gridsome/remark-prismjs"], // <-- this line was missing
}
}
]
};
The issue here is that the last object configuration is used, so when I switch the position of Project and Post I can remove the @gridsome/remark-prismjs from Project.
Is this behaviour intended?
I'm actually unable to use @gridsome/remark-prismjs with @gridsome/vue-remark at all, using the exact same code.
I am unable to use the plugin remark-toc with @gridsome/vue-remark
I have tried:
{
use: '@gridsome/vue-remark',
options: {
typeName: 'Guide', // Required
baseDir: './content/guides', // Where .md files are located
pathPrefix: '/guides', // Add route prefix. Optional
template: './src/templates/Guide.vue',
plugins: ['remark-toc'],
},
},
and
{
use: '@gridsome/vue-remark',
options: {
typeName: 'Guide', // Required
baseDir: './content/guides', // Where .md files are located
pathPrefix: '/guides', // Add route prefix. Optional
template: './src/templates/Guide.vue',
remark: {
plugins: ['remark-toc'],
}
},
},
and
plugins: [
{
use: '@gridsome/vue-remark',
options: {
typeName: 'Guide', // Required
baseDir: './content/guides', // Where .md files are located
pathPrefix: '/guides', // Add route prefix. Optional
template: './src/templates/Guide.vue',
},
},
],
transformers: {
remark: {
plugins: ['remark-toc'],
},
},
all of them ignore my tag in the md files:
## toc
or
## Table of Contents
which get rendered as regular h2 tags.
System:
OS: macOS Mojave 10.14.6
CPU: (4) x64 Intel(R) Core(TM) i5-6287U CPU @ 3.10GHz
Binaries:
Node: 12.13.0 - ~/.nvm/versions/node/v12.13.0/bin/node
Yarn: 1.13.0 - /usr/local/bin/yarn
npm: 6.12.1 - ~/.nvm/versions/node/v12.13.0/bin/npm
Browsers:
Chrome: 78.0.3904.87
Firefox: 70.0
Safari: 13.0.3
npmPackages:
@gridsome/source-graphql: ^0.1.0 => 0.1.0
@gridsome/transformer-remark: ^0.4.0 => 0.4.0
@gridsome/vue-remark: ^0.1.7 => 0.1.7
gridsome: ^0.7.0 => 0.7.8
npmGlobalPackages:
@gridsome/cli: 0.3.1
@danrocha I tested your repository now and it seems to work as expected :)
Here is what I did:
transformers config from gridsome.config.jsplugins option on each @gridsome/vue-remark entry## Table of Contents heading after the import statement in ./content/blog/magic-hours-will-make-photography-shine.mdAnd I got a nested list containing all headings below. Can you try the same and see if it works?
Is this some kind of sorcery? 馃え
Now it did work, indeed.
I'll try later to tweak some option and see if it still holds 馃檹
Thanks a lot @hjvedvik
D.
hi
i have the same problem as @kai-oswald, but his last solution doesn't work for me
My config
module.exports = {
plugins: [
{
use: "@gridsome/vue-remark",
options: {
typeName: "Project",
baseDir: "./markdown/projects",
template: "./src/templates/Project.vue",
pathPrefix: "/projects",
route: "/projects/:title"
}
},
{
use: "@gridsome/vue-remark",
options: {
typeName: "Tag",
baseDir: "./markdown/tags",
template: "./src/templates/Tag.vue",
pathPrefix: "/blog/tags"
}
},
{
use: "@gridsome/vue-remark",
options: {
typeName: "Post",
baseDir: "./markdown/posts",
template: "./src/templates/Post.vue",
pathPrefix: "/posts",
route: "/blog/:slug",
refs: {
tags: "Tag"
},
plugins: ["@gridsome/remark-prismjs"]
}
}
]
};
Code in markdown file:
```js
const mongoose = require("mongoose");
const userSchema = new mongoose.Schema({
name: {
type: String,
required: true,
min: 6
},
email: {
type: String,
required: true,
min: 8
}
});
module.exports = mongoose.model("User", userSchema);
```
And results in browser;
<pre>
<code class="language-js">
"// src/models/User.js
const mongoose = require("mongoose");
const userSchema = new mongoose.Schema({
name: {
type: String,
required: true,
min: 6
},
email: {
type: String,
required: true,
min: 8
}
});
module.exports = mongoose.model("User", userSchema);"
</code>
</pre>
Code in _code_ tag have " and there is no sign of tokens
Hey @sebastianluszczek,
I cloned your repository and your configuration worked after I made a change in the markdown file. Just be sure to edit the markdown file while in gridsome develop, else it will use an older cached version.
I don't know why it works like this, this is probably an additional bug worthy to report?
Config:
module.exports = {
plugins: [
{
use: "@gridsome/vue-remark",
options: {
typeName: "Project",
baseDir: "./markdown/projects",
template: "./src/templates/Project.vue",
pathPrefix: "/projects",
route: "/projects/:title"
}
},
{
use: "@gridsome/vue-remark",
options: {
typeName: "Tag",
baseDir: "./markdown/tags",
template: "./src/templates/Tag.vue",
pathPrefix: "/blog/tags"
},
},
{
use: "@gridsome/vue-remark",
options: {
typeName: "Post",
baseDir: "./markdown/posts",
template: "./src/templates/Post.vue",
pathPrefix: "/posts",
route: "/blog/:slug",
refs: {
tags: "Tag"
},
plugins: ["@gridsome/remark-prismjs"]
}
},
]
}
Generated HTML:
<pre class="language-js"><code class="language-js"><span class="token comment">// src/index.jse</span>
<span class="token keyword">import</span> express <span class="token keyword">from</span> <span class="token string">"express"</span><span class="token punctuation">;</span>
<span class="token keyword">const</span> app <span class="token operator">=</span> <span class="token function">express</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
app<span class="token punctuation">.</span><span class="token function">listen</span><span class="token punctuation">(</span><span class="token number">5000</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Server started on port 5000!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre>
@kai-oswald
at night I found this answer too (I couldn't sleep because of this :smile: )
But thanks for looking at it.
This must be some kind of caching, but I think it is kinda buggy behavior
@kai-oswald @sebastianluszczek Yes, caching is probably the issue here :) I'll make the plugin invalidate the webpack cache in a better way.
Hi guys! Any update or workaround on this topic? I'm having the same bug with the tokenization... I tried the stated suggestions but none of them worked
@tommasongr you could try deleting the .cache folders in your project root and/node_modules/ folder. This helps sometimes. Dont forget to deletethe cache after every restart of the dev server
When developing a remark plugin I can recommend loading it directly in /node_modules/ @gridsome/vue-remark/index.js:147-167
plugins: [
sfcSyntax,
toVueRemarkAst,
[remarkFilePlugin, {
processFiles: remarkOptions.processFiles
}],
[remarkImagePlugin, {
processImages: remarkOptions.processImages,
blur: remarkOptions.imageBlurRatio,
quality: remarkOptions.imageQuality,
background: remarkOptions.imageBackground,
immediate: remarkOptions.lazyLoadImages === false ? true : undefined
}],
yourPluginYouWantToTest // -> function you want to call as a plugin
...options.plugins
]
Note: This is definitely a caching problem, furthermore there is a inconsistency when loading the plugin config.
Trying to migrate from source-filesystem to vue-remark in order to use Vue components in my markdown but I thought it wasn麓t working.
I麓ve compared both contents of source-filesystem and vue-remark by printing out {{$post.content}} and was under the impression they must be identical.
However, the content of the vue-remark'ed node was not containing the rendered toc, but the original markdown instead
"content": "rn## Table of Contentsrnrn
Using VueRemarkContent however is printing the correctly rendered HTML
<VueRemarkContent class="markdown" />
while nodes generated with the source-filesystem plugin already contain the fully rendered HTML you can just add to any div
<div class="markdown" v-html="$page.post.content"/>
It also works while having global transformers defined, in case some-one is using vue-remark and source-filesystem in parallel during migrations
transformers: {
remark: {
externalLinksTarget: '_blank',
externalLinksRel: ['nofollow', 'noopener', 'noreferrer'],
plugins: [
['gridsome-plugin-remark-shiki', {
theme: 'min-light'
}],
'remark-toc'
]
}
},
Most helpful comment
@danrocha I tested your repository now and it seems to work as expected :)
Here is what I did:
transformersconfig fromgridsome.config.jspluginsoption on each@gridsome/vue-remarkentry## Table of Contentsheading after the import statement in./content/blog/magic-hours-will-make-photography-shine.mdAnd I got a nested list containing all headings below. Can you try the same and see if it works?