Code

Pot and Dutch translation update
[inkscape.git] / src / conditions.cpp
1 #define __SP_CONDITIONS_CPP__
3 /*
4  * SVG conditional attribute evaluation
5  *
6  * Authors:
7  *   Andrius R. <knutux@gmail.com>
8  *
9  * Copyright (C) 2006 authors
10  *
11  * Released under GNU GPL, read the file 'COPYING' for more information
12  */
14 #ifdef HAVE_CONFIG_H
15 # include "config.h"
16 #endif
18 #include <set>
19 #include <glibmm/ustring.h>
20 #include "conditions.h"
21 #include "xml/repr.h"
22 #include "rdf.h"
24 typedef bool (* condition_evaluator)(SPItem const *item, gchar const *value);
26 struct Condition {
27     gchar const *attribute;
28     condition_evaluator evaluator;
29 };
31 static bool evaluateSystemLanguage(SPItem const *item, gchar const *value);
32 static bool evaluateRequiredFeatures(SPItem const *item, gchar const *value);
33 static bool evaluateRequiredExtensions(SPItem const *item, gchar const *value);
35 /* define any conditional attributes and their handler functions in this array */
36 static Condition _condition_handlers[] = {
37     { "systemLanguage", evaluateSystemLanguage },
38     { "requiredFeatures", evaluateRequiredFeatures },
39     { "requiredExtensions", evaluateRequiredExtensions },
40 };
42 /* function which evaluates if item should be displayed */
43 bool sp_item_evaluate(SPItem const *item) {
44     Inkscape::XML::Node *grepr = SP_OBJECT_REPR (item);
45     
46     for ( unsigned int i = 0 ; i < sizeof(_condition_handlers)/sizeof(_condition_handlers[0]) ; i++ ) {
47         gchar const *value = grepr->attribute(_condition_handlers[i].attribute);
48         if ( NULL == value )
49             continue;
51         if (!_condition_handlers[i].evaluator(item, value))
52             return false;
53     }
55     return true;
56 }
58 #define ISALNUM(c)    (((c) >= 'a' && (c) <= 'z') || ((c) >= 'A' && (c) <= 'Z') || ((c) >= '0' && (c) <= '9'))
60 static gchar *preprocessLanguageCode(gchar *lngcode) {
61     if ( NULL == lngcode )
62         return NULL;
64     lngcode = g_strstrip(lngcode);
65     if ( 0 == *lngcode )
66         return lngcode;
67     for ( unsigned int i = 0 ; i < strlen(lngcode) ; i++ ) {
68         if ( lngcode[i] >= 'A' && lngcode[i] <= 'Z' ) {
69             lngcode[i] = g_ascii_tolower(lngcode[i]);
70         } else if ( '_' == lngcode[i] ) {
71             lngcode[i] = '-';
72         } else if ( !ISALNUM(lngcode[i]) && '-' != lngcode[i] ) {
73             // only alpha numeric characters and '-' may be contained in language code
74             lngcode[0] = 0;
75             break;
76         }
77     }
78     
79     return lngcode;
80 }
82 static bool evaluateSystemLanguage(SPItem const *item, gchar const *value) {
83     if ( NULL == value )
84         return true;
86     std::set<Glib::ustring> language_codes;
87     gchar *str = NULL;
88     gchar **strlist = g_strsplit( value, ",", 0);
90     for ( int i = 0 ; (str = strlist[i]) ; i++ ) {
91         gchar *lngcode = preprocessLanguageCode(str);
92         if ( 0 == *lngcode )
93             continue;
94         language_codes.insert(lngcode);
96         gchar *pos = strchr (lngcode, '-');
97         if (pos)
98         {
99             // if subtag is used, primary tag is still a perfect match
100             *pos = 0;
101             if ( language_codes.find(lngcode) == language_codes.end() ) {
102                 language_codes.insert(lngcode);
103             }
104         }
105     }
106     g_strfreev(strlist);
108     if (language_codes.empty())
109         return false;
111     SPDocument *document = SP_OBJECT_DOCUMENT(item);
112     Glib::ustring document_language = document->getLanguage();
114     if (document_language.size() == 0)
115         return false;
117     bool match = true;
118     strlist = g_strsplit( document_language.c_str(), ",", 0);
119     for ( int i = 0 ; (str = strlist[i]) ; i++ ) {
120         gchar *lngcode = preprocessLanguageCode(str);
121         if ( 0 == *lngcode )
122             continue;
123         if ( language_codes.find(lngcode) != language_codes.end() ) {
124             match = true;
125             break;
126         }
127         match = false;
128     }
129     g_strfreev(strlist);
130     return match;
133 static std::vector<Glib::ustring> splitByWhitespace(gchar const *value) {
134     std::vector<Glib::ustring> parts;
135     gchar *str = NULL;
136     gchar **strlist = g_strsplit( value, ",", 0);
138     for ( int i = 0 ; (str = strlist[i]) ; i++ ) {
139         gchar *part = g_strstrip(str);
140         if ( 0 == *part )
141             continue;
142         parts.push_back(part);
143     }
144     g_strfreev(strlist);
145     return parts;
148 #define SVG11FEATURE    "http://www.w3.org/TR/SVG11/feature#"
149 #define SVG10FEATURE    "org.w3c."
151 static bool evaluateSVG11Feature(gchar const *feature) {
152     static gchar const *_supported_features[] = {
153         "SVG", // incomplete "SVG-static" - missing support for "Filter"
154            /* SVG - user agent supports at least one of the following:
155                 "SVG-static", "SVG-animation", "SVG-dynamic" or "SVGDOM" */
156         // "SVGDOM", // not sure
157            /* SVGDOM - user agent supports at least one of the following:
158                  "SVGDOM-static", "SVGDOM-animation" or "SVGDOM-dynamic" */
159         "SVG-static", // incomplete - missing support for "Filter"
160            /* SVG-static - user agent supports the following features:
161                 "CoreAttribute", "Structure", "ContainerAttribute",
162                 "ConditionalProcessing", "Image", "Style", "ViewportAttribute",
163                 "Shape", "Text", "PaintAttribute", "OpacityAttribute",
164                 "GraphicsAttribute", "Marker", "ColorProfile",
165                 "Gradient", "Pattern", "Clip", "Mask", "Filter",
166                 "XlinkAttribute", "Font", "Extensibility" */
167         // "SVGDOM-static", // not sure
168            /* SVGDOM-static - All of the DOM interfaces and methods
169                 that correspond to SVG-static */
170         // "SVG-animation", // no support
171            /* SVG-animation - All of the language features from "SVG-static"
172                 plus the feature "feature#Animation" */
173         // "SVGDOM-animation", // no support
174            /* SVGDOM-animation - All of the DOM interfaces and methods
175                 that correspond to SVG-animation */
176         // "SVG-dynamic", // no support
177            /* SVG-dynamic - user agent supports all "SVG-animation" and the following features:
178                 "Hyperlinking", "Scripting", "View", "Cursor",
179                 "GraphicalEventsAttribute", "DocumentEventsAttribute", "AnimationEventsAttribute" */
180         // "SVGDOM-dynamic", // no support
181            /* SVGDOM-dynamic - All of the DOM interfaces and methods
182                 that correspond to SVG-dynamic */
183         "CoreAttribute",
184         "Structure",
185         "BasicStructure",
186         "ContainerAttribute",
187         "ConditionalProcessing",
188         "Image",
189         "Style",
190         "ViewportAttribute", // not sure
191         "Shape",
192         "Text",
193         "BasicText",
194         "PaintAttribute",
195         "BasicPaintAttribute",
196         "OpacityAttribute",
197         "GraphicsAttribute",
198         "BasicGraphicsAttribute",
199         "Marker",
200         "ColorProfile",
201         "Gradient",
202         "Pattern",
203         "Clip",
204         "BasicClip",
205         "Mask",
206         // "Filter",
207         // "BasicFilter",
208         // "DocumentEventsAttribute",
209         // "GraphicalEventsAttribute",
210         // "AnimationEventsAttribute",
211         // "Cursor", // not sure
212         "Hyperlinking", // not sure
213         "XlinkAttribute", // not sure
214         "ExternalResourcesRequired", // not sure
215         "View",
216         // "Script",
217         // "Animation",
218         "Font",
219         "BasicFont",
220         "Extensibility", // not sure
221     };
222     
223     for ( unsigned int i = 0 ; i < sizeof(_supported_features)/sizeof(_supported_features[0]); i++ ) {
224         if ( 0 == strcasecmp(feature, _supported_features[0]) )
225             return true;
226     }
227     return false;
230 static bool evaluateSVG10Feature(gchar const *feature) {
231     static gchar const *_supported_features[] = {
232         "svg.static", // incomplete - no filter effects
233         "dom.svg.static", // not sure
234         // "svg.animation",
235         // "dom.svg.animation",
236         // "svg.dynamic",
237         // "dom.svg.dynamic"
238         // "svg.all",
239         // "dom.svg.all"
240     };
241     for ( unsigned int i = 0 ; i < sizeof(_supported_features)/sizeof(_supported_features[0]); i++ ) {
242         if ( 0 == strcasecmp(feature, _supported_features[0]) )
243             return true;
244     }
245     return false;
248 static bool evaluateSingleFeature(gchar const *value) {
249     if ( NULL == value )
250         return false;
251     gchar const *found;
252     found = strstr(value, SVG11FEATURE);
253     if ( value == found )
254         return evaluateSVG11Feature(found + strlen(SVG11FEATURE));
255     found = strstr(value, SVG10FEATURE);
256     if ( value == found )
257         return evaluateSVG10Feature(found + strlen(SVG10FEATURE));
258     return false;
261 static bool evaluateRequiredFeatures(SPItem const */*item*/, gchar const *value) {
262     if ( NULL == value )
263         return true;
265     std::vector<Glib::ustring> parts = splitByWhitespace(value);
266     if ( 0 == parts.size() )
267         return false;
269     for ( unsigned int i = 0 ; i < parts.size() ; i++ ) {
270         if (!evaluateSingleFeature(parts[i].c_str())) {
271             return false;
272         }
273     }
274     
275     return true;
278 static bool evaluateRequiredExtensions(SPItem const */*item*/, gchar const *value) {
279     if ( NULL == value )
280         return true;
281     return false;
284 /*
285  * Language codes and names:
286 aa Afar
287 ab Abkhazian
288 af Afrikaans
289 am Amharic
290 ar Arabic
291 as Assamese
292 ay Aymara
293 az Azerbaijani
295 ba Bashkir
296 be Byelorussian
297 bg Bulgarian
298 bh Bihari
299 bi Bislama
300 bn Bengali; Bangla
301 bo Tibetan
302 br Breton
304 ca Catalan
305 co Corsican
306 cs Czech
307 cy Welsh
309 da Danish
310 de German
311 dz Bhutani
313 el Greek
314 en English
315 eo Esperanto
316 es Spanish
317 et Estonian
318 eu Basque
320 fa Persian
321 fi Finnish
322 fj Fiji
323 fo Faroese
324 fr French
325 fy Frisian
327 ga Irish
328 gd Scots Gaelic
329 gl Galician
330 gn Guarani
331 gu Gujarati
333 ha Hausa
334 he Hebrew (formerly iw)
335 hi Hindi
336 hr Croatian
337 hu Hungarian
338 hy Armenian
340 ia Interlingua
341 id Indonesian (formerly in)
342 ie Interlingue
343 ik Inupiak
344 is Icelandic
345 it Italian
346 iu Inuktitut
348 ja Japanese
349 jw Javanese
351 ka Georgian
352 kk Kazakh
353 kl Greenlandic
354 km Cambodian
355 kn Kannada
356 ko Korean
357 ks Kashmiri
358 ku Kurdish
359 ky Kirghiz
361 la Latin
362 ln Lingala
363 lo Laothian
364 lt Lithuanian
365 lv Latvian, Lettish
367 mg Malagasy
368 mi Maori
369 mk Macedonian
370 ml Malayalam
371 mn Mongolian
372 mo Moldavian
373 mr Marathi
374 ms Malay
375 mt Maltese
376 my Burmese
378 na Nauru
379 ne Nepali
380 nl Dutch
381 no Norwegian
383 oc Occitan
384 om (Afan) Oromo
385 or Oriya
387 pa Punjabi
388 pl Polish
389 ps Pashto, Pushto
390 pt Portuguese
392 qu Quechua
394 rm Rhaeto-Romance
395 rn Kirundi
396 ro Romanian
397 ru Russian
398 rw Kinyarwanda
400 sa Sanskrit
401 sd Sindhi
402 sg Sangho
403 sh Serbo-Croatian
404 si Sinhalese
405 sk Slovak
406 sl Slovenian
407 sm Samoan
408 sn Shona
409 so Somali
410 sq Albanian
411 sr Serbian
412 ss Siswati
413 st Sesotho
414 su Sundanese
415 sv Swedish
416 sw Swahili
418 ta Tamil
419 te Telugu
420 tg Tajik
421 th Thai
422 ti Tigrinya
423 tk Turkmen
424 tl Tagalog
425 tn Setswana
426 to Tonga
427 tr Turkish
428 ts Tsonga
429 tt Tatar
430 tw Twi
432 ug Uighur
433 uk Ukrainian
434 ur Urdu
435 uz Uzbek
437 vi Vietnamese
438 vo Volapuk
440 wo Wolof
442 xh Xhosa
444 yi Yiddish (formerly ji)
445 yo Yoruba
447 za Zhuang
448 zh Chinese
449 zu Zulu
450  */
453 /*
454   Local Variables:
455   mode:c++
456   c-file-style:"stroustrup"
457   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
458   indent-tabs-mode:nil
459   fill-column:99
460   End:
461 */
462 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :