-
Notifications
You must be signed in to change notification settings - Fork 3.6k
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
[Request] Contribute utility function(s) for converting highlighted html to line-oriented html #3247
Comments
Have you tried the plugin API: hljs.addPlugin({
'after:highlightElement': ({ el, result }) => {
el.innerHTML = lineify(el, [1, 4]);
}
});
But, the |
The issue is not about helping me, I am using the code in my files by including calls to highlightjs before calling lineify, it's about contributing the code so others may use it. E.g. a utility module hosted @ highlightjs. |
Ah, okay. |
I'm sure you're aware we can already highlight I'm not sure about random "utility" scripts (that's a very, very wide hole - really your code could be used with any HTML snippet, it's not specific to us) - though we could probably figure out a place where we might link to such utilities... I'd be more interested in seeing if this couldn't be made into a proper plugin... and in that case I believe we'd be happy to host the repository I think - if you were willing to maintain it. |
This is a pretty custom solution used for reading exam submissions. The students start from a template and when reading their submission it's nice to see which lines they changed. A generated diff isn't suitable. The code will technically work for "any" HTML, but the results won't be of practical use unless the HTML is limited to span-like elements, like what highlightjs generates. If highlightjs suddenly changes to a different generation strategy, it might stop working. That's why I think it makes sense to include it in a utility module. It shouldn't be hard to turn it into a proper plugin, I agree. Do you have a plugin (repo) template, that I can clone and use as a starting point? That'll make it easier for both you and me. |
Nope, sadly, I don't think we have any official plugins yet. :) I'd suggest All you need to do is export your class or function that is a plugin so someone could call Then it's worth discussing how someone could control it per element (which seems to be what you'd want to do here). I don't think that has received much thought in the past vs plugins of a more "global" nature - ie behaving the same everywhere. I'd suggest you embed the configuration in the HTML itself, but I'd be open to a discussion about the possibility of pass-thru of options when calling the API functions themselves. Though at that point it's worth asking whether a wrapper vs plugin might not be better. I think we're exploring some new territory here, but I'm happy to help. |
I will look at |
Right, that's what I was getting at. I see 3 ways forward there:
I imagine option 2 would actually work for a lot of use cases. Number one seems kludgy but I'd have to think thru the ramifications of the option 3. Right now |
I'm a bit leaning towards #2... we don't currently allow someone to specify |
I think I can solve my case by taking a callback argument in the plugin constructor, that will be called for each line in each code block. The code block would need some key attribute i.e. solution 2, so the callback can look up which lines should be styled or marked somehow. The callback could also add line numbers in whatever way it seems fit. I can also support some specific attributes in the code block, like you suggest, for common use cases (like adding line numbers). |
It worked pretty well as outlined. I added a code-block-key attribute and apply the callback to the highlighted element and the array of line elements (span). The callback may modify the line elements before they're added to the element. Hence, option 2 works for my use case. |
So what's it look like? |
Here's the callback:
And here's the code registering the plugin and running highlightjs:
And here's a screenshot (left: submission with student additions to the template emphasised, right: junit test reports): |
https://github.com/hallvard/highlightjs-lineify I've tried highlightjs-lineify.min.js file in dist instead of the original one in my project and it seems to work. |
What's stopping you from putting the data inside the HTML itself instead of just the key? |
Nothing, really. This way it was a smaller change to the page generator. |
What is the loop doing? |
The lineElements are span elements representing lines, wrapping restructured elements from highlightjs. The loop inserts line number elements first in each line element's child list. An example of what someone would like to do. This could be a build-in feature, e.g. an attribute on the code element that is picked up by the plugin. |
Looks interesting. Whenever you think you have something ready and generally useful feel free to add it to our Wiki: https://github.com/highlightjs/highlight.js/wiki/Useful-Plugins For now we've decided it's best to use the wiki to maintain a list of plugins rather than host these repos here directly. We'll have to gradually bump it's prominence a bit as it isn't something we've taken advantage much in the past. I almost wonder if you should perhaps consider the idea of being a "data plugin" though... limiting yourself to merely attaching the line data to either the element (or just the result object literal)... and then letting someone write a second plugin (using the official API) that could take advantage of the data you add in it's own The callback approach might be simpler for implementors though. Sadly we don't have a lot of great patterns built up around the use of plugins yet. |
Now I've implemented both the callback approach, which is very general, and some specific behaviour for adding line numbers using a format string and adding class names to elements. You're right we could just leave it to others to operate on the result, but after reading about how highlightjs never would support line numbers, I though it would be nice to at least support that. And I needed the class name feature myself, so ended up with those two. Concerning "chaining" plugins: Is the order of calling plugins well-defined, so you can ensure the lineify plugin is run before any other that relies on the restructured html? I'll add an entry to the wiki. I've improved the README slightly, one thing missing is how to include/import it. Currently, it isn't published anywhere, so you must either refer to it using a gitcontent url or save it to a local file, like I guess some do for highlightjs. I've no experience publishing, but I guess npm has a task for it. |
Installing plugins in the proper order is the duty of the implementer. Callbacks hooks are executed against plugins in the order that the plugins were added... if someone wanting to build on your plugin would need to install it before their own.
It's not super hard to publish an npm package once you have an account... there are docs/tutorials for it if you look. |
Is your request related to a specific problem you're having?
I needed to color individual lines based on the result of a diff, and this is difficult to do since span-elements may span several lines.
The solution you'd prefer / feature you'd like to see added...
I'd like a utility function for post-processing the highlighted html into a line-oriented html structure.
Any alternative solutions you considered...
Tried existing solution that failed in newest version. Also tried marking the html, but that's not allowed anymore.
Additional context...
Just to make it clear, I've implemented what I need and would like to contribute rather than host it myself (it's so small).
The lineify function below (with the help of lineifyHelper) replaces the highlighted html structure with a corresponding one, but where the top-level span-elements represents a single line of text/code. The previous contents has effectively been split up so the same kind of span-elements contain the same text/code, but the structure is line-oriented. This makes it easy to give specific lines a different look and feel (see the markLines argument) or add line numbers.
This code could be wrapped in a small module that can be used for post-processing. I'd like to avoid having to host this myself, therefore I'd like you to consider it.
The text was updated successfully, but these errors were encountered: