SourceToHTML にGUIを
「SourceToHTML」と「SourceToRTF」をマージし、
また、"HTA"によるユーザーインターフェースを持たせました。
以下は、「SourceToHtml」の本体です。
.\library\SourceToHtml.js (3/3)
//=============================================================================
// 予約語一覧を取得する
//=============================================================================
function getKeywordList()
{
_convert.keyword = new Array();// 予約語一覧
_convert.keyword[0] = new Object();// 強調表示 一覧
_convert.keyword[1] = new Object();
_convert.keyword[2] = new Object();
_convert.keyword[3] = new Object();var keyFileName = "";
for (var i=0;i<4;i++)
{
// 予約語・強調表示 一覧ファイル名
if (i == 0)
keyFileName = ".\\application\\" + _arg.langType + ".key";
else
keyFileName = ".\\application\\" + _arg.langType + ".sp" + i;// ファイルがなければ、何もしない
if (!_fs.FileExists(keyFileName)) continue;// 予約語一覧ファイルを 読み込み専用モードで 開く
var tsKeyword = _fs.OpenTextFile(keyFileName, 1);
while (!tsKeyword.AtEndOfStream)
{
var s = tsKeyword.ReadLine();// 大文字・小文字を区別しない → 予約語を小文字に変換して登録する
if (_convert.ignoreCase) _convert.keyword[i]['"' + s.toLowerCase() + '"'] = s;
// 大文字・小文字を区別する → 予約語をそのまま登録する
else _convert.keyword[i]['"' + s + '"'] = s;// ↑ 何故か toString が登録されるので、" で囲む
}
tsKeyword.Close();
}
}
//-----------------------------------------------------------------------------
// 予約語か? (大文字・小文字を区別する)
//-----------------------------------------------------------------------------
function getKeywordCase(idx, value)
{
// 予約語一覧に登録されていれば、予約語を返す
return (_convert.keyword[idx][value]);
}
//-----------------------------------------------------------------------------
// 予約語か? (大文字・小文字を区別しない)
//-----------------------------------------------------------------------------
function getKeywordIgnoreCase(idx, value)
{
// 予約語一覧に登録されていれば、予約語を返す
return (_convert.keyword[idx][value.toLowerCase()]);
}
//-----------------------------------------------------------------------------
// その「識別子」は、「予約語」か? または「強調表示」対象か?
//-----------------------------------------------------------------------------
function toEmphasis(context)
{
// その「識別子」は、「予約語」か?
for (var i=0;i<4;i++)
{
// 例えば、VB の 「MyBase.New()」 という文の
// 「New」 は、予約語として表示したくないので。。。
if ((i == 0) && (context.prevToken.charAt(context.prevToken.length - 1) == ".")) continue;var s = _convert.getKeyword(i, '"' + context.token + '"');
// ↑ 何故か toString が登録されるので、" で囲んである
if (s)
{
context.token = s;if (i == 0)
context.type = "予約語";
else
context.type = "強調表示" + i;break;
}
}
}
//*****************************************************************************
// プログラムソース を 出力
//*****************************************************************************
function putSource(tsOut)
{
// 入力ファイルを 読み込み専用モードで 開く
var tsIn = _fs.OpenTextFile(_arg.inFileName, 1);// 文脈オブジェクト
var context = new Object();//現在の状態
context.state = "開始待ち";// 入力ファイルの終わりまで繰り返す
while (!tsIn.AtEndOfStream)
{
// 入力ファイルを 1行ずつ読む
context.value = tsIn.ReadLine();// TAB を 空白に 変換
context.value = TabToSpace(context.value);// プログラムソース を 変換して 出力
tsOut.WriteLine(_convert.ConvToHtml(context) + _convert.NewLine);
}
// 入力ファイルを 閉じる
tsIn.Close();
}
//=============================================================================
// テキスト を 変換して返す (文字のエスケ−プだけ)
//=============================================================================
function ConvToHtmlText(context)
{
// 行番号を 出力
var ret = tokenToHtml(FormatNum(++_lineNo) + _arg.lineNoDlm, "行番号");// 変換対象の文字を 変換
ret += tokenToHtml(context.value, "");return ret;
}
//=============================================================================
// プログラムソース を 変換して返す
//=============================================================================
function ConvToHtmlOther(context)
{
// 変換出力用文字列
var ret = "";// 行番号を 出力
ret = tokenToHtml(FormatNum(++_lineNo) + _arg.lineNoDlm, "行番号");// トークンを退避
context.prevToken = "";
context.prevType = "空白";// トークンの種類を クリア
if (context.state == "開始待ち")
context.type = "空白";
// トークンを クリア
context.token = "";while (context.value.length > 0)
{
if (context.state == "開始待ち")
{
var isMatch = false;for (var i=0;i<_convert.state.waitStart.length;i++)
{
// トークンの種類を判定
if (_convert.state.waitStart[i].getToken(context.value))
{
context.token = RegExp.lastMatch;
context.type = _convert.state.waitStart[i].currType;
context.state = _convert.state.waitStart[i].nextState;
context.value = RegExp.rightContext;
isMatch = true;// その「識別子」は、「予約語」か? または「強調表示」対象か?
if (context.type == "識別子") toEmphasis(context);// 終了判定用関数を 割り当て
if (context.state == "終了待ち")
context.getTerm = _convert.state.waitStart[i].getTerm;break;
}
}
// 2 Byte文字 なら
if (!isMatch)
{
context.token = context.value.charAt(0);
context.type = (_convert.useMultiByte ? "識別子" : "不正な文字");
context.state = "開始待ち";
context.value = context.value.substring(1);
}
}
else // 終了待ち
{
// 終了?
if (context.getTerm(context.value))
{
context.token = RegExp.lastMatch;
context.state = "開始待ち";
context.value = RegExp.rightContext;
}
else // まだ、次の行に続く...
{
context.token = context.value;
context.state = "終了待ち";
context.value = "";
}
}
// トークンの種類が変わったら
if (context.prevType != context.type)
{
// トークンを出力
ret += tokenToHtml(context.prevToken, context.prevType);
context.prevToken = context.token;
}
else
{
context.prevToken += context.token;
}
context.prevType = context.type;
}
// トークンを出力
ret += tokenToHtml(context.prevToken, context.prevType);return ret;
}
//-----------------------------------------------------------------------------
// 数値の書式化 (例: 123 → "00123")
//-----------------------------------------------------------------------------
function FormatNum(num)
{
var s = "0000000000" + num;
return (s.substring(s.length - _arg.lineNoLen));
}
//=============================================================================
// トークンに TAG を付けて 返す
//=============================================================================
function tokenToHtml(token, type)
{
if (token.length < 1) return "";// 変換出力用文字列
var ret = "";// 1文字ずつ処理する
for (var i=0;i<token.length;i++)
{
// 1文字取り出す
var c = token.charAt(i);// 変換対象の文字なら、変換して出力 ( "0" → "0" )
if (_arg.escapeChar.indexOf(c) >= 0)
ret += _convert.getEscapeChar(c);// それ以外なら、そのまま出力
else
ret += c;
}// タグで囲む
for (var i=1;i<13;i++)
{
if ((type == _arg.Emphasis[i].Name)
&& (_arg.Emphasis[i].FontEnabled || _arg.Emphasis[i].BackEnabled))
return _arg.Emphasis[i].Begin + ret + _arg.Emphasis[i].End;
}
// 変換しなかった場合
return ret;
}
//-----------------------------------------------------------------------------
// 変換対象の文字を、変換して返す
//-----------------------------------------------------------------------------
function getEscapeCharHtml(arg)
{
return "&#x" + arg.charCodeAt(0).toString(16) + ";";
}
function getEscapeCharRtf(arg)
{
return "\\" + arg;
}
//*****************************************************************************
// 色の指定 (HTML 専用)
//*****************************************************************************
function putColorCss(tsOut)
{
// 出力文字列
var ret = "";// 基本色の指定
ret = "PRE {";
ret += "color:#" + _arg.Emphasis[0].FontColor + ";";
ret += "background-color:#" + _arg.Emphasis[0].BackColor + ";";
ret += "}";
tsOut.WriteLine(ret);// 各表示項目の指定
for (var i=1;i<13;i++)
{
// 無効
if (!_arg.Emphasis[i].FontEnabled && !_arg.Emphasis[i].BackEnabled) continue;ret = "PRE SPAN." + _arg.Emphasis[i].Class + "{";
// 文字
if (_arg.Emphasis[i].FontEnabled)
{
// 文字色
if (_arg.Emphasis[i].FontColor != _arg.Emphasis[0].FontColor)
ret += "color:#" + _arg.Emphasis[i].FontColor + ";";// 太字
if (_arg.Emphasis[i].Bold)
ret += "font-weight:bold;";// 斜体
if (_arg.Emphasis[i].Italic)
ret += "font-style:italic;";// 下線
if (_arg.Emphasis[i].UnderLine)
ret += "text-decoration:underline;";
}// 背景
if (_arg.Emphasis[i].BackEnabled)
{
// 背景色
if (_arg.Emphasis[i].BackColor != _arg.Emphasis[0].BackColor)
ret += "background-color:#" + _arg.Emphasis[i].BackColor + ";";
}ret += "}";
tsOut.WriteLine(ret);// HTML の 指定
_arg.Emphasis[i].Begin = '<SPAN CLASS="' + _arg.Emphasis[i].Class + '">';
_arg.Emphasis[i].End = '</SPAN>';
}
}
//*****************************************************************************
// 色の指定 (RTF 専用)
//*****************************************************************************
function putColorRtf(tsOut)
{
// 出力文字列
var ret = "";// 各表示項目の指定
for (var i=1;i<13;i++)
{
// 無効
if (!_arg.Emphasis[i].FontEnabled && !_arg.Emphasis[i].BackEnabled) continue;// COLOR TABLE の 指定 (文字色)
var r = _arg.Emphasis[i].FontColor.substr(0, 2)
var g = _arg.Emphasis[i].FontColor.substr(2, 2);
var b = _arg.Emphasis[i].FontColor.substr(4, 2);
tsOut.WriteLine("\\red" + parseInt(r, 16) + "\\green" + parseInt(g, 16) + "\\blue" + parseInt(b, 16) + ";");// COLOR TABLE の 指定 (背景色)
r = _arg.Emphasis[i].BackColor.substr(0, 2)
g = _arg.Emphasis[i].BackColor.substr(2, 2);
b = _arg.Emphasis[i].BackColor.substr(4, 2);
tsOut.WriteLine("\\red" + parseInt(r, 16) + "\\green" + parseInt(g, 16) + "\\blue" + parseInt(b, 16) + ";");// 各要素ごとの 指定 (開始タグ)
ret = "";// 文字
if (_arg.Emphasis[i].FontEnabled)
{
// 文字色
if (_arg.Emphasis[i].FontColor != _arg.Emphasis[0].FontColor)
ret += "\\cf" + ((i - 1) * 2 + 1).toString() + " ";// 太字
if (_arg.Emphasis[i].Bold)
ret += "\\b ";// 斜体
if (_arg.Emphasis[i].Italic)
ret += "\\i ";// 下線
if (_arg.Emphasis[i].UnderLine)
ret += "\\ul ";
}// 背景
if (_arg.Emphasis[i].BackEnabled)
{
// 背景色
if (_arg.Emphasis[i].BackColor != _arg.Emphasis[0].BackColor)
ret += "\\highlight" + ((i - 1) * 2 + 2).toString() + " ";
}_arg.Emphasis[i].Begin = ret;
// 各要素ごとの 指定 (終了タグ)
ret = "";// 背景
if (_arg.Emphasis[i].BackEnabled)
{
// 背景色
if (_arg.Emphasis[i].BackColor != _arg.Emphasis[0].BackColor)
ret += "\\highlight0 ";
}// 文字
if (_arg.Emphasis[i].FontEnabled)
{
// 下線
if (_arg.Emphasis[i].UnderLine)
ret += "\\ulnone ";// 斜体
if (_arg.Emphasis[i].Italic)
ret += "\\i0 ";// 太字
if (_arg.Emphasis[i].Bold)
ret += "\\b0 ";
// 文字色
if (_arg.Emphasis[i].FontColor != _arg.Emphasis[0].FontColor)
ret += "\\cf0 ";
}_arg.Emphasis[i].End = ret;
}
}
//*****************************************************************************
// TAB を 空白に 変換
//*****************************************************************************
function TabToSpace(arg)
{
// 変換出力用文字列
var ret = "";// 現在位置
var pos = 0;// 1文字ずつ処理する
for (var i=0;i<arg.length;i++)
{
// 1文字取り出す
var c = arg.charAt(i);// TAB か?
if (c == "\t")
{
// 空白何文字分に置き換えればよいか
var num = 4 - (pos % 4);
// 現在位置を加算
pos += num;
// 変換して出力
ret += " ".substr(0, num);
}
else
{
// 現在位置を加算
if (escape(c).length < 4)
pos++;
else
pos += 2;
// そのまま出力
ret += c;
}
}//行末の空白を削除
return ret.replace(/ +$/,"");
}