nikkie-ftnextの日記

イベントレポートや読書メモを発信

Sphinxのビルドログの一部が太字で出力される仕組み。ここにもANSIエスケープシーケンス!

Today I learned。Sphinx拡張開発の中で知ったことです。

目次

Sphinx拡張からロギング

自作拡張の中でロギングしてみようとなり1sphinx.util.loggingを触りました。

getLogger()してロガーインスタンスを得て、重要度ごとのメソッドにメッセージを渡します(標準モジュールloggingと似ていますね2

logger = logging.getLogger(__name__)
logger.info("✅ Reveal.js CopyCode plugin is already installed")

この出力を見たときに気づいたのです。
いつも見ているSphinxのビルドログには、太字が混ざって出力されていることに。

太字のログ出力の実装

ビルダー

ビルドログの文字列でコードベースを検索して当たりをつけました3
https://github.com/sphinx-doc/sphinx/blob/v8.0.2/sphinx/builders/__init__.py#L381

logger.info(bold(__('updating environment: ')), nonl=True)

ログメッセージをsphinx.util.console.bold()に通すことで、太字にしていることが分かりました。

bold()の実装

console.pyを見ます。
https://github.com/sphinx-doc/sphinx/blob/v8.0.2/sphinx/util/console.py

ANSIエスケープシーケンスを使っていると理解しました。
過去のブログで取り上げており、再会を果たしました!

詳細は過去記事に譲りますが、例えば「Running Sphinx v8.0.2」の「Running Sphinx」を太字にしたい場合、

% printf '\x1b[01mRunning Sphinx\x1b[39;49;00m v8.0.2\n'
Running Sphinx v8.0.2

「Running Sphinx」が太字になっています!
これがbold("Running Sphinx") + " v8.0.2"に相当します。

console.pyはANSIエスケープシーケンスのサポートを拡張しやすいように、動的に関数定義する書き方と読みました。

終わりに

Sphinxのビルドログで太字部分をどのように実現しているか、仕組みを知りました。

  • 太字にしたい箇所はまずsphinx.util.console.bold()に渡し、返った文字列をロガーに渡します
  • bold()の実装では、ANSIエスケープシーケンスが使われていました

P.S. sphinx-revealjsのロギング

NOTICE: For next major version, path of Revealjs will change to other.

https://github.com/attakei/sphinx-revealjs/blob/v2.9.3/sphinx_revealjs/__init__.py#L59-L63

def notify_deprecated(app: Sphinx, config: Config):
    """Do not work. But it keep for next deprecated."""
    logger.info(
        "NOTICE: For next major version, path of Revealjs will change to other."
    )

拡張の実装ではconfig-initedイベントでログ出力するようにしています。
https://github.com/attakei/sphinx-revealjs/blob/v2.9.3/sphinx_revealjs/__init__.py#L77

app.connect("config-inited", notify_deprecated)