ottijp blog

highlightコマンドでRTFを出力すると日本語が文字化けする

2020-05-22 Tags: highlightHomebrwe

環境

  • macOS 10.15.3 (Catalina)
  • highlight 3.57
  • Homebrew 2.2.17

問題

Keynoteに貼るコードのシンタックスハイライトに,Andre Simonさんが公開しているhighlightというツールを使っています.

とてもいい感じのツールなんですが,RTFにする際に日本語が含まれていると文字化けしてしまいます. (RTF中の文字がエスケープされずに,そのままマルチバイトが入ってくる?ようなバグっぽい出力になる.)

$ cat -n code.txt
     1  # Homebrewのインストール
     2  /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"
     3  # パッケージ情報の更新
     4  $ brew update
     5  # パッケージのインストール
     6  $ brew install <formula>
     7  # パッケージのアンインストール
     8  $ brew uninstall <formula>

$ highlight --syntax=bash --out-format=rtf --font-size=30 code.txt
{\rtf1\ansi \deff1{\fonttbl{\f1\fmodern\fprq1\fcharset0 Courier New;}}{\colortbl;\red224\green234\blue238;\red00\green00\blue00;\red191\green03\blue03;\red176\green126\blue00;\red131\green129\blue131;\red131\green129\blue131;\red255\green00\blue255;\red00\green130\blue00;\red129\green129\blue00;\red85\green85\blue85;\red00\green00\blue00;\red00\green87\blue174;\red00\green00\blue00;\red00\green87\blue174;\red00\green00\blue00;\red01\green01\blue129;\red00\green00\blue00;}
\paperw11905\paperh16837\margl1134\margr1134\margt1134\margb1134\sectd\plain\f1\fs60
\pard \cbpat1{{\cf2{}}{\cf5{\i # Homebrew\'c1\'e4\'f3\'f9\'c8\'fcル\i0 }}}\par\pard
\cbpat1{{\cf2{}}{\cf11{/}}{\cf2{bin}}{\cf11{/}}{\cf2{bash}} {\cf14{-c}} {\cf2{}}{\cf3{"$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"}}{\cf2{}}}\par\pard
\cbpat1{{\cf2{}}{\cf5{\i # パッケ\'fcジ情\'e0\'c1更\'d6\i0 }}}\par\pard
\cbpat1{{\cf2{$ brew update}}}\par\pard
\cbpat1{{\cf2{}}{\cf5{\i # パッケ\'fcジ\'c1\'e4\'f3\'f9\'c8\'fcル\i0 }}}\par\pard
\cbpat1{{\cf2{$ brew}} {\cf15{\b install\b0 }} {\cf2{}}{\cf11{<}}{\cf2{formula}}{\cf11{>}}}\par\pard
\cbpat1{{\cf2{}}{\cf5{\i # パッケ\'fcジ\'c1ア\'f3\'e4\'f3\'f9\'c8\'fcル\i0 }}}\par\pard
\cbpat1{{\cf2{$ brew uninstall}} {\cf11{<}}{\cf2{formula}}{\cf11{>}}{\cf2{}}}\par\pard
\cbpat1{}}

この出力を| pbcopyなどどしてクリップボードにコピーし,Keynoteにペーストすると,こんな感じになります.

keynote paste1

日本語が文字化けしたり,なくなったりしてしまいました.

解決策

直接RTFに出力するやり方だとどうやってもうまくいかなったので,一旦HTMLで出力するようにしました. ただし,文字コードがISO-8859-1で出てきてしまうので,書き換えています.

$ highlight --syntax=bash --out-format=html --font-size=30 --font="Migu 1M" code.txt | sed 's/<meta charset="ISO-8859-1">/<meta charset="UTF-8">/' > code.html & open code.html

これで表示されるブラウザ上でコードをコピーし,Keynoteにペーストすると,こんな感じでうまくいきました. (テキストボックスの背景色は,スタイルの背景色に合わせて設定する必要があります.)

keynote paste2

HTML出力にして気づいたのですが,どちらせによRTFだとフォント指定ができず不便なので,HTMLを経由したほうが良いかもしれませんね.

ただ,CLIだけで完結する方法があれば良いんですけどね・・・. pandocやtextutuilを使う方法も見かけて試したのですが,スタイルの情報がなくなってしまうのでダメでした.

自分の変換用コマンド

私の場合,

  • フォント: Migu 1M
  • フォントサイズ: 56pt
  • テーマ: Solarized Light

をデフォルトとしているので,コードをコピーしたあと,次のようなコードで変換しています.

$ tempfile=$(mktemp) pbpaste | highlight --syntax=bash --out-format=html --font-size=56 --font="Migu 1M" --style=solarized-light --include-style | sed 's/<meta charset="ISO-8859-1">/<meta charset="UTF-8">/' > $tempfile.html && open $tempfile.html

ちなみにデフォルトで使えるスタイルの一覧は(Homebrewで入れた場合),次のように確認できます.

$ ls $(brew --cellar)/highlight/<version>/share/highlight/themes
acid.theme
aiseered.theme
andes.theme
anotherdark.theme

(...略...)

ottijp
Satoshi SAKAO (@ottijp)

都内でアプリケーションエンジニアをしています

...