有没有办法使用 ApplescriptObjc 解码 Quoted-Printable 编码?
Is there a way to decode a Quoted-Printable encoding using ApplescriptObjc?
我正在寻找一种方法来解码 HTML 邮件消息中以 Quoted-Printable 编码编码的源代码,想知道这是否可以在 AppleScriptObjC 中完成?
我知道 Python 3 中有一个名为 quopri 的内置模块可以完成这项工作。所以我有一个后备解决方案。只是希望我可以做到这一点而无需在用户机器上安装 Python 3。由于脚本已经内置在 AppleScript 中,我认为 AppleScriptObjC 将是寻找答案的最佳场所。
从网络上搜索,这应该可以解决问题:
use framework "Foundation"
property NSString : class "NSString"
set coded_s to "" -- some quoted-printable string
--convert from applescript text to NSString
set coded_s to NSString's stringWithString:coded_s
-- delete line wraps
set decoded_s to coded_s's stringByReplacingOccurrencesOfString:("=" & return & linefeed) withString:""
-- replace = with percent
set decoded_s to decoded_s's stringByReplacingOccurrencesOfString:"=" withString:"%"
-- decode as percent-escaped string
set decoded_s to decoded_s's stringByReplacingPercentEscapesUsingEncoding:(current application's NSUTF8StringEncoding)
-- convert from NSString to applescript text
decoded_s as text
quoted-printable 编码标准被定义为 RFC 2045
的一部分。
简要概括地说:不可打印的 ASCII 字符被编码为以 "="
开头的三字符序列,紧接着是两位十六进制数,其计算结果为 ASCII字符代码; "="
本身以相同的方式编码;行最多但不能超过 76 个字符,如果 "="
出现在行尾,则它充当连续(或软中断)字符。
我采用了这些规则的超集来确保满足足够的条件,围绕这些条件编写了以下脚本,并“按原样”呈现,没有任何特殊的优化尝试(仍有余地已完成):
#!/usr/bin/env osascript
--------------------------------------------------------------------------------
use framework "Foundation"
use scripting additions
--------------------------------------------------------------------------------
prop NSString: ref current application's NSString
prop rgex: 1024
prop utf8: 4
--------------------------------------------------------------------------------
on qp_decode(input)
local input
try # test for existence as a file path
input as «class fsrf»
NSString's stringWithContentsOfURL:result ¬
encoding:utf8 |error|:(missing value)
on error
input
end try
set qp to __s(result)
replace(qp, "(?m)\h*$", "") # Removing trailing whitespace
replace(qp, "(?sm)=(\R|$)", "") # Join lines split with a soft-break
map(qp, "(?i)=[A-F0-9]{2}", char) # Decode escape sequences, i.e. "=HH"
end qp_decode
--------------------------------------------------------------------------------
# "PRIVATE" HANDLERS:
on __s(init)
ref item 1 of {init}
end __s
to _nsstring_ from _ref given mutability:m as boolean : false
local _ref, m, t
set t to NSString's stringWithString:_ref
if m then set t to t's mutableCopy()
try
set _ref's contents to t
end try
t
end _nsstring_
to replace(_ref, a, b)
local _ref, a, f, t
set t to _nsstring_ from _ref with mutability
t's replaceOccurrencesOfString:a withString:b ¬
options:rgex |range|:{0, t's |length|()}
try
set _ref's contents to t as text
end try
t as text
end replace
to map(_ref, a, func as handler)
local _ref, a, t, f
script
prop fn: func
prop t : _nsstring_ from _ref
prop s : t's mutableCopy()
prop index: 0
on next()
t's rangeOfString:a options:rgex
set [j, n] to the result's [location, |length|]
if n = 0 then return the yield()
set u to (t's substringWithRange:[j, n]) as text
set c to fn(text 2 thru -1 of u)
tell s to replaceOccurrencesOfString:u ¬
withString:c options:0 |range|:[my index, ¬
|length|() - my index]
set index to index + j
set t to the substringFromIndex_(index) of s
next()
end next
on yield()
try
set _ref's contents to s as text
end try
s as text
end yield
end script
result's next()
end map
to base_10 from base_16
# There's probably a more ASObjC-y way to do this
local base_16
set p to 1
set |ξ| to 0
script hexadecimal
prop digits: "123456789ABCDEF"
prop coefficients: reverse of base_16's characters
end script
repeat with x in hexadecimal's coefficients
set |ξ| to |ξ| + (offset of x in (hexadecimal's digits)) * p
set p to p * 16
end repeat
|ξ|
end denary
to char(k)
if k's class = text then set k to (base_10 from k)
character id k
end char
---------------------------------------------------------------------------❮END❯
您将要调用的主要处理程序是 qp_decode()
,它采用单个参数,可以是文字字符串或文件路径,该文件被读取并作为 UTF-8 编码字符串处理,然后作为文字字符串参数进行处理。
我从评论线程中注意到您使用 Script Debugger。如果脚本无法编译或执行,我建议 运行 Script Editor 中的脚本(但是,您需要从原始文件再次 copy/paste来源在这里,因为 Script Debugger 在粘贴之前操作剪贴板的内容)。我实际上在编写和调试此脚本时使用了 vim
和 osascript
,因此它是原始文本。
我正在寻找一种方法来解码 HTML 邮件消息中以 Quoted-Printable 编码编码的源代码,想知道这是否可以在 AppleScriptObjC 中完成?
我知道 Python 3 中有一个名为 quopri 的内置模块可以完成这项工作。所以我有一个后备解决方案。只是希望我可以做到这一点而无需在用户机器上安装 Python 3。由于脚本已经内置在 AppleScript 中,我认为 AppleScriptObjC 将是寻找答案的最佳场所。
从网络上搜索,这应该可以解决问题:
use framework "Foundation"
property NSString : class "NSString"
set coded_s to "" -- some quoted-printable string
--convert from applescript text to NSString
set coded_s to NSString's stringWithString:coded_s
-- delete line wraps
set decoded_s to coded_s's stringByReplacingOccurrencesOfString:("=" & return & linefeed) withString:""
-- replace = with percent
set decoded_s to decoded_s's stringByReplacingOccurrencesOfString:"=" withString:"%"
-- decode as percent-escaped string
set decoded_s to decoded_s's stringByReplacingPercentEscapesUsingEncoding:(current application's NSUTF8StringEncoding)
-- convert from NSString to applescript text
decoded_s as text
quoted-printable 编码标准被定义为 RFC 2045
的一部分。
简要概括地说:不可打印的 ASCII 字符被编码为以 "="
开头的三字符序列,紧接着是两位十六进制数,其计算结果为 ASCII字符代码; "="
本身以相同的方式编码;行最多但不能超过 76 个字符,如果 "="
出现在行尾,则它充当连续(或软中断)字符。
我采用了这些规则的超集来确保满足足够的条件,围绕这些条件编写了以下脚本,并“按原样”呈现,没有任何特殊的优化尝试(仍有余地已完成):
#!/usr/bin/env osascript
--------------------------------------------------------------------------------
use framework "Foundation"
use scripting additions
--------------------------------------------------------------------------------
prop NSString: ref current application's NSString
prop rgex: 1024
prop utf8: 4
--------------------------------------------------------------------------------
on qp_decode(input)
local input
try # test for existence as a file path
input as «class fsrf»
NSString's stringWithContentsOfURL:result ¬
encoding:utf8 |error|:(missing value)
on error
input
end try
set qp to __s(result)
replace(qp, "(?m)\h*$", "") # Removing trailing whitespace
replace(qp, "(?sm)=(\R|$)", "") # Join lines split with a soft-break
map(qp, "(?i)=[A-F0-9]{2}", char) # Decode escape sequences, i.e. "=HH"
end qp_decode
--------------------------------------------------------------------------------
# "PRIVATE" HANDLERS:
on __s(init)
ref item 1 of {init}
end __s
to _nsstring_ from _ref given mutability:m as boolean : false
local _ref, m, t
set t to NSString's stringWithString:_ref
if m then set t to t's mutableCopy()
try
set _ref's contents to t
end try
t
end _nsstring_
to replace(_ref, a, b)
local _ref, a, f, t
set t to _nsstring_ from _ref with mutability
t's replaceOccurrencesOfString:a withString:b ¬
options:rgex |range|:{0, t's |length|()}
try
set _ref's contents to t as text
end try
t as text
end replace
to map(_ref, a, func as handler)
local _ref, a, t, f
script
prop fn: func
prop t : _nsstring_ from _ref
prop s : t's mutableCopy()
prop index: 0
on next()
t's rangeOfString:a options:rgex
set [j, n] to the result's [location, |length|]
if n = 0 then return the yield()
set u to (t's substringWithRange:[j, n]) as text
set c to fn(text 2 thru -1 of u)
tell s to replaceOccurrencesOfString:u ¬
withString:c options:0 |range|:[my index, ¬
|length|() - my index]
set index to index + j
set t to the substringFromIndex_(index) of s
next()
end next
on yield()
try
set _ref's contents to s as text
end try
s as text
end yield
end script
result's next()
end map
to base_10 from base_16
# There's probably a more ASObjC-y way to do this
local base_16
set p to 1
set |ξ| to 0
script hexadecimal
prop digits: "123456789ABCDEF"
prop coefficients: reverse of base_16's characters
end script
repeat with x in hexadecimal's coefficients
set |ξ| to |ξ| + (offset of x in (hexadecimal's digits)) * p
set p to p * 16
end repeat
|ξ|
end denary
to char(k)
if k's class = text then set k to (base_10 from k)
character id k
end char
---------------------------------------------------------------------------❮END❯
您将要调用的主要处理程序是 qp_decode()
,它采用单个参数,可以是文字字符串或文件路径,该文件被读取并作为 UTF-8 编码字符串处理,然后作为文字字符串参数进行处理。
我从评论线程中注意到您使用 Script Debugger。如果脚本无法编译或执行,我建议 运行 Script Editor 中的脚本(但是,您需要从原始文件再次 copy/paste来源在这里,因为 Script Debugger 在粘贴之前操作剪贴板的内容)。我实际上在编写和调试此脚本时使用了 vim
和 osascript
,因此它是原始文本。