Logo ROOT  
Reference Guide
TGHtmlParse.cxx
Go to the documentation of this file.
1// $Id: TGHtmlParse.cxx,v 1.1 2007/05/04 17:07:01 brun Exp $
2// Author: Valeriy Onuchin 03/05/2007
3
4/*************************************************************************
5 * Copyright (C) 1995-2001, Rene Brun, Fons Rademakers and Reiner Rohlfs *
6 * All rights reserved. *
7 * *
8 * For the licensing terms see $ROOTSYS/LICENSE. *
9 * For the list of contributors see $ROOTSYS/README/CREDITS. *
10 *************************************************************************/
11
12/**************************************************************************
13
14 HTML widget for xclass. Based on tkhtml 1.28
15 Copyright (C) 1997-2000 D. Richard Hipp <drh@acm.org>
16 Copyright (C) 2002-2003 Hector Peraza.
17
18 This library is free software; you can redistribute it and/or
19 modify it under the terms of the GNU Library General Public
20 License as published by the Free Software Foundation; either
21 version 2 of the License, or (at your option) any later version.
22
23 This library is distributed in the hope that it will be useful,
24 but WITHOUT ANY WARRANTY; without even the implied warranty of
25 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
26 Library General Public License for more details.
27
28 You should have received a copy of the GNU Library General Public
29 License along with this library; if not, write to the Free
30 Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
31
32**************************************************************************/
33
34// A tokenizer that converts raw HTML into a linked list of HTML elements.
35
36#include <cstring>
37#include <cstdlib>
38#include <cstdio>
39#include <cctype>
40
41#include "TGHtml.h"
42#include "TGHtmlTokens.h"
43#include "strlcpy.h"
44#include "snprintf.h"
45
46//----------------------------------------------------------------------
47
49
50
51/****************** Begin Escape Sequence Translator *************/
52
53// The next section of code implements routines used to translate
54// the '&' escape sequences of SGML to individual characters.
55// Examples:
56//
57// &amp; &
58// &lt; <
59// &gt; >
60// &nbsp; nonbreakable space
61//
62
63// Each escape sequence is recorded as an instance of the following
64// structure
65
66struct SgEsc_t {
67 const char *fZName; // The name of this escape sequence. ex: "amp"
68 char fValue[8]; // The value for this sequence. ex: "&"
69 SgEsc_t *fPNext; // Next sequence with the same hash on zName
70};
71
72// The following is a table of all escape sequences. Add new sequences
73// by adding entries to this table.
74
75static struct SgEsc_t gEscSequences[] = {
76 { "quot", "\"", 0 },
77 { "amp", "&", 0 },
78 { "lt", "<", 0 },
79 { "gt", ">", 0 },
80 { "nbsp", " ", 0 },
81 { "iexcl", "\241", 0 },
82 { "cent", "\242", 0 },
83 { "pound", "\243", 0 },
84 { "curren", "\244", 0 },
85 { "yen", "\245", 0 },
86 { "brvbar", "\246", 0 },
87 { "sect", "\247", 0 },
88 { "uml", "\250", 0 },
89 { "copy", "\251", 0 },
90 { "ordf", "\252", 0 },
91 { "laquo", "\253", 0 },
92 { "not", "\254", 0 },
93 { "shy", "\255", 0 },
94 { "reg", "\256", 0 },
95 { "macr", "\257", 0 },
96 { "deg", "\260", 0 },
97 { "plusmn", "\261", 0 },
98 { "sup2", "\262", 0 },
99 { "sup3", "\263", 0 },
100 { "acute", "\264", 0 },
101 { "micro", "\265", 0 },
102 { "para", "\266", 0 },
103 { "middot", "\267", 0 },
104 { "cedil", "\270", 0 },
105 { "sup1", "\271", 0 },
106 { "ordm", "\272", 0 },
107 { "raquo", "\273", 0 },
108 { "frac14", "\274", 0 },
109 { "frac12", "\275", 0 },
110 { "frac34", "\276", 0 },
111 { "iquest", "\277", 0 },
112 { "Agrave", "\300", 0 },
113 { "Aacute", "\301", 0 },
114 { "Acirc", "\302", 0 },
115 { "Atilde", "\303", 0 },
116 { "Auml", "\304", 0 },
117 { "Aring", "\305", 0 },
118 { "AElig", "\306", 0 },
119 { "Ccedil", "\307", 0 },
120 { "Egrave", "\310", 0 },
121 { "Eacute", "\311", 0 },
122 { "Ecirc", "\312", 0 },
123 { "Euml", "\313", 0 },
124 { "Igrave", "\314", 0 },
125 { "Iacute", "\315", 0 },
126 { "Icirc", "\316", 0 },
127 { "Iuml", "\317", 0 },
128 { "ETH", "\320", 0 },
129 { "Ntilde", "\321", 0 },
130 { "Ograve", "\322", 0 },
131 { "Oacute", "\323", 0 },
132 { "Ocirc", "\324", 0 },
133 { "Otilde", "\325", 0 },
134 { "Ouml", "\326", 0 },
135 { "times", "\327", 0 },
136 { "Oslash", "\330", 0 },
137 { "Ugrave", "\331", 0 },
138 { "Uacute", "\332", 0 },
139 { "Ucirc", "\333", 0 },
140 { "Uuml", "\334", 0 },
141 { "Yacute", "\335", 0 },
142 { "THORN", "\336", 0 },
143 { "szlig", "\337", 0 },
144 { "agrave", "\340", 0 },
145 { "aacute", "\341", 0 },
146 { "acirc", "\342", 0 },
147 { "atilde", "\343", 0 },
148 { "auml", "\344", 0 },
149 { "aring", "\345", 0 },
150 { "aelig", "\346", 0 },
151 { "ccedil", "\347", 0 },
152 { "egrave", "\350", 0 },
153 { "eacute", "\351", 0 },
154 { "ecirc", "\352", 0 },
155 { "euml", "\353", 0 },
156 { "igrave", "\354", 0 },
157 { "iacute", "\355", 0 },
158 { "icirc", "\356", 0 },
159 { "iuml", "\357", 0 },
160 { "eth", "\360", 0 },
161 { "ntilde", "\361", 0 },
162 { "ograve", "\362", 0 },
163 { "oacute", "\363", 0 },
164 { "ocirc", "\364", 0 },
165 { "otilde", "\365", 0 },
166 { "ouml", "\366", 0 },
167 { "divide", "\367", 0 },
168 { "oslash", "\370", 0 },
169 { "ugrave", "\371", 0 },
170 { "uacute", "\372", 0 },
171 { "ucirc", "\373", 0 },
172 { "uuml", "\374", 0 },
173 { "yacute", "\375", 0 },
174 { "thorn", "\376", 0 },
175 { "yuml", "\377", 0 },
176};
177
178
179// The size of the handler hash table. For best results this should
180// be a prime number which is about the same size as the number of
181// escape sequences known to the system.
182
183#define ESC_HASH_SIZE (sizeof(gEscSequences)/sizeof(gEscSequences[0])+7)
184
185
186// The hash table
187//
188// If the name of an escape sequence hashes to the value H, then
189// gApEscHash[H] will point to a linked list of Esc structures, one of
190// which will be the Esc structure for that escape sequence.
191
193
194
195// Hash a escape sequence name. The value returned is an integer
196// between 0 and ESC_HASH_SIZE-1, inclusive.
197
198static int EscHash(const char *zName) {
199 int h = 0; // The hash value to be returned
200 char c; // The next character in the name being hashed
201
202 while ((c = *zName) != 0) {
203 h = h<<5 ^ h ^ c;
204 zName++;
205 }
206 if (h < 0) h = -h;
207
208 return h % ESC_HASH_SIZE;
209}
210
211#ifdef TEST
212// Compute the longest and average collision chain length for the
213// escape sequence hash table
214
215static void EscHashStats()
216{
217 int i;
218 int sum = 0;
219 int max = 0;
220 int cnt;
221 int notempty = 0;
222 struct SgEsc_t *p;
223
224 for (i = 0; i < sizeof(gEscSequences) / sizeof(gEscSequences[0]); i++) {
225 cnt = 0;
226 p = gApEscHash[i];
227 if (p) notempty++;
228 while (p) {
229 ++cnt;
230 p = p->fPNext;
231 }
232 sum += cnt;
233 if (cnt > max) max = cnt;
234 }
235 printf("Longest chain=%d avg=%g slots=%d empty=%d (%g%%)\n",
236 max, (double)sum/(double)notempty, i, i-notempty,
237 100.0*(i-notempty)/(double)i);
238}
239#endif
240
241// Initialize the escape sequence hash table
242
243static void EscInit() {
244 int i; /* For looping thru the list of escape sequences */
245 int h; /* The hash on a sequence */
246
247 for (i = 0; i < int(sizeof(gEscSequences) / sizeof(gEscSequences[i])); i++) {
248/* #ifdef XCLASS_UTF_MAX */
249#if 0
250 int c = gEscSequences[i].value[0];
251 xclass::UniCharToUtf(c, gEscSequences[i].value);
252 }
253#endif
257 }
258#ifdef TEST
259 EscHashStats();
260#endif
261}
262
263
264// This table translates the non-standard microsoft characters between 0x80
265// and 0x9f into plain ASCII so that the characters will be visible on Unix
266// systems. Care is taken to translate the characters into values less than
267// 0x80, to avoid UTF-8 problems.
268
269static char gAcMsChar[] = {
270 /* 0x80 */ 'C',
271 /* 0x81 */ ' ',
272 /* 0x82 */ ',',
273 /* 0x83 */ 'f',
274 /* 0x84 */ '"',
275 /* 0x85 */ '.',
276 /* 0x86 */ '*',
277 /* 0x87 */ '*',
278 /* 0x88 */ '^',
279 /* 0x89 */ '%',
280 /* 0x8a */ 'S',
281 /* 0x8b */ '<',
282 /* 0x8c */ 'O',
283 /* 0x8d */ ' ',
284 /* 0x8e */ 'Z',
285 /* 0x8f */ ' ',
286 /* 0x90 */ ' ',
287 /* 0x91 */ '\'',
288 /* 0x92 */ '\'',
289 /* 0x93 */ '"',
290 /* 0x94 */ '"',
291 /* 0x95 */ '*',
292 /* 0x96 */ '-',
293 /* 0x97 */ '-',
294 /* 0x98 */ '~',
295 /* 0x99 */ '@',
296 /* 0x9a */ 's',
297 /* 0x9b */ '>',
298 /* 0x9c */ 'o',
299 /* 0x9d */ ' ',
300 /* 0x9e */ 'z',
301 /* 0x9f */ 'Y',
302};
303
304
305////////////////////////////////////////////////////////////////////////////////
306/// Translate escape sequences in the string "z". "z" is overwritten
307/// with the translated sequence.
308///
309/// Unrecognized escape sequences are unaltered.
310///
311/// Example:
312///
313/// input = "AT&amp;T &gt MCI"
314/// output = "AT&T > MCI"
315
317{
318 int from; // Read characters from this position in z[]
319 int to; // Write characters into this position in z[]
320 int h; // A hash on the escape sequence
321 struct SgEsc_t *p; // For looping down the escape sequence collision chain
322 static int isInit = 0; // True after initialization
323
324 from = to = 0;
325 if (!isInit) {
326 EscInit();
327 isInit = 1;
328 }
329 while (z[from]) {
330 if (z[from] == '&') {
331 if (z[from+1] == '#') {
332 int i = from + 2;
333 int v = 0;
334 while (isdigit(z[i])) {
335 v = v*10 + z[i] - '0';
336 i++;
337 }
338 if (z[i] == ';') { i++; }
339
340 // Translate the non-standard microsoft characters in the range of
341 // 0x80 to 0x9f into something we can see.
342
343 if (v >= 0x80 && v < 0xa0) {
344 v = gAcMsChar[v & 0x1f];
345 }
346
347 // Put the character in the output stream in place of the "&#000;".
348 // How we do this depends on whether or not we are using UTF-8.
349
350 z[to++] = v;
351 from = i;
352 } else {
353 int i = from+1;
354 int c;
355 while (z[i] && isalnum(z[i])) ++i;
356 c = z[i];
357 z[i] = 0;
358 h = EscHash(&z[from+1]);
359 p = gApEscHash[h];
360 while (p && strcmp(p->fZName, &z[from+1]) != 0) p = p->fPNext;
361 z[i] = c;
362 if (p) {
363 int j;
364 for (j = 0; p->fValue[j]; ++j) z[to++] = p->fValue[j];
365 from = i;
366 if (c == ';') from++;
367 } else {
368 z[to++] = z[from++];
369 }
370 }
371
372 // Look for the non-standard microsoft characters between 0x80 and 0x9f
373 // and translate them into printable ASCII codes. Separate algorithms
374 // are required to do this for plain ascii and for utf-8.
375
376 } else if (((unsigned char) z[from]) >= 0x80 &&
377 ((unsigned char) z[from]) < 0xa0) {
378 z[to++] = gAcMsChar[z[from++] & 0x1f];
379 } else {
380 z[to++] = z[from++];
381 }
382 }
383 z[to] = 0;
384}
385
386/******************* End Escape Sequence Translator ***************/
387
388/******************* Begin HTML tokenizer code *******************/
389
390// The following variable becomes TRUE when the markup hash table
391// (stored in HtmlMarkupMap[]) is initialized.
392
393static int gIsInit = 0;
394
395// The hash table for HTML markup names.
396//
397// If an HTML markup name hashes to H, then gApMap[H] will point to
398// a linked list of sgMap structure, one of which will describe the
399// the particular markup (if it exists.)
400
402
403// Hash a markup name
404//
405// HTML markup is case insensitive, so this function will give the
406// same hash regardless of the case of the markup name.
407//
408// The value returned is an integer between 0 and HTML_MARKUP_HASH_SIZE-1,
409// inclusive.
410
411static int HtmlHash(const char *zName) {
412 int h = 0;
413 char c;
414
415 while ((c = *zName) != 0) {
416 if (isupper(c)) { // do we have to check for this??????
417 c = tolower(c);
418 }
419 h = h<<5 ^ h ^ c;
420 zName++;
421 }
422 if (h < 0) {
423 h = -h;
424 }
425
426 return h % HTML_MARKUP_HASH_SIZE;
427}
428
429
430#ifdef TEST
431// Compute the longest and average collision chain length for the
432// markup hash table
433
434static void HtmlHashStats() {
435 int i;
436 int sum = 0;
437 int max = 0;
438 int cnt;
439 int notempty = 0;
440 struct sgMap *p;
441
442 for (i = 0; i < HTML_MARKUP_COUNT; i++) {
443 cnt = 0;
444 p = gApMap[i];
445 if (p) notempty++;
446 while (p) {
447 cnt++;
448 p = p->fPCollide;
449 }
450 sum += cnt;
451 if (cnt > max) max = cnt;
452 }
453
454 printf("longest chain=%d avg=%g slots=%d empty=%d (%g%%)\n",
455 max, (double)sum/(double)notempty, i, i-notempty,
456 100.0*(i-notempty)/(double)i);
457}
458#endif
459
460
461// Initialize the escape sequence hash table
462
463static void HtmlHashInit(void){
464 int i;
465 int h; // The hash on a markup name
466
467 for (i = 0; i < HTML_MARKUP_COUNT; i++) {
468 h = HtmlHash(HtmlMarkupMap[i].fZName);
470 gApMap[h] = &HtmlMarkupMap[i];
471 }
472#ifdef TEST
473 HtmlHashStats();
474#endif
475}
476
477////////////////////////////////////////////////////////////////////////////////
478/// Append the given TGHtmlElement to the tokenizers list of elements
479
481{
482 pElem->fPNext = 0;
483 pElem->fPPrev = fPLast;
484 if (fPFirst == 0) {
485 fPFirst = pElem;
486 } else {
487 fPLast->fPNext = pElem;
488 }
489 fPLast = pElem;
490 fNToken++;
491}
492
493////////////////////////////////////////////////////////////////////////////////
494/// Insert token pNew before token p
495
497{
498 if (offs < 0) {
499 if (p) {
500 offs = p->fOffs;
501 } else {
502 offs = fNText;
503 }
504 }
505
506////if (p) { pNew->fStyle = p->fStyle; pNew->fFlags = p->fFlags; }
507
508// pNew->fCount = 0;
509 pNew->fOffs = offs;
510 pNew->fPNext = p;
511 if (p) {
512 pNew->fElId = p->fElId;
513 p->fElId = ++fIdind;
514 pNew->fPPrev = p->fPPrev;
515 if (p->fPPrev) p->fPPrev->fPNext = pNew;
516 if (fPFirst == p) fPFirst = pNew;
517 p->fPPrev = pNew;
518 } else {
519 pNew->fElId = ++fIdind;
520 AppendElement(pNew);
521 }
522 fNToken++;
523}
524
525////////////////////////////////////////////////////////////////////////////////
526/// Compute the new column index following the given character.
527
528static int NextColumn(int iCol, char c)
529{
530 switch (c) {
531 case '\n': return 0;
532 case '\t': return (iCol | 7) + 1;
533 default: return iCol+1;
534 }
535 /* NOT REACHED */
536}
537
538////////////////////////////////////////////////////////////////////////////////
539/// Convert a string to all lower-case letters.
540
541void ToLower(char *z)
542{
543 while (*z) {
544 if (isupper(*z)) *z = tolower(*z);
545 z++;
546 }
547}
548
549////////////////////////////////////////////////////////////////////////////////
550/// Process as much of the input HTML as possible. Construct new
551/// TGHtmlElement objects and appended them to the list. Return
552/// the number of characters actually processed.
553///
554/// This routine may invoke a callback procedure which could delete
555/// the HTML widget.
556///
557/// This routine is not reentrant for the same HTML widget. To
558/// prevent reentrancy (during a callback), the p->fICol field is
559/// set to a negative number. This is a flag to future invocations
560/// not to reentry this routine. The p->fICol field is restored
561/// before exiting, of course.
562
564{
565 char *z; // The input HTML text
566 int c; // The next character of input
567 int n; // Number of characters processed so far
568 int inpCol; // Column of input
569 int i, j; // Loop counters
570 int h; // Result from HtmlHash()
571 TGHtmlElement *pElem;// A new HTML element
572 int selfClose; // True for content free elements. Ex: <br/>
573 int argc; // The number of arguments on a markup
574 SHtmlTokenMap_t *pMap; // For searching the markup name hash table
575# define mxARG 200 // Maximum number of parameters in a single markup
576 char *argv[mxARG]; // Pointers to each markup argument.
577 int arglen[mxARG]; // Length of each markup argument
578 //int rl, ol;
579#ifdef pIsInMeachnism
580 int pIsInScript = 0;
581 int pIsInNoScript = 0;
582 int pIsInNoFrames = 0;
583#endif
584 int inLi = 0;
585
586 static char null[1] = { "" };
587
588 inpCol = fICol;
589 n = fNComplete;
590 z = fZText;
591 if (inpCol < 0) return n; // Prevents recursion
592 fICol = -1;
593 pElem = 0;
594
595 while ((c = z[n]) != 0) {
596
597 if (c == -64 && z[n+1] == -128) {
598 n += 2;
599 continue;
600 }
601
602 if (fPScript) {
603
604 // We are in the middle of <SCRIPT>...</SCRIPT>. Just look for
605 // the </SCRIPT> markup. (later:) Treat <STYLE>...</STYLE> the
606 // same way.
607
608 TGHtmlScript *pScr = fPScript;
609 const char *zEnd;
610 int nEnd;
611 //int curline, curch, curlast = n;
612 int sqcnt;
613 if (pScr->fType == Html_SCRIPT) {
614 zEnd = "</script>";
615 nEnd = 9;
616 } else if (pScr->fType == Html_NOSCRIPT) {
617 zEnd = "</noscript>";
618 nEnd = 11;
619 } else if (pScr->fType == Html_NOFRAMES) {
620 zEnd = "</noframes>";
621 nEnd = 11;
622 } else {
623 zEnd = "</style>";
624 nEnd = 8;
625 }
626 if (pScr->fNStart < 0) {
627 pScr->fNStart = n;
628 pScr->fNScript = 0;
629 }
630 sqcnt = 0;
631 for (i = n /*pScr->fNStart + pScr->fNScript*/; z[i]; i++) {
632 if (z[i] == '\'' || z[i] == '"') {
633 sqcnt++; // Skip if odd # quotes
634 } else if (z[i] == '\n') {
635 sqcnt = 0;
636 }
637 if (z[i] == '<' && z[i+1] == '/' &&
638 strncasecmp(&z[i], zEnd, nEnd) == 0) {
639 if (zEnd[3] == 'c' && ((sqcnt % 2) == 1)) continue;
640 pScr->fNScript = i - n;
641 fPScript = 0;
642 n = i + nEnd;
643 break;
644 }
645 }
646 if (z[i] == 0) goto incomplete;
647 if (fPScript) {
648 pScr->fNScript = i - n;
649 n = i;
650 }
651 else {
652#ifdef pIsInMeachnism
653 // If there is a script, execute it now and insert any output
654 // to the html stream for parsing as html. (ie. client side scripting)
655
656 if (pIsInScript && !pIsInNoScript && !pIsInNoFrames) {
657
658 //for (curch = 0, curline = 1; curch <= curlast; curch++)
659 // if (z[curch] == '\n') curline++;
660
661 // arglist in pElem and text pointers in pScr?
662 // Inline scripts can contain unmatched brackets :-)
663 //char varind[50];
664 //sprintf(varind, "HtmlScrVar%d", p->varind++);
665 //char savech = fZText[pScr->fNStart + pScr->fNScript];
666 //fZText[pScr->fNStart + pScr->fNScript] = 0;
667 //char *scriptBody = StrDup(fZText[pScr->fNStart]);
668 //fZText[pScr->fNStart + pScr->fNScript] = savech;
669 AdvanceLayout(p);
670 inParse++;
671 char *result = ProcessScript((TGHtmlScript *) pElem); // pElem or pScr??
672 inParse--;
673 if (result) {
674 ol = fNAlloc;
675 rl = strlen(result);
676 fNAlloc += rl;
677 z = fZText = HtmlRealloc(z, ol+rl);
678 memmove(z + n + rl, z+n, ol - n);
679 memmove(z + n, result, rl);
680 }
681 }
682 pIsInScript = 0;
683 pIsInNoScript = 0;
684 pIsInNoFrames = 0;
685#endif
686 }
687 //continue;
688
689 }
690 else if (isspace((unsigned char)c)) {
691
692 // White space
693 for (i = 0;
694 (c = z[n+i]) != 0 && isspace((unsigned char)c) && c != '\n' && c != '\r';
695 i++) { }
696 if (c == '\r' && z[n+i+1] == '\n') ++i;
697 pElem = new TGHtmlSpaceElement;
698 if (pElem == 0) goto incomplete;
699 ((TGHtmlSpaceElement *)pElem)->fW = 0;
700 pElem->fOffs = n;
701 pElem->fElId = ++fIdind;
702 if (c == '\n' || c == '\r') {
703 pElem->fFlags = HTML_NewLine;
704 pElem->fCount = 1;
705 i++;
706 inpCol = 0;
707 } else {
708 int iColStart = inpCol;
709 pElem->fFlags = 0;
710 for (j = 0; j < i; j++) {
711 inpCol = NextColumn(inpCol, z[n+j]);
712 }
713 pElem->fCount = inpCol - iColStart;
714 }
715 AppendElement(pElem);
716 n += i;
717
718 }
719 else if (c != '<' || fIPlaintext != 0 ||
720 (!isalpha(z[n+1]) && z[n+1] != '/' && z[n+1] != '!' && z[n+1] != '?')) {
721
722 // Ordinary text
723 for (i = 1; (c = z[n+i]) != 0 && !isspace((unsigned char)c) && c != '<'; i++) {}
724 if (c == 0) goto incomplete;
725 if (fIPlaintext != 0 && z[n] == '<') {
726 switch (fIPlaintext) {
727 case Html_LISTING:
728 if (i >= 10 && strncasecmp(&z[n], "</listing>", 10) == 0) {
729 fIPlaintext = 0;
730 goto doMarkup;
731 }
732 break;
733
734 case Html_XMP:
735 if (i >= 6 && strncasecmp(&z[n], "</xmp>", 6) == 0) {
736 fIPlaintext = 0;
737 goto doMarkup;
738 }
739 break;
740
741 case Html_TEXTAREA:
742 if (i >= 11 && strncasecmp(&z[n], "</textarea>", 11) == 0) {
743 fIPlaintext = 0;
744 goto doMarkup;
745 }
746 break;
747
748 default:
749 break;
750 }
751 }
752 pElem = new TGHtmlTextElement(i);
753 if (pElem == 0) goto incomplete;
754 TGHtmlTextElement *tpElem = (TGHtmlTextElement *) pElem;
755 tpElem->fElId = ++fIdind;
756 tpElem->fOffs = n;
757 strncpy(tpElem->fZText, &z[n], i);
758 tpElem->fZText[i] = 0;
759 AppendElement(pElem);
760 if (fIPlaintext == 0 || fIPlaintext == Html_TEXTAREA) {
762 }
763 pElem->fCount = (Html_16_t) strlen(tpElem->fZText);
764 n += i;
765 inpCol += i;
766
767 } else if (strncmp(&z[n], "<!--", 4) == 0) {
768
769 // An HTML comment. Just skip it.
770 for (i = 4; z[n+i]; i++) {
771 if (z[n+i] == '-' && strncmp(&z[n+i], "-->", 3) == 0) break;
772 }
773 if (z[n+i] == 0) goto incomplete;
774
775 pElem = new TGHtmlTextElement(i);
776 if (pElem == 0) goto incomplete;
777 TGHtmlTextElement *tpElem = (TGHtmlTextElement *) pElem;
778 tpElem->fType = Html_COMMENT;
779 tpElem->fElId = ++fIdind;
780 tpElem->fOffs = n;
781 strncpy(tpElem->fZText, &z[n+4], i-4);
782 tpElem->fZText[i-4] = 0;
783 tpElem->fCount = 0;
784 AppendElement(pElem);
785
786 pElem = new TGHtmlElement(Html_EndCOMMENT);
787 AppToken(pElem, 0, n+4);
788
789 for (j = 0; j < i+3; j++) {
790 inpCol = NextColumn(inpCol, z[n+j]);
791 }
792 n += i + 3;
793
794 }
795 else {
796
797 // Markup.
798 //
799 // First get the name of the markup
800doMarkup:
801 argc = 1;
802 argv[0] = &z[n+1];
803 for (i = 1;
804 (c = z[n+i]) != 0 && !isspace((unsigned char)c) && c != '>' && (i < 2 || c != '/');
805 i++) {}
806 arglen[0] = i - 1;
807 if (c == 0) goto incomplete;
808
809 // Now parse up the arguments
810
811 while (isspace((unsigned char)z[n+i])) ++i;
812 while ((c = z[n+i]) != 0 && c != '>' && (c != '/' || z[n+i+1] != '>')) {
813 if (argc > mxARG - 3) argc = mxARG - 3;
814 argv[argc] = &z[n+i];
815 j = 0;
816 while ((c = z[n+i+j]) != 0 && !isspace((unsigned char)c) && c != '>' &&
817 c != '=' && (c != '/' || z[n+i+j+1] != '>')) ++j;
818 arglen[argc] = j;
819 if (c == 0) goto incomplete;
820 i += j;
821 while (isspace((unsigned char)c)) {
822 i++;
823 c = z[n+i];
824 }
825 if (c == 0) goto incomplete;
826 argc++;
827 if (c != '=') {
828 argv[argc] = null;
829 arglen[argc] = 0;
830 argc++;
831 continue;
832 }
833 i++;
834 c = z[n+i];
835 while (isspace((unsigned char)c)) {
836 i++;
837 c = z[n+i];
838 }
839 if (c == 0) goto incomplete;
840 if (c == '\'' || c == '"') {
841 int cQuote = c;
842 i++;
843 argv[argc] = &z[n+i];
844 for (j = 0; (c = z[n+i+j]) != 0 && c != cQuote; j++) {}
845 if (c == 0) goto incomplete;
846 arglen[argc] = j;
847 i += j+1;
848 } else {
849 argv[argc] = &z[n+i];
850 for (j = 0; (c = z[n+i+j]) != 0 && !isspace((unsigned char)c) && c != '>'; j++) {}
851 if (c == 0) goto incomplete;
852 arglen[argc] = j;
853 i += j;
854 }
855 argc++;
856 while (isspace(z[n+i])) ++i;
857 }
858 if (c == '/') {
859 i++;
860 c = z[n+i];
861 selfClose = 1;
862 } else {
863 selfClose = 0;
864 }
865 if (c == 0) goto incomplete;
866 for (j = 0; j < i+1; j++) {
867 inpCol = NextColumn(inpCol, z[n+j]);
868 }
869 n += i + 1;
870
871 // Lookup the markup name in the hash table
872
873 if (!gIsInit) {
874 HtmlHashInit();
875 gIsInit = 1;
876 }
877 c = argv[0][arglen[0]];
878 argv[0][arglen[0]] = 0;
879 h = HtmlHash(argv[0]);
880 for (pMap = gApMap[h]; pMap; pMap = pMap->fPCollide) {
881 if (strcasecmp(pMap->fZName, argv[0]) == 0) break;
882 }
883 argv[0][arglen[0]] = c;
884 if (pMap == 0) continue; // Ignore unknown markup
885
886makeMarkupEntry:
887 // Construct a TGHtmlMarkupElement object for this markup.
888
889 pElem = MakeMarkupEntry(pMap->fObjType, pMap->fType, argc, arglen, argv);
890 if (pElem == 0) goto incomplete;
891
892 pElem->fElId = ++fIdind;
893 pElem->fOffs = n;
894
895 AddFormInfo(pElem);
896
897 // The new markup has now been constructed in pElem. But before
898 // appending it to the list, check to see if there is a special
899 // handler for this markup type.
900
901 if (ProcessToken(pElem, pMap->fZName, pMap->fType)) {
902 // delete pElem;
903
904 // Tricky, tricky. The user function might have caused the p->fZText
905 // pointer to change, so renew our copy of that pointer.
906
907 z = fZText;
908 if (z == 0) {
909 n = 0;
910 inpCol = 0;
911 goto incomplete;
912 }
913 continue;
914 }
915
916 // No special handler for this markup. Just append it to the
917 // list of all tokens.
918
919 AppendElement(pElem);
920 switch (pMap->fType) {
921 case Html_TABLE:
922 break;
923
924 case Html_PLAINTEXT:
925 case Html_LISTING:
926 case Html_XMP:
927 case Html_TEXTAREA:
928 fIPlaintext = pMap->fType;
929 break;
930
931 case Html_NOFRAMES:
932 if (!fHasFrames) break;
933#ifdef pIsInMeachnism
934 pIsInNoFrames = 1;
935#endif
936 case Html_NOSCRIPT:
937 break;
938 // coverity[unreachable]
939 if (!fHasScript) break;
940#ifdef pIsInMeachnism
941 pIsInNoScript = 1;
942#endif
943 case Html_SCRIPT:
944#ifdef pIsInMeachnism
945 pIsInScript = 1;
946#endif
947 // fallthrough
948 case Html_STYLE:
949 fPScript = (TGHtmlScript *) pElem;
950 break;
951
952 case Html_LI:
953 if (!fAddEndTags) break;
954 if (inLi) {
956 AppToken(e, pElem, n);
957 } else {
958 inLi = 1;
959 }
960 break;
961
962 case Html_EndLI:
963 inLi=0;
964 break;
965
966 case Html_EndOL:
967 case Html_EndUL:
968 if (!fAddEndTags) break;
969 if (inLi) {
971 AppToken(e, pElem, n);
972 } else {
973 inLi = 0;
974 }
975 break;
976
977 default:
978 break;
979 }
980
981 // If this is self-closing markup (ex: <br/> or <img/>) then
982 // synthesize a closing token.
983
984 if (selfClose && argv[0][0] != '/' &&
985 strcmp(&pMap[1].fZName[1], pMap->fZName) == 0) {
986 selfClose = 0;
987 pMap++;
988 argc = 1;
989 goto makeMarkupEntry;
990 }
991 }
992 }
993
994incomplete:
995 fICol = inpCol;
996 ////fPScript = 0;
997
998 return n;
999}
1000
1001/************************** End HTML Tokenizer Code ***************************/
1002
1003////////////////////////////////////////////////////////////////////////////////
1004/// Make one markup entry.
1005
1007 int arglen[], char *argv[])
1008{
1010
1011 switch (objType) {
1012 case O_HtmlCell:
1013 e = new TGHtmlCell(type, argc, arglen, argv);
1014 break;
1015
1016 case O_HtmlTable:
1017 e = new TGHtmlTable(type, argc, arglen, argv);
1018 break;
1019
1020 case O_HtmlRef:
1021 e = new TGHtmlRef(type, argc, arglen, argv);
1022 break;
1023
1024 case O_HtmlLi:
1025 e = new TGHtmlLi(type, argc, arglen, argv);
1026 break;
1027
1028 case O_HtmlListStart:
1029 e = new TGHtmlListStart(type, argc, arglen, argv);
1030 break;
1031
1032 case O_HtmlImageMarkup:
1033 e = new TGHtmlImageMarkup(type, argc, arglen, argv);
1034 break;
1035
1036 case O_HtmlInput:
1037 e = new TGHtmlInput(type, argc, arglen, argv);
1038 break;
1039
1040 case O_HtmlForm:
1041 e = new TGHtmlForm(type, argc, arglen, argv);
1042 break;
1043
1044 case O_HtmlHr:
1045 e = new TGHtmlHr(type, argc, arglen, argv);
1046 break;
1047
1048 case O_HtmlAnchor:
1049 e = new TGHtmlAnchor(type, argc, arglen, argv);
1050 break;
1051
1052 case O_HtmlScript:
1053 e = new TGHtmlScript(type, argc, arglen, argv);
1054 break;
1055
1056 case O_HtmlMapArea:
1057 e = new TGHtmlMapArea(type, argc, arglen, argv);
1058 break;
1059
1060 default:
1061 e = new TGHtmlMarkupElement(type, argc, arglen, argv);
1062 break;
1063 }
1064
1065 return e;
1066}
1067
1068////////////////////////////////////////////////////////////////////////////////
1069/// Append text to the tokenizer engine.
1070
1072{
1073 int len = strlen(text);
1074
1075 if (fNText == 0) {
1076 fNAlloc = len + 100;
1077 fZText = new char [fNAlloc];
1078 } else if (fNText + len >= fNAlloc) {
1079 fNAlloc += len + 100;
1080 char *tmp = new char[fNAlloc];
1081 strlcpy(tmp, fZText, fNAlloc);
1082 delete[] fZText;
1083 fZText = tmp;
1084 }
1085
1086 if (fZText == 0) {
1087 fNText = 0;
1088 UNTESTED;
1089 return;
1090 }
1091
1092 strlcpy(&fZText[fNText], text, fNAlloc - fNText);
1093 fNText += len;
1094 fNComplete = Tokenize();
1095}
1096
1097////////////////////////////////////////////////////////////////////////////////
1098/// This routine takes a text representation of a token, converts it into an
1099/// TGHtmlElement object and inserts it immediately prior to pToken. If pToken
1100/// is 0, then the newly created TGHtmlElement is appended.
1101///
1102/// This routine does nothing to resize, restyle, relayout or redisplay
1103/// the HTML. That is the calling routines responsibility.
1104///
1105/// Return the new TGHtmlElement object if successful. Return zero if
1106/// zType is not a known markup name.
1107///
1108/// pToken - Insert before this. Append if pToken == 0
1109/// zType - Type of markup. Ex: "/a" or "table"
1110/// zArgs - List of arguments
1111/// offs - Calculate offset, and insert changed text into fZText!
1112
1114 char *zType, char *zArgs, int offs)
1115{
1116 SHtmlTokenMap_t *pMap; // For searching the markup name hash table
1117 int h; // The hash on zType
1118 TGHtmlElement *pElem; // The new element
1119 //int nByte; // How many bytes to allocate
1120 //int i; // Loop counter
1121
1122 if (!gIsInit) {
1123 HtmlHashInit();
1124 gIsInit = 1;
1125 }
1126
1127 if (strcmp(zType, "Text") == 0) {
1128 pElem = new TGHtmlTextElement(zArgs ? strlen(zArgs) : 0);
1129 if (pElem == 0) return 0;
1130 if (zArgs) {
1131 // coverity[secure_coding]
1132 strcpy (((TGHtmlTextElement *)pElem)->fZText, zArgs); // NOLINT
1133 pElem->fCount = (Html_16_t) strlen(zArgs);
1134 }
1135 } else if (!strcmp(zType, "Space")) {
1136 pElem = new TGHtmlSpaceElement();
1137 if (pElem == 0) return 0;
1138 } else {
1139 h = HtmlHash(zType);
1140 for (pMap = gApMap[h]; pMap; pMap = pMap->fPCollide) {
1141 if (strcasecmp(pMap->fZName, zType) == 0) break;
1142 }
1143 if (pMap == 0) return 0;
1144 if (zArgs == 0 || *zArgs == 0) {
1145 // Special case of no arguments. This is a lot easier...
1146 // well... now its the same thing!
1147 pElem = MakeMarkupEntry(pMap->fObjType, pMap->fType, 1, 0, 0);
1148 if (pElem == 0) return 0;
1149 } else {
1150 // The general case. There are arguments that need to be parsed
1151 // up. This is slower, but we gotta do it.
1152 //int argc;
1153 //char **argv;
1154 //char *zBuf;
1155
1156#if 0
1157 if (!SplitList(zArgs, &argc, &argv)) return 0;
1158
1159 // shall we insert a dummy argv[0]?
1160
1161 pElem = MakeMarkupEntry(pMap->fObjType, pMap->fType, argc/*+1??*/, 0, argv);
1162 if (pElem == 0) return 1;
1163
1164 while (--argc >= 0) if (argv[argc]) delete[] argv[argc];
1165 delete[] argv;
1166#else
1167 return 0;
1168#endif
1169 }
1170 }
1171
1172 pElem->fElId = ++fIdind;
1173
1174 AppToken(pElem, pToken, offs);
1175
1176 return pElem;
1177}
1178
1179////////////////////////////////////////////////////////////////////////////////
1180/// Insert text into text token, or break token into two text tokens.
1181/// Also, handle backspace char by deleting text.
1182/// Should also handle newline char by splitting text.
1183
1184int TGHtml::TextInsertCmd(int /*argc*/, char ** /*argv*/)
1185{
1186#if 0
1187 TGHtmlElement *p, *pElem;
1188 int i, l, n = 0;
1189 int idx = 0;
1190 int ptyp = Html_Unknown;
1191 int istxt = 0;
1192 char *cp = 0, c, *cp2;
1193
1194 if (GetIndex(argv[3], &p, &i) != 0) {
1195 // sprintf(tmp, "malformed index: \"%s\"", argv[3]);
1196 return 0;
1197 }
1198 if (p) {
1199 ptyp = p->fType;
1200 if ((istxt = (ptyp == Html_Text))) {
1201 l = p->fCount;
1202 cp = ((TGHtmlTextElement *)p)->fZText;
1203 }
1204 }
1205 if (argv[2][0] == 'b') { // Break text token into two.
1206 if (!istxt) return 1;
1207 if (i == 0 || i == l) return 1;
1208 pElem = InsertToken(p->fPNext, "Text", cp + i, -1);
1209 cp[i] = 0;
1210 p->fCount = i;
1211 return 1;
1212 }
1213 c = argv[4][0];
1214 if (!c) return 1;
1215 if (c == '\b') {
1216 if ((!istxt) || (!l) || (!i)) {
1217 if (!p) return 1;
1218 if (p->fType == Html_BR)
1219 RemoveElements(p, p);
1220 return 1;
1221 }
1222 if (p && l == 1) {
1223 RemoveElements(p, p);
1224 return 1;
1225 }
1226 if (i == l)
1227 cp[p->fCount] = 0;
1228 else
1229 memcpy(cp+i-1, cp+i, l-i+1);
1230
1231 cp[--p->fCount] = 0;
1232 if (ins.i-- <= 0) ins.i = 0;
1233 ins.p = p;
1234 return 1;
1235 }
1236 if (c == '\n' || c == '\r') {
1237 }
1238 if (istxt) {
1239 char *cp;
1240 int t, j, alen = strlen(argv[4]);
1241 n = alen + l;
1242
1244
1245 if (text->fZText == (char*) ((&text->fZText)+1)) {
1246 cp = new char[n+1];
1247 strcpy(cp, text->fZText);
1248 } else {
1249 cp = new char[n+1];
1250 strcpy(cp, text->fZText);
1251 }
1252 cp2 = new char[alen+1];
1253 memcpy(cp2, argv[4], alen+1);
1255 alen = strlen(cp2);
1256 memmove(cp+alen+i, cp+i, l-i+1);
1257 for (j = 0; j < alen; j++) cp[i+j] = cp2[j];
1258 delete[] cp2;
1259 delete[] text->fZText;
1260 text->fZText = cp;
1261 p->fCount = strlen(cp);
1262 ins.p = p;
1263 ins.i = i+alen;
1264 } else {
1265 p = InsertToken(p ? p->fPNext : 0, "Text", argv[4], -1);
1266 AddStyle(p);
1267 i = 0;
1268 ins.p = p;
1269 ins.i = 1;
1270 }
1271 if (p) {
1272 idx = p->base.id;
1273 AddStrOffset(p, argv[4], i);
1274 }
1275#endif
1276 return 1;
1277}
1278
1279////////////////////////////////////////////////////////////////////////////////
1280/// Returns token map matching zType name.
1281
1283{
1284 SHtmlTokenMap_t *pMap; // For searching the markup name hash table
1285 int h; // The hash on zType
1286
1287 if (!gIsInit) {
1288 HtmlHashInit();
1289 gIsInit = 1;
1290 }
1291 h = HtmlHash(zType);
1292 for (pMap = gApMap[h]; pMap; pMap = pMap->fPCollide) {
1293 if (strcasecmp(pMap->fZName, zType) == 0) break;
1294 }
1295
1296 return pMap;
1297}
1298
1299////////////////////////////////////////////////////////////////////////////////
1300/// Convert a markup name into a type integer
1301
1302int TGHtml::NameToType(char *zType)
1303{
1304 SHtmlTokenMap_t *pMap = NameToPmap(zType);
1305 return pMap ? pMap->fType : (int)Html_Unknown;
1306}
1307
1308////////////////////////////////////////////////////////////////////////////////
1309/// Convert a type into a symbolic name
1310
1311const char *TGHtml::TypeToName(int type)
1312{
1313 if (type >= Html_A && type <= Html_EndXMP) {
1314 SHtmlTokenMap_t *pMap = gApMap[type - Html_A];
1315 return pMap->fZName;
1316 } else {
1317 return "???";
1318 }
1319}
1320
1321////////////////////////////////////////////////////////////////////////////////
1322/// For debugging purposes, print information about a token
1323
1325{
1326//#ifdef DEBUG
1327 static char zBuf[200];
1328 int j;
1329 const char *zName;
1330
1331 if (p == 0) {
1332 snprintf(zBuf, 200, "NULL");
1333 return zBuf;
1334 }
1335 switch (p->fType) {
1336 case Html_Text:
1337 snprintf(zBuf, 200, "text: \"%.*s\"", p->fCount, ((TGHtmlTextElement *)p)->fZText);
1338 break;
1339
1340 case Html_Space:
1341 if (p->fFlags & HTML_NewLine) {
1342 snprintf(zBuf, 200, "space: \"\\n\"");
1343 } else {
1344 snprintf(zBuf, 200, "space: \" \"");
1345 }
1346 break;
1347
1348 case Html_Block: {
1349 TGHtmlBlock *block = (TGHtmlBlock *) p;
1350 if (block->fN > 0) {
1351 int n = block->fN;
1352 if (n > 150) n = 150;
1353 snprintf(zBuf, 200, "<Block z=\"%.*s\">", n, block->fZ);
1354 } else {
1355 snprintf(zBuf, 200, "<Block>");
1356 }
1357 break;
1358 }
1359
1360 default:
1361 if (p->fType >= HtmlMarkupMap[0].fType
1362 && p->fType <= HtmlMarkupMap[HTML_MARKUP_COUNT-1].fType) {
1363 zName = HtmlMarkupMap[p->fType - HtmlMarkupMap[0].fType].fZName;
1364 } else {
1365 zName = "Unknown";
1366 }
1367 snprintf(zBuf, 200, "markup (%d) <%s", p->fType, zName);
1368 for (j = 1 ; j < p->fCount; j += 2) {
1369 snprintf(&zBuf[strlen(zBuf)], 200-strlen(zBuf), " %s=\"%s\"",
1370 ((TGHtmlMarkupElement *)p)->fArgv[j-1],
1371 ((TGHtmlMarkupElement *)p)->fArgv[j]);
1372 }
1373 // coverity[secure_coding]
1374 strlcat(zBuf, ">", sizeof(zBuf));
1375 break;
1376 }
1377 return zBuf;
1378//#else
1379// return 0;
1380//#endif
1381}
1382
1383////////////////////////////////////////////////////////////////////////////////
1384/// Append all the arguments of the given markup to the given TGString.
1385///
1386/// Example: If the markup is <IMG SRC=image.gif ALT="hello!">
1387/// then the following text is appended to the TGString:
1388///
1389/// "src image.gif alt hello!"
1390///
1391/// Notice how all attribute names are converted to lower case.
1392/// This conversion happens in the parser.
1393
1395{
1396 int i;
1397
1398 for (i = 0; i + 1 < pElem->fCount; i += 2) {
1399 str->Append(pElem->fArgv[i]);
1400 str->Append("=");
1401 str->Append(pElem->fArgv[i+1]);
1402 str->Append(" ");
1403 }
1404}
1405
1406////////////////////////////////////////////////////////////////////////////////
1407/// Returns token name of html element p.
1408
1410{
1411 static char zBuf[200];
1412 //int j;
1413 const char *zName;
1414
1415 zBuf[0] = 0;
1416 if (p == 0) {
1417 // coverity[secure_coding]: zBuf is large enough
1418 strcpy(zBuf, "NULL");
1419 return zBuf;
1420 }
1421 switch (p->fType) {
1422 case Html_Text:
1423 case Html_Space:
1424 break;
1425
1426 case Html_Block:
1427 break;
1428
1429 default:
1430 if (p->fType >= HtmlMarkupMap[0].fType &&
1431 p->fType <= HtmlMarkupMap[HTML_MARKUP_COUNT-1].fType) {
1432 zName = HtmlMarkupMap[p->fType - HtmlMarkupMap[0].fType].fZName;
1433 } else {
1434 zName = "Unknown";
1435 }
1436 strlcpy(zBuf, zName, sizeof(zBuf));
1437 break;
1438 }
1439
1440 return zBuf;
1441}
1442
1443////////////////////////////////////////////////////////////////////////////////
1444/// Returns token map at location n.
1445
1447{
1448 return HtmlMarkupMap+n;
1449}
1450
1451////////////////////////////////////////////////////////////////////////////////
1452/// Return all tokens between the two elements as a string list.
1453
1455{
1456 TGString *str;
1457 int i;
1458 const char *zName;
1459 char zLine[100];
1460
1461 str = new TGString("");
1462 while (p && p != pEnd) {
1463 switch (p->fType) {
1464 case Html_Block:
1465 break;
1466
1467 case Html_Text:
1468 str->Append("{ Text \"");
1469 str->Append(((TGHtmlTextElement *)p)->fZText);
1470 str->Append("\" } ");
1471 break;
1472
1473 case Html_Space:
1474 snprintf(zLine, 100, "Space %d %d ",
1475 p->fCount, (p->fFlags & HTML_NewLine) != 0);
1476 str->Append(zLine);
1477 break;
1478
1479 case Html_Unknown:
1480 str->Append("Unknown ");
1481 break;
1482
1483 default:
1484 str->Append("{ Markup ");
1485 if (p->fType >= HtmlMarkupMap[0].fType &&
1486 p->fType <= HtmlMarkupMap[HTML_MARKUP_COUNT-1].fType) {
1487 zName = HtmlMarkupMap[p->fType - HtmlMarkupMap[0].fType].fZName;
1488 } else {
1489 zName = "Unknown";
1490 }
1491 str->Append(zName);
1492 str->Append(" ");
1493 for (i = 0; i < p->fCount; ++i) {
1494 str->Append(((TGHtmlMarkupElement *)p)->fArgv[i]);
1495 str->Append(" ");
1496 }
1497 str->Append("} ");
1498 break;
1499 }
1500 p = p->fPNext;
1501 }
1502
1503 return str;
1504}
1505
1506////////////////////////////////////////////////////////////////////////////////
1507/// Print a list of tokens
1508
1510{
1512
1513 for (p = first; p != last; p = p->fPNext) {
1514 if (p->fType == Html_Block) {
1515 TGHtmlBlock *block = (TGHtmlBlock *) p;
1516 const char *z = block->fZ;
1517 int n = block->fN;
1518 if (n == 0 || z == 0) {
1519 n = 1;
1520 z = "";
1521 }
1522 printf("Block flags=%02x cnt=%d x=%d..%d y=%d..%d z=\"%.*s\"\n",
1523 p->fFlags, p->fCount, block->fLeft, block->fRight,
1524 block->fTop, block->fBottom, n, z);
1525 } else {
1526 printf("Token font=%2d color=%2d align=%d flags=0x%04x name=%s\n",
1527 p->fStyle.fFont, p->fStyle.fColor,
1528 p->fStyle.fAlign, p->fStyle.fFlags, DumpToken(p));
1529 }
1530 }
1531}
#define c(i)
Definition: RSha256.hxx:101
#define h(i)
Definition: RSha256.hxx:106
#define e(i)
Definition: RSha256.hxx:103
void ToLower(char *z)
Convert a string to all lower-case letters.
static int EscHash(const char *zName)
static int HtmlHash(const char *zName)
static char gAcMsChar[]
static int gIsInit
static int NextColumn(int iCol, char c)
Compute the new column index following the given character.
static SHtmlTokenMap_t * gApMap[HTML_MARKUP_HASH_SIZE]
void HtmlTranslateEscapes(char *z)
Translate escape sequences in the string "z".
SHtmlTokenMap_t HtmlMarkupMap[]
static struct SgEsc_t gEscSequences[]
Definition: TGHtmlParse.cxx:75
#define mxARG
static void HtmlHashInit(void)
static struct SgEsc_t * gApEscHash[(sizeof(gEscSequences)/sizeof(gEscSequences[0])+7)]
#define ESC_HASH_SIZE
static void EscInit()
@ Html_COMMENT
Definition: TGHtmlTokens.h:74
@ Html_TEXTAREA
Definition: TGHtmlTokens.h:176
@ Html_XMP
Definition: TGHtmlTokens.h:193
@ Html_STYLE
Definition: TGHtmlTokens.h:167
@ Html_SCRIPT
Definition: TGHtmlTokens.h:158
@ Html_LI
Definition: TGHtmlTokens.h:122
@ Html_LISTING
Definition: TGHtmlTokens.h:125
@ Html_TABLE
Definition: TGHtmlTokens.h:172
@ Html_EndUL
Definition: TGHtmlTokens.h:189
@ Html_EndOL
Definition: TGHtmlTokens.h:144
@ Html_NOFRAMES
Definition: TGHtmlTokens.h:139
@ Html_PLAINTEXT
Definition: TGHtmlTokens.h:151
@ Html_Block
Definition: TGHtmlTokens.h:45
@ Html_Space
Definition: TGHtmlTokens.h:43
@ Html_Text
Definition: TGHtmlTokens.h:42
@ Html_A
Definition: TGHtmlTokens.h:46
@ Html_NOSCRIPT
Definition: TGHtmlTokens.h:141
@ Html_EndLI
Definition: TGHtmlTokens.h:123
@ Html_EndXMP
Definition: TGHtmlTokens.h:194
@ Html_BR
Definition: TGHtmlTokens.h:65
@ Html_Unknown
Definition: TGHtmlTokens.h:44
@ Html_EndCOMMENT
Definition: TGHtmlTokens.h:75
#define HTML_MARKUP_HASH_SIZE
Definition: TGHtmlTokens.h:200
#define HTML_MARKUP_COUNT
Definition: TGHtmlTokens.h:199
#define O_HtmlInput
Definition: TGHtml.h:858
#define O_HtmlHr
Definition: TGHtml.h:860
#define O_HtmlTable
Definition: TGHtml.h:853
#define UNTESTED
Definition: TGHtml.h:65
#define HTML_NewLine
Definition: TGHtml.h:276
#define O_HtmlImageMarkup
Definition: TGHtml.h:857
short Html_16_t
Definition: TGHtml.h:137
#define O_HtmlAnchor
Definition: TGHtml.h:861
#define O_HtmlLi
Definition: TGHtml.h:855
#define O_HtmlMapArea
Definition: TGHtml.h:863
#define O_HtmlRef
Definition: TGHtml.h:854
#define O_HtmlCell
Definition: TGHtml.h:852
#define O_HtmlScript
Definition: TGHtml.h:862
#define O_HtmlListStart
Definition: TGHtml.h:856
#define O_HtmlForm
Definition: TGHtml.h:859
winID h TVirtualViewer3D TVirtualGLPainter p
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t result
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void value
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t UChar_t len
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t type
Option_t Option_t TPoint TPoint const char text
#define snprintf
Definition: civetweb.c:1540
Html_u16_t fN
Definition: TGHtml.h:720
Html_u16_t fRight
Definition: TGHtml.h:719
char * fZ
Definition: TGHtml.h:717
Html_u16_t fLeft
Definition: TGHtml.h:719
int fTop
Definition: TGHtml.h:718
int fBottom
Definition: TGHtml.h:718
Html_u8_t fFlags
Definition: TGHtml.h:266
Html_u8_t fType
Definition: TGHtml.h:265
TGHtmlElement * fPPrev
Definition: TGHtml.h:263
Html_16_t fCount
Definition: TGHtml.h:267
TGHtmlElement * fPNext
Definition: TGHtml.h:262
int fNStart
Definition: TGHtml.h:684
int fNScript
Definition: TGHtml.h:685
Html_16_t fW
Definition: TGHtml.h:309
char * fZText
Definition: TGHtml.h:301
int fAddEndTags
Definition: TGHtml.h:1254
TGString * ListTokens(TGHtmlElement *p, TGHtmlElement *pEnd)
Return all tokens between the two elements as a string list.
int fICol
Definition: TGHtml.h:1181
void AppToken(TGHtmlElement *pNew, TGHtmlElement *p, int offs)
Insert token pNew before token p.
int fIdind
Definition: TGHtml.h:1279
int TextInsertCmd(int argc, char **argv)
Insert text into text token, or break token into two text tokens.
void TokenizerAppend(const char *text)
Append text to the tokenizer engine.
TGHtmlElement * fPFirst
Definition: TGHtml.h:1136
void AddStyle(TGHtmlElement *p)
This routine adds information to the input texts that doesn't change when the display is resized or w...
virtual char * ProcessScript(TGHtmlScript *)
Definition: TGHtml.h:958
int fNToken
Definition: TGHtml.h:1138
TGHtmlElement * InsertToken(TGHtmlElement *pToken, char *zType, char *zArgs, int offs)
This routine takes a text representation of a token, converts it into an TGHtmlElement object and ins...
const char * TypeToName(int type)
Convert a type into a symbolic name.
int Tokenize()
Process as much of the input HTML as possible.
int NameToType(char *zType)
Convert a markup name into a type integer.
int fIPlaintext
Definition: TGHtml.h:1183
void AppendArglist(TGString *str, TGHtmlMarkupElement *pElem)
Append all the arguments of the given markup to the given TGString.
char * fZText
Definition: TGHtml.h:1176
int fNAlloc
Definition: TGHtml.h:1178
void AppendElement(TGHtmlElement *pElem)
Append the given TGHtmlElement to the tokenizers list of elements.
virtual int ProcessToken(TGHtmlElement *, const char *, int)
Definition: TGHtml.h:928
TGHtmlScript * fPScript
Definition: TGHtml.h:1187
int fHasFrames
Definition: TGHtml.h:1253
TGHtmlMarkupElement * MakeMarkupEntry(int objType, int type, int argc, int arglen[], char *argv[])
Make one markup entry.
TGHtmlElement * fPLast
Definition: TGHtml.h:1137
SHtmlTokenMap_t * GetMarkupMap(int n)
Returns token map at location n.
int fNComplete
Definition: TGHtml.h:1179
SHtmlTokenMap_t * NameToPmap(char *zType)
Returns token map matching zType name.
char * DumpToken(TGHtmlElement *p)
For debugging purposes, print information about a token.
char * GetTokenName(TGHtmlElement *p)
Returns token name of html element p.
int GetIndex(const char *zIndex, TGHtmlElement **ppToken, int *pIndex)
This routine decodes a complete index specification.
int fHasScript
Definition: TGHtml.h:1252
void PrintList(TGHtmlElement *first, TGHtmlElement *last)
Print a list of tokens.
void AddFormInfo(TGHtmlElement *p)
Add the DOM control information for form elements.
Definition: TGHtmlForm.cxx:565
int fNText
Definition: TGHtml.h:1177
TGString wraps a TString and adds some graphics routines like drawing, size of string on screen depen...
Definition: TGString.h:20
TString & Append(const char *cs)
Definition: TString.h:564
const Int_t n
Definition: legend1.C:16
null_t< F > null()
Definition: first.py:1
const char * cnt
Definition: TXMLSetup.cxx:75
Html_16_t fObjType
Definition: TGHtml.h:843
Html_16_t fType
Definition: TGHtml.h:842
SHtmlTokenMap_t * fPCollide
Definition: TGHtml.h:844
const char * fZName
Definition: TGHtml.h:841
char fValue[8]
Definition: TGHtmlParse.cxx:68
SgEsc_t * fPNext
Definition: TGHtmlParse.cxx:69
const char * fZName
Definition: TGHtmlParse.cxx:67
TLine l
Definition: textangle.C:4
static uint64_t sum(uint64_t i)
Definition: Factory.cxx:2345