「Dank Mono」 - プログラマーにとっての究極のモノスペースフォント

カテゴリー:  Tech タグ:  font
/images/2023/05/07/dank-mono.webp

昨年 MonoLisa というフォントを購入して使用していましたがいくつか不満があり、今回 Dark Mono というMonospaceのフォントを購入しました。

MonoLisaの不満

MonoLisa は読みやすく、紛らわしい文字も判別しやすい工夫が有り、リガチャ対応やPowerLineなど素晴らしいフォントなのですが、以下の2点で不満を覚えていました。

文字間隔が広い

字を詰めすぎず読みやすさを追求していると思うのですが、その分同じ文字数を表示するのに間延びしてしまいます。このゆったりした文字間隔がよいと思える時と、スペースを効率が悪いと感じてしまう時と疲れ具合によりまちまちです。感覚的にはもう少し効率よい表示が出来たほうが好みです。

高額なWebフォント

自分の環境で見えているコードをそのまま外部にも表示したいので、その場合Webフォントが必要です。MonoLisaはWebフォントも提供しているのですが、さらに追加で最上位のライセンスを購入する必要があります。2万円以上と高額です。

Dank Monoフォントとは

Dark Mono は、Typographerでなく、エンジニアの Phil Pluckthun氏が開発したフォントです。

フォントのホームページで以下のように謳っているように、コーディングに特化しRatinaのような現代の高解像度ディスプレイでの使用を考慮してデザインしたフォントのようです。

A typeface designed for coding aesthetes with modern displays in mind. Delightful ligatures and an italic variant and bold style.

What sets Dank Mono apart? 」という作者の記事で述べられているように、高解像度のディスプレイ向けにデザインを犠牲にすることなく、見た目も美しいフォントを目指して作られた MONOSPACEのフォントです。小文字の 'f'が特長的です。イタリック体も凝っていて、見ていて厭きません。

極端に文字間を詰める事なくMonoLisaより適度な密度があります。

Dank MonoとMonoLisaの比較

Dank MonoとMonoLisaの比較

比較すると、同じフォントサイズでもDank MonoのほうがMonoLisaより多くを表示することが可能な事が分かります。

有償のフォントですが、$30足らずで TrueType、OpenType、Webフォントの全ての形式で、Bold, Regular, Italic体が全てそろっています。Webフォントまでこの価格で提供されているのは、十分リーズナブルだと思います。

このサイトのコーディングなどのフォントも、Webフォントを使って Dank Monoに変更しました。

以下のサンプルとして、Rustで書いた適当なコードを貼り付けておきます。

use rusoto_core::{Region, RusotoError};
use rusoto_s3::{S3, S3Client, CopyObjectRequest, CopyObjectError, ListObjectsV2Request, ListObjectsV2Output};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // AWS認証情報の設定
    let region = Region::UsEast1;
    let client = S3Client::new(region);
    let source_bucket = "original-movies";
    let dest_bucket = "destination-movies";

    // ソースバケット内のオブジェクトを一覧表示する
    let mut continuation_token: Option<String> = None;
    loop {
        let list_request = ListObjectsV2Request {
            bucket: source_bucket.to_owned(),
            continuation_token: continuation_token.clone(),
            ..Default::default()
        };
        let result: ListObjectsV2Output = client.list_objects_v2(list_request).await?;
        let objects = result.contents.unwrap_or_else(Vec::new);
        for object in objects {
            // ソースバケットからオブジェクトをコピーする
            let copy_request = CopyObjectRequest {
                bucket: dest_bucket.to_owned(),
                key: object.key.unwrap().to_owned(),
                copy_source: format!("{}/{}", source_bucket, object.key.unwrap()),
                ..Default::default()
            };
            match client.copy_object(copy_request).await {
                Ok(_) => println!("Copied object: {}", object.key.unwrap()),
                Err(RusotoError::Service(CopyObjectError::PreconditionFailed(msg))) => {
                    // オブジェクトが既に存在する場合は上書きする
                    if msg.contains("Key is already being copied") {
                        println!("Object already exists: {}", object.key.unwrap());
                    } else {
                        println!("Error: {:?}", msg);
                    }
                },
                Err(err) => println!("Error: {:?}", err),
            }
        }
        continuation_token = result.next_continuation_token;
        if !result.is_truncated.unwrap_or(false) {
            break;
        }
    }
    Ok(())
}

コメント

Comments powered by Disqus