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