1: /* webcpp - theme.cpp
2: * Copyright (C)2001-2003 Jeffrey Bakker
3:
4: * This program is free software; you can redistribute it and/or modify
5: * it under the terms of the GNU General Public License as published by
6: * the Free Software Foundation; either version 2 of the License, or
7: * (at your option) any later version.
8:
9: * This program is distributed in the hope that it will be useful,
10: * but WITHOUT ANY WARRANTY; without even the implied warranty of
11: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12: * GNU General Public License for more details.
13:
14: * You should have received a copy of the GNU General Public License
15: * along with this program; if not, write to the Free Software
16: * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17: ___________________________________ .. .
18: */
19:
20:
21: /*
22: Finished
23:
24: Asm
25: Asp
26: C
27: C#
28: C++
29: CG
30: Fortran
31: HTML
32: Java
33: Modula*
34: Objective C
35: Pascal
36: Shell
37:
38: */
39:
40: #include "theme.h"
41: #include <cctype>
42: using namespace std;
43:
44: // (de)construction -----------------------------------------------------------
45: Theme::~Theme() {
46:
47: close();
48: }
49: Theme::Theme() {
50:
51: typical();
52:
53: format2 = true;
54: Picture = "\0";
55: } //---------------------------------------------------------------------------
56: // set file -------------------------------------------------------------------
57: bool Theme::setFile(string filename) {
58:
59: SCSfile = filename;
60:
61: if(filename.rfind(".Scs2") == -1) {
62:
63: if(filename.rfind(".scs") != -1) {
64: format2 = false;
65: }
66: else
67: filename += ".Scs2";
68: }
69: if( openR(filename) ) {
70:
71: return load();
72: }
73: return false;
74: }
75: // set background picture -----------------------------------------------------
76: void Theme::setPicture(string picture) {
77:
78: Picture = picture;
79: }
80: // get the name of the theme --------------------------------------------------
81: string Theme::getThemeName() {
82:
83: return SCSfile;
84: }
85: // get background picture -----------------------------------------------------
86: string Theme::getImageFile() {
87:
88: return Picture;
89: }
90: // loading a theme ------------------------------------------------------------
91: bool Theme::load() {
92:
93: // load an Scs2-format file
94: if(format2) {
95:
96: string Scs2buf;
97: CFdatapair ScsXml;
98:
99: // check for xml tag
100: getline(ifile,Scs2buf);
101: if(Scs2buf.find("<?xml version=\"1.0\"") == -1)
102: {return false;}
103: // check for the document type
104: getline(ifile,Scs2buf);
105: if(Scs2buf.find("<!DOCTYPE SyntaxColourScheme2") == -1)
106: {return false;}
107: // check for Scs2 data section
108: getline(ifile,Scs2buf);
109: if(Scs2buf.find("<SyntaxColourScheme2>") == -1)
110: {return false;}
111:
112: // load the Scs2 data which may be in random order
113: getline(ifile,Scs2buf);
114: while(ifile) {
115:
116: // cerr << "\nScs2: " << Scs2buf << endl;
117:
118: ScsXml << Scs2buf;
119: ScsVec.push_back(Scs2buf);
120: getline(ifile,Scs2buf);
121: }
122:
123: // for(int j=0; j < ScsVec.size(); j++) {
124:
125: // cerr << endl << ScsVec[j].info_nv() << endl;
126: // }
127:
128: // sort the Scs2 data
129: Colours2[BGCOLOR] = getColour("bgcolor");
130: Colours2[PREPROC] = getColour("preproc");
131: Colours2[NORTEXT] = getColour("nortext");
132: Colours2[SYMBOLS] = getColour("symbols");
133: Colours2[KEYWORD] = getColour("keyword");
134: Colours2[KEYTYPE] = getColour("keytype");
135: Colours2[INTEGER] = getColour("integer");
136: Colours2[FLOATPT] = getColour("floatpt");
137: Colours2[DBLQUOT] = getColour("dblquot");
138: Colours2[SINQUOT] = getColour("sinquot");
139: Colours2[COMMENT] = getColour("comment");
140: // use a background image, if found
141: Picture = getColour("background");
142:
143: // check the format of all the colours
144: for(int i=BGCOLOR; i <= COMMENT; i++) {
145:
146: if(Colours2[i] == "\0") {
147: typical();
148: return false;
149: }
150:
151: if(Colours2[i][0] != '#') {
152: Colours2[i].insert(0,"#");
153: }
154:
155: // verify data is in the right format
156: if(!verifyFormat(Colours2[i])) {
157: typical();
158: return false;
159: }
160: // if not, use the defulat scheme
161: }
162: return true;
163: }
164: // load an original SCS-format file
165: for(int i=BGCOLOR; i <= COMMENT; i++) {
166:
167: ifile >> Colours2[i];
168:
169: // convert old Scs to Scs2 format
170: if(i == NORTEXT) {
171: Colours2[SYMBOLS] = Colours2[NORTEXT];
172: i++;
173: }
174: else
175: if(i == KEYWORD) {
176: Colours2[KEYTYPE] = Colours2[KEYWORD];
177: i++;
178: }
179: else
180: if(i == INTEGER) {
181: Colours2[FLOATPT] = Colours2[INTEGER];
182: i++;
183: }
184: else
185: if(i == DBLQUOT) {
186: Colours2[SINQUOT] = Colours2[DBLQUOT];
187: i++;
188: }
189: // they will look exactly the same as the old style
190:
191: if(!verifyFormat(Colours2[i])) {
192: typical();
193: return false;
194: }
195: }
196: return true;
197: }
198:
199:
200: string Theme::getColour(string Name) {
201:
202: for(int i=0; i < ScsVec.size(); i++) {
203:
204: if(ScsVec[i].getname() == Name)
205: return ScsVec[i].getvalue();
206: }
207: // cerr << "\nScs2: " << Name << " was not found!\n";
208: return "\0";
209: }
210: // write a stylesheet ---------------------------------------------------------
211: bool Theme::writeCSS(string cssfile) {
212:
213: if(!openW(cssfile,true)) {return false;}
214: ofile << getCSSdata();
215: closeW();
216: return true;
217: }
218: // set a colour in the theme --------------------------------------------------
219: void Theme::setColour(string colour, int num) {
220:
221: Colours2[num] = colour;
222: }
223: // set default theme ----------------------------------------------------------
224: void Theme::typical() {
225:
226: SCSfile = "typical";
227:
228: setColour("#f1f1f1",BGCOLOR);
229: setColour("#a900a9",PREPROC); //a900a9
230: setColour("#000000",NORTEXT);
231: setColour("#0077dd",SYMBOLS);
232: setColour("#224fff",KEYWORD);
233: setColour("#ff9933",KEYTYPE); //224fff //ff9933
234: setColour("#ff0032",INTEGER);
235: setColour("#ff23a6",FLOATPT);
236: setColour("#00b800",DBLQUOT);
237: setColour("#00b86b",SINQUOT);
238: setColour("#666666",COMMENT);
239: }
240: // enforces proper colour format ----------------------------------------------
241: bool Theme::verifyFormat(string hexData) {
242:
243: // make sure string is the right length
244: if (hexData.size() != 7) {
245: cerr << hexData << "\a is an invalid colour.\n";
246: return false;
247: }
248:
249: // string must start with '#'
250: if (hexData[0] != '#') {
251: cerr << hexData << "\a is an invalid colour.\n";
252: return false;
253: }
254:
255: // change string to uppercase
256: for (int i=1; i < 7; i++) {hexData[i] = toupper(hexData[i]);}
257:
258: // enforce range from #000000 to #FFFFFF
259: for (int j=1; j < 7; j++) {
260:
261: if (hexData[j] < '0' || hexData[j] > 'F') {
262: cerr << hexData << "\a is an invalid colour.\n";
263: return false;
264: }
265: if (ispunct(hexData[j]) || isspace(hexData[j])) {
266: cerr << hexData << "\a is an invalid colour.\n";
267: return false;
268: }
269: }
270:
271: return true;
272: } //---------------------------------------------------------------------------
273: string Theme::getCSSdata() {
274:
275: string CSS;
276:
277: CSS =
278:
279: "/*\nWebcpp v0.8.0 compatible StyleSheet\nhttp://webcpp.sf.net\n"
280: "Theme: " + SCSfile + "\n*/\n\n"
281: "body\n{\nbackground-color: " + Colours2[BGCOLOR] +
282:
283: ( (Picture == "\0")
284: ? "\n}\n\n": ";\nbackground-image: url(\"" + Picture +
285: "\");\nbackground-attachment: fixed\n}\n\n" ) +
286:
287: "a:link {color:" + Colours2[DBLQUOT] + "}\n"
288: "a:visited {color:" + Colours2[COMMENT] + "}\n"
289: "a:active {color:" + Colours2[KEYWORD] + "}\n"
290: "a:hover {color:" + Colours2[PREPROC] + "}\n\n"
291: "pre\n{\ncolor: " + Colours2[NORTEXT] + "\n}\n\n"
292: "font\n{\nfont-size:100%\n}\n\n"
293: "font.symbols\n{\ncolor: " + Colours2[SYMBOLS] + "\n}\n\n"
294: "font.preproc\n{\ncolor: " + Colours2[PREPROC] + "\n}\n\n"
295: "font.integer\n{\ncolor: " + Colours2[INTEGER] + "\n}\n\n"
296: "font.floatpt\n{\ncolor: " + Colours2[FLOATPT] + "\n}\n\n"
297: "font.dblquot\n{\ncolor: " + Colours2[DBLQUOT] + "\n}\n\n"
298: "font.sinquot\n{\ncolor: " + Colours2[SINQUOT] + "\n}\n\n"
299: "font.keyword\n{\ncolor: " + Colours2[KEYWORD] + ";\nfont-weight: bold\n}\n\n"
300: "font.keytype\n{\ncolor: " + Colours2[KEYTYPE] + ";\nfont-weight: bold\n}\n\n"
301: "font.comment\n{\ncolor: " + Colours2[COMMENT] + ";\nfont-style: italic\n}\n\n";
302:
303: return CSS;
304: }
305: //-----------------------------------------------------------------------------
306:
| w | e | b | c | p | p |
|
| |||||