logo       

[ruby-list:42079] Re: NKF MIME encode problem: msg#00110

lang.ruby.japanese

Subject: [ruby-list:42079] Re: NKF MIME encode problem

出沢です

> 前者の方だと思います。

では恥ずかしげもなく、貼付します。
>
> 確か、以前は、
>
> ftp://ftp.ruby-lang.org/pub/ruby/contrib/
>
> あたりで配布されていたような憶えがあります。

お、、contrib ですか!

載せて頂くのは名誉なことです。よしなに。


#!/usr/local/bin/ruby

# Add metod to class String
# public method
# encode64(pre="",len=76,sep="\n ")
# self を rfc2047に従ってMIMEencodeする。
# 1行あたり、len Byte までで折り返す
# pre に追加する形で encode する。
# 折り返しが必要な場合は sep を入れる
#
# decode64
# self が MIMEencodeされているものとして、decodeする。
# encoded と encoded の間にはさまれている "\s+" を削除する
# それ以外の \n には手を触れない。
# その後、日本語SO/SI が続いてあったらこれも削除する。
#
# unfold(cur="",len=76)
# 1行の長さが len の長さを越えない範囲で、\n を削除する。
#
# private method
# tokenize、should_encode?、encode
#

require "kconv"

class String
def tokenize
tmp = self.split(/(\s+)/)
res = []
while tok = tmp.shift
if tok.should_encode?
while tmp[1] && tmp[1].should_encode?
tok << tmp.shift.to_s
tok << tmp.shift.to_s
break unless tmp[0]
end
end
res << tok
end
res
end

def should_encode?
self =~ /\e/
end


PREFIX = "=?ISO-2022-JP?B?"
def decode64
tok = self.split(/(=\?ISO-2022-JP\?B\?|\?=)/)
ret = tok.shift ; ret = "" if ret.nil?
while t = tok.shift
ret += Kconv::tojis(t+tok.shift+tok.shift)
while t=tok.shift
break if t =~ /\S/ || tok[0].nil?
# ignore ^\s+$ between encoded word.
ret += Kconv::tojis(tok.shift+tok.shift+tok.shift)
ret = ret.sub(/\e\$B\e\(B/,"") # remove escape
end
ret += t.to_s
end
ret
end

def encode64(pre="",len=76,sep="\n ")
len=len-1
toks = Kconv::tojis(self).tokenize
sum="" ; cur=""
while tok = toks.shift
if tok.should_encode?
sum,cur = tok.encode(sum,cur,len,sep)
else
if tok =~ /.*\n/
sum << cur + $&; cur=$'
else
cur += tok
end
while cur.length >= len
cur =~ /\s+\S+\s*$/ ; sum << $`+"\n" ; cur = $&
end
end
end
return sum+cur
end

def encode(ret,cur,len,sep)
tkn = self.split(/(\e\$B|\e\(B)/)
# array tkn には、
# A pre J post A pre J post ,,,,,, の順に入っている
# A は無いこともありえる。
# J には空白をはさまない ASCII、ASCIIを含まない空白も含む

token=""

while cell=tkn.shift

rest = ((len - cur.length - 18)*3/8)*2/3*3 - 1
# ~~~~~~~~~~~~~~~~~~~~~~
# 残されたencode後文字長 4Byte当たり元は3バイト.
# 3の倍数の端数は切捨て。
# -1 は、0 から数えるから。

# PREFIX = "=?ISO-2022-JP?B?" 16 postfix 2Byte
# \e\$B \e\(B 4+4=8 計 26
#### 始めの ASCII を処理
if token.length > rest
if token.length > 0
ret << cur + PREFIX + [ token ].pack("m").chop + "?=" + sep
token = ""
else
ret << cur + sep
end
cur = ""
rest = ((len - 18)*3/8)*2/3*3 - 1
end
token << cell
while token.length > rest
# 古い token は < rest のはずだから、rest までで切ると、
# ASCII の部分のはず
ret += cur + PREFIX+[token[0..rest]].pack("m").chop+"?="+sep
cur="" ; token[0..rest]=""
rest = ((len - 18)*3/8)*2/3*3-1 #
end

# JIS文字が残っていなかったら、while を抜ける
break if tkn[0].nil?
# JIS文字長が長すぎたら処理する。
rest = ((len -cur.length - 26)*3/4-token.length)/6*6-1
# (既に変換分を除き encode-prefix分をあらかじめ引き)
# 変換前文字列長にして token 分をひく 2 の倍数に切捨て
# *3/4 がこれで良いか、、、

while tkn[1].length > rest
if rest >0
ret << cur+PREFIX+
[ token+tkn[0]+tkn[1][0..rest]+tkn[2] ].pack("m").chop +
"?="+sep
tkn[1][0..rest]=""
else
ret << cur+PREFIX+ [ token ].pack("m").chop + "?="+sep
end
token="" ; cur=""
rest = ((len - 26)*3/8)*2*3/3 -7 # 1+ SI/SO =7
end # of while tkn[1].length >

token = tkn[1]>"" ? token+tkn[0]+tkn[1]+tkn[2] : ""
tkn.shift; tkn.shift; tkn.shift
end # of while cell=tkn.shift
cur += PREFIX + [token].pack("m").chop+"?=" if token.length>0
return ret,cur
end # of define

def unfold(cur="",len=76)
ret = ""
self.split(/\n/).each{ |tkn|
if (cur + tkn).gsub(/\e\$B|\e\(B/,"").length < len
cur << tkn
else
ret << cur + "\n"; cur = tkn
end
}
ret+cur
end
end
__END__
# Dezawa 1999/3/14 dezawa-CqVnb2lqQMsjBWqPJ1d2aHf5DAMn2ifp@xxxxxxxxxxxxxxxx
# $Log: mime.rb,v $
# Revision 1.4 1999/03/19 20:42:29 dezawa
# edit typo, reform some statement
#
# Revision 1.3 1999/03/19 20:10:39 dezawa
# add usage comment lines
# add method unfold
#
# Revision 1.2 1999/03/19 12:23:01 dezawa
# fold at any \s if need
# unfold is independent method. it is used after decode64
#
# Revision 1.1 1999/03/17 10:56:37 dezawa
# 76Byte is ignore
#

<Prev in Thread] Current Thread [Next in Thread>
Google Custom Search

News | FAQ | advertise