1#!/usr/bin/perl
2
3# Process theme XML files, to generate C++ code
4#
5# This license applies only to this file:
6#
7# Copyright (c) 2014 ruben2020
8# Permission is hereby granted, free of charge, to any person obtaining a copy
9# of this software and associated documentation files (the "Software"), to
10# deal in the Software without restriction, including without limitation the
11# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
12# sell copies of the Software, and to permit persons to whom the Software is
13# furnished to do so, subject to the following conditions:
14#
15# The above copyright notice and this permission notice shall be included in
16# all copies or substantial portions of the Software.
17#
18# THE SOTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
24# IN THE SOFTWARE.
25#
26
27use strict;
28
29use XML::LibXML;
30
31my $debug = 0;
32
33my $themelist;
34my $numOfThemes = 0;
35my $lexstyle;
36
37my $cppstyle;
38my $javastyle;
39my $pythonstyle;
40my $rubystyle;
41my $javascriptstyle;
42
43my $langname;
44my $langdesc;
45my $themename;
46my $themename2;
47my @themes;
48my $defaultbgcolor;
49my $defaultfgcolor;
50my $defaultfontstyle;
51my $currentlinebgcolor;
52my $linenumfgcolor;
53my $stylename;
54my $styleid;
55my $fgcolor;
56my $bgcolor;
57my $fontstyle;
58
59my %acceptedlang =
60(
61	'C++' => 'cpp',
62	'Java' => 'java',
63	'Python' => 'python',
64	'Ruby' => 'ruby',
65	'Javascript' => 'javascript'
66);
67
68my $filename;
69my $parser;
70my $xmldoc;
71
72$themelist .= "static const char* themelist[] = {\n";
73
74$cppstyle .= "static const langstyle cppstyle[] = {\n";
75$javastyle .= "static const langstyle javastyle[] = {\n";
76$pythonstyle .= "static const langstyle pythonstyle[] = {\n";
77$rubystyle .= "static const langstyle rubystyle[] = {\n";
78$javascriptstyle .= "static const langstyle javascriptstyle[] = {\n";
79
80opendir(DIR1, '.');
81while($filename = readdir(DIR1))
82{
83	$themename = '';
84	if ((-f $filename )&&($filename =~ /\.xml$/i))
85	{
86		$themename = $filename;
87		$themename =~ s/\.xml$//i;
88		$themename2 = $themename;
89		$themename2 =~ s/_/ /g;
90		print "\n ==> $themename\n" if ($debug);
91		push @themes, $themename2;
92		processfile();
93		$numOfThemes++;
94	}
95}
96close(DIR1);
97@themes = sort {lc $a cmp lc $b} @themes;
98foreach my $them(@themes)
99{
100	$themelist .= "\t\"$them\",\n";
101}
102$themelist .= "};\n\n";
103
104
105$cppstyle          .= "\t{ NULL, NULL, NULL, 0 }\n};\n\n";
106$javastyle         .= "\t{ NULL, NULL, NULL, 0 }\n};\n\n";
107$pythonstyle       .= "\t{ NULL, NULL, NULL, 0 }\n};\n\n";
108$rubystyle         .= "\t{ NULL, NULL, NULL, 0 }\n};\n\n";
109$javascriptstyle   .= "\t{ NULL, NULL, NULL, 0 }\n};\n\n";
110open(FILO,">themes_gen.cpp");
111print FILO "\n /* THIS FILE WAS AUTO_GENERATED USING parse_themes.pl */";
112print FILO "\n /* DO NOT CHANGE BY HAND                              */\n\n";
113print FILO "#define NUM_OF_THEMES   $numOfThemes\n\n";
114print FILO $themelist;
115print FILO $lexstyle."\n";
116print FILO $cppstyle;
117print FILO $javastyle;
118print FILO $pythonstyle;
119print FILO $rubystyle;
120print FILO $javascriptstyle;
121close(FILO);
122
123################################################
124sub processfile
125{
126
127$parser = XML::LibXML->new();
128$xmldoc = $parser->parse_file($filename);
129my $lstyle;
130my $numofstyles=0;
131my $numofglobalstyles=0;
132$currentlinebgcolor = '';
133$linenumfgcolor = '';
134
135foreach my $sample ( $xmldoc->findnodes('/NotepadPlus/GlobalStyles') )
136{
137	$lexstyle .= "\nstatic const lexstyle global_".$themename."[] = {\n";
138	$defaultbgcolor = '';
139	$defaultfgcolor = '';
140	$defaultfontstyle = '';
141	$numofglobalstyles = 0;
142	foreach my $child ( $sample->getChildnodes )
143	{
144		if (( $child->nodeType() == XML_ELEMENT_NODE )&&($child->nodeName() eq 'WidgetStyle'))
145		{
146			$stylename = '';
147			$styleid = '';
148			$fgcolor = '';
149			$bgcolor = '';
150			$fontstyle = '';
151			$stylename = $child->getAttribute('name') if ($child->hasAttribute('name'));
152			$styleid = $child->getAttribute('styleID') if ($child->hasAttribute('styleID'));
153			$fgcolor = $child->getAttribute('fgColor') if ($child->hasAttribute('fgColor'));
154			$bgcolor = $child->getAttribute('bgColor') if ($child->hasAttribute('bgColor'));
155			$fontstyle = $child->getAttribute('fontStyle') if ($child->hasAttribute('fontStyle'));
156			if ($stylename eq 'Current line background colour') {$currentlinebgcolor = $bgcolor;}
157			if ($styleid eq '33') {$linenumfgcolor = $fgcolor;}
158			if ($styleid eq '0') {next;}
159			$defaultbgcolor = $bgcolor if ($stylename eq 'Default Style');
160			$defaultfgcolor = $fgcolor if ($stylename eq 'Default Style');
161			$defaultfontstyle = $fontstyle if ($stylename eq 'Default Style');
162			$defaultfontstyle = "0" if (length($defaultfontstyle) == 0);
163			$bgcolor = $defaultbgcolor if (length($bgcolor) == 0);
164			$fgcolor = $defaultfgcolor if (length($fgcolor) == 0);
165			$fontstyle = $defaultfontstyle if (length($fontstyle) == 0);
166			print "$stylename, $styleid, $fgcolor, $bgcolor, $fontstyle\n" if ($debug);
167			$lexstyle .= "\t{ $styleid, \"$fgcolor\", \"$bgcolor\", $fontstyle }, // $stylename\n";
168			$numofglobalstyles++;
169        	}
170	}
171	$lexstyle .= "};\n\n";
172}
173
174foreach my $sample ( $xmldoc->findnodes('/NotepadPlus/LexerStyles/LexerType') )
175{
176	$langname = '';
177	$langdesc = '';
178	$langname = $sample->getAttribute('name') if ($sample->hasAttribute('name'));
179	$langdesc = $sample->getAttribute('desc') if ($sample->hasAttribute('desc'));
180	next if (!(defined($acceptedlang{$langdesc})));
181
182	print "\n$langname, $langdesc\n" if ($debug);
183	$lexstyle .= "\nstatic const lexstyle ".$langname."_".$themename."[] = {\n";
184	$numofstyles = 0;
185	foreach my $child ( $sample->getChildnodes )
186	{
187		if (( $child->nodeType() == XML_ELEMENT_NODE )&&($child->nodeName() eq 'WordsStyle'))
188		{
189			$stylename = '';
190			$styleid = '';
191			$fgcolor = '';
192			$bgcolor = '';
193			$fontstyle = '';
194			$stylename = $child->getAttribute('name') if ($child->hasAttribute('name'));
195			$styleid = $child->getAttribute('styleID') if ($child->hasAttribute('styleID'));
196			$fgcolor = $child->getAttribute('fgColor') if ($child->hasAttribute('fgColor'));
197			$bgcolor = $child->getAttribute('bgColor') if ($child->hasAttribute('bgColor'));
198			$fontstyle = $child->getAttribute('fontStyle') if ($child->hasAttribute('fontStyle'));
199			$defaultbgcolor = $bgcolor if ($stylename eq 'DEFAULT');
200			$defaultfgcolor = $fgcolor if ($stylename eq 'DEFAULT');
201			$defaultfontstyle = $fontstyle if ($stylename eq 'DEFAULT');
202			$defaultfontstyle = "0" if (length($defaultfontstyle) == 0);
203			$bgcolor = $defaultbgcolor if (length($bgcolor) == 0);
204			$fgcolor = $defaultfgcolor if (length($fgcolor) == 0);
205			$fontstyle = $defaultfontstyle if (length($fontstyle) == 0);
206			print "$stylename, $styleid, $fgcolor, $bgcolor, $fontstyle\n" if ($debug);
207			$lexstyle .= "\t{ $styleid, \"$fgcolor\", \"$bgcolor\", $fontstyle }, // $stylename\n";
208			$numofstyles++;
209        	}
210	}
211	$lexstyle .= "};\n";
212	$lstyle = "	{ \"$themename2\", \"$defaultfgcolor\", \"$defaultbgcolor\", \"$currentlinebgcolor\", \"$linenumfgcolor\", ".$langname."_".$themename.", global_".$themename.", $numofstyles, $numofglobalstyles },\n";
213	$cppstyle          .= $lstyle if ($langdesc eq 'C++');
214	$javastyle         .= $lstyle if ($langdesc eq 'Java');
215	$pythonstyle       .= $lstyle if ($langdesc eq 'Python');
216	$rubystyle         .= $lstyle if ($langdesc eq 'Ruby');
217	$javascriptstyle   .= $lstyle if ($langdesc eq 'Javascript');
218}
219
220}
221
222