notebook

都内でWEB系エンジニアやってます。

ブログ周りの環境2020

この記事は write-blog-every-week Advent Calendar 202024日目の記事です(4日も遅れてしまった)

ブログ環境 2020 - よしたく blog

yoshitaku-jp.hatenablog.com

を読んで自分もそれっぽいの書いてみようかなと思ったので書いてみる

運用

プライベートのリポジトリにMarkdownをすべて保存している

その中でプレビューなどで確認するようにローカルでMkDocsという静的サイトジェネレータを使っている(2015年くらいから)

MkDocs

www.mkdocs.org

なのでディレクトリ構成はMkDocsに依存した構成となっている

  • ディレクトリ構成(一部)
├── docs
│   ├── memo.md
│   ├── ansible
│   │   ├── ansible_tutorial.md
├── custom
│   ├── index.html
├── bin
│   ├── publish
│   ├── management

そのころの動機としてはアウトプットとして次のようなものをすべて一ヵ所でまとめたかったから

  • 記事
    • Qiita
    • ブログ
    • 社内ブログ
  • スライド
    • 社内LTでの発表資料

さらにその当時frontmatterというのを知らなかったのでMkDocsの管理に使用するYAMLに対してデータを入れると同時に独自の管理用JSONを生成するCLIを書いて管理していた

作ったときはPerlを業務で使用していたのでPerlで書いた(雰囲気だけでも伝われば…)

  • bin/management (DESCRIPTIONのみ抜粋)
__END__

=head1 NAME

memo article management script

=head1 SYNOPSIS

management [filename] [flag] [platform] [categories]

Options:

  --filename(required) docs/category/file.md

  --platform           [blog|draft|qiita|none|radvent|slide]

  --flag               [(o)pen|(m)emo|(d)ictionary|(l)og|(p)ending|(w)riting|(c)heck|(r)eady|(h)ouse]

  --categories         optional category

  --url                url

  --ad                 [amazon]

=head1 DESCRIPTION
  • data.json

マスタのJSONの中身は次のような感じ

[
  {
    "ad" : "",
    "category" : [
       "other"
    ],
    "filepath" : "docs/other/blog_environment2020.md",
    "flag" : "w",
    "id" : "",
    "path" : "other/blog_environment2020",
    "platform" : "draft",
    "title" : "ブログ環境2020と振り返り",
    "updated" : "",
    "url" : ""
  }
]

微妙なところもあるがいまだに使っている

MkDocsにはカスタムページを作成する機能があるので管理用JSONを読み込んで記事の一覧やストックの一覧、検索画面、Revealによるスライド機能など色々くっつけて遊んだりした

当時ほしいと思うものを軒並み作ったので最新のMkDocsだと動かなくなっていてバージョン固定しているw

という背景もあり今考えるとGatsbyや他のものでもすべて代替できそうだなーと感じるものの、差し替えるのもそれなりに時間かかりそうなので本当に気が向いたらするかなー…という温度感

ほかツール

Notionは良さそう!と思ったがスマートフォンから記事のアイデアとか書く習慣自体がなかったのでブログにはあまり活用できていない

買ったものとかサブスク、読書メモとかの管理には使っている

とりあえずの雑多なメモをどうするか

基本的には1ファイル1テーマと言う感じで書くのが理想だがまとまるまで書かないとなかなか書けないので少しでも思いついたら作業ログ感覚で付けるようにした

そうすると、投稿しないがファイル数がめちゃくちゃ増えて今度はどの記事がどんな内容だっけ?というのが一覧でタイトルからのみだとわからなくなってしまった

というのとファイルを作る際にだいたい内容をファイル名にするのでまだわからないなーと言う場合もあって無題のファイルがたくさん発生していた

そのため現在はやり方を変えてmemo.mdファイルに作業ログとか気付いたこととかを書きためていてある程度まとまったタイミングでファイルに切り出して記事化するという感じで運用している

memo.mdがものすごい勢いで増えていくが余裕ができたタイミングなどで振り返りながら「これ記事にするか」みたいな判断をしている

逆にmemo.mdが膨れ上がってくるとそれは振り返って見れていない証拠なのでなるべく減らせるように見返す時間を取っている

1ファイルだけを見れば良い状態にしたのは今のところわりといい感じ

Editor

VS Codeを使用している

MkDocsを立ち上げながらVS CodeでMarkdownを書いていく

基本的に記事書くときなどは自宅のPCオンリー

スマートフォンでは下書きすらもしていない

子どももいるしなかなか時間取れないのでスマートフォンの有効活用は大事だと思っているものの現状できていない

なんか考えて時間の有効活用できるようにしたい…これはそろそろ取り組みたい課題の1つ

textlint

textlintの拡張でリアルタイムに校正している

最初VS Codeで「テキスト校正くん」を使用していたが自分の感覚とあまりマッチしなかったのでprhなどのルールを拾ってきて軒並み適用させて違うなと感じる部分だけカスタムでymlに設定を追加する運用にしている

雰囲気は次のような感じ

filters:
  comments: true
  node-types:
    nodeTypes:
      - Link
      - Image
  whitelist:
    allow:
      - - 出来る
      - で他の
      # ファイル名のリストは除外
      - /.*\.[js|ts|yml|rb|rake|json|html]/
      - /\/etc\/.*
rules:
  prh:
    rulePaths:
      - custom_word_prh.yml
      - node_modules/prh/prh-rules/media/WEB+DB_PRESS.yml
      - node_modules/prh/prh-rules/media/techbooster.yml
  preset-ja-technical-writing:
    ja-no-mixed-period: false
      # periodMark: "."
      # severity: info
    max-comma:
      max: 3
    max-ten:
      max: 3
    max-kanji-continuous-len:
      max: 10
    no-mix-dearu-desumasu:
      preferInHeader: ''
      preferInBody: ですます
      preferInList: である
      strict: false
    arabic-kanji-numbers: true
    no-double-negative-ja: true
    no-dropping-the-ra: true
    no-doubled-conjunctive-particle-ga: true
    no-doubled-conjunction: true
    no-doubled-joshi:
      min_interval: 1
    no-nfd: true
    no-invalid-control-character: true
    no-exclamation-question-mark: false
    no-hankaku-kana: true
    ja-no-weak-phrase: true
    ja-no-successive-word: true
    ja-no-abusage: true
    ja-no-redundant-expression: true
    ja-unnatural-alphabet: true
    no-unmatched-pair: true
  preset-ja-spacing:
    ja-space-between-half-and-full-width:
      space: never
    ja-space-around-code: false
    ja-no-space-between-full-width: true
    ja-nakaguro-or-halfwidth-space-between-katakana: true
    ja-no-space-around-parentheses: true
    ja-space-after-exclamation: false
    ja-space-after-question: false
  spellcheck-tech-word: true
  period-in-list-item:
    periodMark: ''
    periodMarks:
      - "."
      - "。"
      - "."
    ignoreLinkEnd: true
    allowPeriodMarks: []
    allowEmoji: false
    forceAppendPeriod: false
  general-novel-style-ja: false
  ja-hiragana-keishikimeishi: true
  ja-hiragana-fukushi: true
  ja-hiragana-hojodoushi: true
  "@textlint-ja/textlint-rule-no-insert-dropping-sa": true
  prefer-tari-tari: true
  abbr-within-parentheses: true
  no-mixed-zenkaku-and-hankaku-alphabet: true
  footnote-order: true

せっかくやるのだからとGitHub ActionsによるCIも入れて過去書いた記事に対しても実行するようにしている

雑多なメモすべてに対して適用するのはつらいなと思ったので公開されているものと下書きが終わったファイルのみに対象を絞った(それでも結構多くて辛かった)

過去の記事は読んでみると色々若かったなーとか思いながら懐かしみつつ修正した

あと工夫していることといえばショートカットとスニペットくらい

  • ショートカット

VS Codeで問題の内容をショートカットで表示する - notebook

swfz.hatenablog.com

  • スニペット

VS Codeのスニペットを使いtextlintのdisableを楽に行う - notebook

swfz.hatenablog.com

このあたりは個人的にとても体験が良くて赤線が出てきてカーソル合わせてショートカットで表示、内容によって手動で修正もしくは除外用のスニペットで除外という一連の流れをキーボードのみで操作できるのでマウスまで手が動かない

単語数の制限は除外することが多いのでそろそろ見直したほうが良いかなとも感じている

リンク用文字列の挿入

次の4つをテキストエリアに表示してコピー&ペーストするだけでOKになるようなbookmarkletを使っている

対象ページに遷移してブックマークで新たにウィンドウを表示してコピー用に出力を出している

f:id:swfz:20201228153347p:plain

  • Markdown埋め込み
  • hatena埋め込み
  • gist-it
  • GitHubのソースへの直リンク

作ったときはGitHubのコードをそのまま乗せたりしたいという理由でこういうことしていたが最近はあまり使っていないなーと書いていて思った

多分探せばVS Codeの拡張にもありそうだなーと思いつつあまりストレスを感じていないのでしばらくこのままかな

画像の挿入

投稿時はフォトライフでアップロードするので画像の表示が独自記法になってしまう

そうするとローカル(MkDocs)でのプレビュー上で表示できないという問題が起きてしまうのではてなブログには依存しないような書き方をしていて、投稿時にCLIがそのへんを吸収してくれるようにしている

  • ローカル

![alt](blog_environment202001.png)

  • 投稿時

[f:id:swfz:20190224151651g:plain]

というような変換が必要

CLIについては「投稿」の項で書く

その他拡張

最近使ってよかったのがBigQueryのクエリ結果をJSONでコピーしてVS Codeに貼り付け、CSVへ変換してCSVからテーブル変換する拡張を使ってサクッとテーブル風に表示できる流れが体験良かった

次の2つの拡張を使っている

JSON to CSV - Visual Studio Marketplace

CSV to Markdown Table Converter - Visual Studio Marketplace

ARRAYやSTRUCTのカラムがある場合はうまく整形できないがそれ以外のパターンであればサクッとできる

f:id:swfz:20201228153353p:plain

これをコピーして

f:id:swfz:20201228153359g:plain

楽ちん

すべてCtrl+Shift+Pでコマンドパレットを出してそこから選択している

探した感じJSON→MarkdownTable直で変換できる拡張は見当たらなかったので自分で拡張作ってみる題材としては良さそうかも?

あとオマケ程度で画像やテーブルなどはなんかしらの拡張入れてショートカットCtrl+Spaceで表示できるようにしている(が、どの拡張だったか自分で設定したのかは覚えていない…)

f:id:swfz:20201228153414g:plain

投稿

はてなブログのAPIをたたいて記事投稿+画像のフォトライフへの投稿を行ってくれるGemを作った

swfz/hatenablog_publisher: hatenablog publish with imagefile

github.com

上記で記事管理はマスタのJSON+CLIでやっていると書いたがこのマスタのJSONを読みに行って記事の中の情報をパースして画像を引っ張り、フォトライフへ投稿、レスポンスから独自記法への変換を行いMarkdown上は差し替えてはてなブログへ投稿するということをやっている

この流れで汎用的な部分を切り出してGem化した

はてなブログを使っていて面倒だった部分

はてなブログで書いていてどうしても面倒だったのが次の2つ

  • 画像のアップロード(フォトライフ)
  • アップロードした画像の表記が専用表記のため記事と同期を取ったとしてもローカルでは表示できない

これによって結構エネルギーがいるというかどうしても画像が多いと「面倒だなー」という感情が出てしまいあまり良くないなと思ったのでそのへんをGem+CLIで解決している

この流れで投稿をCLI経由で行うようになるとリポジトリ(ローカル)→はてなブログへの一方向の同期になってしまうが、作ったことで大分記事投稿に対するネガティブ感情が減ったので作ってよかったと思っている

蛇足だがこの日中に投稿したいみたいな場合投稿までのリードタイムが短いので滑り込みしやすいw

あと修正時に画像をもう一度アップロードさせるのが微妙に感じたので管理用のJSONなりfrontmatterなりに追記し同じ画像を何度も上げなようにしている、書いていて気付いたが画像の内容に対する変更にはファイル名を変更しないと対応できない…

  • 投稿した後の管理用JSONファイルの中身
{
   "ad" : "amazon",
   "category" : [
      "terraform",
      "gcp"
   ],
   "filepath" : "docs/terraform/cloudrun_scheduler.md",
   "flag" : "o",
   "hatena" : {
      "id" : "26006613664272705",
      "image" : {
         "cloudrun_scheduler01.png" : {
            "id" : "tag:hatena.ne.jp,2005:fotolife-swfz-20201212235741",
            "image_url" : "https://cdn-ak.f.st-hatena.com/images/fotolife/s/swfz/20201212/20201212235741.png",
            "syntax" : "[f:id:swfz:20201212235741p:image]"
         }
      }
   },
   "id" : "",
   "path" : "terraform/cloudrun_scheduler",
   "platform" : "blog",
   "title" : "TerraformでCloudRun+CloudSchedulerを構築する",
   "updated" : "2020-12-12",
   "url" : "https://swfz.hatenablog.com/entry/2020/12/12/235827"
},

画像のURLなどは画像のファイル名をキーとして保存している

Gemの機能プラスアルファでリリースノート用のアイキャッチ画像の自動生成(背景画像は固定で文字の入れ込み)やAmazonのアソシエイトタグを自動で挿入するようにしたりしている、この辺も地味に作業時間取られて面倒くさいなーと思っていたので今は特に意識せずに自動で行ってくれるので体験として良い

不満があるとすればはてなブログのAPI自体が更新されていないので「タグ」機能などが使えない点くらいか

可視化

この辺は書き出すと結構なボリュームになりそうなのでまた別途気力が持てば書く

Datastudioでこんなダッシュボードを用意してBigQuery,Dataflow,CloudFunctionsなどを使って日々自動でデータを収集している

f:id:swfz:20201228153434p:plain

これのおかげでDataStudioだったりBigQueryの素振りがはかどっている

まとめ

とりあえず今までやっていることとか工夫していることとか書き出した気がする

書き出してみるとそれなりに色々やっているなーという感じになった

記事を書いていく中で課題や改善のネタが出てきた気がするので明確化して取り組もうと思う

具体的にはこのあたり

  • ほとんどプライベートリポジトリに閉じたものとなっている
    • 汎用的に使えるような部分を切り出す
  • 検索周りの改善
    • メモリポジトリ、Tilリポジトリ、はてぶ間でまとめて検索できるようにし「これ見たことあるけど…」みたいな場合の一時検索を行いたい
  • スマートフォンからでも草案やメモを書いてmemoリポジトリに同期できる仕組み
    • スマートフォン活用頑張っていきたい
  • ブログ周りの指標の収集、分析

来年もしくは再来年などまたこのような記事を書けるよう改善していきたい