https://gist.github.com/Hamayama/15e4222f6a775fec5c0829361af74e56
hamayama(2017/07/31 22:55:40 UTC)
(use file.filter)
(define (convert-file infile outfile)
(file-filter-for-each
(^[line outp]
(rxmatch-if (#/^[ \t]*$/ line) (#f) ...処理してoutpに出力...))
:reader read-line :input infile :output outfile))
file.filterは、定番の「一時ファイルに出力して最後にrename」も同時に
サポートします (一時ファイルを使うと、処理中にエラーが発生した場合に
中途半端な出力ファイルを残さないで済む。特に既にある出力ファイルを更新したい場合、
エラー発生時には元のファイルがそのまま残されるので便利)
;; file-filter-for-each の lambda の出力ポート固定版
(define (file-filter-for-each-to-output proc . args)
(apply file-filter-for-each
(lambda (data out)
(with-output-to-port out
(lambda () (proc data))))
args))
例えば、最初のサンプルのケースだと、以下のようになります。
(define (convert-file infile outfile)
(define space-str (make-string space-size #\space))
(file-filter-for-each-to-output
(lambda (line)
(rxmatch-if (#/^[ \t]*$/ line) (#f)
(print "")
(print (regexp-replace-all #/^( *)\t/ line #"\\1~space-str"))))
:reader read-line :input infile :output outfile))
すなわち、outfile は指定しながら、lambda の方では出力ポート指定を省略できるというものです。