How to write diff code with syntax highlight in Github
Asked Answered
E

3

15

Github supports syntax highlight as follows:

```javascript
let message = 'hello world!'
```

And it supports diff as follows: (but WITHOUT syntax highlight)

```diff
-let message = 'hello world!'
+let message = 'hello stackoverflow!'
```

How can I get both 'syntax hightlight' AND 'diff' ?

Enteron answered 5/11, 2018 at 1:47 Comment(0)
H
8

No, this is not a supported feature at this time.

GitHub documents their processing of lightweight markup languages (including Markdown, among others) in github/markup. Note step 3:

  1. Syntax highlighting is performed on code blocks. See github/linguist for more information about syntax highlighting.

If we follow that link, we find a list of grammars that Linguist uses to provide syntax highlighting on GitHub. Linguist can only apply one of the grammars in that list to a block of code at a time. Of course, one of the grammars is Diff. However, that grammar knows nothing about the language of code being diffed, so you don't get syntax highlighting of that.

Of course, there are other languages which are often combined. For example, HTML is often included in a templating language. Therefore, in addition to the HTML grammar, we also find grammars for HTML+Django, HTML+ECR HTML+EEX, HTML+ERB, and HTML+PHP. In each case, the single grammar is aware of two languages. Both the specific templating language and the HTML which is interspersed within the template.

To accomplish the same thing with a diff, you would need a separate "diff" grammar for every single language listed. In other words, the number of grammars would double. Of course, a way to avoid this might be to treat diff differently. When diff is specified, they could run the block through the syntax highlighter twice, once for diff and once for the source language. However, at least when processing code blocks in lightweight markup languages, they have not implemented such a feature.

And if they ever were to implement such a feature in the future, it would likely be more complicated that simply running the code block through twice. After all, every line of the diff has diff specific content which would confuse the other language grammar. Therefore, every grammar would need to be diff aware, or each line would need to be fed to the grammar separately with the diff parts removed. The problem with the later is that the grammar would not have the context of each line and is more likely to get things wrong. Whether such a solution is possible is outside this cope of this answer, but the point is that it is reasonable to expect that such a feature would be much lower priority to support due to the complexity involved.

So why does GitHub do syntax highlighting in other places on its website? Because, in those cases, it has access to the two source files being diffed and it generates the diff itself. Each source is first highlighted (avoiding the complexity mentioned above), then the diff is created from the two highlighted source files. However, a diff included in a Markdown code block is already a diff when GitHub first sees it. There is no way for them to highlight the pre-diff code first. In other words, the process they currently use would not be transferable to supporting the requested feature.

Harwilll answered 5/11, 2018 at 14:46 Comment(1)
And what if, instead of treating diff as a language for syntax highlighting, it takes two variables, which are two code blocks (both with their language set, should be the same), then it generates a diff, just like GitHub does?Isidora
M
2

You would need to post-process the output of the git diff in order to add syntax highlighting for the right language of the file being diff'ed.

But since you are asking for GitHub, that post-processing is not in your control, and is not provided by GitHub at the moment in its GFM (GitHub Flavored Markdown Spec).

It is supported for source files, in a regular diff like this one or in a PR: GitHub does the syntax highlighting of the two versions of the file, and then computes the diff.

It is not supported in a regular markdown fenced code block, where the +/- of a diff would throw off the syntax highlighting engine, considering there is no "diff" operation done here (just the writer trying to add diff +/- symbols)

Microscope answered 5/11, 2018 at 6:4 Comment(4)
So that's really a feature that Github hasn't provided yet. Thanks!Enteron
@EasonWang No problem. Don't forget to read https://mcmap.net/q/589816/-git-clean-filter-shows-differences-in-the-result-of-git-diffMicroscope
But when I create a pull request, Github can show both 'syntax highlight' AND 'diff' correctly. I just can't understand why they do not support this in normal Issues, Comments and '.md' files.Enteron
@EasonWang I have edited the answer: in one case, GitHub is computing a diff on files it knows the syntax. In the other case (markdown), the "+/-" are foreign symbol not part of the language mentioned at the beginning of the code fence section: the syntax engine does not know what to do with them.Microscope
B
1

Timetravel to 2024

This feature is now supported by Github thanks to the latest release of nokogiri-diff

Ref - https://github.com/github/markup/releases/tag/v5.0.0

Bleary answered 6/8 at 5:31 Comment(2)
Great! How can it be used, i.e. what is the markdown syntax? I tried diff but it didn't work.Titograd
It works the same way as described in a question. ``` diff -let message = 'hello world!' +let message = 'hello stackoverflow!' ```Bleary

© 2022 - 2024 — McMap. All rights reserved.