OSDN Git Service

505546deb6b26fb1d9d3ed6a0a7622b5606b420c
[hmh/hhml.git] / wiki / wikiformat.h
1 #ifndef WIKIFORMAT_H
2 #define WIKIFORMAT_H
3
4 #include "wikimotor.h"
5 #include "wikiattrib.h"
6 #include "wikitable.h"
7 #include "motoroutput.h"
8 #include "motorenv.h"
9 #include "mlenv.h"
10 #include "ftable.h"
11 #include "ustring.h"
12 #include "util_splitter.h"
13 #include "util_string.h"
14 #include <boost/ptr_container/ptr_vector.hpp>
15 #include <boost/unordered_map.hpp>
16 #include <vector>
17 #include <iostream>
18 #include <assert.h>
19
20 class  WikiBlock;
21 class  WikiFormat;
22
23 class  WikiMlEnv: public MlEnv {
24  public:
25     WikiMlEnv (MlPool* _mlpool, MlFTable* _mlftable): MlEnv (_mlpool, _mlftable) {};
26     virtual  ~WikiMlEnv () {};
27
28     virtual void  setVar (const ustring& name, MNode* val);
29     virtual void  setAry (const ustring& name, size_t i, MNode* val);
30     virtual void  setArySize (const ustring& name, size_t n);
31     virtual void  setAry (const ustring& name, MNode* list);
32     virtual MNode*  getVar (const ustring& name);
33     virtual MNode*  getAry (const ustring& name, size_t i);
34     virtual size_t  getArySize (const ustring& name);
35     virtual void  setLocalVar (const ustring& name, MNode* val);
36     virtual void  defineLocalVar (const ustring& name);
37     virtual ustring  wikiVarName (const ustring& name);
38 };
39
40 class  WikiMotorOutputString: public MotorOutputString {
41  public:
42     WikiFormat*  wiki;
43
44     WikiMotorOutputString (WikiFormat* _wiki): wiki (_wiki) {};
45     virtual  ~WikiMotorOutputString () {};
46     virtual void  flush (bool fsuper);
47     virtual bool  isResponse () {
48         return false;
49     };
50 };
51
52 class  WikiLine {
53  public:
54     typedef boost::ptr_vector<WikiLine>  linevec;
55
56     uiterator  begin0;
57     uiterator  begin;
58     uiterator  end;
59     void  (*fn) (WikiLine* wl, WikiFormat* wiki);
60     linevec*  block;
61     WikiLine*  block2;
62     bool  fsuper;
63
64     WikiLine (uiterator b, uiterator e, bool _fsuper) {
65         begin0 = begin = b;
66         end = e;
67         fn = NULL;
68         block = NULL;
69         block2 = NULL;
70         fsuper = _fsuper;
71     };
72     WikiLine (uiterator b0, uiterator b, uiterator e, bool _fsuper) {
73         begin0 = b0;
74         begin = b;
75         end = e;
76         fn = NULL;
77         block = NULL;
78         block2 = NULL;
79         fsuper = _fsuper;
80     };
81     virtual  ~WikiLine () {
82         delete block;
83         delete block2;
84     };
85     
86 };
87
88 class  WikiMacro {
89  public:
90     MNodePtr  vars;
91     WikiLine::linevec*  wl;
92
93 #if 0
94     WikiMacro (MNode* _vars, WikiLine::linevec* _wl) {
95         vars = _vars;
96         wl = _wl;
97     };
98 #endif
99     WikiMacro () {
100         wl = NULL;
101     };
102     virtual  ~WikiMacro () {
103 //      delete vars;
104 //      vars = NULL;
105         delete wl;
106         wl = NULL;
107     };
108 };
109
110 class  WikiLineScanner {
111  public:
112     WikiLine::linevec*  wlv;
113     int  idx;
114
115     WikiLineScanner (WikiLine::linevec* v) {
116         assert (v);
117         wlv = v;
118         idx = -1;
119     };
120     virtual  ~WikiLineScanner () {};
121
122     virtual WikiLine*  cur () {
123         if (0 <= idx && idx < wlv->size ()) {
124             return &(*wlv)[idx];
125         } else {
126             return NULL;
127         }
128     };
129     virtual WikiLine*  next () {
130         idx ++;
131         return cur ();
132     };
133     virtual void  rollback () {
134         if (idx >= 0)
135             idx --;
136     };
137     virtual bool  isEnd () {
138         return idx >= wlv->size ();
139     };
140 };
141
142 class  WikiBlock {
143  public:
144     typedef enum {
145         BlockNone,
146         BlockParagraph,
147         BlockH,
148         BlockPreformatRaw,
149         BlockItemText,
150         BlockItemUL,
151         BlockItemOL,
152         BlockItemNL,
153         BlockItemDL,
154         BlockTS,
155         BlockTable,
156         BlockSelect,
157         BlockQuote,
158         BlockDF,
159         BlockDiv,
160         BlockForm,
161         BlockElement,
162         BlockHR,
163         BlockRaw,
164     }  blockType;
165     typedef enum {
166         CloseNA,
167         CloseFalse,
168         CloseTrue,
169     }  closeType;
170
171     blockType  type;
172     WikiFormat*  wiki;
173
174     WikiBlock (blockType t, WikiFormat* w): type (t), wiki (w) {};
175     virtual  ~WikiBlock () {};
176
177     virtual void  addLine (uiterator b, uiterator e) {
178         assert (0);
179     };
180     virtual bool  nextLine (uiterator b, uiterator e) = 0;
181     virtual closeType  closeLine (uiterator b, uiterator e) {
182         return CloseNA;
183     };
184     virtual void  addLines (uiterator b, uiterator e) {
185         assert (0);
186     };
187     virtual void  addHtml (const ustring& ht) {
188         assert (0);
189     };
190     virtual void  close () {};
191     virtual void  output (MotorOutput* out) = 0;
192 };
193
194 class  WikiBlockComplex: public WikiBlock {
195  public:
196     boost::ptr_vector<WikiBlock>  block;
197
198     WikiBlockComplex (blockType t, WikiFormat* w): WikiBlock (t, w) {};
199     virtual  ~WikiBlockComplex () {};
200     virtual void  outputBlock (MotorOutput* out);
201 };
202
203 class  WikiBlockParagraph: public WikiBlock {
204  public:
205     int  count;
206     bool  singleTag;
207     bool  pflag;
208     WikiMotorObjVec  objv;
209
210     WikiBlockParagraph (WikiFormat* w): WikiBlock (BlockParagraph, w) {
211         count = 0;
212         singleTag = false;
213         pflag = false;
214     };
215     virtual  ~WikiBlockParagraph () {};
216
217     virtual bool  nextLine (uiterator b, uiterator e);
218     virtual void  addLine (uiterator b, uiterator e);
219     virtual void  addHtml (const ustring& ht);
220     virtual void  output (MotorOutput* out);
221 };
222 inline WikiBlockParagraph*  WikiBlockParagraph_type (WikiBlock* b) {
223     assert (b->type == WikiBlock::BlockParagraph);
224     return (WikiBlockParagraph*)b;
225 }
226
227 class  WikiBlockH: public WikiBlockComplex {
228  public:
229     ustring  title;
230     ustring  anchor;
231     int  level0;
232     int  level;
233
234     WikiBlockH (WikiFormat* w): WikiBlockComplex (BlockH, w) {
235         level0 = level = 0;
236     };
237     virtual  ~WikiBlockH () {};
238
239     virtual bool  nextLine (uiterator b, uiterator e);
240     virtual void  addLine (uiterator b, uiterator e);
241     virtual closeType  closeLine (uiterator b, uiterator e);
242     virtual void  close ();
243     virtual void  output (MotorOutput* out);
244     virtual void  outputBeginDiv (int lv, MotorOutput* out);
245     virtual void  outputEndDiv (int lv, MotorOutput* out);
246     virtual bool  checkEmpty ();
247 };
248
249 class  WikiBlockPreformatRaw: public WikiBlock {
250  public:
251     ustring  text;
252     char  markup;
253
254     WikiBlockPreformatRaw (WikiFormat* w): WikiBlock (BlockPreformatRaw, w) {
255         markup = 0;
256     };
257     virtual  ~WikiBlockPreformatRaw () {};
258
259     virtual bool  nextLine (uiterator b, uiterator e);
260     virtual void  addLine (uiterator b, uiterator e);
261     virtual void  output (MotorOutput* out);
262 };
263
264 class  WikiBlockItem;
265 class  WikiBlockItemText: public WikiBlockComplex {
266  public:
267     ustring  html;
268     bool  indentHack;
269     WikiAttribItem  attrib;
270     WikiBlockItem*  parent;
271
272     WikiBlockItemText (WikiFormat* w, WikiBlockItem* _p): WikiBlockComplex (BlockItemText, w), attrib (w, this) {
273         indentHack = false;
274         parent = _p;
275     };
276     virtual  ~WikiBlockItemText () {};
277     virtual bool  nextLine (uiterator b, uiterator e);
278     virtual void  addLine (uiterator b, uiterator e);
279     virtual bool  checkAddLine (uiterator b, uiterator e);
280     virtual void  output (MotorOutput* out);
281 };
282
283 class  WikiBlockItem: public WikiBlock {
284  public:
285     int  ch;
286     boost::ptr_vector<WikiBlockItemText>  block;
287     WikiAttrib1  attrib;
288
289     WikiBlockItem (blockType t, WikiFormat* w): WikiBlock (t, w), attrib (w, WikiAttrib1::SEL_ID, false, WikiAttrib1::M_NORMAL) {
290         assert (t == BlockItemUL || t == BlockItemOL || t == BlockItemNL);
291         ch = 0;
292         if (t == BlockItemOL)
293             attrib.selector |= WikiAttrib1::SEL_START;
294     };
295     virtual  ~WikiBlockItem () {};
296
297     virtual bool  nextLine (uiterator b, uiterator e);
298     virtual void  setChar (char c);
299     virtual void  addLine (uiterator b, uiterator e);
300     virtual void  output (MotorOutput* out);
301     virtual void  outputBlock (MotorOutput* out);
302 };
303
304 class  WikiBlockItemDL: public WikiBlock {
305  public:
306     boost::ptr_vector<WikiMotorObjVec>  objv1;
307     boost::ptr_vector<WikiMotorObjVec>  objv2;
308
309     WikiBlockItemDL (WikiFormat* w): WikiBlock (BlockItemDL, w) {};
310     virtual  ~WikiBlockItemDL () {};
311
312     virtual bool  nextLine (uiterator b, uiterator e);
313     virtual void  addLine (uiterator b, uiterator e);
314     virtual void  output (MotorOutput* out);
315 };
316
317 class  WikiBlockTable: public WikiBlock {
318  public:
319     class  TableCell {
320     public:
321         ustring  html;
322         boost::ptr_vector<WikiBlock>  block;
323         WikiAttribTable  cellattrib;
324         bool  fcolspan;
325         bool  frowspan;
326         int  rowspan;
327         int  colspan;
328         bool  spanmatch;
329
330         TableCell (WikiFormat* _wiki, WikiAttrib1::mode_t _mode): cellattrib (_wiki, WikiAttribTable::SEL_TD, _mode) {
331             fcolspan = false;
332             frowspan = false;
333             rowspan = 1;
334             colspan = 1;
335             spanmatch = false;
336         };
337         virtual  ~TableCell () {};
338         virtual void  cellBody (WikiMotorObjVec* vtext, WikiBlockTable* table, int idx);
339         virtual void  outputTD (WikiFormat* wiki, MotorOutput* out, bool fturn);
340         virtual void  outputTDe (MotorOutput* out);
341     };
342
343     class  CellList_t: public boost::ptr_vector<TableCell> {
344     public:
345         WikiAttribTable  rowattrib;
346
347         CellList_t (WikiFormat* _wiki): rowattrib (_wiki, WikiAttribTable::SEL_TR, WikiAttrib1::M_ATTRIB) {};
348         virtual  ~CellList_t () {};
349     };
350     typedef boost::ptr_vector<CellList_t>  TableAry_t;
351
352     int  n;
353     WikiAttribTable  attrib;
354     bool  cont;
355     int  ccont;
356     CellList_t  defaultList;
357     TableAry_t  ary;
358     ustring  captionHtml;
359
360     WikiBlockTable (WikiFormat* _wiki): WikiBlock (BlockTable, _wiki), attrib (_wiki, WikiAttribTable::SEL_TABLE, WikiAttrib1::M_ATTRIB_TEXT), defaultList (_wiki) {
361         n = 0;
362         cont = false;
363         ccont = 0;
364     };
365     virtual  ~WikiBlockTable () {};
366
367     virtual bool  nextLine (uiterator b, uiterator e);
368     virtual void  addLine (uiterator b, uiterator e);
369     virtual closeType  closeLine (uiterator b, uiterator e);
370     virtual void  output (MotorOutput* out);
371     virtual void  addLine_head (uiterator b, uiterator e);
372     virtual void  addLine_body (uiterator b, uiterator e);
373     virtual TableCell*  newCell (int idx);
374     virtual TableCell*  newCell (WikiAttribTable& rowattrib);
375     virtual void  normalize ();
376     virtual void  outputTableTag (MotorOutput* out);
377     virtual void  outputTBody (MotorOutput* out);
378     virtual void  outputTBodyCell (WikiFormat* wiki, MotorOutput* out, TableCell* cell);
379 };
380
381 class  WikiBlockSelect: public WikiBlock {
382  public:
383     class  SelectItem {
384     public:
385         ustring  label;
386         ustring  value;
387         bool  fvalue;
388         bool  fselect;
389
390         SelectItem (): fvalue (false), fselect (false) {};
391         virtual  ~SelectItem () {};
392     };
393
394     int  n;
395     ustring  name;
396     WikiAttribInput  attrib;
397     std::vector<SelectItem>  item;
398
399     WikiBlockSelect (WikiFormat* w): WikiBlock (BlockSelect, w), attrib (w, WikiAttribInput::SEL_ELSIZE) {
400         attrib.selector |= WikiAttrib1::SEL_DEFAULT2 | WikiAttrib1::SEL_MULTIPLE2 | WikiAttrib1::SEL_SCRIPT2;
401         n = 0;
402     };
403     virtual  ~WikiBlockSelect () {};
404
405     virtual bool  nextLine (uiterator b, uiterator e);
406     virtual void  addLine (uiterator b, uiterator e);
407     virtual void  addLine_head (uiterator b, uiterator e);
408     virtual void  addLine_body (uiterator b, uiterator e);
409     virtual void  close ();
410     virtual void  output (MotorOutput* out);
411 };
412
413 class  WikiBlockQuote: public WikiBlockComplex {
414  public:
415     WikiBlockQuote (WikiFormat* w): WikiBlockComplex (BlockQuote, w) {};
416     virtual  ~WikiBlockQuote () {};
417
418     virtual bool  nextLine (uiterator b, uiterator e);
419     virtual closeType  closeLine (uiterator b, uiterator e);
420     virtual void  addLine (uiterator b, uiterator e);
421     virtual void  output (MotorOutput* out);
422 };
423
424 class  WikiBlockDiv: public WikiBlockComplex {
425  public:
426     WikiAttrib1  attrib;
427
428     WikiBlockDiv (WikiFormat* w): WikiBlockComplex (BlockDiv, w), attrib (w, WikiAttrib1::SEL_CLASS2, false, WikiAttrib1::M_ATTRIB) {};
429     virtual  ~WikiBlockDiv () {};
430
431     virtual bool  nextLine (uiterator b, uiterator e);
432     virtual void  addLine (uiterator b, uiterator e);
433     virtual closeType  closeLine (uiterator b, uiterator e);
434     virtual void  output (MotorOutput* out);
435 };
436
437 class  WikiBlockForm: public WikiBlockComplex {
438  public:
439     enum {
440         M_NONE,
441         M_GET,
442         M_POST,
443     }  method;
444     WikiAttrib1  attrib;
445     ustring  url;
446     bool  fscript;
447     bool  qfileform;
448
449     WikiBlockForm (WikiFormat* w): WikiBlockComplex (BlockForm, w), attrib (w, WikiAttrib1::SEL_TARGET, true, WikiAttrib1::M_ATTRIB) {
450         method = M_NONE;
451         fscript = false;
452         qfileform = false;
453     };
454     virtual  ~WikiBlockForm () {};
455
456     virtual bool  nextLine (uiterator b, uiterator e);
457     virtual void  addLine (uiterator b, uiterator e);
458     virtual closeType  closeLine (uiterator b, uiterator e);
459     virtual void  output (MotorOutput* out);
460 };
461
462 class  WikiBlockElement: public WikiBlockComplex {
463  public:
464     ustring  name;
465
466     WikiBlockElement (WikiFormat* w): WikiBlockComplex (BlockElement, w) {};
467     virtual  ~WikiBlockElement () {};
468
469     virtual bool  nextLine (uiterator b, uiterator e);
470     virtual void  addLine (uiterator b, uiterator e);
471     virtual closeType  closeLine (uiterator b, uiterator e);
472     virtual void  output (MotorOutput* out);
473 };
474
475 class  WikiBlockElementMap: public boost::unordered_map<ustring, WikiBlockElement*> {
476  public:
477     WikiBlockElementMap () {};
478     virtual  ~WikiBlockElementMap () {};
479
480     WikiBlockElement*  get (const ustring& name) {
481         iterator  it = find (name);
482         if (it == end ()) {
483             return NULL;
484         } else {
485             return it->second;
486         }
487     };
488     WikiBlockElement*  put (const ustring& name, WikiBlockElement* e) {
489         std::pair<iterator, bool>  x;
490         x = insert (value_type (name, e));
491         x.first->second = e;
492         return e;
493     };
494     WikiBlockElement*  del (const ustring& name) {
495         assert (0);
496     };
497 };
498
499 class  WikiBlockHR: public WikiBlock {
500  public:
501     WikiBlockHR (WikiFormat* w): WikiBlock (BlockHR, w) {};
502     virtual  ~WikiBlockHR () {};
503
504     virtual bool  nextLine (uiterator b, uiterator e);
505     virtual void  addLine (uiterator b, uiterator e);
506     virtual void  output (MotorOutput* out);
507 };
508
509 class  WikiBlockRaw: public WikiBlock {
510  public:
511     ustring  text;
512
513     WikiBlockRaw(WikiFormat* w): WikiBlock (BlockRaw, w) {};
514     virtual  ~WikiBlockRaw () {};
515
516     virtual bool  nextLine (uiterator b, uiterator e);
517     virtual void  addLine (uiterator b, uiterator e);
518     virtual void  output (MotorOutput* out);
519 };
520
521 class  WikiFormat {
522  public:
523     typedef  enum {
524         M_NONE,
525         M_URL,
526     }  ipMode_t;
527     class  DepthCount {
528     public:
529         WikiFormat*  wiki;
530         DepthCount (WikiFormat* _wiki) {
531             wiki = _wiki;
532             wiki->depth ++;
533         };
534         virtual  ~DepthCount () {
535             wiki->depth --;
536             assert (wiki->depth >= 0);
537         };
538         virtual bool  test () {
539             return wiki->depth >= 32;
540         };
541     };
542
543     WikiBlock*  cur;
544     WikiBlockForm*  curform;
545     int  hlevel;
546     int  headbase;
547     MotorEnv*  env;
548     MlEnv*  mlenv;
549     MlFTable  mlFTable;
550     ustring  errorMsg;
551     boost::ptr_vector<WikiBlock>  block;
552     boost::ptr_vector<WikiBlock>*  blockp;
553     std::vector<WikiBlock*>  bstack;
554     std::vector<boost::ptr_vector<WikiBlock>*>  pstack;
555     WikiBlockElementMap  elementMap;
556     bool  protectMode;
557     ipMode_t  ipMode;
558     int  depth;
559     bool  motorPre;
560
561     WikiFormat (MotorEnv* e, bool mode) {
562         cur = NULL;
563         curform = NULL;
564         hlevel = 0;
565         headbase = 0;
566         env = e;
567         mlenv = new WikiMlEnv (env->mlenv->mlPool, &mlFTable);
568         mlenv->env = env;
569         if (env->log)
570             mlenv->log = env->log;
571         else
572             mlenv->log = &std::cerr;
573         mlenv->setStartTime ();
574         mlenv->resetProg ();
575         mlFTable.setFTable (&GWikiFTable, NULL);
576         blockp = &block;
577         protectMode = mode;
578         ipMode = M_NONE;
579         depth = 0;
580 #ifdef WIKIMOTORPRE
581         motorPre = true;
582 #else
583         motorPre = false;
584 #endif
585     };
586     virtual  ~WikiFormat () {
587         delete mlenv;
588     };
589
590     virtual void  compile (const ustring& text, bool fsuper);
591     virtual void  output (boost::ptr_vector<WikiBlock>& ary);
592     virtual void  output () {
593         output (block);
594     };
595     virtual void  outputElement (const ustring& elementName);
596     virtual void  pass1 (const ustring& text, WikiLine::linevec* block, bool fsuper);
597     virtual int  pass1_1 (Splitter& sp, ustring* elseword, ustring* endword, WikiLine::linevec* block, uiterator* elsebegin0, uiterator* elsebegin, uiterator* elseend, bool fsuper);
598     virtual bool  pass1_2 (Splitter& sp, uiterator& b, uiterator& e, uiterator& t, uiterator& u, uiterator& v, WikiLine::linevec* block, bool fsuper);
599     virtual void  errorOutput ();
600
601     virtual bool  checkClose (uiterator b, uiterator e);
602     virtual void  compileLine (WikiLineScanner& scanner);
603     virtual void  compileLines (WikiLineScanner& scanner, bool (*fn)(WikiLine& spp, WikiLineScanner& scanner, WikiFormat* wiki, void* par) = NULL, void* par = NULL);
604     virtual void  pushBlockRaw (uiterator b, uiterator e);
605     virtual void  push_block (boost::ptr_vector<WikiBlock>* b) {
606         bstack.push_back (cur);
607         cur = NULL;
608         pstack.push_back (blockp);
609         blockp = b;
610     };
611     virtual void  pop_block () {
612         if (cur)
613             cur->close ();
614         cur = bstack.back ();
615         bstack.pop_back ();
616         blockp = pstack.back ();
617         pstack.pop_back ();
618     };
619     virtual int  countWikiH (uiterator& b, uiterator e);
620     virtual void  wikiMotor (uiterator b, uiterator e, WikiMotorObjVec& ans);
621     virtual ustring  wikiMotor (uiterator b, uiterator e);
622     virtual void  wikiMotorInline (uiterator b, uiterator e, WikiMotorObjVec& ans);
623     virtual void  outputName (MotorOutput* out, const char* name, size_t len, const ustring& val, bool cond = true);
624     virtual void  outputName (MotorOutput* out, const char* name, size_t len, long val, bool cond = true);
625     virtual void  outputFlag (MotorOutput* out, const char* name, size_t len, bool flag);
626     virtual void  outputID (MotorOutput* out, const ustring& id);
627     virtual void  outputClass (MotorOutput* out, std::vector<ustring>& classes);
628     virtual void  outputSubmitScript (MotorOutput* out, const char* name, size_t len, const ustring& onclick, bool scriptcut);
629     virtual void  outputNum (MotorOutput* out, const char* name, size_t len, int val);
630     virtual MNode*  getVar (const ustring& name) {
631         return mlenv->getVar (name);
632     };
633     virtual ustring  getVar_string (const ustring& name) {
634         return mlenv->getVar_string (name);
635     };
636     virtual ustring  getAry_string (const ustring& name, size_t i) {
637         return mlenv->getAry_string (name, i);
638     };
639     virtual size_t  getArySize (const ustring& name) {
640         return mlenv->getArySize (name);
641     };
642     virtual MNode*  arrayToTexp (const ustring& name);
643     virtual MNode*  evalVar (const ustring& name);
644     virtual MNode*  buildArgs (WikiMotorObjVecVec::const_iterator b, WikiMotorObjVecVec::const_iterator e);
645     virtual void  logLispFunctionError (const ustring& msg, const ustring& cmd);
646 };
647
648 extern ustring  uWiki;
649 extern ustring  uAWiki;
650
651 #endif /* WIKIFORMAT_H */