「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 + '>'; }