moeをgithub pagesに移行しました。
それにあわせて色々と内容を見直してます。以前よりも導入が容易になっているので、メモの方法論に興味がある方はどうぞ!なにかあれば、ここのコメント欄に書くか、twitter、Mail等で連絡して下さい。
私が運営している他のgithub pagesについてもよろしく!
moeをgithub pagesに移行しました。
それにあわせて色々と内容を見直してます。以前よりも導入が容易になっているので、メモの方法論に興味がある方はどうぞ!なにかあれば、ここのコメント欄に書くか、twitter、Mail等で連絡して下さい。
私が運営している他のgithub pagesについてもよろしく!
最近、moeのHPをgoogleSiteからGitHub Pagesに移行しようと画策しており、その過程でスクリプトを見直している。 今までは、howmファイルのファイル名と一行目を対応させたコメントファイルを作成していたが、これを各エントリのコメントを変更するだけにする。コメントファイルは、XC_cwrtで自動作成すればいい。これなら、スクリプトをLOADEVENTに登録しても、以前のように無限ループに陥る心配をする必要がなくなるわけだ(多分)。
以下を編集して取込み。
XC_cwrt = 2 ; コメントファイル作成は 0:手動 1:確認有 2:自動
以下をScriptフォルダに保存。
title2comment.js
//!*script
// コメントのないhowmファイルの一行目をコメントに
for (var a = PPx.Entry.AllEntry; !a.atEnd(); a.moveNext() ){
// フォルダを除外
if (a.Attributes & 16){
continue;
// .howmかつコメントがないファイルへの処理
} else if (a.Name.match(/.howm$/i) && a.Comment.match(/^$/i)){
var dir = PPx.Extract('%1');
var entryName = a.Name;
var f = dir + "\\" + entryName;
// 一行目を読み込む。文字化けする場合は"sjis"を"utf-8"に
var s = readFile(f, "sjis");
// 2~40字を切り取ったものをコメントに
a.Comment = s.slice( 2,40 );
}
}
// ファイルの一行目を読み込む関数
function readFile(fname, charset) {
if (charset == undefined) {
charset = "_autodetect_all";
}
var adTypeBinary = 1, adTypeText = 2;
var adReadAll = -1, adReadLine = -2;
var s = new ActiveXObject("ADODB.Stream");
s.Type = adTypeText;
s.charset = charset;
s.Open();
s.LoadFromFile(fname);
var text = s.ReadText(adReadLine);
s.Close();
return text;
}
howmファイルを入れているフォルダで以下を実行。
*diroption -thisbranch cmd:"*script %0\Script\title2comment.js"
僕はhowmファイルとPPxでメモ環境を構築している(参照:MoE)。
今まではhowmファイルの作成、編集にはxyzzyを用いていたが、これをPPeでできるようにする。これでPPx単体でMoEをできるようになり、導入のハードルが下がるかも?
*edit %*nowdatetime(Y-N-D-HMS).howm -new -k *editmode -modify:silent %%: *insert "= %%bn%%bn[%*nowdatetime(Y-N-D-HMS)]" %%: *cursor -3,3,0
以下をPPxフォルダに保存。
template.howm
=
=の後ろに空白があり、それに続けて改行を3つ入れている。*insertでは改行文字の入力ができないので(多分)必要になる。
以下のコマンドで、howmファイルを作成できる。
*edit %*nowdatetime(Y-N-D-HMS).howm -new -k *editmode -modify:silent %%: *insertfile %%0template.howm %%: *insert "[%*nowdatetime(Y-N-D-HMS)]" %%: *cursor -3,3,0
最近の更新で*insertで改行を入れられるようになった!感謝!
僕はhowm形式でメモを取っている(参考:MOE)。
メモファイルを他のファイルと紐付けしたい時がある。
・関連するメモ
・画像ファイル
・PDFファイル
・etc
アウトラインプロセッサならこういう機能のやつもありそうだが、ファイラだと実装は無理かなとあまり追求してこなかった。
最近、リストファイルを利用すれば可能なことに気づいた。
Paper Plane xUI Module Junk parts が必要。
KC_main = { ; PPcメイン窓
\ENTER ,*ifmatch CX,%n %: *execute ,%'ppcx_cmd' %: *stop
%K"@\ENTER"
CLOSEEVENT ,*ifmatch CX,%n %: *alias ppcx_cmd = %%K"@\ENTER" %: *stop
^\ENTER ,*ifmatch CX,%n %: *stop
*ifmatch "o:e,a:d-",%0%Y.txt %: *execute C,*jumppath "%0%Y.txt" %: *stop
*alias ppcx_cmd = *makelistfile %0%Y.txt -basic -comment -marked %%: %%K"@Q" %: *ppc -r -bootid:x -single %1 -k *linemessage 登録するファイルを選択してください
BS ,*ifmatch 4,%*DirectoryType %: %K"@^LEFT %: *stop
%K"@BS
}
1.メモファイル上でCtrl+Shift+Enterを押すと、独立窓が開く。紐付けしたいファイルをマークして、Shift+Enter。これでPPxフォルダに、「メモファイルのファイル名.txt」というリストファイルが作成される。
2.次からはCtrl+Shift+Enterでそのリストファイルに潜れる。
・ファイル名が同じリストファイルを作って開いているだけ。howm形式だとかぶることがないので機能する。
・この方法でリストファイルに潜ると、BackSpaceでListFileを保存したフォルダに移動してしまう。なのでPaper Plane xUI Module Junk partsを使い、リストファイルか否かを判別して「履歴を戻る」をしている。
・これだと一つのフォルダ内のファイルしか登録できない。あとで追加したい場合は*ppcfileを使うといい。
//!*script
// howmファイルを作成する
// 第一引数:作成するフォルダ
// 第二引数:タイトル
// *script %0Script\makehowm.js,%1,homuhomu
// editor %*script(%0Script\makehowm.js,%1,%*now(date))
var fso = PPx.CreateObject("Scripting.FileSystemObject");
var dirname = PPx.Arguments.Item(0);
var filename = PPx.Extract("%*nowdatetime(Y-N-D-HMS)")+".howm";
var filepath = fso.BuildPath(dirname,filename);
var str="= ";
// 引数が複数あればそれをつなげる
for (var i = 1; i < PPx.Arguments.length; i++) {
if (i==1){
str += PPx.Arguments.Item(i);
} else {
str += ","+PPx.Arguments.Item(i);
}
}
str += "\r\n\r\n\r\n["+PPx.Extract('%*now')+"]";
var file = fso.OpenTextFile(filepath, 2, true);
file.Write(str);
file.Close();
PPx.result = filename;//!*script
// 与えられたhowmファイルのタイトルを変更するスクリプト
// 第一引数:howmファイルパス
// 第二引数:変更するタイトル
// *script %0Script\changetitle.js,%R,homuhomu
var s="";
var str = "";
var filepath = PPx.Arguments.Item(0);
var fso = PPx.CreateObject("Scripting.FileSystemObject");
var f = fso.OpenTextFile(filepath, 1);
// 引数が複数あればそれをつなげる
for (var i = 1; i < PPx.Arguments.length; i++) {
if (i==1){
str=str + PPx.Arguments.Item(i);
} else {
str=str + ","+PPx.Arguments.Item(i);
}
}
s = "= "+str+"\r\n";
f.ReadLine(); //空読みで一行目を飛ばす
while (!f.AtEndOfStream) {
s += f.ReadLine()+"\r\n"; //sに一行づつ読み込み
}
f.Close();
//PPx.Echo(s);
// 書き込み
var f2 = fso.OpenTextFile(filepath, 2);
f2.Write(s);
f2.Close();//!*script
// 与えられたhowmファイルの一行目の2文字~30字を切り取ったものを返すスクリプト
// 第一引数:howmファイルのパス
// %*script(%0Script\gettitle.js,%R)
var filepath = PPx.Arguments.Item(0);
var objFileSys = PPx.CreateObject("Scripting.FileSystemObject");
var objInFile = objFileSys.OpenTextFile(filepath, 1);
var str = objInFile.ReadLine().slice( 2,30 );
objInFile.Close();
PPx.result = str;KC_main = { ; PPcメイン窓
\K ,*ifmatch "/D:\\Temp\\todo/",%1 %: *script %0Script\settitle.js,D:\\Temp\\todo,%"todo"%E %: *stop
%K"@\K"
\E ,*ifmatch "/D:\\Temp\\todo/",%1 %: *script %0Script\changetitle.js,%R,%"todoの変更"%{%*script(%0Script\gettitle.js,%R)%}%: *stop
%K"@\E"
}
_Command = { ; ユーザコマンド・関数
todo = *script %0Script\settitle.js,D:\Temp\todo,%*arg(1)
}
*todo の引数がなければtodoフォルダを開く設定は以下のようになる。
_Command = { ; ユーザコマンド・関数
todo = *ifmatch !0,0%*arg(1) %: *script %0Script\settitle.js,C:\Users\tukasa\Dropbox\todo,%*arg(1) %: *stop
*execute C,*jumppath "C:\Users\tukasa\Dropbox\todo" %: *focus C
}
//!*script
// カレントディレクトリに一行目とファイルパスを対応させたコメントファイル(00_INDEX.txt)を作成
// アウトラインプロセッサ用。行頭の空白を維持し、エントリの順番通りに書き出す
var strLine = "\r\n";
var fs = PPx.CreateObject("Scripting.FileSystemObject");
for (var i = 0; i < PPx.EntryAllCount; i++) {
// エントリがディレクトリの時の処理
if (PPx.Entry(i).Attributes & 16) {
if (PPx.Entry(i).Name == "."){
strLine += PPx.Entry(i).Name + "\t*\r\n";
} else if (PPx.Entry(i).Name == "..") {
strLine += PPx.Entry(i).Name + "\t**\r\n";
} else if (PPx.Entry(i).Comment=="") {
strLine += PPx.Entry(i).Name + "\t" + PPx.Entry(i).Name + "\r\n";
} else {
strLine += PPx.Entry(i).Name + "\t" + PPx.Entry(i).Comment + "\r\n";
}
// エントリがhowmのときの処理
} else if (PPx.Entry(i).Name.match(/.howm$/i)) {
// ファイルの一行目を取得
var f = fs.OpenTextFile(PPx.Entry(i).Name, 1);
var title = f.ReadLine().slice( 2 );
// コメントの最初に空白があればそれを反映
if (PPx.Entry(i).Comment.match(/^ +/)) {
var heading = PPx.Entry(i).Comment.match(/^ +/);
strLine += PPx.Entry(i).Name + "\t" + heading + title + "\r\n";
} else {
strLine += PPx.Entry(i).Name + "\t" + title + "\r\n";
}
f.Close();
}
}
if (strLine == "\r\n"){
PPx.Quit();
} else {
strLine += '00_INDEX.txt\t *** COMMENT FILE ***';
}
// 00_INDEX.txtに書き込み
var f2 = fs.OpenTextFile("00_INDEX.txt", 2, true, -1); // unicodeで書き込み
f2.Write(strLine);
f2.Close();
//!*script
// 拡張コメントソート用。拡張コメント1を利用。
// 00_INDEX.txtの記載順に連番を付ける。
var fs = PPx.CreateObject("Scripting.FileSystemObject");
if (!fs.FileExists("00_INDEX.txt")) {
PPx.Quit();
}
// ゼロ埋め
function zeroPadding(num,length){
return ('0000000000' + num).slice(-length);
}
var array = {};
var stream = new ActiveXObject("ADODB.Stream");
stream.type = 2;
stream.charset = "Unicode";
stream.open();
stream.loadFromFile("00_INDEX.txt");
var i = 1;
var firstLine = '';
while(!stream.EOS){
firstLine = stream.readText('-2').split("\t")[0];
array[firstLine]=i;
i +=1;
}
stream.close();
for (var i = 0; i < PPx.EntryAllCount; i++) {
if (PPx.Entry(i).Name.match(/.howm$/i)) {
var num = zeroPadding(parseInt(array[PPx.Entry(i).Name]),4);
PPx.Entry(i).SetComment(1,num);
}
}
KC_main = { ; PPcメイン窓
^\LEFT ,*comment "%*regexp("%*comment","s/^\s?(.*)/$1/")"
^\RIGHT ,*comment " %*comment"
^\DOWN = @DEL @INS @DOWN
^\UP = @UP @DEL @INS
F7 ,*script %0Script\MakeOutlineComment.js
COMMENTEVENT1 ,*script %0Script\OutlineSort.js
}
MC_sort = {
拡張ソート&1 = 24,-1,-1,B11111,1
}
XC_cwrt = 0
-|K_ppv =
KV_main = { ; PPcメイン窓
^X ,*setnextkey K_ppv
}
K_ppv = { ** comment **
H ,%Ob D:\bin\xyzzy\xyzzy.exe -e (howm-create2dir) G:\howm
^Z ,%KC"@BS @N"
^X ,*script %0\Script\PPvChangeDir.js
}


KC_main = { ; PPcメイン窓
^R ,*comment "%ee%"コメントの編集"%{%*comment%|%}"
}
XC_cwrt = 2 ; コメントファイル作成は 0:手動 1:確認有 2:自動
//!*script
//カレントディレクトリに一行目とファイルパスを対応させたコメントファイル(00_INDEX.txt)を作成
var strLine = "\n";
var currentDir = PPx.Extract('%1');
var objFileSys = PPx.CreateObject("Scripting.FileSystemObject");
for (var i = 0; i < PPx.EntryAllCount; i++) {
// サイズが0のファイルとディレクトリは読み込まない
if (PPx.Entry(i).Size == 0) {
if (PPx.Entry(i).Comment != ""){
str = PPx.Entry(i).Name + "\t" + PPx.Entry(i).Comment + "\n";
strLine = strLine + str;
}
}
// 拡張子がtxtとhowmのファイルを読み込む
else if (PPx.Entry(i).Name.match(/.howm$/i)) {
var entryName = PPx.Entry(i).Name;
var objItem = currentDir + "\\" + entryName;
// ファイルの内容を取得
objInFile = objFileSys.OpenTextFile(objItem, 1);
// ファイル名+Tab+一行目の最初二文字~100字を切り取ったもの+改行をstrに代入
str = entryName + "\t" + objInFile.ReadLine().slice( 2,100 ) + "\n";
strLine = strLine + str;
objInFile.Close();
}
}
// カレントディレクトリに00_INDEX.txtを作成
strCreateFile = objFileSys.BuildPath(currentDir,"00_INDEX.txt");
objFileSys.CreateTextFile(strCreateFile);
// 00_INDEX.txtに書き込み
objOutFile = objFileSys.OpenTextFile(strCreateFile, 2);
objOutFile.Write(strLine);
objOutFile.Close();
// F5で更新
PPx.Execute("%K\"@[F5]\"")
KC_main = { ; PPcメイン窓
F6 ,*script %0\Script\MakeComment.js
}
%Ob D:\bin\xyzzy\xyzzy.exe -e (howm-create2dir) %1 %: *script %0\Script\MakeComment.js
%Obsq D:\bin\xyzzy\xyzzy.exe -e (howm-create2dir) %1 %: *script %0\Script\MakeComment.js
-|M_makefile =
M_makefile = { ** comment **
&howm = %Ob D:\bin\xyzzy\xyzzy.exe -e (howm-create2dir) %1 %: *script %0\Script\MakeComment.js
&TXT = *set name=%1\%"テキストファイル"%{%|.txt%} %: *makefile "%'name'" %: editor "%'name'" %: *jumppath "%'name'" /entry
&CFG = *set name=%1\%"CFGFile"%{%|.cfg%} %: *makefile "%'name'" %: editor "%'name'" %: *jumppath "%'name'" /entry
&PlainFile = *set name=%1\%"PlainFile"%E %: *makefile "%'name'" %: editor "%'name'" %: *jumppath "%'name'" /entry
&VBS = *set name=%1\%"VBScript"%{%|.vbs%} %: *makefile "%'name'" %: editor "%'name'" %: *jumppath "%'name'" /entry
&JS = *set name=%1\%"JScript"%{%|.js%} %: *makefile "%'name'" %: editor "%'name'" %: *jumppath "%'name'" /entry
}
KC_main = { ; PPcメイン窓
\K ,%M_makefile,H
}
;;; howmファイルを作成
(defun make-howm-create2dir-file (&optional howm-dir)
(interactive)
(let* ((filename (format-time-string "%Y-%m-%d-%H%M%S.howm"))
(filepath
(if howm-dir
(concat (file-name-as-directory howm-dir) (format-time-string "%Y-%m-%d-%H%M%S.howm"))
(format-time-string "%Y-%m-%d-%H%M%S.howm"))))
(find-file filepath)
(if (eq (point-max) (point-min))
(progn
(insert (format-time-string "= \n\n[%Y-%m-%d %H:%M]\n"))
(goto-char (+ (point-min) 2))))
))
;;; 本体
(defun howm-create2dir (arg)
(if (file-directory-p arg)
(progn
(make-howm-create2dir-file arg)
(howm-create2dir-mode))))
;;; メジャーモード
(define-derived-mode howm-create2dir-mode nil "howm2dir"
"homu mode"
(define-key howm-create2dir-mode-map "\C-c,c" 'make-howm-create2dir-file)
(define-key howm-create2dir-mode-map (kbd "C-:") 'hateda-heading)
(define-key howm-create2dir-mode-map (kbd "C-]") 'hateda-heading2)
(font-lock-add-keywords
nil
'(("^\\*\\*\\*.*\n" . my-face-b-1)
("^\\*\\*.*\n" . my-face-b-2))))
;;; フェイス
(defface my-face-b-1 '((t (:foreground "white" :background "SteelBlue"))) nil)
(defface my-face-b-2 '((t (:foreground "white" :background "blue"))) nil)
(defvar my-face-b-1 'my-face-b-1)
(defvar my-face-b-2 'my-face-b-2)
;;; 行頭に見出しをつける
(defun hateda-heading ()
(interactive "*")
(save-excursion
(beginning-of-line)
(insert "**")))
(defun hateda-heading2 ()
(interactive "*")
(save-excursion
(beginning-of-line)
(insert "*")))
(provide 'howm-create2dir)
(provide 'howm-create2dir-mode)
(defun make-howm-create2dir-file (&optional howm-dir)
(interactive)
(let* ((filename (format-time-string "%Y-%m-%d-%H%M%S.howm"))
(filepath
(if howm-dir
(concat (file-name-as-directory howm-dir) (format-time-string "%Y-%m-%d-%H%M%S.howm"))
(format-time-string "%Y-%m-%d-%H%M%S.howm"))))
(find-file filepath)
(if (eq (point-max) (point-min))
(progn
(insert (format-time-string "= \n\n[%Y-%m-%d %H:%M]\n"))
(goto-char (+ (point-min) 2))))
))
(defun howm-create2dir (arg)
(if (file-directory-p arg)
(progn
(make-howm-create2dir-file arg)
(howm-create2dir-mode))))
(define-derived-mode howm-create2dir-mode nil "howm2dir"
"homu mode"
(define-key howm-create2dir-mode-map "\C-c,c" 'make-howm-create2dir-file))
(provide 'howm-create2dir)
(provide 'howm-create2dir-mode)
;; howm-create2dir読み込み
(require 'howm-create2dir)
;; howmファイルをhowm2dirモードで開く
(setq auto-mode-alist
(cons (cons "\\.howm$" 'howm-create2dir-mode) auto-mode-alist))
%Ob E:\emacs\bin\runemacs.exe -execute ("howm-create2dir \"%*regexp("%1","s/\\/\\\\/g")\"")
-|M_makefile =
M_makefile = { ** comment **
&howm = %Ob E:\emacs\bin\runemacs.exe -execute ("howm-create2dir \"%*regexp("%1","s/\\/\\\\/g")\"")
&TXT = *set name=%1\%"テキストファイル"%{%|.txt%} %: *makefile "%'name'" %: editor "%'name'" %: *jumppath "%'name'" /entry
&CFG = *set name=%1\%"CFGFile"%{%|.cfg%} %: *makefile "%'name'" %: editor "%'name'" %: *jumppath "%'name'" /entry
&PlainFile = *set name=%1\%"PlainFile"%E %: *makefile "%'name'" %: editor "%'name'" %: *jumppath "%'name'" /entry
&VBS = *set name=%1\%"VBScript"%{%|.vbs%} %: *makefile "%'name'" %: editor "%'name'" %: *jumppath "%'name'" /entry
&JS = *set name=%1\%"JScript"%{%|.js%} %: *makefile "%'name'" %: editor "%'name'" %: *jumppath "%'name'" /entry
}
KC_main = { ; PPcメイン窓
\K ,%M_makefile,H
}
KV_main = { ; PPvメイン窓
E ,%"Text edit"%Orib,editor %FDC -g %L
\E ,%K"@Q" %: %"Text edit"%Ob,editor %FDC -g %L
N ,%Ob D:\bin\xyzzy\xyzzy.exe -e (howm-create2dir) %1
\N ,%Ob D:\bin\xyzzy\xyzzy.exe -e (howm-create2dir) D:\howm
}
まず、対象がフロー(流れ)であることを明確に意識する必要がある。必要とされるのは、膨大な量のフローを制御するダイナミック(動的)な方法である。一定量のストック(蓄積)を管理するスタティック(静的)な対処法ではない。
これは自明のことである。しかし、従来の収納システムは、「内容がほぼ変わらないストックのための管理」のためのものだ。「大量のものが流入し、ストックの内容が短期間のうちに入れ替わってしまう」という認識は、殆どないのである。(野口悠紀雄『「超」整理法〈3〉』P21)
マゼラン的な仕事を扱うには、マニュアル遵守的な仕事とは異なる発想にもとづいて、処理システムを構築する必要がある。
とくに重要なのは、「バッファー」(buffer)だ。これは、「緩衝器」、つまり二つのもの、あるいは二つのプロセスの中間にあって、衝撃を受け止めるための装置である。
まず、外から入ってきたものや新しく作ったものを、簡単な手続きによって(できれば、殆ど手間をかけずに)、システムの中に受け入れる必要がある。整然とした収納でなくともよい。しかし、書類が紛失したり迷子になったりすることはないようにする。つまり、「とりあえず受け入れる」のである。これが、「受け入れバッファー」だ。
そして、不要と思われるものを必要なものから区分し、所要の措置や加工などを行い、次の段階に送る。
この際、確立された処理法はないのだから、本当に正しい処理をしたかどうかは分からない。やり直す必要があるかもしれない。そのため、完全でなくともよいから、一応の措置をする。一〇〇%処理を目論んで何もしないのではなく、とにかく一歩進める。「ゼロか完璧か」でなく、八割の処理をするのだ。これは、単なる先送りとは違う。「もっとも重要と思われること」は、行っておくのである。
そして、「多分必要ないだろう」と思われるものを、日常の仕事のジャマにならないようなところに置く。つまり「とりあえず捨てておく」のである。これが、「廃棄バッファー」だ。(野口悠紀雄『「超」整理法〈3〉』p41)
従来の整理法では、情報をストックとして扱っている。つまり、将来に向かって価値が減少することを重視していない。したがって、「いかに保存するか」に重点があり、「いかに捨てるか」は、副次的なこととしか考えられていない。
情報が比較的少ない時代には、こうした考えが妥当したかもしれない。しかし、現代のように情報が増えてくると、基本的な考えを転換する必要がある。つまり、情報とは生まれ消えるものであり、一定の寿命を持ったフロー量である、と捉える必要があるのだ。
(野口悠紀雄『「超」整理法』P8)
「とりあえず捨てる」ためのバッファーは、つぎの二つの条件を満たしていなければならない。
(1)目の前からは消えていること。
(2)しかし、必要になれば取り戻すことのできること。(野口悠紀雄『「超」整理法〈3〉』p55)
記憶があてにならないという事実も、「発見の手帳」をつかっているうちに、うかびあがってきた一つの「発見」であった。わたしは、自分自身の発見や着想をも、すぐにわすれてしまうのである。その証拠に、わたしの「発見の手帳」をよみかえしてみると、まったくおなじ内容の「大発見」がしばしばあらわれてくる。まえに一ぺん「発見」したことをわすれてしまって、またおなじことを「発見」してしまうのだ。
しかし、とにかくもそれが記録にとどめてあったことによって、無意味な二重発見をチェックすることもできるのである。もしこれが、なんにもかいてなかったら、わたしは毎日大発見をしたような気になっても、じっさいのわたしの知的活動の内容は、何年もまえとおなじところで足ぶみしているのかもしれないのだ。かいておきさえすれば、まえの発見が、つぎの発見のためのふみ石になって、しだいに巨大な構築物にまでつみあげることも可能なはずである。(梅棹忠夫『知的生産の技術』P27)