howmファイルの切り分け:日付とファイル名
1日1ファイルのhowmのファイル名は現在、2009-04-15.howmとかいう、「YYYY-mm-dd.howm」という形式。
各メモのヘッダ行直下には「[2009-04-15 01:25] 」という、「YYYY-mm-dd HH:MM」でタイムスタンプが入っている。(タイムヘッダとする。)
ここから「2009-04-15-012500.homw」というような、「YYYY-mm-dd-HHMMSS.howm」という1メモ1ファイル名を作る。
なお、直下にタイムヘッダが無い、フォーマットが違う、直前のものと同じか遡っている場合、それらを無視して、直前で使った日付に1秒足したものをファイル名とする。
そんなわけで、そのデータは大域変数に保存すればいいけど、クロージャを使ってみる。
こんな感じで、例によってまずは闇雲に書く。
モジュールsrfi-19に時間や日付関係のものが集まっている。
timeとdateのクラスを行き来してれば、細かい操作もできていい感じ。
(use srfi-19) (define (make-time-header filename) (let ((time-cur (date->time-monotonic (make-date 0 0 0 0 (string->number (substring filename 8 10)) (string->number (substring filename 5 7)) (string->number (substring filename 0 4)) (* 9 60 60)))))
しかし、よく見ると、string->dateで文字列からdateオブジェクトが生成できるっぽい。
読み込みのフォーマット、テンプレート文字列はdate->stringのものをそのまま。
(use srfi-19) (define (make-time-header filename) (let ((time-cur (date->time-monotonic (string->date (substring filename 0 10) "~Y-~m-~d") ))) (lambda (time-h) (let ((time-tmp 0) (duration 0)) (cond ((= 16 (string-length time-h)) (set! time-tmp (date->time-monotonic (string->date time-h "~Y-~m-~d ~H:~M"))) (cond ((time>? time-tmp time-cur) (set! time-cur time-tmp) (set! duration 0)) (else (set! duration 1)))) (else (set! duration 1))) (set-time-second! time-cur (+ (time-second time-cur) duration)) (date->string (time-monotonic->date time-cur (date-zone-offset (current-date))) "~Y-~m-~d-~H~M~S"))))) (define get-basename (make-time-header "2010-02-12.howm")) (get-basename "2010-02-13 09:13") (get-basename "") (get-basename "2010-02-19 10:13")
time-curに直前の日付を保存しておいて、読み込んだタイムヘッダと比較。そして1秒足すかそのまま使うか、という場合分け。
とやってると迷宮に入り込んだ。
要は、ファイル名作成に使うデータを、最新にすればいい、ということになる。
そして使ったら1秒増やしてtime-curに保存。
(use srfi-19) (define (make-basename-generator filename) (let ((time-cur (date->time-monotonic (string->date (substring filename 0 10) "~Y-~m-~d") ))) (lambda (time-h) (let ((time-tmp (make-time time-monotonic 0 0))) (when (and (string? time-h) (= 16 (string-length time-h))) (set! time-tmp (date->time-monotonic (string->date time-h "~Y-~m-~d ~H:~M")))) (when (time<? time-tmp time-cur) (set-time-second! time-tmp (time-second time-cur))) (set-time-second! time-cur (+ (time-second time-tmp) 1)) (date->string (time-monotonic->date time-tmp (date-zone-offset (current-date))) "~Y-~m-~d-~H~M~S"))))) (define get-basename (make-basename-generator "2010-02-12.howm")) (get-basename "2010-02-13 09:13") (get-basename #f) (get-basename "2010-02-16 00:00")
と考えると、こんな感じかなあ。
オブジェクトのコピーのつもりでつい、「(set! time-tmp time-cur)」とかやっちゃいがちだった。
set!は参照先を切り替えるだけなんだな。