Compare commits

...

10 Commits

Author SHA1 Message Date
takahiro e66cd1c51a my-yatex-review-citem-stop-regexpのC[ABCD]のhiligh修正 2026-07-21 16:25:45 +09:00
takahiro c981153301 update 2026-07-12 07:05:08 +09:00
takahiro db8fa04f1f 5.6対応 2026-07-11 18:53:05 +09:00
takahiro 180c084bbc 学生用に\XX{}を追加 2026-07-11 08:21:12 +09:00
takahiro 90128ba06f (0, 0)にwindow配置 2026-07-04 08:26:34 +09:00
takahiro 38dc2a2b3d lab-ai--dwimの注意削除 2026-07-04 08:15:34 +09:00
takahiro ccd161718a lab-ai--dwim重複削除 2026-07-04 08:14:20 +09:00
takahiro af88bcc2df my-replace-zen-to-ascii.el修正 2026-07-04 08:11:33 +09:00
takahiro b91f2f22dd Readme.org更新 2026-07-03 21:39:35 +09:00
takahiro a42e98be2a provide追加 2026-07-03 21:39:27 +09:00
6 changed files with 440 additions and 276 deletions
+341 -210
View File
@@ -1,4 +1,3 @@
\
#+TITLE: my-lisp の読み込み手順 #+TITLE: my-lisp の読み込み手順
#+AUTHOR: Takahiro Ohkubo #+AUTHOR: Takahiro Ohkubo
#+LANGUAGE: ja #+LANGUAGE: ja
@@ -6,15 +5,12 @@
* 概要 * 概要
このディレクトリには、自作 Emacs Lisp を置きます。 配布するLispは、自作Lispとして、以下のディレクトリに配置します。
想定ディレクトリは以下です。
#+begin_src sh #+begin_src sh
~/.emacs.d/site-lisp/my-lisp/ ~/.emacs.d/site-lisp/my-lisp/
#+end_src #+end_src
現在の例では、以下のファイルを読み込みます。 現在は、以下のファイルを配布しています。
#+begin_src sh #+begin_src sh
my-labai.el my-labai.el
@@ -25,9 +21,24 @@ my-replace-zen-to-ascii.el
my-yatex-review-highlight.el my-yatex-review-highlight.el
#+end_src #+end_src
最終的には以下のような構成にします。
#+begin_example
~/.emacs.d/
├── init.el
└── site-lisp/
└── my-lisp/
├── my-labai.el
├── my-org-pukiwiki.el
├── my-org-unfill-aware.el
├── my-qrcode.el
├── my-replace-zen-to-ascii.el
└── my-yatex-review-highlight.el
#+end_example
* init.el で load-path に追加する * init.el で load-path に追加する
まず、=init.el= の先頭付近に以下を追加します。 まず、=init.el= の先頭付近に以下を追加して、自作Lispのload pathを追加します。
#+begin_src emacs-lisp #+begin_src emacs-lisp
;; ------------------------------------------------------------ ;; ------------------------------------------------------------
@@ -37,23 +48,6 @@ my-yatex-review-highlight.el
(add-to-list 'load-path (expand-file-name "~/.emacs.d/site-lisp/my-lisp")) (add-to-list 'load-path (expand-file-name "~/.emacs.d/site-lisp/my-lisp"))
#+end_src #+end_src
既に以下のようにして、=~/.emacs.d/site-lisp/= 以下のサブディレクトリを
自動的に =load-path= へ追加している場合は、この設定だけでも動作します。
#+begin_src emacs-lisp
(cd "~/.emacs.d/site-lisp/")
(if (fboundp 'normal-top-level-add-subdirs-to-load-path)
(normal-top-level-add-subdirs-to-load-path))
(cd "~")
#+end_src
ただし、自作 Lisp の場所を明示した方が分かりやすいので、以下を追加しておく
ことを推奨します。
#+begin_src emacs-lisp
(add-to-list 'load-path (expand-file-name "~/.emacs.d/site-lisp/my-lisp"))
#+end_src
* init.el で require する * init.el で require する
=init.el= に以下を追加します。 =init.el= に以下を追加します。
@@ -71,239 +65,376 @@ my-yatex-review-highlight.el
(require 'my-yatex-review-highlight) (require 'my-yatex-review-highlight)
#+end_src #+end_src
ただし、各 =.el= ファイルの末尾に以下のような =provide= が必要です。 ** my-labai.el
研究室用 Lab-AI GatewayをEmacsから利用するためのクライアントです。
通常のテキスト変換、翻訳、メール校正、Python コード生成、チャット、画像生成、画像編集をEmacs内から実行できます。
*** 主な機能
- 選択範囲または段落を Lab-AI に送信し、結果で置換します。
- 日本語から英語、英語から日本語、日本語校正、英語校正を実行します。
- Python コード生成・修正用のプロンプトを送れます。
- 独立した =*Lab-AI*= チャットバッファを使えます。
- チャット履歴を保持し、次の質問に文脈として付加します。
- 画像ファイル、PDF、macOS クリップボード画像を添付できます。
- LaTeX 数式プレビューを =*Lab-AI*= バッファ内で表示できます。
- 画像生成・画像編集 API を呼び出し、生成画像を Emacs で開きます。
*** 前提条件
- =~/.config/lab-ai/token= に大窪から配布してもらったAPIトークンを保存しておく必要があります。
- HTTP 通信には =curl= を使います。
- クリップボード画像添付には macOS の =pngpaste= が必要です。
- チャット内 LaTeX プレビューには =latex==dvipng= が必要です。
- 画像添付は PNG/JPEG/WebP/GIF、PDF に対応しています。
*** 主要設定
| 変数 | 既定値 | 内容 |
| =lab-ai-url= | =https://amorphous.tf.chiba-u.jp/lab-ai/chat= | チャット API の URL |
| =lab-ai-image-url= | =https://amorphous.tf.chiba-u.jp/lab-ai/image= | 画像生成 API の URL |
| =lab-ai-image-edit-url= | =https://amorphous.tf.chiba-u.jp/lab-ai/image-edit= | 画像編集 API の URL |
| =lab-ai-model= | =gpt-5.5= | 使用モデル |
| =lab-ai-models= | =gpt-5-mini=, =gpt-5=, =gpt-5.5= | 選択可能モデル |
| =lab-ai-timeout= | =600= | curl の最大待ち時間、秒 |
| =lab-ai-max-attachment-size= | 50 MB | 添付ファイルの最大サイズ |
| =lab-ai-chat-history-max-messages= | 200 | チャット履歴として保持する最大メッセージ数 |
| =lab-ai-image-size= | =1024x1024= | 画像生成・編集サイズ |
*** 基本コマンド
| コマンド | 機能 |
| =lab-ai-translate-dwim= | 選択範囲または段落を自動判定して翻訳します。日本語を含む場合は英訳、それ以外は和訳します。 |
| =lab-ai-ja->en-academic= | 日本語を自然な学術英語に翻訳します。 |
| =lab-ai-ja->ja-academic= | 日本語の科学技術文章を校正します。 |
| =lab-ai-en->ja= | 英語を自然な日本語に翻訳します。 |
| =lab-ai-en->en= | 英語を読みやすく校正します。 |
| =lab-ai-python-code= | 説明または未完成コードから Python コードを生成・修正します。 |
| =lab-ai-mail= | メール文を自然で読みやすく校正します。 |
| =lab-ai-bullets->paper-ja= | 箇条書きの結果を論文本文風の日本語に整形します。 |
| =lab-ai-prompt= | 任意の指示を入力して選択範囲または段落に適用します。 |
| =lab-ai-switch-model= | 使用モデルを切り替えます。 |
| =lab-ai-show-model= | 現在のモデルを表示します。 |
*** チャット機能
=M-x lab-ai-chat==*Lab-AI*= バッファを開きます。
=You:= の下に入力し、=C-c C-c= で送信します。
| キー | 機能 |
| =C-c C-c= | プロンプト送信 |
| =C-c C-a= | 画像/PDF ファイルを添付 |
| =C-c C-v= | macOS クリップボード画像を添付 |
| =C-c C-k= | 添付をクリア |
| =C-c C-h= | チャット履歴をクリア |
| =C-c C-l= | LaTeX プレビューの表示/解除 |
*** 画像生成・画像編集
| コマンド | 機能 |
| =lab-ai-image= | 画像プロンプトを入力して画像を生成します。 |
| =lab-ai-image-edit= | 既存画像ファイルを選択し、編集指示を送信します。 |
生成画像は =user-emacs-directory/cache/lab-ai/images/= に保存され、=image-mode= で開かれます。
*** グローバルキー
| キー | コマンド |
| =C-x t= | =lab-ai-translate-dwim= |
| =C-c r a= | =lab-ai-ja->en-academic= |
| =C-c r j= | =lab-ai-ja->ja-academic= |
| =C-c r e= | =lab-ai-en->en= |
| =C-c r t= | =lab-ai-en->ja= |
| =C-c r m= | =lab-ai-mail= |
| =C-c r i= | =lab-ai-prompt= |
| =C-c r p= | =lab-ai-python-code= |
| =C-c r s= | =lab-ai-switch-model= |
| =C-c r c= | =lab-ai-chat= |
| =C-c r b= | =lab-ai-bullets->paper-ja= |
| =C-c r M= | =lab-ai-show-model= |
| =C-c r g= | =lab-ai-image= |
| =C-c r G= | =lab-ai-image-edit= |
*** 注意点
- =lab-ai--dwim= がファイル内で2回定義されています。後半の定義が有効になります。動作上は問題ありませんが、整理するなら前半の定義は削除できます。
- 起動画面には =C-c C-m Switch model= と表示されますが、現在の =lab-ai-chat-mode-map= には =C-c C-m= が割り当てられていません。必要なら以下を追加します。
- yatex modeでC-cが重複します。別キーにするか、M-xで関数呼び出ししてください。
#+begin_src emacs-lisp #+begin_src emacs-lisp
(provide 'my-org-unfill-aware) (define-key lab-ai-chat-mode-map (kbd "C-c C-m") #'lab-ai-switch-model)
#+end_src #+end_src
例えば、=my-replace-zen-to-ascii.el= の末尾には以下が必要です。 - ファイル末尾には =(provide 'my-labai)= が入っているので、=(require 'my-labai)= で読み込めます。
#+begin_src emacs-lisp ** my-org-pukiwiki.el
(provide 'my-replace-zen-to-ascii)
Org-modeの文書をPukiWiki記法に変換する簡易exporterです。
PukiWiki に貼り付けるためのテキスト生成、ファイル出力、クリップボードコピーができます。
*** 主な機能
- Org 見出しを PukiWiki 見出しに変換します。
- Org の箇条書きと番号付きリストを PukiWiki 形式に変換します。
- Org 表を PukiWiki 表として出力します。
- =#+begin_src=, =#+begin_example= ブロックを半角スペース始まりの整形済みテキストに変換します。
- =file:= リンクを =#ref(...)= に変換します。
- URL ラベル付きリンクを PukiWiki の =[[label>URL]]= に変換します。
- Shift-JIS で問題になりやすい一部 Unicode 文字を ASCII 近似に置換します。
*** 主要設定
| 変数 | 既定値 | 内容 |
| =my-org-pukiwiki-coding-system= | =japanese-shift-jis= | ファイル出力時の文字コード |
*** コマンド
| コマンド | 機能 |
| =my-org-pukiwiki-export-buffer= | 現在の Org バッファを PukiWiki に変換し、=*PukiWiki*= バッファに表示します。 |
| =my-org-pukiwiki-export-file= | 現在の Org バッファを =.pukiwiki= ファイルとして Shift-JIS 出力します。 |
| =my-org-pukiwiki-copy-to-clipboard= | 変換結果を kill-ring、つまりクリップボード相当にコピーします。 |
| =my-org-pukiwiki-convert-string= | 文字列を PukiWiki 記法へ変換する内部利用向け関数です。 |
*** 変換例
Org:
#+begin_src org
* 見出し1
** 見出し2
- 項目
1. 番号付き
[[https://example.org][Example]]
[[file:image.png]]
#+end_src #+end_src
* provide がない場合の読み込み方法 PukiWiki:
もし =provide= がない古い Lisp ファイルがある場合は、=require= ではなく
=load= を使います。
#+begin_src emacs-lisp
(load "my-labai")
(load "my-org-pukiwiki")
(load "my-org-unfill-aware")
(load "my-qrcode")
(load "my-replace-zen-to-ascii")
(load "my-yatex-review-highlight")
#+end_src
ただし、今後は各ファイル末尾に =provide= を追加して、=require= で読み込む
形式に統一する方が良いです。
* 安全な読み込み方法
ファイルが存在する場合だけ読み込むには、以下のようにします。
#+begin_src emacs-lisp
;; ------------------------------------------------------------
;; my-lisp
;; ------------------------------------------------------------
(add-to-list 'load-path (expand-file-name "~/.emacs.d/site-lisp/my-lisp"))
(dolist (lib '(my-labai
my-org-pukiwiki
my-org-unfill-aware
my-qrcode
my-replace-zen-to-ascii
my-yatex-review-highlight))
(when (locate-library (symbol-name lib))
(require lib)))
#+end_src
この方法では、ファイルが見つからない場合は無視されます。
ただし、設定ミスに気づきにくくなるため、普段使いでは単純に =require= する方が
おすすめです。
* 推奨する init.el 追記例
以下を =init.el= の local lisp 設定の後ろあたりに追加します。
#+begin_src emacs-lisp
;; ------------------------------------------------------------
;; my-lisp
;; ------------------------------------------------------------
(add-to-list 'load-path (expand-file-name "~/.emacs.d/site-lisp/my-lisp"))
(require 'my-labai)
(require 'my-org-pukiwiki)
(require 'my-org-unfill-aware)
(require 'my-qrcode)
(require 'my-replace-zen-to-ascii)
(require 'my-yatex-review-highlight)
#+end_src
* キー設定例
** Org の改行削除
=my-org-unfill-aware.el= 用のキー設定例です。
#+begin_src emacs-lisp
(bind-key "C-c u a" 'my-org-unfill-aware-ascii)
(bind-key "C-c u j" 'my-org-unfill-aware-japanese)
(bind-key "C-c u u" 'my-org-unfill-aware-auto)
(bind-key "C-c u A" 'my-org-unfill-aware-ascii-copy)
(bind-key "C-c u J" 'my-org-unfill-aware-japanese-copy)
(bind-key "C-c u C" 'my-org-unfill-aware-auto-copy)
#+end_src
** 全角英数字・上付き下付き数字の ASCII 化
=my-replace-zen-to-ascii.el= 用のキー設定例です。
#+begin_src emacs-lisp
(bind-key "C-c h" 'replace-zen-to-ascii-region)
(bind-key "C-c H" 'replace-zen-to-ascii-region-copy)
#+end_src
** Org から PukiWiki 変換
=my-org-pukiwiki.el= に定義されている関数名に合わせて設定します。
例:
#+begin_src emacs-lisp
;; 関数名は my-org-pukiwiki.el の定義に合わせて調整する
;; (bind-key "C-c p" 'my-org-pukiwiki-export-to-buffer)
;; (bind-key "C-c P" 'my-org-pukiwiki-copy-to-clipboard)
#+end_src
** QR code 表示
=my-qrcode.el= に定義されている関数名に合わせて設定します。
例:
#+begin_src emacs-lisp
;; 関数名は my-qrcode.el の定義に合わせて調整する
;; (bind-key "C-c q" 'my-qrcode-region)
#+end_src
* 読み込み確認
Emacs 起動後、以下を評価します。
#+begin_src emacs-lisp
(locate-library "my-org-unfill-aware")
#+end_src
以下のようなパスが返れば、=load-path= の設定は成功です。
#+begin_example #+begin_example
"/Users/takahiro/.emacs.d/site-lisp/my-lisp/my-org-unfill-aware.el" * 見出し1
** 見出し2
-項目
+番号付き
[[Example>https://example.org]]
#ref(image.png)
#+end_example #+end_example
また、関数が定義されているか確認するには、以下を評価します。 *** 注意点
- Org の4階層目以降の見出しは、PukiWiki の見出しではなく太字として出力されます。
- =#+TITLE=, =#+AUTHOR=, =#+OPTIONS= などのメタデータ行は出力されません。
- 表の区切り行は削除されます。
- 完全な Org exporter ではなく、研究室 Wiki 用の実用的な簡易変換です。
** my-org-unfill-aware.el
Org 構造を壊さずに、通常段落のハード改行を除去するためのツールです。
PDF や Web からコピーした文章、AI の出力、改行が多すぎる文章を整える用途に向いています。
*** 主な機能
- 通常段落の改行を削除します。
- 見出し、リスト、表、Org キーワード、コメント、水平線、drawer、src/example/export ブロック、display math は保持します。
- 英文用、日本語用、自動判定の3モードがあります。
- バッファを書き換えず、変換結果だけを kill-ring にコピーするコマンドがあります。
*** 主要設定
| 変数 | 既定値 | 内容 |
| =my-org-unfill-aware-preserve-list-items= | =t= | リスト項目行を構造行として保持するかどうか |
*** コマンド
| コマンド | 機能 |
| =my-org-unfill-aware-ascii= | 通常段落の改行を半角スペースに置換します。英文向けです。 |
| =my-org-unfill-aware-japanese= | 通常段落の改行をスペースなしで削除します。日本語向けです。 |
| =my-org-unfill-aware-auto= | 日本語/CJK を含む場合は日本語モード、それ以外は ASCII モードで処理します。 |
| =my-org-unfill-aware-ascii-copy= | ASCII モードで変換し、結果を kill-ring にコピーします。バッファは変更しません。 |
| =my-org-unfill-aware-japanese-copy= | 日本語モードで変換し、結果を kill-ring にコピーします。バッファは変更しません。 |
| =my-org-unfill-aware-auto-copy= | 自動判定で変換し、結果を kill-ring にコピーします。バッファは変更しません。 |
*** 使用例
#+begin_src emacs-lisp #+begin_src emacs-lisp
(fboundp 'my-org-unfill-aware-auto) (global-set-key (kbd "C-c u") #'my-org-unfill-aware-auto)
(fboundp 'replace-zen-to-ascii-region) (global-set-key (kbd "C-c U") #'my-org-unfill-aware-auto-copy)
#+end_src #+end_src
=t= が返れば読み込み成功です。 *** 注意点
* コマンドラインで起動確認する - regionがある場合は region、ない場合はバッファ全体を処理します。
- リスト項目の継続行は、継続行自身が構造行でない限り通常段落として扱われます。
- 完全な Org parser ではなく、行単位の実用的な判定で処理します。
GUI を起動せずに =init.el= の読み込み確認をするには以下を実行します。 ** my-qrcode.el
選択範囲の文字列を QR コードに変換し、別フレームで表示するツールです。
URL や短いテキストをスマートフォンに渡す用途に便利です。
*** 主な機能
- region の文字列を =qrencode= に渡して PNG の QR コードを生成します。
- QRコードを =*QR Code*= バッファに表示します。
- QRコード専用の別フレームを作成します。
- =+=, =-= キーで拡大・縮小できます。
*** 前提条件
=qrencode= コマンドが必要です。
MacPorts の場合は次のようにインストールします。
#+begin_src sh #+begin_src sh
emacs --batch -l ~/.emacs.d/init.el sudo port install qrencode
#+end_src #+end_src
エラーがなければ読み込みは概ね成功です。 *** 主要設定
* よくあるエラー | 変数 | 既定値 | 内容 |
| =my-qrcode-buffer-name= | =*QR Code*= | QR 表示用バッファ名 |
| =my-qrcode-frame-pixel-size= | 500 | QR 表示フレームの縦横ピクセルサイズ |
| =my-qrcode-frame-left= | 100 | フレーム左位置 |
| =my-qrcode-frame-top= | 100 | フレーム上位置 |
** Cannot open load file *** コマンド
例: | コマンド | 機能 |
| =my-qrcode-from-region= | region の文字列から QR コードを生成し、別フレームに表示します。 |
| =my-qrcode-zoom-in= | QR コードを拡大します。 |
| =my-qrcode-zoom-out= | QR コードを縮小します。 |
| =my-qrcode-zoom-reset= | QR コードの倍率を 1.0 に戻します。 |
| =my-qrcode-redraw= | 現在の倍率で QR コードを再描画します。 |
#+begin_example *** QR 表示バッファ内のキー
Cannot open load file: No such file or directory, my-org-unfill-aware
#+end_example
原因は、=load-path= にディレクトリが入っていないことです。 | キー | 機能 |
| =+= / === | 拡大 |
| =-= | 縮小 |
| =0= | 倍率リセット |
| =q= | ウィンドウを閉じる |
対処: *** 使用例
#+begin_src emacs-lisp #+begin_src emacs-lisp
(add-to-list 'load-path (expand-file-name "~/.emacs.d/site-lisp/my-lisp")) (global-set-key (kbd "C-c q") #'my-qrcode-from-region)
#+end_src #+end_src
** Required feature was not provided *** 注意点
例: - regionがactiveでない場合はエラーになります。
- 生成PNGは一時ファイルとして作成されます。
- ファイル末尾のコメント例では =my-region-to-qrcode= という古い関数名が残っていますが、現在の実コマンドは =my-qrcode-from-region= です。
#+begin_example ** my-replace-zen-to-ascii.el
Required feature my-org-unfill-aware was not provided
#+end_example
原因は、ファイル末尾に =provide= がないことです。 全角英数字、全角記号、Unicode の上付き・下付き数字、引用符、ダッシュ類を ASCII に変換するツールです。
LaTeX 原稿、コード、ファイル名、コマンドラインに混入した全角文字を直す用途に向いています。
対処: *** 主な機能
- 全角スペースを半角スペースに変換します。
- 全角英数字をASCII英数字に変換します。
- 全角記号をASCII記号に変換します。
- =²=, =₃= などの上付き・下付き数字を通常の数字に変換します。
- =“ ” = などの引用符を ASCII の引用符に変換します。
- ==, ==, =—= などのダッシュ・マイナス類を =-= に変換します。
- 必要に応じて =μ=, =Å=, =×=, =°= などの科学記号も ASCII 近似へ変換できます。
*** 主要設定
| 変数 | 既定値 | 内容 |
| =my-replace-zen-to-ascii-convert-scientific-symbols= | =nil= | =t= にすると科学記号も ASCII 近似へ変換します。 |
科学記号変換は原稿中では意味を変える可能性があるため、既定では無効です。
*** コマンド
| コマンド | 機能 |
| =replace-zen-to-ascii-region= | region 内の対象文字を ASCII に変換します。 |
| =replace-zen-to-ascii-buffer= | バッファ全体の対象文字を ASCII に変換します。 |
| =replace-zen-to-ascii-region-copy= | region を変換し、結果を kill-ring にコピーします。バッファは変更しません。 |
| =replace-zen-to-ascii-buffer-copy= | バッファ全体を変換し、結果を kill-ring にコピーします。バッファは変更しません。 |
| =replace-zen-to-ascii-toggle-scientific-symbols= | 科学記号変換の ON/OFF を切り替えます。 |
*** 使用例
#+begin_src emacs-lisp #+begin_src emacs-lisp
(provide 'my-org-unfill-aware) (global-set-key (kbd "C-c z") #'replace-zen-to-ascii-region)
(global-set-key (kbd "C-c Z") #'replace-zen-to-ascii-buffer)
#+end_src #+end_src
をファイル末尾に追加します。 *** 注意点
** Symbol's function definition is void - コマンド名は互換性のため =replace-zen-to-ascii-...= になっています。
- 科学記号変換を ON にすると、例えば =μ==u==Å==A==×==x==°== deg= になります。
- 化学式や論文原稿では、科学記号変換を常時 ON にしない方が安全です。
例: ** my-yatex-review-highlight.el
#+begin_example YaTeX バッファ内で、査読返信や改訂原稿用の独自 LaTeX マクロを色分け表示するツールです。
Symbol's function definition is void: my-org-unfill-aware-auto =\RA=, =\RB=, =\RC=, =\RD=, =\TO=, =\XX=, =\CA=, =\CB=, =\CC=, =\CD= を overlay でハイライトします。
#+end_example
原因は、関数が定義されていない、またはファイルが読み込まれていないことです。 *** 主な機能
対処: - =\RA{label}{body}= から =\RD{label}{body}= までを色分け表示します。
- 第1引数、つまりラベル部分は背景付き太字で表示します。
- 第2引数、つまり本文部分は対応色の文字色で表示します。
- =\TO{body}= は赤太字で表示します(大窪コメント)。
- =\XX{body}= は赤ピンク太字で表示します(学生コメント)。
- =\CA{A1}= から =\CD{...}= までは、次の =\CO=, =\CA=, =\CB=, =\CC=, =\CD=, =\end{enumerate}=, =\end{document}= までを本文として色付けします。
- 編集後に idle timer で自動再ハイライトします。
- 古い font-lock 方式の review macro highlight が残っている場合、enable 時に削除します。
*** 対応マクロ
| マクロ | 用途 | 表示 |
| =\RA{label}{body}= | Reviewer A など | label は赤系背景付き、body は赤系文字 |
| =\RB{label}{body}= | Reviewer B など | label は青系背景付き、body は青系文字 |
| =\RC{label}{body}= | Reviewer C など | label は緑系背景付き、body は緑系文字 |
| =\RD{label}{body}= | Reviewer D など | label は紫系背景付き、body は紫系文字 |
| =\TO{body}= | TODO/対応事項 | 赤太字 |
| =\XX{body}= | TODO/対応事項 | 赤ピンク太字 |
| =\CA{label}= | 回答案 A | label と次項目までの本文を RA 系の色で表示 |
| =\CB{label}= | 回答案 B | label と次項目までの本文を RB 系の色で表示 |
| =\CC{label}= | 回答案 C | label と次項目までの本文を RC 系の色で表示 |
| =\CD{label}= | 回答案 D | label と次項目までの本文を RD 系の色で表示 |
*** 主要設定
| 変数 | 既定値 | 内容 |
| =my-yatex-review-label-background= | =gray30= | ラベル部分の背景色 |
| =my-yatex-review-idle-delay= | 0.8 | 編集後、自動再ハイライトまでの待ち時間、秒 |
*** コマンド
| コマンド | 機能 |
| =my-yatex-review-highlight-enable= | review macro highlight を有効化します。 |
| =my-yatex-review-highlight-disable= | review macro highlight を無効化します。 |
| =my-yatex-review-highlight-toggle= | 有効/無効を切り替えます。 |
| =my-yatex-review-highlight-refresh= | 現在のバッファ全体を再スキャンしてハイライトを更新します。 |
| =my-yatex-review-install-keybindings= | 現在のバッファにローカルキーを設定します。 |
| =my-yatex-review-setup= | キー設定とハイライト有効化をまとめて行います。 |
| =my-yatex-review-set-faces= | face 設定を再適用します。 |
*** YaTeX バッファ内のキー
| キー | コマンド | 機能 |
| =C-c h= | =my-yatex-review-highlight-toggle= | ハイライト ON/OFF |
| =C-c r= | =my-yatex-review-highlight-refresh= | 手動再ハイライト |
*** 自動設定
このファイルは読み込み時に以下の hook を追加します。
#+begin_src emacs-lisp #+begin_src emacs-lisp
(require 'my-org-unfill-aware) (add-hook 'yatex-mode-hook #'my-yatex-review-setup)
(add-hook 'YaTeX-mode-hook #'my-yatex-review-setup)
#+end_src #+end_src
を確認します。 そのため、YaTeXバッファを開くと自動的にreview macro highlightが有効になります。
* 推奨配置 *** 注意点
最終的には以下のような構成にします - overlay による表示変更なので、ファイル内容自体は変更されません
- =\CA= から =\CD= の本文範囲は正規表現で次項目を探して決まります。特殊な環境では意図より長く色付けされる可能性があります。
#+begin_example - =C-c r==my-labai.el= のグローバル prefix と衝突する可能性があります。ただし YaTeX バッファ内では local key の方が優先されます。
~/.emacs.d/
├── init.el
└── site-lisp/
└── my-lisp/
├── my-labai.el
├── my-org-pukiwiki.el
├── my-org-unfill-aware.el
├── my-qrcode.el
├── my-replace-zen-to-ascii.el
└── my-yatex-review-highlight.el
#+end_example
* メモ
=normal-top-level-add-subdirs-to-load-path= を使っている場合、
=~/.emacs.d/site-lisp/my-lisp/= は自動的に =load-path= に入るはずです。
しかし、自作 Lisp の管理を明確にするため、次の1行は入れておく方が安全です。
#+begin_src emacs-lisp
(add-to-list 'load-path (expand-file-name "~/.emacs.d/site-lisp/my-lisp"))
#+end_src
+56 -47
View File
@@ -9,35 +9,64 @@
;; configuration ;; configuration
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defvar lab-ai-url (defgroup lab-ai nil
"https://amorphous.tf.chiba-u.jp/lab-ai/chat") "Lab-AI client."
:group 'applications)
(defvar lab-ai-image-url (defconst lab-ai-url
"https://amorphous.tf.chiba-u.jp/lab-ai/image") "https://amorphous.tf.chiba-u.jp/lab-ai/chat"
"Lab-AI chat endpoint.")
(defvar lab-ai-image-edit-url (defconst lab-ai-image-url
"https://amorphous.tf.chiba-u.jp/lab-ai/image-edit") "https://amorphous.tf.chiba-u.jp/lab-ai/image"
"Lab-AI image generation endpoint.")
(defvar lab-ai-image-size (defconst lab-ai-image-edit-url
"1024x1024") "https://amorphous.tf.chiba-u.jp/lab-ai/image-edit"
"Lab-AI image editing endpoint.")
(defconst lab-ai-supported-models
'("gpt-5.6-luna"
"gpt-5.6-terra"
"gpt-5.6-sol")
"Models supported by the Lab-AI gateway.")
(defvar lab-ai-models (defcustom lab-ai-model
'("gpt-5-mini" "gpt-5.6-terra"
"gpt-5" "Default model used by Lab-AI."
"gpt-5.5")) :type '(choice
(const :tag "GPT-5.6 Luna" "gpt-5.6-luna")
(const :tag "GPT-5.6 Terra" "gpt-5.6-terra")
(const :tag "GPT-5.6 Sol" "gpt-5.6-sol"))
:group 'lab-ai)
(defvar lab-ai-model (defcustom lab-ai-image-size
"gpt-5.5") "1024x1024"
"Default image size used by Lab-AI."
:type '(choice
(const "1024x1024")
(const "1024x1536")
(const "1536x1024"))
:group 'lab-ai)
(defvar lab-ai-timeout (defcustom lab-ai-timeout
"600") "600"
"Timeout in seconds passed to curl."
:type 'string
:group 'lab-ai)
(defvar lab-ai-max-attachment-size (defcustom lab-ai-max-attachment-size
(* 50 1024 1024)) (* 5 1024 1024)
"Maximum attachment size in bytes."
:type 'integer
:group 'lab-ai)
(defcustom lab-ai-chat-history-max-messages
200
"Maximum number of chat history messages."
:type 'integer
:group 'lab-ai)
(defvar lab-ai-chat-history-max-messages
200)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; API ;; API
@@ -197,29 +226,6 @@
(goto-char beg) (goto-char beg)
(insert text)) (insert text))
(defun lab-ai--dwim (system user)
(let* ((bnds (lab-ai--bounds))
(beg (copy-marker (car bnds)))
(end (copy-marker (cdr bnds) t))
(origin-buffer (current-buffer))
(txt (buffer-substring-no-properties beg end))
(prompt
(concat system "\n\n"
user "\n\n"
txt)))
(message "Lab-AI: sending request... model=%s" lab-ai-model)
(lab-ai-request-async
prompt
(lambda (answer)
(when (buffer-live-p origin-buffer)
(with-current-buffer origin-buffer
(save-excursion
(lab-ai--replace-region beg end answer))
(message "Lab-AI: done. model=%s" lab-ai-model))))
(lambda (err)
(message "Lab-AI: error: %s"
(error-message-string err))))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; translation/editing commands ;; translation/editing commands
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -533,6 +539,8 @@ Run again to clear previews."
#'lab-ai-chat-clear-attachments) #'lab-ai-chat-clear-attachments)
(define-key map (kbd "C-c C-h") (define-key map (kbd "C-c C-h")
#'lab-ai-chat-clear-history) #'lab-ai-chat-clear-history)
(define-key map (kbd "C-c C-m")
#'lab-ai-switch-model)
map)) map))
@@ -908,13 +916,16 @@ Run again to clear previews."
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; misc ;; misc
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun lab-ai-show-model ()
(interactive)
(message "Lab-AI model: %s" lab-ai-model))
(defun lab-ai-switch-model () (defun lab-ai-switch-model ()
(interactive) (interactive)
(setq lab-ai-model (setq lab-ai-model
(completing-read (completing-read
"Model: " "Model: "
lab-ai-models lab-ai-supported-models
nil t nil t
lab-ai-model)) lab-ai-model))
(when (get-buffer lab-ai-chat-buffer) (when (get-buffer lab-ai-chat-buffer)
@@ -922,9 +933,6 @@ Run again to clear previews."
(lab-ai-chat-update-mode-line))) (lab-ai-chat-update-mode-line)))
(message "lab-ai model => %s" lab-ai-model)) (message "lab-ai model => %s" lab-ai-model))
(defun lab-ai-show-model ()
(interactive)
(message "Lab-AI model: %s" lab-ai-model))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Keys ;; Keys
@@ -949,4 +957,5 @@ Run again to clear previews."
(define-key lab-ai-map (kbd "g") #'lab-ai-image) (define-key lab-ai-map (kbd "g") #'lab-ai-image)
(define-key lab-ai-map (kbd "G") #'lab-ai-image-edit) (define-key lab-ai-map (kbd "G") #'lab-ai-image-edit)
(provide 'my-labai)
(message "lab-ai loaded: model=%s" lab-ai-model) (message "lab-ai loaded: model=%s" lab-ai-model)
+1 -1
View File
@@ -4,7 +4,7 @@
;; Version: 0.1 ;; Version: 0.1
;; Keywords: org, text, clipboard ;; Keywords: org, text, clipboard
;; ;;
;; This file provides Org-aware functions to remove hard line breaks ;; This file haves Org-aware functions to remove hard line breaks
;; from normal paragraphs while preserving Org structures such as ;; from normal paragraphs while preserving Org structures such as
;; headings, lists, tables, source/example/export blocks, drawers, ;; headings, lists, tables, source/example/export blocks, drawers,
;; comments, horizontal rules, and display math lines. ;; comments, horizontal rules, and display math lines.
+5 -4
View File
@@ -12,11 +12,11 @@
"QR frame size in pixels." "QR frame size in pixels."
:type 'integer) :type 'integer)
(defcustom my-qrcode-frame-left 100 (defcustom my-qrcode-frame-left 0
"QR frame left position." "QR frame left position."
:type 'integer) :type 'integer)
(defcustom my-qrcode-frame-top 100 (defcustom my-qrcode-frame-top 0
"QR frame top position." "QR frame top position."
:type 'integer) :type 'integer)
@@ -177,7 +177,8 @@
(make-frame (make-frame
`((name . "QR Code") `((name . "QR Code")
(left . ,my-qrcode-frame-left) (left . ,my-qrcode-frame-left)
(top . ,my-qrcode-frame-top))))) (top . ,my-qrcode-frame-top)
(user-position . t)))))
;; 正方形サイズ(ピクセル単位) ;; 正方形サイズ(ピクセル単位)
(set-frame-size (set-frame-size
@@ -199,7 +200,7 @@
;; (global-set-key ;; (global-set-key
;; (kbd "C-c q") ;; (kbd "C-c q")
;; #'my-region-to-qrcode) ;; #'my-qrcode-from-region)
(provide 'my-qrcode) (provide 'my-qrcode)
-1
View File
@@ -1,4 +1,3 @@
\
;;; my-replace-zen-to-ascii.el --- Convert fullwidth/superscript/subscript chars to ASCII -*- lexical-binding: t; -*- ;;; my-replace-zen-to-ascii.el --- Convert fullwidth/superscript/subscript chars to ASCII -*- lexical-binding: t; -*-
;; This library converts selected fullwidth ASCII-like characters, ;; This library converts selected fullwidth ASCII-like characters,
+37 -13
View File
@@ -11,6 +11,8 @@
;; ;;
;; \TO: ;; \TO:
;; 第1引数: 赤太字、背景は変更しない ;; 第1引数: 赤太字、背景は変更しない
;; \XX:
;; 学生が修正した部分。第1引数を黄色太字で表示する。
;; ;;
;; \CA-\CD: ;; \CA-\CD:
;; \CA は \RA と同じ色 ;; \CA は \RA と同じ色
@@ -35,6 +37,7 @@
(defface my-latex-RD-body-face '((t ())) "Face for second argument of \\RD.") (defface my-latex-RD-body-face '((t ())) "Face for second argument of \\RD.")
(defface my-latex-TO-body-face '((t ())) "Face for argument of \\TO.") (defface my-latex-TO-body-face '((t ())) "Face for argument of \\TO.")
(defface my-latex-XX-body-face '((t ())) "Face for argument of \\XX.")
(defvar my-yatex-review-label-background "gray30" (defvar my-yatex-review-label-background "gray30"
@@ -97,6 +100,13 @@
'my-latex-TO-body-face nil 'my-latex-TO-body-face nil
:foreground "tomato" :foreground "tomato"
:background 'unspecified :background 'unspecified
:weight 'bold)
;; XX: student revision
(set-face-attribute
'my-latex-XX-body-face nil
:foreground "DeepPink"
:background 'unspecified
:weight 'bold)) :weight 'bold))
@@ -151,7 +161,9 @@
(1 'my-latex-RD-label-face t) (1 'my-latex-RD-label-face t)
(2 'my-latex-RD-body-face t)) (2 'my-latex-RD-body-face t))
("\\\\TO{\\([^{}\n]*\\)}" ("\\\\TO{\\([^{}\n]*\\)}"
(1 'my-latex-TO-body-face t)))) (1 'my-latex-TO-body-face t))
("\\\\XX{\\([^{}\n]*\\)}"
(1 'my-latex-XX-body-face t))))
;; 重いので refresh のたびには呼ばない ;; 重いので refresh のたびには呼ばない
(when font-lock-mode (when font-lock-mode
@@ -283,8 +295,8 @@ Return number of highlighted answer macros."
(let ((count 0)) (let ((count 0))
(goto-char (point-min)) (goto-char (point-min))
;; 行頭またはインデント後の \CA, \CB, \CC, \CD を対象にする ;; 行頭に限定せず、\CA, \CB, \CC, \CD を検索する
(while (re-search-forward "^[ \t]*\\\\\\(C[ABCD]\\)\\_>" nil t) (while (re-search-forward "\\\\\\(C[ABCD]\\)\\_>" nil t)
(let* ((macro (match-string-no-properties 1)) (let* ((macro (match-string-no-properties 1))
(faces (my-yatex-review--faces-for-citem-macro macro)) (faces (my-yatex-review--faces-for-citem-macro macro))
(label-face (nth 0 faces)) (label-face (nth 0 faces))
@@ -303,25 +315,29 @@ Return number of highlighted answer macros."
;; \CA{A1} の A1 部分 ;; \CA{A1} の A1 部分
(my-yatex-review--make-overlay (my-yatex-review--make-overlay
(nth 0 arg1) (nth 1 arg1) label-face 1000) (nth 0 arg1)
(nth 1 arg1)
label-face
1000)
;; A1 に続く本文部分 ;; ラベルに続く回答本文
;; \RA などの局所 overlay より少し低い priority にする
(my-yatex-review--make-overlay (my-yatex-review--make-overlay
body-beg body-end body-face 900) body-beg
body-end
body-face
900)
;; 次の item まで飛ぶ ;; 次の回答項目まで移動
(goto-char body-end)))))) (goto-char body-end))))))
count)) count))
;; ============================================================ ;; ============================================================
;; Main refresh ;; Main refresh
;; ============================================================ ;; ============================================================
(defun my-yatex-review-highlight-refresh () (defun my-yatex-review-highlight-refresh ()
"Refresh highlighting for \\RA, \\RB, \\RC, \\RD, \\TO, and \\CA-\\CD." "Refresh highlighting for \\RA-\\RD, \\TO, \\XX, and \\CA-\\CD."
(interactive) (interactive)
;; refresh 時は font-lock 削除や face 再設定をしない。 ;; refresh 時は font-lock 削除や face 再設定をしない。
@@ -339,7 +355,7 @@ Return number of highlighted answer macros."
;; ------------------------------------------------------------ ;; ------------------------------------------------------------
(goto-char (point-min)) (goto-char (point-min))
(while (re-search-forward "\\\\\\(R[ABCD]\\|TO\\)\\_>" nil t) (while (re-search-forward "\\\\\\(R[ABCD]\\|TO\\|XX\\)\\_>" nil t)
(let ((macro (match-string-no-properties 1))) (let ((macro (match-string-no-properties 1)))
(cond (cond
@@ -361,7 +377,6 @@ Return number of highlighted answer macros."
;; second argument ;; second argument
(my-yatex-review--make-overlay (my-yatex-review--make-overlay
(nth 0 arg2) (nth 1 arg2) body-face 1000))))))) (nth 0 arg2) (nth 1 arg2) body-face 1000)))))))
;; \TO{body} ;; \TO{body}
((string= macro "TO") ((string= macro "TO")
(let ((arg1 (my-yatex-review--read-brace-arg))) (let ((arg1 (my-yatex-review--read-brace-arg)))
@@ -369,8 +384,17 @@ Return number of highlighted answer macros."
(setq count (1+ count)) (setq count (1+ count))
(my-yatex-review--make-overlay (my-yatex-review--make-overlay
(nth 0 arg1) (nth 1 arg1) (nth 0 arg1) (nth 1 arg1)
'my-latex-TO-body-face 1000))))))) 'my-latex-TO-body-face 1000))))
;; \XX{body}: student revision
((string= macro "XX")
(let ((arg1 (my-yatex-review--read-brace-arg)))
(when arg1
(setq count (1+ count))
(my-yatex-review--make-overlay
(nth 0 arg1) (nth 1 arg1)
'my-latex-XX-body-face 1000)))))))
;; ------------------------------------------------------------ ;; ------------------------------------------------------------
;; \CA, \CB, \CC, \CD ;; \CA, \CB, \CC, \CD
;; ------------------------------------------------------------ ;; ------------------------------------------------------------