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

gatsby-remark-prismjs failed to highlight cpp code #1917

Closed
vincentbel opened this issue Aug 26, 2017 · 5 comments
Closed

gatsby-remark-prismjs failed to highlight cpp code #1917

vincentbel opened this issue Aug 26, 2017 · 5 comments

Comments

@vincentbel
Copy link
Contributor

Problem

gatsby-remark-prismjs failed to highlight the following markdown with cpp code:

## A Sample Cpp Code

```cpp
int sum(int a, int b) {
    return a + b;
}
```

I made a repo(VincentBel/gatsby-prism-cpp-highlight-bug) to reproduce the issue.
Some quick link:

The result:

image

and the generated js file:

      <pre class="language-cpp"><code>int sum(int a, int b) {
    return a + b;
}</code></pre>

Env

  • OS: macOS Sierra 10.12.6
  • node: v6.9.1
  • npm: 5.3.0
  • yarn: 0.27.5
  • gatsby version:
"gatsby": "^1.9.7",
"gatsby-remark-prismjs": "^1.2.1",
"gatsby-source-filesystem": "^1.4.4",
"gatsby-transformer-remark": "^1.7.2",
@vincentbel
Copy link
Contributor Author

vincentbel commented Aug 26, 2017

I investigated the issue, and here are some info:

What Causes the Problem?

gatsby-remark-prismjs will try to require prism the required language component:

if (!Prism.languages[language]) {
try {
require(`prismjs/components/prism-${language}.js`)
} catch (e) {
// Language wasn't loaded so let's bail.
return code
}

but for language cpp, it extends c:(prism: components/prism-cpp.js)

Prism.languages.cpp = Prism.languages.extend('c', {
  // ....
})

And the Prism.languages.extend function (prism: prism.js#L76-L81): (See the comments I added)

extend: function (id, redef) {
  // id is 'c', but it is not added to `_.languages` yet,
  // so the variable `lang` will be undefined
  var lang = _.util.clone(_.languages[id]);

  for (var key in redef) {
   // Throw an `Cannot read property 'keyword' of undefined` Error!!
    lang[key] = redef[key];
  }

  return lang;
}

It throw an Cannot read property 'keyword' of undefined error. So it failed to load the cpp component.

How to Fix

For cpp:

  1. components/prism-cpp.js extends 'c', so we load the 'c' component first
  2. components/prism-c.js extends 'clike', so we load the 'clike' component first
  3. components/prism-clike.js extends nothing, load it

That is: load clike => load c => load cpp.

So before loading language component, we should load the extended language component first.

But how can we know the language components dependencies? There exist a components.js file in prism, it has the language components dependencies, We can use it.

The cpp part:

languages: {
  // ...
  "cpp": {
	  "title": "C++",
	  "require": "c",
	  "owner": "zeitgeist87"
  },
  // ...
}

The fixes won't be hard, I'll send a pull request if you agree with the above. 🤗

@KyleAMathews
Copy link
Contributor

Ooooo… prism has more layers. Nice! Would love a PR adding support for the extended language stuff!

@vincentbel
Copy link
Contributor Author

@KyleAMathews Oops, It seem the components.js file is only for interval use. It doesn't have a module.exports. And even the file doesn't exists in npm(https://unpkg.com/[email protected]/). 😅


Maybe we can have a copy of the language part? (But we need to keep in sync if prism changes it)

@KyleAMathews
Copy link
Contributor

Copying it in sounds fine. Could you add a make.js script that downloads the file and add the module.exports etc? That way when there is updates it'll be trivial to update the components module.

@vincentbel
Copy link
Contributor Author

Yeah, of course.

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

No branches or pull requests

2 participants