source: trunk/gsdl/src/recpt/documentaction.cpp@ 281

Last change on this file since 281 was 281, checked in by sjboddie, 25 years ago

tidied a few things up. documentaction::define_external_macros now
resets the "c" arg if it's set to something stupid by the .xx suffixes

  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 23.8 KB
Line 
1/**********************************************************************
2 *
3 * documentaction.cpp --
4 * Copyright (C) 1999 The New Zealand Digital Library Project
5 *
6 * PUT COPYRIGHT NOTICE HERE
7 *
8 * $Id: documentaction.cpp 281 1999-06-16 23:53:15Z sjboddie $
9 *
10 *********************************************************************/
11
12/*
13 $Log$
14 Revision 1.6 1999/06/16 23:53:15 sjboddie
15 tidied a few things up. documentaction::define_external_macros now
16 resets the "c" arg if it's set to something stupid by the .xx suffixes
17
18 Revision 1.5 1999/06/16 03:10:49 sjboddie
19 define_internal_macros() now sets _pagetitle_ macro to document's title
20 (including parents of current document)
21
22 Revision 1.4 1999/06/15 01:55:29 sjboddie
23 - got text highlighting working
24 - got multiple collections working (now outputs error message if an
25 attempt is made to get a document when the "c" arg isn't set.
26
27 Revision 1.3 1999/06/08 04:29:37 sjboddie
28 added argsinfo to the call to check_cgiargs to make it easy to set
29 args to their default if they're found to be screwed up
30
31 Revision 1.2 1999/05/10 03:40:35 sjboddie
32 lots of changes - slowly getting document action sorted out
33
34 Revision 1.1 1999/04/30 01:59:40 sjboddie
35 lots of stuff - getting documentaction working (documentaction replaces
36 old browseaction)
37
38 Revision 1.2 1999/03/29 02:14:27 sjboddie
39
40 More changes to browseaction
41
42 Revision 1.1 1999/03/25 03:09:40 sjboddie
43
44 subjectbrowseaction became browseaction
45
46
47 */
48
49
50#include "documentaction.h"
51#include "browsetools.h"
52#include "OIDtools.h"
53#include "querytools.h"
54#include "unitool.h"
55
56documentaction::documentaction () {
57 // this action uses cgi variables "a", "d", "cl",
58 // "x", "gc", "gt", "gp", and "hl"
59 cgiarginfo arg_ainfo;
60 arg_ainfo.shortname = "a";
61 arg_ainfo.longname = "action";
62 arg_ainfo.multiplechar = true;
63 arg_ainfo.defaultstatus = cgiarginfo::weak;
64 arg_ainfo.argdefault = "p";
65 arg_ainfo.savedarginfo = cgiarginfo::must;
66 argsinfo.addarginfo (NULL, arg_ainfo);
67
68 arg_ainfo.shortname = "d";
69 arg_ainfo.longname = "document OID";
70 arg_ainfo.multiplechar = true;
71 arg_ainfo.defaultstatus = cgiarginfo::none;
72 arg_ainfo.argdefault = "";
73 arg_ainfo.savedarginfo = cgiarginfo::can;
74 argsinfo.addarginfo (NULL, arg_ainfo);
75
76 arg_ainfo.shortname = "cl";
77 arg_ainfo.longname = "classification OID";
78 arg_ainfo.multiplechar = true;
79 arg_ainfo.defaultstatus = cgiarginfo::none;
80 arg_ainfo.argdefault = "";
81 arg_ainfo.savedarginfo = cgiarginfo::can;
82 argsinfo.addarginfo (NULL, arg_ainfo);
83
84 // in this action "gc" controls the expand/contract
85 // contents function
86 arg_ainfo.shortname = "gc";
87 arg_ainfo.longname = "expand contents";
88 arg_ainfo.multiplechar = false;
89 arg_ainfo.defaultstatus = cgiarginfo::weak;
90 arg_ainfo.argdefault = "0";
91 arg_ainfo.savedarginfo = cgiarginfo::can;
92 argsinfo.addarginfo (NULL, arg_ainfo);
93
94 // in this action "gt" controls the expand/contract
95 // text function 0 = not expanded, 1 = expand unless
96 // there are more than 10 sections containing text,
97 // 2 = expand all
98 arg_ainfo.shortname = "gt";
99 arg_ainfo.longname = "expand text";
100 arg_ainfo.multiplechar = false;
101 arg_ainfo.defaultstatus = cgiarginfo::weak;
102 arg_ainfo.argdefault = "0";
103 arg_ainfo.savedarginfo = cgiarginfo::can;
104 argsinfo.addarginfo (NULL, arg_ainfo);
105
106 // in this action "gp" is the "go to page" control
107 // used by the Book type of toc
108 arg_ainfo.shortname = "gp";
109 arg_ainfo.longname = "go to page";
110 arg_ainfo.multiplechar = true;
111 arg_ainfo.defaultstatus = cgiarginfo::none;
112 arg_ainfo.argdefault = "";
113 arg_ainfo.savedarginfo = cgiarginfo::mustnot;
114 argsinfo.addarginfo (NULL, arg_ainfo);
115
116 // in this action "hl" is the "highlighting on/
117 // highlighting off control
118 arg_ainfo.shortname = "hl";
119 arg_ainfo.longname = "highlighting on/off";
120 arg_ainfo.multiplechar = false;
121 arg_ainfo.defaultstatus = cgiarginfo::weak;
122 arg_ainfo.argdefault = "1";
123 arg_ainfo.savedarginfo = cgiarginfo::must;
124 argsinfo.addarginfo (NULL, arg_ainfo);
125
126 // "x" is 0 normally or 1 if page
127 // has been "detached"
128 arg_ainfo.shortname = "x";
129 arg_ainfo.longname = "detached page";
130 arg_ainfo.multiplechar = false;
131 arg_ainfo.defaultstatus = cgiarginfo::weak;
132 arg_ainfo.argdefault = "0";
133 arg_ainfo.savedarginfo = cgiarginfo::can;
134 argsinfo.addarginfo (NULL, arg_ainfo);
135}
136
137documentaction::~documentaction () {
138}
139
140bool documentaction::init (ostream &logout) {
141 return action::init (logout);
142}
143
144bool documentaction::check_cgiargs (cgiargsinfoclass &/*argsinfo*/, cgiargsclass &/*args*/,
145 ostream &/*logout*/) {
146 // don't want to check anything yet.
147 return true;
148}
149
150void documentaction::get_cgihead_info (cgiargsclass &/*args*/, response_t &response,
151 text_t &response_data, ostream &/*logout*/) {
152 response = content;
153 response_data = "text/html";
154}
155
156
157// define all the macros which might be used by other actions
158// to produce pages.
159void documentaction::define_external_macros (displayclass &disp, cgiargsclass &args,
160 recptproto *collectproto, ostream &logout) {
161
162 // define_external_macros sets the following macros:
163
164 // _navigationbar_ this is the navigation bar containing the search button
165 // and any classification buttons - it goes at the top of
166 // most pages. for now we're assuming that there'll always
167 // be a search button - we should probably check that there
168 // is a query action before making this assumption
169
170 // _httpbrowseXXX_ the http macros for each classification (i.e. if there
171 // are Title and Creator classifications _httpbrowseTitle_
172 // and _httpbrowseCreator_ will be set
173
174 // _javaimagesnavbar_ this is the javascript code to shove in to make the
175 // flashy images used by _navigationbar_ work
176
177 // _cgiargd_ these are overridden if they use the tricky ".xx" syntax
178 // _cgiargcl_
179
180 // can't do anything if collectproto is null (i.e. no collection was specified)
181 if (collectproto == NULL) return;
182
183 outconvertclass text_t2ascii;
184 comerror_t err;
185 InfoFiltersResponse_t filterinfo;
186 FilterResponse_t response;
187 FilterRequest_t request;
188 text_tarray metadata;
189 text_t navigationbar, javaimagesnavbar, width, topparent;
190 int twidth, swidth, iwidth = 0;
191
192 text_t &arg_d = args["d"];
193 text_t &arg_cl = args["cl"];
194 text_t &collection = args["c"];
195
196 // if the "gp" (go to page) argument is set we need to set
197 // the "d" argument to the corresponding page
198 if ((!arg_d.empty()) && (!args["gp"].empty()) &&
199 (is_number (args["gp"]))) {
200 text_t top;
201 get_top (arg_d, top);
202 metadata.push_back ("Title");
203 get_children (top, collection, metadata, collectproto, response, logout);
204 ResultDocInfo_tarray::const_iterator dochere = response.docInfo.begin();
205 ResultDocInfo_tarray::const_iterator docend = response.docInfo.end();
206 while (dochere != docend) {
207 if ((*dochere).metadata[0].values[0] == args["gp"]) {
208 arg_d = (*dochere).OID;
209 disp.setmacro ("cgiargd", "Global", arg_d);
210 break;
211 }
212 dochere ++;
213 }
214 metadata.erase (metadata.begin(), metadata.end());
215 }
216
217 // do a call to translate OIDs if required
218 request.filterName = "NullFilter";
219 request.filterResultOptions = FROID;
220 if (needs_translating (arg_d)) {
221 request.docSet.insert (arg_d);
222 collectproto->filter (collection, request, response, err, logout);
223 arg_d = response.docInfo[0].OID;
224 request.docSet.erase (request.docSet.begin(), request.docSet.end());
225 disp.setmacro ("cgiargd", "Global", arg_d);
226 }
227 // we'll also check here that the "cl" argument has a "classify" doctype
228 // (in case ".fc" or ".lc" have screwed up)
229 if (needs_translating (arg_cl)) {
230 request.fields.push_back("doctype");
231 request.docSet.insert (arg_cl);
232 request.filterResultOptions = FRmetadata;
233 collectproto->filter (collection, request, response, err, logout);
234 // set to original value (without .xx stuff) if doctype isn't "classify"
235 if (response.docInfo[0].metadata[0].values[0] != "classify")
236 strip_suffix (arg_cl);
237 else
238 arg_cl = response.docInfo[0].OID;
239 disp.setmacro ("cgiargcl", "Global", arg_cl);
240 }
241
242 get_top (arg_cl, topparent);
243
244 collectproto->get_filterinfo (collection, filterinfo, err, logout);
245 if (err == noError) {
246 // check that there's a browse filter
247 if (filterinfo.filterNames.find ("BrowseFilter") != filterinfo.filterNames.end()) {
248
249 metadata.push_back ("Title");
250 metadata.push_back ("classifytype");
251 get_children ("", collection, metadata, collectproto, response, logout);
252
253 // don't do anything unless there are classifications
254 if (!response.docInfo.empty()) {
255
256 ResultDocInfo_tarray::const_iterator dochere = response.docInfo.begin();
257 ResultDocInfo_tarray::const_iterator docend = response.docInfo.end();
258
259 navigationbar = "<!-- Navigation Bar -->\n";
260
261 // calculate width of spacers and set macro
262 if (args.getintarg("v") == 0) {
263 disp.expandstring ("Global", "_pagewidth_", width);
264 twidth = width.getint();
265
266 disp.expandstring ("query", "_searchwidth_", width);
267 iwidth += width.getint();
268
269 while (dochere != docend) {
270 disp.expandstring ("document", "_" + (*dochere).metadata[0].values[0] + "width_", width);
271 iwidth += width.getint();
272 dochere ++;
273 }
274 if ((twidth - iwidth) < int(response.docInfo.size())) swidth = 2;
275 else swidth = (twidth - iwidth) / response.docInfo.size();
276 disp.setmacro ("widthtspace", "Global", swidth);
277 }
278
279 navigationbar += "<nobr>\n";
280 if (args["a"] == "q") {
281 navigationbar += "_icontabsearchgreen_";
282 } else {
283 navigationbar += "_imagesearch_";
284 javaimagesnavbar = "_javasearch_";
285 }
286 dochere = response.docInfo.begin();
287 while (dochere != docend) {
288 const text_t &title = (*dochere).metadata[0].values[0];
289 const text_t &classifytype = (*dochere).metadata[1].values[0];
290
291 // if we're inside a document all the classification buttons should be enabled
292 if (arg_d.empty() && ((*dochere).OID == topparent))
293 navigationbar += "_imagespacer__icontab" + title + "green_";
294 else {
295 navigationbar += "_imagespacer__image" + title + "_";
296
297 // set the _httpbrowseXXX_ macro for this classification
298 text_t link = (*dochere).OID;
299 if (classifytype == "AZList" || classifytype == "Datelist") link += ".fc";
300 disp.setmacro ("httpbrowse" + title, "Global",
301 "_httpdocument_&cl=" + link);
302 }
303 javaimagesnavbar += "_java" + title + "_";
304 dochere ++;
305 }
306 navigationbar += "\n</nobr>\n";
307 navigationbar += "<!-- End of Navigation Bar -->\n";
308 disp.setmacro ("navigationbar", "Global", navigationbar);
309 if (args.getintarg("v") == 0)
310 disp.setmacro ("javaimagesnavbar", "Global", javaimagesnavbar);
311 }
312 }
313 } else {
314 logout << text_t2ascii
315 << "Error (documentaction::define_external_macros()) in call to get_filterinfo() "
316 << get_comerror_string (err);
317 }
318}
319
320
321// define all the macros which are related to pages generated
322// by this action
323void documentaction::define_internal_macros (displayclass &disp, cgiargsclass &args,
324 recptproto *collectproto, ostream &logout) {
325
326 // define_internal_macros sets the following macros:
327
328 // _pagetitle_ the title to be displayed at the top of the browser window
329
330 // _imagethispage_ the title image to be displayed at top right of page
331
332 // _classificationlinks_ the links between classifications to be displayed
333 // at top of list or datelist classifications
334
335 // _httpprevarrow_ these are set if next or previous arrows
336 // _httpnextarrow_ are to be used - (i.e. if it's an AZList or a Datelist
337 // classifytype at a top level or if it's a Book or a
338 // Hierarchy classifytype at document level
339
340 // _header_ the header macro is overridden if we're not at a top level
341 // classification to remove the title block
342
343 // _javaimagescontent_ this is the javascript code to shove in to make the
344 // flashy buttons work
345
346 // can't do anything if collectproto is null (i.e. no collection was specified)
347 if (collectproto == NULL) return;
348
349
350 text_tarray metadata;
351 FilterResponse_t response;
352 text_t &arg_d = args["d"];
353 text_t &arg_cl = args["cl"];
354 text_t &collection = args["c"];
355
356 metadata.push_back ("Title");
357 metadata.push_back ("classifytype");
358
359 if (!arg_d.empty()) {
360 // we're at document level
361 text_t javaimagescontent;
362
363 // get metadata for this document and it's parents
364 if (get_info (arg_d, collection, metadata, true, collectproto, response, logout)) {
365 disp.setmacro ("header", "document", "_textheader_");
366
367 text_t pagetitle;
368 text_tarray::const_iterator this_title = response.docInfo[0].metadata[0].values.begin();
369 text_tarray::const_iterator end_title = response.docInfo[0].metadata[0].values.end();
370 while (this_title != end_title) {
371 if ((this_title + 1) == end_title) pagetitle += *this_title;
372 else pagetitle += *this_title + ": ";
373 this_title ++;
374 }
375 disp.setmacro ("pagetitle", "document", pagetitle);
376
377 text_t &classifytype = response.docInfo[0].metadata[1].values[0];
378 if (classifytype.empty()) classifytype = "Book"; // defaults to Book
379 if ((classifytype == "Book") || (classifytype == "Hierarchy"))
380 set_arrow_macros (arg_d, classifytype, disp, collectproto, collection, logout);
381
382 if (args["u"] != "1") {
383 javaimagescontent += "_javadetach_";
384 if (args["gt"] == "1")
385 javaimagescontent += "_javacontracttext__javacontinue_";
386 else
387 javaimagescontent += "_javaexpandtext_";
388 if (classifytype == "Hierarchy")
389 if (args["gc"] == "1")
390 javaimagescontent += "_javacontractcontents_";
391 else
392 javaimagescontent += "_javaexpandcontents_";
393 if (args["hl"] != "1")
394 javaimagescontent += "_javahighlighting_";
395 else
396 javaimagescontent += "_javanohighlighting_";
397 disp.setmacro ("javaimagescontent", "document", javaimagescontent);
398 }
399 }
400 } else {
401 if (!arg_cl.empty()) {
402
403 // get metadata for top level classification
404 text_t classtop;
405 get_top (arg_cl, classtop);
406 if (get_info (classtop, collection, metadata, false, collectproto, response, logout)) {
407
408 text_t &title = response.docInfo[0].metadata[0].values[0];
409 text_t &classifytype = response.docInfo[0].metadata[1].values[0];
410
411 disp.setmacro ("imagethispage", "document",
412 "_icon" + title + "page_");
413
414 // now get the metadata for each child of top level
415 // so we can generate the _classificationlinks_ and arrow macros
416 // (if they're required by the current classification type)
417
418 if ((classifytype == "AZList") || (classifytype == "Datelist")) {
419
420 text_t classificationlinks, navarrows;
421 text_t link = "<a href=\"_httpdocument_&cl=";
422
423 metadata.erase(metadata.begin(), metadata.end());
424 metadata.push_back ("Title");
425 metadata.push_back ("doctype");
426 if (get_children (classtop, collection, metadata, collectproto, response, logout)) {
427
428 // don't want links unless there are 2 or more sections
429 if (response.docInfo.size() >= 2) {
430
431 classificationlinks += "<!-- Classification Links -->\n";
432 classificationlinks += "<table width=_pagewidth_ cellpadding=0 cellspacing=0 border=0>\n";
433 classificationlinks += "<tr><td valign=top><center>\n";
434
435 ResultDocInfo_tarray::const_iterator sechere = response.docInfo.begin();
436 ResultDocInfo_tarray::const_iterator secend = response.docInfo.end();
437
438 while (sechere != secend) {
439 if ((*sechere).metadata[1].values[0] == "classify") {
440 if ((*sechere).OID == arg_cl) {
441
442 // set the _httpprevarrow_, _httpnextarrow_ macros while we're here
443 if (sechere != response.docInfo.begin())
444 disp.setmacro ("httpprevarrow", "document", "_httpdocument_&cl=" + (*(sechere-1)).OID);
445 if ((sechere + 1) != secend)
446 disp.setmacro ("httpnextarrow", "document", "_httpdocument_&cl=" + (*(sechere+1)).OID);
447
448 classificationlinks += "\n<b>" + (*sechere).metadata[0].values[0] + "</b>&nbsp;&nbsp;&nbsp;";
449 } else {
450 classificationlinks += link + (*sechere).OID + "\">";
451 classificationlinks += (*sechere).metadata[0].values[0] + "</a>";
452 if ((sechere + 1) != secend) classificationlinks += "&nbsp;&nbsp;&nbsp;";
453 }
454 }
455 sechere ++;
456 }
457
458 classificationlinks += "\n</center></td></tr></table>\n";
459 classificationlinks += "<!-- End of Classification Links -->\n";
460
461 disp.setmacro ("classificationlinks", "document", classificationlinks);
462 }
463 }
464 }
465 }
466 }
467 }
468}
469
470bool documentaction::do_action (cgiargsclass &args, recptproto *collectproto,
471 displayclass &disp, outconvertclass &outconvert,
472 ostream &textout, ostream &logout) {
473
474 if (collectproto == NULL) {
475 logout << "documentaction::do_action called with NULL collectproto\n";
476 textout << outconvert << disp << "_document:header_\n"
477 << "Error: Attempt to get document without setting collection\n"
478 << "_document:footer_\n";
479 } else {
480
481 text_tarray metadata;
482 FilterResponse_t response;
483 FilterResponse_t queryresponse;
484 DocumentRequest_t docrequest;
485 DocumentResponse_t docresponse;
486 text_t topparent, classifytype, classifytitle;
487 comerror_t err;
488 bool highlight = false;
489
490 text_t &arg_d = args["d"];
491 text_t &arg_cl = args["cl"];
492 text_t &collection = args["c"];
493
494 text_t OID = arg_d;
495 if (arg_d.empty()) OID = arg_cl;
496
497 textout << outconvert << disp << "_document:header_\n"
498 << "_document:content_\n";
499
500 if (arg_d.empty() && arg_cl.empty()) {
501 textout << outconvert << disp << "Document contains no data_document:footer_\n";
502 return true;
503 }
504
505 // if we have a query string and highlighting is turned on we need
506 // to redo the query to get the terms for highlighting
507 if (!args["q"].empty() && args.getintarg("hl")) {
508 FilterRequest_t request;
509 text_t quotedstring; // don't use this here
510 request.filterResultOptions = FRmatchTerms;
511 if (do_query (request, args, collectproto, quotedstring, queryresponse, logout))
512 highlight = true;
513 }
514
515 // get the classifytitle and classifytype
516 get_top (OID, topparent);
517 metadata.push_back ("Title");
518 metadata.push_back ("classifytype");
519 if (get_info (topparent, collection, metadata, false, collectproto, response, logout)) {
520 classifytitle = response.docInfo[0].metadata[0].values[0];
521 classifytype = response.docInfo[0].metadata[1].values[0];
522 }
523
524 if (!arg_d.empty()) {
525
526 if (classifytype == "Hierarchy")
527 output_hierarchy_toc (classifytitle, args, collectproto, disp,
528 outconvert, textout, logout);
529 else
530 // Book is the default for a document level toc - AZList and Datelist don't
531 // make sense for document level
532 output_book_toc (classifytitle, args, collectproto, disp,
533 outconvert, textout, logout);
534 } else {
535
536 if (classifytype == "Hierarchy")
537 output_hierarchy_toc (classifytitle, args, collectproto, disp,
538 outconvert, textout, logout);
539 else if (classifytype == "Datelist")
540 output_datelist_toc (classifytitle, args, collectproto, disp,
541 outconvert, textout, logout);
542 else
543 // AZList is the default for a classification level toc - Book doesn't make
544 // sense for classification level
545 output_azlist_toc (classifytitle, args, collectproto, disp,
546 outconvert, textout, logout);
547 }
548
549 // get info on this document
550 metadata.erase (metadata.begin(), metadata.end());
551 metadata.push_back("Title");
552 metadata.push_back("hastxt");
553 metadata.push_back("haschildren");
554
555 if (get_info (OID, collection, metadata, false, collectproto, response, logout)) {
556 text_t &title = response.docInfo[0].metadata[0].values[0];
557 int hastxt = response.docInfo[0].metadata[1].values[0].getint();
558 int haschildren = response.docInfo[0].metadata[2].values[0].getint();
559
560 int gt = args.getintarg("gt");
561 if (gt == 0) {
562 if (hastxt == 1) {
563 // get the text
564 docrequest.OID = OID;
565 collectproto->get_document (collection, docrequest, docresponse, err, logout);
566
567 textout << outconvert << disp << "<p>\n<h3>" << title << "</h3>";
568 if (highlight)
569 highlighttext(docresponse.doc, queryresponse.termInfo, disp,
570 outconvert, textout, logout);
571 else
572 textout << outconvert << disp << docresponse.doc;
573 }
574 } else {
575
576 // text is to be expanded
577 int tmp; // this doesn't get used here
578 if (!haschildren)
579 OID = get_parent (OID);
580
581 get_contents (OID, classifytype, tmp, collection, collectproto, response, logout);
582
583 ResultDocInfo_tarray::const_iterator sechere = response.docInfo.begin();
584 ResultDocInfo_tarray::const_iterator secend = response.docInfo.end();
585
586 if (gt == 1) {
587 // check if there are more than 10 sections containing text to be expanded -
588 // if there are output warning message - this isn't a great way to do this
589 // since the sections may be very large or very small - one day I'll fix it
590 // -- Stefan.
591 int seccount = 0;
592 while (sechere != secend) {
593 if ((*sechere).metadata[3].values[0] == "1") seccount ++;
594 if (seccount > 10) break;
595 sechere ++;
596 }
597 if (seccount > 10) textout << outconvert << disp << "_document:textltwarning_";
598 else gt = 2;
599 }
600
601 if (gt == 2) {
602 // get the text for each section
603 sechere = response.docInfo.begin();
604 int count = 0;
605 while (sechere != secend) {
606 textout << outconvert << disp << "\n<p><a name=" << count << "><h3>"
607 << (*sechere).metadata[0].values[0] << "</h3></a>\n";
608 if ((*sechere).metadata[3].values[0] == "1") {
609 docrequest.OID = (*sechere).OID;
610 collectproto->get_document (collection, docrequest, docresponse, err, logout);
611 if (highlight)
612 highlighttext(docresponse.doc, queryresponse.termInfo, disp,
613 outconvert, textout, logout);
614 else
615 textout << outconvert << disp << docresponse.doc;
616 }
617 count ++;
618 sechere ++;
619 }
620 }
621 }
622 }
623 textout << outconvert << disp << "_document:footer_\n";
624 }
625 return true;
626}
627
628
629// highlighttext highlights query terms in text string and outputs the resulting text string
630void documentaction::highlighttext(text_t &text, TermInfo_tarray &terms, displayclass &disp,
631 outconvertclass &outconvert, ostream &textout, ostream &/*logout*/) {
632
633 text_tmap allterms;
634 text_tmap::const_iterator it;
635
636 // first load all the term variations into a map
637 TermInfo_tarray::const_iterator this_term = terms.begin();
638 TermInfo_tarray::const_iterator last_term = terms.end();
639 while (this_term != last_term) {
640 text_tarray::const_iterator this_var = (*this_term).matchTerms.begin();
641 text_tarray::const_iterator last_var = (*this_term).matchTerms.end();
642 while (this_var != last_var) {
643 allterms[*this_var] = 1;
644 this_var ++;
645 }
646 this_term ++;
647 }
648
649 // get the text to start and end a hightlight
650 text_t starthighlight = "<b><u>";
651 text_t endhighlight = "</u></b>";
652 if (disp.isdefaultmacro("Global", "starthighlight"))
653 disp.expandstring("Global", "_starthighlight_", starthighlight);
654 if (disp.isdefaultmacro("Global", "endhighlight"))
655 disp.expandstring("Global", "_endhighlight_", endhighlight);
656
657
658 text_t::iterator here = text.begin();
659 text_t::iterator end = text.end();
660 text_t word, buffer;
661 while (here != end) {
662 if (is_unicode_letdig(*here)) {
663 // not word boundary
664 word.push_back(*here);
665 here++;
666
667 } else {
668 // found word boundary
669 // add last word if there was one
670 if (!word.empty()) {
671 it = allterms.find(word);
672 if (it != allterms.end()) {
673 word = starthighlight + word + endhighlight;
674 }
675 buffer += word;
676 word.clear();
677 }
678
679 if (*here == '<') {
680 // skip over rest of html tag
681 while ((here != end) && (*here != '>')) {
682 buffer.push_back(*here);
683 here++;
684 }
685 }
686
687 buffer.push_back(*here);
688 here++;
689
690 if (buffer.size() > 1024) {
691 textout << outconvert << disp << buffer;
692 buffer.clear();
693 }
694 }
695 }
696 textout << outconvert << disp << buffer;
697}
Note: See TracBrowser for help on using the repository browser.