home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DOS/V Power Report 1998 August
/
VPR9808B.BIN
/
APUPDATE
/
VC
/
Tx300d
/
TX300D.LZH
/
HTML.C
< prev
next >
Wrap
C/C++ Source or Header
|
1997-06-12
|
85KB
|
3,190 lines
// HTML support
// (c)1997 TY
// 970219 start
//2.99D 970331 TXCMDBASE対応
#include <windows.h>
#include <windowsx.h>
#include "dialog.h"
#include "outline.h"
//{###HTML}
//HTMLファイル専用の編集機能を提供します。
static BOOL htmlFlushCurTag(TX* text);
static BOOL txHtmlFlushArea(TX* textTarget,IFILE adrTop,IFILE adrEnd,int tag,BOOL fSelect);
//## tag base op.
int TXAPI tagFromStr(mchar* p)
{
return txOp(text,TXOP_TAGFROMSTR,(WPARAM)p,0);
}
mchar* TXAPI tagToStr(int tag)
{
return (mchar*)txOp(text,TXOP_TAGTOSTR,tag,0);
}
mchar* TXAPI tagPrint(mchar* dst,int tag)
{
*dst++ = '<';
strcpy(dst,tagToStr(tag));dst += strlen(dst);
return dst;
}
mchar* TXAPI tagPrintEx(tx* text,int tag,long atr,int tagmode,mchar *buff)
{
BOOL fColor = FALSE;
static mchar szNull[] = "";
if (tag == TAG_H) {
if (1 <= atr && atr <= 6) {
mchar* dst = buff;
*dst++ = '<';
if (tagmode == TAG_END) *dst++ = '/';
*dst++ = 'H';
*dst++ = atr + '0';
*dst++ = '>';
*dst = 0;
return buff;
}
}
if (1 <= tag && tag < TAG_N) {
mchar* dst = buff;
*dst++ = '<';
if (tagmode == TAG_END) {
*dst++ = '/';
}
strcpy(dst,tagToStr(tag));dst += strlen(dst);
*dst++ = '>';
*dst = 0;
return buff;
}
return "";
}
BOOL TXAPI tagIsParaatr(int tag)
{
switch(tag) {
case TAG_P:
case TAG_H:
case TAG_UL:
// case TAG_PRE:
case TAG_OL:
case TAG_DL:
case TAG_BLOCKQUOTE:
case TAG_LEFT:
case TAG_CENTER:
case TAG_RIGHT: return TRUE;
}
return FALSE;
}
//##tag atr
// 以下、タグの直後に置く
// [説明].説明
// [S]....シングルタグ
// [NN]...Netscape専用
// [IE]...IE専用
// [!IE]...IEではだめ
// 以下、タグの直前に置く
// [I]....タグ挿入専用
// [R]....タグのプロパティ専用
//2.99E 970403 アトリビュート毎にIE,NNを区別することはまだできていない、今後対応する予定
// とりあえず、対応していないブラウザでもアトリビュートは指定できるようにした。
static mchar* _tszfh[] = {
".見出し",
"H1 [見出し1] ALIGN=<LEFT|CENTER|RIGHT>",
"H2 [見出し2] ALIGN=<LEFT|CENTER|RIGHT>",
"H3 [見出し3] ALIGN=<LEFT|CENTER|RIGHT>",
"H4 [見出し4] ALIGN=<LEFT|CENTER|RIGHT>",
"H5 [見出し5] ALIGN=<LEFT|CENTER|RIGHT>",
"H6 [見出し6] ALIGN=<LEFT|CENTER|RIGHT>",
".段落体裁",
"DIV [複数の段落を揃える] ALIGN=<LEFT|RIGHT|CENTER|JUSTIFY>",
"PRE [テキストをそのまま表示] WIDTH=<VALUE>",
"P [段落を揃える] ALIGN=<LEFT|CENTER|RIGHT>",
"[I] P [段落を作る] [S]",
"BR [改行する] [S] CLEAR=<LEFT|RIGHT|ALL>",
"NOBR [改行しない]",//2.99C 970326 シングルタグではない
"WBR [改行のヒント] [S]",
"BLOCKQUOTE [引用]",
"CENTER [中央揃え]",
"MULTICOL [段組] [NN] COLS=<VALUE> GUTTER=<VALUE> WIDTH=<VALUE>",
"SPACER [スペースを空ける] [S] [NN] TYPE=<horizontal|vertical|block> SIZE=<VALUE> WIDTH=<VALUE> HEIGHT=<VALUE> ALIGN=<top|middle|bottom|left|right>",//NN //2.99C 970326 align修正
".水平線",
"HR [水平線] [S] ALIGN=<LEFT|RIGHT|CENTER> SIZE=<VALUE> WIDTH=<VALUE_PERCENT> NOSHADE COLOR=<COLOR>", ////2.99E 970403 COLORはIEのみとする予定
".文字装飾",
"BIG [大きい文字]",
"SMALL [小さい文字]",
"FONT [文字のサイズと色] SIZE=<7|6|5|4|3|2|1|+4|+3|+2|+1|-1|-2|-3|-4> COLOR=<COLOR>",// "FACE=<STR>",// FACE:NN
"BASEFONT [文字のサイズの基準] [S] SIZE=<7|6|5|4|3|2|1>",
"B [太字]",
"I [斜線]",
"EM [強調]",
"STRONG [最強調]",
"TT [タイプライタ書体]",
"CITE [引用書体]",
"CODE [プログラムコード書体]",
"DFN [定義書体]",
"KBD [キーボード書体]",
"SAMP [サンプル書体]",
"U [下線]",
"S [打ち消し線]",
"STRIKE [打ち消し線]",//2.99C 970326 new
"VAR [変数名を表現する書体]",
"ADDRESS [アドレスを表現する書体]",
"BLINK [文字を点滅] [NN]",
"SUP [上つき]",
"SUB [下つき]",
"MARQUEE [文字のスクロール] [IE] DIRECTION=<LEFT|RIGHT> BEHAVIOR=<SCROLL|SLIDE|ALTERNATE> LOOP=<VALUE_LOOP> SCROLLAMOUNT=<VALUE> SCROLLDELAY=<VALUE> BGCOLOR=<COLOR> WIDTH=<VALUE> HEIGHT=<VALUE> ALIGN=<TOP|MIDDLE|BOTTOM> HSPACE=<VALUE> VSPACE=<VALUE>",
".リンク",
"A [リンク] HREF=<URL> TARGET=<STR:_self|_blank|_parent|_top|title|main|contents> NAME=<STR>",//2.99C 970325 INPUT_STRWITHSEL化
"BASE [基準URLを指定] [S] HREF=<URL> TARGET=<STR:_self|_blank|_parent|_top|title|main|contents>",//2.99C 970325 INPUT_STRWITHSEL化
".画像",//2.97A 970302 ".図"だとアウトライン表示うまくない
"IMG [画像] [S] SRC=<URL> ALIGN=<TOP|BOTTOM|MIDDLE|LEFT|RIGHT> ALT=<STR> WIDTH=<VALUE> HEIGHT=<VALUE> BORDER=<VALUE> HSPACE=<VALUE> VSPACE=<VALUE> LOWSRC=<URL> ISMAP USEMAP=<URL>",
"IMG_DYNSRC [ムービーやVRML] [S] [IE] dynsrc=<URL> start=<fileopen|mouseover> controls=<VALUE_BOOL> loop=<VALUE_LOOP> loopdelay=<VALUE> src=<URL> alt=<STR>",//2.99C 970326
"MAP [マップ名の定義] NAME=<STR>",
"AREA [領域の定義] [S] SHAPE=<RECT|CIRCLE|POLYGON> COORDS=<STR> HREF=<URL> NOHREF",
".箇条書き",
"UL [箇条書き] COMPACT TYPE=<DISC|CIRCLE|SQUARE>",
"LI [箇条書き項目] [S] TYPE=<DISC|CIRCLE|SQUARE|A|a|I|i|1> VALUE=<VALUE>",// ULかOLかで、TYPEの値異なる
"OL [番号付き箇条書き] COMPACT TYPE=<A|a|I|i|1> START=<VALUE>",
"DL [定義型] COMPACT", //// COMPACTはNNのみにする予定
"DD [定義型の見出し] [S]",//2.99 970319
"DT [定義型の説明] [S]",//2.99 970319
"MENU COMPACT",
"DIR COMPACT",
".文書情報",
"BODY [本文] BACKGROUND=<URL> BGCOLOR=<COLOR> TEXT=<COLOR> LINK=<COLOR> VLINK=<COLOR> ALINK=<COLOR>",
"TITLE [タイトル]",
"HTML",
"HEAD [ファイル情報]",
// "ISINDEX PROMPT=<STR>",
"LINK REV=<STR> REL=<STR> HREF=<URL>",
"[R] WZHTMLNEW ページタイトル=<STR> 背景画像=<URL> 背景色=<COLOR> テキスト色=<COLOR> ホットテキスト色=<COLOR> 参照済み色=<COLOR> クリック時の色=<COLOR> 基準フォントサイズ=<7|6|5|4|3|2|1> ターゲットフレーム=<STR:_self|_blank|_parent|_top|title|main|contents> 基準URL=<URL>",//2.99C 970326
".フォーム",
"FORM [入力フォームの定義] ACTION=<URL> METHOD=<POST|GET> ENCTYPE=<MULTIPART|FORM-DATA>",
"INPUT [入力エリアとボタン] [S] TYPE=<text|password|checkbox|radio|image|hidden|submit|reset> NAME=<STR> VALUE=<STR> CHECKED SIZE=<VALUE> MAXLENGTH=<VALUE>",//2.98 970307 TYPEは小文字。大文字だと認識しないブラウザがある。
#if 1//2.99 970319 <select>...</select>、<option>はシングルタグ
"SELECT [選択メニュー] NAME=<STR> SIZE=<VALUE> MULTIPLE",
"OPTION [選択肢] [S] SELECTED",
#else
"SELECT [選択メニュー] [S] NAME=<STR> SIZE=<VALUE> MULTIPLE",
"OPTION [選択肢] SELECTED",
#endif
"TEXTAREA [テキスト入力エリア] ROWS=<VALUE> COLS=<VALUE> NAME=<STR> WRAP=<OFF|VIRTUAL|PHYSICAL>",
".表",
"TABLE [表] BORDER=<VALUE_BOOL> CELLSPACING=<VALUE> CELLPADDING=<VALUE> WIDTH=<VALUE_PERCENT> align=<left|right> bgcolor=<COLOR>",//2.99C 970326 align,bgcolor追加
"TD [要素] ALIGN=<LEFT|RIGHT|CENTER> VALIGN=<TOP|MIDDLE|BOTTOM> NOWRAP COLSPAN=<VALUE> ROWSPAN=<VALUE> WIDTH=<VALUE_PERCENT> BGCOLOR=<COLOR>",
"TH [見出し要素] ALIGN=<LEFT|RIGHT|CENTER> VALIGN=<TOP|MIDDLE|BOTTOM> NOWRAP COLSPAN=<VALUE> ROWSPAN=<VALUE> WIDTH=<VALUE_PERCENT> BGCOLOR=<COLOR>",
"TR [改行] [S] ALIGN=<LEFT|RIGHT|CENTER> VALIGN=<TOP|MIDDLE|BOTTOM> bgcolor=<color>",//2.99C 970326 bgcolor追加
"[I] TR [改行]",
"CAPTION [名前] ALIGN=<TOP|BOTTOM>",
"COL [セルオプション] [S] [NN] align=<center|left|right> span=<VALUE>",//2.99C 970326
#if 1//2.99E 970403
"COLGROUP [セルオプション] [S] [!IE] halign=<center|left|right> valigin=<middle|top|bottom> span=<VALUE> width=<VALUE>",//2.99C 970326
#else
"COLGROUP [セルオプション] [S] [NN] halign=<center|left|right> valigin=<middle|top|bottom> span=<VALUE> width=<VALUE>",//2.99C 970326
#endif
".フレーム",
"FRAMESET [フレーム] FRAMEBORDER=<yes|no> BORDER=<VALUE> BORDERCOLOR=<COLOR>",// ROWS,COLS 未対応 //// BORDERCOLORはNNのみ
"FRAME [フレームの内容] [S] SRC=<URL> NAME=<STR> TARGET=<STR:_blank|_self|_parent|_top> MARGINWIDTH=<VALUE> MARGINHEIGHT=<VALUE> SCROLLING=<YES|NO|AUTO> NORESIZE FRAMEBORDER=<yes|no> BORDERCOLOR=<COLOR>",//2.99C 970326 name->target
"NOFRAME [フレーム非対応ブラウザ用body]",//2.99C 970326
"IFRAME [フローティングフレーム] [IE] width=<VALUE> height=<VALUE> src=<URL>",//2.99C 970326
".オブジェクト、アプレット、スクリプト",
"APPLET [アプレット] CODE=<STR> PARAM NAME=<STR> CODEBASE=<URL> NAME=<STR> ALT=<STR> ALIGN=<LEFT|RIGHT|CENTER> WIDTH=<VALUE> HEIGHT=<VALUE> HSPACE=<VALUE> VSPACE=<VALUE>",
"PARAM [パラメータ] [S] NAME=<STR> VALUE=<VALUE>",
"EMBED [プラグイン] [S] SRC=<URL> WIDTH=<VALUE> HEIGHT=<VALUE>",
"NOEMBED [EMBEDタグに対応していないブラウザへの表示]",//2.99C 970326 シングルタグではない
"OBJECT [オブジェクト] CLASSID=<STR> CODEBASE=<URL> WIDTH=<VALUE> HEIGHT=<VALUE> NAME=<STR> ID=<STR>",
"SCRIPT [スクリプト] LANGUAGE=<STR>",
".その他",
"BGSOUND [BGM] [S] [IE] SRC=<URL> LOOP=<VALUE_LOOP>",
"COMMENT [コメント] [IE]",//2.99C 970326
NULL,
};
static mchar* _getcaption(mchar* szAtr)
{
if (!stricmp(szAtr,"align")) return "整列";
if (!stricmp(szAtr,"alink")) return "リンク中";
if (!stricmp(szAtr,"alt")) return "代替文章";
if (!stricmp(szAtr,"compact")) return "コンパクト";
if (!stricmp(szAtr,"height")) return "高さ";
if (!stricmp(szAtr,"noshade")) return "影なし";
if (!stricmp(szAtr,"size")) return "サイズ";
if (!stricmp(szAtr,"vlink")) return "読込済リンク";
if (!stricmp(szAtr,"width")) return "幅";
return szAtr;
}
static int getaccesskey(int ic)
{
int ret = ic + 'A';
if (ret >= 'H') ret++; //2.99D 970402 'H'はヘルプのために空ける
if (ret <= 'Z') return ret;
ret = ret - ('Z'+1) + '0';
if (ret <= '9') return ret;
return ' ';
}
static mchar* getcaption(mchar* szAtr,int ic)
{
static mchar buff[CCHWORD];
sprintf(buff,"%s(&%c)",_getcaption(szAtr),getaccesskey(ic));
return buff;
}
static mchar* getcaptionc(mchar* szAtr,int ic)
{
static mchar buff[CCHWORD];
sprintf(buff,"%s(&%c):",_getcaption(szAtr),getaccesskey(ic));
return buff;
}
static mchar* getcaptionref(mchar* szAtr,int ic)
{
static mchar buff[CCHWORD];
sprintf(buff,"%s(&%c)...",_getcaption(szAtr),getaccesskey(ic));
return buff;
}
#define INPUT_COLOR 1
#define INPUT_URL 2
#define INPUT_SELSTR 3 // like as <LEFT|CENTER|RIGHT>
#define INPUT_VALUE 4
#define INPUT_VALUE_PERCENT 5
#define INPUT_BOOL 6
#define INPUT_STR 7
#define INPUT_VALUE_BOOL 8 //2.97A 970228 0,1ならINPUT_BOOL、2以上ならINPUT_VALUE
#define INPUT_VALUE_LOOP 9 //2.97A 970302 INFINITE
#define INPUT_STRWITHSEL 10 //2.99C 970325 new INPUT_STR + 規定値
static mchar* strdup(mchar* sz)
{
int len = strlen(sz);
mchar* p = malloc(len + 1);
if (p) {
strcpylen(p,sz,len);
return p;
}
return NULL;
}
typedef struct {
mchar szAtr[32];
mchar szfilename[CCHPATHNAME];
COLORREF rgb;
BYTE fExist; // 存在したか?
BYTE fPercent; // %指定?
BYTE fInfinite; // INFINITE?
BYTE flag;
int idi;
int idColorButton; //2.99C 970325
int idDelColorButton; //2.99C 970325
mchar szSelStr[CCHWORD];
HSTRBLK sbSelStr;
DWORD value;
} ATRDATA;
static void inputFromSz(ATRDATA* data)
{
mchar* sz = data->szSelStr;
data->idi = 0;//2.99C 970325
if (!stricmp(sz,"<COLOR>")) {
data->idi = INPUT_COLOR;
return;
}
if (!stricmp(sz,"<URL>")) {
data->idi = INPUT_URL;
return;
}
if (!stricmp(sz,"<VALUE>")) {
data->idi = INPUT_VALUE;
return;
}
if (!stricmp(sz,"<VALUE_BOOL>")) {
data->idi = INPUT_VALUE_BOOL;
return;
}
if (!stricmp(sz,"<VALUE_LOOP>")) {
data->idi = INPUT_VALUE_LOOP;
return;
}
if (!stricmp(sz,"<VALUE_PERCENT>")) {
data->idi = INPUT_VALUE_PERCENT;
return;
}
if (!stricmp(sz,"<STR>")) {
data->idi = INPUT_STR;
return;
}
if (!strnicmp(sz,"<STR:",5)) {//2.99C 970325
data->idi = INPUT_STRWITHSEL;
}
if (
data->idi == INPUT_STRWITHSEL ||//2.99C 970325
(sz[0] == '<' && strchr(sz,'|'))
) {
mchar* szs;
if (data->idi == INPUT_STRWITHSEL) {
//2.99C 970325
szs = strdup(sz + 5);
} else {
szs = strdup(sz + 1);
data->idi = INPUT_SELSTR;
}
if (szs) {
mchar* sz = szs;
// delete tail '>'
int len = strlen(szs);
if (len && szs[len - 1] == '>') szs[len-1] = 0;
//
data->sbSelStr = sbNewAlloc(strlen(sz) + 100);
if (data->sbSelStr) {
if (data->idi != INPUT_STRWITHSEL) {
sbAdd(data->sbSelStr,"標準");
}
while(1) {
mchar* p = strchr(sz,'|');
if (!*sz) break;
if (p) {
*p = 0;
p++;
} else {
p = sz + strlen(sz);
}
sbAdd(data->sbSelStr,sz);
sz = p;
}
if (data->idi == INPUT_STRWITHSEL) {
sbReverse(data->sbSelStr);
}
}
free(szs);
}
return;
}
}
static int hextonum(mchar c)
{
if (isdigit(c)) return c - '0';
if ('A' <= c && c <= 'F') return c - 'A' + 10;
if ('a' <= c && c <= 'f') return c - 'a' + 10;
return -1;
}
static DWORD _tcolor[] = {
0x000000,0xFFFFFF,0xFF0000,0x00FF00,
0x0000FF,0xFF00FF,0xFFFF00,0x00FFFF,
0x000080,0x008080,0x008000,0x800000,
0x800080,0x808000,0x808080,0xC0C0C0,
};
static mchar* _tszcolor[] = {//2.99C 970325
"black(黒)",
"white(白)",
"red(赤)",
"lime(黄緑)",
"blue(青)",
"fuchsia(ピンク)",
"yellow(黄色)",
"aqua(水色)",
"navy(紺)",
"teal(深緑)",
"green(緑)",
"maroon(茶)",
"purple(紫)",
"olive(うぐいす色)",
"gray(灰色)",
"silver(銀色)",
};
static COLORREF rgbFromIndex(UINT i)
{
if (i >= 16) return 0;
DWORD col = _tcolor[i];
return RGB(col>>16,(col>>8)&0xFF,col&0xFF);
}
//2.99C 970325 new
static COLORREF rgbFromSz(mchar* szColor)
{
mchar* p = szColor;
if (*p == '#') {
p++;
int r,g,b;
r = hextonum(*p++) << 4;
r |= hextonum(*p++);
g = hextonum(*p++) << 4;
g |= hextonum(*p++);
b = hextonum(*p++) << 4;
b |= hextonum(*p++);
return RGB(r,g,b);
} else {
int lch = strlen(szColor);
for (int i = 0;i < 16;i++) {
if (!strnicmp(_tszcolor[i],szColor,lch)) {
mchar c = _tszcolor[i][lch];
if (c == 0 || c == '(') {
return rgbFromIndex(i);
}
}
}
}
return 0;
}
static int rgbToIndex(COLORREF rgb)
{
int r = GetRValue(rgb);
int g = GetGValue(rgb);
int b = GetBValue(rgb);
DWORD col = MAKELONG(MAKEWORD(b,g),MAKEWORD(r,0));
for (int i = 0;i < 16;i++) {
if (_tcolor[i] == col) return i;
}
return -1;
}
static void rgbPrint(COLORREF rgb,mchar* buff)
{
//2.99C 970325 new
mchar*dst = buff;
*dst++ = '#';
sprintf(dst,"%02X%02X%02X",GetRValue(rgb),GetGValue(rgb),GetBValue(rgb));dst += strlen(dst);
*dst = 0;
}
static BOOL atrMatch(mchar* szfh,ATRDATA* data,HSTRBLK sbColor)
{
// szfh:<>で括られたSZFH
mchar* p = szfh;
p += strGetWordLen(p);
while(1) {
p = strGetWordTop(p);
int len = strGetWordLen(p);
if (!len) break;
mchar szAtr[CCHWORD];
mchar szContent[CCHWORD] = {0};
sstrcpylen(szAtr,p,len);
p += len;
if (*p == 0 && len && p[-1] == '>') {
// 末尾の'>'を消去
szAtr[len-1] = 0;
}
{
mchar* q = strchr(szAtr,'=');
if (q) {
*q = 0;
sstrcpy(szContent,q + 1);
}
}
//information("[%s][%s]",szAtr,data->szAtr);
if (!stricmp(szAtr,data->szAtr)) {
data->fExist = TRUE;
if (szContent[0]) { // '='に続けて指定あり
pathFormLong(szContent);
mchar* p = szContent;
//information("[%s] %d",data->szAtr,data->idi);
switch(data->idi) {
case INPUT_COLOR: {
#if 1//2.99C 970325
data->rgb = rgbFromSz(szContent);
#else
if (*p == '#') {
p++;
int r,g,b;
r = hextonum(*p++) << 4;
r |= hextonum(*p++);
g = hextonum(*p++) << 4;
g |= hextonum(*p++);
b = hextonum(*p++) << 4;
b |= hextonum(*p++);
data->rgb = RGB(r,g,b);
} else {
if (sbColor) {
int lch = strlen(szContent);
for (int i = 2;i < 2 + 16;i++) {
mchar* sz = sbRead(sbColor,i);
if (!strnicmp(sz,szContent,lch) && sz[lch] == '(') {
data->rgb = rgbFromIndex(i - 2);
break;
}
}
}
}
#endif
break;
}
case INPUT_SELSTR:
case INPUT_URL:
case INPUT_STRWITHSEL://2.99C 970325
case INPUT_STR: {
sstrcpy(data->szfilename,szContent);
break;
}
case INPUT_VALUE_LOOP: {
if (!stricmp(szContent,"INFINITE")) {
data->fInfinite = TRUE;
} else {
data->value = atoi(szContent);
}
break;
}
case INPUT_VALUE_BOOL:
case INPUT_VALUE: {
data->value = atoi(szContent);
break;
}
case INPUT_VALUE_PERCENT: {
data->value = atoi(szContent);
data->fPercent = (strchr(szContent,'%') != NULL);
break;
}
}
} else { // '='なし
if (data->idi == INPUT_BOOL) {
data->flag = TRUE;
} else if (data->idi == INPUT_VALUE_BOOL) {
data->value = 1;
}
}
// information(szContent);
return TRUE;
}
}
return FALSE;
}
static BOOL atrCheckSupport(mchar* szfh,ATRDATA* tdata,int ndata,txstr szReport)
{
// szfh:<>で括られたSZFH
mchar* p = szfh;
p += strGetWordLen(p);
while(1) {
p = strGetWordTop(p);
int len = strGetWordLen(p);
if (!len) break;
mchar szAtr[CCHWORD];
sstrcpylen(szAtr,p,len);
p += len;
if (*p == 0 && len && p[-1] == '>') {
// 末尾の'>'を消去
szAtr[len-1] = 0;
}
{
mchar* q = strchr(szAtr,'=');
if (q) *q = 0;
}
{
BOOL fFound = FALSE;
for (int i = 0;i < ndata;i++) {
if (!stricmp(szAtr,tdata[i].szAtr)) {
fFound = TRUE;
break;
}
}
if (!fFound) {
if (szReport[0]) {
szReport += ",";
} else {
szReport = "アトリビュート ";
}
szReport += szAtr;
}
}
}
if (szReport[0]) {
szReport += " は未対応です";
// information(szReport);
return FALSE;
}
return TRUE;
}
#define IDD_SELCOLORTOP 100
#define IDD_SELCOLOREND 199
#define IDD_VALUETOP 200
#define IDD_VALUEEND 299
#define IDD_DELCOLORTOP 300//2.99C 970325
#define IDD_DELCOLOREND 399
#define IDD_REFERIMGSIZE 400
//2.99C 970325
typedef struct {
HSTRBLK sbColor;
ATRDATA* tdata;
int ndata;
} EDITCONTEXT;
static mchar _szColorStd[] = "標準色";
BOOL dlgprocEdit(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
{
switch(message) {
case WM_INITDIALOG: {
break;
}
case WM_COMMAND: {
int id = WM_COMMAND_GetId(wParam);
int notify = WM_COMMAND_GetNotify(wParam,lParam);
HDIALOG hd = dialogFromHwnd(hwnd);
EDITCONTEXT* context = (LPVOID)dialogGetCustdata(hd);
ATRDATA* data = context->tdata;
if (IDD_SELCOLORTOP <= id && id <= IDD_SELCOLOREND) {
if (id & 0x01) {
#if 1
for (int i = 0;i < context->ndata;i++,data++) {
if (data->idColorButton == id) {
dialogRead(hd);
data->rgb = rgbFromSz(data->szfilename);
if (txccGetColor(text,&data->rgb,"色の選択")) {
rgbPrint(data->rgb,data->szfilename);
sbAddHist(context->sbColor,data->szfilename);
dialogWrite(hd);
}
break;
}
}
return TRUE;
#else
ComboBox_SetCurSel(GetDlgItem(hwnd,id - 1),1);
#endif
}
} else if (IDD_VALUETOP <= id && id <= IDD_VALUEEND) {
if (!(id & 0x00) && notify == EN_CHANGE) {
mchar szbuff[CCHWORD];
Edit_GetText(GetDlgItem(hwnd,id),szbuff,cchof(szbuff));
Button_SetCheck(GetDlgItem(hwnd,id + 1),!szbuff[0]);
}
} else if (IDD_DELCOLORTOP <= id && id <= IDD_DELCOLOREND) {//2.99C 970325
for (int i = 0;i < context->ndata;i++,data++) {
if (data->idDelColorButton == id) {
dialogRead(hd);
if (
!stricmp(data->szfilename,_szColorStd) ||
strchr(data->szfilename,'(') //2.99D 970331 基本16色も削除できないようにした
) {
// 標準色は削除できない
information("標準色、基本16色は削除できません");//2.99D 970331 message
} else {
sbDel(context->sbColor,data->szfilename);
strcpy(data->szfilename,_szColorStd);
dialogWrite(hd);
}
break;
}
}
} else if (id == IDD_REFERIMGSIZE) {
//2.99C 970325 GIFのイメージのサイズが取得できるようにした
int width,height;
BOOL fOK = FALSE;
dialogRead(hd);
for (int i = 0;i < context->ndata;i++,data++) {
if (!stricmp(data->szAtr,"SRC")) {
mchar szfilename[CCHPATHNAME];
strcpy(szfilename,data->szfilename);
pathSetMode(szfilename,text->szfilename,NULL,PATH_ABSOLUTEDRIVE);
if (!pathIsExt(szfilename,".gif")) {
information("%s\nこのファイルのイメージサイズは取得できません。\nGIF形式のファイルだけイメージサイズが取得できます。",szfilename);
} else {
HFILE hfile = hfileOpen(szfilename);
if (hfile == HFILE_ERROR) {
information("%s\nが開けません。",szfilename);
} else {
mchar buff[0x500];
int lch = hfileRead(hfile,buff,0x500);
mchar* p = buff;
for (;lch--;p++) {
if (*p == ',' && lch >= 8) {
p++;
p += 4;
width = *(WORD*)p;p += 2;
height = *(WORD*)p;
fOK = TRUE;
break;
}
}
//
hfileClose(hfile);
}
}
break;
}
}
if (fOK) {
for (int i = 0;i < context->ndata;i++,data++) {
if (!stricmp(data->szAtr,"WIDTH")) {
data->value = width;
} else if (!stricmp(data->szAtr,"HEIGHT")) {
data->value = height;
}
}
dialogWrite(hd);
}
}
break;
}
}
return FALSE;
}
#define MAX_ATRDATA 20
typedef struct {
ATRDATA tdata[MAX_ATRDATA];
int ndata;
} TAGEDITATRARG;
static void dialogAddOkCancelHtmlhelp(HDIALOG hd,mchar* szTagName)
{
dialogCmdLFV(hd);
dialogOK(hd,10);
dialogCancel(hd,10);
if (*szTagName == '/') szTagName++;
//information("htmlwz " + szTagName);
//2.99F 970404 htmlwz.hlp 16bitにも対応
//2.99F 970404 text->szexedirをつけないとヘルプひらけないことがある
//2.99F 970404 ".hlp"がないとWindows3.1で開かない
//2.99F 970404 ""で括るとWinHelpで開けないが、strGetWordLenで切れちゃう。dialog.cを改良した
//2.99F 970404 WinNT4.0では32bitのヘルプ開けないので16bitで開く
if ((_fwin40 && _platform == WINDOWS95) || _fwinnt351) {
dialogHelpID(hd,10,"\"" + text->szexedir + "htmlwz.hlp\" " + szTagName,IDH_HTMLTAG);
} else {
dialogHelpID(hd,10,"\"" + text->szexedir + "htmlwz16.hlp\" " + szTagName,IDH_HTMLTAG);
}
}
static BOOL tagEditAtr(TX* text,mchar* szTag,txstr szResult,TAGEDITATRARG* ana)
{
// szTagを編集して結果をszResultに返す。
// charatr等のセットは行わない。
// information(szTag);
//2.99C 970326 anaを指定すると解析/入力結果を返す
BOOL ret = FALSE;
BOOL fErr = FALSE;
txstr szErr;
mchar szTagName[CCHWORD];
mchar* szfh = NULL;
int tag = tagFromStr(szTag);//2.99 970319
mchar* p = szTag + 1;
int lenTag = strGetWordLen(p);
if (strchrs(szTag,"\x0D\x0A")) {//2.99B 970322
information("このタグには改行コードが含まれているので編集できません。\nテキストモードで編集してください。");
return FALSE;
}
if (!strcmp(szTag,"<!--") || !strcmp(szTag,"-->")) {
information("コメントタグの編集はできません。");
return FALSE;
}
if (
//2.99B 970322
lenTag >= cchof(szTagName) ||
strlen(szTag) + 10 > 500 //2.99C 970326 CCHPATHNAMEだと足りなかった
) {
information("このタグは長すぎて編集できません。\nテキストモードで編集してください。");
return FALSE;
}
if (lenTag && p[lenTag-1] == '>') lenTag--;// アトリビュートなしの場合
sstrcpylen(szTagName,p,lenTag);//2.99B 970322 strcpy->sstrcpy
//2.99C 970326
int lenTagCmp = lenTag;
mchar szTagNameCmp[CCHWORD];
sstrcpy(szTagNameCmp,szTagName);
if (tag == TAG_IMG) {
//2.99C 970326 IMG_DYNSRC対応
if (stristr(szTag,"dynsrc")) {
sstrcpy(szTagNameCmp,"IMG_DYNSRC");
lenTagCmp = strlen(szTagNameCmp);
}
}
{
mchar* p;
for (int i = 0;p = _tszfh[i];i++) {
//2.97A 970302
if (*p == '.') continue;
if (*p == '[') {
if (!strnicmp(p,"[R]",3)) {
// "[R]"ならOK
p += 3;
p = strGetWordTop(p);
} else {
continue;
}
}
//
int len = strGetWordLen(p);
if (lenTagCmp == len && !strnicmp(szTagNameCmp,p,lenTag)) {//2.99C 970326 szTagName->szTagNameCmp,lenTag->lenTagCmp
szfh = p;
break;
}
}
if (!szfh) {
szErr = szTag + "のアトリビュートには対応していません";
fErr = TRUE;
}
}
p = szfh;
//
txstr szTitle;
if (!stricmp(szTagName,"WZHTMLNEW")) {
szTitle = "新規作成 - HTML";
} else {
szTitle = szTagName;
szTitle += " タグのアトリビュート";
}
HDIALOG hd = dialog(szTitle);
EDITCONTEXT context;
structClear(context);
dialogSetCustdata(hd,(DWORD)&context);
dialogSetHookEx(hd,"\m.dlgprocEdit");
int idSelColor = IDD_SELCOLORTOP;
int idDelColor = IDD_DELCOLORTOP;
int idValue = IDD_VALUETOP;
//
ATRDATA tdata[MAX_ATRDATA];
memset(tdata,0,sizeof(tdata));
context.tdata = tdata;
//2.99C 970325 色にヒストリを付けたので全面改良
static mchar _szhistColor[] = "rgbHtml";
HSTRBLK sbColor = historyOpen(_szhistColor,2048);
context.sbColor = sbColor;
// skip tag
if (p) p += strGetWordLen(p);
int n = 0;
if (!fErr) {
int ic = 0;
for (int i = 0;;i++) {
if (i == MAX_ATRDATA) {
szErr = "タグ ";
szErr += szTagName;
szErr += " のアトリビュートデータが複雑すぎます";
fErr = TRUE;
break;
}
ATRDATA* data = &tdata[i];
p = strGetWordTop(p);
int len = strGetWordLen(p);
if (!len) break;
mchar szbuff[CCHWORD];
sstrcpylen(szbuff,p,len);
p += len;
if (szbuff[0] == '[') {
//2.97A 970302 []内は無視
i--;
continue;
}
{
mchar* q = strchr(szbuff,'=');
if (q) {
*q = 0;
sstrcpy(data->szSelStr,q + 1);
inputFromSz(data);
} else {
data->idi = INPUT_BOOL;
}
sstrcpy(data->szAtr,szbuff);
}
atrMatch(szTag,data,sbColor);
switch(data->idi) {
case INPUT_COLOR: {
if (sbColor) {
dialogSetH(hd);
if (data->fExist) {
int icolor = rgbToIndex(data->rgb);
if (icolor >= 0) {
strcpy(data->szfilename,_tszcolor[icolor]);
} else {
rgbPrint(data->rgb,data->szfilename);
sbAddHist(sbColor,data->szfilename);//2.99F 970403 色のヒストリに存在しない色がアトリビュート指定されていたときに取り込む様にした。
}
} else {
strcpy(data->szfilename,_szColorStd);
}
dialogControlID(hd,idSelColor++);
dialogSelectStrH(hd,getcaptionc(data->szAtr,ic++),data->szfilename,CCHPATHNAME32,20,20,sbColor);
#if 1//2.99C 970325
data->idColorButton = idSelColor;
dialogControlID(hd,idSelColor++);
dialogButton(hd,getcaptionref("参照",ic++),NULL,11);
//
data->idDelColorButton = idDelColor;
dialogControlID(hd,idDelColor++);
dialogButton(hd,getcaption("ヒストリから削除",ic++),NULL,16);
#else
dialogControlID(hd,idSelColor++);
dialogColor(hd,getcaptionref("参照",ic++),data->szAtr,&data->rgb,11,NULL);
#endif
dialogSetV(hd);
dialogLF(hd);
}
break;
}
case INPUT_URL: {
#if 1//3.00A3 970508 <A>や<IMG>タグのアトリビュートで、相対/ドライブ名なし/...の選択ができるようにした。
dialogControlRefer(hd,"-html *.*");
#else
#if 1//3.00A 970502 INPUT_URLの参照マスクを"*.*"にした
dialogControlRefer(hd,"-r *.*");
#else
dialogControlRefer(hd,"-r *.gif");
#endif
#endif
dialogStrC(hd,getcaptionc(data->szAtr,ic++),data->szfilename,20,CCHPATHNAME32,30);
break;
}
case INPUT_STR: {
dialogStrC(hd,getcaptionc(data->szAtr,ic++),data->szfilename,20,CCHPATHNAME32,30);
break;
}
case INPUT_STRWITHSEL: {//2.99C 970325
dialogControlHist(hd,data->sbSelStr);
dialogStrC(hd,getcaptionc(data->szAtr,ic++),data->szfilename,20,CCHPATHNAME32,30);
break;
}
case INPUT_SELSTR: {
if (data->sbSelStr) {
dialogSelectStrH(hd,getcaptionc(data->szAtr,ic++),data->szfilename,CCHPATHNAME32,20,20,data->sbSelStr);
}
break;
}
case INPUT_VALUE_PERCENT:
case INPUT_VALUE_BOOL:
case INPUT_VALUE_LOOP:
case INPUT_VALUE: {
dialogSetH(hd);
BOOL fReferImgSize = FALSE;//2.99C 970325
dialogControlID(hd,idValue++);
if (tag == TAG_IMG && !stricmp(data->szAtr,"WIDTH")) fReferImgSize = TRUE;//2.99C 970325
dialogInt(hd,getcaptionc(data->szAtr,ic++),&data->value,20,5);
//
dialogControlReverseBool(hd);
dialogControlID(hd,idValue++);
dialogCheckB(hd,getcaption("標準値を使用",ic++),&data->fExist);
//
if (data->idi == INPUT_VALUE_PERCENT) dialogCheckB(hd,getcaption("%指定",ic++),&data->fPercent);
if (data->idi == INPUT_VALUE_LOOP) dialogCheckB(hd,getcaption("無限ループ",ic++),&data->fInfinite);
//
if (fReferImgSize) {//2.99C 970325
dialogControlID(hd,IDD_REFERIMGSIZE);
dialogButton(hd,getcaptionref("参照",ic++),NULL,11);
}
dialogSetV(hd);
dialogLF(hd);
break;
}
case INPUT_BOOL: {
dialogCheckB(hd,getcaption(data->szAtr,ic++),&data->flag);
break;
}
default: {
dialogCaption(hd,data->szAtr);
break;
}
}
}
n = i;
context.ndata = n;
if (!atrCheckSupport(szTag,tdata,n,szErr)) fErr = TRUE;
if (n == 0) {//2.97A 970302
szErr = szTag + "のアトリビュートには対応していません";
fErr = TRUE;
}
}
if (fErr) {
dialogTerm(hd);
HDIALOG hd = dialog(szTitle);
szResult = szTag;
dialogStr(hd,"タグ(&T):",szResult,16,40);
dialogCaptionDynamic(hd,szErr,60);
//2.99D 970402 HTMLタグプロパティにヘルプボタン追加
dialogAddOkCancelHtmlhelp(hd,szTagName);
if (dialogOpen(hd)) {
ret = TRUE;
}
} else {
int modeTable = (tag == TAG_TH);
if (tag == TAG_TD || tag == TAG_TH) {//2.99 970319 <TD>,<TH>切り替えできるようにした
dialogRadioID(hd,&modeTable,"<TD>タグ","<TH>タグ");
}
//2.99D 970402 HTMLタグプロパティにヘルプボタン追加
dialogAddOkCancelHtmlhelp(hd,szTagName);
if (dialogOpen(hd)) {
ret = TRUE;
szResult = "<";
if (tag == TAG_TD || tag == TAG_TH) {//2.99 970319
if (modeTable) {
szResult += "TH";
} else {
szResult += "TD";
}
} else {
szResult += szTagName;
}
for (int i = 0;i < n;i++) {
ATRDATA* data = &tdata[i];
switch(data->idi) {
case INPUT_COLOR: {
data->fExist = (stricmp(data->szfilename,_szColorStd) != 0);
break;
}
case INPUT_STRWITHSEL://2.99C 970325
case INPUT_STR:
case INPUT_URL: data->fExist = (data->szfilename[0] != 0);break;
case INPUT_SELSTR: data->fExist = (strcmp(data->szfilename,"標準") != 0);break;
case INPUT_BOOL: data->fExist = data->flag;break;
case INPUT_VALUE_BOOL: data->fExist = (data->value != 0);break;
}
if (data->fExist) {
mchar buff[20];
szResult += " ";
szResult += data->szAtr;
switch(data->idi) {
case INPUT_COLOR: {
#if 1//2.99C 970325
if (data->szfilename[0] == '#') {
szResult += "=";
szResult += data->szfilename;
} else {
mchar* p = strchr(data->szfilename,'(');
if (p) *p = 0;
szResult += "=";
szResult += data->szfilename;
}
#else
if (!stricmp(data->szfilename,sbRead(sbColor,1))) {
// 詳細で指定した色
szResult += "\"";
rgbPrint(data->rgb,buff);
szResult += "\"";
szResult += "=";
szResult += buff;
} else {
mchar* p = strchr(data->szfilename,'(');
if (p) *p = 0;
szResult += "=";
szResult += data->szfilename;
}
#endif
break;
}
case INPUT_STRWITHSEL://2.99C 970325
case INPUT_STR:
case INPUT_URL: {
szResult += "=\"";
szResult += data->szfilename;
szResult += "\"";
break;
}
case INPUT_SELSTR: {
szResult += "=";
szResult += data->szfilename;
break;
}
case INPUT_VALUE: {
sprintf(buff,"%ld",data->value);
szResult += "=";
szResult += buff;
break;
}
case INPUT_VALUE_LOOP: {
if (data->fInfinite) {
szResult += "=INFINITE";
} else {
sprintf(buff,"%ld",data->value);
szResult += "=";
szResult += buff;
}
break;
}
case INPUT_VALUE_BOOL: {
if (data->value >= 2) {
sprintf(buff,"%ld",data->value);
szResult += "=";
szResult += buff;
}
break;
}
case INPUT_VALUE_PERCENT: {
sprintf(buff,"%ld",data->value);
szResult += "=";
szResult += buff;
if (data->fPercent) {
szResult += "%";
}
break;
}
}
}
}
szResult += ">";
// information("%s",szResult);
}
}
// delete
for (int i = 0;i < n;i++) {
ATRDATA* data = &tdata[i];
if (data->sbSelStr) {
sbDelete(data->sbSelStr);
data->sbSelStr = NULL;//2.99C 970326
}
}
if (ana) {//2.99C 970326
memcpy(ana->tdata,tdata,sizeof(ana->tdata));
ana->ndata = n;
}
if (sbColor) {
historyClose(_szhistColor,sbColor);
}
return ret;
}
#if 0//3.00A2 970505 txGetParaRear API化された
static int txGetParaRear(TX* text,txstr szpara)
{
txstr szbuff(500);
IFILE adr = txGetAddress(text);
IFILE adrParatop = txGetParaTop(text);
int ret = txGetPara(text,szbuff);
IFILE d = adr - adrParatop;
szpara = &szbuff[d];
return ret - d;
}
#endif
static BOOL _uiPropertyTag(TX* text,BOOL fNoFlush)
{
// カーソル位置から最も近いタグのアトリビュートを編集。
// ダイアログでOKしたかどうか返す。
BOOL ret = FALSE;
txstr szResult(500);
if (text->editmode) {
if (txGetChar(text) == CHAR_PLUG) {
LPVOID plug = txGetCurPlug(text);
if (!plug) return FALSE;
int modePlug = ((PLUGHEAD*)plug)->modePlug;
mchar* szTag = NULL;
switch(modePlug) {
case PLUG_HTML_TAG: szTag = ((PLUGHTMLTAG*)plug)->szTag;break;
case PLUG_TAB: szTag = ((PLUGTAB*)plug)->szTag;break;
case PLUG_IMG: szTag = ((PLUGIMG*)plug)->szTag;break;
case PLUG_IMG_LINK: szTag = ((PLUGIMG_LINK*)plug)->szTag;break;
case PLUG_HR: szTag = ((PLUGHR*)plug)->szTag;break;
}
if (szTag) {
UINT offSzTag = (LPBYTE)szTag - (LPBYTE)plug;
if (tagEditAtr(text,szTag,szResult,NULL)) {
//information(szResult);
int cch = strlen(szResult) + 1;
LPVOID plug1 = plugatrNewEx(text,modePlug,cch);
// plugatrNewExで、plugが無効になる可能性があるので
// Readし直す。
LPVOID plug0 = txGetCurPlug(text);
if (plug1) {
txSetUndisp(text);
{
memcpy(plug1,plug0,offSzTag);
*((WORD*)((LPBYTE)plug1 + offSzTag - 2)) = cch;
strcpy((LPBYTE)plug1 + offSzTag,szResult);
//
if (modePlug == PLUG_TAB) {
//2.99 970319 TDのALIGNの変更がすぐに画面に反映されるようにした
PLUGTAB* plug = plug1;
int modeAlign = ALIGN_LEFT;
mchar* p = stristr(szResult,"align");
if (p) {
p += strlen("align");
if (*p == '=') {
p++;
if (strimatch(p,"right")) {
modeAlign = ALIGN_RIGHT;
} else if (strimatch(p,"center")) {
modeAlign = ALIGN_CENTER;
}
}
}
plug->modeAlign = modeAlign;
plug->cxIndent = 0;
}
//
txDeleteChar(text);
txInsertPlug(text,plug1);
txLeft(text);
//
if (!fNoFlush) htmlFlushCurTag(text);//2.97 970222
ret = TRUE;
}
txSetDisp(text);
} else {
////err
}
}
}
}
} else {
if (txGetChar(text) != '<') {
if (!txSearchEx(text,"<",SEARCH_PREV|SEARCH_NOSELECT)) return FALSE;
}
txstr szline;
txGetParaRear(text,szline);
mchar* p = strchr(szline,'>');
if (p) {
p[1] = 0;
// information(szline);
if (tagEditAtr(text,szline,szResult,NULL)) {
txSetUndisp(text);
{
txDeleteBytes(text,strlen(szline));
txCurInsertBuff(text,szResult,strlen(szResult));
ret = TRUE;
}
txSetDisp(text);
}
}
}
return ret;
}
BOOL TXCMDBASE uiPropertyTag(TX* text)
{
if (txGetCurPlugmode(text) == PLUG_LINK) {
return call("word.txuiLink");
} else {
IFILE adr = txGetAddress(text);
IFILE adrCurscreen = txGetAddressCurscreen(text);
BOOL fMove = FALSE;
PLUGTAB* plug;
if (
text->editmode &&
!txIsCurReturn(text) && //2.99C 970326 表の改行の上では表のプロパティは開かないようにした
(plug = txIsCurParaIncludeTable(text))
) {
//2.99 970319 <TD>のプロパティがわかりにくかった
if (txGetCurPlugmode(text) == PLUG_TAB) {
information("テーブルタグ<TD>,<TH>のプロパティを開くには、プロパティを開きたいセルの中の文字にカーソルを合わせて「書式|タグのプロパティ」を実行してください。");
return FALSE;// カーソルが縦線上なら何もしない。
}
PLUGHTMLTAG* plugNow = txGetCurPlug(text);//2.99C 970326
#if 1//2.99H 970405
if (
plugNow &&
plugNow->head.modePlug == PLUG_HTML_TAG
) {
//2.99H 970405 表の中のHTMLタグのプロパティ編集ができなかった
} else {
fMove = TRUE;
txSetUndisp(text);
text->fUndispCursor++;//2.99C 970326
//
txJumpParaTop(text);
while(1) {
if (txIsCurReturn(text)) break;
if (txGetCurPlug(text) == plug) break;
if (!txRight(text)) break;
}
}
#else
if (
plugNow &&
plugNow->head.modePlug == PLUG_HTML_TAG &&
plugNow->tag == TAG_TR
) {
//2.99C 970326 <TR>タグの上で<TD>のプロパティが開くことがあった
} else {
fMove = TRUE;
txSetUndisp(text);
text->fUndispCursor++;//2.99C 970326
//
txJumpParaTop(text);
while(1) {
if (txIsCurReturn(text)) break;
if (txGetCurPlug(text) == plug) break;
if (!txRight(text)) break;
}
}
#endif
}
BOOL ret = _uiPropertyTag(text,FALSE);
if (fMove) {
txJumpAddress(text,adr);
txSetLyCurscreen(text,adrCurscreen);
text->fUndispCursor--;//2.99C 970326
txSetDisp(text);
}
return ret;
}
}
//## new html file
permanent txstr p_szNewpage(500,"<WZHTMLNEW ページタイトル=homepage>");
#define NP_TITLE 0 // ページタイトル
#define NP_BACKGROUND 1 // 背景画像
#define NP_BGCOLOR 2 // 背景色
#define NP_TEXT 3 // テキスト色
#define NP_LINK 4 // ホットテキスト色
#define NP_VLINK 5 // 参照済み色
#define NP_ALINK 6 // クリック時の色
#define NP_BASEFONT 7 // 基準フォントサイズ
#define NP_TARGET 8 // ターゲットフレーム
#define NP_URL 9 // 基準URL
#define data(i) (ana->tdata[i].szfilename)
#define dataExist(i) (ana->tdata[i].fExist)
static void datainsert(TX* text,mchar* szCaption,int id,TAGEDITATRARG* ana)
{
if (dataExist(id)) {
txInsertChar(text,' ');
txInsert(text,szCaption);
txInsert(text,"=\"");
txInsert(text,data(id));
txInsertChar(text,'"');
}
}
BOOL TXAPI uiNewPage(TX* text)
{
//「新規作成 - HTML」ダイアログ
//2.99C 970326 new
BOOL ret = FALSE;
txstr szResult(500);
TAGEDITATRARG _ana;
TAGEDITATRARG* ana = &_ana;
if (tagEditAtr(text,p_szNewpage,szResult,ana)) {
p_szNewpage = szResult;
//information(szResult);
//
int editmode0 = text->editmode;
txSetEditmode(text,0);
txSetUndisp(text);
//
txInsertf(text,"<HTML>\n<HEAD>\n<!--MadeByWZ-->\n");
txInsertf(text,"<TITLE>%s</TITLE>\n",data(NP_TITLE));
//
if (dataExist(NP_URL) || dataExist(NP_TARGET)) {
txInsert(text, "<BASE");
datainsert(text,"URL",NP_URL,ana);
datainsert(text,"TARGET",NP_TARGET,ana);
txInsert(text,">");
}
txInsert(text,"</HEAD>\n");
//
txInsert(text,"<BODY");
datainsert(text,"BACKGROUND",NP_BACKGROUND,ana);
datainsert(text,"BGCOLOR",NP_BGCOLOR,ana);
datainsert(text,"TEXT",NP_TEXT,ana);
datainsert(text,"LINK",NP_LINK,ana);
datainsert(text,"VLINK",NP_VLINK,ana);
datainsert(text,"ALINK",NP_ALINK,ana);
txInsert(text, ">");
//
if (dataExist(NP_BASEFONT)) txInsertf(text,"<BASEFONT SIZE=%s>\n",data(NP_BASEFONT));
txInsert(text,"\n\n</BODY>\n</HTML>\n");
//
txPrevPara(text);txPrevPara(text);txPrevPara(text);
txSetEditmode(text,editmode0);
if (editmode0) txCurInsertReturn(text);
txSetDisp(text);
ret = TRUE;
}
return ret;
}
//##tag base insert
BOOL TXAPI txInsertHtmlSzTag(TX* text,mchar* szTag,int tag)
{
if (text->editmode) {
int cch = strlen(szTag) + 1;
PLUGHTMLTAG* plug = plugatrNewEx(text,PLUG_HTML_TAG,cch);
if (plug) {
plug->cchTagAlloc = cch;
plug->tag = tag;
if (tag == TAG_COMMENT) {
//2.99D 970331 <!-- -->は特別扱い
plug->fTagTop = (szTag[0] == '<');
} else {
plug->fTagTop = (szTag[1] != '/');
}
strcpy(plug->szTag,szTag);
txInsertPlug(text,plug);
/// txDispAll(text);
return TRUE;
}
} else {
txInsert(text,szTag);
return TRUE;
}
return FALSE;
}
BOOL TXAPI txInsertTag(TX* text,mchar* szline)
{
//2.99 970319
mchar* p = strchr(szline,'<');
if (p) {
int paramode = 0;//2.99 970319
// 1...シングルタグの場合はタグの前で改行。ペアタグの場合は、開始タグの前と終了タグの後で改行
// 2...シングルタグの場合はタグの後で改行。
// 3...シングルタグの場合はタグの前後で改行。ペアタグの場合、開始タグの前後、終了タグの前後で改行
mchar *pend = strchr(szline,'>');
if (pend) {
BOOL fSingle = (pend[1] != '-');
pend[1] = 0;
mchar* szTag = p;
txstr szBuff;//2.99C 970326
{//2.99C 970326 IMG_DYNSRC対応
mchar* p = strchr(szTag,'_');
if (p) {
szBuff = szTag;
szBuff[p - szTag] = ' ';
szBuff[pend - szTag] = 0;
szBuff += "=\"\">";
szTag = szBuff;
}
}
int tag = tagFromStr(szTag);
mchar* szTagEnd = pend + 2; // 終了タグ
{//2.99 970320 for アルファベット順
mchar* p = strchr(szTagEnd,'>');
if (p) p[1] = 0;
}
switch(tag) {
case TAG_OL:
case TAG_DL:
case TAG_UL:
case TAG_BLOCKQUOTE:
case TAG_SCRIPT://2.99C 970326
case TAG_IECOMMENT://2.99C 970326
case TAG_MAP://2.99C 970326
case TAG_APPLET://2.99C 970326
case TAG_OBJECT://2.99C 970326
case TAG_NOFRAME://2.99C 970326
case TAG_IFRAME://2.99C 970326
case TAG_SELECT: paramode = 3;break;
}
switch(tag) {
case TAG_P:
case TAG_H:
case TAG_LEFT:
case TAG_CENTER:
case TAG_RIGHT:
case TAG_OPTION: paramode = 1;break;
}
switch(tag) {//2.99D 970331 タグの挿入:<BR>の後で改行を入れるようにした
case TAG_BR: paramode = 2;break;
}
//
txSetUndisp(text);
if (fSingle) {
if (text->fClip) {
txSelectDelete(text);
}
if ((paramode == 1 || paramode == 3) && !txIsCurParaTop(text)) txInsertReturn(text);//2.99 970319
txInsertHtmlSzTag(text,szTag,tag);
if (paramode >= 2 && !txIsCurReturn(text)) txInsertReturn(text);//2.99 970319
} else {
if (text->fClip) {
IFILE adr = txGetAddressSelectTop(text);
IFILE adrEnd = txGetAddressSelectEnd(text);
// 終了タグ
txJumpAddress(text,adrEnd);
if (paramode == 3) txInsertReturn(text);//2.99 970319
txInsertHtmlSzTag(text,szTagEnd,tag);
if (paramode && !txIsCurParaTop(text)) {
//2.99 970319
txInsertReturn(text);
txLeft(text);
}
txSelectEx(text,CLIP_CHAR);
// 開始タグ
txJumpAddress(text,adr);
if (paramode && !txIsCurParaTop(text)) txInsertReturn(text);//2.99 970319
txInsertHtmlSzTag(text,szTag,tag);
if (paramode == 3) {
txInsertReturn(text);//2.99 970319
txLeft(text);
}
txLeft(text);
//
} else {
// 開始タグ
if (paramode && !txIsCurParaTop(text)) txInsertReturn(text);//2.99 970319
txInsertHtmlSzTag(text,szTag,tag);
if (paramode == 3) txInsertReturn(text);//2.99 970319
//2.99C 970326
IFILE adrCurscreen = txGetAddressCurscreen(text);
IFILE adr = txGetAddress(text);
// 終了タグ
if (paramode == 3 && !txIsCurParaTop(text)) txInsertReturn(text);//2.99 970319
txInsertHtmlSzTag(text,szTagEnd,tag);
if (paramode && !txIsCurParaTop(text)) txInsertReturn(text);//2.99 970319
//2.99C 970326 タグの挿入:開始タグと終了タグの間にカーソルを置くようにした
txJumpAddress(text,adr);
txSetLyCurscreen(text,adrCurscreen);
}
}
if (text->fClip) text->fClipMouse = TRUE;
txSetDisp(text);
}
}
return TRUE;
}
BOOL TXCMDBASE uiInsertTagComment(TX* text)
{
// コメントを挿入
HDIALOG hd = dialog("コメント");
txstr sz;
dialogStr(hd,"コメント(&C):",sz,10,30);
if (dialogOpen(hd)) {
#if 1//2.99D 970331 新コメントに対応
txInsertHtmlSzTag(text,"<!--",TAG_COMMENT);
txInsert(text,sz);
txInsertHtmlSzTag(text,"-->",TAG_COMMENT);
return TRUE;
#else
sz = "<!-- " + sz;
sz += " -->";
return txInsertHtmlSzTag(text,sz,TAG_COMMENT);
#endif
}
return FALSE;
}
BOOL TXCMDBASE insertTag(mchar* szTag)
{
// シングルタグの挿入
// szTagは、"WBR"のように指定
// 「html.insertTag([WBR])」に様にコマンド指定してメニューに割り付けられます。
//2.99C 970326 new
txstr szline;
szline = "<";
szline += szTag;
szline += ">";
return txInsertTag(text,szline);
}
BOOL TXCMDBASE insertTagContainer(mchar* szTag)
{
// コンテナタグの挿入
// szTagは、"P align=center"のように指定
// 「html.insertTagContainer([P align=center])」に様にコマンド指定してメニューに割り付けられます。
//2.99C 970326 new
txstr szline;
szline = "<";
szline += szTag;
szline += ">-</";
{
txstr sz;
int len = strGetWordLen(szTag);
txstrcpylen(sz,szTag,len);
szline += sz;
szline += ">";
}
//information(szline);
return txInsertTag(text,szline);
}
permanent BOOL p_modeUiInsertTag = 0;//2.99 970320 旧p_fAlphabetOrder
#define IT_CATEGORY 0
#define IT_LIST 1
#define IT_DIRECT 2
static BOOL _uiInsertTagDirect(TX* text,BOOL fSw)
{
//2.99C 970327 new
HDIALOG hd = dialog("タグの挿入");
static BOOL fPair = FALSE;
static txstr szTag;
dialogSetContexthelp(hd,TRUE);
dialogControlHelp(hd,432);
dialogStr(hd,"タグ(&T):",szTag,10,30);
dialogControlHelp(hd,433);
dialogCheck(hd,"閉タグも挿入(&P)",&fPair);
//
int iddCategory = 0;
int iddList = 0;
if (fSw) {
int cx = 19;
dialogLFV(hd);
dialogOK(hd,cx);
dialogCancel(hd,cx);
iddCategory = dialogCmd(hd,"機能順(&C) >>",cx);
iddList = dialogCmd(hd,"アルファベット順(&L) >>",cx);
}
int ret;
if (ret = dialogOpen(hd)) {
if (ret == iddCategory) {
p_modeUiInsertTag = IT_CATEGORY;
return -1;
} else if (ret == iddList) {
p_modeUiInsertTag = IT_LIST;
return -1;
} else {
if (fPair) {
return insertTagContainer(szTag);
} else {
return insertTag(szTag);
}
}
}
return FALSE;
}
//2.99C 970327 new
BOOL TXCMD uiInsertTagDirect(TX* text)
{
// タグを直接入力して挿入
return _uiInsertTagDirect(text,FALSE);
}
//2.97B 970303 new
insertP
{
// <P>を挿入
#if 1///3.00A 970427 <P>の挿入を、改行+<P>に。テキスト->体裁時の<P>の変換と統一
txInsertReturn(text);
txInsertHtmlSzTag(text,"<P>",TAG_P);
return TRUE;
#else
txInsertHtmlSzTag(text,"<P>",TAG_P);
txInsertReturn(text);
return TRUE;
#endif
}
static BOOL IsCurParaIncludeTag(TX* text,int tag)
{
// 論理行頭からカーソル位置の手前までの間にtagがあるかどうか返す
//3.00A2 970503 new
if (text->editmode == 0) return FALSE;
IFILE paraTop = txGetParaTop(text);
if (paraTop < text->temp1) paraTop = text->temp1;
IMEM off = paraTop - text->temp1;
{
mchar* p = text->buff + off;
IMEM cb = text->cur0 - off;
for (;cb--;p++) {
if (*p == CHAR_PLUG) {
CHARATR charatr;
charatrRead(text,text->temp1 + (p - text->buff),&charatr);
PLUGHTMLTAG* plug = plugatrRead(text,charatrGetPlug(charatr));
if (plug->head.modePlug == PLUG_HTML_TAG) {
if (plug->tag == tag) return TRUE;
}
}
}
}
return FALSE;
}
//2.97B 970303 new
insertBR
{
// <BR>を挿入
txInsertHtmlSzTag(text,"<BR>",TAG_BR);
if (text->editmode == 0 && !text->fOverWrite) {
//2.99D 970401 insertBRでオートインデントが効くようにした
txWriteReturn(text);
} else {
#if 1//3.00A 970427 <BR>の挿入で、<Table>,<LI>内では改行しないようにした
PARAATR paraatr;
paraatrRead(text,text->npara,¶atr);
if (
paraatr.fArticle ||
txIsCurParaIncludeTable(text) ||
IsCurParaIncludeTag(text,TAG_DT) || //3.00A2 970503 <BR>の挿入で、<DT>,<DD>内では改行しないようにした
IsCurParaIncludeTag(text,TAG_DD) //3.00A2 970503
) {
// 改行しない
} else {
txInsertReturn(text);
}
#else
txInsertReturn(text);
#endif
}
return TRUE;
}
//2.99 970320
extern "paraform" void TXAPI txInsertNspace(TX* text,int nspace,BOOL fJspace);
static BOOL _uiInsertTag(TX* textTarget)
{
// HTMLのタグを挿入します。
// 挿入したタグの解釈はしません。
//2.97A 970302 new
//2.99 970320 renew 機能順/アルファベット順が選択できるようにした
static int _isel;
int modeHtml = text->share->config.modeHtml;
int lchLine = CCHWORD;//2.99 970320
int ret = 0;
TX _txBody;
TX* text = &_txBody;
if (txInit(text,NULL)) {
// 設定がなくても正常に動作するように
strcpy(text->tsztitle[0],".");
strcpy(text->tsztitle[1],"..");
strcpy(text->tsztitle[2],"");
//
mchar* sz;
for (int i = 0;sz = _tszfh[i];i++) {
mchar* p = sz;
if (*p == '.') {
if (p_modeUiInsertTag == IT_CATEGORY) {
txInsert(text,p);
txInsertReturn(text);
}
} else {
if (*p == '[') {
if (!strnicmp(p,"[R]",3)) continue;
p += strGetWordLen(p);
p = strGetWordTop(p);
}
mchar szTag[CCHWORD];
int len = strGetWordLen(p);
sstrcpylen(szTag,p,len);
p += len;
p = strGetWordTop(p);
//
mchar szCaption[CCHWORD] = {0};
int len = strGetWordLen(p);
if (*p == '[' && len >= 2) {
sstrcpylen(szCaption,p+1,len-2);
p += len;
}
//
BOOL fEnable = TRUE;
BOOL fSingle = FALSE;
while(1) {
p = strGetWordTop(p);
int len = strGetWordLen(p);
if (!*p) break;
if (*p == '[') {
if (!strnicmp(p,"[IE]",4)) {
#if 1//2.99C 970326
if (modeHtml == HTML_IE || modeHtml == HTML_IENN) {
} else {
fEnable = FALSE;
break;
}
#else
if (modeHtml != HTML_IE) {
fEnable = FALSE;
break;
}
#endif
} else if (!strnicmp(p,"[NN]",4)) {
#if 1//2.99C 970326
if (modeHtml == HTML_NN || modeHtml == HTML_IENN) {
} else {
fEnable = FALSE;
break;
}
#else
if (modeHtml != HTML_NN) {
fEnable = FALSE;
break;
}
#endif
} else if (!strnicmp(p,"[!IE]",5)) {//2.99E 970403
if (modeHtml == HTML_IE) {
fEnable = FALSE;
break;
}
} else if (!strnicmp(p,"[S]",3)) {
fSingle = TRUE;
}
}
p += len;
}
if (fEnable) {
if (p_modeUiInsertTag == IT_LIST) {
txInsertf(text,"%c <%s>",szTag[0],szTag);
if (!fSingle) {
txInsertf(text,"-</%s>",szTag);
}
txInsertf(text," %s",szCaption);
// sortを高速化するため、行の長さを一定に
int lch = txGetAddress(text) - txGetParaTop(text);
if (lch < lchLine) {
txInsertNspace(text,lchLine - lch,FALSE);
} else if (lch > lchLine) {
txJumpParaTop(text);
txJumpAddress(text,txGetAddress(text) + lchLine);
txDeleteParaEnd(text);
//
int lch = txGetAddress(text) - txGetParaTop(text);
txInsertNspace(text,lchLine - lch,FALSE);
}
} else {
txInsert(text,"..");
if (szCaption[0]) {
txInsertf(text,"%s <%s>",szCaption,szTag);
} else {
txInsertf(text,"%s <%s>",szTag,szTag);
}
if (!fSingle) {
txInsertf(text,"-</%s>",szTag);
}
}
txInsertReturn(text);
}
}
}
if (p_modeUiInsertTag == IT_LIST) {
SORTARG sort;
structClear(sort);
sort.sizeStruct = sizeof(sort);
sort.lineTop = 1;
sort.lchItem = 10;//2.99 970320 1だとH1,H2のソートが変
sort.lchLine = lchLine + 2;
txJumpFileEnd(text);
sort.lineEnd = text->npara - 1;
txSort(text,&sort);
}
//
//dialogaText(text,NULL);
HDIALOG hd = dialog("タグの挿入");
DTRECT r;
dialogGetPos(hd,&r);
r.cx = DTCX * 40;
r.cy = DTCY * 12;
if (p_modeUiInsertTag == IT_LIST) {
dialogList(hd,NULL,text,40,12);
} else {
dialogAddTitle(hd,&r);
}
int cx = 19;
int iddOrder;
int iddDirect;
dialogLFV(hd);
dialogOK(hd,cx);
dialogCancel(hd,cx);
if (p_modeUiInsertTag == IT_LIST) {
iddOrder = dialogCmd(hd,"機能順(&C) >>",cx);
} else {
iddOrder = dialogCmd(hd,"アルファベット順(&L) >>",cx);
}
iddDirect = dialogCmd(hd,"直接入力(&D) >>",cx);//2.99C 970327
if (p_modeUiInsertTag == IT_LIST) {
txJumpNpara(text,_isel + 1);
ret = dialogOpen(hd);
} else {
CHOOSEOUTLINE co;
memset(&co,0,sizeof(CHOOSEOUTLINE));
co.text = text;
co.szhook = NULL;//"\m.dlgprocTemplate";
co.iselFirst = _isel;
co.fNoTitleHead = TRUE;
ret = dialogSelectTitle(hd,&co);
}
if (ret) {
if (ret == iddOrder) {
if (p_modeUiInsertTag == IT_LIST) {
p_modeUiInsertTag = IT_CATEGORY;
} else {
p_modeUiInsertTag = IT_LIST;
}
ret = -1;
} else if (ret == iddDirect) {
p_modeUiInsertTag = IT_DIRECT;
ret = -1;
} else {
_isel = text->npara - 1;
txstr szline;
txGetPara(text,szline);
mchar* p = szline;
p = strchr(szline,'<');
if (p) {
txInsertTag(textTarget,p);
}
}
}
//
txClose(text);
}
return ret;
}
BOOL TXCMDBASE uiInsertTag(TX* textTarget)
{
// タグを挿入
// タグの機能別、アルファベット順、直接入力ができます。
int ret = FALSE;
while(1) {
if (p_modeUiInsertTag == IT_DIRECT) {
ret = _uiInsertTagDirect(textTarget,TRUE);
} else {
ret = _uiInsertTag(textTarget);
}
if (ret == -1) continue;
break;
}
return ret;
}
//##tag special insert
#define IschReturn(c) (c==CHAR_LF||c==CHAR_CR||c==CHAR_FF||c==CHAR_EOF)
static mchar* szFindTagEnd(mchar* p)
{
// pからタグのendを探して返す
for (;;p++) {
mchar c = *p;
if (IschReturn(c)) break;
if (c == '>') {
p++;
break;
}
}
return p;
}
BOOL htmlTagInsert(TX* textTarget,mchar* szcmd)
{
// szcmdのタグを挿入して、解釈する。
// <WZSELTEXT>:選択されたテキストを挿入
// <WZCUR>:カーソルの位置を指定
// <WZTAGATR>:解釈が終わってから、カーソル位置のタグのプロパティダイアログを表示
BOOL fTagPara = FALSE;// defaultはCHARATR tag
TX _txBody;
TX* text = &_txBody;
BOOL fLI = FALSE;//2.99C 970325 <LI>用
int len;
if (len = strmatch(szcmd,"<WZLI>")) {//2.99C 970325
szcmd += len;
fLI = TRUE;
}
if (txInit(text,NULL)) {
BOOL fClip = (stristr(szcmd,"<WZSELTEXT>") && textTarget->fClip);
IFILE adr = txGetAddress(textTarget);
if (fClip) adr = txGetAddressSelectTop(textTarget);
//
IFILE adrJump = TXRECORD_ERROR;
txInsert(text,szcmd);
txJumpFileTop(text);
//
TX _textDst;
TX* textDst = &_textDst;
if (txInit(textDst,NULL)) {
textDst->fHTML = TRUE;
textDst->fForm = TRUE;
textDst->fTxsemForceConvert = TRUE;
textDst->fTxsemHtmlInside = TRUE;//2.97A 970303
textDst->fDispTag = TRUE;
if (textTarget->editmode) txSetEditmode(textDst,1);
if (fClip) {
txPrivatePush(textTarget); // PushはtxInitの後に行う
}
BOOL fAbort = FALSE;
while(1) {
mchar* p = text->buff + text->cur;
if (*p == '<') {
mchar* p1 = szFindTagEnd(p);
int lch = p1 - p;
if (!strnicmp(p,"<WZ",3)) {
// WZタグ
mchar szTag[CCHWORD];
int l = lch;
p += 3;l -= 3;
if (l && p[l-1] == '>') l--;
sstrcpylen(szTag,p,l);
txDeleteBytes(text,lch);
if (!stricmp(szTag,"SELTEXT")) {
if (fClip) {
if (fLI) {//2.99C 970325
TX* text = textDst;
IFILE adr = txGetAddress(text);
txClipPaste(text,HCLIP_PRIVATE,TRUE,CLIP_CHAR);
txJumpAddress(text,adr);
while(1) {
if (txIsCurEof(text)) break;
if (!txInsertHtmlSzTag(text,"<LI>",TAG_LI)) break;
if (!txNextPara(text)) break;
}
txJumpFileEnd(text);
//dialogaText(text,NULL);
} else {
txClipPaste(textDst,HCLIP_PRIVATE,TRUE,CLIP_CHAR);
}
//dialogaText(textDst,NULL);
}
} else if (!stricmp(szTag,"CUR")) {
adrJump = txGetAddress(textTarget) + txGetAddress(textDst);
} else if (!stricmp(szTag,"TAGATR")) {
txLeft(textDst);
#if 1//3.00A2 970504 「書式|色とサイズ」のダイアログのバックに画面サイレントがかかっていた。
{
int fUndisp = textTarget->fUndisp;
textTarget->fUndisp = 0;
txDispTextAll(textTarget);
int ret = _uiPropertyTag(textDst,TRUE);
textTarget->fUndisp = fUndisp;
if (!ret) {
fAbort = TRUE;
break;
}
}
#else
if (!_uiPropertyTag(textDst,TRUE)) {
fAbort = TRUE;
break;
}
#endif
#if 1//3.00A 970502 HTMLファイルでテキストモードで「書式|色とサイズ」が変だった
if (txIsWP(textDst)) {
txRight(textDst);
} else {
txSearchEx(textDst,">",0);
txRight(textDst);
}
#else
txRight(textDst);
#endif
}
} else {
mchar szTag[CCHWORD];
sstrcpylen(szTag,p,lch);
int tag = tagFromStr(szTag);
if (tagIsParaatr(tag)) {
fTagPara = TRUE; // PARAATR tag
}
if (!txInsertHtmlSzTag(textDst,szTag,tag)) {
////err
break;
}
txRightBytes(text,lch);
}
} else {
TXCHAR ch = txReadChar(text);
if (ch == CHAR_EOF || ch == 0) break;
txInsertChar(textDst,ch);
}
}
if (!fAbort) {
txSelectDelete(textTarget);
txInsertText(textTarget,textDst);
}
txClose(textDst);
//
if (fClip) {
clipDeleteTop(HCLIP_PRIVATE);
}
//dialogaText(textTarget,NULL);
if (!fAbort) {
IFILE adrEnd = txGetAddress(textTarget);
#if 1//3.00A 970502 HTMLファイルでテキストモードで[太字]などを実行するとカーソルキーでカーソルが移動しなくなった
if (txIsWP(textTarget)) {
txHtmlFlushArea(textTarget,adr,adrEnd,fTagPara ? TAG_H : TAG_B,TRUE);
} else {
txSelectEx(textTarget,CLIP_CHAR);
txJumpAddress(textTarget,adr);
}
#else
txHtmlFlushArea(textTarget,adr,adrEnd,fTagPara ? TAG_H : TAG_B,TRUE);
#endif
if (!fClip) {
txSelectQuit(textTarget);
if (adrJump != TXRECORD_ERROR) txJumpAddress(textTarget,adrJump);
}
}
txSetDisp(textTarget);
if (fClip) textTarget->fClipMouse = TRUE;//2.97A 970301
}
txClose(text);
}
return TRUE;
}
static void txInsertTextAndSelect(TX* textTarget,TX* text)
{
IFILE adr = txGetAddress(textTarget);
txInsertText(textTarget,text);
txSelectEx(textTarget,CLIP_CHAR);
txJumpAddress(textTarget,adr);
}
#if 0
static int txGetCurTag(TX* text)
{
if (text->editmode) {
if (txGetChar(text) == CHAR_PLUG) {
PLUGHTMLTAG* plug = txGetCurPlug(text);
if (plug->head.modePlug == PLUG_HTML_TAG) {
return tagFromStr(plug->szTag);
}
}
return 0;
} else {
if (txGetChar(text) == '<') {
return tagFromStr(text->buff + text->cur);
}
return 0;
}
}
#endif
static int _htmlTagDelete(TX* textTarget,mchar* szTag,BOOL fDeletePair)
{
// !fDeletePair : 範囲選択内のszTagをすべて削除
// fDeletePair : 範囲選択内のszTagペアを一つ削除
// szTagは、"<P>"のように指定。
// szTagがNULLなら、全部削除
// 削除した個数を返す
int tagDel = szTag ? tagFromStr(szTag) : 0;
int nDel = 0;
if (textTarget->fClip) {
BOOL fDelTop = FALSE;
BOOL fDelEnd = FALSE;
TX _txBody;
TX* text = &_txBody;
if (txInit(text,NULL)) {
text->fHTML = TRUE;
text->fForm = TRUE;
text->fTxsemForceConvert = TRUE;
text->fTxsemHtmlInside = TRUE;//2.97A 970303
text->fDispTag = TRUE;
#if 1//3.00A2 970503
if (textTarget->editmode) {
txSetEditmode(text,1);
}
#else
txSetEditmode(text,1);
#endif
//
txPrivatePush(textTarget);// txInitの前にPushするとATRがPasteされない
txClipPaste(text,HCLIP_PRIVATE,TRUE,CLIP_CHAR);
clipDeleteTop(HCLIP_PRIVATE);
//dialogaText(text,NULL);
txJumpFileTop(text);
#if 1//3.00A2 970503 テキストモードのHTMLファイル編集で、「題|本文」を指定しても<H1>が削除されなかった
while(1) {
BOOL f = FALSE;
int tag = 0;
BOOL fTagTop;
if (text->editmode == 0) {
if (txGetChar(text) == '<') {
mchar* p = text->buff + text->cur;
tag = tagFromStr(p);
fTagTop = !(p[1] == '/');
}
} else {
if (txGetChar(text) == CHAR_PLUG) {
PLUGHTMLTAG* plug = txGetCurPlug(text);
if (plug->head.modePlug == PLUG_HTML_TAG) {
tag = tagFromStr(plug->szTag);
fTagTop = plug->fTagTop;
}
}
}
if (tag) {
if (tag == tagDel || tagDel == 0) {
if (fDeletePair) {
if (fTagTop) {
if (!fDelTop) {
fDelTop = TRUE;
f = TRUE;
}
} else {
if (!fDelEnd) {
fDelEnd = TRUE;
f = TRUE;
}
}
} else {
f = TRUE;
}
}
}
if (f) {
if (txGetChar(text) == CHAR_PLUG) {
txDeleteChar(text);
} else {
// テキストのタグを削除
while(1) {
if (txIsCurReturn(text)) break;
if (txGetChar(text) == '>') {
txDeleteChar(text);
break;
}
txDeleteChar(text);
}
}
nDel++;
} else {
if (!txRight(text)) break;
}
}
#else
while(1) {
BOOL f = FALSE;
if (txGetChar(text) == CHAR_PLUG) {
PLUGHTMLTAG* plug = txGetCurPlug(text);
if (plug->head.modePlug == PLUG_HTML_TAG) {
int tag = tagFromStr(plug->szTag);
if (tag == tagDel || tagDel == 0) {
if (fDeletePair) {
if (plug->fTagTop) {
if (!fDelTop) {
fDelTop = TRUE;
f = TRUE;
}
} else {
if (!fDelEnd) {
fDelEnd = TRUE;
f = TRUE;
}
}
} else {
f = TRUE;
}
}
}
}
if (f) {
txDeleteChar(text);
nDel++;
} else {
if (!txRight(text)) break;
}
}
#endif
//dialogaText(text,NULL);
if (nDel) {
txSelectDelete(textTarget);
txInsertTextAndSelect(textTarget,text);
}
txClose(text);
}
}
return nDel;
}
static int htmlTagDelete(TX* textTarget,mchar* szTag)
{
return _htmlTagDelete(textTarget,szTag,FALSE);
}
//2.99C 970327 new
BOOL TXCMDBASE clearTag(TX* text)
{
// 範囲内のすべてのタグを削除
if (!text->fClip) {
information("タグをクリアするには、範囲を選択してください");
return FALSE;
}
txSetUndisp(text);
IFILE adrCurscreen = txGetAddressCurscreen(text);
BOOL ret = htmlTagDelete(text,NULL);
txSetLyCurscreen(text,adrCurscreen);
txSetDisp(text);
return ret;
}
static BOOL htmlTagInsertEx(TX* text,mchar* szdel,mchar* szcmd,BOOL fSw)
{
// fSw=TRUE : szdelタグが存在したら、削除するだけで挿入しないでFALSEを返す
// そうでなければTRUEを返す
BOOL ret = TRUE;
txSetUndisp(text);
IFILE adrCurscreen = txGetAddressCurscreen(text);
int nDel = htmlTagDelete(text,szdel);
if (fSw && nDel) {
htmlTagInsert(text,"<WZSELTEXT>");
ret = FALSE;
} else {
htmlTagInsert(text,szcmd);
}
txSetLyCurscreen(text,adrCurscreen);
txSetDisp(text);
return ret;
}
BOOL txHtmlSet(TX* text,int tag,int arg)
{
BOOL ret = TRUE;
BOOL fParaatrTag = tagIsParaatr(tag);
if (tag == TAG_LI || tag == TAG_LINUM) fParaatrTag = TRUE;//2.99C 970326
//
mchar szTag[CCHTAG];
BOOL fClip = text->fClip;
txSetUndisp(text);
NPARA nparaTop;
NPARA nparaEnd;
IFILE adrCurscreen = txGetAddressCurscreen(text);
if (fParaatrTag) {
if (text->fClip) {
// 段落単位の範囲選択に変換
IFILE adrTop = txGetAddressSelectTop(text);
IFILE adrEnd = txGetAddressSelectEnd(text);
txJumpAddress(text,adrTop);
txJumpParaTop(text);
nparaTop = text->npara;
txSelectEx(text,CLIP_CHAR);
txJumpAddress(text,adrEnd);
if (txIsCurParaTop(text)) {
txPrevPara(text);
}
txJumpParaEnd(text);
nparaEnd = text->npara;
} else {
txJumpParaTop(text);
txSelectEx(text,CLIP_CHAR);
txJumpParaEnd(text);
nparaTop = nparaEnd = text->npara;
}
}
switch(tag) {
case TAG_UL: {
// htmlTagDelete(text,"<P>");
#if 1//3.00A2 970504 HTML体裁モードでの<UL>挿入を改良
if (arg < 0) {
txParaatrSet(text,TAG_INDENTADD,(LPVOID)arg);
_htmlTagDelete(text,"<UL>",TRUE);
} else {
PARAATR paraatr;
paraatrRead(text,nparaTop,¶atr);
//
txParaatrSet(text,TAG_INDENTADD,(LPVOID)arg);
//
txJumpNpara(text,nparaTop);
tagPrintEx(text,tag,arg,TAG_TOP,szTag);
txInsertHtmlSzTag(text,szTag,tag);
txInsertReturn(text);nparaEnd++;//2.99C 970325 字下げで<UL>に改行を付けるようにした
paraatrWrite(text,nparaTop,¶atr);
//
txJumpNpara(text,nparaEnd);
txJumpParaEnd(text);
txInsertReturn(text);nparaEnd++;//2.99C 970325
tagPrintEx(text,tag,arg,TAG_END,szTag);
txInsertHtmlSzTag(text,szTag,tag);
paraatrWrite(text,nparaEnd,¶atr);
}
#else
txParaatrSet(text,TAG_INDENTADD,(LPVOID)arg);
if (arg < 0) {
_htmlTagDelete(text,"<UL>",TRUE);
} else {
txJumpNpara(text,nparaTop);
tagPrintEx(text,tag,arg,TAG_TOP,szTag);
txInsertHtmlSzTag(text,szTag,tag);
txInsertReturn(text);nparaEnd++;//2.99C 970325 字下げで<UL>に改行を付けるようにした
//
txJumpNpara(text,nparaEnd);
txJumpParaEnd(text);
tagPrintEx(text,tag,arg,TAG_END,szTag);
txInsertReturn(text);nparaEnd++;//2.99C 970325
txInsertHtmlSzTag(text,szTag,tag);
}
#endif
break;
}
case TAG_H: {
// 行末が<BR>なら、<BR>は次行に送るのはうまくいかなかった
htmlTagDelete(text,"<H1>"); // <Hn>を削除
//
PARAATR paraatr;
paraatr.modeTitle = arg;
txParaatrSet(text,TAG_H,¶atr);
//
if (arg) {
if (txIsWP(text)) {//3.00A 970502 テキストモードのHTMLファイルで<H1>が2重になった
txJumpNpara(text,nparaTop);
tagPrintEx(text,tag,arg,TAG_TOP,szTag);
txInsertHtmlSzTag(text,szTag,tag);
//
txJumpNpara(text,nparaEnd);
txJumpParaEnd(text);
tagPrintEx(text,tag,arg,TAG_END,szTag);
txInsertHtmlSzTag(text,szTag,tag);
}
}
break;
}
case TAG_LEFT:
case TAG_CENTER:
case TAG_RIGHT: {
#if 1 //2.97A 970302
#if 1//2.99 970320 センタリングは<CENTER>を使う。ネスケでは<P align="center">ではちゃんと表示されないため。
txParaatrSet(text,tag,0);
htmlTagDelete(text,"<P>");
htmlTagDelete(text,"<CENTER>");
htmlTagDelete(text,"<DIV>");//2.99C 970326
if (tag != TAG_LEFT) {
txJumpNpara(text,nparaTop);
if (tag == TAG_CENTER) {
txInsertHtmlSzTag(text,"<CENTER>",TAG_CENTER);
} else {
#if 1//2.99C 970326 右寄せは<DIV ALIGN=RIGHT>を使う。<P ALIGN=RIGHT>は文章しか揃えることができない
txInsertHtmlSzTag(text,"<DIV ALIGN=RIGHT>",TAG_DIV);
#else
txInsertHtmlSzTag(text,"<P ALIGN=RIGHT>",TAG_P);
#endif
}
//
txJumpNpara(text,nparaEnd);
txJumpParaEnd(text);
if (tag == TAG_CENTER) {
txInsertHtmlSzTag(text,"</CENTER>",TAG_CENTER);
} else {
#if 1//2.99C 970326
txInsertHtmlSzTag(text,"</DIV>",TAG_DIV);
#else
txInsertHtmlSzTag(text,"</P>",TAG_P);
#endif
}
}
#else
txParaatrSet(text,tag,0);
htmlTagDelete(text,"<P>");
if (tag != TAG_LEFT) {
txJumpNpara(text,nparaTop);
txInsertHtmlSzTag(
text,
tag == TAG_CENTER ? "<P ALIGN=CENTER>" : "<P ALIGN=RIGHT>",
TAG_P
);
//
txJumpNpara(text,nparaEnd);
txJumpParaEnd(text);
txInsertHtmlSzTag(text,"</P>",TAG_P);
}
#endif
#else
htmlTagInsertEx(text,"<P>","<P ALIGN=LEFT><WZSELTEXT></P>",FALSE);
#endif
break;
}
case TAG_TABLE: {
ret = FALSE;
int x = LOWORD(arg);
int y = HIWORD(arg);
if (text->editmode) {
mchar *buff = malloc(100 + (x * 9 + 4) * y);
if (buff) {
txSetUndisp(text);
mchar* dst = buff;
strcpy(dst,"<TABLE BORDER>");dst += strlen(dst);
#if 1//2.99 970319
for (;y--;) {
strcpy(dst,"<TR>");dst += strlen(dst);
for (int i = 0;i < x;i++) {
strcpy(dst,"<TD>");dst += strlen(dst);
}
}
#else
for (;y--;) {
for (int i = 0;i < x;i++) {
strcpy(dst,"<TD></TD>");dst += strlen(dst);
}
strcpy(dst,"<TR>");dst += strlen(dst);
}
#endif
strcpy(dst,"</TABLE>");dst += strlen(dst);
*dst = 0;
txInsertReturn(text);
BOOL ret = htmlTagInsert(text,buff);
txInsertReturn(text);
free(buff);
// 表の頭へ移動
txSelectQuit(text);
while(1) {
if (txIsCurParaIncludeTable(text)) {
break;
} else {
if (!txPrevPara(text)) break;
}
}
while(1) {
if (txIsCurParaIncludeTable(text)) {
if (!txPrevPara(text)) break;
} else {
txNextPara(text);
break;
}
}
txFlushTable(text);
txRight(text);
//
ret = TRUE;
txSetDisp(text);
}
} else {
txSetUndisp(text);
{
txInsertReturn(text);
txInsertLine(text,"<TABLE BORDER>");
IFILE adr = txGetAddress(text);
#if 1//2.99 970319
if (text->share->config.modeHtmlOutTable) {
for (;y--;) {
txInsert(text,"<TR>");txInsertReturn(text);
for (int i = 0;i < x;i++) {
txInsertChar(text,CHAR_TAB);
txInsert(text,"<TD></TD>");//3.00B1 970612 HTMLテキストモード「セルを1行毎に出力」のとき表を挿入すると、</TD>が<TD>として挿入された。
txInsertReturn(text);
}
}
} else {
#if 1//2.99D 970329 テキストモードでのHTMLの表の挿入改良
for (;y--;) {
txInsert(text,"<TR>");
for (int i = 0;i < x;i++) {
txInsert(text,"<TD>");
}
txInsertReturn(text);
}
#else
for (;y--;) {
txInsert(text,"<TR>");txInsertReturn(text);
for (int i = 0;i < x;i++) {
txInsert(text,"<TD>");
}
}
#endif
}
#else
for (;y--;) {
for (int i = 0;i < x;i++) {
txInsert(text,"<TD></TD>");
}
txInsert(text,"<TR>");txInsertReturn(text);
}
#endif
txInsertLine(text,"</TABLE>");
txJumpAddress(text,adr);
}
txSetDisp(text);
}
break;
}
case TAG_B: {
// 選択されてないときに、タグが解釈されないのは仕様
ret = htmlTagInsertEx(text,"<B>","<B><WZCUR><WZSELTEXT></B>",TRUE);
break;
}
case TAG_I: {
ret = htmlTagInsertEx(text,"<I>","<I><WZCUR><WZSELTEXT></I>",TRUE);
break;
}
case TAG_U: {
ret = htmlTagInsertEx(text,"<U>","<U><WZCUR><WZSELTEXT></U>",TRUE);
break;
}
case TAG_FONT: {
htmlTagInsertEx(text,"<FONT>","<FONT><WZTAGATR><WZCUR><WZSELTEXT></FONT>",FALSE);
break;
}
case TAG_LI: {//2.99C 970325
htmlTagDelete(text,"<UL>");
htmlTagDelete(text,"<OL>");
ret = htmlTagInsertEx(text,"<LI>","<WZLI><UL><WZCUR><WZSELTEXT></UL>",TRUE);
break;
}
case TAG_LINUM: {//2.99C 970325
htmlTagDelete(text,"<UL>");
htmlTagDelete(text,"<OL>");
ret = htmlTagInsertEx(text,"<LI>","<WZLI><OL><WZCUR><WZSELTEXT></OL>",TRUE);
break;
}
}
if (fParaatrTag) {
if (fClip) {
txJumpNpara(text,nparaEnd);
txJumpParaEnd(text);
txSelectEx(text,CLIP_CHAR);
txJumpNpara(text,nparaTop);
text->fClipMouse = TRUE;
} else {
txSelectQuit(text);
txJumpNpara(text,nparaTop);
}
}
txSetLyCurscreen(text,adrCurscreen);
txSetDisp(text);
return ret;
}
BOOL TXCMDBASE uiColor(TX* text)
{
// 文字列の色指定
return txHtmlSet(text,TAG_FONT,0);
}
//2.99C 970326 new
insertArticleDisc
{
// 箇条書きの挿入
if (htmlTagInsert(text,"<UL><LI><WZCUR></UL>")) {
if (text->editmode) {txRight(text);txRight(text);}
return TRUE;
}
return FALSE;
}
//2.99C 970326 new
insertArticleNum
{
// 番号付き箇条書きの挿入
if (htmlTagInsert(text,"<OL><LI><WZCUR></OL>")) {
if (text->editmode) {txRight(text);txRight(text);}
return TRUE;
}
return FALSE;
}
//2.99C 970326 new
insertArticleDefine
{
// 定義型箇条書きの挿入
if (htmlTagInsert(text,"<DL><DT><WZCUR><DD></DL>")) {
if (text->editmode) {txRight(text);txRight(text);}
return TRUE;
}
return FALSE;
}
//2.99C 970326 new
insertArticleTable
{
// 定義型箇条書きの挿入
if (htmlTagInsert(text,"<TABLE><TR VALIGN=TOP><TD NOWRAP><WZCUR><TD></TABLE>")) {
if (text->editmode) {txRight(text);txRight(text);}
return TRUE;
}
return FALSE;
}
//2.99C 970326 HTML:「挿入|箇条書き」追加
BOOL TXCMDBASE insertArticle(TX* text)
{
// 箇条書きの形式を選んで挿入
HDIALOG hd = dialog("箇条書きの挿入");
static int mode;
dialogControlRadioV(hd);
dialogRadioID(hd,&mode,
"箇条書き(&A)",
"番号付き箇条書き(&N)",
"定義型箇条書き(&D)",
"表形式箇条書き(&T)"
);
if (dialogOpen(hd)) {
switch(mode) {
case 0:return insertArticleDisc();
case 1:return insertArticleNum();
case 2:return insertArticleDefine();
case 3:return insertArticleTable();
}
}
return FALSE;
}
//##tag delete
static int txSearchTag(TX* text,mchar* szTag,BOOL fPrev,int* pLeft)
{
// szTagは、"FONT"の様に指定する。
// 開始タグを見つけたらTAG_TOP,終了タグを見つけたらTAG_END,
// 見つからなかったら-1を返す
// カーソルは見つけたタグの'<'に設定する。
// pLeft:次を検索する前に、txLeftする回数を返す。
*pLeft = 0;
if (text->editmode) {
int lch = strlen(szTag);
SEARCHMODE mode = SEARCH_CUR|SEARCH_NOSELECT;
if (fPrev) mode |= SEARCH_PREV;
mchar szFind[2] = {CHAR_PLUG,0};
while(1) {
if (!txSearchEx(text,szFind,mode)) break;
CHARATR charatr;
charatrRead(text,txGetAddress(text),&charatr);
PLUGHTMLTAG* plug = plugatrRead(text,charatrGetPlug(charatr));
if (plug->head.modePlug == PLUG_HTML_TAG) {
int ret = TAG_TOP;
mchar* p = plug->szTag;
p++;
if (*p == '/') {
p++;
ret = TAG_END;
}
if (!strnicmp(szTag,p,lch) && !isalnum(szTag[lch])) {
return ret;
}
}
if (fPrev) {
if (!txLeft(text)) break;
} else {
if (!txRight(text)) break;
}
}
return -1;
} else {
SEARCHMODE mode = SEARCH_CUR|SEARCH_WORD|SEARCH_NOSELECT|SEARCH_NOSENSECASE;
if (fPrev) mode |= SEARCH_PREV;
//3.00A3 970508 *pLeft++ がpLeftの内容を+1してなかったので、呼び出し側で無限ループになることがあった
// (*pLeft)++のように修正した
while(1) {
if (!txSearchEx(text,szTag,mode)) break;
*pLeft = 0;
if (!txLeft(text)) break;
(*pLeft)++;
mchar ch = txGetChar(text);
if (ch == '<') {
return TAG_TOP;
} else if (ch == '/') {
if (!txLeft(text)) break;
(*pLeft)++;
if (txGetChar(text) == '<') {
return TAG_END;
}
}
//
while((*pLeft)--) txRight(text);
*pLeft = 0;//3.00A3 970508 無限ループになった
if (fPrev) {
if (!txLeft(text)) break;
} else {
if (!txRight(text)) break;
}
}
return -1;
}
}
static BOOL txHtmlFlushArea(TX* textTarget,IFILE adrTop,IFILE adrEnd,int tag,BOOL fSelect)
{
if (!textTarget->editmode) return TRUE;//2.97A 970302
if (adrTop > adrEnd) {
IFILE tmp = adrTop;
adrTop = adrEnd;
adrEnd = tmp;
}
if (adrEnd > adrTop) {
TX _txBody;
TX* text = &_txBody;
if (txInit(text,NULL)) {
text->fHTML = TRUE;
text->fForm = TRUE;
text->fTxsemForceConvert = TRUE;
text->fTxsemHtmlInside = TRUE;
text->fTxsemNoUI = TRUE;
text->fSetWidthByWindow = TRUE;// for dialogaText
#if 0 // <H4 ALIGN=CENTER>...</H4>の変更が反映されない。
text->fTxsemNoChangeReturn = TRUE;
#endif
text->fDispTag = TRUE;
txSetEditmode(text,1);
//
txJumpAddress(textTarget,adrTop);
txSelectEx(textTarget,CLIP_CHAR);
txJumpAddress(textTarget,adrEnd);
//
txPrivatePush(textTarget);
txClipPaste(text,HCLIP_PRIVATE,TRUE,CLIP_CHAR);
clipDeleteTop(HCLIP_PRIVATE);
//statprintf("%d",__LINE__);
//dialogaText(text,NULL);
txSetEditmode(text,0);
//dialogaText(text,NULL);
txSetEditmode(text,1);
//dialogaText(text,NULL);
//
txSelectDelete(textTarget);
//statprintf("%d",__LINE__);
//
NPARA nparaTop = textTarget->npara;
PARAATR paraatrTop;
paraatrRead(textTarget,nparaTop,¶atrTop);
IFILE adr2Top = txGetAddress(textTarget);
txInsertText(textTarget,text);
IFILE adr2End = txGetAddress(textTarget);
if (!tagIsParaatr(tag)) {
// 中央揃えなどがリセットされるので、復活させる
NPARA nparaEnd = textTarget->npara;
for (NPARA npara = nparaTop;npara <= nparaEnd;npara++) {
PARAATR paraatr;
paraatrRead(textTarget,npara,¶atr);
paraatr.modeAlign = paraatrTop.modeAlign;
paraatrWrite(textTarget,npara,¶atr);
}
}
//statprintf("%d",__LINE__);
if (fSelect) {
txJumpAddress(textTarget,adr2Top);
txSelectEx(textTarget,CLIP_CHAR);
txJumpAddress(textTarget,adr2End);
}
//statprintf("%d",__LINE__);
txDispAll(textTarget);
txClose(text);
}
}
return TRUE;
}
static BOOL tagIsPairAndSingle(int tag)
{
// tagがペアタグでも単独でも使われるものならTRUEを返す
switch(tag) {
case TAG_P:
case TAG_LINK:
case TAG_TD:
case TAG_TH:
case TAG_CENTER: return TRUE;
}
return FALSE;
}
static BOOL _htmlDeleteTag(TX* text,BOOL fFlush)
{
// タグの削除
// fFlush = 0:カーソル位置がタグのときは、タグと対応するペアタグを削除し、
// 間の文字列の属性を変更する。
// fFlush = 1:カーソル位置がタグのときは、対応するペアタグまでの文字列の属性を変更する。
// fFlush = 2:カーソル位置がタグのときは、対応するペアタグまでジャンプする
mchar* p = text->buff + text->cur;
int tag = 0;
int lch = 0;
BOOL fTagTop = FALSE;
BOOL fAtrExist = TRUE; // ATRがあるか?
mchar szTag[CCHWORD];
mchar* pTag;
if (text->editmode) {
if (*p == CHAR_PLUG) {
#if 1//2.99C 970326
PLUGHTMLTAG* plug = txGetCurPlug(text);
if (text->fHTML && plug->head.modePlug == PLUG_HR && fFlush == 1) {
//2.99C 970326 HTML:水平線のプロパティを変更しても表示に反映されなかった
IFILE adrCurscreen = txGetAddressCurscreen(text);
IFILE adr = txGetAddress(text);
if (txHtmlFlushArea(text,adr,adr+1,0,FALSE)) {
// 余計な空白を削除
if (txIsCurReturn(text)) txDeleteChar(text);
//
txJumpAddress(text,adr);
txSetLyCurscreen(text,adrCurscreen);
return TRUE;
} else {
return FALSE;
}
}
if (plug->head.modePlug != PLUG_HTML_TAG) return FALSE;
pTag = plug->szTag;
lch = strlen(pTag);
#else
CHARATR charatr;
charatrRead(text,txGetAddress(text),&charatr);
PLUGHTMLTAG* plug = plugatrRead(text,charatrGetPlug(charatr));
if (plug->head.modePlug != PLUG_HTML_TAG) return FALSE;
//
pTag = plug->szTag;
lch = strlen(pTag);
#endif
} else {
return FALSE;
}
} else if (*p == '<') {
pTag = p;
lch = szFindTagEnd(p) - p;
} else {
return FALSE;
}
tag = tagFromStr(pTag);
fTagTop = !(pTag[1] == '/');
int d = 1 + !fTagTop;
sstrcpylen(szTag,pTag + d,lch - d);
int l = strGetWordLen(szTag);
if (l && szTag[l-1] == '>') {
fAtrExist = FALSE;
l--;
}
szTag[l] = 0;
if (!fFlush && text->editmode && !text->fDispTag) {
if (question(" %s タグを削除して良いですか?",szTag) != IDYES) return TRUE;
}
// information(szTag);
if (tag == TAG_P) {
if (!fTagTop || fAtrExist) {
// OK
} else {
// <P>だけなら、閉タグなし。
tag = 0;
}
}
#if 0 //3.00A3 970508 htmlDeleteTagが効いてなかった
if (!fFlush) {
//2.97A 970303 削除の場合はペアタグは見ない様にした。
// 無限ループになる場合がある様だ。
if (text->editmode) {
txDeleteChar(text);
} else {
txDeleteBytes(text,lch);
}
} else
#endif
{
switch(tag) {
case TAG_P:
case TAG_H:
case TAG_UL:
case TAG_B:
case TAG_I:
case TAG_U:
case TAG_TT:
case TAG_STRONG:
case TAG_EM:
case TAG_CITE:
case TAG_CODE:
case TAG_KBD:
case TAG_SAMP:
case TAG_VAR:
case TAG_SUB:
case TAG_SUP:
case TAG_PRE:
case TAG_FONT:
case TAG_OL:
case TAG_DL:
case TAG_BLOCKQUOTE:
case TAG_LINK:
case TAG_ADDRESS:
case TAG_TD:
case TAG_TH:
case TAG_CAPTION:
case TAG_CENTER: {
// ペアタグも削除
BOOL fPandS = tagIsPairAndSingle(tag);//3.00A3 970508
BOOL fPrev = !fTagTop;
int fEnd = fTagTop;
BOOL fFound = FALSE;
IFILE adr = txGetAddress(text);
int ly = text->ly;
txSetUndisp(text);
txMarkCur(text);
IFILE adrTop;
if (fFlush) {
// cursor move for search next
if (fPrev) {
adrTop = txGetAddress(text) + 1;
if (!txLeft(text)) break;
} else {
adrTop = txGetAddress(text);
if (!txRight(text)) break;
}
} else {
if (text->editmode) {
txDeleteChar(text);
} else {
txDeleteBytes(text,lch);
}
adrTop = txGetAddress(text);
}
while(1) {
int left;
int ret = txSearchTag(text,szTag,fPrev,&left);
if (ret == -1) break;
if (ret == TAG_TOP) {
fEnd++;
if (fPrev && fEnd == 1) {
fFound = TRUE;
break;
}
if (!fPrev && fPandS) {
break;//3.00A3 970508 for <TD>aaa<TD>bbb</TD>
}
} else {
fEnd--;
if (!fPrev && fEnd == 0) {
fFound = TRUE;
break;
}
if (fPrev && fPandS) {
break;//3.00A3 970508 for <TD>aaa<TD>bbb</TD>
}
}
//
while(left--) txRight(text);
if (fPrev) {
if (!txLeft(text)) break;
} else {
if (!txRight(text)) break;
}
}
if (fFound) {
if (fFlush == 2) {
//2.99 970313
} else if (text->editmode) {
if (fFlush) {
if (!fPrev) {
txRight(text);
if (txIsCurReturn(text)) {
//2.97 970223 <H4 ALIGN=CENTER>...</H4>の変更が反映される様に。
txRight(text);
}
}
} else {
txDeleteChar(text);
}
IFILE adrEnd = txGetAddress(text);
txHtmlFlushArea(text,adrTop,adrEnd,tag,FALSE);
} else {
mchar* p = text->buff + text->cur;
if (*p == '<') {
int lch = szFindTagEnd(p) - p;
txDeleteBytes(text,lch);
}
}
}
if (fFlush == 2) {
//2.99 970313
if (fFound) {
} else {
txJumpAddress(text,adr);
}
txSetLy(text,ly);
} else if (fFlush) {
txJumpAddress(text,adr);
txSetLy(text,ly);
} else {
txJumpMarkCur(text);
}
txSetDisp(text);
break;
}
default: {
if (!fFlush) {
if (text->editmode) {
txDeleteChar(text);
} else {
txDeleteBytes(text,lch);
}
}
break;
}
}
}
return TRUE;
}
static BOOL htmlFlushCurTag(TX* text)
{
// 体裁モードのときに、カーソル位置にあるタグとペアタグの間の文字列を解釈。
if (text->editmode) return _htmlDeleteTag(text,TRUE);
return FALSE;
}
//2.99 970313 new
BOOL TXCMD TXAPI txHtmlJumpPairTag(TX* text)
{
// カーソル位置のHTMLタグのペアタグにジャンプ
return _htmlDeleteTag(text,2);
}
BOOL TXCMD htmlDeleteTag(TX* text)
{
// タグの削除
// カーソル位置がタグのときは、タグと対応するペアタグを削除し、
// 間の文字列の属性を変更する。
return _htmlDeleteTag(text,FALSE);
}
//##その他
#ifndef __FLAT__
extern "shell.dll" {
HINSTANCE WINAPI ShellExecute(HWND,LPCSTR,LPCSTR,LPCSTR,LPCSTR,int);
}
#endif
#include "event.h"
BOOL TXCMDBASE htmlbrowser(TX* text)
{
// HTMLに関連付けられているブラウザで、現在編集中のHTMLテキストを表示
if (text->fHTML) {
if (text->fEdit) {
int ret = question("%sは変更されています。\n保存しますか?",text->szfilename);
if (ret == IDCANCEL) return FALSE;
if (ret == IDYES) {
if (!txuiSave(text)) return FALSE;
}
}
#if 1//2.99C 970326 htmlbrowser:event.openURLを使うように変更
return openURL(text,text->szfilename);
#else
if (ShellExecute(text->hwndbase,"open",text->szfilename,NULL,NULL,SW_SHOW) <= 32) {
return TRUE;
}
#endif
}
return FALSE;
}
extern "word" BOOL txGetWordCaption(TX* text,txstr szCaption);
//2.99 970313 new
BOOL TXAPI TXCMDBASE txuiInsertAnchor(TX* text)
{
// アンカーの挿入
BOOL fClip = FALSE;
txstr szCaption;
if (txGetWordCaption(text,szCaption)) {
fClip = TRUE;
} else {
//2.99C 970325 キャプションのデフォルトはスペース一個が良い
szCaption = " ";
}
//
HDIALOG hd = dialog("アンカーの挿入");
txstr szAnchor;
dialogStr(hd,"アンカー(&A):",szAnchor,20,33);
dialogStr(hd,"キャプション(&C):",szCaption,20,33);
if (dialogOpen(hd)) {
txSelectDelete(text);
txstr sz = "<A NAME=\"";
sz += szAnchor;
sz += "\">";
txInsertHtmlSzTag(text,sz,TAG_LINK);
txInsert(text,szCaption);
txInsertHtmlSzTag(text,"</A>",TAG_LINK);
return TRUE;
}
return FALSE;
}
LfToBr
{
// 改行を<BR>に変換
//3.00A 970502 WZ2.0のword.txLfToBr復活
if (!text->fClip) {
information("範囲を選択してから実行してください。");
return FALSE;
} else {
txWalkStart(text);
while(txIsWalking(text)) {
txJumpParaEnd(text);
txInsertHtmlSzTag(text,"<BR>",TAG_BR);
if (!txNextPara(text)) break;
}
txWalkEnd(text);
return TRUE;
}
}
main
{
}