背景
Markdownでコードを書く上で,便利な機能が二つあります.
まず一つは,コードブロックを書く機能.
```c
#include
int main() {
printf("hello, world!!\n");
}
```
#include <stdio.h>
int main() {
printf("hello, world!!\n");
}
もう一つは,GitHubのcommit detailsのように,変更部分を分かりやすく表記するもの.
```diff_c
#include
int main() {
- printf("hello, world!!");
+ printf("hello, world!!\n");
}
```
#include <stdio.h>
int main() {
- printf("hello, world!!");
+ printf("hello, world!!\n");
}
しかしVSCodeの拡張機能によるMarkdownでは,diff_c
のようなものがサポートされておらず,変更部分を強調するなら以下のようにint
やmain
の色を変えることができません.ついでに言うと背景色もないです.
```diff
#include
int main() {
- printf("hello, world!!");
+ printf("hello, world!!\n");
}
```
一方,コードとして見やすい表示を選択すると,今度は変更部分が強調されず分かりづらいです.
```c
#include
int main() {
- printf("hello, world!!");
+ printf("hello, world!!\n");
}
```
そこで,JavaScriptとCSSを使うことでVSCodeのMarkdownでもコードの変更部分と予約語に着色したpdf出力を得ることを考えました.
本論
リバースエンジニアリング
まず,以下のソースコードをVSCodeのMarkdownでHTML化しました.
```diff
-import numpy
+import numpy as np
```
そうして得られたHTMLコードの,関係ある部分を抜粋すると以下のようになっていました.
<style>
.hljs-deletion {
color: #c82829;
}
.hljs-addition {
color: #718c00;
}
</style>
<pre class="hljs"><code><div><span class="hljs-deletion">-import numpy</span>
<span class="hljs-addition">+import numpy as np</span>
</div></code></pre>
追加部分はhljs-additoin
クラスに,削除部分はhljs-deletion
クラスに属させることでそれぞれ装飾しているようです.
そこでここでは,
```c
#include
int main() {
- printf("hello, world!!");
+ printf("hello, world!!\n");
}
```
という普通のコード表記に+
や-
を入れ,この+
や-
にhljs-additoin
クラスなどを付けることで,int
やmain
,そして追加・削除部分の全てに着色することにしました.
JavaScriptコード
Markdownコードから+
と-
を読み取り,それぞれ<span class='hljs-addition'>+</span>
,<span class='hljs-deletion'>-</span>
に書き換えます.
// Markdownファイルの最後に実行
// +や-を上書き
// ただし,プログラム中の普通の足し算や引き算に影響がないよう,改行直後の+-のみを変更
const pmChange = () => {
var codes = document.getElementsByTagName("code");
for (let i = 0; i < codes.length; i++) {
var c = codes.item(i).getElementsByTagName("div").item(0);
var cs = c.innerHTML.split("\n+");
for (let j = 0; j < cs.length-1; j++) {
c.innerHTML = c.innerHTML.replace(
"\n+",
"\n<span class='hljs-addition'>+</span>"
);
}
cs = c.innerHTML.split("\n-");
for (let j = 0; j < cs.length-1; j++) {
c.innerHTML = c.innerHTML.replace(
"\n-",
"\n<span class='hljs-deletion'>-</span>"
);
}
}
};
CSS
VSCodeのMarkdownでは,削除・追加部分の文字色は変わっていましたが背景色までは変わっていませんでした.
ここでは背景色も変えることにします.
/* 透明度の定義 */
body {
--opacity: 0.2;
}
/* 背景色 */
span.hljs-addition::before,
span.hljs-deletion::before {
position: absolute;
max-width: 100%;
content:
" "
" "
" "
" "; /* 80文字の空白 */
}
span.hljs-addition::before {
background-color: rgba(124, 252, 0, var(--opacity));
}
span.hljs-deletion::before {
background-color: rgba(255, 99, 71, var(--opacity));
}
/* 文字色 */
span.hljs-addition {
color: #718c00;
}
span.hljs-deletion {
color: #c82829;
}
結果
無事,見やすく表示されました!
コード全部
表記の都合上,コードブロックの「```」の前にバックスラッシュを入れています.
コピペするときは,貼り付けた後にバックスラッシュを削除してください.
<style>
/* 透明度の定義 */
body {
--opacity: 0.2;
}
/* 背景色 */
span.hljs-addition::before,
span.hljs-deletion::before {
position: absolute;
max-width: 100%;
content:
" "
" "
" "
" "; /* 80文字の空白 */
}
span.hljs-addition::before {
background-color: rgba(124, 252, 0, var(--opacity));
}
span.hljs-deletion::before {
background-color: rgba(255, 99, 71, var(--opacity));
}
/* 文字色 */
span.hljs-addition {
color: #718c00;
}
span.hljs-deletion {
color: #c82829;
}
</style>
\```c
#include <stdio.h>
int main() {
- printf("hello, world!!");
+ printf("hello, world!!\n");
}
\```
<script>
// Markdownファイルの最後に実行
// +や-を上書き
// ただし,プログラム中の普通の足し算や引き算に影響がないよう,改行直後の+-のみを変更
const pmChange = () => {
document.write("abc\ndef<br>");
var codes = document.getElementsByTagName("code");
for (let i = 0; i < codes.length; i++) {
var c = codes.item(i).getElementsByTagName("div").item(0);
var cs = c.innerHTML.split("\n+");
for (let j = 0; j < cs.length-1; j++) {
c.innerHTML = c.innerHTML.replace(
"\n+",
"\n<span class='hljs-addition'>+</span>"
);
}
cs = c.innerHTML.split("\n-");
for (let j = 0; j < cs.length-1; j++) {
c.innerHTML = c.innerHTML.replace(
"\n-",
"\n<span class='hljs-deletion'>-</span>"
);
}
}
};
pmChange();
</script>