「Web AI」用のサイトを作っている際に作成した、JavaScriptドキュメント作成ツールです(「Web AI」は、クロノス・クラウンの柳井政和が開発しているJavaScirptのライブラリです)。
「easyJsDoc」は、ドキュメント作成ツールですが、JavaScriptを実際に解析しているわけではないです。コメント部分を読んで、単にそのコメントを抜き出して整形しているだけです。そのため、ドキュメント用の記述は、あらかじめ書き手が全て記述しておく必要があります。
あまり役に立たなさそうなツールですが、必要な人もいるかと思い、一応公開しておきます。
それでは以下、「easyJsDoc」になります。
解析のために読み込む範囲は、「/**~*/」になります。
/** * * この部分を読み込みます。 * */
以下、利用できる「@~」記述です。
| @access | スコープ | 値は「public」か「private」。デフォルトは「public」。 |
| @variable | 変数 | オブジェクトのパス「hoge.hoge」で記述。関数は「hoge.hoge()」。 |
| @title | タイトル | 日本語でオブジェクトの短い説明を記述。 |
| @description | 説明 | 長文で説明。2つ以上の改行が間にある場合は「<br><br>」が挿入される。 |
| @param | 引数 | 引数名と説明をタブ区切りで記述。 |
| @return | 戻り値 | 戻り値の内容を記述。 |
以下、例です。
/**
* @variable crocro.getPrm
* @title 値の取得
* @description 説明1行目
* 説明2行目
* 説明3行目
* @param arg1 引数1
* @param arg2 引数2
* @return 取得した値
*/
this.getPrm = function() {
}
/**
* @access private
* @variable crocro.getPrmIn
* @title 値の取得
* @description 説明1行目
* 説明2行目
* 説明3行目
* @param arg1 引数1
* @param arg2 引数2
* @return 取得した値
*/
var getPrmIn = function() {
}
以下、CSSのサンプルです。
/* for easyJsDoc */
/* contents */
.ejd_out_cntnts {
line-height: 150%;
border: solid 2px silver;
margin-bottom: 24px;
padding: 12px;
font-size: 120%;
font-family: monospace;
border-collapse: separate;
border-spacing: 0px;
}
.ejd_out_cntnts_public {
background: #DFEFFF;
}
.ejd_out_cntnts_private {
background: #DFDFDF;
}
.ejd_out_cntnts td {
border: solid 1px silver;
padding: 4px;
}
.ejd_cntnts_access {
font-size: 80%;
}
.ejd_cntnts_link {
word-break: break-all;
}
.ejd_cntnts_title {
font-size: 80%;
}
/* data */
.ejd_out {
border: solid 2px silver;
margin-bottom: 24px;
padding: 12px;
}
.ejd_access {
margin-bottom: 4px;
}
.ejd_variable {
margin-bottom: 12px;
font-size: 150%;
background: #9FCFFF;
padding: 6px;
}
.ejd_variable_private {
background: #9F9F9F;
}
.ejd_title {
margin-bottom: 16px;
margin-left: 18px;
font-size: 120%;
font-weight: bold;
background: #BFDFFF;
padding: 6px;
}
.ejd_title_private {
background: #DFDFDF;
}
.ejd_description {
margin-bottom: 8px;
margin-left: 32px;
font-size: 100%;
line-height: 150%
}
.ejd_param {
margin-bottom: 8px;
margin-left: 64px;
font-size: 100%;
font-family: monospace;
}
.ejd_return {
margin-bottom: 8px;
margin-left: 64px;
font-size: 100%;
font-family: monospace;
}
以下、ソースコードです。
/* easyJsDoc <http://crocro.com/>
is released under the MIT License <http://www.opensource.org/licenses/mit-license.php>
in a Japanese translation <http://sourceforge.jp/projects/opensource/wiki/licenses%2FMIT_license>
Copyright (c) 2010 Masakazu Yanai / (c) 2010 Cronus Crown <webmaster@crocro.com>
*/
/**
* @variable clsHdr
* @title クラスの頭に付ける文字
* @description
*
* スタイルシートの頭に付ける文字列。
*/
var clsHdr = "ejd_"; // クラスの頭に付ける文字
/**
* @variable mkDoc()
* @title ドキュメント作成
* @description
*
* ソースコードのコメントを読んで、ドキュメントを作成する。
*
* @param srcCoder ソースコード
* @return なし。
*/
function mkDoc(srcCode) {
// 変数の初期化
var resHtml = "";
var cntntsArr = [];
// 該当箇所の抜き出し
var cmntArr = srcCode.match(/\/\*\*[\s\S]+?\*\//g) || [];
// 該当箇所から内容配列を構築
var datArr = [];
for (var i = 0; i < cmntArr.length; i ++) {
// コメントの整形
var cmnt = cmntArr[i];
cmnt = cmnt
.replace(/\/\*\*/, "")
.replace(/\*\//, "")
.replace(/^[ \t]*?\*/gm, "")
.replace(/^[ \t]*/gm, "")
// コメントの分解
var dat = [];
cmnt.replace(
/@([a-zA-Z]+)[ \t\n]+?([\s\S]+?)(?=@|$)/g,
function(str, key, bdy){
var d = {key : key, bdy : bdy};
d.bdy = d.bdy
.replace(/^[ \t]*/gm, "")
.replace(/\n{2,}/g, "<br><br>")
.replace(/\n/g, "");
dat.push(d);
}
);
datArr.push(dat);
}
// 出力用のHTMLを作成
var b = function(n){
var s = " ";
var res = "";
for (var i = 0; i < n; i ++) res += s;
return res;
}
for (var i = 0; i < datArr.length; i ++) {
// パラメータの最大長を判定
var prmBsLen = 2;
for (var j = 0; j < datArr[i].length; j ++) {
if (datArr[i][j]["key"] == "param") {
var bdy = datArr[i][j]["bdy"];
bdy = bdy.replace(/([^ \t]+)[ \t]*/, function(str, s1) {
if (s1.length + 2 > prmBsLen) prmBsLen = s1.length + 2;
return str;
});
}
}
// スコープの確認
var acs = "";
for (var j = 0; j < datArr[i].length; j ++) {
var key = datArr[i][j]["key"];
var bdy = datArr[i][j]["bdy"];
if (key == "access" && bdy == "private") {
acs = "private";
}
}
if (acs == "") {
acs = "public";
var dat = {key : "access", bdy : acs};
datArr[i].unshift(dat);
}
// 出力文字列の作成
var oneHtml = "";
var variable = "";
var title = "";
for (var j = 0; j < datArr[i].length; j ++) {
// 変数の初期化
var key = datArr[i][j]["key"];
var bdy = datArr[i][j]["bdy"];
var cls = key;
// 加工処理
if (key == "param" || key == "param") {
bdy = bdy.replace(/([^ \t]+)[ \t]*/, function(str, s1) {
var len = prmBsLen - s1.length;
return s1 + b(len);
});
bdy = key + b(3) + bdy;
}
if (key == "return") {
bdy = key + b(2) + bdy;
}
if (key == "variable") {
variable = bdy;
if (acs == "private") cls += " " + clsHdr + cls + "_private";
}
if (key == "title") {
title = bdy;
if (acs == "private") {
cls += " " + clsHdr + cls + "_private";
}
}
// 結果を連結
oneHtml += mkDiv(cls, bdy);
}
// リンクの追加
var cANameStr = '<a name="' + variable + '">';
var cLnkStr = '<span class="ejd_cntnts_link">'
+ '<a href="#' + variable + '">'
+ variable.replace(/\./g, "<wbr>.").replace(/\(/g, "<wbr>(")
+ '</a></span>';
var cTtlStr = '<span class="ejd_cntnts_title">' + title + '</span>';
var cAcsStr = '<span class="ejd_cntnts_access">' + acs + '</span>';
// 目次の作成
if (variable != "") {
cntntsArr.push({access : cAcsStr, name : variable,
link : cLnkStr, title : cTtlStr});
}
// 結果の連結
oneHtml = mkDiv("out", oneHtml);
resHtml += cANameStr + oneHtml;
}
// 目次のHTMLを作成
var publicCArr = [];
var privateCArr = [];
for (var i = 0; i < cntntsArr.length; i ++) {
var cntnts = cntntsArr[i];
if (cntnts.access.indexOf("public") >= 0) {
publicCArr.push(cntnts);
} else {
privateCArr.push(cntnts);
}
}
var publicCStr = publicCArr.length > 0
? mkCntnts(publicCArr, clsHdr + "out_cntnts_public") : "";
var privateCStr = privateCArr.length > 0
? mkCntnts(privateCArr, clsHdr + "out_cntnts_private") : "";
resHtml = publicCStr + privateCStr + resHtml;
// 結果の出力
$("#resHtml").val(resHtml);
$("#vwSmpl").html(resHtml);
}
/**
* @variable mkCntnts(cntntsArr)
* @title 目次HTML作成
* @description
*
* 目次のHTMLを作成する。
*
* @param cntntsArr 目次の配列。
* @param addClsStr 追加クラス文字列。
* @return 作成したHTML文字列。
*/
function mkCntnts(cntntsArr, addClsStr) {
// 目次のHTMLを作成
var cntntsStr = "";
for (var i = 0; i < cntntsArr.length; i ++) {
var cntnts = cntntsArr[i];
var str
= mkTag("td", "", cntnts.access)
+ mkTag("td", "", cntnts.link)
+ mkTag("td", "", cntnts.title)
cntntsStr += mkTag("tr", "", str);
}
cntntsStr = mkTag("table", "out_cntnts " + addClsStr, cntntsStr);
return cntntsStr;
}
/**
* @variable mkDiv(clsStr, inStr)
* @title divタグ作成
* @description
*
* divタグを作成する。
*
* @param clsStr クラス文字列。
* @param inStr HTML内部に追加する文字列。
* @return 作成したdivタグのHTML文字列。
*/
function mkDiv(clsStr, inStr) {
return '<div class="' + clsHdr + clsStr + '">' + inStr + '</div>';
}
/**
* @variable mkTag(tagStr, clsStr, inStr)
* @title タグ作成
* @description
*
* タグを作成する。
*
* @param tagSt タグ文字列。
* @param clsStr クラス文字列。
* @param inStr HTML内部に追加する文字列。
* @return 作成したタグのHTML文字列。
*/
function mkTag(tagStr, clsStr, inStr) {
return '<' + tagStr + ' class="' + clsHdr + clsStr + '">'
+ inStr + '</' + tagStr + '>';
}