ラベル HHXモジュールの利用 の投稿を表示しています。 すべての投稿を表示
ラベル HHXモジュールの利用 の投稿を表示しています。 すべての投稿を表示

2007年9月9日日曜日

HSPスクリプトビューワ(Footy2)

Footy2とHHXモジュールによるスクリプトビューワ。機能は読み込みのみで、保存さえできません(^-^;

私がプログラミングを始めたころはリッチテキストを扱うなんてまさに雲の上のお話だったのですが、なべしんさんのおかげでとても簡単になりました。ちょっと信じ難いくらいお手軽です。

それとヘッダファイルFooty2.asを作成したので、なべしんさんの許可が降りたら公開したいと思います。
#include "../hsphelp/src/hhx_db.hsp"
#uselib "Footy2.dll"
#func Footy2Create "Footy2Create" int, int, int, int, int, int
#func Footy2Delete "Footy2Delete" int
#func Footy2TextFromFile "Footy2TextFromFileA" int, sptr, int
#func Footy2AddEmphasis "Footy2AddEmphasisA" int, sptr, sptr, int, int, int, int, int, int
#func Footy2FlushEmphasis "Footy2FlushEmphasis" int
// 独立レベル
/*ASCII記号用フラグ*/
#define global EMP_IND_PARENTHESIS 0x00000001//!< 前後に丸括弧()があることを許可する
#define global EMP_IND_BRACE 0x00000002//!< 前後に中括弧{}があることを許可する
#define global EMP_IND_ANGLE_BRACKET 0x00000004//!< 前後に山形括弧<>があることを許可する
#define global EMP_IND_SQUARE_BRACKET 0x00000008//!< 前後に各括弧[]があることを許可する
#define global EMP_IND_QUOTATION 0x00000010//!< 前後にコーテーション'"があることを許可する
#define global EMP_IND_UNDERBAR 0x00000020//!< 前後にアンダーバー_があることを許可する
#define global EMP_IND_OPERATORS 0x00000040//!< 前後に演算子 + - * / % ^  があることを許可する
#define global EMP_IND_OTHER_ASCII_SIGN 0x00000080//!< 前述のものを除く全てのASCII記号 # ! $ & | \ @ ?  .
/*ASCII文字列を指定するフラグ*/
#define global EMP_IND_NUMBER 0x00000100//!< 前後に数字を許可する
#define global EMP_IND_CAPITAL_ALPHABET 0x00000200//!< 前後に大文字アルファベットを許可する
#define global EMP_IND_SMALL_ALPHABET 0x00000400//!< 前後に小文字アルファベットを許可する
/*空白を指定するフラグ*/
#define global EMP_IND_SPACE 0x00001000//!< 前後に半角スペースを許可する
#define global EMP_IND_FULL_SPACE 0x00002000//!< 前後に全角スペースを許可する
#define global EMP_IND_TAB 0x00004000//!< 前後にタブを許可する
/*そのほかの文字列*/
#define global EMP_IND_JAPANESE 0x00010000//!< 日本語
#define global EMP_IND_KOREAN 0x00020000//!< 韓国語
#define global EMP_IND_EASTUROPE 0x00040000//!< 東ヨーロッパ
#define global EMP_IND_OTHERS 0x80000000//!< 上記以外
/*省略形(主にこれらを使用すると指定が楽です)*/
#define global EMP_IND_ASCII_SIGN 0x000000FF//!< 全てのASCII記号列を許可する
#define global EMP_IND_ASCII_LETTER 0x00000F00//!< 全てのASCII文字を許可する(数字とアルファベット)
#define global EMP_IND_BLANKS 0x0000F000//!< 全ての空白文字列を許可する
#define global EMP_IND_OTHER_CHARSETS 0xFFFF0000//!< 全てのキャラクタセットを許可する
#define global EMP_IND_ALLOW_ALL 0xFFFFFFFF//!< 何でもOK

// キャラクタセット
#enum global CSM_AUTOMATIC = 0

// ビュー状態
#enum global VIEWMODE_NORMAL = 0

#enum global EMP_INVALIDITY = 0//!< 無効
#enum global EMP_WORD//!< 単語を強調
#enum global EMP_LINE_AFTER//!< それ以降~行末
#enum global EMP_LINE_BETWEEN//!< 二つの文字の間(同一行に限る・二つの文字列を指定)
#enum global EMP_MULTI_BETWEEN//!< 二つの文字の間(複数行にわたる・二つの文字列を指定)

// 強調表示モード
#define global EMPFLAG_BOLD   0x00000001//!< 太字にする
#define global EMPFLAG_NON_CS 0x00000002//!< 大文字と小文字を区別しない
#define global EMPFLAG_HEAD   0x00000004//!< 頭にあるときのみ

// エラー
#define global FOOTY2ERR_NONE           0   //!< 関数が成功した
#define global FOOTY2ERR_ARGUMENT       -1  //!< 引数おかしい
#define global FOOTY2ERR_NOID           -2  //!< IDが見つからない
#define global FOOTY2ERR_MEMORY         -3  //!< メモリー不足
#define global FOOTY2ERR_NOUNDO         -4  //!< アンドゥ情報がこれ以前に見つからない
#define global FOOTY2ERR_NOTSELECTED    -5  //!< 選択されていない
#define global FOOTY2ERR_UNKNOWN        -6  //!< 不明なエラー
#define global FOOTY2ERR_NOTYET         -7  //!< 未実装(ごめんなさい)
#define global FOOTY2ERR_404            -8  //!< ファイルが見つからない、検索文字列が見つからない
#define global FOOTY2ERR_NOTACTIVE      -9  //!< アクティブなビューは存在しません
#define global FOOTY2ERR_ENCODER        -10 //!< 文字コードのエンコーダが見つかりません(ファイルのエンコード形式が不正です、バイナリとか)
#define global FOOTY2ERR_NOT_SELECTING  -11 //!< 選択していない

#define COLOR_COMMENT 0xcccccc
#define COLOR_COMMAND 0xcc00cc
#define COLOR_FUNC 0xffff00
#define COLOR_PREPROCESS 0xffcc00
#define COLOR_LABEL 0xffff00
#define COLOR_SYSVAR 0xcc9900
#define COLOR_MACRO 0xcc9900
#define COLOR_STRING 0x00ccff
    title "Footytest"
    Footy2Create hwnd00ginfo_winxginfo_winyVIEWMODE_NORMAL
    if ( stat != FOOTY2ERR_NONE ) : end
    idFooty = stat

    // ファイルを読み込む
    dialog "hsp"16
    if ( stat == 0 ) : end
    fileName = refstr
    Footy2TextFromFile idFooty, fileName, CSM_AUTOMATIC
    if ( stat != FOOTY2ERR_NONE ) : end

    // hsphelpディレクトリの存在を確認
    chdir dir_exe
    dirlist s, "hsphelp"5 
    if ( stat == 0 ) : dialog "hsphelpディレクトリが見つかりません。"1 : end
    chdir dir_exe + "/hsphelp"

    // HHXのデータベースをロード
    HHX_init_load_db
    if HHX_currentset_sum() ! HHX_diskset_sum() {
        // HSファイルに何かしらの変更が加わったため、データベースを再構築
        logmes "HHXのデータベースをリビルドしています..."
        HHX_init_rebuild_db DBR_READONLY
    } else {
        HHX_init_extract_db             // 配列変数hhxdataxにメモリ上のデータをロード
    }
    logmes "HHXのデータベースをロードしました。"

    // データベースから命令・関数をひとつずつ取り出し、その名前を列挙する
    db_num = HHX_select_all()           // すべての命令・関数などを検索対象とする(ABC順)
    sdim buf, 16000
    notesel buf
    repeat db_num
        c = HHX_get_next()              // 次の命令・関数などのナンバーを取得
        db_name  = hhxdata( c, C_NAME )
        db_group = hhxdata( c, C_GROUP )
        db_prm   = hhxdata( c, C_PRM )
        if instr( db_group, 0"プリプロセッサ命令" ) >= 0 {
            ; プリプロセッサ
            Footy2AddEmphasis idFooty, db_name, 0EMP_WORD011EMP_IND_BLANKSCOLOR_PREPROCESS
        } else : if instr( db_group, 0"システム変数" ) >= 0 {
            ; システム変数
            Footy2AddEmphasis idFooty, db_name, 0EMP_WORD011EMP_IND_BLANKS | EMP_IND_PARENTHESIS | EMP_IND_OTHER_ASCII_SIGNCOLOR_SYSVAR
        } else : if instr( db_group, 0"マクロ" ) >= 0 {
            ; マクロ
            Footy2AddEmphasis idFooty, db_name, 0EMP_WORD011EMP_IND_BLANKS | EMP_IND_PARENTHESIS | EMP_IND_OTHER_ASCII_SIGNCOLOR_MACRO
        } else : if db_prm = "" {
            ; 引数なし(命令)
            Footy2AddEmphasis idFooty, db_name, 0EMP_WORD011EMP_IND_BLANKSCOLOR_COMMAND
        } else : if peek( db_prm ) = '(' {
            ; 関数型
            Footy2AddEmphasis idFooty, db_name, 0EMP_WORD011EMP_IND_BLANKS | EMP_IND_PARENTHESISCOLOR_FUNC
        } else {
            ; 命令型
            Footy2AddEmphasis idFooty, db_name, 0EMP_WORD011EMP_IND_BLANKSCOLOR_COMMAND
        }
    loop
    // そのほかの色分け
    Footy2AddEmphasis idFooty, "/*""*/"EMP_MULTI_BETWEEN011EMP_IND_ALLOW_ALLCOLOR_COMMENT
    Footy2AddEmphasis idFooty, ";"0EMP_LINE_AFTER011EMP_IND_ALLOW_ALLCOLOR_COMMENT
    Footy2AddEmphasis idFooty, "//"0EMP_LINE_AFTER011EMP_IND_ALLOW_ALLCOLOR_COMMENT
    Footy2AddEmphasis idFooty, "*"0EMP_LINE_AFTEREMPFLAG_HEAD11EMP_IND_ALLOW_ALLCOLOR_LABEL
    Footy2AddEmphasis idFooty, "{\"""\"}"EMP_MULTI_BETWEEN02, -1EMP_IND_ALLOW_ALLCOLOR_STRING

    // 色分けを反映
    Footy2FlushEmphasis idFooty

    onexit *exit
    stop
*exit
    Footy2Delete FootyID
    end

2007年8月16日木曜日

HHXモジュール 命令・関数から検索

前回はすべての命令・関数を対象としましたが、今回は特定の文字列を含む命令だけを抽出する方法を紹介します。
と言っても前回HHX_select_all()としていたところを、HHX_select_where(p1, p2, p3)とするだけです。メインの検索処理はモジュールが行ってくれます。

検索結果はキーワード適合度の高い順に並びます。検索キーワードが命令概要(C_SUMMARY)に載っている命令の方が説明(C_INST)に載っている命令よりも適合度が高くなります。
キーワード適合度の強さについては、hsp_db.hsp内のコメントをご覧ください。

#include "../hsphelp/src/hhx_db.hsp"
#module
//
// 文字列の右側を半角スペースで埋める
#defcfunc add_spaces str sTarget, local iLength, local sResult
    iStrlen = strlen( sTarget )
    iLength = 30 - iStrlen
    if iLength < 1 : iLength = 1
    sdim sResult, iLength + iStrlen + 1
    sResult = sTarget
    memset sResult, ' ', iLength, iStrlen
    return sResult
#global

// hsphelpディレクトリの存在を確認
    chdir dir_exe
    dirlist s, "hsphelp"5 
    if stat == 0 : dialog "hsphelpディレクトリが見つかりません。"1 : end
    chdir dir_exe + "/hsphelp"

// HHXのデータベースをロード
    HHX_init_load_db
    if HHX_currentset_sum() ! HHX_diskset_sum() {
        HHX_init_rebuild_db DBR_WRITEDB
    } else {
        HHX_init_extract_db
    }

// 画面上にオブジェクトを配置
    sSerch = "色" : sdim note, 10000 : notesel note
    objsize 12024 : objmode 2 : font msgothic12
    input sSerch, ginfo_winx - 12024
    pos ginfo_winx - 1200
    button gosub "検索"*serch
    pos 024
    mesbox note, ginfo_winxginfo_winy - ginfo_cy

    gosub *serch

    onkey gosub *lbl_onkey
    stop

// 入力ボックスでEnterを押したとき、検索を開始
*lbl_onkey
    objsel -1
    if ( wparam == 13 ) & ( stat == 0 ) : gosub *serch
    return

// ある条件によってデータベースから検索を行い、その結果を列挙する
*serch
    note = ""
    db_num = HHX_select_where( sSerch, -1, -1 )   // 検索対象文字を解説などに含む命令・関数を列挙する
    repeat db_num
        c = HHX_get_next()
        sLine = add_spaces( hhxdata( c, C_NAME ) ) + hhxdata( c, C_SUMMARY )
        noteadd sLine
    loop
    objprm 2, note
    return

2007年8月13日月曜日

HHXモジュール 命令・関数一覧を取得

おそらくあまり利用者のいないHHXモジュールについて、しばらく扱ってみようと思います。
HHXモジュールはHSファイルにアクセスする際、非常に強力な手段として利用することができます。HHXに付属されており、誰でも利用することができます。作者はsprocketさんです。

まずは以前も紹介した、命令・関数一覧の作成から。
データベースのロード手順はどんなスクリプトでも同じです。実際にこのスクリプトがHHX自身のスクリプトとほとんど同じであることを確認していただけると思います。

HHX_select_allを実行しただけでは名称順にソートされた状態ですが、HHX_order_by命令を利用することでグループ名・依存DLL名などによってソートできます。#include "../hsphelp/src/hhx_db.hsp"
#module
//
// 文字列の右側を半角スペースで埋める
#defcfunc add_spaces str sTarget, local iLength, local sResult
    iStrlen = strlen( sTarget )
    iLength = 30 - iStrlen
    if iLength < 1 : iLength = 1
    sdim sResult, iLength + iStrlen + 1
    sResult = sTarget
    memset sResult, ' ', iLength, iStrlen
    return sResult
#global

// hsphelpディレクトリの存在を確認
    chdir dir_exe
    dirlist s, "hsphelp"5 
    if stat == 0 : dialog "hsphelpディレクトリが見つかりません。"1 : end
    chdir dir_exe + "/hsphelp"

// HHXのデータベースをロード
    HHX_init_load_db
    if HHX_currentset_sum() ! HHX_diskset_sum() {
        // HSファイルに何かしらの変更が加わったため、データベースを再構築
        mes "HHXのデータベースをリビルドしています..."
        HHX_init_rebuild_db DBR_WRITEDB // データベースを作成し、配列変数hhxdataxにロード
                                        // より高速化を望むなら DBR_WRITEDB を DBR_READONLY としても良い
    } else {
        HHX_init_extract_db             // 配列変数hhxdataxにメモリ上のデータをロード
    }
    mes "HHXのデータベースをロードしました。"

// データベースから命令・関数をひとつずつ取り出し、その名前を列挙する
    db_num = HHX_select_all()           // すべての命令・関数などを検索対象とする(ABC順)
;   HHX_order_by C_GROUP                // コメントを外すとグループ名でソート(昇順)
    sdim buf, 16000
    notesel buf
    mes "命令一覧を作成します..."
    repeat db_num
        c = HHX_get_next()              // 次の命令・関数などのナンバーを取得
        sLine = add_spaces( hhxdata( c, C_NAME ) ) + hhxdata( c, C_SUMMARY )
        noteadd sLine                   // ナンバー c で表現される命令・関数などの名前をnoteaddする
                                        // C_SUMMARYなら命令・関数の概要を、C_INSTならその説明文を取得することができる(他はhhx_db.hspを参照)
    loop
    mes "命令一覧の作成を完了しました。"
    objmode 2
    font msgothic12
    mesbox buf, ginfo_winxginfo_winy - ginfo_cy
    stop

2007年8月12日日曜日

HSファイルからHTMLヘルプを作成する(2)

XHTMLに変わっている点を除き、恐らく機能的には以前同梱されていたヘルプと完全互換。
かなり大きめ(~1.5MB)のテキストデータを扱いますので、スペックに自信がない場合はawaitのコメントアウトをはずすか、他のアプリケーションを終了させた状態で実行することをオススメします。

グループを定義していない命令を想定していなかった問題を修正。
再現性を向上。


現在再現性や利便性の向上を図り、改良中です。満足のいくものができたら公開します。
v1.1を公開しました。
ウェブサイトで新バージョンの配布を行っています。

関連:HSファイルからHTMLヘルプを作成する

// hsファイルからHTMLヘルプを作成
// 機能別索引を除くすべての索引も作成する
#include "../hsphelp/src/hhx_db.hsp"
#module
//
// 関数名・命令名からidを得る
#defcfunc get_id str name, local s
    s = name
    if ( peek( s, 0 ) == '#' ) : s = strmid( s, 1strlen( s ) - 1 )
    return "s_" + s

// 関数名・命令名からファイルの通し番号(独自に定義)を得る
//   help_a.htmlを0、help_b.htmを1、…help_sp.htmを26とする
#defcfunc get_filenum str name, local s, local p
    s = name
    p = peek( s, 0 )
    if ( 'A' <= p ) & ( p <= 'Z' ) : p -= 'A' - 'a'
    if ( 'a' <= p ) & ( p <= 'z' ) {
        return p - 'a'
    } else {
        return 'z' - 'a' + 1
    }
//
// 通し番号からファイル名を得る
#defcfunc get_filename int num
    if ( 0 <= num ) & ( num <= 'z' - 'a' ) {
        return "help_" + strf"%c", num + 'a' ) + ".htm"
    } else {
        return "help_sp.htm"
    }
//
// 半角スペースで埋める
#defcfunc add_spaces str sTarget, local iLength, local sResult
    iStrlen = strlen( sTarget )
    iLength = 30 - iStrlen
    if iLength < 1 : iLength = 1
    sdim sResult, iLength + iStrlen + 1
    sResult = sTarget
    memset sResult, ' ', iLength, iStrlen
    return sResult
#global

    chdir dir_exe + "/hsphelp"
    sdim buf, 10000
    html_header = {"<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Frameset//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd\">
<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"ja\" lang=\"ja\">
<head>
\t<meta http-equiv=\"Content-Type\" content=\"text/html; charset=Shift_JIS\" />
\t<meta http-equiv=\"Content-Language\" content=\"ja\" />
\t<link rel=\"stylesheet\" type=\"text/css\" href=\"hsphelp.css\" />
\t<title>HSP command help</title>
</head>
"}


    gosub *load_db           // HHXのDBからデータをロードする
    gosub *make_html_files   // HTMLファイルを作成する
    gosub *make_frame_file   // フレーム用HTMLファイルを作成する
    gosub *make_ref_file     // グループ別索引用HTMLを作成
    gosub *make_css_file     // CSSファイルを作成する
    dialog "HTMLファイルの作成が完了しました。\nHTMLファイルを開きますか?"2
    if stat == 6 : exec "indexf.htm"16
    end

*load_db
    HHX_init_load_db
    if HHX_currentset_sum() ! HHX_diskset_sum() {
        mes "HHXのデータベースをリビルドしています..."           // HSファイルに何かしらの変更が加わったため、DBを再構築
        HHX_init_rebuild_db DBR_WRITEDB
    } else {
        HHX_init_extract_db
    }
    mes "HHXのデータベースをロードしました。"
    return

*init_file
    // HTMLのヘッダを書き込む
    sdim file, 20000
    file = html_header + "<body>\n\t<h1>HSP command help</h1>\n"
    file_offset = strlen( file )
    return

*save_file
    // HTMLファイルを保存する
    file += "</body></html>"
    file_offset += strlen"</body></html>" )
    bsave get_filename( file_type ), file, file_offset
    return

*init_index
    // 索引用HTMLのヘッダを書きこむ
    sdim index, 100000  : index  = html_header + "<body>\n\t<h1>HSP command help ABC順索引</h1><ul class=\"index_list\">\n" // 索引
    sdim indexf, 100000 : indexf = html_header + "<body>\n\t<h1>索引</h1>\n\t<ul class=\"indexf_list\">\n"                  // フレーム用ミニ索引
    indexf += "<p><a href=\"hspref.htm\" target=\"main\">グループ別索引</a></p>\n"
    indexf += "<p><a href=\"hsppidx.htm\" target=\"main\">ABC順索引</a></p>\n"
    index_offset  = strlen( index )
    indexf_offset = strlen( indexf )
    return

*save_index
    // 索引用HTMLを保存する
    index  += "\t</ul>\n</body></html>"
    indexf += "\t</ul>\n</body></html>"
    index_offset  += strlen"\t</ul>\n</body></html>" )
    indexf_offset += strlen"\t</ul>\n</body></html>" )
    bsave "hsppidx.htm",  index,  index_offset
    bsave "hsppidxf.htm", indexf, indexf_offset
    return

*make_html_files
    // HTMLファイルを作成する
    mes "HTMLファイルの作成を開始..."
    db_num = HHX_select_all()           // すべての命令・関数を検索対象とする
    file_type = get_filenum"#" )      // 最初は記号で始まる命令用のファイル(help_sp.htm)からはじめる
    file_name = get_filename( file_type )
    gosub *init_file
    gosub *init_index

    repeat db_num
        c = HHX_get_next()
        db_name  = hhxdata( c, C_NAME ) // 命令・関数名
        id = get_id( db_name )
        if file_type != get_filenum( db_name ) {
            // 次のHTMLファイルへ移行
            gosub *save_file
            gosub *init_file
            file_type = get_filenum( db_name )
            file_name = get_filename( file_type )
        }

        // 索引
        buf = "\t\t<li><a href=\"" + file_name + "#" + id + "\">" + add_spaces( db_name ) + hhxdata( c, C_SUMMARY ) + "</a></li>\n"
        index  += buf : index_offset  += strlen( buf )
        buf = "\t\t<li><a href=\"" + file_name + "#" + id + "\" target=\"main\">" + db_name + "</a></li>\n"
        indexf += buf : indexf_offset += strlen( buf )

        // 見出し(h2タグ)
        buf = "\t<h2 id=\"" + id + "\" class=\"keyword_name\">" + db_name + "</h2>\n"
        // パラメータ
        buf += "\t<p class=\"prm\">" + add_spaces( db_name + " " + hhxdata( c, C_PRM ) ) + "[" + hhxdata( c, C_SUMMARY ) + "]</p>\n"
        // パラメータ詳細
        if hhxdata( c, C_PRM2 ) != "" {
            buf += "\t\t<p class=\"prm_detail\">" + hhxdata( c, C_PRM2 ) + "</p>\n"
        }
        // 説明文
        if hhxdata( c, C_INST ) != "" {
            buf += "\t\t<h3>説明</h3><p class=\"inst\">" + hhxdata( c, C_INST ) + "</p>\n"
        }
        // 備考
        if hhxdata( c, C_NOTE ) != "" {
            buf += "\t\t<h3>備考</h3><p class=\"note\">" + hhxdata( c, C_NOTE ) + "</p>\n"
        }
        // 参照
        if hhxdata( c, C_HREF ) != "" {
            buf += "\t\t<h3>参照</h3><ul class=\"href\">"
            i = 0 : l = strlen( hhxdata( c, C_HREF ) )
            repeat
                getstr s, hhxdata( c, C_HREF ), i, ' '
                i += strsize
                buf += "\t\t\t<li><a href=\"" + get_filenameget_filenum( s ) ) + "#" + get_id( s ) + "\">" + s + "</a></li>\n"
                if l <= i : break
            loop
            buf += "\t\t</ul>"
        }
        // 水平線(次の項目との区切り)
        buf += "\n\t<hr>\n\n"

        // 変数に書き込み
        file += buf
        file_offset += strlen( buf )

;       title str( double( cnt ) / db_num ) + "% finished..."
;       await 1
    loop

    // 最後のファイルをディスクに保存
    gosub *save_file
    gosub *save_index
    return

*make_ref_file
    db_num = HHX_select_all()
    HHX_order_by C_GROUP
    sdim ref, 100000
    ref  = html_header + "<body>\n\t<h1>HSP command help グループ別索引</h1>\n"
    ref += "\t<h2>(グループ未定義)</h2>\n\t\t<ul class=\"ref_list\">\n"
    ref_offset = strlen( ref )
    group_name = ""
    repeat db_num
        c = HHX_get_next()
        buf = ""
        db_name  = hhxdata( c, C_NAME )
        db_group = hhxdata( c, C_GROUP )
        if group_name != db_group {
            buf += "\t\t</ul>\n"
            buf += "\t<h2>" + db_group + "</h2>\n\t\t<ul class=\"ref_list\">\n"
            group_name = db_group
        }
        buf += "\t\t\t<li><a href=\"" + get_filenameget_filenum( db_name ) ) + "#" + get_id( db_name ) + "\">" + add_spaces( db_name ) +  hhxdata( c, C_SUMMARY )  + "</a></li>\n"
        ref += buf
        ref_offset += strlen( buf )
    loop
    ref        += "\t\t</ul>\n</body></html>"
    ref_offset += strlen"\t\t</ul>\n</body></html>" )
    bsave "hspref.htm", ref, ref_offset
    return

*make_frame_file
    buf = html_header + {"\t<frameset cols=\"80%,*\">
\t\t<frame src=\"hspref.htm\" name=\"main\" />
\t\t<frame src=\"hsppidxf.htm\" name=\"sub\" />
\t</frameset>
\t<noframes>
\t\t<p>これはフレーム対応ブラウザ用のファイルです。<br />
\t\tフレームに対応したブラウザでご覧になるか、<a href=\"hsppidx.htm\">命令一覧</a>をご利用ください。</p>
\t</noframes>
</html>"}

    bsave "indexf.htm", buf, strlen( buf )
    return

*make_css_file
    mes "CSSファイルの作成を開始..."
    buf = {"body {
\tbackground-color : #f0e0d0 ;
}
h2 {
\tcolor : #000080 ;
\tfont-size : large ;
\tfont-weight : bold ;
\twhite-space : pre ;
}
h2.keyword_name {
\tfont-size : x-large ;
\tcolor : #504030 ;
\tfont-weight : bold ;
}
h3 {
\tfont-weight : bold ;
}
p.prm {
\tcolor : #000080 ;
\twhite-space : pre ;
\tmargin-left : 70px ;
\tfont-size : large ;
\tfont-weight : bold ;
\tfont-family : monospace ;
}
p.prm_detail {
\tcolor : #000080 ;
\tfont-size : small ;
\twhite-space : pre ;
\tmargin-left : 70px ;
}
p.inst {
\tmargin-left : 70px ;
\twhite-space : pre ;
}
p.note {
\tmargin-left : 70px ;
}
ul.href {
\tmargin-left : 70px ;
}
ul.index_list {
\tfont-size : large ;
}
ul.index_list li {
\twhite-space : pre ;
\tfont-family : monospace ;
\tmargin-bottom : 1ex ;
}
ul.indexf_list {
}
ul.ref_list {
\tfont-size : large ;
}
ul.ref_list li {
\twhite-space : pre ;
\tfont-family : monospace ;
\tmargin-bottom : 1ex ;
}"}

    bsave "hsphelp.css", buf, strlen( buf )
    return

2007年8月4日土曜日

HSファイルからHTMLヘルプを作成する

HSP3.1から同梱されなくなったHTMLヘルプを作成するスクリプト。
命令一覧は作成しません。

祝・50投稿ヽ(´▽`)ノ

よくよく考えたらHHXのDBにはABC順に記録されているので、配列を使う必要は全くありませんでした。
もしEXE化する機会があれば処理方法を再度考え直してみたいと思います。

改良版をこちらのページから入手できます。

関連:HSファイルからHTMLヘルプを作成する(2)

// hsファイルからHTMLヘルプを作成
#include "../hsphelp/src/hhx_db.hsp"
#module
// 関数名・命令名からidを得る
#defcfunc get_id str name, local s
    s = name
    if ( peek( s, 0 ) < 'a' ) | ( 'z' < peek( s, 0 ) ) : s = strmid( s, 1strlen( s ) - 1 )
    return "s_" + s
// 関数名・命令名からファイルの通し番号(独自に定義)を得る
//   help_a.htmlを0、help_b.htmを1、…help_sp.htmを26とする
#defcfunc get_filenum str name, local s, local p
    s = name
    p = peek( s, 0 )
    if ( 'A' <= p ) & ( p <= 'Z' ) : p -= 'A' - 'a'
    if ( 'a' <= p ) & ( p <= 'z' ) {
        return p - 'a'
    } else {
        return 'z' - 'a' + 1
    }
// 通し番号からファイル名を得る
#defcfunc get_filename int num
    if ( 0 <= num ) & ( num <= 'z' - 'a' ) {
        return "help_" + strf"%c", num + 'a' ) + ".htm"
    } else {
        return "help_sp.htm"
    }
#global

    chdir dir_exe + "/hsphelp"

    gosub *load_db           // HHXのDBからデータをロードする
    gosub *init              // 前準備
    gosub *make_html_files   // HTMLファイルを作成する
    gosub *make_css_file     // CSSファイルを作成する
    dialog "finish"
    end

*load_db
    HHX_init_load_db
    if HHX_currentset_sum() ! HHX_diskset_sum() {
        mes "rebuilding db..."           // HSファイルに何かしらの変更が加わったため、DBを再構築
        HHX_init_rebuild_db DBR_WRITEDB
    } else {
        HHX_init_extract_db
    }
    return

*init
    // a ~ zと特殊文字(_, #)用のファイルを用意
    sdim file, 1024, 'z' - 'a' + 2 
    dim file_offset, 'z' - 'a' + 2 

    // HTMLのヘッダをそれぞれのファイルに書き込む
    buf = {"<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">
<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"ja\" lang=\"ja\">
<head>
\t<meta http-equiv=\"Content-Type\" content=\"text/html; charset=Shift_JIS\" />
\t<meta http-equiv=\"Content-Language\" content=\"ja\" />
\t<link rel=\"stylesheet\" type=\"text/css\" href=\"hsphelp.css\" />
\t<title>HSP command help</title>
</head>
<body>
\t<h1>HSP command help</h1>\n"}

    l = strlen( buf )
    repeat 'z' - 'a' + 2
        file( cnt ) = buf
        file_offset( cnt ) = l
    loop
    return

*make_html_files
    db_num = HHX_select_all() // すべての命令・関数を検索対象とする

    repeat db_num
        c = HHX_get_next()
        db_name  = hhxdata( c, C_NAME )         // 命令・関数名
        file_num = get_filenum( db_name )       // この命令が記録されるHTMLの通し番号(独自に定義したもの)

        // 見出し(h2タグ)
        buf = "\t<h2 id=\"" + get_id( db_name ) + "\" class=\"keyword_name\">" + db_name + " " +  hhxdata( c, C_PRM ) + "\t\t[" + hhxdata( c, C_SUMMARY ) + "]</h2>\n"
        // パラメータ
        if hhxdata( c, C_PRM2 ) != "" {
            buf += "\t\t<p class=\"prm\">" + hhxdata( c, C_PRM2 ) + "</p>\n"
        }
        // 説明文
        if hhxdata( c, C_INST ) != "" {
            buf += "\t\t<h3>説明</h3><p class=\"inst\">" + hhxdata( c, C_INST ) + "</p>\n"
        }
        // 備考
        if hhxdata( c, C_NOTE ) != "" {
            buf += "\t\t<h3>備考</h3><p class=\"note\">" + hhxdata( c, C_NOTE ) + "</p>\n"
        }
        // 参照
        if hhxdata( c, C_HREF ) != "" {
            buf += "\t\t<h3>参照</h3><ul class=\"href\">"
            i = 0 : l = strlen( hhxdata( c, C_HREF ) )
            repeat
                getstr s, hhxdata( c, C_HREF ), i, ' '
                i += strsize
                buf += "\t\t\t<li><a href=\"" + get_filenameget_filenum( s ) ) + "#" + get_id( s ) + "\">" + s + "</a></li>\n"
                if l <= i : break
            loop
            buf += "\t\t</ul>"
        }
        // 水平線(次の項目との区切り)
        buf += "\n\t<hr>\n\n"

        // 配列に保存
        l = strlen( buf )
        file( file_num ) += buf
        file_offset( file_num ) += l

;       title str( 100 * double( cnt ) / db_num ) + "% finished..."
;       await 1
    loop

    // ファイルをディスクに保存
    repeat 'z' - 'a' + 2
        file( cnt ) += "</body></html>"
        file_offset( cnt ) += strlen"</body></html>" )
        bsave get_filenamecnt ), file( cnt ), file_offset( cnt )
    loop
    return

*make_css_file
    buf = {"body {
background-color : #f0e0d0 ;
}
h2 {
color : #000080 ;
font-size : large ;
font-weight : bold ;
white-space : pre ;
}
h3 {
font-weight : bold ;
}
p.prm {
color : #000080 ;
font-size : small ;
white-space : pre ;
margin-left : 70px;
}
p.inst {
margin-left : 70px;
white-space : pre ;
}
p.note {
margin-left : 70px;
}
ul.href {
margin-left : 70px;
}"}

    bsave "hsphelp.css", buf, strlen( buf )
    return

2007年7月25日水曜日

(X)HTMLコンバータ (6) hsファイルから命令や関数等の一覧を作成

hsファイルから関数一覧を作成」と同じ考え方ですが、HHX付属のモジュールを利用することで格段に効率UPしました。

#include "../hsphelp/src/hhx_db.hsp"
#define HELP_DIR "hsphelp"

// ヘルプディレクトリの存在を確認
    chdir dir_exe
    dirlist s, HELP_DIR, 5
    if stat == 0 : dialog "ヘルプディレクトリが見つかりません", 1 : end
    chdir HELP_DIR

// データベースのロード
    mes "loading..."
    HHX_init_load_db
    if HHX_currentset_sum() ! HHX_diskset_sum() {
        mes "rebuilding db..."
        HHX_init_rebuild_db DBR_WRITEDB
    } else {
        HHX_init_extract_db
    }

// コンバータ用デーベースの作成
    mes "making DB for (X)HTML-converter..."
    db_num = HHX_select_all()
    repeat db_num
        c = HHX_get_next()
        db_name  = hhxdata( c, C_NAME )
        db_group = hhxdata( c, C_GROUP )
        db_prm   = hhxdata( c, C_PRM )
        if instr( db_group, 0, "プリプロセッサ命令" ) >= 0 {
            ; プリプロセッサ
            notesel list_prepro
        } else : if instr( db_group, 0, "システム変数" ) >= 0 {
            ; システム変数
            notesel list_sysval
        } else : if instr( db_group, 0, "マクロ" ) >= 0 {
            ; マクロ
            notesel list_macro
        } else : if db_prm = "" {
            ; 引数なし(命令)
            notesel list_command
        } else : if peek( db_prm ) = '(' {
            ; 関数型
            notesel list_func
        } else {
            ; 命令型
            notesel list_command
        }
        noteadd db_name
    loop
    mes "finish."

2007年7月21日土曜日

(X)HTMLコンバータ (3) hsファイルから関数一覧を作成


hsファイルから関数一覧を作成するスクリプト。

関数のヘルプは%prmの次行の1文字目が必ず"("になることを利用しています。
最初はnotegetで1行ずつ調べるスクリプトを組んだのですが非常に遅かったため、instr()を利用したところ意外と高速なスクリプトができました。やはりHSP内部に任せられる処理は丸投げた方が早いようです。

このスクリプトは今後のhsファイルの仕様変更に伴い、使えなくなる可能性があります。
// hsファイルから関数リストを作成 2007.07.20

#include "hspda.as"

#define HSP3_EXE    "hsp3.exe"  // HSP3実行ファイルの名前
#define DIR_HELP    "hsphelp"   // ヘルプファイルが保存されているディレクトリの名前
#const  EXPAND_SIZE 1024        // funcListを拡張する単位[byte]

#module
// 指定したファイルが存在するならば1、存在しないならば0を返す
#defcfunc fileExist str fileName
    exist fileName
    return ( strsize >= 0 )
// 指定したディレクトリが存在するならば1、存在しないならば0を返す
#defcfunc dirExist str dirName, local s
    dirlist s, dirName, 5
    return stat
// 文字列を小文字に変換する
#define global ctype toLower( %1 = "" ) getpath( %1, 16 )
#global

    chdir dir_exe
    if ( fileExist( HSP3_EXE ) == 0 ) {
        dialog "HSP3があるフォルダで実行してください。", 1
        end
    }

    if ( dirExist( DIR_HELP ) == 0 ) {
        dialog "hsphelpフォルダが見つかりません。", 1
        end
    }

    chdir DIR_HELP

    // hsファイルの一覧を取得
    notesel hsFileList
    dirlist hsFileList, "*.hs", 1

    funcListSize = EXPAND_SIZE
    sdim funcList, funcListSize
    funcListPos = 0

    repeat notemax
        noteget tmp, cnt
        if ( fileExist( tmp ) == 0 ) : continue             // 念のための存在確認

        notesel hsFile
        noteload tmp
        hsFilePos = 0
        repeat
            ins = instr( hsFile, hsFilePos, "%index\n" )
            if ( ins < 0 ) : break
            hsFilePos += ins + strlen"%index\n" )         // strlen()は定数化した方が高速
            getstr funcName, hsFile, hsFilePos
            hsFilePos += strsize

            ins = instr( hsFile, hsFilePos, "%prm\n" )
            if ( ins < 0 ) : break
            hsFilePos += ins + strlen"%prm\n" )           // strlen()は定数化した方が高速
            getstr tmp, hsFile, hsFilePos
            hsFilePos += strsize
            if strmid( tmp, 0, 1 ) == "(" {
                if ( funcListPos + strlen( funcName + "\n" ) >= funcListSize ) {
                    funcListSize += EXPAND_SIZE
                    memExpand funcList, funcListSize
                }
                poke funcList, funcListPos, funcName + "\n"
                funcListPos += strlen( funcName + "\n" )
            }
        loop
        noteunsel
    loop
    sdim hsFile, 4
    sdim hsFileList, 4

    // 結果をアルファベット順に並び替えて表示
    sortnote funcList
    mesbox funcList, ginfo_winxginfo_winy
    stop