speced / respec

A tool for creating technical documents and web standards
https://respec.org/
Other
713 stars 385 forks source link

Add ability to load other highlight languages via config #2152

Open BigBlueHat opened 5 years ago

BigBlueHat commented 5 years ago

Follow-up from #1063

Description of problem

Many specs at the W3C (and elsewhere) use the Turtle format.

There is a PR to highlight.js for adding Turtle that has apparently been available since shortly after I filed #1063.

The JSON-LD WG is nearing CR for the JSON-LD 1.1 syntax document, and we use a good bit of Turtle, so having this added would help us there particularly.

Also, credit goes to @cygri for finding this highlighter! https://github.com/w3c/json-ld-syntax/pull/67#issuecomment-472408686

Thanks! 🎩

P.S.: The PR also includes a highlighter for SPARQL which W3C specs and notes also use from time to time.

cygri commented 5 years ago

There was some further work on top of that PR by @VladimirAlexiev, which led to this branch:

https://github.com/VladimirAlexiev/highlight.js/tree/feature/language-sparql-ttl

I've tried this for SPARQL and Turtle, and it works well. I had to follow the build instructions to create a highlight.pack.js from source.

It looks like maintainership of highlight.js is somewhat adrift at the moment (highlightjs/highlight.js#1678), so PRs are not being merged.

marcoscaceres commented 5 years ago

We are currently moving away from using the hljs bundle. So, the way to do this is to use preProcess to load the highlighter language:

      async function loadSparqlLang() {
        const worker = await new Promise(resolve => {
          require(["core/worker"], ({ worker }) => resolve(worker));
        });
        const action = "highlight-load-lang";
        const langURL = new URL(/*URL to your language file*/).href;
        // this needs to match the name of the property created in highlight js for the language
        const propName = "sparql-ttl";
        const lang = "sparql-ttl"; // check what this should be 
        worker.postMessage({ action, langURL, propName, lang });
        return new Promise(resolve => {
          worker.addEventListener("message", function listener({ data }) {
            const { action: responseAction, lang: responseLang } = data;
            if (responseAction === action && responseLang === lang) {
              worker.removeEventListener("message", listener);
              resolve();
            }
          });
        });
      }
      var respecConfig = {
        preProcess: [loadSparqlLang],
        // other stuff
      }

In the future, we will make this a bit easier... allowing languages to be dynamically loaded by just having a highlightLanguages: ["xml", "rdf", "sparql"] and so on....

marcoscaceres commented 5 years ago

Updated the above.

marcoscaceres commented 5 years ago

About the language support, I followed up: https://github.com/highlightjs/highlight.js/pull/1553/

We need a maintainer for the language itself. I maintain hljs now.

VladimirAlexiev commented 5 years ago

My PR is also used in Ontotext training presentations, which are made with reveal.js, so I have some code to repackage hljs for reveal.

We have a task to merge my PR that's been outstanding for a year but now if the w3c wants to use it, I'll requisition a JS dev to do it.

See https://github.com/highlightjs/highlight.js/pull/1553 and https://github.com/highlightjs/highlight.js/pull/1844

marcoscaceres commented 5 years ago

@VladimirAlexiev that would be great. I can get the repo set up for you on the hljs side and we can go from there.

sidvishnoi commented 4 years ago

Had a play at this locally.

Unfortunately, highlightjs doesn't export the languages in the way ReSpec wants to use. The prod build has language as commonjs modules (example), and the GitHub repo has anonymous function (example) So, we can't directly use these hosted language files.

ReSpec uses importScripts in the Worker, which means the language file must expose a global "propName".

Possible solutions: