2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

VSCodeのMarkdownでGitHubのcommit detailsみたいなやつをやりたいけどコードの色は消したくない

Posted at

背景

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のようなものがサポートされておらず,変更部分を強調するなら以下のようにintmainの色を変えることができません.ついでに言うと背景色もないです.

```diff
#include

int main() {
- printf("hello, world!!");
+ printf("hello, world!!\n");
}
```

image.png

一方,コードとして見やすい表示を選択すると,今度は変更部分が強調されず分かりづらいです.

```c
#include

int main() {
- printf("hello, world!!");
+ printf("hello, world!!\n");
}
```

image.png

そこで,JavaScriptとCSSを使うことでVSCodeのMarkdownでもコードの変更部分と予約語に着色したpdf出力を得ることを考えました.

image.png

本論

リバースエンジニアリング

まず,以下のソースコードを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クラスなどを付けることで,intmain,そして追加・削除部分の全てに着色することにしました.

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;
}

結果

無事,見やすく表示されました!

image.png

コード全部

表記の都合上,コードブロックの「```」の前にバックスラッシュを入れています.
コピペするときは,貼り付けた後にバックスラッシュを削除してください.

<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>
2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?