【JavaScript】クライアントサイドWiki(PukiWiki風) その4  CSV形式の表組みルール追加、整形ルール見直し

プログラミング・Web開発カテゴリを表すパンダのイラスト プログラミング・Web開発

仕事柄、ExcelやAccessのような表形式データを使うことが多いので、この機能は追加しておきたかった項目です。
簡易版ですが十分使えるので満足しています。

<meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
<HTML lang="ja">
<head>
<script>

//グローバル変数を設定
var fso = new ActiveXObject("Scripting.FileSystemObject");
var oBaseFolder = getBaseFolder();

//このHTMLファイルが置かれているフォルダのパス名を取得する
function getBaseFolder(){
    var FullPath = location.href.replace(/file:\/\/\//, "").replace(/file:\/\//,"//").replace(/%20/g, " ");

    if(fso.fileExists(FullPath)){
        var thisFile = fso.getFile(FullPath);
    }else{
        alert('File not Exists:' + FullPath);
    }

    return thisFile.parentFolder;
}

//ページ名を指定してページを開く
function open(pagename){
    var content = getContent(pagename);
    if(! content){
        return edit(pagename);
    }

    //1行毎に分割してWiki用に整形
    var list = content.replace(/[\n\r][\n\r]?/g, "\n").split("\n");
    var html = '<pre>'

    //true:前行がマッチしていた false:前行がマッチしていない
    var matched = false;
    for (var i = 0; i < list.length; i++){
        //カンマ区切りのデータ(,A,B,C)をテーブル表示 複数行にも対応
        if (list[i].match(/(^,.*)/)){
            var resArray = list[i].split(",");
            list[i] = "";

            if (matched == false){
                //前回の行が、テーブル整形ルールにマッチしていなかった。新規のテーブルと判断し<table>ヘッダを付与。
                list[i] += "<table border='1' cellspacing='0' id='tbl'><tr>"
            }

            //テーブルに要素を詰める。
            for (var j = 1; j < resArray.length; j++){
                list[i] += "<td>" + resArray[j] + "</td>";
            }
            list[i] += "</tr>";
            
            //整形ルールにマッチしていたため、フラグをたてる。
            matched = true;
        }else{
            if ( matched == true ) {
                matched = false;
                html += "</table>"
            }
        }
        html += convert(list[i]);
        html += "\n";
    }
    html = html + '</pre>';

    //ファイル名、更新日時等を付与
    html = html + getDateCreated(pagename);

    setPageName(pagename);
    setContent(html);
    showEditLink();
}

//ファイルの更新日時を取得する
function getDateCreated(pagename){
    var s = '';
    var filepath = getFilePath(pagename);

    f = fso.GetFile(filepath);
    s = f.Path.toUpperCase() + "<BR>";
    s += "作成日時:" + f.DateCreated;
    s += "  最終更新日時: " + f.DateLastModified;
    return(s);
}

//日時を取得する
function getDate(){
    var content = '';
    DD = new Date();
    Year = DD.getYear();
    Month = DD.getMonth() + 1;
    Day = DD.getDate();

    return Year + "年" + Month + "月" + Day + "日";
}

function convert(content){
    if (content.match(/(^ .*)/)) {
        content = content.replace(/(^ .*)/mg,"<pre>$1</pre>");
    } else {
        if (content.match(/(\[\[.*)/)) {
            var pattern = /\[\[([-_.!~*'()a-zA-Z0-9;\/?:\@&=+\$,%#]+\.(gif|jpe?g|png|bmp))\]\]/ig;
            content = content.replace(pattern, "<img src='$1'>");

            content = content.replace(/\[\[(\S+?)>(\S+?)\]\]/ig, "<a href=\"$2\" target=\"_blank\" > $1 </a>");
            content = content.replace(/\[\[((http|https).+)\]\]/ig, "<a href=\"$1\" target=\"_blank\" > $1 </a>");
            content = content.replace(/\[\[(\S+?)>(\\\\.+)\]\]/ig, "<a href=\"$2\" target=\"_blank\" > $1 </a>");
            content = content.replace(/\[\[(\\\\.+)\]\]/ig, "<a href=\"$1\" target=\"_blank\" > $1 </a>");
            content = content.replace(/\[\[([^\]\]ihf]+)\]\]/g, "<a href='javascript:open(\"$1\")'>$1</a>");
        } else {
            content = content.replace( /(((mailto|http|https|ftp):([^\x00-\x20()<>\x7F-\xFF])*))/g, "<a href=\"$1\" target=\"_blank\" > $1 </a>")
        }
        content = content.replace(/COLOR\(([^\(\)]*)\){([^}]*)}/g,"<span style=\"color:$1\">$2</span>");
        content = content.replace(/SIZE\(([^\(\)]*)\){([^}]*)}/g,"<span style=\"font-size:$1px\">$2</span>");
        content = content.replace(/COLOR\(([^\(\)]*)\):((?:(?!COLOR\([^\)]+\)\:).)*)/ig,"<span style=\"color:$1\">$2</span>");
        content = content.replace(/SIZE\(([^\(\)]*)\):((?:(?!SIZE\([^\)]+\)\:).)*)/ig,"<span class=\"size$1\">$2</span>");
        content = content.replace(/%%%(?!%)((?:(?!%%%).)*)%%%?/ig,"<ins>$1</ins>");
        content = content.replace(/%%(?!%)((?:(?!%%).)*)%%/g,"<del>$1</del>");
        content = content.replace(/'''(?!')((?:(?!''').)*)'''/g,"<em>$1</em>");
        content = content.replace(/''(?!')((?:(?!'').)*)''/g,"<strong>$1</strong>");

        content = content.replace(/(\*\*\*)(.*)/g,"<h4>$2</h4>");
        content = content.replace(/(\*\*)(.*)/g,"<h3>$2</h3>");
        content = content.replace(/(\*)(.*)/g,"<h2>$2</h2>");
    }
    return content;
}

function edit(pagename){
    var content = getContent(pagename);
    var html =
           "<form  onsubmit='save(\"" + pagename + "\"); return false;'>"
         + "<textarea cols='120' rows='30' id='textarea' wrap='off'>" + content + "</textarea><br />"
         + "<input type='submit' value='保存'><br />"
         + "</form>";

    setPageName(pagename);
    setContent(html);
    hideEditLink();
}

function editCurrentPage(){
    pagename = id('headerH1').innerText;
    edit(pagename);
}

function save(pagename){
    var content = id('textarea').value;
    var filepath = getFilePath(pagename);
    var file = fso.createTextFile(filepath);
    file.write(content);
    file.Close();
    open(pagename);
}

function openIndexPage(){
    var enuFiles = new Enumerator(oBaseFolder.Files);
    var myFiles = [];
    for (; !enuFiles.atEnd(); enuFiles.moveNext() ){ 
        var FilePath = enuFiles.item(); 
        var ExtensionName = fso.GetExtensionName(FilePath);
        var BaseName = fso.GetBaseName(FilePath);
        if(ExtensionName == "txt"){
            myFiles.push(BaseName);
        }
    } 

    var list = [];
    for(var i = 0; i < myFiles.length; i++){
        list.push('<li><a href="javascript:open(\'' + myFiles[i] + '\');">' + myFiles[i] + '</a></li>');
    }

    var content = list.join("\n");
    setPageName('ページ一覧');
    setContent('<pre>' + content + '</pre>');
    hideEditLink();
}

function getFilePath(pagename){
    var filename = pagename + ".txt";
    return oBaseFolder.Path + "\\\\" + filename;
}

function getContent(pagename){
    var content = '';
    var filepath = getFilePath(pagename);

    if(fso.fileExists(filepath)){
        var file = fso.openTextFile(filepath);
        if(! file.atEndOfStream){
            content = file.readAll();
        }
        file.Close();
    }
    return content;
}

function showEditLink() {
    id('editLink').style.display = "inline";
}

function hideEditLink() {
    id('editLink').style.display = "none";
}

function setContent(html) {
    id('content').innerHTML = html;
}

function setPageName(pagename) {
    if(pagename){
        id('headerH1').innerText = pagename;
    }
}

function id(s) {
    return document.getElementById(s);
}

function FindIndexPage() {
    var enuFiles = new Enumerator(oBaseFolder.Files);
    var myFiles = [];
    for (; !enuFiles.atEnd(); enuFiles.moveNext()) {
        var FilePath = enuFiles.item();
        var ExtensionName = fso.GetExtensionName(FilePath);
        var BaseName = fso.GetBaseName(FilePath);

        if (ExtensionName == "txt") {
            var database = FilePath;
            var sword = Text1.value;
            var check = BaseName.indexOf(sword, 0);
            if (0 <= check) {
                myFiles.push(BaseName);
            } else {
                if (0 <= openAndSerch(BaseName)) {
                    myFiles.push(BaseName);
                }
            }
        }
    }
    
    var list = [];
    for (var i = 0; i < myFiles.length; i++) {
        list.push('<li><a href="javascript:open(\'' + myFiles[i] + '\');">' + myFiles[i] + '</a></li>');
    }

    var content = list.join("\n");
    setPageName('検索結果:' + Text1.value);
    setContent('<pre>' + content + '</pre>');
    hideEditLink();
}

function openAndSerch(pagename) {
    var content = getContent(pagename);
    if (!content) {
        return edit(pagename);
    }
    var database = content;
    var sword = Text1.value;
    var check = database.indexOf(sword, 0);
    return check;
}

</script>

<style type="text/css">
    #Text1 {
        width: 79px;
    }
    .style1 {
        width: 464px;
    }
    h2 {
        font-family: verdana, arial, helvetica, Sans-Serif;
        color: inherit;
        background-color: #DDEEFF;
        padding: .3em;
        border: 0px;
        margin: 0px 0px .5em 0px;
    }
    h3 {
        font-family: verdana, arial, helvetica, Sans-Serif;
        border-bottom: 3px solid #DDEEFF;
        border-top: 1px solid #DDEEFF;
        border-left: 10px solid #DDEEFF;
        border-right: 5px solid #DDEEFF;
        color: inherit;
        background-color: #FFFFFF;
        padding: .3em;
        margin: 0px 0px .5em 0px;
    }
    h4 {
        font-family: verdana, arial, helvetica, Sans-Serif;
        border-left: 18px solid #DDEEFF;
        color: inherit;
        background-color: #FFFFFF;
        padding: .3em;
        margin: 0px 0px .5em 0px;
    }
    pre {
        border-top: #DDDDEE 1px solid;
        border-bottom: #888899 1px solid;
        border-left: #DDDDEE 1px solid;
        border-right: #888899 1px solid;
        padding: .5em;
        margin-left: 1em;
        margin-right: 2em;
    }
    #headerH1 {
        width: 500px;
    }
</style>
</head>
<body onload="javascript:open('トップページ')">
    <table width="100%" border="0">
        <tr valign="top">
            <td class="style1">
                <h1 id="headerH1">トップページ</h1>
            </td>
            <td align="right">
                <a href="javascript:open('トップページ')">トップページ</a> | 
                <span id="editLink"><a href="javascript:editCurrentPage()">編集</a> | </span>
                <a href="javascript:openIndexPage()">ページ一覧</a> | 
                <input id="Text1" type="text" /> <a href="javascript:FindIndexPage()">検索</a>&nbsp; 
            </td>
        </tr>
    </table>
    <hr id="br1" />
    <div id="content"></div>
</body>
</html>

この記事の更新履歴

この記事は、生成AIを活用した自動レビュー・更新フローにより内容を見直し、必要な修正を反映しています。

2026年9月11日

  • 変更破損していたコード内のHTML自動リンクタグを修正し、コードブロックで整形しました。

文書情報

記事タイトル
【JavaScript】クライアントサイドWiki(PukiWiki風) その4  CSV形式の表組みルール追加、整形ルール見直し
作成日
更新日
Source URL
https://papanda925.com/?p=433

ライセンス: 本記事のうち、当サイトが権利を有する本文・自作図表は、特記なき限り CC BY 4.0 で利用できます。生成AIを活用して作成・編集した内容を含みます。コードについて、別途ライセンス表示またはリンク先GitHubリポジトリのライセンスがある場合は、その条件を優先します。引用・第三者資料・画像・商標等は本ライセンスの対象外です。 利用ポリシー

タイトルとURLをコピーしました