Groffを使ったノベラ
要約
著者は、2つの「ノベラ」(短編小説)をGNU groffという組版システムを使って執筆しました。この記事では、カスタムマクロ、ページ番号、トラップ、ハイフネーションなどのgroffの技術的な詳細や、Markdownによる前処理、Vimを使った執筆環境についても解説しています。著者はgroffの高速かつ高品質な出力に満足しており、執筆プロセス自体を楽しんだと述べています。
全文翻訳
Groffを使ったノベラ
2026-10-31
最近、私の2作目の「ノベラ」が完成しました。
[画像: pdfinfo-wc.png: 'pdfinfo'と'wc'の出力画面:最初のドキュメントは約50ページ/1万5千語、2番目のドキュメントは約120ページ/4万語。]
考えないでください:これは公開しません。個人的に送ることもありません。公開するのとほぼ同じことです。
最初の物語はA5サイズで約50ページ(約1万5千語)、2番目の物語は約120ページ(約4万語)です。(どちらも「ノベラ」の定義にはギリギリですが、最初のものは少し短く、2番目のものは少し長いです。)
私がこれを実行したというのは、かなり不条理でシュールな感覚です。学校では、「書く」ことに関連することは何でも私にとって純粋な恐怖でした――それが数学、物理学、その他の「技術的な」ことに関連しない限りは。しかし、現実はこうです。
どれくらい時間がかかったか?最初のものは7ヶ月以上かかりました。しかし、2番目の、より長いものは?10日でした。
去年のいつ頃だったか、おそらく7月頃に、私は何十年もアパートに置かれていた本を読み始めました。そして、それは思ったよりもずっと楽しかったのです。なぜかは分かりません。本を読んだことがないわけではありませんが、それは常にいくらか退屈なことで、時間がかかりました――技術的なものでない限りは。ここではフィクションや小説についてのみ言及しています。せいぜい年に1冊です。しかし、昨年はどういうわけか夢中になり、今では2025年7月以来約30冊の小説を読みました。速いもの(数日)もあれば、遅いもの(3ヶ月)もありました。
自分でやってみるのは、それほど大きな飛躍ではありませんでした。
このブログは依然として技術的な性質を持っているので、使用したソフトウェアについて説明します。
目次:
groff
私の両方の「本」(厳密には「本」ではありませんが、簡単のためそう呼び続けます)はgroffで組版されています。Linuxのターミナルでマニュアルページを表示するのに使われる、あのツールです。groff/troffはフル機能の組版システムであり、実際の書籍を作成することもできます。これは以前のブログ記事でも何度か言及しました。
[画像: troff-books-1.webp: 私の『The C Programming Language』、『The UNIX Programming Environment』、『UNIX Network Programming』のコピーの写真。] [画像: troff-books-2.webp: 『The C Programming Language』の1ページ。] [画像: troff-books-3.webp: 『UNIX Network Programming』の1ページ、図が含まれている。]
私の場合、groffの魅力は、比較的軽量で高速でありながら、高品質な出力を生成できることです。50ページのドキュメントを作成するのに、私の13.5年前のPCで約700ミリ秒、120ページのドキュメントでは1.6秒かかります。これには後述するいくつかの前処理も含まれています。最近のほとんどのソフトウェアが泥の中を歩くような感覚であるのに対し、これは爽快なほど速いです。
より楽しくするために、独自の小さなマクロパッケージを作成しました。しかし、それほど大したものではありません。非常に小さいです。シンプルな小説やノベラには、目次、相互参照、図、コードブロック、リストなどはほとんど必要ありません。ただきれいに流れるようなテキストと、時折強調される単語があるだけです。
免責事項:以下のテキストにはTODO項目がいくつかあります。groffは本格的な組版システムであり、これらのことは複雑です。私はそのすべての側面をマスターするには程遠いです。
基本的なフォーマット
マクロは3つだけです:
." セクションヘッダー / 章タイトル
.de SH
. sp 1v
. ps +5p
. ce
\f[HR]\$1\fP
. ps
. sp 4v
..
." ハンギングインデント付きの通常の段落。
.de PP
. br
. ti +2m
..
." 「長い」段落、より長い空きスペース。
.de LP
. sp 2v
..
(SHという名前は、マニュアルページからの引き継ぎです。私はかなりの数のマニュアルページを書いてきたので、この名前がいつの間にか定着しました。「CH」を「chapter heading」や「CT」を「chapter title」とした方が良かったかもしれません。あるいは、.CHAPTERでもいいでしょう。)
マクロの定義は.deから始まり、..までのすべてがそのマクロの一部です。
.SH: 1vee下に移動し、フォントサイズを大きくし、中央揃えを要求し、マクロの最初の引数をHRフォント(Helvetica)で表示し、前のフォントサイズに戻り、さらに4veeのスペースを追加します。.PP: 現在の行を改行し、次の出力行に一時的なインデントを要求します。これにより、ドイツ語の書籍で一般的なハンギングインデントが作成されます。.LP: 段落間の単なる空きスペースです。章内の時間経過などに使用します。
個々のコマンドはman 7 groffで調べることができます。
これだけで、ある程度書籍らしく見えるドキュメントを作成できます。
上記のコードスニペットをmacros.groffというファイルに保存します。章ごとに1つのファイルを作成しました。例:chapter01.groff。その後、次のようなコマンドでPDFを作成できます:
groff -Tpdf -dpaper=a5 -P-pa5 macros.groff chapter01.groff >book.pdf
A5は「一般的な書籍」のページサイズに近いです。
フッターとページ番号
デフォルトではページ番号がないことに気づくでしょう。デジタルPDFだけが欲しいなら、ページ番号なしで済ませることもできます。印刷には便利ですが、正直なところファイル内ではあまり必要ありません。
ただし:ページ区切りで混乱が生じます。上記の設定でPDFを作成すると、次のようになります:
[画像: wrong-page-break.webp: PDFビューアのスクリーンショット:最後のテキスト行がページの外に出ている。]
最後の行のベースラインがページのすぐ外側にあるようです。何が起こっているのかよくわかりませんが、ページサイズをA5に設定することに関連しているようです。つまり、まだ設定が必要な場所を見落としているのでしょう。これは、以下の処理によって暗黙的に修正されます。
ページ番号全体は3つの部分からなります。まず、フッター(ページ番号が表示される領域)の大きさはどれくらいか?これをレジスタで定義しました(これは必須ではありませんが、この方が「コード」を読みやすいと感じます)――名前は任意です:
.nr _FooterSize 5v
次に、ページの底にトラップを仕掛けます:
.wh -
[_FooterSize]u _FooterTrap
\n[_FooterSize]は_FooterSizeという名前のレジスタの値を取得します。その前にマイナス記号があり、負の値で、ページの底からの相対位置です。ドキュメントによると:
一般的なレジスタ(nrリクエストで作成または更新されたもの)は、暗黙的に単位なし、または測定コンテキストで解釈される場合は基本単位で扱われます。
なぜuを追加する必要があるのか、100%確信が持てません。まだマニュアルのすべてを読んだわけではありません。言うまでもなく、これがないと機能しません。
さて、トラップはページの終わりから5vの位置に設定され、_FooterTrapマクロを呼び出します。それは次のようになります:
.de _FooterTrap
." 現在の環境をスタックにプッシュし、`_FooterEnv`に切り替えます。
." 親環境は部分的に収集された行を保持します。
. ev _FooterEnv
." デフォルト環境から設定をコピーします。
. evc 0
." ページ1と2ではこれは行いません。私の実際の「本」ではタイトルページです。
. if \n[%]>2 {
." 垂直位置を設定します。下のテキストで説明します。
. sp |\n[.p]u-2v
." %レジスタを中央揃えで表示します。
. ce
\fR\n[%]\fP
}
." 前の環境に戻ります。
. ev
." ページブレークを要求します。
' bp
..
インラインコメントなしでは、より読みやすくなります:
.de _FooterTrap
. ev _FooterEnv
. evc 0
. if \n[%]>2 {
. sp |\n[.p]u-2v
. ce
\fR\n[%]\fP
}
. ev
' bp
..
なぜ.bpではなく'bpなのか?それは後で説明します。
私が確信が持てない点:垂直位置を|\n[.p]u-2vに設定しました。これはページの上部からの相対位置で、ページ長から2veeを引いたものです。ドキュメントにある「マイナス1vee」を含めて|-2v-1vが機能すると思ったのですが、無限ループ(おそらく同じトラップが繰り返しトリガーされる)になります。なぜでしょうか?
対称性のために、ページの先頭にも空きスペースを設けたいです:
.nr _HeaderSize 5v
.de _HeaderTrap
' sp |\n[_HeaderSize]u
..
.wh 0v _HeaderTrap
そして、もう一つのTODO:これは100%対称ではありません。ヘッダーの長さはフッターより少し長いです。これもページサイズの問題でしょうか?
トラップの詳細
トラップについて詳しく見てみましょう。私はこれについて100%確信が持てません――これは私の理解の範囲内です。
実際、例から一歩戻りましょう。次から始めます:
これはメアリー・シェリーの『フランケンシュタイン』からの短い抜粋です。
これらの幻影は、私が初めて、私の魂を魅了し、それを天国へと高めた詩人たちを読んだときに消え去りました。私も詩人になり、1年間は自分の創造した楽園で暮らしました。ホメロスやシェイクスピアの名前が聖別されている神殿に、私も一席を得られるだろうと想像しました。私の失敗と、その失望をいかに重く受け止めたかは、あなたもよくご存知でしょう。しかし、ちょうどその時、私は従兄弟の遺産を受け継ぎ、私の考えは以前の方向へと転換しました。
私が現在の事業に専念することを決意してから6年が経過しました。今でも、私がこの偉大な事業に身を捧げたと決めたその瞬間を覚えています。まず、私は肉体を苦行に慣らすことから始めました。北海へのいくつかの遠征に漁師たちと同行しました。寒さ、飢え、渇き、睡眠不足を自ら耐え抜きました。日中は普通の船員よりもハードに働き、夜は数学、医学理論、そして海軍の冒険家が最も実用的な利益を得られるであろう物理科学の分野の研究に費やしました。2度、グリーンランドの捕鯨船で副船員として雇われ、見事に職務を遂行しました。船長が私に船の第2位の地位を申し出て、最大限の熱意で留まるよう懇願してくれたとき、私は少し誇らしかったことを認めなければなりません。私のサービスは非常に価値があると考えられていたからです。
これをtest.groffとして保存し、PDFを作成します:
groff -Tpdf test.groff >book.pdf
次のようになります:
10vの位置にトラップを仕掛けます。今のところ空なので何も起こりません――これをファイルの先頭に挿入します:
.de MyTrap
..
.wh 10v MyTrap
."
PDFは同じように見えます。
では、トラップマクロを次のように変更するとどうなるでしょうか?
.de MyTrap
FOO
..
結果はこれです:
出力が「fishers」という単語に達したとき、トラップが発動しました。「FOO」はPDFでは「fishers」の後に挿入されます。「fishers」がトラップをトリガーし、その後「FOO」が挿入されました。とてもシンプルだと思います、そうでしょう?
「FOO」をその行の先頭に配置し、その行にその単語だけを配置したいとします。「fishers」は次の行に配置されます。
環境を切り替えることが鍵だと理解しています:環境は、現在収集されている行(その他多くのこと)を保持します。新しい環境に切り替えると、新しいバッファ/行が得られます――まだ空の状態です。その後、この行をフラッシュ/ブレークしてPDFに含め、前の環境に戻ることができます:
.de MyTrap
. ev MyTrapEnv
FOO
. br
. ev
..
次のようになります:
ここまでは順調です。では、「FOO」の前後に空行を1行ずつ入れたいとします:
.de MyTrap
. ev MyTrapEnv
. sp
FOO
. sp
. ev
..
新しい環境で.spを発行します:これはブレークしてスペースを挿入します。まだ何も収集されていないため、この時点ではブレークは何も出力しません。次にFOOがあります――これは直接出力されず、収集されるだけです。次の.spは再びブレークし(それによって「FOO」を出力し)、さらにスペースを挿入します。
さて。では、トラップ内で「FOO」をその前後の2行で出力するのがすべてだとします。その後、通常のテキストをページの絶対位置、例えば17vから再開させたいとします。
そこで、次のようにしてみましょう。前の環境に戻り、絶対位置指定を発行します:
.de MyTrap
. ev MyTrapEnv
. sp
FOO
. sp
. ev
. sp |17v
..
おっと:
.sp |17vは既に収集された行(「fishers」だけが含まれる行)をブレークし、その後スペースを挿入しました。このブレークは望ましくありません。(「fishers」がトラップ内で終了した位置と全く同じ位置にあることにも注意してください。)
これは、.の代わりに'を使用することで回避できます:
' 中立のアポストロフィは、制御文字が認識される場所で、
制御文字として機能します。 これは、bp、ce、cf、fi、fl、"in"、nf、rj、
sp、 ti、 および trf リクエストによって暗示される(最初の)ブレークを抑制します。
要求された操作は、次のブレークで有効になります。
そこで、これを実行します:
.de MyTrap
. ev MyTrapEnv
. sp
FOO
. sp
. ev
' sp |17v
..
結果:
ドキュメントの例では環境は変更されていません。しかし、環境を変更すると何が起こるかを理解するのがはるかに簡単です。(そして、私が正しく理解したことを願っています。)
最後に1点:環境は設定を保持します。.ev fooは、その名前の環境が既に存在しない限り、前の環境をクローンするのではなく、完全に新しい環境を開始します。だから私のマクロパッケージは.evc 0も実行するのです。
ちょっとした演習として、'sp |12v、'sp |11.5v、'sp |11v、'sp |9vまで、何が起こるか見てみてください。
文間スペーシング
この記事を書いているときに初めて、ドキュメント(基本)で次の文を見つけました:
文を新しい行で始めない場合は、前の文の後にスペースを2つ入れてください。GNU troffは文を終了する句読点を認識し、それに応じて文間スペースを挿入します。
私はこれをしませんでした。なぜなら、ドイツ語では一般的ではないからです。しかし、今、それが見えます。PDFでは、時々次のようになります:
Foo. Bar.
そして時々、わずかな追加スペースがあります:
Foo. Bar.
私の知る限り、これは通常ドイツ語の本では行われません。私はこのリクエストでこれを無効にしました。これは「最小単語間スペーシング」をデフォルト値の12に保ちますが、「追加文間スペーシング」を0に設定します:
.ss 12 0
これは私のマクロパッケージの一部ではありませんが、「インデックス」ファイル(以下のデモパッケージを参照)の最初にあります。
ドイツ語のハイフネーション
どうやら、これは簡単です:
.hla den
.hpf hyphen.den
denは「de(utsch) new」です:これには2006年の「新しい」ドイツ語の規則が含まれています。
Markdownとその他の前処理
実際、私の両方の物語は、説明したマクロを使ってプレーンなgroffで書きました。
Markdownには、「視覚的に魅力的」という大きな利点があります:ほとんど人間が読むことを意図したテキストのように見えます。groffは、それほどではありません。つまり、ひどいものではありませんでした。もしこれが苦痛なら、groffで170ページ以上を書くことはなかったでしょう。大丈夫です。私は他の場所でもgroffを使用しています。しかし、Markdownはほんの少し優れており、創造的なプロセスに集中できると想定しています。
そこで、その後、2番目の物語を「Markdown」に変換しました。最初のものについては、その作業はしませんでした。これは引用符で囲んでいます。なぜなら、要素が非常に少ないため、完全なMarkdownではないからです:
- ファイルの先頭にある
# 章タイトル。 - 段落間の空行、
---は「長い空の段落」用。 *foo*は強調テキスト用。
それだけです。変換は非常に簡単です。
このすべてをプレーンなMarkdownで記述し、HTMLファイルを作成することもできたでしょう。私はすでにそのためのツールを持っています――それが私のブログを動かしています。これでもPDFファイルを生成できるかもしれません。しかし、そこには、例えば、テキストを適切に両端揃えするためのエンジンが欠けているでしょう。HTMLで両端揃えされたテキストを見るのは目に痛いです、それは完全な災害のように見えます。groffやTeXが作成する結果ははるかに優れています。
ついでに、基本的な文字置換もできます:ドイツ語の組版引用符U+201EとU+201Cは私のキーボードに直接ありますが、ギヨメ(Guillemets)は書籍では好まれます。
最初はすべてPythonで行おうと思いましたが、その後小さなPerlスニペットに切り替えました。なぜなら、ファイル全体を読み込んでからマルチライン正規表現を実行するのが簡単だからです。それは次のようなものです:
perl -0pe '
# ギヨメは書籍で好まれます。
s/... ドイツ語の組版引用符、デモパッケージ参照 .../... ギヨメ .../g;
# Markdown "h1" を ".SH" に。
s/^# ([^
]+)\n/.SH "\1"\n/smg;
# Markdown "hr" を ".LP" に。
s/\n---\n/.LP/smg;
# Markdown 段落を ".PP" に。
s/\n\n/\n.PP\n/smg;
# Markdown 強調を groff のフォント選択に:
s/\*([^*]+)\*/\\fI\1\\fP/smg;
'
出力は依然として私の小さなマクロパッケージのためのgroffです。しかし、次のように書けるようになりました:
# Kapitel 42: Die Antwort
Da war sie also. Die Antwort auf *alle* Fragen.
Und dann ging es weiter:
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum
hendrerit blandit suscipit. Maecenas sed nisi nec ante mattis
vulputate. Pellentesque maximus leo id purus vestibulum dictum.
Donec tincidunt mollis viverra. Curabitur at ligula in turpis
pellentesque vehicula.
Duis hendrerit commodo mauris, non posuere leo vulputate ut. Nulla
finibus urna eget vehicula auctor. Mauris in posuere nibh. Vivamus
ut metus vel nisi gravida molestie vitae et tellus. Integer mi odio,
vestibulum eget laoreet vel, auctor nec ligula. Quisque eu placerat
quam, eu tincidunt mauris. Nam vestibulum lectus non leo dignissim,
non sagittis dolor venenatis.
これははるかに読みやすく、Vimではシンタックスハイライトも表示されます。まあ、*強調された*部分だけですが――残りは関係ありません:
[画像: vim-md.png: Vimのスクリーンショット、標準Markdownハイライト表示:強調されたテキストはターミナルの「スタンドアウト」属性を使用。]
Vimといえば…
Vim
Goyo
これには非常に重要なVimプラグインがあります:
https://github.com/junegunn/goyo.vim
これはほぼすべてのUI要素を非表示にします。
さらに、ターミナルウィンドウをフルスクリーンモードにしてデスクトップを隠しました。
これで、「邪魔されない執筆」の完成です。音楽をかけるかもしれませんが、それ以外は何もありません。ブラウザも、時計も、何もありません。Undo機能付きのタイプライターだけです。
[画像: vim-photo.webp: Vimのスクリーンショット、Markdownハイライト表示とGoyoがアクティブ、ターミナルはフルスクリーンモード。]
フォントはUW ttyp0の11x22バリアントです。
テキストの折り返し
プレーンテキストファイルでテキストをフォーマットする一般的な方法があります:
This is one sentence.
This is another one.
And so on and so on.
One sentence per line, that's it.
Sentences can be short.
Or they can be pretty long, sometimes even exceeding the available width on your screen, thus requiring you to either scroll or have your editor soft-wrap it for you when displaying it.
上記のgroffドキュメントから学んだように、これはgroffにとって意味があります(文末を正しく検出する)。また、VCSでの差分表示をノイズレスにします。
もう一つの一般的な方法は、各段落を独自の行に配置することです。例えば、全体の後に「物理的な」改行文字は1つだけで、それを適切に表示するのはエディタの仕事です:
This is one sentence. This is another one. And so on and so on. One sentence per line, that's it. Sentences can be short. Or they can be pretty long, sometimes even exceeding the available width on your screen, thus requiring you to either scroll or have your editor soft-wrap it for you when displaying it.
私は1990年代後半から2000年代初頭にかけて数年間、この2番目の方法を使用しましたが、最終的にハードラップテキストに切り替えました。次のようになります:
This is one sentence. This is another one. And so on and so on. One
sentence per line, that's it. Sentences can be short. Or they can be
pretty long, sometimes even exceeding the available width on your
screen, thus requiring you to either scroll or have your editor
soft-wrap it for you when displaying it.
私はこれが読みやすく、ナビゲートしやすいと感じます。そして、Tエディタを多用し、すべてのファイルがそのように見えていた(もちろん手動フォーマット)「良い」昔のDOS時代を思い出させます。欠点はあります、はい。他の人との共同作業にはあまり適していませんが、私の場合、それは問題ではありません。
もう一つの欠点は、編集中にこれらの段落を再フォーマットする必要があることです。幸い、Vimはそれを簡単にします:
" ~/.vimrc に:
set nojs
map Q gq}
その後、カーソルを段落の先頭に置くだけで:
[T]his is one sentence.
This is another one.
And so on and so on.
One sentence per line, that's it.
Sentences can be short.
そしてQを押すと、次のようになります:
This is one sentence. This is another one. And so on and so on. One
sentence per line, that's it. Sentences can be short.
[_]
カーソルはその段落の後ろに配置されます。ドキュメント全体を再フォーマットするには、Qを押し続けるだけで、最後まで到達します。
- -- 編集:または
:set formatoptions+=aとして、編集中に段落が自動的に再フォーマットされるようにします。通常はそれを望みませんが、散文を書く場合には非常に役立つかもしれません。
nojsオプション(面白い名前ですね?)は私にとって新しく、今見つけました。正式名称はnojoinspacesで、私がすべきこと(しかしドイツ語では一般的ではない)まさにそのことを防ぎます:ピリオドの後にスペースを2つ挿入しません。これがない場合、つまりset jsを使用した場合、結果は次のようになります:
This is one sentence. This is another one. And so on and so on.
One sentence per line, that's it. Sentences can be short.
一部の人々はそれを好みますが、私は好みません。
Git
私がやることのほとんどすべてと同様に、これもGitに入っています。
しかし、それは終わりです。定期的に現在の状態をコミットしますが、それ以外はほとんど気にしません。適切なコミットメッセージもなく、何もありません。単に「バックアップ」を容易にし、ラップトップとデスクトップPC間でデータを同期するためのツールです。
demo-book.tar.gz: 全体をまとめる
言ったように、実際の「本」は公開しません。しかし、ここでは「足場」のデモを示します:
(これは更新しません。現在の状態のスナップショットにすぎません。)
執筆プロセスそのもの
これについてはあまり言いません。私は完全な初心者です。
何度か方向転換しました。両方の物語で、実際のテキストを書き始める前に全体をドラフトしようとしましたが、あまり役に立ちませんでした。最初の物語は anyway それほど素晴らしいものではありません。興味深い前提がありますが、私は本当に「ゾーン」に入っていませんでした。それも、あれほど時間がかかった理由です。2番目の物語は、はるかに平凡な基本的なアイデアを持っており、その後、それが実際にはどれほど興味深いかに気づきました。多くのひねりや展開があり、私はそれが大好きです。
特に、事実を正確に保つことは思ったよりもはるかに困難でした――特にコース変更があった場合。どのキャラクターが、いつ、何を、なぜ知っているのか?動機は?すべては一貫していてもっともらしいか?常にすべてを疑う――彼女は今、本当にそれをしなければならないのか、それとももっと可能性の高い抜け道があるのか?100ページ前に彼女が言ったすべての文は、最後の大きな暴露の後でも意味をなすか?そのようなことです。私はそれに慣れる必要があります。おそらく次回は、キャラクターごとにプロフィールのような、小さな「キャラクターインベントリ」を使用するでしょう。
独自のルールセット、歴史などを持つ世界を構築することは非常に魅力的であることが判明しました。キャラクターを構築するのも同様です。
物語の長さは、校正をばかばかしく困難にします。例えば、120ページを数分で読むつもりはありません。昨日、2番目の物語をもう一度読み直しましたが、それは…メモを確認…3時間かかりました。痛い。
今後どうするか?
昨日、その120ページのものを再び読み直した今…実際、気に入っています。結果に満足しています。明らかに学ぶべきことはたくさんあります:この分野全体が私にとって完全に新しいものです。物語の展開がうまくない場所をいくつか特定しました――ペースが正しくない、物事が速すぎる。(現時点では、全体を一度に読むときにしか気づきません。うっ。)時々、言葉遣いが良くない。詳細が足りない。などです。しかし、物語自体は私が自分で読んで楽しむことができるものです。
groffをさらに深く掘り下げることも、明らかな理由からTODOリストにあります。
このすべてについて私が本当に気に入ったのは、完全にトンネルに入り込んだことです。120ページのものを作成するのにかかった10日のうちの1日、私は実際にはキーボードをタイプしていませんでした:私たちは国内を旅行しており、多くの空き時間があり、ラップトップを持っていませんでしたが、基本的に少なくとも1つの章を「書き」、それを(ほとんど)記憶しました。行ったり来たり、新しいアイデア。完全に没頭していました。
もっとそういうことがしたいです。:-)
もしかしたら、いつか(このウェブサイトに掲載するかもしれません)公開されるかもしれませんが、今は違います。私は自分のためにこれをやっています。私の作品が失礼な批評家によってバラバラにされることには、全く興味がありません。そっとしておいてください。:-)
そして、LLMの使用を提案することを考えているなら:おめでとうございます、あなたは完全にポイントを見逃しています。「座れ、6点。」