テキストを手書きノートに変換 は何をしますか?
あなたは、コンテンツを手書き風のページに変換します。レンダラーは scripts/handnotes.py です。必要なのは Python と Pillow、numpy のみであり、これらは ChatGPT や Claude のコードサンドボックスに既にインストールされています。
デフォルトの結果: 青インク、デフォルトの手書き文字で書かれた、方眼紙のノートページをスマホで撮影したような画像。ユーザーから特別な指定がなければ、これを出力します。
ステップ0: 誰の手書き文字を使うか?
一度だけ、簡潔に質問してください: 「ご自身の手書き文字の写真をできるだけ多く送ってください(すでに書いたノート、宿題など)。なければ、デフォルトの手書き文字を使います。」
- 写真がない場合: デフォルトの手書き文字を使用します。再度質問しないでください。
- 写真がある場合: まず手書き文字を学習し(下記「写真からの手書き文字学習」を参照)、その後
--hand their-handオプションを付けてレンダリングします。ページ数が多いほど、文字あたりのサンプル数が増え、より自然な結果になります。3~6ページが適切です。
ステップ1: 入力を読み取る
- PDF: pypdf、pdftotext、または独自のリーダーでテキストを抽出します。スキャンPDFの場合は、ページ画像を確認します。
- 写真、スクリーンショット、ホワイトボード: 視覚機能を使って自分で読み取ります。OCRライブラリは実行しないでください。
- テキスト、解答、Webページ: そのまま使用します。
ステップ2: ページを書く
2つのケースがあります。
- 授業のノート: 優秀な学生が書くようなノートを書きます。短い行、キーワード、原文の構造を保ち、長さは原文の15~30%にします。
- ユーザーから与えられた解答や宿題: すべての手順と数値をそのまま保持します。学生が紙に書くように書きます:
1/、a)、b)のラベル、1行に1つの式、手順の間に=>を入れます。AIっぽい装飾(「ヒント:」、過剰なハイライト、太字など)は追加しないでください。ユーザーがそうする場合にのみ、最終結果に下線や!!を付けます。
ユーザーの言語を維持します。数値、名前、数式は正確にそのままにします。
マークアップ:
# タイトル ## 見出し ### 小見出し(下線)
- 箇条書き(2スペースで1段階インデント) 1. 番号付き
-> 矢印行 !! 重要行(赤) > サイドノート(アクセントインク)
[ ] ToDo [x] 完了(チェック済み) --- 区切り線 空行 = 1行空ける
インライン: ==ハイライト== **太字** __下線__ ~~取り消し線~~ {赤}色付きインク{/} -> (描画矢印)
\$ = ドル記号 $...$ インライン数式 $$...$$ 単独行 = ディスプレイ数式
数式。 すべての数式は $...$ で囲みます。$x^2$ や $E_2$ のような短いものでも同様です。サポート:
\frac{a}{b}, \sum_{k=1}^{n}, \prod, \int_a^b, \lim_{n \to +\infty}, \sqrt{x}, \sqrt[3]{x}, x^{n+1}, x_i, \left( ... \right), \binom{n}{k}, \vec{u}, \bar{x}, \mathbb{R}, \text{...}, \mid, ギリシャ文字, \in \subset \cup \cap \emptyset \forall \exists \leq \geq \neq \approx \pm \times \cdot \infty \to \implies \iff, およびスペース \, \; \quad。
小数は元の表記に従い(0,81 または 0.81)、大きな数値は数式内で 50\,000 のように書きます。区間はそのまま読み取れるように書きます($[0, 1[$)。大きな数式は独自の $$...$$ 行に配置します。ページ幅を超える数式は自動的に縮小されますが、長い数式は = で2行に分割するとより自然に見えます。
ページを notes.md として保存します。
ステップ3: レンダリング
python scripts/handnotes.py render notes.md -o notes.pdf
これでデフォルト出力(ノートブック写真、方眼紙、青インク、デフォルト手書き文字)が得られます。ユーザーが指定した場合のみ変更します:
| オプション | 値 |
|---|---|
--style | notebook(実際のページのスマホ写真風:不均一な光、行の傾き、用紙の傾き、ボールペンインク) · ipad(別のエンジン:均一なApple Pencilのストロークで文字をなぞるクリーンなページ) |
--paper | squared(ノートブック)または grid(iPad)、lines、college、seyes、dots、blank |
--hand | default、または build-hand や learn で作成したフォルダ |
--font | 代わりに手書きフォントを使用: caveat、kalam、patrick、gochi、indie、playpen |
--ink | blue(ノートブック)または black(iPad)、red、green、purple、pencil |
--page | a4、letter、ipad、ipad-landscape |
--seed N | 毎回同じページを生成。Nを変えると別のバージョン |
-o notes.png とすると、PDFの代わりに画像(notes-1.png、notes-2.png、...)が出力されます。
ステップ4: 確認してから提供
1ページ目を確認してください(PDFが表示できない場合はPNGでレンダリング)。行がページからはみ出したり、他の行と重なっていないこと、すべての数値が元のソースと一致していることを確認します。その後、ファイルを提供します。
写真からの手書き文字学習
これは、その人がすでに書いたページであればどんなものでも機能します。特別に書き込んでもらう必要はありません。
-
切り出し:
python scripts/handnotes.py segment p1.jpg p2.jpg p3.jpg -o hand-workこれにより、ノートの印刷された罫線が除去され、インクの断片がすべて切り出され、番号付きのシートhand-work/sheet-pageN-K.pngが作成されます。 -
ラベル付け: すべてのシートを確認します。元の写真が読めるため、そのページに何が書かれているかはわかっています。
hand-work/labels.jsonを記述します(ページ番号は写真の順序に従います):{"1": {"12": "a", "13": "(", "40": "the", "41": "7"}, "2": {"5": "é", "9": "dy"}}- 確信がある断片のみラベル付けします。不明瞭なもの、半分に切れたもの、隣の文字とくっついているもの、取り消し線のあるもの、単なる線の断片はスキップします。
- 複数の結合した文字を含む断片は、その単語やペア("the"、"le"、"qu")としてラベル付けできます。これは、その文字列が出現するたびに再利用され、非常に自然に見えます。
- 各小文字と各数字について、最低2~3のサンプルを目指します。
-
構築:
python scripts/handnotes.py build-hand hand-work hand-work/labels.json -o their-handこれにより、サイズとインクの強さが正規化され、切り出しが不適切なサンプルが除外され、書き手自身のストロークから不足している文字が構築されます(uはnから、mはnを2つ、wはvを2つ、r、q)。アクセント文字(é è à ê ç ë)は、対応するプレーンな文字の上に描画されます。不足している文字があれば、そのフォントが代わりに使用されることが表示されます。 -
レンダリングを1回確認します。 ページを見て、壊れていたり薄すぎる文字をズームインします。
their-hand/hand.jsonにリストされているtheir-hand/glyphsファイル内の該当サンプルを見つけ、不良ラベルを削除して再度構築します。
their-hand フォルダはその人の手書き文字です。次回も再利用できるように、ZIPで圧縮して提供することを提案します。
テンプレートルート(template、その後 learn)もあります。これは、その人が2ページの升目を埋めるものです。よりクリーンですが、手間がかかるので、ユーザーが好む場合のみ提供します。