require "yaml"
# exerb用
# カレントディレクトリを実行ファイルと同じディレクトリにする
Dir.chdir( ExerbRuntime.filepath.sub( /[\\\/][^\\\/]*?$/, "" ) ) if $Exerb
def pause
exec( "pause" ) if $Exerb
end
class String
# 文字を数値文字参照に変換する
def touref
require 'kconv'
toutf16.unpack( "n*" ).map do |n|
( n < 128 ? '%c' : '\\u%04x' ) % n
#( n < 128 ? '%c' : '&#%x;' ) % n
end.join
end
end
# UTF-8の2バイト文字にマッチする正規表現
reg_utf8 = / [\xc0-\xdf][\x80-\xbf] | [\xe0-\xef][\x80-\xbf]{2}
| [\xf0-\xf7][\x80-\xbf]{3} | [\xf8-\xfb][\x80-\xbf]{4}
| [\xfc-\xfd][\x80-\xbf]{5} /x
opelish = YAML.load_file( "setting.yaml" )
unless opelish["dir_opera_script"] && File.exists?( opelish["dir_opera_script"] )
p "setting.yaml [dir_opera_script] is undefined or missing"
pause( )
exit
end
unless opelish["stylish_rdf"] && File.exists?( opelish["stylish_rdf"] )
p "setting.yaml [stylish_rdf] is undefined or missing"
pause( )
exit
end
opelish["dir_opera_script"].gsub!( /\//, "\\" )
opelish["dir_opera_script"].gsub!( /[\\\/]*$/, "\\" )
reg_code = /
@-moz-document
\s
((?>[^{]+)) # $1 document pattern
\{
(\s* # $2 css code
(?>[^{]+\{[^{}]*\}\s*)+
)
\}
/x
reg_pattern = /
(url|url-prefix|domain) # $1 match type
\s*
\(\s*"?
(.*?) # $2 match target
"?\s*\)
/x
reg_selector = /
(?:
(?=[,}])([,}])(?>[^:]*) # セレクタの前にカンマもしくはCSSコード
|
^(?>[^:]*) # セレクタがコード全体の先頭にある
)
:
(?:
(?:(?:last|only)-(?:child|of-type))
|
(?:nth-(?:child|last-child|of-type|last-of-type))
|
(?:root|target|not|:selection)
)
(?>[^,{]*)(?=[,{])
(\{[^{]*\})? # 直前に{且つ最後に{...}があるなら、セレクタとCSSコードまとめて削除
/x
begin
rdf = File.open( opelish["stylish_rdf"], "r" ) { |f| f.read }
rdf.gsub!( /\/\*.*?\*\//m, "" )
rdf.gsub!( /^\s+/m, "" )
rdf.gsub!( /\s+$/m, "" )
rdf.gsub!( /[\r\n]/, "" )
jsbody = []
cnt = {}
rdf.gsub( /<RDF:Description([^>]*?)>(.*?)<\/RDF:Description>/ ) do
stylish_params = $1
rdf_text = $2
stylish_code = rdf_text[ /<stylish:code>(.*?)<\/stylish:code>/, 1 ]
# アプリケーションインターフェース用のスタイルは変換しない
next if stylish_code.include?( "there.is.only.xul" )
# スタイルの状態を取得
desc = stylish_params[ /:description="([^"]*)"/, 1 ]
global = stylish_params.include?( ':global="true"' )
enabled = stylish_params.include?( ':enabled="true"' )
# 有効になっていないスタイルは変換しない
next unless enabled || opelish["export_disable_style"]
stylish_code.gsub!( reg_utf8 ) { $&.touref }
stylish_code.gsub!( /</, "<" )
stylish_code.gsub!( />/, ">" )
# Mozilla用のcssを削除
stylish_code.gsub!( /([{;])\s*-moz-.*?:.*?([;}])/i, "\\1\\2" )
stylish_code.gsub!( /([{;])\s*[a-z_-]*?\s*:\s*-moz-.*?([;}])/i, "\\1\\2" )
# ダブルクォート中の { と , を数値文字参照にする
stylish_code.gsub!( /"(?>[^"{,]*)(?:([{,])[^"{,]*)*"/ ) do
if $1 == "{"
$&.gsub( "{", "\\u7B" )
elsif $1 == ","
$&.gsub( ",", "\\u2C" )
else
$&
end
end
# サポートされていないセレクタの削除
if opelish["remove_unsupported_selector"]
stylish_code.gsub!( reg_selector ) do
( $1 == "{" && $2 != "" ) ? "" : $1
end
end
jsbody << "//" + desc
if global
stylish_code.gsub!( /@namespace url\([^)]*\);?/, "" )
jsbody << "addStyle( '*', '*', '#{stylish_code}' );"
cnt[desc] = true
else
stylish_code.gsub( reg_code ) do
pattern = $1
css_text = $2
css_text.gsub!( /\"/, "\\\"" )
pattern.gsub( reg_pattern ) do
type = $1
target = $2
# 暗号化されたページではUserJavaScriptが動作しないので変換しない
next if target.include?( "https" )
jsbody << "addStyle( '#{type}', '#{target}', '#{css_text}' );"
cnt[desc] = true
end
end
end
end
p "export " + cnt.keys.length.to_s + " styles."
rescue
p $!
pause( )
exit
end
jsbody.unshift( '// ==UserScript==
// @name Opelish
// @description Export and convert stylish.rdf for UserJavaScript on Opera
// @namespace http://bmky.net/
// @author szsk
// @version 1.0
// ==/UserScript==
( function( ) {
var url = location.href;
var host = location.hostname;
function addStyle( type, target, style )
{
if(
( type == "url" && url == target )
|| ( type == "url-prefix" && url.indexOf( target ) == 0 )
|| ( type == "domain" && host.indexOf( target ) != -1 )
|| ( type == "*" && target == "*" )
) {
var head = document.getElementsByTagName( "head" );
if( head.length == 0 ) return;
var link = document.createElement( "link" );
link.rel = "stylesheet";
link.type = "text/css";
link.href = "data:base64," + style;
head[0].appendChild( link );
}
}
' )
jsbody << '} )( )'
File.open( opelish["dir_opera_script"] + "opelish.js", "w" ) do |f|
f.puts jsbody.join( "\n" )
end
pause( )