Nami2000 ファイルの構造解析


解析中だったり...

はじめに


Nami2000 は ゆうきひろ 氏により作成されたアウトライン エディタです。MS-Windows で動作します。シンプルで軽快な操作性が売りです。

Nami2000(Windows95/98/Me/文書作成)
http://www.vector.co.jp/soft/win95/writing/se10166...
がらくた工房
http://www.geocities.jp/my_ultraseven/mozart/_star...

Nami2000 ファイルの構造


Nami2000 ファイルは二つのブロックで構成されています。始めにツリー ブロックがあり、ページ ブロックが続きます。

ツリー ブロック

int32ブロック サイズ
char[]ブロック

ツリー ブロックはタブ(0x09)でインデントされたページ タイトルの集まりです。各行がページに対応しています。行末は CRLF(0x0D, 0x0A) です。

ツリーの深さはインデントの個数で表現されています。

インデントのあとにページ タイトルが続きます。

ツリー ブロックを擬似的に表現すると次のようになります。タブをピリオド(.)で置き換えています。
Nami2000 ファイルの構造解析
.Nami2000 ファイルの構造
..ツリー ブロック
..ページ ブロック
.更新履歴

各行には制約があります。

ページ タイトルの頭の空白記号(半角空白、タブ)とピリオド(.)は取り除かれます。

各行は最大 254 文字です。最後の文字がマルチ バイト文字のとき文字数が増えます。ただし処理が不完全なため壊れている場合があります。

ページ ブロック


ページ ブロックには各ページの情報が保存されています。ページの順序はツリー ブロックの並び順で保存されています。階層情報は含まれません。
int32テキスト サイズ
char[]テキスト
int32カーソル位置
int32union

union は第1〜2ページとそれ以降で構造が変わります。第1〜2ページを first、 second 、以降を page で構造を示します。
unionfirst
int16カレント ページ
int16サブアイコン
second
int16編集モード
int16サブアイコン
page
int32サブアイコン

カレント ページは最後に編集したページの番号です。番号は第1ページを 0 として数えます。

編集モードの値は次のとおり。
0Text
1Delphi
2HSP
3C/C++
4VB
5Html
6User

サブアイコンの値は次のとおり。
0なし
1赤矢印
2青矢印
3緑矢印
4チェック
5エクスクラメーション(!)
6金槌
7止まれ
8
9ツール チップ
10カレンダー

もろもろ


エンディアネスはリトル エンディアン。

int の符号付/符号なしは調べてない。

文字コードはシフトJIS( CodePage 932 )。
改行コードは CRLF(0x0D, 0x0A) 。

ライブラリー


準備中。Ruby で記述したものはありますが...

parser


何もないのもあれなので...読み込む処理だけのサンプルです。

# -*- coding: cp932 -*-

class ReadWrap
    def initialize( i_io )
        i_io.binmode
        @m_io = i_io
    end

    def read( i_size )
        r = @m_io.read( i_size )
    end

    def read_int16
        r = self.read( 2 )
        r = r.unpack( "v" ).first
    end

    def read_int32
        r = self.read( 4 )
        r = r.unpack( "V" ).first
    end
end

class Page
    attr_accessor   :indent
    attr_accessor   :title
    attr_accessor   :body
    attr_accessor   :cursol
    attr_accessor   :subicon
end

ARGV.each do |nm2k_file|
    current_page = nil
    highlight_mode = nil
    pages = []

    open( nm2k_file, "rb" ) do |h|
        io = ReadWrap.new( h )

        tree_block_size = io.read_int32
        tree_block = io.read( tree_block_size )

        tree_block.each do |line|
p line
            # crlf を取り除く
            line.chomp!( "\r\n" )
            pg = Page.new
            c, title, = line.scan( /^(\t*)(.*)$/ ).first
            # \t の数=インデント
            pg.indent = c.size
            pg.title = title
            pages.push( pg )
        end

        proc_3 = Proc.new { |pg|
            subicon = io.read_int32
            pg.subicon = subicon
            proc_3
        }
        proc_2 = Proc.new { |pg|
            highlight_mode = io.read_int16
            subicon = io.read_int16
            pg.subicon = subicon
            proc_3
        }
        proc_1 = Proc.new { |pg|
            current_page = io.read_int16
            subicon = io.read_int16
            pg.subicon = subicon
            proc_2
        }
        uni = proc_1

        pages.each do |pg|
            body_size = io.read_int32
            body = io.read( body_size )
            cursol = io.read_int32
            uni = uni.call( pg )
            pg.body = body
            pg.cursol = cursol
p pg
        end
    end
end

更新履歴



2011/2/17thu 記述を見直した。サンプル追加。
2005/11/26sat ページ作成
タグ

コメントをかく


「http://」を含む投稿は禁止されています。

利用規約をご確認のうえご記入下さい

Wiki内検索

編集にはIDが必要です