グロフとのノベラ短編集

2026/11/01 22:51

グロフとのノベラ短編集

RSS: https://news.ycombinator.com/rss

要約▶

Japanese Translation:

2026 年 10 月 31 日のブログ投稿において、開発者が無料のコマンドラインツールを用いて 2 つの自作ノベルを制作するための簡素化されたワークフローを共有しています。最初のノベル(約 50 ページ/A5 判/約 15,000 語)は作成に 7 か月以上かかったのに対し、2 つめのノベル(約 120 ページ/約 4 万字)は 2025 年 7 月からの集中的な読書期間を経て、わずか 10 日で完了しました。執筆は Vim の Goyo プラグインを用い、フルスクリーンモードで実装し、ハードラップされた段落構造を採用するとともに、最小限の distraction(ブラウザや時計を表示しない)を実現しています。バージョン管理には Git を使用しており、デバイス間での同期を定期的なコミットのみで行うことを目的としています。組版は Groff/Troff に依存しており、カスタムパッケージ

macros.groff
がヘッダー(
.SH
)、段落(
.PP
,
.LP
)、フッター、ページ番号(トラップ処理による)を制御します。PDF は A5 ドキュメントとして出力され、厳密にドイツ語のタイポグラフィ規則に準拠しています(句読点後の句間スペースを無効化、ピリオド後の二重スペースルールの抑制、特定の活字分割規則)。前処理では Perl スクリプトを用いて Markdown 様式の構文を Groff マクロに変換します。この最小限なスタックは、商用ソフトウェアを使用せずにもドイツ語組版によるプロフェッショナル品質の書籍制作が可能であることを示しています。プロジェクトには
demo-book.tar.gz
のスケルトンが含まれ、コンテンツの深さを重視する作家向けの再現可能なテンプレートとして提供されています。ただし、著者はペース配分およびキャラクターの一貫性に関する改善余地を認めており、さらに Groff の学習を予定しています。

本文

デスクトップ環境での小説執筆と groff 組版実験記(2026 年)

2026 年 10 月 31 日時点のブログ記事より、技術的な執筆環境の詳細を整理します。

執筆の経緯と成果

  • ノベルの完結
    • 第一作: A5 サイズ約 50 ページ(文字数:約 1.5 万字)。
    • 第二作: A5 サイズ約 120 ページ(文字数:約 4 万字)。
    • 期間の違い
      • 第一作:7 ヶ月以上かかった。
      • 第二作:わずか10 日間。
  • 読書習慣の転換
    • 2025 年 7 月頃、放置されていた本を読み始めてからはめり込んだ。
    • その後は約 30 の小説を読み上げ(数日〜3 ヶ月ほどのペースで)。
    • 技術以外の創作活動は以前は苦手だったが、今回は手作業をすることに没頭できた。

使用ソフトウェアの概要

  • groff (Linux)
    • マニュアルページの組版システムをフル機能化して本を作成。
    • 特徴: コマンドが少ないため高速(50 ページで 700ms、120 ページで 1.6 秒)。
    • 出力品質: 高解像度な PDF 生成が可能。
  • Markdown
    • 創作プロセスでの入力形式として使用。
    • メリット: 人間が読みやすい「視覚的」なテキストとして記述可能。
    • 制限: フル機能の Markdown はせず、章タイトル、空行、強調(
      *foo*
      )のみを使用。
  • Vim
    • 執筆エディタとして使用。
    • Goyo プラグイン: UI を最小化し、没頭した執筆環境を構築。
    • フォント: UW ttyp0 の 11x22 バリアントを使用。
  • Git
    • バックアップとラップトップ・デスクトップ間の同期用。
    • コミットメッセージは省略する簡易管理。

groff による組版詳細

基本的なフォーマット

独自の小さなマクロパッケージを作成し、以下の 3 つのマクロのみを使用している。

マacro名機能実装例
SH
セクションヘッダー(章タイトル)
フォントを大きく・中央揃えにする
groff<br>.de SH<br>  .   sp 1v<br>  .   ps +5p<br>  .   ce<br>  \f[HR]\\$1\fP<br>  .   ps<br>  .   sp 4v<br>..<br>
PP
通常の段落(ハングインデント付き)
groff<br>.de PP<br>  .   br<br>  .   ti +2m<br>..<br>
LP
長い段落(大きな空白を挿入)
時間飛躍などに使用
groff<br>.de LP<br>  .   sp 2v<br>..<br>
  • コマンド検索: 個別コマンドは
    man 7 groff
    で確認。
  • PDF 生成コマンド:
    groff -Tpdf -dpaper=a5 -P-pa5 macros.groff chapter01.groff >book.pdf
    

フッターとページ番号の設定

デフォルトではページ番号が表示されないが、印刷用 PDF では必須とするため以下を設定。

設定手順

  1. フッター領域の定義: レジスター(変数)でサイズを管理。
    .nr _FooterSize 5v
    
  2. ページ下部へのトラップ配置:
    .wh -\n[_FooterSize]u _FooterTrap
    

_FooterTrap
マクロの解説

.de _FooterTrap
.\" 環境を切り替える
.   ev _FooterEnv
.\" デフォルト設定のコピー
.   evc 0
.\" ページ 1,2(タイトルページ)はスキップ
.   if \\n[%]>2 \{\
.       .   sp |\\n[.p]u-2v      ! 垂直位置の計算(詳細後述)
.       .   ce                   ! 中央揃え
.       \fR\\n[%]\fP             ! ページ番号を出力
.   \}
.\" 元環境に戻り、ページブレークを発行
.   ev
'   bp
..
  • 注意点:
    'bp
    (ノーブレイク)を使用しないと無限ループや位置ズレが生じる。
  • TODO: ヘッダーとフッターの対称性を完全に整えていない。

文間の空白の制御

ドイツ語では文後に 2 スペースを置かない習慣があるため、デフォルト挙動を抑制。

.ss 12 0 ! 単語間空白:12, 追加文間空白:0

ドイツ語のハイフネーション

2006 年の新しいドイツ語規則(Deutsches Neue)に対応するため設定。

.hla den    ! German language definition
.hpf hyphen.den ! Hyphenation rules

Markdown と前処理の workflow

マークダウンからの変換プロセス

  1. 入力形式: Markdown(章タイトル、強調など簡易版)。
  2. ツール: Python で HTML 化も可能だが、HTML の整形は可読性が低い。Perl を使用して直接 groff 形式へ変換。
  3. 変換スクリプト (
    perl
    )
    :
    perl -0pe '
    # U+201E/U+201C を Guillemets (<>) に置換
    s/... German typographic quotes .../... Guillemets .../g;
    
    # "# Title" -> ".SH \\"Title\\"\\n"
    s/^# ([^\n]+)\n/.SH "\1"\n/smg;
    
    # "---" -> ".LP"
    s/\n---\n/.LP/smg;
    
    # 空行 -> "\n.PP\n" (段落区切り)
    s/\n\n/\n.PP\n/smg;
    
    # "*text*" -> "\fItext\fP" (強調表示)
    s/\*([^*]+)\*/\\fI\1\\fP/smg;
    '
    
  4. 出力: 自作の
    macros.groff
    を使用した groff 入力ファイル。

Vimでのリフロー化

  • アプローチ: 「ハードラップ(物理的改行)」方式を採用。
    • 一文を一行に配置(スクロールやソフトラップを排除)。
    • groff が句読点を正しく検知し、適切な空白を挿入する仕組みを利用。
  • リフロー手順 (Vim):
    1. ~/.vimrc
      に設定:
      set nojs ! "nojoinspaces"(文後の二重スペース禁止)
      map Q gq} ! クリップボードを介して段落一括整形
      
    2. カーソルを段落の先頭に置いて
      Q
      を押すことで、物理改行から論理的改行へ変換。
  • メリット: テキストが正しく解釈され、diff も最小限に抑えられる。

Git と執筆プロセス

データ管理戦略

  • コミット頻度: 定期的なステート保存のみ。
  • コミットメッセージ: 省略(簡易バックアップ・同期用として位置づけ)。
  • リソース:
    demo-book.tar.gz
    のスナップショット公開あり(本物の出版はなし)。

執筆の難点と学習曲線

  • 世界観の構築: 歴史やルール、キャラクターの設定を整合させることが想像以上に困難。
    • キャラクターの動機や知識が一貫しているか常に検証が必要。
    • 解決策: 次回以降は「キャラクターインベントリ」を作成しプロフィール化する予定。
  • 校正の難易度:
    • 長文(120 ページ)を校正するには時間がかかる。
    • プレースメントや展開の早さが偏っている箇所を発見した。
  • 没頭状態 (Flow):
    • 第二作執筆時に「キーボードに触れずともアイデアが湧く」集中体験を得た。
    • 目標: そのようなトンネル(集中)状態を日常化したい。

次のステップと結論

  • 出版: 現時点ではウェブ公開のみで、批評に晒す意図はない。
  • LLM の使用: プロンプトエンジニアリングを試みる提案は却下。
  • 今後の課題:
    • groff
      の深層(トラップの制御等)への掘り下げ。
    • 文体の多様化と詳細度の向上。

同じ日のほかのニュース

一覧に戻る →

2026/11/02 0:58

Show HN: HackerBooks – ハッカートビューのように、HN で言及された本のためのサービス

## Japanese Translation: このテキストは、マウス使用よりも効率を優先したアプリケーション内でのキーボードナビゲーションの習得に必要な手順を提供しています。核心的なメッセージは、特定のキーが本間の移動や異なるコンテンツビューへの瞬時のアクセスを可能にする直接コマンドとして機能することです。例えば、`/` を入力するとフォーカス検索バーが有効化され、`j` または `k` を押すことで家(Home)行から手を離さずにリスト内で縦方向に移動できます。`Enter` を押すとフォーカスされた本が開かれ、`Esc` はウィンドウを閉じたり前の画面に戻ったりします。また、`g` の組み合わせ(例:`g h`, `g t`, `g m`)は、ホーム、全時間最高位、最も推奨されるなどの特定セクションへの直接ジャンプを可能にします。さらに、`?` はヘルプコマンドを表示します。これらのショートカットにより、マウスへの依存が軽減され、カテゴリへの高速アクセスやデジタルライブラリの滑らかな管理が実現されます。結果として、このシステムはユーザーに対しインターフェースに対する即時の制御力を付与し、基本的なナビゲーションタスクを迅速なアクションに変換することで、全体の生産性と使いやすさを向上させます。なお、このガイドは現在の機能への参照ツールとしての役割に限定されています。

2026/10/30 13:17

Nibnib:解凍速度が極めて高速な画像圧縮

## Japanese Translation: nibnib イメージ形式は、RP2350 マイクロコントローラ上で高速かつ決定論的なデコードを目的とした専用圧縮方式である。入力バイト 1 つあたり 2 ピクセルの並列デコードを行い、約 6 クロックサイクルで 1 ピクセル当りのデコードを完了し、4bpp の圧縮比を実現する。絶対値カラーを保持する標準的なパレット形式とは異なり、nibnib はパレットにカラーデルタを格納し、Floyd-Steinberg エラー拡散法を用いて人間の視覚感度特性をモデル化することで滑らかな領域での画質向上を図る。デコード処理は完全に決定論的であり、直前までにデコードされた最終ピクセルを 2 倍とし、ストリームからバイトを読み込みパレットでアップルックして加算し、入力バイト 1 つあたり 2 ピクセルの 16bpp(RGB 565)を生成する。一方、エンコーディングは非対称であり大幅に低速である。可能となるパレットとコードワードの組み合わせに対して探索を行い、立方体を小さなデルタ値および加重付きガウスランダムエントリで構成した初期化から始め、高品質な複製へデコード可能なエンコーディングを選択する。その貪欲的な左から右への探索手法のため、現時点ではシャープなエッジの右側に残留アーティファクトが生じるが、将来のバージョンでは右から左またはブーストロホン方式によるエンコーディングによりこの影響を低減することが可能である。イメージのレイアウトは、2 バイトで幅と高さを格納するヘッダー、256 エントリの 32 ビットパレット、そして各行が 2 ピクセルに続き ((width − 2)/2) バイトのパレットインデックスを持つ構成となっている。追加的なメタデータフィールドは存在せず、この形式はアーカイブストレージではなくリアルタイムレンダラーとの緊密な統合を意図している。元々 RP2350 での DVI 出力実験として開発された nibnib は、Apache License 2.0 または MIT ライセンスのいずれかを選択して vic-2350 リポジトリで入手可能である。

2026/10/28 18:46

AFL++ を活用したより効果的なファスティングテストのためのヒント

## Japanese Translation: 6 年間の約 1,000 プロジェクトのテストに基づき、著者は AFL++ が Linux 上の C/C++ fuzzing プラットフォームとして決定版であると主張し、ファジー化されていないソフトウェアにはほぼ間違いなくバグが含まれていることを確認しています。速度を損なうことなく脆弱性の検出を最大化するためには、公式文書で強調されている特定のハイパフォーマンス構成を採用すべきです。主要な最適化策には、クラッシュ間でプログラムの状態を維持するパシストンモードの利用(通常は 10 倍ほど高速化)、`afl-gcc-fast` とともに `-fsanitize=address,undefined` および他のフラグでサニタイザーを設定することが含まれます。具体的なチューニングも不可欠であり、デフォルトの 4KiB リミットを超えて `max_malloc_fill_size` を増やすことで use-after-free エラーを検出し、`detect_stack_use_after_return` を有効化し、GCC の libstdc++ で `-D_GLIBCXX_DEBUG` を用いてコンテナオーバーフローを検出します。さらに、単一の翻訳単位(instrumented target と uninstrumented library)でビルドすることで静的関数の設定を簡略化でき、テスト設計ではグローバル状態の干渉を最小限に抑え、ASan による読み取りミスを防ぐために直接バッファ渡しを避け、ファイル入力は `memfd_create` を使用する必要があります。これらのターゲット指向な調整により、デフォルト設定で見逃されがちな重要なメモリ安全性の問題を発見でき、大規模な fuzzing キャンペーンの徹底的さを大幅に向上させます。

グロフとのノベラ短編集 | そっか~ニュース