Problem/Motivation
Many sites need code formatting/syntax highlighting enabled for at least one of their text formats. However, it's surprisingly difficult to get it right on a Drupal site. For Drupal 8, several solutions exist such as:
- Markdown-based solutions (Markdown filter, Markdown editor for BUEditor, CommonMark)
- Code Filter
- highlight js (ok, not yet ported to D8)
- GeSHi Filter for syntax highlighting
- BUEditor
- Code Snippets
- ...and probably several others
Proposed resolution
We've settled on using CKEditor in Drupal 8 so the most sensible thing to do is to continue extending it for our needs. There's a great addon/library called Code Snippet that does just what we need and uses the popular highlight.js library.
There's also an excellent contrib module that acts as a wrapper for the Code Snippet library called CKEditor CodeSnippet. It very easily allows to add the Code Snippet button to the CKEditor toolbar and customize the languages that are supported as well as the template to use to render code blocks. Its requirements are that you add the library under the libraries directory at the root of your Drupal install and that you ensure <code> and <pre> are accepted HTML elements in your text formats.
This feature wouldn't be enabled by default so it wouldn't be intrusive.
Remaining tasks
- Discuss relevancy (how code formatting needs compare to, e.g. sub/super script that ship but aren't enabled by default)
- Evaluate if the CodeSnippet popup is compatible with our accessibility standards
- Discuss whether we want to support another CKEditor plugin in core.
User interface changes
- In case we'd be incorporating the CKEditor CodeSnippet Drupal module 'as is' in core, then users would have to enable the module from the Extend page.
- If not, then nothing would change as the feature would be available as part of the CKEditor module integration
- Users are now exposed with a new CKEditor button for code formatting when they are editing a CKEditor-powered text format.
API changes
None expected.
Data model changes
None expected.
Comments
Comment #2
cilefen commented"Discuss relevancy" is important. Developers know that code formatting is something a good site must have of course, but the rest of the world who don't code cannot be convinced. And, developers will find it easy to install a contrib module.
Comment #3
anavarreComment #4
thpoul commentedI second #2. I personally can't imagine anyone else than a developer making use of it. There is already https://www.drupal.org/project/codesnippet which works great.
Comment #5
anavarreIt'd also be helpful for people writing technical documentation, e.g. a knowledge base
#4 - The proposal is about just that: adding https://www.drupal.org/project/codesnippet in a way that suits core.
Comment #6
wim leersWe've done #1993928: Language of parts: Introduce a language toolbar button for the Drupal 8.1 release. That also isn't relevant for everybody (many sites are monolingual). But it's a great option to have that preconfigured/well-integrated out of the box, because it addresses a common need.
I think the same can be said for this module. I'd love to first better understand how mature the Drupal contrib module is (i.e. the maintainer's POV), because there obviously is much more to configure than there is for #1993928: Language of parts: Introduce a language toolbar button. More to configure means more things that can go wrong or can be complex, and it's that that we must fully understand before actually considering to add this to Drupal core.
Comment #7
wim leersI asked the maintainer that question over at #2797577-4: FYI: Proposal to add the module to core.
Comment #8
kevinquillen commentedTwo things that are hard at the moment with the nature of the plugin itself:
There are plenty, plenty of styles that come with the plugin out of the box that should be sufficient. But you always have a few who want to use their own. The module only looks at the styles directory of the plugin right now. This is minor to me.
Adding more languages to highlight is a little higher. At the moment, to support more languages you need to form alter and add your options, and you run into a few tricky parts:
Again, this may suit 99% of folks out there, but if someone wants to highlight some Erlang or Elixir for example, they will be out of luck. I am probably overthinking it and it could be not really an issue. The HighlightJS that would go into core could be customized with a more curated list, not sure how that would be handled.
Beyond that, it seems to work pretty well and feedback otherwise has been good.
edit: actually I just noticed that the default language list has changed with the last few releases, and I will need to update.
Comment #9
kevinquillen commentedIt looks like the version of HighlightJS that ships with the codesnippet plugin is version 8, while the current release is version 10. How could that be resolved? Anyone who replaces HighlightJS with their own custom build will be on the new version.
Comment #10
kevinquillen commentedYou could supply your own highlighting engine to this API.
In the interest of core, which one would satisfy most use cases? I still see similar issues persisting no matter the engine (adding new languages).
Comment #11
wim leersThanks, that's very helpful!
Let's first address the language selection. This is a hardcoded list, that can evolve over time. We don't want to expose the entire list, at least not by default. Funny coincidence: this is exactly the same problem that we faced at #1993928: Language of parts: Introduce a language toolbar button :) There, the language system came to our help in providing a predefined shorter list of languages (United Nations official languages). So then the site builder can choose either that shorter list, or the full list. We could do something similar here.
Second: code syntax highlighting theme selection. This is something that we can indeed easily auto-detect and then expose those choices.
Finally: CKEditor also offers
codesnippet_geshi, which does server-side syntax highlighting (and hence doesn't require JS). This was the most popular option in the past. But not anymore. And more importantly, Geshi itself seems to have died: https://github.com/GeSHi/. So that's not even something we should remotely consider.I'm going to do a review of your code and possibly post some patches.
Comment #12
kevinquillen commentedSome would say to throw all options in, but that isn't practical because it would be about 300kb+ in size for that javascript file, which loads for everyone. ~30-50kb would be optimal to me. Is there a way to customize the build instead of the download from ckeditor.com in a way that is easy to manage?
Was aware of GeSHi but was not aware of its inactivity. HighlightJS just released version 9.6.0 (my bad, I referenced it as 10 before) and is 10 years old. Looks like it still gets regular updates every couple of months.
There are others, like PrismJS, as well.
I would think that at a minimum, it should support:
Comment #13
wim leersI didn't realize there were different packaged versions of highlight.js. That makes things annoyingly subjective :( I'd personally definitely omit Gherkin, for example. I'd also certainly include Diff and INI.
An easy-to-manage way for customizing that for a particular site… that's just not really feasible, unfortunately.
I think that even just for that reason, this being added to core may need to be postponed, until you've figured out a workable solution for that in contrib. Unless we can reach broad agreement on which languages to support.
Although… can't we rely on generic syntax highlighting for everything but the most common languages? Maybe we can even pick an objective metric, such as "top 20 languages"?
Comment #14
anavarreI've been wondering about Prism as well since there's an already existing CKEditor add-on. As the add-on page says:
Which is something that makes me wonder if that could be an alternative to highlight.js in case it wouldn't be suitable to core?
#11
Could config.codeSnippet_languages help?
#12
The prism.js homepage says:
But https://raw.githubusercontent.com/ranelpadon/ckeditor-prism/master/lib/prism/prism_patched.min.js is 98k large and 37k large when gzipped on my local computer.
Perhaps this is because the CKEditor add-on extends other libraries?
#13
We can still follow the top 20 from http://www.tiobe.com/tiobe-index and add a few that we believe to still be relevant for a vast majority of developers/technical writers (e.g. diff)
Popularity
Comment #15
kevinquillen commentedPrism faces that same problem - if you wanted to support highlighting of many languages OOTB, the kitchen sink version (without any extra plugins for it) weighs in at:
Total filesize: 217.17KB (99% JavaScript + 1% CSS)And thats minified.
Prism has the added benefit to have additional plugins (I use it on a non Drupal site) enhancing the highlighter, but it doesn't look like the ckeditor plugin makes much use of those. Again, adding those in is another 1-2 kb each. Not a big deal on desktop + wired connection, but bad for mobile and will ding you on performance benchmark frontend tests (if you're into that sort of thing).
The config.codeSnippet_languages is just a list - to actually support highlighting, the language needs to be packed into the javascript file. For example, if you added a new language in the form and the config, it will appear, but not highlight. That is why you have to go and select what languages you want these highlighters to support, and generate the new js file.
Both of the ckeditor plugins come with them bundled in, which is confusing because they could be versions behind (HighlightJS is) and configured differently than the default downloads on their site.
Comment #16
kevinquillen commentedThis is interesting, I skipped right over this part before.
This is the Common list:
That should be good enough for most, I would think.
Is there a way we can request updating the version of HighlightJS in the ckeditor.com plugin to the latest version? As for the extra languages, could there be an extended UI like Wim was mentioning, and add this into the page when language boxes are checked off:
etc? That might be a good middle ground.
Comment #17
kevinquillen commentedUpon looking at the codesnippet plugin.js, I have refactored the CodeSnippet class to remove the config object that held codesnippet settings, as it was superfluous and really wasn't useful, #2800233: Refactor to remove dependency on config object.
It looks like it was there to do two things:
It looks like I did that to get around some quirks with the
checkboxesform element. For example, thecpparray item value is C++. If you were to wrap that with anarray_map, values like that will never be set as checked. Is there a cleaner way to do this?I also posted a patch to introduce a
hook_uninstallprocedure, where the module cleans up after itself. See: #2800239: Cleanup on uninstall. I noticed that when uninstalling, plugin information isn't removed from editor configurations. Seems like it should be.Comment #18
Grayside commentedLooking beyond content creation, a solution to add syntax highlighting might encompass serialized data highlighting, which goes beyond the WYSIWYG.
Comment #21
wim leersSo, let's be realistic: this is not going to happen in Drupal core in the foreseeable future.