OSDN Git Service

BOOTSTRAPHACK in wiki attribute.
[hmh/hhml.git] / wiki / wikiattrib.cc
1 #include "wikiattrib.h"
2 #include "wikiformat.h"
3 #include "wikimotor.h"
4 #include "util_check.h"
5 #include "ustring.h"
6
7 bool  WikiAttrib1::readAttrib1 (WikiMotorObjVec* cell, bool& rc) {
8     ustring  key;
9     WikiMotorObjVec  vval;
10     bool  ferr = false;
11
12     if (cell->size () == 0) {
13         if (mode == M_ATTRIB || mode == M_ATTRIB_TEXT)
14             return true;
15         else
16             return false;
17     }
18     if (cell->splitChar_keyword ('=', key, vval)) {
19         if (paramID (key, vval, ferr)) {
20         } else if (paramClass (key, vval, ferr)) {
21 #ifdef BOOTSTRAPHACK
22         } else if (paramDataPrefix (key, vval, ferr)) {
23 #endif
24         } else if (paramOnClickCheck (key)) {
25             if (! checkScript (vval, onclick, ferr)) {
26                 wiki->errorMsg.append (cell->dump ()).append (CharConst (": link script error.\n"));
27                 ferr = true;
28             }
29         } else if (paramOnFocusCheck (key)) {
30             if (! checkScript (vval, onfocus, ferr)) {
31                 wiki->errorMsg.append (cell->dump ()).append (CharConst (": link script error.\n"));
32                 ferr = true;
33             }
34         } else if (paramOnBlurCheck (key)) {
35             if (! checkScript (vval, onblur, ferr)) {
36                 wiki->errorMsg.append (cell->dump ()).append (CharConst (": link script error.\n"));
37                 ferr = true;
38             }
39         } else if (paramOnChangeCheck (key)) {
40             if (! checkScript (vval, onchange, ferr)) {
41                 wiki->errorMsg.append (cell->dump ()).append (CharConst (": link script error.\n"));
42                 ferr = true;
43             }
44         } else if ((selector & SEL_TARGET) && paramTargetCheck (key)) {
45             paramTargetBody (key, vval.textOut (wiki), target, ferr);
46         } else if (readAttribMore (key, vval, ferr)) {
47         } else {
48             if (mode == M_ATTRIB) {
49                 wiki->errorMsg.append (cell->dump ()).append (CharConst (": bad attribute.\n"));
50                 rc = false;
51             }
52             return false;
53         }
54     } else {
55         if (selector & SEL_CLASS2) {
56             paramClassValue (*cell, classlist, ferr);
57         } else if (selector & SEL_TARGET2) {
58             paramTargetBody (uEmpty, cell->textOut (wiki), target, ferr);
59         } else if ((selector & SEL_ONCLICK2) && checkScript (*cell, onclick, ferr)) {
60         } else if ((selector & SEL_MULTIPLE2) && match (key, CharConst ("multiple"))) {
61             fmultiple = true;
62         } else if ((selector & SEL_DEFAULT2) && match (key, CharConst ("default"))) {
63             fdefault = true;
64         } else if ((selector & SEL_SCRIPT2) && checkScript (*cell, script, ferr)) {
65         } else if (readAttribMore2 (key, *cell, ferr)) {
66         } else {
67             if (mode == M_ATTRIB) {
68                 wiki->errorMsg.append (cell->dump ()).append (CharConst (": bad attribute.\n"));
69                 rc = false;
70             }
71             return false;
72         }
73     }
74     if (ferr) {
75         rc = false;
76         return false;
77     } else {
78         return true;
79     }
80 }
81
82 bool  WikiAttrib1::shiftAttrib (WikiMotorObjVecPtr& vec) {
83     bool  rc = true;
84     WikiMotorObjVecPtr  v2;
85
86     while (vec->size () > 0) {
87         WikiMotorObjVec  cell;
88
89         v2 = WikiMotorObjVecPtr (new WikiMotorObjVec);
90         if (vec->splitChar (':', cell, *v2) || mode == M_ATTRIB || mode == M_ATTRIB_TEXT) {
91             if (! readAttrib1 (&cell, rc))
92                 return rc;
93             vec = v2;
94         } else {
95             return true;
96         }
97     }
98     return true;
99 }
100
101 void  WikiAttrib1::skipAttrib (WikiMotorObjVecPtr& vec) {
102     WikiMotorObjVecPtr  v2;
103
104     if (vec->size () > 0) {
105         WikiMotorObjVec  cell;
106
107         v2 = WikiMotorObjVecPtr (new WikiMotorObjVec);
108         if (vec->splitChar (':', cell, *v2)) {
109             vec = v2;
110         }
111     }
112 }
113
114 bool  WikiAttrib1::readAttrib (WikiMotorObjVecVec::const_iterator& b, const WikiMotorObjVecVec::const_iterator& e) {
115     bool  rc = true;
116
117     while (b < e) {
118         WikiMotorObjVec*  cell = b->get ();
119         if (! readAttrib1 (cell, rc))
120             return rc;
121         b ++;
122     }
123     return true;
124 }
125
126 bool  WikiAttrib1::checkScript (WikiMotorObjVec& vec, ustring& scr, bool& ferr) {
127     bool  f = false;
128     int  i;
129     ustring  u;
130     for (i = 0; i < vec.size () && vec[i]->type == WikiMotorObj::wiki_funcLink; i ++) {
131         WikiMotorObjFuncLink*  fn = WikiMotorObjFuncLink_type (&*vec[i]);
132         u = fn->execDefunArgs (wiki);
133         // XXX: 末尾の空白を除去し,セミコロンを確認する。
134         scr.append (u);
135         f = true;
136     }
137     if (f)
138         return true;
139
140     return false;
141 }
142
143 bool  WikiAttrib1::shiftLink (WikiMotorObjVecPtr& vec, ustring& url, bool& fscript) {
144     bool  ferr = false;
145     bool  rc;
146     WikiMotorObjVec  cell;
147     WikiMotorObjVecPtr  v2 (new WikiMotorObjVec);
148
149     rc = vec->splitChar (':', cell, *v2);
150     if (checkScript (cell, url, ferr)) {
151         fscript = true;
152         vec = v2;
153         return true;
154     } else if (rc && cell.match (CharConst ("http"), CharConst ("https"))) {
155         ustring  proto = cell.dump ();
156         vec = v2;
157         cell.clear ();
158         v2 = WikiMotorObjVecPtr (new WikiMotorObjVec);
159         rc = vec->splitChar (':', cell, *v2);
160         if (! cell.splitURL_2 (wiki, proto, url)) {
161             vec = v2;
162             return false;
163         }
164         vec = v2;
165         if (vec->size () > 0) {
166             cell.clear ();
167             v2 = WikiMotorObjVecPtr (new WikiMotorObjVec);
168             rc = vec->splitChar (':', cell, *v2);
169             if (cell.splitURL_3 (wiki, url, url))
170                 vec = v2;
171         }
172         return true;
173     } else if (cell.splitURLPath (wiki, url)) {
174         vec = v2;
175         return true;
176     } else {
177         return false;
178     }
179     return false;
180 }
181
182 bool  WikiAttrib1::readLink (WikiMotorObjVecVec::const_iterator& b, const WikiMotorObjVecVec::const_iterator& e, ustring& url, bool& fscript, bool noscript) {
183     bool  ferr = false;
184     bool  rc;
185     WikiMotorObjVec*  cell;
186     static uregex  re (CharConst ("^[a-z]{3,6}$"));
187
188     if (b == e)
189         return false;
190     cell = b->get ();
191     rc = (b + 1 < e);
192     if (! noscript && checkScript (*cell, url, ferr)) {
193         fscript = true;
194         b ++;
195         return true;
196     } else if (rc && cell->regmatch (re)) {
197         ustring  proto = cell->dump ();
198         b ++;
199         cell = b->get ();
200         if (! cell->splitURL_2 (wiki, proto, url)) {
201             b ++;
202             return false;
203         }
204         b ++;
205         if (b < e) {
206             cell = b->get ();
207             if (cell->splitURL_3 (wiki, url, url))
208                 b ++;
209         }
210         return true;
211     } else if (cell->splitURLPath (wiki, url)) {
212         b ++;
213         return true;
214     } else {
215         return false;
216     }
217     return false;
218 }
219
220 bool  WikiAttrib1::shiftName (WikiMotorObjVecPtr& vec, ustring& name) {
221     if (vec->size () > 0) {
222         WikiMotorObjVec  cell;
223         WikiMotorObjVecPtr  v2 (new WikiMotorObjVec);
224
225         vec->splitChar (':', cell, *v2);
226         name = cell.textOut (wiki);
227         vec = v2;
228         return true;
229     } else {
230         return false;
231     }
232 }
233
234 void  WikiAttrib1::output (MotorOutput* out) {
235     wiki->outputID (out, id);
236     wiki->outputClass (out, classlist);
237 #ifdef BOOTSTRAPHACK
238 //    std::pair<ustring,ustring>::const_iterator  b, e;
239     std::vector<datapre_t>::const_iterator  b, e;
240     b = datapre.begin ();
241     e = datapre.end ();
242     for (; b < e; b ++) {
243         wiki->outputName (out, (*b).first.c_str (), (*b).first.size (), (*b).second);
244     }
245 #endif
246     wiki->outputSubmitScript (out, CharConst ("onclick"), onclick, scriptcut);
247     wiki->outputSubmitScript (out, CharConst ("onfocus"), onfocus, scriptcut);
248     wiki->outputSubmitScript (out, CharConst ("onblur"), onblur, scriptcut);
249     wiki->outputSubmitScript (out, CharConst ("onchange"), onchange, scriptcut);
250     wiki->outputName (out, CharConst ("target"), target);
251     wiki->outputFlag (out, CharConst ("multiple"), fmultiple);
252     // no fdefault
253     outputMore (out);
254 }
255
256 bool  WikiAttrib1::paramID (const ustring& key, WikiMotorObjVec& vval, bool& ferr) {
257     if (match (key, CharConst ("id"))) {
258         paramIDValue (key, vval, id, ferr);
259         return true;
260     } else {
261         return false;
262     }
263 }
264
265 void  WikiAttrib1::paramIDValue (const ustring& key, WikiMotorObjVec& vval, ustring& var, bool& ferr) {
266     ustring  value (vval.textOut (wiki));
267     if (checkWikiID (value)) {
268         var = value;
269         ferr = false;
270     } else {
271         wiki->errorMsg.append (key).append (uEq).append (value).append (CharConst (": bad value\n"));
272         ferr = true;
273     }
274 }
275
276 bool  WikiAttrib1::paramClass (const ustring& key, WikiMotorObjVec& vval, bool& ferr) {
277     if (match (key, CharConst ("class"))) {
278         paramClassValue (vval, classlist, ferr);
279         return true;
280     } else {
281         return false;
282     }
283 }
284
285 void  WikiAttrib1::paramClassValue (WikiMotorObjVec& vval, std::vector<ustring>& var, bool& ferr) {
286     WikiMotorObjVecVec  args;
287     ferr = false;
288     vval.splitCharA (',', args);
289     for (int i = 0; i < args.size (); i ++) {
290         ustring  value (args[i]->textOut (wiki));
291         if (value.length () > 0) {
292             if (checkWikiID (value)) {
293                 var.push_back (value);
294             } else {
295                 wiki->errorMsg.append (value).append (CharConst (": bad class name\n"));
296                 ferr = true;
297             }
298         }
299     }
300 }
301
302 bool  WikiAttrib1::paramWidth (const ustring& key, WikiMotorObjVec& vval, ustring& var, bool& ferr) {
303     if (match (key, CharConst ("width"), CharConst ("w"))) {
304         paramWidthValue (key, vval, var, ferr);
305         return true;
306     } else {
307         return false;
308     }
309 }
310
311 bool  WikiAttrib1::paramHeight (const ustring& key, WikiMotorObjVec& vval, ustring& var, bool& ferr) {
312     if (match (key, CharConst ("height"), CharConst ("h"))) {
313         paramWidthValue (key, vval, var, ferr);
314         return true;
315     } else {
316         return false;
317     }
318 }
319
320 void  WikiAttrib1::paramWidthValue (const ustring& key, WikiMotorObjVec& vval, ustring& var, bool& ferr) {
321     ustring  value (vval.textOut (wiki));
322     if (checkWidth (value)) {
323         var = value;
324 //          if (checkNum (value))
325 //              var.append (CharConst ("px"));
326         ferr = false;
327     } else {
328         wiki->errorMsg.append (key).append (uEq).append (value).append (CharConst (": bad value\n"));
329         ferr = true;
330     }
331 }
332
333 bool  WikiAttrib1::paramSize (const char* name, size_t namelen, const ustring& key, WikiMotorObjVec& vval, ustring& var, bool& ferr) {
334     if (match (key, name, namelen)) {
335         ustring  value (vval.textOut (wiki));
336         if (checkNum (value)) {
337             var = value;
338             ferr = false;
339         } else {
340             ferr = true;
341         }
342         return true;
343     }
344     return false;
345 }
346
347 void  WikiAttrib1::paramUNum (const ustring& value, int& var, const ustring& name) {
348     if (checkNum (value)) {
349         var = strtoul (value);
350     } else {
351         wiki->errorMsg.append (name).append (uEq).append (value).append (uErrorBadValue).append (uLF);
352     }
353 }
354
355 void  WikiAttrib1::paramColor (const ustring& value, ustring& var, const ustring& name) {
356     if (checkColor (value)) {
357         var = value;
358     } else {
359         wiki->errorMsg.append (name).append (uEq).append (value).append (uErrorBadValue).append (uLF);
360     }
361 }
362
363 bool  WikiAttrib1::paramTargetCheck (const ustring& key) {
364     return match (key, CharConst ("target"));
365 }
366
367 void  WikiAttrib1::paramTargetBody (const ustring& key, const ustring& value, ustring& var, bool& ferr) {
368     if (value.length () == 0 || checkWikiID (value)) {
369         var = value;
370     } else {
371         if (key.length () > 0)
372             wiki->errorMsg.append (key).append (uEq).append (value).append (CharConst (": bad target name.\n"));
373         else
374             wiki->errorMsg.append (value).append (CharConst (": bad target name.\n"));
375         ferr = true;
376     }
377 }
378
379 bool  WikiAttrib1::paramOnClickCheck (const ustring& name) {
380     return match (name, CharConst ("onclick"));
381 }
382
383 bool  WikiAttrib1::paramOnFocusCheck (const ustring& name) {
384     return match (name, CharConst ("onfocus"));
385 }
386
387 bool  WikiAttrib1::paramOnBlurCheck (const ustring& name) {
388     return match (name, CharConst ("onblur"));
389 }
390
391 bool  WikiAttrib1::paramOnChangeCheck (const ustring& name) {
392     return match (name, CharConst ("onchange"));
393 }
394
395 #ifdef BOOTSTRAPHACK
396 bool  WikiAttrib1::paramDataPrefix (const ustring& key, WikiMotorObjVec& vval, bool& ferr) {
397 //    if (match (CharConst ("data-"), key) && checkWikiID (key)) {
398     if (matchHead (key, CharConst ("data-")) && checkWikiID (key)) {
399         ustring  value (vval.textOut (wiki));
400         if (checkWikiID (value)) {
401             datapre.push_back (std::pair<ustring,ustring> (key, value));
402             ferr = false;
403         } else {
404             wiki->errorMsg.append (key).append (uEq).append (value).append (CharConst (": bad value\n"));
405             ferr = true;
406         }
407         return true;
408     } else {
409         return false;
410     }
411 }
412 #endif
413 /* ============================================================ */
414 void  WikiAttribTable::init () {
415     fheader = false;
416     halign = HAlignNone;
417     valign = VAlignNone;
418     fnowrap = false;
419 #ifdef WIKITABLEATTRIB
420     fnoborder = false;
421     cellspacing = -1;
422     cellpadding = -1;
423 #endif
424     fpadding = false;
425 //      halign = HAlignNone;
426     fnowhite = false;
427     fturn = false;
428
429     id.resize (0);
430     while (! classlist.empty ())
431         classlist.pop_back ();
432     width.resize (0);
433     height.resize (0);
434     bgcolor.resize (0);
435     onclick.resize (0);
436 }
437
438 void  WikiAttribTable::copyFrom (WikiAttribTable& b) {
439     int  i;
440
441     id = b.id;
442     for (i = 0; i < b.classlist.size (); i ++)
443         classlist.push_back (b.classlist[i]);
444     onclick = b.onclick;
445     fheader = b.fheader;
446     halign = b.halign;
447     valign = b.valign;
448     width = b.width;
449     height = b.height;
450     bgcolor = b.bgcolor;
451     fnowrap = b.fnowrap;
452 }
453
454 bool  WikiAttribTable::readAttribMore (const ustring& key, WikiMotorObjVec& vval, bool& ferr) {
455     if (paramWidth (key, vval, width, ferr)) {
456     } else if (paramHeight (key, vval, height, ferr)) {
457     } else if (match (key, CharConst ("bgcolor"), CharConst ("bg"))) {
458         paramColor (vval.textOut (wiki), bgcolor, key);
459     } else {
460         switch (selector2) {
461         case SEL_TABLE:
462 #ifdef WIKITABLEATTRIB
463             if (match (key, CharConst ("cellspacing"), CharConst ("spc"))) {
464                 paramUNum (vval.textOut (wiki), cellspacing, key);
465             } else if (match (key, CharConst ("cellpadding"))) {
466                 paramUNum (vval.textOut (wiki), cellpadding, key);
467             } else {
468                 return false;
469             }
470 #else
471             return false;
472 #endif
473             break;
474         case SEL_TR:
475         case SEL_TD:
476             return false;
477         default:
478             assert (0);
479         }
480     }
481     return true;
482 }
483
484 bool  WikiAttribTable::readAttribMore2 (const ustring& key, WikiMotorObjVec& cell, bool& ferr) {
485     if (match (key, CharConst ("left"), CharConst ("l"))) {
486         halign = HAlignLeft;
487     } else if (match (key, CharConst ("right"), CharConst ("r"))) {
488         halign = HAlignRight;
489     } else if (match (key, CharConst ("center"), CharConst ("c"))) {
490         halign = HAlignCenter;
491     } else {
492         switch (selector2) {
493         case SEL_TABLE:
494 #ifdef WIKITABLEATTRIB
495             if (match (key, CharConst ("noborder"), CharConst ("nb"))) {
496                 fnoborder = true;
497             } else
498 #endif
499             if (match (key, CharConst ("padding"), CharConst ("pad"))) {
500                 fpadding = true;
501             } else if (match (key, CharConst ("expanding"), CharConst ("expand"))) {
502                 fpadding = false;
503             } else if (match (key, CharConst ("nowhite"), CharConst ("nw"))) {
504                 fnowhite = true;
505             } else if (match (key, CharConst ("turn"))) {
506                 fturn = true;
507             } else {
508                 return false;
509             }
510             break;
511         case SEL_TR:
512         case SEL_TD:
513             if (match (key, CharConst ("header"), CharConst ("h"))) {
514                 fheader = true;
515             } else if (match (key, CharConst ("top"), CharConst ("t"))) {
516                 valign = VAlignTop;
517             } else if (match (key, CharConst ("middle"), CharConst ("m"))) {
518                 valign = VAlignMiddle;
519             } else if (match (key, CharConst ("bottom"), CharConst ("b"))) {
520                 valign = VAlignBottom;
521             } else if (match (key, CharConst ("nowrap"), CharConst ("nw"))) {
522                 fnowrap = true;
523             } else if (match (key, CharConst ("*"))) {
524                 init ();
525             } else {
526                 return false;
527             }
528             break;
529         default:
530             assert (0);
531         }
532     }
533
534     return true;
535 }
536
537 void  WikiAttribTable::outputMore (MotorOutput* out) {
538     switch (halign) {
539     case HAlignLeft:
540         out->out_raw (CharConst (" align=\"left\""));
541         break;
542     case HAlignCenter:
543         out->out_raw (CharConst (" align=\"center\""));
544         break;
545     case HAlignRight:
546         out->out_raw (CharConst (" align=\"right\""));
547         break;
548     }
549     wiki->outputName (out, CharConst ("width"), width);
550     wiki->outputName (out, CharConst ("height"), height);
551     wiki->outputName (out, CharConst ("bgcolor"), bgcolor);
552
553     switch (selector2) {
554     case SEL_TABLE:
555 #ifdef WIKITABLEATTRIB
556         wiki->outputName (out, CharConst ("border"), fnoborder ? 0 : 1, false);
557         wiki->outputName (out, CharConst ("cellspacing"), cellspacing, false);
558         wiki->outputName (out, CharConst ("cellpadding"), cellpadding, false);
559 #endif
560         break;
561     case SEL_TR:
562     case SEL_TD:
563         switch (valign) {
564         case VAlignTop:
565             out->out_raw (CharConst (" valign=\"top\""));
566             break;
567         case VAlignMiddle:
568             out->out_raw (CharConst (" valign=\"middle\""));
569             break;
570         case VAlignBottom:
571             out->out_raw (CharConst (" valign=\"bottom\""));
572             break;
573         }
574         wiki->outputFlag (out, CharConst ("nowrap"), fnowrap);
575         break;
576     default:
577         assert (0);
578     }
579 }
580
581 /* ============================================================ */
582 bool  WikiAttribImg::readAttribMore (const ustring& key, WikiMotorObjVec& vval, bool& ferr) {
583     if (paramWidth (key, vval, width, ferr)) {
584     } else if (paramHeight (key, vval, height, ferr)) {
585     } else if (match (key, CharConst ("alt"))) {
586         alt = vval.textOut (wiki);
587     } else {
588         return false;
589     }
590     return true;
591 }
592
593 void  WikiAttribImg::outputMore (MotorOutput* out) {
594     wiki->outputName (out, CharConst ("width"), width);
595     wiki->outputName (out, CharConst ("height"), height);
596     // longdesc
597 }
598
599 /* ============================================================ */
600 bool  WikiAttribInput::readAttribMore (const ustring& key, WikiMotorObjVec& vval, bool& ferr) {
601     if ((selector2 & SEL_INPUT) && paramSize (CharConst ("size"), key, vval, psize, ferr)) {
602     } else if ((selector2 & SEL_ELSIZE) && match (key, CharConst ("size"))) {
603         ustring  v = vval.textOut (wiki);
604         if (match (v, CharConst ("*"))) {
605             elsize = 1;
606         } else if (checkNum (v)) {
607             elsize = to_int32 (v);
608             if (elsize < 0 || elsize > 999) {
609                 elsize = 1;
610             }
611         } else {
612             elsize = 1;
613         }
614     } else if (paramWidth (key, vval, pwidth, ferr)) {
615     } else if ((selector2 & SEL_TEXTAREA) && paramSize (CharConst ("cols"), key, vval, pcols, ferr)) {
616     } else if ((selector2 & SEL_TEXTAREA) && paramSize (CharConst ("rows"), key, vval, prows, ferr)) {
617     } else if ((selector2 & SEL_TEXTAREA) && match (key, CharConst ("wrap"))) {
618         ustring  value (vval.textOut (wiki));
619         if (match (value, CharConst ("off"))) {
620             pwrap = W_OFF;
621         } else if (match (value, CharConst ("soft"))) {
622             pwrap = W_SOFT;
623         } else if (match (value, CharConst ("hard"))) {
624             pwrap = W_HARD;
625         } else if (paramWidth (key, vval, pwidth, ferr)) {
626         } else {
627             wiki->errorMsg.append (key).append (CharConst ("=")).append (vval.dump ()).append (CharConst (": link script error.\n"));
628             ferr = true;
629             return false;
630         }
631     } else {
632         return false;
633     }
634     return true;
635 }
636
637 bool  WikiAttribInput::readAttribMore2 (const ustring& key, WikiMotorObjVec& cell, bool& ferr) {
638     if (key == uDefault) {
639         pdefault = true;
640     } else if ((selector2 & SEL_CHECK) && match (key, CharConst ("checked"))) {
641         pchecked = true;
642     } else if ((selector2 & SEL_TEXTAREA) && match (key, CharConst ("tab"))) {
643         ftab = true;
644     } else {
645         return false;
646     }
647     return true;
648 }
649
650 void  WikiAttribInput::outputMore (MotorOutput* out) {
651     wiki->outputName (out, CharConst ("size"), psize);
652     wiki->outputName (out, CharConst ("size"), elsize);
653     if (pwidth.size () > 0) {
654         if (checkNum (pwidth)) {
655             out->out_raw (CharConst (" style=\"width:"))->out_toHTML_noCtrl (pwidth)->out_raw (CharConst ("px;\""));
656         } else {
657             out->out_raw (CharConst (" style=\"width:"))->out_toHTML_noCtrl (pwidth)->out_raw (CharConst (";\""));
658         }
659     }
660     if (selector2 & SEL_CHECK) {
661         wiki->outputFlag (out, CharConst ("checked"), pchecked);
662     }
663     if (selector2 & SEL_TEXTAREA) {
664         wiki->outputName (out, CharConst ("cols"), pcols, false);
665         wiki->outputName (out, CharConst ("rows"), prows);
666         switch (pwrap) {
667         case W_OFF:
668             out->out_raw (CharConst (" wrap=\"off\""));
669             break;
670         case W_SOFT:
671             out->out_raw (CharConst (" wrap=\"soft\""));
672             //  out->out_raw (CharConst (" wrap=\"virtual\""));
673             break;
674         case W_HARD:
675             out->out_raw (CharConst (" wrap=\"hard\""));
676             //  out->out_raw (CharConst (" wrap=\"physical\""));
677             break;
678         }
679         if (ftab) {
680             out->out_raw (uSPC)
681                 ->out_raw (CharConst ("onkeypress"))
682                 ->out_raw (CharConst ("=\""))
683                 ->out_toHTML (ustring (CharConst ("return insertTab(event,this);")))
684                 ->out_raw ("\"");
685             out->out_raw (uSPC)
686                 ->out_raw (CharConst ("onkeydown"))
687                 ->out_raw (CharConst ("=\""))
688                 ->out_toHTML (ustring (CharConst ("return insertTab(event,this);")))
689                 ->out_raw ("\"");
690             out->out_raw (uSPC)
691                 ->out_raw (CharConst ("onkeyup"))
692                 ->out_raw (CharConst ("=\""))
693                 ->out_toHTML (ustring (CharConst ("return insertTab(event,this);")))
694                 ->out_raw ("\"");
695         }
696     }
697 }
698
699 /* ============================================================ */
700 bool  WikiAttribButton::readAttrib (WikiMotorObjVecVec::const_iterator& b, const WikiMotorObjVecVec::const_iterator& e) {
701     bool  rc = true;
702
703     if (b < e) {
704         WikiMotorObjVec*  cell = b->get ();
705         mode_t  bm = mode;
706
707         mode = M_NORMAL;
708         if (! readAttrib1 (cell, rc)) {
709             name = cell->textOut (wiki);
710         }
711         mode = bm;
712         b ++;
713     }
714     while (b < e) {
715         WikiMotorObjVec*  cell = b->get ();
716         if (! readAttrib1 (cell, rc))
717             return rc;
718         b ++;
719     }
720     return true;
721 }
722
723 /* ============================================================ */
724 bool  WikiAttribItem::readAttribMore (const ustring& key, WikiMotorObjVec& vval, bool& ferr) {
725     if (match (key, CharConst ("ulclass"))) {
726         if (owner && owner->parent && owner->parent->attrib.classlist.size () == 0) {
727             paramClassValue (vval, owner->parent->attrib.classlist, ferr);
728         }
729     } else if (match (key, CharConst ("ulid"))) {
730         if (owner && owner->parent && owner->parent->attrib.id.size () == 0) {
731             paramIDValue (key, vval, owner->parent->attrib.id, ferr);
732         }
733     } else {
734         return false;
735     }
736     return true;
737 }
738
739 /* ============================================================ */