highlightjs/highlight.js

Support Prism.js grammar parsing but use the Highlight.js HTML/theme pipeline

Open

#3.619 aberto em 13 de set. de 2022

Ver no GitHub
 (5 comments) (0 reactions) (0 assignees)JavaScript (3.497 forks)batch import
enhancementgood first issuehelp welcomeparser

Métricas do repositório

Stars
 (22.960 stars)
Métricas de merge de PR
 (Nenhuma PRs mesclada em 30d)

Description

Related #2212.

I'm not sure this belongs in core yet, and I don't necessarily want a hard or soft Prism dependency. I suppose perhaps you could also pass Prism into the function itself though so it's late binding?

Caveats

  • Using custom parsers is still private API since the Emitter API is public yet. Hence the __emitTokens name of the property.
  • See #3620

What needs to be done

Example Usage

To replace our JavaScript support with Prism's:

import Prism from 'prismjs'
const prismJS = fromPrism(Prism.languages.javascript)
hljs.registerLanguage("javascript", prismJS)

Code

function prismTypeToScope(name) {
  // very poor results, must be improved
  return name;
}

function prismTokensToEmitter(tokens, emitter) {
  tokens.forEach(token => {
    if (typeof(token) === "string") {
      emitter.addText(token)
    } else if (token.type) {
      let scope = prismTypeToScope(token.type)
      if (typeof(token.content) === "string") {
        emitter.addKeyword(token.content, scope)
      } else { // array of tokens
        emitter.openNode(scope)
        prismTokensToEmitter(token.content, emitter)
        emitter.closeNode()
      }
    }
  })
}

function prismParserWrapper(code, emitter) {
  const tokens = Prism.tokenize(code, this._prism)
  prismTokensToEmitter(tokens, emitter)
}

function fromPrism(prismGrammar) {
  return function(hljs) {
    let self = {}

    Object.assign(self, {
      _prism: prismGrammar,
      __emitTokens: prismParserWrapper.bind(self)
    })
    return self
  }
}

Guia do colaborador