1#!/usr/bin/perl
2
3#============================================================================
4#
5#   File : gendoc.pl
6#   Creation date : Sun 17 Dec 2006 20:36:07 by Szymon Stefanek
7#
8#   This file is part of the KVIrc IRC Client distribution
9#   Copyright (C) 2000-2009 Szymon Stefanek <pragma at kvirc dot net>
10#
11#   This program is FREE software. You can redistribute it and/or
12#   modify it under the terms of the GNU General Public License
13#   as published by the Free Software Foundation; either version 2
14#   of the License, or (at your option) any later version.
15#
16#   This program is distributed in the HOPE that it will be USEFUL,
17#   but WITHOUT ANY WARRANTY; without even the implied warranty of
18#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
19#   See the GNU General Public License for more details.
20#
21#   You should have received a copy of the GNU General Public License
22#   along with this program. If not, write to the Free Software Foundation,
23#   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
24#
25#============================================================================
26
27#################################################################################################
28# GLOBAL CONFIGS
29#################################################################################################
30
31$g_currenttime = gmtime($ENV{SOURCE_DATE_EPOCH} || time);
32$g_currentuser = $ENV{USER} || getlogin || getpwuid($<) || "Unknown";
33$g_syntaxcolor="#802000";
34
35$g_kvssyntaxcolor="#802000";
36$g_kvstypenamecolor="#808080";
37$g_kvstypedelimiterscolor="#8080a0";
38
39$g_bodybgcolor="#FFFFFF";
40$g_bodytextcolor="#000000";
41$g_bodylinkcolor="#000000";
42$g_tablebgcolor="#F4F4F4";
43$g_internaltablecolor="#D5D5D5";
44$g_classfnctablecolor="#D5D5D5";
45$g_classfncbodytablecolor="#EDEDED";
46$g_bodytablebgcolor="#EAEAEA";
47$g_commentcolor="#207500";
48$g_fileextension=".html";
49#$g_headerborderlightcolor="#A0A0A0";
50#$g_headerborderdarkcolor="#000000";
51$g_headerbgcolor="#FFFFFF";
52
53$g_prefixes{'command'}="cmd";
54$g_prefixes{'function'}="fnc";
55$g_prefixes{'event'}="event";
56$g_prefixes{'language'}="doc";
57$g_prefixes{'class'}="class";
58$g_prefixes{'module'}="module";
59$g_prefixes{'widget'}="widget";
60
61$g_version = "4.0.0";
62$g_filehandle="";
63$g_shortsIdx{"keyterms"}=0;
64$g_directory = "";
65$g_css = "";
66
67#################################################################################################
68# PARSE ARGS
69#################################################################################################
70
71
72sub usage
73{
74	print "\n";
75	print "Usage:\n";
76	print "  gendoc.pl [-v <kvirc_version>] <target_dir> <dir1> <dir2> ...\n";
77	print "Parameters:\n";
78	print "  <target_dir>       : directory where the doc files should be written\n";
79	print "  <dir1> <dir2> ...  : a list of directories from which to extract docs\n";
80	print "Options:\n";
81	print "  -v forces the specified version to be displayed in the\n";
82	print "     generated documents\n";
83	print "Notes:\n";
84	print "  Docs will be extracted only by files with these extensions:\n";
85	print "  .h .cpp .template\n";
86	print "\n";
87}
88
89$i = 0;
90$cont = 1;
91while($cont)
92{
93	if($ARGV[$i] eq "--version")
94	{
95		print "gendoc.pl 2.0.0: KVIrc documentation generator\n";
96		exit(0);
97	} elsif($ARGV[$i] eq "-v")
98	{
99		$i++;
100		if($ARGV[$i] eq "")
101		{
102			usage();
103			die "Switch -v requires a parameter"
104		}
105		$g_version = $ARGV[$i];
106		$i++;
107	} elsif($ARGV[$i] eq "--css")
108	{
109		$i++;
110		if($ARGV[$i] eq "")
111		{
112			usage();
113			die "Switch --css requires a parameter"
114		}
115		$g_css = $ARGV[$i];
116		$i++;
117	} else {
118		$cont = 0; # stop processing
119	}
120}
121
122$g_directory = $ARGV[$i];
123$i++;
124
125if($g_directory eq "")
126{
127	usage();
128	die "Missing target directory";
129}
130
131$j = 0;
132while($ARGV[$i] ne "")
133{
134	recurse($ARGV[$i]);
135	$i++;
136}
137
138
139#################################################################################################
140# SUBS
141#################################################################################################
142
143sub recurse($)
144{
145	my($path) = @_;
146
147	## append a trailing / if it's not there
148	$path .= '/' if($path !~ /\/$/);
149
150	## loop through the files contained in the directory
151	for my $eachFile (glob($path.'*'))
152	{
153
154		## if the file is a directory
155		if( -d $eachFile)
156		{
157			## pass the directory to the routine ( recursion )
158			recurse($eachFile);
159		} else {
160			if($eachFile =~ /(\.cpp|\.h|\.template)$/)
161			{
162				$g_filesToProcess[$j] = $eachFile;
163				$j++;
164			}
165		}
166	}
167}
168
169sub print_header
170{
171	print $g_filehandle "<html>\n";
172	print $g_filehandle "<head>\n";
173	print $g_filehandle "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" >\n";
174	print $g_filehandle "<title>$_[0]</title>\n";
175	print $g_filehandle "<style type=\"text/css\">\n";
176
177	if($g_css ne "")
178	{
179		open(INPUT, $g_css) or die "Error opening $g_css: $!";
180		while(<INPUT>)
181		{
182			chomp;
183			print $g_filehandle "$_ ";
184		}
185		close(INPUT);
186	}
187
188	print $g_filehandle "</style>\n";
189	print $g_filehandle "</head>\n";
190	print $g_filehandle "<body bgcolor=\"$g_bodybgcolor\" text=\"$g_bodytextcolor\">\n";
191
192	print $g_filehandle "<table width=\"100%\" cellpadding=\"1\" cellspacing=\"0\" border=\"0\">\n";
193	print $g_filehandle " <tr>\n";
194	print $g_filehandle "  <td align=\"left\" bgcolor=\"$g_headerbgcolor\">\n";
195	print $g_filehandle "    <a href=\"index.html\"><img src=\"helplogoleft.png\" iorder=\"0\"></a>\n";
196	print $g_filehandle "  </td>\n";
197	print $g_filehandle "  <td align=\"right\" bgcolor=\"$g_headerbgcolor\">\n";
198	print $g_filehandle "    <img src=\"helplogoright.png\">\n";
199	print $g_filehandle "  </td>\n";
200	print $g_filehandle " </tr>\n";
201	print $g_filehandle "</table>\n";
202}
203
204sub print_footer
205{
206	print $g_filehandle "<div class='footer'>KVIrc $g_version Documentation - generated by $g_currentuser on $g_currenttime</div>\n";
207	print $g_filehandle "</body>\n";
208	print $g_filehandle "</html>\n";
209}
210
211sub print_tablestart
212{
213	print $g_filehandle "<table width=\"100%\" cellpadding=\"3\" cellspacing=\"0\" border=\"0\">\n";
214	#print $g_filehandle "<tr><td bgcolor=\"$g_tablebgcolor\">\n";
215}
216
217sub print_tableend
218{
219	#print $g_filehandle "</td></tr>\n";
220	print $g_filehandle "</table>\n";
221}
222
223sub print_title
224{
225	print $g_filehandle "  <tr>\n";
226	print $g_filehandle "    <td class='title-table-cell'>\n";
227	print $g_filehandle "      <div class='title-text'>$_[0]</div>";
228	if($_[1] ne "")
229	{
230		print $g_filehandle "      <div class='title-secondary-text'>$_[1]</div>";
231	}
232	print $g_filehandle "    </td>\n";
233	print $g_filehandle "  </tr>\n";
234}
235
236sub print_twocolumntitle
237{
238	print $g_filehandle "  <tr>\n";
239	print $g_filehandle "    <td colspan='2' class='title-table-cell'>\n";
240	print $g_filehandle "      <div class='title-text'>$_[0]</div>";
241	if($_[1] ne "")
242	{
243		print $g_filehandle "      <div class='title-secondary-text'>$_[1]</div>";
244	}
245	print $g_filehandle "    </td>\n";
246	print $g_filehandle "  </tr>\n";
247}
248
249
250sub print_subtitle
251{
252	print $g_filehandle "  <tr>\n";
253	print $g_filehandle "    <td class='subtitle-table-cell'><div class='subtitle-text'>$_[0]</div></td>\n";
254	print $g_filehandle "  </tr>\n";
255}
256
257sub print_twocolumnsubtitle
258{
259	print $g_filehandle "  <tr>\n";
260	print $g_filehandle "    <td colspan='2' class='subtitle-table-cell'><div class='subtitle-text'>$_[0]</div></td>\n";
261	print $g_filehandle "  </tr>\n";
262}
263
264sub print_body
265{
266	print $g_filehandle "  <tr bgcolor=\"$g_bodytablebgcolor\">\n";
267	print $g_filehandle "    <td>$_[0]</td>\n";
268	print $g_filehandle "  </tr>\n";
269}
270
271sub print_twocolumnbody
272{
273	print $g_filehandle "<tr bgcolor=\"$g_bodytablebgcolor\">\n";
274	print $g_filehandle "  <td>$_[0]</td>\n";
275	print $g_filehandle "  <td>$_[1]</td>\n";
276	print $g_filehandle "</tr>\n";
277}
278
279sub print_entry
280{
281	if($_[1] ne "")
282	{
283		if($_[0] ne "")
284		{
285			print_subtitle($_[0]);
286		}
287		print_body($_[1]);
288	}
289}
290
291sub make_single_token
292{
293	$_[0] =~ s/^[	 ]*//g;
294	$_[0] =~ s/[	 ]*$//g;
295	$_[0] =~ s/\n//g;
296}
297
298sub make_single_line
299{
300	$_[0] =~ s/^[ 	\n]*//g;
301	$_[0] =~ s/[	 \n]*$//gs;
302}
303
304sub make_syntax
305{
306	$_[0] =~ s/^[ 	\n]*//g;
307	$_[0] =~ s/[	 \n]*$//gs;
308	my @arry;
309	@arry = split('\n',$_[0]);
310	$_[0] = "";
311	foreach(@arry)
312	{
313		$_ =~ s/^[ 	\n]*//g;
314		if($_ ne "")
315		{
316			if($_[0] ne "")
317			{
318				$_[0] = "$_[0]\n$_";
319			} else {
320				$_[0] = "$_";
321			}
322		}
323	}
324	$_[0] =~ s/\n+/<br>\n/gs;
325}
326
327sub extract_keyterms
328{
329	my($docfilename);
330	my(%parts);
331	my($part); # Part title
332	my($partbody);
333	my($tabblock);
334	my($tmp);
335	my($type);
336
337	if(!open(CPPFILE,"$_[0]"))
338	{
339		return;
340	}
341	# Process the entire file
342
343	while(<CPPFILE>)
344	{
345		if(/^[ 	]*\@doc:[ 	a-z_]*/)
346		{
347			# Process a single document block
348
349			$docfilename="$_";
350			$docfilename=~ s/[ 	]*//g;
351			$docfilename=~ s/\@doc://g;
352			$docfilename=~ s/\n//g;
353			$docfilename=~ s/\r//g;
354			$docfilename=~ s/([a-zA-Z_]*)/\L\1/g;
355
356			undef %parts;
357			$part = "";
358
359			INNERLOOP: while(<CPPFILE>)
360			{
361
362				if(/^[	 ]*\*\/[ 	]*/)
363				{
364					# End of comment
365					if(($part ne "") && ($partbody ne "") && ($partbody ne "\n"))
366					{
367						# We have an entire part to store
368						$parts{$part}="$partbody";
369					}
370					last INNERLOOP;
371				} else {
372					# Inside a part
373					if(/^[	 ]*\@[a-z]*:[	 ]*/)
374					{
375						# A part title
376						if(($part ne "") && ($partbody ne "") && ($partbody ne "\n"))
377						{
378							# We have an entire part to store
379							$parts{$part}="$partbody";
380						}
381						# Start of the part
382						# Extract the title
383						$part="$_";
384						$part=~ s/[	 ]*//g;
385						$part=~ s/\@//g;
386						$part=~ s/://g;
387						$part=~ s/\n//g;
388						# Clear the body (begin)
389						$partbody="";
390					} else {
391						# Somewhere in a part body
392						if(($_ ne "") && ($_ ne "\n"))
393						{
394							if($partbody eq "")
395							{
396								# If it is the first line of the part body
397								# Extract the amount of tabs that the part has
398								# We will use it to remove the C++ indentation
399								$tabblock = "$_";
400								$tabblock =~ s/^([	]*).*/\1/g;
401								$tabblock =~ s/\n//g;
402							}
403
404							if($tabblock ne "")
405							{
406								# If we have the initial tabblock , remove it from the line (remove indentation)
407								$_ =~ s/^$tabblock//g;
408							}
409
410							process_body_line($_,0);
411
412							$partbody="$partbody$_";
413						}
414					}
415				}
416			}
417
418			# OK... We have a document in $parts
419			make_single_line($parts{'short'});
420			make_single_token($parts{'title'});
421			make_single_token($parts{'type'});
422
423			$parts{'type'}=~ s/\@//g;
424			$parts{'type'}=~ s/://g;
425
426			if($parts{'type'} eq "")
427			{
428				$parts{'type'}="generic";
429			}
430
431			$type = $parts{'type'};
432
433			$tmp = $g_prefixes{$type};
434			if($tmp eq "")
435			{
436				$tmp="doc";
437			}
438
439			$docfilename="$tmp\_$docfilename";
440
441			$zzz="keyterms";
442
443			if($parts{'keyterms'} ne "")
444			{
445				$keyterms = $parts{'keyterms'};
446				$keyterms =~ s/\n//gs;
447
448				for $term (split(/,/,$keyterms))
449				{
450					make_single_token($term);
451					if($term ne "")
452					{
453						$termx=$term;
454						$termx=~ s/([\+\(\)\?\.\:\*\|\=\;\^\!\~])/\\$1/g;
455
456						$g_keyterms{$term} = "$docfilename$g_fileextension";
457						$g_keytermsclean{$term} = "$termx";
458
459						$tmp="keyterms_$g_shortsIdx{$zzz}";
460						$g_shorts{$tmp}="$term<!>$parts{'short'}<!>$docfilename$g_fileextension";
461						#print "GOT $g_shorts{$tmp} ($tmp)";
462						$g_shortsIdx{$zzz}++;
463					}
464				}
465			}
466
467			$tmp="keyterms_$g_shortsIdx{$zzz}";
468			$g_shorts{$tmp}="$parts{'title'}<!>$parts{'short'}<!>$docfilename$g_fileextension";
469			#print "GOT $g_shorts{$tmp} ($tmp)";
470			$g_shortsIdx{$zzz}++;
471		}
472	}
473
474	close(CPPFILE);
475}
476
477
478
479sub substitute_keyterms
480{
481	my(@lines);
482	my(@tmp);
483	my($left);
484	my($right);
485	my($line);
486	my($term);
487
488	# Kinda complex keyword substitution routine
489
490
491	# For each keyterm we have
492	for $term (@g_keytermsSorted)
493	{
494		# If the doc we're scanning isn't the keyword target
495		if($_[1] ne $g_keyterms{$term})
496		{
497			$termclean=$g_keytermsclean{$term};
498
499			# If the doc matches the keyterm at least once
500			if($_[0] =~ /$termclean/)
501			{
502				$ref=$g_keyterms{$term};
503				$ref =~ s/([a-zA-Z_]*)/\L\1/g;
504
505				@tmp = split(/</,$_[0]);
506				$_[0]="";
507				$first=1;
508				$skipIt = 0;
509				for(@tmp)
510				{
511					if($skipIt)
512					{
513						if(/[A-Za-z0-9\"]>/)
514						{
515							$skipIt=0 if /^[ ]*\/a[ ]*>/;
516						}
517					}
518
519					if($skipIt)
520					{
521						$_[0]="$_[0]<$_";
522					} else {
523						if(/[A-Za-z0-9\"]>/)
524						{
525							if(/^[ ]*a[ 	][ 	]*h/)
526							{
527								$skipIt=1;
528								$first ? $_[0] .= $_ : $_[0] .= "<$_";
529							} else {
530								($left,$right) = split(/>/,$_);
531								$right=~s/([^A-Za-z0-9<>\+\-\=_])($termclean)([^A-Za-z0-9<>\+\-\=_])/$1<a href=\"$ref\">$2<\/a>$3/ig;
532								$_[0] .= "<$left>$right";
533							}
534						} else {
535							$_=~s/([^A-Za-z0-9<>\+\-\=_\.])($termclean)([^A-Za-z0-9<>\+\-\=_\.])/$1<a href=\"$ref\">$2<\/a>$3/ig;
536							$_[0] .= $_;
537						}
538						$first=0;
539					}
540				}
541			}
542		}
543	}
544}
545
546
547sub build_usage_from_kvs_syntax_line
548{
549	$_[0] =~ s/\&lt\;([A-Za-z0-9_]+):([A-Za-z0-9_]+)\&gt\;/\&lt\;\1\&gt\;/g;
550	$_[0] =~ s/\[([A-Za-z0-9_]+):([A-Za-z0-9_]+)\]/\[;\1\]/g;
551	$_[0] =~ s/^\&lt\;([A-Za-z0-9_]+)\&gt\;//g;
552}
553
554sub build_usage_from_kvs_syntax
555{
556	my @arry;
557	@arry = split('\n',$_[0]);
558	$tmp = "";
559	foreach(@arry)
560	{
561		build_usage_from_kvs_syntax_line($_);
562		if($tmp ne "")
563		{
564			$tmp = "$tmp\n$_";
565		} else {
566			$tmp = "$_";
567		}
568	}
569	return $tmp;
570}
571
572sub process_kvs_syntax_line
573{
574	$_[0] =~ s/\&lt\;([A-Za-z0-9_]+):([A-Za-z0-9_]+)\&gt\;/\&lt\;\1\<font color=\"$g_kvstypenamecolor\"\>:\2\<\/font\>\&gt\;/g;
575	$_[0] =~ s/\[([A-Za-z0-9_]+):([A-Za-z0-9_]+)\]/\[\1\<font color=\"$g_kvstypenamecolor\"\>:\2\<\/font\>\]/g;
576	$_[0] =~ s/^\&lt\;([A-Za-z0-9_]+)\&gt\;/\&lt\;\<font color=\"$g_kvstypenamecolor\"\>\1\<\/font\>\&gt\;/g;
577	$_[0] =~ s/^([A-Za-z0-9_\.]+)/\<b\>\1\<\/b\>/g;
578	$_[0] =~ s/(\$[A-Za-z0-9_\.]*)/\<b\>\1\<\/b\>/g;
579	$_[0] =~ s/\(/\<b\>\(<\/b\>/g;
580	$_[0] =~ s/\)/\<b\>\)<\/b\>/g;
581	$_[0] =~ s/\&lt\;/\<font color=\"$g_kvstypedelimiterscolor\"\>\&lt\;\<\/font\>/g;
582	$_[0] =~ s/\&gt\;/\<font color=\"$g_kvstypedelimiterscolor\"\>\&gt\;\<\/font\>/g;
583	$_[0] =~ s/\[/\<font color=\"$g_kvstypedelimiterscolor\"\>\[\<\/font\>/g;
584	$_[0] =~ s/\]/\<font color=\"$g_kvstypedelimiterscolor\"\>\]\<\/font\>/g;
585}
586
587sub process_kvs_syntax
588{
589	my @arry;
590	@arry = split('\n',$_[0]);
591	$_[0] = "";
592	foreach(@arry)
593	{
594		process_kvs_syntax_line($_);
595		if($_[0] ne "")
596		{
597			$_[0] = "$_[0]\n$_";
598		} else {
599			$_[0] = "$_";
600		}
601	}
602}
603
604
605sub process_body_line
606{
607	my($bInExample);
608
609	$bInExample = $_[1];
610
611	# Kill plain text tags
612	$_[0] =~ s/\</\&lt\;/g;
613	$_[0] =~ s/\>/\&gt\;/g;
614
615	if($bInExample)
616	{
617		# Additional processing for examples
618		if($_[0] =~ /^[	 ]*#.*/)
619		{
620			$_[0] =~ s/^(.*)(#[^\"]*)/\1\<span class=\"comment-text\">\2\<\/span\>/g;
621		} else {
622			$_[0] =~ s/([\(\)]+)/\<span class=\"example-paren\">\1\<\/span\>/g;
623			$_[0] =~ s/([\{\}]+)/\<span class=\"example-bracket\">\1\<\/span\>/g;
624			$_[0] =~ s/(%[a-zA-Z0-9_\.]+)/\<span class=\"example-variable\">\1\<\/span\>/g;
625			# Too hard to fix these
626			#$_[0] =~ s/([ ][\.\+\-\*\=]+[ ]*)/\<span class=\"example-oper\">\1\<\/span\>/g;
627			#$_[0] =~ s/(\&gt\;)/\<span class=\"example-oper\">\1\<\/span\>/g;
628			#$_[0] =~ s/(\&lt\;)/\<span class=\"example-oper\">\1\<\/span\>/g;
629		}
630		$_[0] =~ s/\n+/<br>\n/gs;
631	}
632
633	$_[0] =~ s/^				/\&nbsp\;\&nbsp\;\&nbsp\;\&nbsp\;\&nbsp\;\&nbsp\;\&nbsp\;\&nbsp\;\&nbsp\;\&nbsp\;\&nbsp\;\&nbsp\;\&nbsp\;\&nbsp\;\&nbsp\;\&nbsp\;/g;
634	$_[0] =~ s/^			/\&nbsp\;\&nbsp\;\&nbsp\;\&nbsp\;\&nbsp\;\&nbsp\;\&nbsp\;\&nbsp\;\&nbsp\;\&nbsp\;\&nbsp\;\&nbsp\;/g;
635	$_[0] =~ s/^		/\&nbsp\;\&nbsp\;\&nbsp\;\&nbsp\;\&nbsp\;\&nbsp\;\&nbsp\;\&nbsp\;/g;
636	$_[0] =~ s/^	/\&nbsp\;\&nbsp\;\&nbsp\;\&nbsp\;/g;
637
638	$_[0] =~ s/\[br\]/\<br\>/g;
639	$_[0] =~ s/\[b\]/\<b\>/g;
640	$_[0] =~ s/\[p\]/\<p\>/g;
641	$_[0] =~ s/\[\/p\]/\<\/p\>/g;
642	$_[0] =~ s/\[\/b\]/\<\/b\>/g;
643	# [big][/big] is an alias to [title][/title]
644	$_[0] =~ s/\[big\]/\<\/td\>\<\/tr\>\<tr\>\<td class=\"subtitle-table-cell\"\>\<div class=\"subtitle-text\"\>/g;
645	$_[0] =~ s/\[\/big\]/\<\/div\>\<\/td\>\<\/tr\>\<tr\>\<td bgcolor=\"$g_bodytablebgcolor\"\>/g;
646	$_[0] =~ s/\[title\]/\<\/td\>\<\/tr\>\<tr\>\<td class=\"subtitle-table-cell\"\>\<div class=\"subtitle-text\"\>/g;
647	$_[0] =~ s/\[\/title\]/\<\/div\>\<\/td\>\<\/tr\>\<tr\>\<td bgcolor=\"$g_bodytablebgcolor\"\>/g;
648	$_[0] =~ s/\[subtitle\]/\<\/td\>\<\/tr\>\<tr\>\<td class=\"subsubtitle-table-cell\"\>\<div class=\"subsubtitle-text\"\>/g;
649	$_[0] =~ s/\[\/subtitle\]/\<\/div\>\<\/td\>\<\/tr\>\<tr\>\<td bgcolor=\"$g_bodytablebgcolor\"\>/g;
650	$_[0] =~ s/\[pre\]/\<pre\>/g;
651	$_[0] =~ s/\[\/pre\]/\<\/pre\>/g;
652	$_[0] =~ s/\[center\]/\<center\>/g;
653	$_[0] =~ s/\[\/center\]/\<\/center\>/g;
654	$_[0] =~ s/\[i\]/\<i\>/g;
655	$_[0] =~ s/\[\/i\]/\<\/i\>/g;
656	$_[0] =~ s/\[ul\]/\<ul\>/g;
657	$_[0] =~ s/\[\/ul\]/\<\/ul\>/g;
658	$_[0] =~ s/\[li\]/\<li\>/g;
659	$_[0] =~ s/\[\/li\]/\<\/li\>/g;
660	$_[0] =~ s/\[table\]/\<table bgcolor=\"$g_internaltablecolor\" width=\"100\%\"\>/g;
661	$_[0] =~ s/\[\/table\]/\<\/table\>/g;
662	$_[0] =~ s/\[tr\]/\<tr\>/g;
663	$_[0] =~ s/\[\/tr\]/\<\/tr\>/g;
664	$_[0] =~ s/\[td\]/\<td\>/g;
665	$_[0] =~ s/\[\/td\]/\<\/td\>/g;
666	$_[0] =~ s/\[example\][ 	\n]*/\<\/td\>\<\/tr\>\<tr\>\<td class=\"example-box\"\>/g;
667	$_[0] =~ s/\[\/example\]/\<\/td\>\<\/tr\>\<tr\>\<td bgcolor=\"$g_bodytablebgcolor\"\>/g;
668	$_[0] =~ s/\[comment\]/<span class="comment-text">/g;
669	$_[0] =~ s/\[\/comment\]/<\/span>/g;
670
671	# The doc tag needs to include '$(*)' due to the expressioneval article
672	$_[0] =~ s/\[doc\]([a-zA-Z0-9_\$*\(\)]*)\[\/doc\]/\<a href=\"doc_\L\1\E$g_fileextension">\1\<\/a\>/g;
673	$_[0] =~ s/\[doc:([a-zA-Z0-9_]*)\]([a-zA-Z0-9_\-\&\;\.\$*\(\) ]*)\[\/doc\]/\<a href=\"doc_\L\1\E$g_fileextension"\>\2\<\/a\>/g;
674
675	$_[0] =~ s/\[cmd\]([a-zA-Z0-9_\.]*)\[\/cmd\]/\<a href=\"cmd_\L\1$g_fileextension">\1\<\/a\>/g;
676	$_[0] =~ s/\[cmd:([a-zA-Z0-9_\.]*)\]([a-zA-Z0-9_\-\&\;\. ]*)\[\/cmd\]/\<a href=\"cmd_\L\1$g_fileextension"\>\2\<\/a\>/g;
677	$_[0] =~ s/\[fnc\]\$([a-zA-Z0-9_\.]*)\[\/fnc\]/\<a href=\"fnc_\L\1$g_fileextension">\$\1\<\/a\>/g;
678	$_[0] =~ s/\[fnc\]\$([a-zA-Z0-9_\.]*)\(\)\[\/fnc\]/\<a href=\"fnc_\L\1$g_fileextension">\$\1()\<\/a\>/g;
679	$_[0] =~ s/\[fnc\]([a-zA-Z0-9_\.]*)\[\/fnc\]/\<a href=\"fnc_\L\1$g_fileextension">\$\1\<\/a\>/g;
680	$_[0] =~ s/\[fnc:\$([a-zA-Z0-9_\.]*)\]\$([\$a-zA-Z0-9_\-\&\;\. ]*)\[\/fnc\]/\<a href=\"fnc_\L\1$g_fileextension"\>\$\2\<\/a\>/g;
681	$_[0] =~ s/\[event\]\$([a-zA-Z0-9_]*)\[\/event\]/\<a href=\"event_\L\1$g_fileextension">\$\1\<\/a\>/g;
682	$_[0] =~ s/\[event:([a-zA-Z0-9_]*)\]([a-zA-Z0-9_]*)\[\/event\]/\<a href=\"event_\L\1$g_fileextension">\2\<\/a\>/g;
683	$_[0] =~ s/\[class\]([a-zA-Z0-9_]*)\[\/class\]/\<a href=\"class_\L\1$g_fileextension">\1\<\/a\>/g;
684	$_[0] =~ s/\[class:([a-zA-Z0-9_]*)\]([a-zA-Z0-9_ ]*)\[\/class\]/\<a href=\"class_\L\1$g_fileextension">\2\<\/a\>/g;
685	$_[0] =~ s/\[module:([a-zA-Z0-9_]*)\]([a-zA-Z0-9_ ]*)\[\/module\]/\<a href=\"module_\L\1$g_fileextension">\2\<\/a\>/g;
686	$_[0] =~ s/\[widget:([a-zA-Z0-9_]*)\]([a-zA-Z0-9_ ]*)\[\/widget\]/\<a href=\"widget_\L\1$g_fileextension">\2\<\/a\>/g;
687	$_[0] =~ s/\[classfnc:([a-zA-Z0-9_]*)\]\$([a-zA-Z0-9_]*)\[\/classfnc\]/\<a href=\"class_\L\1$g_fileextension#\2">\$\2\<\/a\>/g;
688	$_[0] =~ s/\[classfnc\]\$([a-zA-Z0-9_]*)\[\/classfnc\]/\<a href=\"#\1">\$\1\<\/a\>/g;
689	$_[0] =~ s/\[classsignal:([a-zA-Z0-9_]*)\]([a-zA-Z0-9_]*)\[\/classsignal\]/\<a href=\"class_\L\1$g_fileextension#\2">\2\<\/a\>/g;
690	$_[0] =~ s/\[classsignal\]([a-zA-Z0-9_]*)\[\/classsignal\]/\<a href=\"#\L\1">\1\<\/a\>/g;
691	$_[0] =~ s/\[anchorlink:([^\]]*)\]/\<a href=\"\1"\>/g;
692	$_[0] =~ s/\[\/anchorlink\]/\<\/a\>/g;
693	$_[0] =~ s/\[anchor:([a-zA-Z0-9_]*)\]/\<a name=\"\1"\>/g;
694	$_[0] =~ s/\[\/anchor\]/\<\/a\>/g;
695	$_[0] =~ s/\[note\][ 	\n]*/\<\/td\>\<\/tr\>\<tr\>\<td class=\"note-box\"\>/g;
696	$_[0] =~ s/\[\/note\]/\<\/td\>\<\/tr\>\<tr\>\<td bgcolor=\"$g_bodytablebgcolor\"\>/g;
697
698
699}
700
701
702sub process_file
703{
704	my($docfilename);
705	my(%parts);
706	my($part); # Part title
707	my($partbody);
708	my($tabblock);
709	my($tmp);
710	my($type);
711	my($iExampleState);
712	my($szExampleTabBlock);
713
714
715	if(!open(CPPFILE,"$_[0]"))
716	{
717		return;
718	}
719	# Process the entire file
720
721	$iExampleState = 0;
722
723	while(<CPPFILE>)
724	{
725		if(/^[ 	]*\@doc:[ 	a-z_]*/)
726		{
727			# Process a single document block
728
729			$docfilename="$_";
730			$docfilename=~ s/[ 	]*//g;
731			$docfilename=~ s/\@doc://g;
732			$docfilename=~ s/\n//g;
733			$docfilename=~ s/([a-zA-Z_]*)/\L\1/g;
734
735			undef %parts;
736			$part = "";
737
738			INNERLOOP: while(<CPPFILE>)
739			{
740
741				if(/^[	 ]*\*\/[ 	]*/)
742				{
743					# End of comment
744					if(($part ne "") && ($partbody ne "") && ($partbody ne "\n"))
745					{
746						# We have an entire part to store
747						$parts{$part}="$partbody";
748					}
749					last INNERLOOP;
750				} else {
751					# Inside a part
752					if(/^[	 ]*\@[a-z]*:[	 ]*/)
753					{
754						# A part title
755						if(($part ne "") && ($partbody ne "") && ($partbody ne "\n"))
756						{
757							# We have an entire part to store
758							$parts{$part}="$partbody";
759						}
760						# Start of the part
761						# Extract the title
762						$part="$_";
763						$part=~ s/[	 ]*//g;
764						$part=~ s/\@//g;
765						$part=~ s/://g;
766						$part=~ s/\n//g;
767						# Clear the body (begin)
768						$partbody="";
769						$iExampleState = 0;
770					} else {
771						# Somewhere in a part body
772						if(($_ ne "") && ($_ ne "\n"))
773						{
774							if($partbody eq "")
775							{
776								# If it is the first line of the part body
777								# Extract the amount of tabs that the part has
778								# We will use it to remove the C++ indentation
779								$tabblock = "$_";
780								$tabblock =~ s/^([	]*).*/\1/g;
781								$tabblock =~ s/\n//g;
782							}
783
784							if($tabblock ne "")
785							{
786								# If we have the initial tabblock , remove it from the line (remove indentation)
787								$_ =~ s/^$tabblock//g;
788							}
789
790							# Process example code blocks
791							if($iExampleState eq 0)
792							{
793								if(($_ =~ /\[(example|pre)\]*/) && (!($_ =~ /\[\/(example|pre)\]*/)))
794								{
795									$iExampleState = 1;
796									$szExampleTabBlock = "";
797								}
798							} else {
799								if($szExampleTabBlock ne "")
800								{
801									# If we have the initial tabblock , remove it from the line (remove indentation)
802									$_ =~ s/^$szExampleTabBlock//g;
803								}
804
805								if(($_ =~ /\[\/(example|pre)\]*/))
806								{
807									$iExampleState = 0;
808								} else {
809									if($iExampleState eq 1)
810									{
811										$iExampleState = 2;
812										$szExampleTabBlock = "$_";
813										$szExampleTabBlock =~ s/^([	]*).*/\1/g;
814										$szExampleTabBlock =~ s/\n//g;
815
816										if($szExampleTabBlock ne "")
817										{
818											# If we have the initial tabblock , remove it from the line (remove indentation)
819											$_ =~ s/^$szExampleTabBlock//g;
820										}
821									}
822								}
823							}
824
825							process_body_line($_,$iExampleState);
826
827
828							$partbody="$partbody$_";
829						}
830					}
831				}
832			}
833
834			# OK... We have a document in $parts
835			# Process the title
836			if($parts{'title'} eq "")
837			{
838				print "\n ($_[0]) Warning: no title specified for $docfilename\n";
839				$parts{'title'}="No title specified";
840			}
841
842			make_single_token($parts{'title'});
843			if($parts{'syntax'} ne "")
844			{
845				if($parts{'usage'} eq "")
846				{
847					$parts{'usage'} = build_usage_from_kvs_syntax($parts{'syntax'})
848				}
849			}
850
851			make_syntax($parts{'usage'});
852			make_syntax($parts{'syntax'});
853			make_single_line($parts{'parameters'});
854			make_single_line($parts{'inherits'});
855			make_single_token($parts{'short'});
856			make_single_token($parts{'window'});
857			make_single_token($parts{'type'});
858
859			$parts{'type'}=~ s/\@//g;
860			$parts{'type'}=~ s/://g;
861
862			if($parts{'type'} eq "")
863			{
864				$parts{'type'}="generic";
865			}
866
867			$type = $parts{'type'};
868
869			$tmp = $g_prefixes{$type};
870			if($tmp eq "")
871			{
872				$tmp="doc";
873			}
874			$docfilename="$tmp\_$docfilename";
875
876			if($g_shortsIdx{$type} eq "")
877			{
878				$g_shortsIdx{$type} = 0;
879			}
880
881			$tmp="$type\_$g_shortsIdx{$type}";
882			$g_shorts{$tmp}="$parts{'title'}<!>$parts{'short'}<!>$docfilename$g_fileextension";
883			#print "$tmp, $g_shorts{$tmp}\n";
884			$g_shortsIdx{$type}++;
885
886			# Keyterms substitution is confusing. Better to rely on manual linking only.
887
888			#if($parts{'body'} ne "")
889			#{
890			#	substitute_keyterms($parts{'body'},"$docfilename$g_fileextension");
891			#}
892			#if($parts{'description'} ne "")
893			#{
894			#	substitute_keyterms($parts{'description'},"$docfilename$g_fileextension");
895			#}
896			#if($parts{'switches'} ne "")
897			#{
898			#	substitute_keyterms($parts{'switches'},"$docfilename$g_fileextension");
899			#}
900
901			use File::Path;
902			mkpath("$g_directory");
903			if(open(DOCFILE,">$g_directory/$docfilename$g_fileextension"))
904			{
905				$g_filehandle=DOCFILE;
906
907				print_header($parts{'title'});
908				print_tablestart();
909
910				print_title($parts{'title'},$parts{'short'});
911
912				if($parts{'syntax'} ne "")
913				{
914					process_kvs_syntax($parts{'syntax'});
915					print_entry("Usage","<div class='syntax-text'>$parts{'syntax'}</div>");
916				} else {
917					if($parts{'usage'} ne "")
918					{
919						print_entry("Usage","<div class='syntax-text'>$parts{'usage'}</div>");
920					}
921				}
922
923				if($parts{'parameters'} ne "")
924				{
925					print_entry("Parameters","<font color=\"$g_syntaxcolor\"><pre><code>$parts{'parameters'}</code></pre></font>");
926				}
927
928				print_entry("Inherits","$parts{'inherits'}");
929				print_entry("Window","$parts{'window'}");
930				print_entry("","$parts{'body'}");
931				print_entry("Description","$parts{'description'}");
932
933				if($parts{'switches'} ne "")
934				{
935					print_subtitle("Switches");
936
937					print DOCFILE "  <tr bgcolor=\"$g_bodytablebgcolor\">\n";
938					print DOCFILE "    <td>\n";
939					print DOCFILE "      <table class=\"switch-table\">\n";
940
941					@lines = split("\n","$parts{'switches'}");
942					$swbody = "";
943					for(@lines)
944					{
945						if(/!sw:.*/)
946						{
947							if("$swbody" ne "")
948							{
949								print DOCFILE "<tr><td class=\"switch-body-table-cell\">$swbody</td></tr>\n";
950								$swbody = "";
951							}
952							$_ =~ s/!sw:[ 	]*//g;
953							$_ =~ s/^[	 ]*//g;
954							$_ =~ s/\n//gs;
955							$tmp = $_;
956							$tmp =~ s/\(.*\)//g;
957							$tmp =~ s/\$//g;
958							print DOCFILE "<tr><td class=\"switch-title-table-cell\">$_</td></tr>\n";
959						} else {
960							if($swbody ne "")
961							{
962								$swbody="$swbody $_";
963							} else {
964								$swbody="$_";
965							}
966						}
967
968					}
969					if("$swbody" ne "")
970					{
971						print DOCFILE "<tr><td>$swbody</td></tr>\n";
972					}
973
974					print DOCFILE "      </table>\n";
975					print DOCFILE "    </td>\n";
976					print DOCFILE "  </tr>\n";
977				}
978
979
980				if($parts{'functions'} ne "")
981				{
982					print_subtitle("Functions");
983
984					print DOCFILE "  <tr bgcolor=\"$g_bodytablebgcolor\">\n";
985					print DOCFILE "    <td>\n";
986					print DOCFILE "      <table bgcolor=\"$g_classfncbodytablecolor\">\n";
987
988					@lines = split("\n","$parts{'functions'}");
989					$fncbody = "";
990					for(@lines)
991					{
992						if(/!fn:.*/)
993						{
994							if("$fncbody" ne "")
995							{
996								print DOCFILE "<tr><td>$fncbody</td></tr>\n";
997								$fncbody = "";
998							}
999							$_ =~ s/!fn:[ 	]*//g;
1000							$_ =~ s/^[	 ]*//g;
1001							$_ =~ s/\n//gs;
1002							$tmp = $_;
1003							$tmp =~ s/\(.*\)//g;
1004							$tmp =~ s/\$//g;
1005							print DOCFILE "<tr bgcolor=\"$g_classfnctablecolor\"><td><code><b><font color=\"$g_examplecolor\"><a name=\"$tmp\">$_</a></font></b></code></td></tr>\n";
1006						} else {
1007							if($fncbody ne "")
1008							{
1009								$fncbody="$fncbody $_";
1010							} else {
1011								$fncbody="$_";
1012							}
1013						}
1014
1015					}
1016					if("$fncbody" ne "")
1017					{
1018						print DOCFILE "<tr><td>$fncbody</td></tr>\n";
1019					}
1020
1021					print DOCFILE "      </table>\n";
1022					print DOCFILE "    </td>\n";
1023					print DOCFILE "  </tr>\n";
1024				}
1025
1026				if($parts{'signals'} ne "")
1027				{
1028					print_subtitle("Signals");
1029
1030					print DOCFILE "  <tr bgcolor=\"$g_bodytablebgcolor\">\n";
1031					print DOCFILE "    <td>\n";
1032					print DOCFILE "      <table bgcolor=\"$g_classfncbodytablecolor\">\n";
1033
1034					@lines = split("\n","$parts{'signals'}");
1035					$sigbody = "";
1036					for(@lines)
1037					{
1038						if(/!sg:.*/)
1039						{
1040							if("$sigbody" ne "")
1041							{
1042								print DOCFILE "<tr><td>$sigbody</td></tr>\n";
1043								$sigbody = "";
1044							}
1045							$_ =~ s/!sg:[ 	]*//g;
1046							$_ =~ s/^[	 ]*//g;
1047							$_ =~ s/\n//gs;
1048							$tmp = $_;
1049							$tmp =~ s/\(.*\)//g;
1050							$tmp =~ s/\$//g;
1051							print DOCFILE "<tr bgcolor=\"$g_classfnctablecolor\"><td><code><b><font color=\"$g_examplecolor\"><a name=\"$tmp\">$_</a></font></b></code></td></tr>\n";
1052						} else {
1053							if($sigbody ne "")
1054							{
1055								$sigbody="$sigbody $_";
1056							} else {
1057								$sigbody="$_";
1058							}
1059						}
1060
1061					}
1062					if("$sigbody" ne "")
1063					{
1064						print DOCFILE "<tr><td>$sigbody</td></tr>\n";
1065					}
1066
1067					print DOCFILE "      </table>\n";
1068					print DOCFILE "    </td>\n";
1069					print DOCFILE "  </tr>\n";
1070				}
1071
1072				print_entry("Examples","$parts{'examples'}");
1073				print_entry("See also","$parts{'seealso'}");
1074				print_tableend();
1075
1076
1077				if($parts{'type'} eq "command")
1078				{
1079					print DOCFILE "<hr><a href=\"index$g_fileextension\">Index</a>, <a href=\"doc_command_alphabetic_a$g_fileextension\">Commands</a>\n";
1080				} elsif($parts{'type'} eq "function")
1081				{
1082					print DOCFILE "<hr><a href=\"index$g_fileextension\">Index</a>, <a href=\"doc_function_alphabetic_a$g_fileextension\">Functions</a>\n";
1083				} elsif($parts{'type'} eq "event")
1084				{
1085					print DOCFILE "<hr><a href=\"index$g_fileextension\">Index</a>, <a href=\"doc_event_alphabetic_a$g_fileextension\">Events</a>\n";
1086				} elsif($parts{'type'} eq "generic")
1087				{
1088					print DOCFILE "<hr><a href=\"index$g_fileextension\">Index</a>, <a href=\"doc_generic_index_all$g_fileextension\">Miscellaneous</a>\n";
1089				} elsif($parts{'type'} eq "language")
1090				{
1091					print DOCFILE "<hr><a href=\"index$g_fileextension\">Index</a>, <a href=\"doc_language_index_all$g_fileextension\">Language Overview</a>\n";
1092				} elsif($parts{'type'} eq "class")
1093				{
1094					print DOCFILE "<hr><a href=\"index$g_fileextension\">Index</a>, <a href=\"doc_class_index_all$g_fileextension\">Object Classes</a>\n";
1095				} elsif($parts{'type'} eq "module")
1096				{
1097					print DOCFILE "<hr><a href=\"index$g_fileextension\">Index</a>, <a href=\"doc_module_index_all$g_fileextension\">Modules</a>\n";
1098				} elsif($parts{'type'} eq "widget")
1099				{
1100					print DOCFILE "<hr><a href=\"index$g_fileextension\">Index</a>, <a href=\"doc_widget_index_all$g_fileextension\">Features</a>\n";
1101				}
1102
1103				print_footer(DOCFILE);
1104
1105				close(DOCFILE);
1106			} else { print "Can't open $g_directory/$docfilename$g_fileextension for writing\n"; }
1107		}
1108	}
1109
1110	close(CPPFILE);
1111}
1112
1113
1114#################################################################################################
1115# COMMAND/FUNCTION.... INDEXES
1116#################################################################################################
1117
1118sub generate_indexes
1119{
1120	my(@oldCommands);
1121	my(@commands);
1122	my(@sortedCommands);
1123	my(@chars);
1124	my($alllinks);
1125	my($upcase);
1126	my($count);
1127
1128	my($doctitle);
1129	my($category);
1130	my($number);
1131
1132	$doctitle = $_[0];
1133	$category = $_[1];
1134	$number = $_[2];
1135
1136	#print("Generating indexes for $doctitle $category $number\n");
1137
1138	######################################################
1139	# generate some helper stuff (alphabetic index links)
1140
1141	@chars=("\$","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z");
1142
1143	$i = 0;
1144
1145	$alllinks="<table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\"><tr>";
1146
1147	for(@chars)
1148	{
1149		$alllinks = "$alllinks <td><a href=\"doc_$category\_alphabetic_$_$g_fileextension\">$_</a></td>\n";
1150		$i++;
1151		if($i > 13)
1152		{
1153			$i = 0;
1154			$alllinks = "$alllinks</tr><tr>\n";
1155		}
1156	}
1157
1158	$alllinks ="$alllinks <td><a href=\"doc_$category\_index_all$g_fileextension\">All</a></td></tr></table>";
1159
1160	#####################################
1161	# Simple plain long index
1162
1163	$i=0;
1164
1165	undef %terms;
1166
1167	while($i < $g_shortsIdx{$category})
1168	{
1169		$tmp="$category\_$i";
1170		($cmd,$short,$link) = split("<!>",$g_shorts{$tmp});
1171		$terms{$cmd} = "1";
1172		$commands[$i]=$g_shorts{$tmp};
1173		$commands[$i] =~ s/\n//g;
1174		$i++;
1175	}
1176
1177	#####################################
1178	# Load the other terms from the db (if there)
1179	# Make sure that we do not overwrite the current entries
1180	if(open(OLDDB,"$g_directory/_db_$category.idx"))
1181	{
1182		while(<OLDDB>)
1183		{
1184			$_ =~ s/\n//g;
1185			if($_ ne "")
1186			{
1187				($cmd,$short,$link) = split("<!>",$_);
1188				if($terms{$cmd} ne "1")
1189				{
1190					$terms{$cmd} = "1";
1191					$commands[$i]=$_;
1192					$i++;
1193				}
1194			}
1195		}
1196		close(OLDDB);
1197	}
1198
1199	$count = $i;
1200
1201
1202	#####################################
1203	# Re-dump them
1204	if(open(OLDDB,"> $g_directory/_db_$category.idx"))
1205	{
1206		$i = 0;
1207		while($i < $count)
1208		{
1209			print OLDDB "$commands[$i]\n";
1210			$i++;
1211		}
1212		close(OLDDB);
1213	}
1214
1215	@sortedCommands = sort @commands;
1216
1217	if(open(CMDINDEX,">$g_directory/doc_$category\_index_all$g_fileextension"))
1218	{
1219		$g_filehandle=CMDINDEX;
1220
1221		print_header("$doctitle: All");
1222		print_tablestart();
1223		print_title("$doctitle: All","");
1224		print_tableend();
1225
1226		print_tablestart();
1227		print_body($alllinks);
1228		print_tableend();
1229
1230		print_tablestart();
1231
1232		$i=0;
1233
1234		while($i < $count)
1235		{
1236			($cmd,$short,$link) = split("<!>",$sortedCommands[$i]);
1237			$link =~ s/([a-zA-Z_]*)/\L\1/g;
1238			print_twocolumnbody("<a href=\"$link\">$cmd</a>",$short);
1239			$i++;
1240		}
1241
1242		print_tableend();
1243
1244		print_tablestart();
1245		print_body($alllinks);
1246		print_tableend();
1247
1248		print_footer();
1249
1250		close(CMDINDEX);
1251	} else {
1252		print "Can't open $g_directory/doc_$category\_index_all$g_fileextension for writing\n";
1253	}
1254
1255
1256	#######################
1257	# Alphabetic
1258
1259	for(@chars)
1260	{
1261		if(open(CMDINDEX,">$g_directory/doc_$category\_alphabetic_$_$g_fileextension"))
1262		{
1263
1264			$upcase=$_;
1265			$upcase=~ tr/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/;
1266
1267
1268			$g_filehandle=CMDINDEX;
1269
1270			print_header("$doctitle: $_");
1271			print_tablestart();
1272			print_title("$doctitle: $_","");
1273			print_tableend();
1274
1275			print_tablestart();
1276			print_body($alllinks);
1277			print_tableend();
1278
1279			print_tablestart();
1280
1281			$i=0;
1282			$j=0;
1283			if($number > 0)
1284			{
1285				#print("NUMBER > 0,COUNT = $count\n");
1286				while($i < $count)
1287				{
1288					($cmd,$short,$link) = split("<!>",$sortedCommands[$i]);
1289					#$left=substr($cmd,0,$number);
1290					#$right=$cmd;
1291					#$right=~ s/^$left//;
1292					$left = substr($cmd,0,$number);
1293					$right = substr($cmd,$number);
1294					$link =~ s/([a-zA-Z_]*)/\L\1/g;
1295
1296
1297					#print("RIGHT=$right,_=$_,LEFT=$left,UPCASE=$upcase\n");
1298
1299					if(($right =~ /^$_/) or ($right =~ /^$upcase/) or ($right eq $_))
1300					{
1301						$j++;
1302						print_twocolumnbody("<a href=\"$link\">$left$right</a>",$short);
1303					}
1304					$i++;
1305				}
1306
1307			} else {
1308				#print("NUMBER == 0,COUNT = $count\n");
1309				while($i < $count)
1310				{
1311					($cmd,$short,$link) = split("<!>",$sortedCommands[$i]);
1312					$link =~ s/([a-zA-Z_]*)/\L\1/g;
1313					if(($cmd =~ /^$_/) || ($cmd =~ /^$upcase/))
1314					{
1315						$j++;
1316						print_twocolumnbody("<a href=\"$link\">$cmd</a>",$short);
1317					}
1318					$i++;
1319				}
1320			}
1321
1322			if($j == 0)
1323			{
1324				print_body("No matches");
1325			}
1326
1327			print_tableend();
1328
1329			print_tablestart();
1330			print_body($alllinks);
1331			print_tableend();
1332
1333			print_footer();
1334
1335			close(CMDINDEX);
1336		} else {
1337			print "Can't open $g_directory/doc_$category\_alphabetic_$_$g_fileextension for writing\n";
1338		}
1339	}
1340}
1341
1342#################################################################################################
1343# MAIN
1344#################################################################################################
1345
1346# Force flushing of STDOUT
1347$|=1;
1348
1349# print "--\n";
1350# print "-- Generating documentation, this may take a while :)\n";
1351# print "--\n";
1352# print "-- Extracting keyterms\n";
1353# Extract the keywords to generate the cross-references
1354$i = 0;
1355$g_numFilesToProcess = @g_filesToProcess;
1356
1357use integer;
1358while($g_filesToProcess[$i] ne "")
1359{
1360	if(($i%($g_numFilesToProcess/10)) == 10)
1361	{
1362		# pad numbers
1363		$num = $i*40/$g_numFilesToProcess;
1364		if($num<10) { $num = " $num"; }
1365		print "[ $num%] Generating documentation: Extracting keyterms (pass 1 of 3)\n";
1366	}
1367	extract_keyterms($g_filesToProcess[$i]);
1368	$i++;
1369}
1370print "[ 40%] Generating documentation: Extracting keyterms (pass 1 of 3)\n";
1371$g_files=$i - 1;
1372
1373# print "\n";
1374# print "-- Extracting documents and generating cross-references\n";
1375
1376# Sort them
1377@g_keytermsSorted = sort {length($b) <=> length($a)} keys(%g_keyterms);
1378
1379# Process the files now
1380$i = 0;
1381
1382while($g_filesToProcess[$i] ne "")
1383{
1384	if(($i%($g_numFilesToProcess/10)) == 10)
1385	{
1386		# pad numbers
1387		$num = 40+($i*40/$g_numFilesToProcess);
1388		if($num<10) { $num = " $num"; }
1389		print "[ $num%] Generating documentation: Extracting documents (pass 2 of 3)\n";
1390	}
1391
1392	process_file($g_filesToProcess[$i]);
1393	$i++;
1394}
1395print "[ 80%] Generating documentation: Extracting documents (pass 2 of 3)\n";
1396# print "\n";
1397# print "-- Generating indexes\n";
1398
1399print "[ 82%] Generating documentation: Creating indexes (pass 3 of 3)\n";
1400generate_indexes("Commands","command",0);
1401print "[ 84%] Generating documentation: Creating indexes (pass 3 of 3)\n";
1402generate_indexes("Functions","function",1);
1403print "[ 86%] Generating documentation: Creating indexes (pass 3 of 3)\n";
1404generate_indexes("Modules","module",0);
1405print "[ 88%] Generating documentation: Creating indexes (pass 3 of 3)\n";
1406generate_indexes("Classes","class",0);
1407print "[ 90%] Generating documentation: Creating indexes (pass 3 of 3)\n";
1408generate_indexes("Events","event",2);
1409print "[ 92%] Generating documentation: Creating indexes (pass 3 of 3)\n";
1410generate_indexes("Language Documentation","language",0);
1411print "[ 94%] Generating documentation: Creating indexes (pass 3 of 3)\n";
1412generate_indexes("Features","widget",0);
1413print "[ 96%] Generating documentation: Creating indexes (pass 3 of 3)\n";
1414generate_indexes("Misc. Documentation","generic",0);
1415print "[ 98%] Generating documentation: Creating indexes (pass 3 of 3)\n";
1416generate_indexes("Keyterms & Concepts","keyterms",0);
1417print "[100%] Generating documentation: Creating indexes (pass 3 of 3)\n";
1418
1419if(open(DOCINDEX,">$g_directory/index$g_fileextension"))
1420{
1421	$g_filehandle=DOCINDEX;
1422	print_header("Documentation Index");
1423	print_tablestart();
1424	print_twocolumntitle("Index","");
1425	print_twocolumnsubtitle("Fundamentals");
1426	print_twocolumnbody("<a href=\"doc_ircintro$g_fileextension\">Introduction to IRC</a>","A \"must read\" for beginners");
1427	print_twocolumnbody("<a href=\"doc_kvircintro$g_fileextension\">Introduction to KVIrc</a>","A couple of words about KVIrc");
1428
1429	print_twocolumnsubtitle("Scripting Concepts: The KVS Manual");
1430	print_twocolumnbody("<a href=\"doc_kvs_introduction$g_fileextension\">Introduction to KVS</a>","Introduction to the KVIrc Scripting Language");
1431	print_twocolumnbody("<a href=\"doc_kvs_basicconcepts$g_fileextension\">Basic KVS Concepts</a>","The first steps in the KVS world");
1432	print_twocolumnbody("<a href=\"doc_kvs_aliasesandfunctions$g_fileextension\">Aliases and Functions</a>","How to write aliases/functions");
1433	print_twocolumnbody("<a href=\"doc_kvs_datatypes$g_fileextension\">Variables</a>","Which types of variables are available and how to handle them");
1434	print_twocolumnbody("<a href=\"doc_operators$g_fileextension\">Operators</a>","Describes simple operations with variables");
1435	print_twocolumnbody("<a href=\"doc_events$g_fileextension\">Events</a>","How to handle network events in KVS");
1436	print_twocolumnbody("<a href=\"doc_objects$g_fileextension\">Objects</a>","Object oriented scripting");
1437	print_twocolumnbody("<a href=\"doc_kvs_addons$g_fileextension\">Addons</a>","How to write nice addons for KVIrc");
1438	print_twocolumnbody("<a href=\"doc_kvs_codingtips$g_fileextension\">Coding Tips</a>","Some tips that may help you");
1439	print_twocolumnbody("<a href=\"doc_language_index_all$g_fileextension\">All the language documents</a>","All the documents related to KVS");
1440
1441	print_twocolumnsubtitle("Scripting Reference");
1442	print_twocolumnbody("<a href=\"doc_command_alphabetic_a$g_fileextension\">Commands</a>","The listing of available commands");
1443	print_twocolumnbody("<a href=\"doc_function_alphabetic_a$g_fileextension\">Functions</a>","The listing of available functions");
1444	print_twocolumnbody("<a href=\"doc_event_alphabetic_a$g_fileextension\">Events</a>","The listing of available events");
1445	print_twocolumnbody("<a href=\"doc_class_index_all$g_fileextension\">Object Classes</a>","The listing of available object classes");
1446	print_twocolumnsubtitle("Other Documents");
1447	print_twocolumnbody("<a href=\"doc_keyboard$g_fileextension\">Keyboard shortcuts</a>","Map of the global keyboard shortcuts");
1448	print_twocolumnbody("<a href=\"doc_module_index_all$g_fileextension\">Modules</a>","Documentation related to specific modules");
1449	# print_twocolumnbody("<a href=\"doc_widget_index_all$g_fileextension\">Features</a>","Documentation on features of KVIrc");
1450	print_twocolumnbody("<a href=\"doc_generic_index_all$g_fileextension\">Miscellaneous</a>","Misc documentation that didn't find any other place");
1451	print_twocolumnbody("<a href=\"doc_keyterms_index_all$g_fileextension\">Keyterms</a>","The (long) listing of all the keyterms");
1452	print_tableend();
1453	print_footer();
1454
1455	close(DOCINDEX);
1456} else {
1457	print "Can't open $g_directory/index$g_fileextension for writing\n";
1458}
1459
1460if(open(NOHELP,">$g_directory/nohelpavailable$g_fileextension"))
1461{
1462	$g_filehandle=NOHELP;
1463	print_header("No help available");
1464
1465	print_tablestart();
1466	print_title("No help available","");
1467	print_tableend();
1468
1469	print $g_filehandle "<h3>Sorry :(<br>Unfortunately there is no documentation related to the item you have selected</h3><br>\n";
1470	print $g_filehandle "Please try a different search term or take a look at the <a href=\"index$g_fileextension\">documentation index</a> ";
1471	print $g_filehandle "and try to locate the topic manually.<br><br>";
1472	print_footer();
1473	close(NOHELP);
1474} else {
1475	printf "Can't open $g_directory/nohelpavailable$g_fileextension for writing\n";
1476}
1477
1478if(open(TAG,">$g_directory/documentation.$g_version.tag"))
1479{
1480	print TAG "dummy\n";
1481	close(TAG);
1482} else {
1483	printf "Can't open $g_directory/documentation.$g_version.tag for writing\n";
1484}
1485
1486
1487# print "\n";
1488# print "--\n";
1489# print "-- Done! (Processed $g_files files)\n";
1490# print "--\n";
1491