2024年10月28日月曜日

書庫ファイル内の画像をサムネイルに

書庫ファイル内の画像ファイルをサムネイルにする。

準備

以下の二つのファイルをScriptフォルダに保存。

//!*script
// 書庫ファイルから画像を抽出する
// 7zipが必要
// 第一引数:書庫ファイルのパス
//
// 例:*setentryimage %*script(%0Script\getarchiveimage.js,%FCD) -save
// 引数がなければ終了
if (PPx.Arguments.Length < 1){
PPx.SetPopLineMessage("引数が正しくありません。");
PPx.Quit();
}
// 7z.exeのパス
//var exec = "C:\\Program Files\\7-Zip\\7z.exe";
const exec = PPx.Extract('%\'7z\'');
const tempdir = PPx.Extract("%*temp(name,d)");
const sorce_file = PPx.Arguments(0);
const fso = PPx.CreateObject("Scripting.FileSystemObject");
const allowExtensions = /\.(jpg|jpeg|png|gif)$/i; // 拡張子の指定
// 7zipで一時フォルダに解凍
const command = '%OBnsq ' + exec + '' + ' e -y ' + ' -o\"' + tempdir + '\" \"' + sorce_file + '\"';
PPx.Execute(command);
// ファイルパスを取得
const objFolder = fso.GetFolder(tempdir);
const enmFile = PPx.Enumerator(objFolder.Files);
for (; !enmFile.atEnd(); enmFile.moveNext()){
f_name = enmFile.item().Name.toUpperCase();
if (f_name.match(allowExtensions)){
const cover_path = PPx.Extract('%*name(BCD,"'+f_name+'","'+tempdir+'")');
PPx.Result = cover_path;
break;
}
}
//!*script
//
// 書庫ファイルの表紙画像をサムネイルにする
// カレントフォルダのマークファイルかつ書庫ファイルに対して実行
// このスクリプトと同じフォルダにgetarchiveimage.jsを置く必要
// e.g. *script %0Script\setarchiveimage_marked.js
const script_dir = PPx.Extract('%*name(KD,"' + PPx.ScriptName + '")');
const allowExtensions = /\.(zip|rar)$/i; // 拡張子の指定
// マークがない場合の処理
if (!PPx.EntryMarkCount) {
const filepath = PPx.Extract('%1') + "\\" + PPx.EntryName;
if (PPx.EntryName.match(allowExtensions)&& !(PPx.EntryAttributes & 16)){
const img = PPx.Extract('%*script('+script_dir+'\\getarchiveimage.js,"'+filepath+'")');
PPx.Execute("*setentryimage "+img+" -save");
}
} else {
// マークがある場合の処理
PPx.EntryFirstMark;
while(true){
const filepath = PPx.Extract('%1') + "\\" + PPx.EntryName;
if (PPx.EntryName.match(allowExtensions)&&!(PPx.EntryAttributes & 16)){
const img = PPx.Extract('%*script('+script_dir+'\\getarchiveimage.js,"'+filepath+'")');
PPx.Execute("*setentryimage "+img+" -save");
}
if(PPx.EntryNextMark != 1) break;
}
}

やり方

エントリ表示形式を、画像が含まれるものに変更する。とりあえずは、[;]で表示されるメニューから「サムネイル1」を選んでおけばいい。こうしないと、以下の過程で「no image mode」と言われてしまう。

カーソル下の書庫ファイルのサムネイルを変更したい場合は、以下のコマンドを実行する。

*setentryimage %*script(%0Script\getarchiveimage.js,%FCD) -save

複数の書庫ファイルのサムネイルを同時に変更したい場合は、ファイルをマークした後、以下のコマンドを実行する。

*script %0Script\setarchiveimage_marked.js

2024年10月26日土曜日

PPvでEPWING形式の辞書を引く(PPvを分割)

PPvを分割して別のPPvを開いたり閉じたりする動作が気に入ったので、PPv+EBWIN4もこの形式にしてみる。

必要なもの

EBWIN4には、EPWING形式の辞書をあらかじめ登録しておこう。

準備

以下の二つのファイルをScriptフォルダに保存する。dic.luaのEBWIN4のパスは環境に応じて読み替えてください。

--EBWIN4で検索した結果をファイルに出力
--第一変数:検索語
--第二変数:出力ファイルパス
ebwin="D:\\bin\\EBWIN4\\ebwinc.exe /C=1 /E=u"
nyagos.exec(ebwin .. " " .. arg[1] .. " > " .. arg[2])
view raw dic.lua hosted with ❤ by GitHub
//!*script
// PPvのカーソル位置にある文字を返す
// 単語が空白区切りであることが前提
// 例: *linemessage %*script(%0\Script\selectword.js)
var linetext = PPx.Extract('%*selecttext');
var lh = PPx.Extract('%lH');
// var blankpos = linetext.indexOf( ' ' );
// 文字列を左右に分割し、空白前/後を削除
var lstr = linetext.substr( 0, lh ).replace(/.*\s(.*?)$/, '$1');
var rstr = linetext.substr( lh ).replace(/^(.*?)\s.*/, '$1');
// 文字列を再結合
var str = lstr+rstr;
// 句読点等を取り除く
var result = str.replace(/(\.|\,|\"|\'|\!|\?|\;|\:)/g, '');
// ’以前を取り除く。フランス語の単語抽出用
var result = result.replace(/.*’(.*)$/, '$1');
// 文字数が45を超えていれば以降のコマンド実行を中止
if (result.length > 45){
PPx.SetPopLineMessage("文字数が多すぎます");
PPx.Quit(-1);
}
PPx.Result = result;
PPx.Quit();
view raw selectword.js hosted with ❤ by GitHub

以下を編集して取込。

_Command    = {    ; ユーザコマンド・関数
splitppv    = *string i,height0=%*windowrect(,h)
    *string i,height1=%*calc("%*arg(2)*%*windowrect(,h)/100")
    *string i,height2=%*calc("%*windowrect(,h)-%si"height1"")
    *windowsize %N,%*windowrect(,w),%si"height1"
    *ppv -bootid:X -k %%J"%*arg(1)" %%: *fitwindow %N,%%N,4 %%: *windowsize %%N,%*windowrect(,w),%si"height2" %%: *selectppx %n
ebwin2ppv = *string i,ratio=%*arg(1)
    *string i,tempfile=%*temp(name,f)
    %Oi nyagos -f %0Script\dic.lua %*script(%0Script\selectword.js) %si"tempfile"
    *ifmatch 0,0%NVX %: *splitppv %si"tempfile",%si"ratio" %: *mapkey use,K_splitppv %: *stop
    *execute VX,%%J%si"tempfile"
}

K_splitppv    = {
Q    ,*ifmatch !0,0%NVX %: %Oi *windowsize %N,%*windowrect(,w),%si"height0"
    *mapkey delete,K_splitppv
    *closeppx "%n,VX"
ENTER    ,*ifmatch !0,0%NVX %: %Oi *windowsize %N,%*windowrect(,w),%si"height0" %: *closeppx VX %: *stop
    *splitppv %si"tempfile",%si"ratio"
}

やり方

[I]でキャレットモードにしてから、辞書を引きたい単語を範囲選択して、以下のコマンドを実行する。

*ebwin2ppv 50

引数で分割の割合を変更できる。単位は百分率。半分にしたかったら50、四分の一なら75、とすればいい。 僕はマウス中クリックでこのコマンドを起動するようにしている。

MV_click    = {    ; PPv メイン窓
M_SPC    ,*ebwin2ppv 50
}

参考

つかさのほえほえ日記: PPvでEPWING形式の辞書を引く

2024年10月23日水曜日

コメントを検索してマーク

僕はhowm形式でメモを取り、タイトルをコメントで表示している(参考:moe | メモの方法論)。

「TODO」「借りたい本」「日付」みたいに、特定の文字列がタイトルに含まれるエントリをまとめて処理するため、コメントの文字列を検索してマークするスクリプトを作った。

//!*script
// 第一引数で指定した文字列をコメントに含むファイルをマーク
// e.g. *script %0Script\commentmark.js,"^TODO "
// 引数がなければ終了
if (PPx.Arguments.Length < 1){
PPx.SetPopLineMessage("引数が正しくありません。");
PPx.Quit();
}
const re = new RegExp(PPx.Arguments.Item(0), "i");
for (var i = 0; i < PPx.EntryAllCount; i++) {
if (PPx.Entry(i).Comment.match(re)){
PPx.Entry(i).Mark = 1;
}
}
view raw commentmark.js hosted with ❤ by GitHub

コメント行頭が「TODO 」のエントリをマークしたい場合は以下。

*script %0Script\commentmark.js,"^TODO "

コメントが「2024-10-23」といった形式のエントリをマークしたい場合は以下。

*script %0Script\commentmark.js,"^[0-9]{4}-[0-9]{2}-[0-9]{2}$"

2024年10月21日月曜日

リストファイルの表示形式を事前に変更

リストファイルの用途は様々で、その用途に応じて適切な表示形式もかわる。リストファイルにジャンプしたあと、一々[;]で切り替えるのも面倒なので、事前にコマンドで変更できるようにする。

やり方

以下のコマンドを、リストファイルへのジャンプ前に一度実行する。これは一覧1(&L)に切り替える例。

*string o,hoge=一覧1(&L) %: *diroption -listfile cmd:"*viewstyle -listfile %so"hoge" %%: *diroption -listfile cmd:"""

一覧&2なら次のようになる。

*string o,hoge=一覧&2 %: *diroption -listfile cmd:"*viewstyle -listfile %so"hoge" %%: *diroption -listfile cmd:"""

以下は*whereisと組み合わせた例。

*string o,hoge=一覧1(&L) %: *diroption -listfile cmd:"*viewstyle -listfile %so"hoge" %%: *diroption -listfile cmd:""" %: *whereis

解説

*diroption -listfile cmd:"任意のコマンド" により、リストファイル表示時に任意のコマンドを実行することができる。 ここに、

  • 表示形式を変更
  • 自分自身を削除

の2つのコマンドを登録することで、リストファイル表示時に一度だけ、表示形式を変更することができる。FIRSTEVENTを使った以前からあるテクニックの応用ですね(詳しくはヘルプで「FIRSTEVENT を使用する」を検索)。

2024年10月5日土曜日

テキストファイル内の画像パスをPPVで表示

テキストファイル中に画像ファイルのパスを書いておけば、それを別IDのPPVで閲覧できるようにする。これで、テキストファイルのメモでも画像や図を扱いたい!という我々の永遠の課題を解決できるかもしれない?

準備

以下をScriptフォルダに保存。

//!*script
// 特定の拡張子が書かれた行の文字列を取得
// 例: %I%*script(%0Script\getimagepath.js,1)
// 第一引数(省略可能):獲得する行の上限
const num = (PPx.Arguments.length) ? PPx.Arguments(0) : -1; // 獲得する行の上限
const filepath = PPx.Extract("%FCD");
const separator = ","; // 区切り文字
const allowExtensions = /\.(jpg|jpeg|png|gif)$/i; // 拡張子の指定
const fso = PPx.CreateObject('Scripting.FileSystemObject');
const f = fso.OpenTextFile(filepath, 1);
let str = "";
let i = 0;
while(! f.AtEndOfStream){
const line=f.ReadLine();
if (line.match(allowExtensions)) {
str += line+separator;
i += 1;
}
if (i == num){
break;
}
}
f.close();
PPx.result=str.slice(0, -1); // 末尾の区切り文字を削除
view raw getimagepath.js hosted with ❤ by GitHub

以下を編集して取り込み。

_Command    = {    ; ユーザコマンド・関数
openhalfppv    = *windowsize %N,%*windowrect(,w),%*calc("%*windowrect(,h)/2")
    *ppv -bootid:X -k %%J"%*arg(1)" %%: *fitwindow %N,%%N,4 %%: *windowsize %%N,%*windowrect(,w),%*windowrect(,h) %%: *selectppx %n
previewimagepath = *openhalfppv %*script(%0Script\getimagepath.js,1)
    *mapkey use,K_halfppv
    *linecust imgpreview,KV_main:LOADEVENT,*ifmatch %%n,%n %(%: *RotateCustomize _User:imgpath,%*script(%0Script\getimagepath.js) %: *ifmatch !0,0%*getcust(_User:imgpath) %: *execute VX,%%J"%*getcust(_User:imgpath)"%)
    *linecust quitimgview,KV_main:CLOSEEVENT,*ifmatch %%n,%n %%: *linecust imgpreview,KV_main:LOADEVENT, %%: *linecust quitimgview,KV_main:CLOSEEVENT,
}

K_halfppv    = {
Q    ,*ifmatch !0,0%NVX %: %Oi *windowsize %N,%*windowrect(,w),%*calc("%*windowrect(,h)*2")
	*closeppx "%n,VX"
^N    ,*RotateCustomize _User:imgpath,%*script(%0Script\getimagepath.js) %: *execute VX,%%J%*getcust(_User:imgpath)
ENTER    ,*ifmatch !0,0%NVX %: %Oi *windowsize %N,%*windowrect(,w),%*calc("%*windowrect(,h)*2") %: *closeppx VX %: *stop
	*openhalfppv %*script(%0Script\getimagepath.js,1)
}

やり方

画像ファイルパスを書き込んだテキストファイルを用意し、PPVで表示する。

PPV上で以下のコマンドを実行。

*previewimagepath

PPVの大きさが半分になり、空いたスペースにPPV[X]が起動。画像ファイルを表示する。

PPvの表示ファイルが切り替わると、表示画像も切り替わる。以下はPPv中心の連動ビュー(参考:一対一対応 | PPxMemo)と組み合わせたもの。

その他キーバインド

  • [ENTER] 画像表示非表示トグル
  • [Q] 半分になったPPVの大きさをもとに戻してから終了
  • ^[N] テキストファイル内の次の画像ファイルパスを表示

追記 2024-10-14

表示している画像ファイルパスをハイライトする設定は以下。

_Command    = {    ; ユーザコマンド・関数
openhalfppv    = *windowsize %N,%*windowrect(,w),%*calc("%*windowrect(,h)/2")
    *ppv -bootid:X -k %%J"%*arg(1)" %%: *fitwindow %N,%%N,4 %%: *windowsize %%N,%*windowrect(,w),%*windowrect(,h) %%: *selectppx %n
previewimagepath = *openhalfppv %*script(%0Script\getimagepath.js,1)
    *mapkey use,K_halfppv
    *highlight %*script(%0Script\getimagepath.js,1)
    *linecust imgpreview,KV_main:LOADEVENT,*ifmatch %%n,%n %(%: *RotateCustomize _User:imgpath,%*script(%0Script\getimagepath.js) %: *ifmatch !0,0%*getcust(_User:imgpath) %: *execute VX,%%J"%*getcust(_User:imgpath)" %: *highlight %*getcust(_User:imgpath)%)
    *linecust quitimgview,KV_main:CLOSEEVENT,*ifmatch %%n,%n %%: *linecust imgpreview,KV_main:LOADEVENT, %%: *linecust quitimgview,KV_main:CLOSEEVENT,
}

K_halfppv    = {
Q    ,*ifmatch !0,0%NVX %: %Oi *windowsize %N,%*windowrect(,w),%*calc("%*windowrect(,h)*2")
	*closeppx "%n,VX"
^N    ,*RotateCustomize _User:imgpath,%*script(%0Script\getimagepath.js) %: *execute VX,%%J%*getcust(_User:imgpath) %: *highlight %*getcust(_User:imgpath)
ENTER    ,*ifmatch !0,0%NVX %: %Oi *windowsize %N,%*windowrect(,w),%*calc("%*windowrect(,h)*2") %: *closeppx VX %: *stop
	*openhalfppv %*script(%0Script\getimagepath.js,1)
}