α版
折りたたみを実装する予定です。
ieは10以上で見てね。
/*******************************************************************************
* ■function: exportClass
* 動作概要: <style>〜</style>間にクラス情報を書き出す
* -----------------------------------------------------------------------------
* Argument:
* none
*
* Return:
* none
*
* -----------------------------------------------------------------------------
* memo:
******************************************************************************/
function exportClass()
{
//各種変数宣言
var styleTag;
var htmlHead;
var classText = "";
//<style>〜</style>を獲得
styleTag = window.document.getElementsByTagName( "style" ).item( 0 );
//<style>〜</style>が無ければ作成
if( styleTag == null )
{
//0番目の<head>要素を獲得
htmlHead = window.document.getElementsByTagName( "head" ).item( 0 );
//<head>〜</head>に<style>〜<style>追加
htmlHead.appendChild( window.document.createElement( "style" ) );
//再度<style>〜</style>を獲得
styleTag = window.document.getElementsByTagName( "style" ).item( 0 );
}
//全クラスを書き出す
for( var name in classList )
{
//lengthは除外
if( name == "length" )
{
continue;
}
//開始
classText += "." + name + "{";
//全プロパティを書き出す
for( var value in classList[name] )
{
//lengthは除外
if( value == "length" )
{
continue;
}
//値を書き出す
classText += value + ":" + classList[name][value] + ";";
}
//終了
classText += "}";
}
classText += "pre{font-family:\"メイリオ\"; font-size:10px;}";
classText += "ol{background-color:powderblue;}";
classText += "ul{background-color:powderblue;}";
classText += "li{padding-left:1em;border-left:0.3em solid teal;white-space:pre-wrap;}";
classText += "li:nth-child(even){background-color:#fefffe}";
classText += "li:nth-child(odd){background-color:ghostwhite}";
//classText += "li.oddLine{}";
//classText += "li.evenLine{}";
//本作業
styleTag.innerHTML += classText;
}
/*******************************************************************************
* ■object: classList
* 内容: cssのクラスを管理する
* -----------------------------------------------------------------------------
* Properties:
* 連想配列: プロパティ名:値
*
* -----------------------------------------------------------------------------
* memo:
******************************************************************************/
var classList = new Array();
classList["UnityComment"] = { "color":"green" };
classList["MultiComment"] = { "color":"lightseagreen" };
classList["SingleString"] = { "color":"darkred" };
classList["DoubleString"] = { "color":"darkred" };
classList["ErrorString"] = { "background-color":"yellow" };
classList["Number"] = { "color":"red" };
classList["Keyword0"] = { "color":"blue" };
classList["Keyword1"] = { "color":"steelblue" };
classList["Keyword2"] = { "color":"skyblue" };
classList["Keyword3"] = { "color":"black" };
classList["Keyword4"] = { "color":"black" };
classList["Keyword5"] = { "color":"black" };
classList["Keyword6"] = { "color":"black" };
classList["Keyword7"] = { "color":"black" };
classList["Keyword8"] = { "color":"black" };
classList["Keyword9"] = { "color":"black", "font-weight": "bold" };
//classList["evenLine"] = { "background-color":"#fefffe" };
//classList["oddLine"] = { "background-color":"ghostwhite" };
/*******************************************************************************
* ■object: languageList
* 内容: cssのクラスを管理する
* -----------------------------------------------------------------------------
* Members:
* keyword: 連想配列→ クラス名:キーワードリスト(配列) で使用
*
* -----------------------------------------------------------------------------
* memo:
******************************************************************************/
var Language = function()
{
this.keyword = new Array();
}
Language.prototype.numRegex = new RegExp( "(^|\\b)(\\d+)(\\b|$)", "g" );
var languageList = new Array();
languageList["js"] = new Language();
with( languageList["js"] )
{
mus = "/*";
mue = "*/";
uni = "//";
keyword =
{
"Keyword0": new Array( "if","else","for","in","do","while","switch","case","default","try","catch","throw","finally","break","continue","return","debugger","var","function","this","with" ),
"Keyword1": new Array( "new","delete","void","instanceof","typeof" ),
"Keyword2": new Array( "true", "false", "null", "prototype" ),
"Keyword3": new Array( "ActiveXObject","Array","ArrayBuffer","arguments","Boolean","DataView","Date","Debug","Enumerator","Error","Float32Array","Float64Array","Function","Global","Int8Array","Int16Array","Int32Array","JSON","Math","Number","Object","RegExp","Regular","String","Uint8Array","Uint16Array","Uint32Array","VBArray","WinRTError" ),
"Keyword9": new Array( "const","enum","export","extends","import","super","implements","interface","let","package","private","protected","public","static","yield" ) //諸事情によりclass削除
};
}
/*******************************************************************************
* ■function: highlighting
* 動作概要: 文字列を強調する
* -----------------------------------------------------------------------------
* Argument:
* <in> str: プレーンテキスト
*
* Return:
* 強調した文字列
*
* -----------------------------------------------------------------------------
* memo:
******************************************************************************/
Language.prototype.highlighting = function( str )
{
//各種変数初期化
var temp = new Array();
//キーワードを強調する
for( var style in this.keyword )
{
//length要素は無視
if( style == "length" )
{
continue;
}
//強調実行
str = str.replace(
new RegExp( "(^|\\b)(" + this.keyword[style].join( "|" ) + ")(\\b|$)", "g" ),
"<span class=\"" + style + "\">$2</span>"
);
}
//数字を強調する
str = str.replace(
this.numRegex,
"<span class=\"Number\">$2</span>"
);
//強調後の文字列を返す
return str;
}
var OnloadFuncList = new Array();
OnloadFuncList.push( exportClass );
OnloadFuncList.push( HighlightHTML );
/*******************************************************************************
* ■function: onload
* 動作概要: 読込み完了直後にOnloadFuncList内の関数を順次実行する(FIFO)
* -----------------------------------------------------------------------------
* Argument:
* none
*
* Return:
* 「行番号(3桁右詰)+" "」を返して、行番号をカウントアップするメソッド
*
* -----------------------------------------------------------------------------
* memo:
******************************************************************************/
window.onload = function()
{
//各種変数宣言
var execute;
//登録された関数を順次実行する
while( execute = OnloadFuncList.shift() )
{
execute();
}
}
/*******************************************************************************
* ■function: lastStringIs
* 動作概要: 文字列の終端が比較文字列に一致するか判定する。
* -----------------------------------------------------------------------------
* Argument:
* <in> find: 比較文字列
*
* Return:
* true: 一致
* false: 不一致
*
* -----------------------------------------------------------------------------
* memo:
******************************************************************************/
String.prototype.lastStringIs = function()
{
var index = this.lastIndexOf( arguments[0] );
if( index >= 0 && index == this.length - arguments[0].length )
{
return true;
}
else
{
return false;
}
}
/*******************************************************************************
* object: initRuler
* 動作概要: 行数初期化
* -----------------------------------------------------------------------------
* Argument:
* none
*
* Member:
* line(val): 行数
* count(fnc): 行数カウントアップ&<li>タグリターン
* get(fnc): 行数リターン
*
* Return:
* none
*
* -----------------------------------------------------------------------------
* memo: クロージャーのつもりだったけどget()が欲しくなった。
******************************************************************************/
var initRuler = function()
{
//各種変数宣言
this.line = 1;
this.count = function()
{
var listTag = "<li id=\"line_" + this.line + "\" value=\"" + this.line + "\">";
//行数カウントアップ
this.line++;
//li終了、開始タグを返す
return listTag;
};
this.get = function()
{
return this.line;
}
}
/*******************************************************************************
* ■function: HighlightHTML
* 動作概要: 対象クラスの文字列を強調表示する
* -----------------------------------------------------------------------------
* Argument:
* none
*
* Return:
* none
*
* -----------------------------------------------------------------------------
* memo: ">"は">"に"<"は"<"に置換しておくこと
******************************************************************************/
function HighlightHTML()
{
//各種変数宣言
var Original = ""; //元のテキスト
var Temporal = ""; //テキストの一時領域
var Translate = ""; //ハイライト処理完了後のテキスト
var offset = 0; //オフセット値
var error_text = -1; //構文エラー
var plain_text = 0; //通常テキスト
var multi_comment = 1; //複数行コメント
var unity_comment = 2; //一行コメント
var double_string = 3; //文字列1
var single_string = 4; //文字列2
var text_control = plain_text; //コメント,文字列フラグ
var elements = null; //ハイライト対象の言語
var ruler = null; //行数記録要員
var diplo = 0; //連続行数
//
//登録している言語を順次検索する
for( var lang in languageList )
{
if( lang == "length" )
{
continue;
}
//言語ごとに対象タグを獲得する
elements = window.document.getElementsByClassName( lang );
for( var num=elements.length-1; num>=0; num-- )
{
//元のテキストを獲得(タブを半角スペース4つに変更)
Original = elements[num].innerHTML.replace( /\t/g, " " );
//各変数初期化
ruler = new initRuler();
Translate = "<ol>" + ruler.count();
offset = 0;
text_control = plain_text;
Temporal = "";
//1文字ずつ調査
while( offset <= Original.length )
{
//対象の文字を獲得
Temporal += Original.charAt( offset++ );
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//制御コードの処理
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//■(\\)→読み飛ばす
if( Temporal.lastStringIs( "\\" ) )
{
//次の文字を読み込む
Temporal += Original.charAt( offset++ );
}
//■(\n)→改行後、行番号を添付
else if( Temporal.lastStringIs( "\n" ) )
{
//テキストの状態を判定
switch( text_control )
{
//通常時は一旦確定させる
case plain_text:
Temporal = languageList.js.highlighting( Temporal );
break;
//単一行コメントは終了
case unity_comment:
text_control = plain_text;
Temporal += "</span>";
break;
//複数行コメントは次の行も
case multi_comment:
Temporal += "</span>";
break;
//文字列は終了→以降エラー
case single_string:
case double_string:
text_control = error_text;
Temporal = languageList.js.highlighting( Temporal ) + "</span><span class=\"mistake\">";
break;
//その他は続ける
default:
break;
}
//
Translate += Temporal + "</li>" + ruler.count();
//
Temporal = "";
//複数行のみ特別に処理
if( text_control == multi_comment )
{
Translate += "<span class=\"MultiComment\">"
//複数行継続
diplo++;
}
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//{〜}の処理
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//■開始
else if( Temporal.lastStringIs( "{" ) && text_control == plain_text )
{
//キーワード強調
Translate += languageList.js.highlighting( Temporal );
//
Temporal = "";
}
//■終了
else if( Temporal.lastStringIs( "}" ) && text_control == plain_text )
{
//キーワード強調
Translate += languageList.js.highlighting( Temporal );
//
Temporal = "";
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//コメント,文字列の処理
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//■複数行コメント開始
else if( Temporal.lastStringIs( "/*" ) && text_control == plain_text )
{
//フラグ設定ON
text_control = multi_comment;
//キーワード強調
Translate += languageList.js.highlighting( Temporal.substring( 0, Temporal.length-"/*".length ) ) + "<span class=\"MultiComment\">" + "/*";
//
Temporal = "";
//複数行開始
diplo = 1;
}
//複数行コメント終了
else if( Temporal.lastStringIs( "*/" ) )
{
//通常
if( text_control == multi_comment )
{
//フラグ設定OFF
text_control = plain_text;
//コメント強調終了
Translate += Temporal + "</span>";
//
Temporal = "";
//複数行終了
var aa = $( "line_" + ( ruler.get() - diplo ) );
//複数行終了
diplo = 0;
}
//例外
else if( text_control == plain_text )
{
//コメント強調終了
text_control = error_text;
//
Translate += languageList.js.highlighting( Temporal ) + "</span><span class=\"ErrorString\">";
//
Temporal = "";
}
}
//単一行コメント開始
else if( Temporal.lastStringIs( "//" ) && text_control == plain_text )
{
//フラグ設定ON
text_control = unity_comment;
//キーワード強調
Translate += languageList.js.highlighting( Temporal.substring( 0, Temporal.length-"//".length ) ) + "<span class=\"UnityComment\">" + "//";
//
Temporal = "";
}
//文字列1
else if( Temporal.lastStringIs( "\'" ) )
{
//開始
if( text_control == plain_text )
{
//フラグ設定ON
text_control = single_string;
//キーワード強調
Translate += languageList.js.highlighting( Temporal.substring( 0, Temporal.length-"\'".length ) ) + "<span class=\"SingleString\">" + "\'";
//
Temporal = "";
}
//終了
else if( text_control == single_string )
{
//フラグ設定OFF
text_control = plain_text;
//文字列強調終了
Translate += Temporal + "</span>";
//
Temporal = "";
}
}
//文字列2
else if( Temporal.lastStringIs( "\"" ) )
{
//開始
if( text_control == plain_text )
{
//フラグ設定ON
text_control = double_string;
//キーワード強調
Translate += languageList.js.highlighting( Temporal.substring( 0, Temporal.length-"\"".length ) ) + "<span class=\"DoubleString\">" + "\"";
//
Temporal = "";
}
//終了
else if( text_control == double_string )
{
//フラグ設定OFF
text_control = plain_text;
//文字列強調終了
Translate += Temporal + "</span>";
//
Temporal = "";
}
}
}
//最終行
if( text_control == plain_text )
{
//強調開始
Translate += languageList.js.highlighting( Temporal );
//
Temporal = "";
}
else
{
//強調終了
Translate += Temporal + "</span>";
//
Temporal = "";
}
//強調後のテキストを表示
elements[num].innerHTML = Translate + "</li></ol>";
}
}
}