]>
Commit | Line | Data |
---|---|---|
1 | ///////////////////////////////////////////////////////////////////////////// | |
2 | // Name: No names yet. | |
3 | // Purpose: Contrib. demo | |
4 | // Author: Aleksandras Gluchovas | |
5 | // Modified by: | |
6 | // Created: 22/09/98 | |
7 | // RCS-ID: $Id$ | |
8 | // Copyright: (c) Aleskandars Gluchovas | |
9 | // Licence: wxWindows licence | |
10 | ///////////////////////////////////////////////////////////////////////////// | |
11 | ||
12 | #ifndef __SCRIPTBINDER_G__ | |
13 | #define __SCRIPTBINDER_G__ | |
14 | ||
15 | #if defined( wxUSE_TEMPLATE_STL ) | |
16 | ||
17 | #include <vector> | |
18 | ||
19 | #ifdef WIN32 | |
20 | #include <bstring.h> | |
21 | #else | |
22 | #include <strclass.h> | |
23 | #include <string.h> | |
24 | #endif | |
25 | ||
26 | #else | |
27 | ||
28 | #include "wxstlvec.h" | |
29 | #include "wx/string.h" | |
30 | ||
31 | // FIXME:: dirty! | |
32 | typedef wxString string; | |
33 | ||
34 | #endif | |
35 | ||
36 | #ifndef ASSERT | |
37 | // assert yourself | |
38 | #define ASSERT(x) if (!(x) ) throw; | |
39 | #endif | |
40 | ||
41 | #include "markup.h" | |
42 | ||
43 | // just another portable stream class... | |
44 | ||
45 | class ScriptStream | |
46 | { | |
47 | protected: | |
48 | char* mpBuf; | |
49 | size_t mSize; | |
50 | size_t mCapacity; | |
51 | public: | |
52 | ScriptStream(); | |
53 | ~ScriptStream(); | |
54 | ||
55 | void WriteBytes( const void* srcBuf, size_t count ); | |
56 | ||
57 | ScriptStream& operator<<( const char* str ); | |
58 | ScriptStream& operator<<( const string& str ); | |
59 | ScriptStream& operator<<( char ch ); | |
60 | ||
61 | void endl(); | |
62 | ||
63 | inline char* GetBuf() { return mpBuf; } | |
64 | inline size_t GetBufSize() { return mSize; } | |
65 | ||
66 | // clears current contents of the stream | |
67 | void Reset() { mSize = 0; } | |
68 | }; | |
69 | ||
70 | ||
71 | class ScriptTemplate; | |
72 | ||
73 | // used internally by ScriptTemplate | |
74 | ||
75 | enum TEMPLATE_VARIABLE_TYPES | |
76 | { | |
77 | TVAR_INTEGER, | |
78 | TVAR_STRING, | |
79 | TVAR_DOUBLE, | |
80 | TVAR_REF_ARRAY | |
81 | }; | |
82 | ||
83 | // helper structures used only by ScriptTemplate | |
84 | ||
85 | struct TVarInfo | |
86 | { | |
87 | public: | |
88 | const char* mName; | |
89 | int mType; | |
90 | int mOfs; | |
91 | ||
92 | TVarInfo( const char* name, int ofs, int varType ) | |
93 | : mName(name), | |
94 | mType( varType ), | |
95 | mOfs( ofs ) | |
96 | {} | |
97 | }; | |
98 | ||
99 | struct TArrayInfo : public TVarInfo | |
100 | { | |
101 | public: | |
102 | int mRefOfs; | |
103 | int mSizeIntOfs; | |
104 | int mObjRefTemplOfs; | |
105 | ||
106 | TArrayInfo( const char* name ) | |
107 | : TVarInfo( name, 0, TVAR_REF_ARRAY ) | |
108 | {} | |
109 | }; | |
110 | ||
111 | // stores offset of the given member (of the given class) | |
112 | // to (*pOfs), though the use of template classes would have | |
113 | // solved this problem in much clearer fashion | |
114 | ||
115 | // FOR NOW:: obtaining physical offset of class member | |
116 | // does not appeare to be protable across compilers? | |
117 | // FIXME:: +/- 1 problem | |
118 | ||
119 | #ifdef __UNIX__ | |
120 | #define WEIRD_OFFSET 1 | |
121 | #else | |
122 | #define WEIRD_OFFSET 0 | |
123 | ||
124 | #endif | |
125 | ||
126 | #define GET_VAR_OFS( className, varName, pOfs ) \ | |
127 | { \ | |
128 | int* className::* varPtr; \ | |
129 | varPtr = (int* className::*)&className::varName; \ | |
130 | \ | |
131 | (*pOfs) = int(*(int*)&varPtr)-WEIRD_OFFSET; \ | |
132 | } | |
133 | ||
134 | class ScriptSection; | |
135 | ||
136 | #if defined( wxUSE_TEMPLATE_STL ) | |
137 | ||
138 | typedef vector<TVarInfo*> TVarListT; | |
139 | ||
140 | // container class for sections | |
141 | typedef vector<ScriptSection*> SectListT; | |
142 | ||
143 | #else | |
144 | ||
145 | typedef TVarInfo* TVarInfoPtrT; | |
146 | typedef ScriptSection* ScriptSectionPtrT; | |
147 | ||
148 | typedef WXSTL_VECTOR_SHALLOW_COPY(TVarInfoPtrT) TVarListT; | |
149 | ||
150 | // container class for sections | |
151 | typedef WXSTL_VECTOR_SHALLOW_COPY(ScriptSectionPtrT) SectListT; | |
152 | ||
153 | #endif | |
154 | ||
155 | // class performs preprocessing of arbitrary scripts, | |
156 | // replaces identifiers enclosed in $(..) tag, whith | |
157 | // values of the corresponding class member variables | |
158 | ||
159 | class ScriptTemplate | |
160 | { | |
161 | protected: | |
162 | // do not use string object here - parsing of | |
163 | // C string can be much faster (in debug v.) | |
164 | char* mTText; | |
165 | ||
166 | ||
167 | TVarListT mVars; | |
168 | ||
169 | inline void PrintVar( TVarInfo* pInfo, | |
170 | void* dataObj, | |
171 | ScriptStream& stm ); | |
172 | ||
173 | public: | |
174 | ScriptTemplate( const string& templateText ); | |
175 | virtual ~ScriptTemplate(); | |
176 | ||
177 | bool HasVar( const char* name ); | |
178 | ||
179 | // Member variables registration methods. | |
180 | ||
181 | // NOTE:: GET_VAR_OFS() macro should be used | |
182 | // to get offset of the class member (see #define above) | |
183 | void AddStringVar ( const char* name, int ofs ); | |
184 | void AddIntegerVar( const char* name, int ofs ); | |
185 | void AddDoubleVar ( const char* name, int ofs ); | |
186 | ||
187 | void AddObjectRefArray( const char* name, | |
188 | int ofsRefToFirstObj, | |
189 | int ofsObjSizeInt, | |
190 | int ofsObjRefTempl | |
191 | ); | |
192 | ||
193 | // reads the script, replaces $(..) tags with values | |
194 | // of registered members of dataObj object, and outputs | |
195 | // the result to given text stream | |
196 | ||
197 | void PrintScript( void* dataObj, ScriptStream& stm ); | |
198 | }; | |
199 | ||
200 | class ScriptSection; | |
201 | ||
202 | // class manages section and aggregated sections of | |
203 | // inter-linked documents | |
204 | ||
205 | class ScriptSection | |
206 | { | |
207 | protected: | |
208 | ||
209 | // NOTE:: "$(NAME)", $(ID), "$(BODY)" and "$(REFLIST)" aree | |
210 | // reseved template variables of ScriptSection | |
211 | ||
212 | // the below there members are registered to ScriptTemplate, | |
213 | // GUID within the section tree (numeric) | |
214 | ||
215 | ScriptSection* mpParent; | |
216 | string mId; // $(ID) | |
217 | string mName; // $(NAME) | |
218 | string mBody; // $(BODY) | |
219 | ||
220 | // NULL, if this section is not aggregated anywhere | |
221 | ||
222 | SectListT mSubsections; // aggregated sectons | |
223 | SectListT mReferences; // registered as $(REFLIST) | |
224 | ||
225 | bool mAutoHide; // see autoHide arg, in constructor | |
226 | bool mSortOn; // TRUE, if sort subsectons by naem | |
227 | ||
228 | // tempalte for this section | |
229 | ScriptTemplate* mpSectTempl; | |
230 | ||
231 | // template used for links (or references) to this section | |
232 | ScriptTemplate* mpRefTempl; | |
233 | ||
234 | // do not call destructor of this object, | |
235 | // call RemoveRef() instead | |
236 | int mRefCount; | |
237 | ||
238 | static int mIdCounter; // generator of GUIDs | |
239 | ||
240 | // fields registered and used by ScriptTemplate object | |
241 | void* mRefFirst; | |
242 | int mArrSize; | |
243 | ||
244 | protected: | |
245 | virtual void AddRef(); | |
246 | virtual void RemoveRef(); | |
247 | void DoRemoveEmptySections(int& nRemoved, SectListT& removedLst); | |
248 | void DoRemoveDeadLinks( SectListT& removedLst); | |
249 | ||
250 | public: | |
251 | ||
252 | // NOTE:: pass NULL to certain template, if your sure | |
253 | // this kind of template will never be used, | |
254 | // e.g. if section is contained but never referrenced, | |
255 | // then pReferenceTemplate can be NULL | |
256 | ||
257 | // if autoHide option is TRUE, the section will be automatically | |
258 | // collapsed (not shown) if it doesn't contain any references | |
259 | // to other sections (e.g. could be usefull for autoamically | |
260 | // hiding empty index-sections). | |
261 | ||
262 | ScriptSection( const string& name = "", | |
263 | const string& body = "", | |
264 | ScriptTemplate* pSectionTemplate = NULL, | |
265 | ScriptTemplate* pReferenceTemplate = NULL, | |
266 | bool autoHide = FALSE, | |
267 | bool sorted = FALSE | |
268 | ); | |
269 | ||
270 | // calls RemoveRef() to all aggreagated sections first, | |
271 | // then to all referenced section - this way all | |
272 | // sections (even not aggregated ones) become "garbage-collected" | |
273 | ||
274 | // NOTE:: do not call destructor directlly, call RemoveRef() | |
275 | // instead | |
276 | virtual ~ScriptSection(); | |
277 | ||
278 | ||
279 | // if addToReferencesToo is TRUE, section is aggregated and | |
280 | // also added to reference list of this section | |
281 | ||
282 | void AddSection( ScriptSection* pSection, bool addToReferencesToo = FALSE ); | |
283 | ||
284 | // add cross-reference to this given section | |
285 | void AddReference( ScriptSection* pReferredSection ); | |
286 | ||
287 | // subsection may be given of variable depth level, | |
288 | // e.g. "publications/reviews/software" | |
289 | ||
290 | ScriptSection* GetSubsection( const char* name ); | |
291 | ||
292 | // returns list aggregated sections | |
293 | SectListT& GetSubsections(); | |
294 | ||
295 | // binds reserved template names ( $(..) ) to member | |
296 | // vairalbes in the ScriptSection class, should be called | |
297 | // to initialize each user-code provided script template | |
298 | ||
299 | static void RegisterTemplate( ScriptTemplate& sectionTempalte ); | |
300 | ||
301 | // prints out section tree to the stream, starting from | |
302 | // this section as a root node | |
303 | virtual void Print( ScriptStream& stm ); | |
304 | ||
305 | // searches empty sections which has autoHide == TRUE, | |
306 | // and colapses them (this method should be called ) | |
307 | // on the root-section of the sections tree | |
308 | ||
309 | // NOTE:: does not work properly, yet! | |
310 | void RemoveEmptySections(); | |
311 | }; | |
312 | ||
313 | // base class for documnetation generators | |
314 | // (allows user code set up target script type, | |
315 | // independently of documentation type) | |
316 | ||
317 | class DocGeneratorBase | |
318 | { | |
319 | protected: | |
320 | MarkupTagsT mTags; | |
321 | ||
322 | // override this method to do some post processing | |
323 | // after generation of document, or even write some | |
324 | // data into output stream, before the section tree | |
325 | // is flushed into it. | |
326 | ||
327 | // return FALSE, if something has gone wrong and | |
328 | // document cannot be saved now | |
329 | ||
330 | virtual bool OnSaveDocument( ScriptStream& stm ) | |
331 | { return 1; } | |
332 | ||
333 | // override this method to provide reference to | |
334 | // the top section of the document (used as default | |
335 | // starting section when saving a document) | |
336 | ||
337 | virtual ScriptSection* GetTopSection() | |
338 | { return 0; } | |
339 | ||
340 | public: | |
341 | ||
342 | DocGeneratorBase() | |
343 | : mTags(0) // no defaul script | |
344 | {} | |
345 | ||
346 | // dectrouctors of polymorphic classes SHOULD be virtual | |
347 | virtual ~DocGeneratorBase() {} | |
348 | ||
349 | // returns tags, being used for specific target script | |
350 | MarkupTagsT GetScriptMarkupTags() { return mTags; } | |
351 | ||
352 | // sets tag array for specific script | |
353 | ||
354 | // NOTE:: Why virtual? since approach with MarkupTagsT is | |
355 | // "flowless" only in theory. Overriding this method | |
356 | // allows document generators to check the type of the | |
357 | // target script, and perhaps make some modifications | |
358 | // to generator's tamplates, to match the specific script | |
359 | ||
360 | virtual void SetScriptMarkupTags( MarkupTagsT tags ) | |
361 | { mTags = tags; } | |
362 | ||
363 | // seves document to file starting from the root-node of | |
364 | // the document (provided by GetTopSection() method), | |
365 | // or from "pFromSection" if it's not NULL. | |
366 | ||
367 | // fopenOptions arg. is string passed to fopen() method, | |
368 | // returns TRUE, if saving was successfull | |
369 | ||
370 | virtual bool SaveDocument( const char* fname, | |
371 | const char* fopenOptions = "w", | |
372 | ScriptSection* pFromSection = NULL | |
373 | ); | |
374 | ||
375 | }; | |
376 | ||
377 | #endif |