忘れな草稿

技術・科学系の文書を置いとく処を構築した

以前日常的なこととかを書くブログのほうでも言及したように、日常のこととは別に技術系のことや自然科学系のことを書く専用のサイト、つまり今このページがあるサイト(https://tasuten.github.io/notes/)がようやくリリース出来そうなのでその技術スタックとかこだわりポイントとかを一番最初のエントリとして投稿しておく。ただこれはあくまで執筆時点でのコードのポイントなのでこの文章を読んでる時分によってはいろいろ変わってるかもしれないのであくまで参考程度に。

個人的にはブログのように日付区切で、とは考えてなく雑な言い方をすると自分専用QiitaやZenn、dev.toみたいな感じに思ってるので「技術ブログ」という名称は使ってないけど、まあ中身としては巷でよくある静的サイトジェネレータを用いた技術ブログの類みたいなモンではある。

技術スタックについて

静的サイトジェネレータ

基本的には静的サイトジェネレータにGatsbyを使ってて、gatsbyjs/gatsby-starter-blogをベースに自分に必要なモノだけになるようにかなり機能を削ぎ落としてシンプルにした感じ。

Gatsbyを選んだ理由、つまり静的サイトジェネレータの選定の際に気にしたポイントとしては

  • JSXでテンプレートが書けること

    • 見通しをよくするため変数・定数を導入したりモジュール化などを始めるとliquidjsやNunjucksでは基本的にHTMLが主でアルゴリズムや構造を書く仕組みは従でやや辛くなってくる
    • 一方JSXは確かに最初の見た目こそ気持ち悪いがJavaScriptが主、HTMLが従な感じで比較的アルゴリズムや構造を表すには確かに便利
  • Markdown処理系が選べること・拡張しやすいこと

    • もしくはremarkjsを採用していること

      • いわゆるMarkdown処理系の中では恐らく一番拡張の自由度が高い
    • 脚注やコードブロックのシンタックスハイライト、KaTeXによる数式などMarkdown処理系をそこそこ拡張したかった
  • SCSSが使えること

    • これについては後でも多少触れる
  • ある程度のユーザ数が居て情報などが多いこと、比較的メンテがされていること

あたりで、これを満たすのを選んでいく中でGatsbyに絞られたという感じ。

最初は11tyでやっていて確かにかなりシンプルで良かったのだけれど、11tyはMarkdown処理系がmarkdown-it以外実質的に使えず、また11tyはシンプルであるがゆえに拡張しようとするとちょい厳しい感じがあったのでお流れに。

今にして思えばNext.jsもよい選択肢ではあった。けど少なくとも選定時点ではGatbyのほうがより静的サイトジェネレータ的であったこと、あとはGatsbyのHot ReloadingがなかなかDeveloper ExperienceというかWriting ExperienceがよかったのでGatsbyにした。

ただGatsbyはReactと蜜に結合してて、正直コンテンツ的にはペラ1枚とそう変わらないこのサイトにReactはやや富豪的というか無駄が多く、またフレームワークというものの性質としてそのフレームワークの流儀=Gatsbyのやり方を外れると一気に辛くなるので正直よい乗り換え先(non-ReactでかつJSXというかなり歪な要求にはなるけど)があったら乗り換えたいとは思ってる。もしくは、一から書こうかとも思ってる。

ただやっぱりHot ReloadingがかなりReactに依存してる感はあるので、Hot Reloadingを持ったままとなると「開発モードではReactをon」「本番コード生成ではそのへんのフレームワークコードを全部落とす」というアプローチになりそうかなー、とは思ってる。

CSS(SCSS)

CSSに関してはmeta-langとしてSCSSを採用した。また、スタイルは既存のフレームワークなしで全部フルスクラッチで書いた。ただ既存のフレームワークもかなり参考にはしてる。

SCSSの採用理由としては、mix-inの仕組みや変数の扱い、ネストをいい感じにやってくれるのがよかった。

で、CSSをほぼフルスクラッチで書いた理由としては雑に言えば「自分のサイトだし出来るところまでカスタマイズしたい」欲が強く出たと言った感じ。既存のフレームワークを読み込む方式だと例えば気に入らないところがあると後から他のCSSファイルで上書き、という方式になる。けどどうせそれをするなら最初から自分のコードが手元にあったほうがいろいろ融通も効くかなぁと言うことで。

ちなみに全部というのはいわゆるReset CSSやコードハイライトも含めて全部で、外部のCSSが使われてるのはGoogle Fonts(Fira Sansを採用してる)の部分とKaTeXによる数式部分のみとなっている。

CSSの工夫点に関してはGitHubソースを見てもらうほうが多分早い。

Reset CSSでの工夫の要点としては

  • 少なくともサイト構築次点ではform系の要素はないのでそのへんのresetは省いてる
  • ルビまわりなど若干日本語特有のモノを追加してる

などがある。

コードのハイライトはHTMLの生成に関してはPrism、カラースキームに関してはNordを採用してる。

たとえばこんな感じで。

const fizzbuzz = (n) => {
    if (n % 15 == 0) {
      return "fizzbuzz";
    } else if(n % 5 == 0) {
      return "buzz";
    } else if(n % 3 == 0) {
      return "fizz";
    } else {
      return n.toString(10); // 基数10で文字列変換
    }
}

Array.from(Array(100).keys()).map( n => {
  console.log(fizzbuzz(n+1))
})

カラースキームのCSSに関してはNordのはPrismJS/prism-themesに既に半公式のがあったのだけれど、行の折り返しやフォントあたりもカスタマイズしたくてNord公式のガイドラインや他のエディタのシンタックスハイライトなども参考にしつつゴリゴリっと書いた。

実を言うと一箇所本来のNordの色ではないガイドラインから外れたの部分があって、それは上記の例で言えばコメント部分で使われてる色なんだけど、これは元の色のままだと「十分なコントラスト比が確保できてない」とアクセシビリティのwarningが出るので元の色々をベースにしつつやや明るくしてる。

他、ページ全体のレイアウトや色に関しては見ての通りモノトーンで1カラムとしてる。

方針としては

  • フォントサイズは基本等比数列で

    • そのままだと調整しにくいような場合のためにより細かいsecondaryな比も併用してる
  • 縦のレイアウトに関してはvertical rhythmとよばれる手法を採用し基本単位の繰り返しで整える
  • いわゆるレスポンシブデザインに関しては「技術系のメモということで見る人の大半はPCブラウザだろう」ということでPC-Firstな方針で

のようなのがある。上2点に関しては無難なノウハウを採用してる、という印象。

またheadingはh2, h3あたりを主としそれ以下のものはだいぶ手を抜いてる。だってh4くらいまでならまだしも文章でh5h6は使わんでしょ。1

あと大きめのサイズの見出しではfont-variant-east-asian: proportional-width;でOpenTypeフォントの機能のプロポーショナル仮名を採用してシュッとして見えるようにしてる。

フォントの選定に関してはまず考えるべきものとして欧文フォントと和文フォント、それとコード部分で使われる等幅フォントということになる。

和文フォントに関しては沼沼の沼で、Webフォントもパフォーマンスを考えるとまだ少し厳しいかなということでsans-serifとだけ指定してる。また、コード部分のフォントもWindowsをConsolas、Appleデバイス(macOS, iOS)はMenloで、AndroidはRoboto Monoとそれぞれ一番無難そうな等幅フォントでカバーした。Linux Desktopなどの環境は考え出すときりがないので諦めてmonospaceにfallbackさせている。

欧文フォントは、まずこれは個人的な好みもあるけどHumanist sans-serifあたりがほどほどに柔らかく見出しでも本文でも読みやすいと感じる。で、これまたOS指定のものを探してもいいのだけれど、「OSごとの微妙な差異で悩みそうな気がするなー」ということでOSに依存しないWebフォントを採用している。もちろんパフォーマンスへの影響は出るだろうけど、Google Fontsの中でもかなりポピュラーなFira Sansを指定することでどっかでキャッシュが効いてるだろうと期待してる。

サイト名に関しては文字通り「忘れな草」+「草稿」のいわゆるかばん語で、「草稿」のようにサクッと気軽に書けるように自分への心理的ハードルを下げるのと、一方で「忘れな草(forget-me-not)」のとおり忘れられるコンテンツにはならないで欲しい、とのまあざっくりとした気持ちを込めた。と言ってもふと頭に降ってきたただ語呂がいい語というのも否定はしない。

faviconは大体のブラウザをカバーする32×32の.ico、Twitter CardやOGP向けの画像としてはTwitterのSummaryが144×144以上、FacebookなどのOGPが200×200以上とのことだったのでその最下限の200×200としている。apple-touch-iconやandroid-touch-iconなどはそもそものユースケースを想定すると必要ないかなと思い指定していない。

ついでに細かいがfaviconの方は若干角丸にしてる。この辺はInkscapeやGimpでサクッと作った。曲率半径は適当に指定した(画像幅200pxに対して)50pxがよかったのでそのまま採用してる。

デザインのモチーフは背景色になってる薄い青紫はJIS慣用色名の「わすれなぐさ色」で、真ん中のオブジェクトはペントミノの1つのF-pentominoで、これはコンウェイのライフゲームにおいて長寿型とよばれるなかなか面白い性質を持ち、様々なパターンを生成する。のでまあ理系っぽくってコンセプトに合っていいんじゃない?と思って採用した。

他には

  • RSSは採用していない

    • これはRSSのAtomフォーマットはどうもupdatedされた日時や各エントリごとの一意なidが必要なんだけどこれのうまい設計が思いつかなくて面倒くさくなって留保した
  • print用のCSSは準備できてないので例えばこのサイトを印刷しようとするとあんまり綺麗じゃない、がそもそもそこまで優先度が高くなさそうと思った
  • KaTeXが稀に微妙に描画がダメるときがあるけどそのへんは諦めてる
  • preactは試したけどどうせサイトビルドの段階で(fullのほうの)reactを要求されたので依存関係を増やすほどではないなと思い採用していない
  • Markdownの仕様かしらないけど改行入れると半角スペースに変換されて、和文だと若干の違和感が生じる
  • dependabotとかのためにせめて簡単なe2eテストもどきを入れたいけど依存関係をこれ以上増やすのは面倒

って上げだすときりがない。いろいろ至ってない点はあるけど Done is better than perfect.とりあえず動くと思うからリリースしようぜの精神で出した次第。

なんでまあ後は適当にKaTeX表示チェック用の数式でも置いてお茶を濁しときます。多分更新頻度はそんなに高くないでしょうけどこれからまあぼちぼち文章を書いて置いていければと思います。

Gμν+Λgμν=8πGc4Tμνitψ(x,t)=[22m2+V(x,t)]ψ(x,t)\begin{aligned} G_{\mu\nu} + \Lambda g_{\mu\nu} &= \frac{8 \pi G}{c^4}T_{\mu\nu} \\ i \hbar \frac{\partial}{\partial t} \psi(\bm{x},t) &= \left[ \frac{-\hbar^2}{2m} \nabla^2 + V(\bm{x}, t)\right] \psi(\bm{x},t) \end{aligned}

  1. ちなみにHTMLのタグ上はh7以降は無い