There's an echo in my head

日々のメモ。

HTMLからMarkdownに変換するツールを書いている

Rust を使って、自力で HTML のパーサを書いている。

https://github.com/a2ikm/html2md

モチベーションは、

  • Google Docs で整形してから Markdown 形式に落とし込むことが最近多く、いい感じにやってくれるツールが欲しかった
    • Google Docs と連携して変換するツールもあるにはがあるが、外部に共有することができないケースが多く、使えない
    • HTML から Markdown に変換するは多くあるが、 Google Docs フレンドリーなものが欲しかった
      • レビューの記録を削ったり
      • CSS でネストしてるように見えるリストをちゃんとネストさせたり
  • HTML のパーサを書いてみたかった
    • ブラウザのように文法的に間違っているものを許容する仕組みをどう実現するかに興味があった
  • Rust を使ってみたかった

現状、それっぽく変換できるようにはなっているが、まだいくつか課題がある。

  • 利用するのに今はソースコードからビルドするしかないので、 GitHub Actions 上でクロスコンパイルしてバイナリをダウンロードできるようにしたい
  • レビューの記録を削るようなオプションを提供したい
  • CSS でネストしたリストを今は Markdown レンダリング時にインデントで調整しているが、 AST として表現できるようにしたい
  • Google Docs でダウンロードできるのは HTML 直ではなく画像等とまとめた zip ファイルなので、それを扱えるようにしたい

追々やっていきたい。

ローカル開発環境用のクレデンシャルを 1Password で管理してコマンド実行時にラッパースクリプトで流し込む

趣味で Go のアプリケーションを開発しているときに、ローカルの開発環境用の環境変数の管理について次のようなことを悩んでいた。

悩んだ結果、次のようなことをやってみた。

  • クレデンシャルは 1Password で管理する
  • make 経由でのコマンド実行時には、 1Password から読み込んだクレデンシャルを export してくれるラッパーをかませる

具体例として、まずラッパーはこんな感じ。ファイル名は local_exec.sh とする。

#!/usr/bin/env bash

set -e

# 直接書けるものは直接書く
export PORT=8080

# 1Password に格納されているクレデンシャルは CLI の `op read` コマンドで取り出す
# 引数に渡しているのはフィールドごとに割り当てられている secret reference という URL
# ref: https://developer.1password.com/docs/cli/reference/commands/read
export YOUR_CREDENTIAL=$(op read "op://myvault/myapp/secret/key")

exec "$@"

そして Makefile はこんな感じ。

.PHONY: run
run:
    ./local_exec.sh myapp

実行方法は普段の make と同じ。

$ make run

ただし、1Password へのアクセスが要求されていることの確認ダイアログに同意する必要がある点に注意が必要。最初の1回だけでなく、どうやら一定時間ごとに要求されるようになっているらしい。

以上のようにすることで、クレデンシャルは 1Password に一元管理したうえで、コマンド実行時の export の処理も他の環境変数同様にラッパーに集約することができた。

ただ、これを行うには、他の人とソースコードを共有するときに次のような前提が必要となる。

  • 1Password が導入されていること
  • 共通の secret reference にクレデンシャルが設定されていること

これらは結構大きなハードルになるので、複数人が参加するプロジェクトでは導入は難しそう。

メモ

.env から環境変数を読み込む場合には Songmu さんの「bashでdotenvファイルを環境変数に読み出す」が参考になる。

macOS をセットアップするときに設定しているもの ~Sonoma以降~

macOS で行っている細かな設定を https://ikm.hatenablog.jp/entry/2020/07/24/181100 にメモしていたけど、 Ventura 以降 System Preferences の表示が大きく変わってしまい、そのまま参考にできなくなってしまった。今回 Sonoma に更新したので、新しく書き直す。

確認ダイアログのボタンを Tab キーで選択できるようにする

System Preferences > Keyboard > Keyboard navigation

スクロールバーを常に表示する

System Preferences > Apperrance > Show scroll bars > Always

自動補正をだいたい無効化する

System Preferences > Keyboard > Text Input > Edit > All Input Sources > 図のような感じ

同一アプリケーション内のウィンドウを Option+Tab で切り替える

System Preferences > Keyboard > Keyboard Shortcuts... > Keyboard > Move focus to next window

Terminal.app のタブを Ctrl+Tab で切り替える

デフォルトでできるようになっているので不要。

Terminal.app からコピーするときに装飾を除外する

$ defaults write com.apple.Terminal CopyAttributesProfile com.apple.Terminal.no-attributes

Terminal.app でコマンド実行した行に角カッコが付かないようにする

$ defaults write com.apple.Terminal AutoMarkPromptLines -bool NO

タイトルバーのファイル名をダブルクリックしたときにファイル名の変更をしない

$ defaults write -g ApplePersistence -bool no

Google Chrome.app でスワイプしたときにナヴィゲーションの操作をしない

$ defaults write com.google.Chrome AppleEnableSwipeNavigateWithScrolls -bool FALSE

円マークでバックスラッシュを入力する

  1. Input method の設定画面を開く
  2. 日本語入力の ¥ の入力でバックスラッシュを入力するよう選択する
  3. あわせて Input modes でローマ字にチェックを入れる
  4. そうすると Input method で ABC の項目がマイナスボタンで削除できるようになるので、削除する

M1 Mac で Ruby 3.2.0 をインストールした際に libyaml でちょっとハマった

Ruby 3.2 から libyaml や libffi などのソースコードがバンドルされなくなった*1らしく、その影響で次のようなエラーが出た。どうやら libyaml が見つからないらしい。

$ rbenv install --verbose 3.2.0
(snip)
yaml.h not found
(snip)
psych:
  Could not be configured. It will not be installed.
  Check ext/psych/mkmf.log for more details.
*** Fix the problems, then remove these directories and try again if you want.
Generating RDoc documentation
/private/var/folders/jr/yc04bj413qscqvvgr4b31j7w0000gn/T/ruby-build.20230106185644.21896.yeUJhx/ruby-3.2.0/lib/yaml.rb:3: warning: It seems your ruby installation is missing psych (for YAML output).
To eliminate this warning, please install libyaml and reinstall your ruby.
uh-oh! RDoc had a problem:
cannot load such file -- psych
(snip)

結論から言えば、次のようにしたら通った。

$ brew install libyaml
$ brew link libyaml
$ export LDFLAGS="-L/opt/homebrew/lib $LDFLAGS"
$ export CFLAGS="-I/opt/homebrew/include $CFLAGS"
$ rbenv install 3.2.0

以下、雑多なメモ。

背景としては二つの要因があって、

  • 僕の環境では ruby-build 向けに RUBY_CONFIGURE_OPTS="--with-yaml-dir=$(brew --prefix libyaml)" みたいに設定してあって、 libyaml のパスが ruby./configure に渡されるようにしてあった。しかし、いつからかこの configure オプション自体が消えたため、 libyaml のパスが渡されなくなっていた
  • Intel Mac 時代の homebrew は brew link すれば /usr/local/lib や /usr/local/include にライブラリをリンクしてくれていたので、^のオプションがなかったとしてもコンパイラのデフォルト設定で見つかっていた。しかし、 M1 Mac からは brew link しても /opt/homebrew/lib や /opt/homebrew/include にリンクされるだけで /usr/local 配下には入らないので、コンパイラが見つけることができなくなった
  • なので、 LDFLAGS や CLAGS を使って libyaml などのライブラリがある場所を指定する必要が出てきた

ということなんだと思う。低レイヤについては詳しくないので間違っているかもしれない。

ついでに、 ruby 3.2.0 の configure オプションの一覧もメモしておく。

$ ./configure --help
`configure' configures this package to adapt to many kinds of systems.

Usage: ./configure [OPTION]... [VAR=VALUE]...

To assign environment variables (e.g., CC, CFLAGS...), specify them as
VAR=VALUE.  See below for descriptions of some of the useful variables.

Defaults for the options are specified in brackets.

Configuration:
  -h, --help              display this help and exit
      --help=short        display options specific to this package
      --help=recursive    display the short help of all the included packages
  -V, --version           display version information and exit
  -q, --quiet, --silent   do not print `checking ...' messages
      --cache-file=FILE   cache test results in FILE [disabled]
  -C, --config-cache      alias for `--cache-file=config.cache'
  -n, --no-create         do not create output files
      --srcdir=DIR        find the sources in DIR [configure dir or `..']

Installation directories:
  --prefix=PREFIX         install architecture-independent files in PREFIX
                          [/usr/local]
  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
                          [PREFIX]

By default, `make install' will install all the files in
`/usr/local/bin', `/usr/local/lib' etc.  You can specify
an installation prefix other than `/usr/local' using `--prefix',
for instance `--prefix=$HOME'.

For better control, use the options below.

Fine tuning of the installation directories:
  --bindir=DIR            user executables [EPREFIX/bin]
  --sbindir=DIR           system admin executables [EPREFIX/sbin]
  --libexecdir=DIR        program executables [EPREFIX/libexec]
  --sysconfdir=DIR        read-only single-machine data [PREFIX/etc]
  --sharedstatedir=DIR    modifiable architecture-independent data [PREFIX/com]
  --localstatedir=DIR     modifiable single-machine data [PREFIX/var]
  --runstatedir=DIR       modifiable per-process data [LOCALSTATEDIR/run]
  --libdir=DIR            object code libraries [EPREFIX/lib]
  --includedir=DIR        C header files [PREFIX/include]
  --oldincludedir=DIR     C header files for non-gcc [/usr/include]
  --datarootdir=DIR       read-only arch.-independent data root [PREFIX/share]
  --datadir=DIR           read-only architecture-independent data [DATAROOTDIR]
  --infodir=DIR           info documentation [DATAROOTDIR/info]
  --localedir=DIR         locale-dependent data [DATAROOTDIR/locale]
  --mandir=DIR            man documentation [DATAROOTDIR/man]
  --docdir=DIR            documentation root [DATAROOTDIR/doc/PACKAGE]
  --htmldir=DIR           html documentation [DOCDIR]
  --dvidir=DIR            dvi documentation [DOCDIR]
  --pdfdir=DIR            pdf documentation [DOCDIR]
  --psdir=DIR             ps documentation [DOCDIR]

Program names:
  --program-prefix=PREFIX            prepend PREFIX to installed program names
  --program-suffix=SUFFIX            append SUFFIX to installed program names
  --program-transform-name=PROGRAM   run sed PROGRAM on installed program names

System types:
  --build=BUILD     configure for building on BUILD [guessed]
  --host=HOST       cross-compile to build programs to run on HOST [BUILD]
  --target=TARGET   configure for building compilers for TARGET [HOST]

Optional Features:
  --disable-option-checking  ignore unrecognized --enable/--with options
  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
  --enable-load-relative  resolve load paths at run time
  --enable-rpath          embed run path into extension libraries. enabled by
                          default on ELF platforms
  --enable-devel          enable development build
  --disable-werror        don't make warnings into errors even if a compiler
                          support -Werror feature [[disabled by default unless
                          development version]]
  --disable-fortify-source
                          disable -D_FORTIFY_SOURCE=2 option, which causes
                          link error on mingw
  --disable-largefile     omit support for large files
  --enable-mathn          enable canonicalization for mathn
  --enable-setreuid       use setreuid()/setregid() according to need even if
                          obsolete
  --enable-multiarch      enable multiarch compatible directories
  --enable-shared         build a shared library for Ruby
  --disable-pie           disable PIE feature
  --enable-dtrace         enable DTrace for tracing inside ruby. enabled by
                          default on systems having dtrace
  --enable-gcov           enable coverage measurement by gcov
  --disable-install-doc   do not install either rdoc indexes or C API
                          documents during install
  --disable-install-rdoc  do not install rdoc indexes during install
  --disable-install-capi  do not install C API documents during install
  --disable-jit-support   disable JIT features
  --enable-yjit           enable in-process JIT compiler that requires Rust
                          build tools. enabled by default on supported
                          platforms if rustc 1.58.0+ is available
  --disable-install-static-library
                          do not install static ruby library
  --disable-dln           disable dynamic link feature
  --enable-debug-env      enable RUBY_DEBUG environment variable
  --enable-mkmf-verbose   enable verbose in mkmf
  --disable-rubygems      disable rubygems by default

Optional Packages:
  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
  --with-baseruby=RUBY    use RUBY as baseruby; RUBY is the pathname of ruby
  --without-git           never use git
  --without-gcc           never use gcc
  --with-os-version-style=TYPE
                          OS version number for target and target_os [[full]]
                          (full|teeny|minor+0|minor|major+0|major|none)
  --with-arch=ARCHS       build an Apple/NeXT Multi Architecture Binary (MAB);
                          ARCHS is a comma-delimited list of architectures for
                          which to build; if this option is disabled or
                          omitted entirely, then the package will be built
                          only for the target platform
  --with-compress-debug-sections=type
                          enable debug section compression
  --with-gmp-dir=DIR      specify the prefix directory where gmp is installed
  --without-gmp           disable GNU GMP to accelerate Bignum operations
  --with-opt-dir=DIR-LIST add optional headers and libraries directories
                          separated by $PATH_SEPARATOR
  --with-winnt-ver=0xXXXX target Windows NT version (default to 0x0600)
  --with-thread=IMPLEMENTATION
                          specify the thread implementation to use
  --with-jemalloc         use jemalloc allocator
  --with-coroutine=IMPLEMENTATION
                          specify the coroutine implementation to use
  --with-dln-a-out        dln_a_out is deprecated
  --without-mjit-tabs     expand tabs in mjit header
  --with-static-linked-ext
                          link external modules statically
  --without-valgrind      disable valgrind memcheck support
  --with-ext=EXTS         pass to --with-ext option of extmk.rb
  --with-out-ext=EXTS     pass to --without-ext option of extmk.rb
  --with-setup=SETUP      use extension libraries setup
  --with-rubylibprefix=DIR
                          prefix for ruby libraries [[LIBDIR/RUBY_BASE_NAME]]
  --with-soname=SONAME    base name of shared library
  --with-setjmp-type      select setjmp type
  --with-rdoc=ri,html     comma/space separated list of RDoc formats to
                          install
  --with-rubyarchprefix=DIR
                          prefix for architecture dependent ruby libraries
                          [[RUBYLIBPREFIX/ARCH]]
  --with-rubysitearchprefix=DIR
                          prefix for architecture dependent site libraries
                          [[RUBYLIBPREFIX/SITEARCH]]
  --with-ridir=DIR        ri documentation [[DATAROOTDIR/ri]]
  --with-ruby-version=STR ruby version string for version specific directories
                          [[full]] (full|minor|STR)
  --with-sitedir=DIR      site libraries in DIR [[RUBY_LIB_PREFIX/site_ruby]],
                          "no" to disable site directory
  --with-sitearchdir=DIR  architecture dependent site libraries in DIR
                          [[SITEDIR/SITEARCH]], "no" to disable site directory
  --with-vendordir=DIR    vendor libraries in DIR
                          [[RUBY_LIB_PREFIX/vendor_ruby]], "no" to disable
                          vendor directory
  --with-vendorarchdir=DIR
                          architecture dependent vendor libraries in DIR
                          [[VENDORDIR/SITEARCH]], "no" to disable vendor
                          directory
  --with-search-path=DIR  specify the additional search path
  --with-rubyhdrdir=DIR   core headers in DIR
                          [[INCLUDEDIR/RUBY_BASE_NAME-RUBY_VERSION]]
  --with-rubyarchhdrdir=DIR
                          architecture dependent core headers in DIR
                          [[$(rubyhdrdir)/$(arch)]]
  --with-sitehdrdir=DIR   core site headers in DIR [[RUBYHDRDIR/site_ruby]]
  --with-sitearchhdrdir=DIR
                          architecture dependent core site headers in DIR
                          [[RUBYHDRDIR/site_ruby]]
  --with-vendorhdrdir=DIR core vendor headers in DIR
                          [[RUBYHDRDIR/vendor_ruby]]
  --with-vendorarchhdrdir=DIR
                          architecture dependent core vendor headers in DIR
                          [[RUBYHDRDIR/vendor_ruby]]
  --with-mantype=TYPE     specify man page type; TYPE is one of man and doc
  --with-ruby-pc=FILENAME pc file basename
  --with-destdir=DESTDIR  specify default directory to install

Some influential environment variables:
  cflags      additional CFLAGS (ignored when CFLAGS is given)
  cppflags    additional CPPFLAGS (ignored when CPPFLAGS is given)
  cxxflags    additional CXXFLAGS (ignored when CXXFLAGS is given)
  AR          Archiver command
  AS          Assembler command
  CC          C compiler command
  CXX         C++ compiler command
  LD          Linker command
  NM          Symbol list command
  OBJCOPY     Objcopy command
  OBJDUMP     Objdump command
  RANLIB      Ranlib command
  STRIP       Strip command
  CFLAGS      C compiler flags
  LDFLAGS     linker flags, e.g. -L<lib dir> if you have libraries in a
              nonstandard directory <lib dir>
  LIBS        libraries to pass to the linker, e.g. -l<library>
  CPPFLAGS    (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if
              you have headers in a nonstandard directory <include dir>
  CXXFLAGS    C++ compiler flags
  CPP         C preprocessor

Use these variables to override the choices made by `configure' or to help
it to find libraries and programs with nonstandard names/locations.

Report bugs to the package provider.

*1:https://www.ruby-lang.org/en/news/2022/12/25/ruby-3-2-0-released/ の "No longer bundle 3rd party sources" を参照

Homecomings “Garden With A Holy Light“ at 渋谷 Spotify O-EAST

行ってきた。この時期のワンマンは3年連続参加かな?……過去ログを見返したら合っていた。

月末まで配信も観られるようだから、また観ようかな。便利な世の中だ。 https://homecomings.jp/news/1159/

来年も参加できるといいな。

このブログに出てくるコードスニペッツは、引用あるいは断りがない限りMITライセンスです。