- 2007-12-12 (水) 9:06
- blog

おはようございます。
JC です。
さて皆さん。 AS3 のソースをブログに乗せる時ってどうしてますか?
そのまま?
それとも何か工夫はあるでしょうか?
俺はこんな方法を使っています。という紹介。
八角研究所 : Flex2でソースコードをブログに貼り付けるツールを作る その2
で、 唐辛子という Flex2 で書かれたブログにプログラムのソースコードを貼り付けるツールが紹介されていました。
感謝。
エスケープ文字とかの判定がされていないとか、外部から読み込んだ CSS ファイルがプレビューの際に特に反映されないとか、
色々在りますが、ソレを解決しつつ、 AS3 のパーサーを作ってみました。
まぁ、コードがひどいことになっているのはちょっと急いでいたからでってことで勘弁してくださいww
※ だれかきれいにしてくれたら連絡くださいwww
まずは CSS を反映させてみよう。
CSS の読み込み自体はやっているので、StyleSheetObject Class(以下 SSOと略す) を作ってみました。
SSO のコンストラクタ に 読み込んだ CSS ファイルの String を渡して、init() を呼べばおk。
以下が SSO のソース
/** * ... * @author Default * @version 0.1 */ package jc.com.bkzen.flex.code { public class StyleSheetObject { private var css_array: Array; public var css_object: Object; public var class_names: Array; private static const PRE_NAME: String = "code"; private static const PRE_REP: String = "pre"; private static const CODE_NOTE: String = "color"; private static const CLASS_NAME: String = "class_name"; public function StyleSheetObject(css_string: String) { var s:String = css_string.replace(/(rn|n)/g, "r"); css_array = css_string.split("}"); css_array.pop(); css_object = new Object(); for (var i: String in css_array) { css_array[i] += "}"; css_array[i] = css_array[i].replace(/r/, ""); } } public function init(): void { class_names = new Array(); for (var i: int = 0; i < css_array.length; i ++ ) { var css: String = css_array[i]; var ks: int = css.indexOf("{"); var name: String = css.substring(css.lastIndexOf(".", ks), ks); name = name.replace(/(s|.)/g, ""); if (name == StyleSheetObject.PRE_NAME) { name = StyleSheetObject.PRE_REP; } else { name = "." + name; } css = css.substring(ks + 1, css.length - 1); css = css.replace(/(s*$|r)/g, ""); var c_obj: Object = new Object(); c_obj[StyleSheetObject.CLASS_NAME] = new Array(); var tmp: Array = css.split(";"); if (tmp[tmp.length - 1] == "") { tmp.pop(); } for each(var a: int in tmp) { tmp[a] = tmp[a].replace(/^s*/g, ""); tmp[a] = tmp[a].replace(/:s*/g,":"); var tmpb: Array = tmp[a].split(":"); for (var c: int = 0; c < tmpb.length; c += 2 ) { c_obj[tmpb[c]] = tmpb[c + 1]; c_obj[StyleSheetObject.CLASS_NAME].push(tmpb[c]); } var color: String = c_obj[StyleSheetObject.CODE_NOTE]; if (color.length == 4) { var colorB: String = "#"; for (var b: int = 1; b < color.length; b ++ ) { colorB += color.charAt(b); colorB += color.charAt(b); } c_obj[StyleSheetObject.CODE_NOTE] = colorB; } } css_object[name] = c_obj; class_names.push(name); } } } }
次に AS3 の Parser Class である SParserAS3 をつくりました。
以下がソース。
package { public class SParserAS3 extends SParser { public static const STYLE_SUB_KEYWORD: String = "subkeyword"; public static const STYLE_ADD_KEYWORD: String = "addkeyword"; public var reserve_sub_word: Array = []; public var reserve_additional_word: Array = []; public function SParserAS3(source: String) { super(source); } protected override function initTable(): void { table = [ // comment new SParserTableItem(/^\/*/s, "", null), new SParserTableItem(/^/*.*?*//s, STYLE_REM, null), new SParserTableItem(/^\//[^rn]*/, "", null), new SParserTableItem(/^//[^rn]*/, STYLE_REM, null), // number new SParserTableItem(/^(d+.d+|d+)/, STYLE_NUMBER, null), // string new SParserTableItem(/^\"/, "", null), new SParserTableItem(/^"/, STYLE_STRING, readStringDQ), new SParserTableItem(/^\'/, "", null), new SParserTableItem(/^'/, STYLE_STRING, readStringSQ), // word new SParserTableItem(/^[w][wd]*/, "", checkReserveWord) ]; reserve_word = [ // for AS3 "class", "dynamic", "extends", "implements", "import", "interface", "new", "case", "do", "while", "else", "if", "for", "in", "switch", "throw", "intrinsic", "private", "public", "static", "get", "set", "function", "var", "try", "catch", "finally", "while", "with", "default", "break", "continue", "delete", "return", "final", "each", "label", "internal", "native", "override", "protected", "const", "namespace", "package", "include", "use", "AS3", "flash_proxy", "object_proxy" ]; reserve_sub_word = [ "super", "this", "null", "Infinity", "NaN", "undefined", "true", "false", "is", "as", "instanceof", "typeof" ]; reserve_additional_word = [ "void", "Null", "ArgumentError", "arguments", "Array", "Boolean", "Class", "Date", "DefinitionError", "Error", "EvalError", "Function", "int", "Math", "Namespace", "Number", "Object", "QName", "RangeError", "ReferenceError", "RegExp", "SecurityError", "String", "SyntaxError", "TypeError", "uint", "URIError", "VerifyError", "XML", "XMLList", "Accessibility", "AccessibilityProperties", "ActionScriptVersion", "AVM1Movie", "Bitmap", "BitmapData", "BitmapDataChannel", "BlendMode", "CapsStyle", "DisplayObject", "DisplayObjectContainer", "FrameLabel", "GradientType", "Graphics", "IBitmapDrawable", "InteractiveObject", "InterpolationMethod", "JointStyle", "LineScaleMode", "Loader", "LoaderInfo", "MorphShape", "MovieClip", "PixelSnapping", "Scene", "Shape", "SimpleButton", "SpreadMethod", "Sprite", "Stage", "StageAlign", "StageDisplayState", "StageQuality", "StageScaleMode", "SWFVersion", "EOFError", "IllegalOperationError", "InvalidSWFError", "IOError", "MemoryError", "ScriptTimeoutError", "StackOverflowError", "ActivityEvent", "AsyncErrorEvent", "ContextMenuEvent", "DataEvent", "ErrorEvent", "Event", "EventDispatcher", "EventPhase", "FocusEvent", "FullScreenEvent", "HTTPStatusEvent", "IEventDispatcher", "IMEEvent", "IOErrorEvent", "KeyboardEvent", "MouseEvent", "NetStatusEvent", "ProgressEvent", "SecurityErrorEvent", "StatusEvent", "SyncEvent", "TextEvent", "TimerEvent", "ExternalInterface", "BevelFilter", "BitmapFilter", "BitmapFilterQuality", "BitmapFilterType", "BlurFilter", "ColorMatrixFilter", "ConvolutionFilter", "DisplacementMapFilter", "DisplacementMapFilterMode", "DropShadowFilter", "GlowFilter", "GradientBevelFilter", "GradientGlowFilter", "ColorTransform", "Matrix", "Point", "Rectangle", "Transform", "Camera", "ID3Info", "Microphone", "Sound", "SoundChannel", "SoundLoaderContext", "SoundMixer", "SoundTransform", "Video", "FileFilter", "FileReference", "FileReferenceList", "IDynamicPropertyOutput", "IDynamicPropertyWriter", "LocalConnection", "NetConnection", "NetStream", "ObjectEncoding", "Responder", "SharedObject", "SharedObjectFlushStatus", "Socket", "URLLoader", "URLLoaderDataFormat", "URLRequest", "URLRequestHeader", "URLRequestMethod", "URLStream", "URLVariables", "XMLSocket", "PrintJob", "PrintJobOptions", "PrintJobOrientation", "ApplicationDomain", "Capabilities", "IME", "IMEConversionMode", "LoaderContext", "Security", "SecurityDomain", "SecurityPanel", "System", "AntiAliasType", "CSMSettings", "Font", "FontStyle", "FontType", "GridFitType", "StaticText", "StyleSheet", "TextColorType", "TextDisplayMode", "TextField", "TextFieldAutoSize", "TextFieldType", "TextFormat", "TextFormatAlign", "TextLineMetrics", "TextRenderer", "TextSnapshot", "ContextMenu", "ContextMenuBuiltInItems", "ContextMenuItem", "Keyboard", "KeyLocation", "Mouse", "ByteArray", "Dictionary", "Endian", "IDataInput", "IDataOutput", "IExternalizable", "Proxy", "Timer", "XMLDocument", "XMLNode", "XMLNodeType" ]; } protected override function checkReserveWord(tok: SToken): SToken { for each (var keyword: String in reserve_word) { if (ignore_case) { if (keyword.toUpperCase() == tok.text.toUpperCase()) { tok.style = STYLE_KEYWORD; break; } else { checkReserveWord2(tok); } } else { if (keyword == tok.text) { tok.style = STYLE_KEYWORD; break; } else { checkReserveWord2(tok); } } } return tok; } protected function checkReserveWord2(tok: SToken): SToken { for each (var keyword: String in reserve_sub_word) { if (ignore_case) { if (keyword.toUpperCase() == tok.text.toUpperCase()) { tok.style = STYLE_SUB_KEYWORD; break; } else { checkReserveWord3(tok); } } else { if (keyword == tok.text) { tok.style = STYLE_SUB_KEYWORD; break; } else { checkReserveWord3(tok); } } } return tok; } protected function checkReserveWord3(tok: SToken): SToken { for each (var keyword: String in reserve_additional_word) { if (ignore_case) { if (keyword.toUpperCase() == tok.text.toUpperCase()) { tok.style = STYLE_ADD_KEYWORD; break; } } else { if (keyword == tok.text) { tok.style = STYLE_ADD_KEYWORD; break; } } } return tok; } } }
コレもびみょーなコードになってます。すみません。
そしてあとは SourceConvTougarasi.mxml にそれらを反映させればおk。
その部分が以下。
private var cso: StyleSheetObject;
private function exec_btn_click():void
{
var source:String = source_txt.text;
// タブを展開
source = KString.expandTab(source, 4);
// 解析用クラスを生成
var klass:Class = type_cmb.selectedItem.parser;
var instance:* = new klass( source );
var parser:SParser = SParser(instance);
var tokens:SToken = parser.makeToken();
var html:String = tokens.getHtml();
html = "<pre class="code">"+html+"</pre>";
// プレビューとHTMLのコードを表示する
navi.selectedChild = html_tab;
var css:StyleSheet = new StyleSheet();
for (var i: int = 0; i < cso.class_names.length; i++) {
var class_name: String = cso.class_names[i];
css.setStyle(class_name, cso.css_object[class_name]);
}
view_txt.styleSheet = css;
view_txt.htmlText = html
if (usestyle_chk.selected) {
// 直接STYLE属性に値を書く
html_txt.text = tokens.getHtmlStyle(css);
}
else {
// CSS
html_txt.text = html;
}
}
private function setCSS():void
{
var s:String = read_css_service.lastResult.toString();
cso = new StyleSheetObject(s);
s = s.replace(/(rn|n)/g, "r");
css_txt.text = s;
cso.init();
}
適当ですみません。暇だったら直します。
八角研究所さん。ありがとうございます。
- Newer: BBQ
- Older: Flex, ActionScript 3 の勉強
Comments (Close):2
- 通りすがり 08-03-19 (水) 0:49
-
Flex暦半年のプログラマです。すばらしいっす!こんなの僕には作れません。
ツールのSWFファイルがダウンロードできるようになってると、便利だと思います。
- jc 08-03-19 (水) 5:42
-
>>通りすがりさん
Flex 暦は多分同じくらいかとw
Flash暦は3年ぐらいですがw
確かにツールとしてあってブログに投稿するときに使えたら便利ですね~
今仕事に追われているので時間があるときに考えてみますw

