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>/ ) do stylish_params = $1 rdf_text = $2 stylish_code = rdf_text[ /(.*?)<\/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 == "*" ) ) { //opera.postError( type, target, style ); var link = document.createElement( "link" ); link.rel = "stylesheet"; link.type = "text/css"; link.href = "data:base64," + style; document.getElementsByTagName( "head" )[0].appendChild( link ); } } ' ) jsbody << '} )( )' File.open( opelish["dir_opera_script"] + "opelish.js", "w" ) do |f| f.puts jsbody.join( "\n" ) end pause( )