Skip to main content

Fixing Diffs

· 4 min read
Iain Davis
Software Engineer, Principal @ IainDavis.dev

In my last blog post, I used a diff to show how my SVG files had changed.

For those who don't know a diff is an operation on two files that shows a graphical representation of how one is different than the other.

They look like this:

on the command linein a nice UI like GitHub
Screen capture showing a command-line diffScreen capture showing a diff in GitHub

The green lines show something being added, the red ones something being removed. A change to a line will produce a red line AND a green line in the output.

In theory, Docusaurs supports a notation to produce nicely formatted diff output.

Indeed, in my VS Code editor, the lines prefixed with '+' were highlighted green, and the ones prefixed with '-' were highlighted red. But in the rendered page, there was no change from a standard code block:

editor: right!where it matters: wrong!
Screen capture showing appropriate line-coloring in editorScreen capture showing no line-coloring in rendered website

I'm not the first to run into this problem (and in fact it's not the first time I've run into it).

I found this solution online:

Docusaurus relies on a library called 'Prism' for its syntax highlighting, and Prism includes a feature called 'magic comments'. If you define a magic comment, and then include that magic comment in your code blocks, prism will remove it from the output and apply a CSS class to the next line, which you can use to apply formatting. Docusaurus allows you to modify the Prism configuration (including magic comments) from within its own configuration file.

Applied to my repository, it looks like this:

Definition of magic comments:

const config: Config = {
// ... other docusaurus configuration options
themeConfig: {
// Replace with your project's social card
// ... other theming configuration
prism: {
// ... other prism configuration
magicComments: [
{
className: 'code-block-diff-add-line',
line: 'diff-add',
},
{
className: 'code-block-diff-remove-line',
line: 'diff-remove'
}
]
},
} ,
};

adding variables and styles to my global style definitions:

:root {
/* ...existing light-theme (default) variable defs styles... */
--iaindavisdev-diff-insertion: #b0f6ac;
--iaindavisdev-diff-deletion: #fcc8c0;
}

/* For readability concerns, you should choose a lighter palette in dark mode. */
[data-theme='dark'] {
/* ...existing dark-theme variable defs styles... */
--iaindavisdev-diff-insertion: #254323;
--iaindavisdev-diff-deletion: #432723;
}

/* new styles! */
.code-block-diff-add-line {
background-color: var(--iaindavisdev-diff-insertion);
display: block;
margin: 0 -40px;
padding: 0 40px;
}

.code-block-diff-add-line::before {
position: absolute;
left: 8px;
padding-right: 8px;
content: '+';
}

.code-block-diff-remove-line {
background-color: var(--iaindavisdev-diff-deletion);
display: block;
margin: 0 -40px;
padding: 0 40px;
}

.code-block-diff-remove-line::before {
position: absolute;
left: 8px;
padding-right: 8px;
content: '-';
}

/**
* use magic comments to mark diff blocks
*/
pre code:has(.code-block-diff-add-line) {
padding-left: 40px!important;
}

pre code:has(.code-block-diff-remove-line) {
padding-left: 40px!important;
}

And you can see the result in this post.

There's an added bonus: my code blocks now retain their original syntax highlighting as well as adding the diff highlights. In the default Docusaurus diff highlighting, all formatting is stripped out except for the diff highlights, unless you're willing to do some more work to shoehorn some more of prism's native capabilities in to Docusaurus.

On the down-side, in the editor now, those blocks are littered with kind of obnoxious comments that make it harder to read. Eventually, I will probably implement this more robust fix (from the same thread as the quick-fix I've applied!):

For now, this was a solution I can implement (and document here) much more quickly, so I'm happy with it for today.