XHTMLプラグイン Y.Nakamuraパッチ Ver.1.22ynp5

概要

取り入れられなかった要望を自前実装+ついでにちょいと不具合修正という感じで、XHTMLプラグインの改造をしてみました。Ver.1.22がベースです。

お約束

変更内容

不具合修正(およびその技術解説)

興味のある方以外は、見出し(修正された不具合)だけ読んで頂ければ問題ありません。とくに最後のは長いので読み飛ばすのが吉。

「HTMLリンク文書の更新」で、現在開いている文書以外に新たにリンク関連のヘッダを追加する場合、HTML 4.01でも<link href="2002_03.html" rel="prev" />となってしまっていた

裏テキストとしてファイルを開いただけではtext::doctypeが設定されないにも関わらず、ヘッダの挿入(SetHeaderStr関数)で__ISXHTML__を参照していたため、必ずXHTML扱いになってしまっていました。

SortNavigator関数でファイルオープン後DOCTYPEを取得(temp::doctype = GetCurDoctype(temp);)することで対応しました。

「ハイパーリンクの挿入」において、「リンク先のtitleを読みとる」が効かなくなっていた

裏テキストとしてファイルを開いただけではtext->filekindにファイルの種類が設定されないにも関わらず、この値をもとにHTML文書かどうかを判定していたため、title読み取りの処理が行なわれていませんでした。

uiInsertHtmlLink関数でファイルオープン後、txConfigGet(text2);することで対応しました。

「表の挿入」において、「1行目はヘッド」オプションのON/OFFに関わらず、常に1行目がthになっていた

BOOL値p_table_headが、実際の処理中に参照されていませんでしたので、これを参照するようにしました。

ただし、その後「表の挿入」の処理を大幅に改造してしまったので、あまり意味がなくなってしまいました。

uiInsertImage関数内のwndImeSetOpen(hwnd,0);は存在しない値を引数に取っていた

変数の自動定義によりコンパイルは通っていましたが、意味のない記述となっていました。wndImeSetOpen(text->hwndtext,0);に修正しました。

返り値がvoidの関数内で、returnでBOOL値を返しているものがあった

warningレベルなので不具合は言い過ぎかもしれませんが。もとのコードをあまり崩さずに、簡単に変更できるもの(OpenLink関数)は変更しておきました。

__pluginHelp、DeleteTag、SelectToHtml、uiInsertCommentあたりで(値を返すためと言うより)関数を抜けるためにreturnが使われている部分は、とりあえずそのままです。

どちらにせよ実害はありませんが……。

ファイルオープン時、HTMLヘッダの<meta http-equiv="Content-Type" content="text/html; charset=hogehoge">で文字コードを指定していない場合、あるいは指定してあってもhttp-equiv属性値が二重引用符で括られていない場合、もとの文字コードに関係なくShift-JISで保存される場合があった

(恐らく無駄に)長くなりますが問題があった点と修正内容をコード付きで解説します。

以下はXHTMLプラグインの__on_txFrameNew関数の一部+αです。上がVer.1.19、下がVer.1.22のもの。

void __on_txFrameNew(TX* text)
{

(前略)

        // 漢字コードを補正
        //txSetUndispEx(text);
        ad = txGetAddress(text); ly=text->ly;
        mchar sz[CCHWORD];
        GetHeaderStr(text,"meta>[^>]*http-equiv=¥"Content-Type¥"","content",
        sz,CCHWORD,0,0);
        if (stristr(sz,"SHIFT_JIS")) text->kcSave = KC_SJIS;
        else if (stristr(sz,"ISO-2022-JP")) text->kcSave = KC_JIS;
        else if (stristr(sz,"EUC-JP")) text->kcSave = KC_EUC;
        //text->fClip = FALSE;
        txSelectQuit(text);
        //txSetDispEx(text);
        //txSetLy(text,ly);txJumpAddress(text,ad);
        txJumpAddress(text,ad);txSetLy(text,ly); // 1999.09.09 Imabeppu 

(後略)

}
BOOL GetKc(mchar *sz)
{
    if (stristr(sz,"SHIFT_JIS")) return  KC_SJIS;
    else if (stristr(sz,"ISO-2022-JP")) return KC_JIS;
    else if (stristr(sz,"EUC-JP")) return KC_EUC;
}

void __on_txFrameNew(TX* text)
{

(前略)

    if (!_var(OPT_SJIS)) {
        // 漢字コードを補正
        //txSetUndispEx(text);
        ad = txGetAddress(text); ly=text->ly;
        mchar sz[CCHWORD];
        GetHeaderStr(text,"meta>[^>]*http-equiv=¥"Content-Type¥"","content",
        sz,CCHWORD,0,0);
        text->kcSave = GetKc(sz);
        //text->fClip = FALSE;
        txSelectQuit(text);
        //txSetDispEx(text);
        //txSetLy(text,ly);txJumpAddress(text,ad);
        txJumpAddress(text,ad);txSetLy(text,ly); // 1999.09.09 Imabeppu
    }

(後略)

}

ぱっと見で気が付くのは二点、Ver.1.22ではヘッダの文字コードを取得する部分が関数化されており、また_var(OPT_SJIS)が偽の場合のみ文字コード補正の処理が走るようになっています。後者はこの際直接的には関係ないので置いておくとして、問題はGetKc関数近辺です。

三点まずいところがあります。ヘッダ文字列の取得処理(GetHeaderStr(text,"meta>[^>]*http-equiv=¥"Content-Type¥"",〜)が、meta要素のhttp-equiv属性が二重引用符で囲まれていない場合に正しい値を返さないこと、GetHeaderStrが偽を返した場合(=ヘッダ内に<META http-equiv="Content-Type"〜な文字列が存在しない場合)を想定していないこと、また当該ヘッダが存在したとして、GetKc関数が属性値に「SHIFT_JIS」、「ISO-2022-JP」、「EUC-JP」が含まれていない場合を想定していないことです。ついでに細かいところだと、返り値がintなのにBOOL GetKc(mchar *sz)なのもアレです。まあtypedefされてるだけなんで結局は一緒なんですが。

結果として、text->kcSave = GetKc(sz)の部分において、ヘッダが存在しなくても「ヘッダを拠り所にした文字コードの判定処理」が走ってしまい、またヘッダが存在してもhttp-equiv属性が二重引用符で囲まれていないと正しい属性値を取得できず、さらにそこで「3種類の文字コードのどれにも該当しない」場合の返り値が設定されていないものだから0が帰ってきて(何で返り値が設定されてないと0になるのかよく分かってないんですが。0というよりNULLが帰ってきてるのかな?)、0=KC_SJISなものだからtext->kcSaveにKC_SJISが設定されてしまうと。そういうわけみたいです。

二重引用符についてはVer.1.19以前からの問題なのですが、これまでは正しい文字列が取得できなくても処理がスキップされていただけなので顕在化しなかったのでしょう。また、ここは新規にファイルを開いた際のみ走る処理なので、一度開いたファイルのmeta要素から二重引用符を外しても影響はありません。

そこでこんなコードに修正してみました。

#define KC_ERROR -1//★Y.Nakamura 不正な、あるいは対応外の文字コード指定
int GetKc(mchar *sz) //★Y.Nakamura 内部的には同じだけど一応
{
    if (stristr(sz,"SHIFT_JIS")) return  KC_SJIS;
    else if (stristr(sz,"ISO-2022-JP")) return KC_JIS;
    else if (stristr(sz,"EUC-JP")) return KC_EUC;
    return KC_ERROR; //★Y.Nakamura
}

void __on_txFrameNew(TX* text)
{

(前略)

    if (!_var(OPT_SJIS)) {
        // 漢字コードを補正
        //txSetUndispEx(text);
        ad = txGetAddress(text); ly=text->ly;
        mchar sz[CCHWORD];
        //★Y.Nakamura GetHeaderStrがTRUE(文字列が取得できた)で
        //GetKcの返り値が有効な場合のみkcSaveをセット
        if(GetHeaderStr(text,"meta>[^>]*http-equiv=¥"?Content-Type¥"?","content",
        sz,CCHWORD,0,0)){
            int kcTemp = GetKc(sz);
            if(kcTemp != KC_ERROR) text->kcSave = kcTemp;
        }
        //text->fClip = FALSE;
        txSelectQuit(text);
        //txSetDispEx(text);
        //txSetLy(text,ly);txJumpAddress(text,ad);
        txJumpAddress(text,ad);txSetLy(text,ly); // 1999.09.09 Imabeppu
    }

(後略)

}

私的改良

「デフォルトHTML」を複数指定可能にした

優先的に参照したい順に、セミコロン(;)で区切って指定してください(例:index.html;index.shtml)。

「ハイパーリンクの挿入」においてローカルのファイルを参照する場合、ファイル名が「デフォルトHTML」と同じなら相対URIからファイル名を削除するようにした

デフォルトHTMLがindex.htmlなら、「../pocketpc/index.html」が「../pocketpc/」になるわけです。個人的ちょっぴりこだわってるところなので対応してみました。

部分識別子(#hogehoge)が付いている場合でも、きちんとファイル名だけを抜いてくれます。たぶん。

同一ディレクトリの場合はただ空になってしまうと不正なリンクになってしまうので、ファイル名に"./"をセットします。たぶん。

人によってはこうなって欲しくない場合もあるかと思いますが、めんどくさいのでなるべく追加コード量を減らしたかったのでオプション化はしていません。気に入らないならソースを見てよろしくやってください(無責任)。

「imageの挿入」ダイアログで、align属性はDOCTYPEがTransitionalの場合のみ表示されるようにした

もともと実害はないのですが、やはり仕様に厳密な方が好みですので……。

「表の挿入」において「1行目はヘッド」オプションを拡張。ヘッダを「なし」、「1行目」、「1桁目」、「両方」から選ぶ方式にした

もとに戻したい場合はソースのuiInsertTableHtml関数の10行くらい上の「#if 1」を「#if 0」にすればOKです。

Ctrl+クリックによるURIジャンプの際、href属性値内のURIは必ずXHTMLプラグイン側で処理するようにした

標準ではWZ本体のオプション「URLの色分け」がONの場合はWZ側に処理を任せていますが、それだと「http://www.google.co.jp/search?sourceid=navclient&amp;hl=ja&amp;ie=utf8&amp;oe=utf8&amp;querytime=AVuE&amp;q=%E9%9B%AA%E6%9D%91%E5%B0%8F%E7%94%BA」というふうに文字実体参照が使われている場合、初めの";"までしかURIとして認識してくれません。XHTMLプラグイン側で処理すれば、属性値全体を取得してWebブラウザに渡すので、正しくリンク先に到達することができます。

Ctrl+クリックによるmailto:ジャンプ(メーラー立ち上げ)の際、数値文字参照&#64;を@に変換するようにした

かなり個人的な事情(spam、ウイルス避けのおまじないとしてメールアドレス内の@を数値文字参照で表記)に偏っています。気に入らないならソースを(以下略)。

Ctrl+クリックによるローカルジャンプ時、ファイルの拡張子がWZ共通設定の「バイナリファイルの拡張子」と一致したらWZではなく関連付けで開くようにした

画像やアーカイブファイルへのリンクを記述した際、ついCtrl+クリックしてWZで開いちゃったりしませんか。僕はします。そこで(WZ本体側で適切に設定していれば)画像ビューアやアーカイバで開けるようにしてみました。思い付き実装ですが結構気に入っています。

SearchLink関数で、pathSetModeの代わりにpathSetAbsoluteを使うように

ここはCtrl+クリックによるローカルジャンプと仕様をそろえて、デフォルトHTMLがある場合はそちらを開くようにするのがよいという判断により変更しました。

ダウンロード

XHTMLプラグイン Ver.1.22のソース(xhtml.txc)に対する差分ファイルになっています 。

パッチの当て方

パッチファイルはGNU patchを使って当てるものですが、N.Yamamotoさんのマクロ「safefile」の「safefile.patchtext」コマンドでも当てられますのでこの方が簡単です。

patch.exeもsafefileもようわからん!という人は、自己展開型差分ファイルを使ってください。XHTMLプラグインをインストールしたフォルダ(通常は「C:¥Program Files¥WZ EDITOR¥MACRO」)にxhtml122to122ynp5.exeを置いて実行すればOKです。

どちらもソースに対する差分ですので当てたらコンパイルし直してください。パッチが正常にあたれば、XHTMLプラグインのバージョンは「1.22+ynp5」になります。ynp5は「Y.Nakamuraのパッチその5」の意です。

更新履歴

Ver.1.22ynp5 2002/06/18(Tue)

謝辞

素晴らしいプラグインを作ってくださったy.mikomeさんに感謝します。

本パッチの作成にあたっては、WhiningZoneのM.Shibataさんに技術的アドバイスと一部コードの提供、また激励のお言葉(笑)をいただきました。ありがとうございます。

ビレッジセンターのHTML掲示板にて、不具合報告や改良ネタとなる発言をしてくださった方々に感謝します。

Copyright©1998-2005 Yujiro Nakamura All rights reserved.
本サイトに関するご連絡の方法はreadmeをご参照ください。
本Webページの無断引用、本Webページへの無断リンクを歓迎します(笑)。