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

Exclude certain languages from highlighting altogether #2068

Closed
asbjornu opened this issue Sep 26, 2019 · 7 comments · Fixed by #2074
Closed

Exclude certain languages from highlighting altogether #2068

asbjornu opened this issue Sep 26, 2019 · 7 comments · Fixed by #2074

Comments

@asbjornu
Copy link

asbjornu commented Sep 26, 2019

Motivation
Prism's current behavior makes it impossible to use Prism and Mermaid on the same page.

Description
I'd like to have what the title in #558 says ("Ignore some html tags") and not what the provided solution does ("Preserve markup even after Prism has applied syntax highlighting"). The issue I'm facing is having both Mermaid and Prism on the same page and Prism just destroys Mermaid code blocks so Mermaid can't do anything sensible with it. Instead of preserving markup (which I suppose will also "fix" the problem), I'd like Prism to just not touch .language-mermaid elements. Is this not possible?

Alternatives
I've searched around and found gaearon/gitbook-plugin-prism#28 which proves that there's a need for this feature and I can't think of a way to work around this. Had there only been a Prism.highlightElements() method that took a list of elements I could select and filter beforehand manually, I could have solved this myself. But since this method doesn't exist, I'm unable to fix this without learning how to develop a Prism plugin of some sort. And I find the Prism API documentation to be very sparse (the available hooks don't seem to be documented, for instance), I'm struggling to do so. Please help! 🙏 😃

@mAAdhaTTah
Copy link
Member

There is a highlightElement method you can use to select & filter beforehand then iterate over and call it on.

@asbjornu
Copy link
Author

@mAAdhaTTah, thanks. I was able to get it to work by doing the following:

<script src="prism.js" data-manual></script>
var elements = document.querySelectorAll('.highlighter-rouge:not(.language-mermaid) pre.highlight');

for (var element of elements) {
    Prism.highlightElement(element, false);
}

The problem is that it performs several times worse than Prism does out of the box without data-manual and the individual Prism.highlightElement() invocation. I suppose Prism initializes itself a lot smarter than I'm able to through its API. I therefore feel like this is a must-have feature in the core of Prism.

@mAAdhaTTah
Copy link
Member

The problem is that it performs several times worse

Can you elaborate on the performance degradation you're seeing? There isn't anything you're doing here that looks terribly different from what Prism does itself.

@asbjornu
Copy link
Author

Perhaps it's just me, but I find that my home-grown solution causes a very notable flash of un-highlighted code before Prism performs the highlight, while removing data-manual and my initialization code makes highlighting instant and unnoticeable.

@RunDevelopment
Copy link
Member

@asbjornu
This is just my suspicion but do you test on Chrome?

Chrome as a bit of an issue with large changes to the DOM (100 LOC add about 2000 new nodes). There is a workaround for this: Detach the pre from the DOM before highlighting and reattach it afterward.
See #1907 for an example of this workaround. (Note that the download page uses async highlighting, you probably want to go for synchronous highlighting.)

my home-grown solution causes a very notable flash of un-highlighted code before Prism performs the highlight

Sounds like asynchronous highlighting. Try passing false to the async parameter of Prism's highlighting functions.

I suppose Prism initializes itself a lot smarter than I'm able to through its API.

Nope. It's as dumb as it gets.
This is the selector we use and apart from the plugin hook (which usually isn't used) and the callback stuff, it's the same as your code. (The container is document which is passed from highlightAll.)

@asbjornu
Copy link
Author

Your assumptions are correct, @RunDevelopment. Even though that helps, It would be nice if Prism could be initialized with a CSS selector or array of elements (as a result from document.querySelectorAll()) or (as in highlight.js) the ability to configure a set of white-listed languages Prism should highlight, alternatively black-list the languages it should not highlight.

@RunDevelopment
Copy link
Member

[...] if Prism could be initialized with a CSS selector or array of elements (as a result from document.querySelectorAll())

I against this because the resulting function will look something like this:

function highlightElements(selectorOrElements: string | Iterable<Element>): void {
    if (typeof selectorOrElements === 'string') {
        selectorOrElements = document.querySelectorAll(selectorOrElements);
    }
    for (const element of selectorOrElements) {
        Prism.highlightElement(element);
    }
}

I think that this is a function simple enough that we don't need to include it in our library.

to configure a set of white-listed languages

I don't know the details of what you intend here but I guess that it's similar to #1761.

I'll make a small plugin for this and ping you when it's done.

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

Successfully merging a pull request may close this issue.

3 participants