Loading...
Searching...
No Matches
XML.h
1/*
2
3MIT License
4
5Copyright (c) 2017 FMI Open Development / Markus Peura, first.last@fmi.fi
6
7Permission is hereby granted, free of charge, to any person obtaining a copy
8of this software and associated documentation files (the "Software"), to deal
9in the Software without restriction, including without limitation the rights
10to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11copies of the Software, and to permit persons to whom the Software is
12furnished to do so, subject to the following conditions:
13
14The above copyright notice and this permission notice shall be included in all
15copies or substantial portions of the Software.
16
17THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23SOFTWARE.
24
25 */
26/*
27Part of Rack development has been done in the BALTRAD projects part-financed
28by the European Union (European Regional Development Fund and European
29Neighbourhood Partnership Instrument, Baltic Sea Region Programme 2007-2013)
30 */
31/*
32 * TreeXML.h
33 *
34 * Created on: Jun 24, 2012
35 * Author: mpeura
36 */
37
38
39
40#ifndef DRAIN_XML
41#define DRAIN_XML
42
43#include <ostream>
44
45#include <drain/Sprinter.h>
46#include <drain/FlexibleVariable.h>
47
48#include "ClassXML.h"
49// #include "UtilsXML.h"
50// #include "Flags.h"
51#include "ReferenceMap.h"
52#include "StyleXML.h"
53
54namespace drain {
55
56
58class XML : protected ReferenceMap2<FlexibleVariable> {
59public:
60
61 typedef int intval_t;
62
63 // TODO:
64 // static const intval_t flag_OPEN = 128;
65 // static const intval_t flag_TEXT = 256;
66 static const intval_t UNDEFINED = 0;
67 static const intval_t COMMENT = 1; // || flag_TEXT
68 static const intval_t CTEXT = 2; // || flag_TEXT
69 static const intval_t SCRIPT = 3; // || flag_EXPLICIT || flag_TEXT
70 static const intval_t STYLE = 4; // || flag_EXPLICIT
71 static const intval_t STYLE_SELECT = 5;
72
74 static
75 const std::map<char,std::string> encodingMap;
76
78
80
83 template <class T2, class ...T3>
84 inline
85 bool typeIs(const T2 & arg, const T3... args) const {
86 if (type == static_cast<intval_t>(arg)){
87 return true;
88 }
89 else {
90 return typeIs(args...);
91 }
92 };
93
94protected:
95
96 inline
97 bool typeIs() const {
98 return false;
99 };
100
101protected:
102
103 intval_t type = XML::UNDEFINED;
104
105 // String, still easily allowing numbers through set("id", ...)
106 std::string id;
107 // Consider either/or
108 std::string url;
109public:
110 std::string ctext;
111
112 // Could be templated, behind Static?
113 static int nextID;
114
115 inline
116 static int getCount(){
117 return nextID;
118 }
119
120
121 inline
122 bool isUndefined() const {
123 return type == UNDEFINED;
124 }
125
126 inline
127 bool isComment() const {
128 return type == COMMENT;
129 }
130
131 inline
132 bool isCText() const {
133 return type == CTEXT;
134 }
135
136 inline
137 bool isStyle() const {
138 return type == STYLE;
139 }
140
142 virtual
143 bool isSingular() const;
144
146 virtual
147 bool isExplicit() const;
148
150
154 virtual
155 void clear();
156
158
162 inline
163 void reset(){
164 clear();
165 type = UNDEFINED;
166 }
167
169
172 inline
173 void setId(){
174 link("id", id);
175 }
176
178 inline
179 void setId(const std::string & s){
180 link("id", id = s);
181 }
182
184 template <char C='\0', typename ...TT>
185 inline
186 void setId(const TT & ...args) {
187 link("id", id = drain::StringBuilder<C>(args...));
188 }
189
191 inline
192 const std::string & getId() const {
193 return id;
194 }
195
196
198
202 template <class ...T>
203 inline
204 void setComment(const T & ...args) {
205 this->clear(); // what if also uncommenting needed?
206 // this->clearClasses();
207 type = COMMENT;
208 setText(args...);
209 }
210
212
217 virtual // redef shows variadic args, below?
218 void setText(const std::string & s);
219
220 template <class ...T>
221 void setText(const T & ...args) {
222 setText(StringBuilder<>(args...).str()); // str() to avoid infinite loop
223 }
224
225 virtual inline
226 const std::string & getText() const {
227 return ctext;
228 }
229
230 inline
231 const std::string & getUrl(){
232 return url;
233 }
234
235 inline
236 void setUrl(const std::string & s){
237 url = s;
238 // ctext = s;
239 }
240
241 template <class ...T>
242 inline
243 void setName(const T & ...args){
244 setAttribute("data-name", drain::StringBuilder<>(args...));
245 }
246
247
248 // ---------------- Attributes ---------------
249
250 virtual inline // shadows - consider virtual
251 bool empty() const {
252 return map_t::empty();
253 }
254
255 inline
256 const map_t & getAttributes() const {
257 return *this;
258 };
259
260 // Maybe controversial. Helps importing sets of variables.
261 inline
262 map_t & getAttributes(){
263 return *this;
264 };
265
266 // Rename getAttribute?
267 inline
268 const drain::FlexibleVariable & get(const std::string & key) const {
269 return (*this)[key];
270 }
271
272 // Rename getAttribute?
273 inline
274 drain::FlexibleVariable & get(const std::string & key){
275 return (*this)[key];
276 }
277
278
279 // Rename getAttribute?
280 template <class V>
281 inline
282 V get(const std::string & key, const V & defaultValue) const {
283 return map_t::get(key, defaultValue);
284 }
285
286 inline
287 std::string get(const std::string & key, const char * defaultValue) const {
288 return map_t::get(key, defaultValue);
289 }
290
292 // But otherways confusing?
293 virtual inline
294 void setAttribute(const std::string & key, const std::string &value){
295 (*this)[key] = value;
296 }
297
299 // But otherways confusing?
300 virtual inline
301 void setAttribute(const std::string & key, const char *value){
302 (*this)[key] = value; // -> handleString()
303 }
304
306 template <class V>
307 inline
308 void setAttribute(const std::string & key, const V & value){
309 (*this)[key] = value; // -> handleString()
310 }
311
312
313 inline
314 void removeAttribute(const std::string & s){
315 iterator it = this->find(s);
316 if (it != this->end()){
317 this->erase(it);
318 }
319 }
320
321
322 // ------------------ Style ---------------
323
324protected:
325
326 StyleXML style;
327
328public:
329
330 inline
331 const StyleXML & getStyle() const {
332 return style;
333 }
334
335 inline
336 void setStyle(const StyleXML & s){
337 style.clear();
338 SmartMapTools::setValues(style, s);
339 }
340
341 void setStyle(const std::string & value){
342 drain::Logger mout(__FILE__, __FUNCTION__);
343 if (type == UNDEFINED){
344 mout.reject<LOG_WARNING>("setting style for UNDEFINED elem: ", value);
345 mout.unimplemented<LOG_WARNING>("future option: set type to STYLE_SELECT");
346 }
347 else if (type == STYLE){
348 mout.reject<LOG_WARNING>("not setting style for STYLE elem: ", value); // , *this);
349 }
350 else {
351 SmartMapTools::setValues(style, value, ';', ':', "; \t\n"); // sep, equal, trim (also ';' ?)
352 }
353 }
354
355 inline
356 void setStyle(const char *value){
357 setStyle(std::string(value));
358 }
359
360 inline
361 void setStyle(const std::string & key, const std::string & value){
362 drain::Logger mout(__FILE__, __FUNCTION__);
363 if (type == UNDEFINED){
364 mout.reject<LOG_WARNING>("setting style for UNDEFINED elem: ", key, '=', value);
365 mout.unimplemented<LOG_WARNING>("future option: set type to STYLE_SELECT");
366 }
367 else if (type == STYLE){
368 mout.reject<LOG_WARNING>("not setting style for STYLE elem: ", value); // , *this);
369 }
370 else {
371 this->style[key] = value;
372 }
373 }
374
375
377
383 template <class V>
384 inline
385 void setStyle(const std::string & key, const std::initializer_list<V> &l){
386 // const std::initializer_list<Variable::init_pair_t > &l
387 if (type == STYLE){ // typeIs(STYLE) fails
388 drain::Logger mout(__FILE__, __FUNCTION__);
389 mout.warn("Setting style of STYLE? initializer_list<", drain::TypeName<V>::str(), "> = ", sprinter(l)); // , StyleXML::styleLineLayout ?
390 }
391 this->style[key] = l;
392 }
393
394
396
399 template <class V>
400 inline
401 void setStyle(const std::string & key, const V & value){
402
403 if (type == STYLE){
404 drain::Logger(__FILE__, __FUNCTION__).reject<LOG_WARNING>("Setting style of STYLE: ", key, "=", value);
405 }
406 else {
407 this->style[key] = value;
408 }
409 }
410
411 inline
412 void setStyle(const std::initializer_list<std::pair<const char *,const drain::Variable> > &args){
414 }
415
416 /*
417 void setStyle( const std::initializer_list<std::pair<const char *,const char *> > & args){
418 drain::SmartMapTools::setValues(style, args);
419 }
420 */
421
422 /*
423 template <class S>
424 inline
425 void setStyle(const S &value){
426 drain::Logger mout(__FILE__, __FUNCTION__);
427 mout.error("unsupported type ", drain::TypeName<S>::str(), " for value: ", typeid(value));
428 }
429 */
430
431
432protected:
433
434 // ------------------ Style Class ---------------
435
436 ClassListXML classList;
437
438public:
439
440 const ClassListXML & getClasses() const {
441 return classList;
442 }
443
444 template <typename ... TT>
445 inline
446 void addClass(const TT &... args) {
447 classList.add(args...);
448 }
449
453 template <class V>
454 inline
455 bool hasClass(const V & cls) const {
456 return classList.has(cls);
457 }
458
459 inline
460 void removeClass(const std::string & s) {
461 classList.remove(s);
462 }
463
464 inline
465 void clearClasses(){
466 classList.clear();
467 }
468
469
470 virtual
471 void specificAttributesToStream(std::ostream & ostr) const;
472
473
474 enum tag_display_mode {
475 FLEXIBLE_TAG = 0, // <TAG>...</TAG> or <TAG/>
476 OPENING_TAG= 1, // <TAG>
477 CLOSING_TAG = 2, // </TAG>
478 EMPTY_TAG = OPENING_TAG | CLOSING_TAG, // element has no descendants: <hr/>
479 NON_EMPTY_TAG, // opening and closing tags must appear, even when empty: <script></script>
480 };
481
482
483 virtual
484 std::ostream & nodeToStream(std::ostream & ostr, tag_display_mode mode=EMPTY_TAG) const = 0;
485
486// ----------------- Static utilities for derived classes ----------------------
487
488
489 template <class TR>
490 static
491 std::ostream & toStream(std::ostream & ostr, const TR & tree, const std::string & defaultTag="ELEM", int indent=0);
492
493
494 template <class V>
495 static inline
496 void xmlAttribToStream(std::ostream &ostr, const std::string & key, const V &value){
497 //StringTools::replace(XML::encodingMap, data.ctext, ostr);
498 //ostr << ' ' << key << '=' << '"' << value << '"'; // << ' ';
499 ostr << ' ';
501 ostr << '=' << '"';
503 ostr << '"';
504 //<< key << '=' << '"' << value << '"'; // << ' ';
505 }
506
508
511 template <typename TX>
512 static inline
513 TX & xmlAssign(TX & dst, const TX & src){
514
515 if (&src != &dst){
516 dst.clear();
517 // also dst->clear();
518 dst->setType(src->getType());
519 dst->setText(src->ctext); //CTXX
520 dst->getAttributes() = src->getAttributes();
521 }
522
523 return dst;
524 }
525
527
530 template <typename TX>
531 static inline
532 TX & xmlAssign(TX & dst, const typename TX::xml_node_t & src){
533
534 xmlAssignNode(dst.data, src);
535 /*
536 if (&src != &dst.data){
537 dst->clear(); NOW reset()
538 dst->getAttributes().importMap(src.getAttributes());
539 dst->setStyle(src.getStyle());
540 dst->setText(src.ctext);
541 }
542 */
543 return dst;
544 }
545
547
552 template <typename X>
553 static inline
554 X & xmlAssignNode(X & dst, const X & src){
555
556 if (&src != &dst){
557 //dst.clear(); // clear attributes,
558 dst.reset(); // clear attributes, style, cstring and type.
559 dst.setType(src.getType()); // important: creates links!
560 dst.getAttributes().importMap(src.getAttributes());
561 dst.setStyle(src.getStyle());
562 // dst.setText(src.ctext); // wrong! set type to CTEXT
563 dst.ctext = src.ctext;
564 }
565
566 return dst;
567 }
568
570
573 template <typename TX, typename V>
574 static inline
575 TX & xmlAssign(TX & tree, const V & arg){
576 tree->set(arg);
577 return tree;
578 }
579
581
584 template <typename TX>
585 static
586 //T & xmlAssign(T & tree, std::initializer_list<std::pair<const char *,const char *> > l){
587 TX & xmlAssign(TX & tree, std::initializer_list<std::pair<const char *,const Variable> > l){
588
589 switch (static_cast<intval_t>(tree->getType())){
590 case STYLE:
591 for (const auto & entry: l){
592 TX & elem = tree[entry.first];
593 elem->setType(STYLE_SELECT);
594 drain::SmartMapTools::setValues(elem->getAttributes(), entry.second, ';', ':', std::string(" \t\n"));
595 }
596 break;
597 case UNDEFINED:
598 tree->setType(STYLE_SELECT);
599 // no break
600 case STYLE_SELECT:
601 default:
602 tree->set(l);
603 break;
604 }
605
606 return tree;
607 };
608
609 // UNDER CONSTRUCTION!
611
616 template <typename TX>
617 static inline // NOT YET as template specification of xmlAssign(...)
618 TX & xmlAssignString(TX & tree, const std::string & s){
619 if (tree->isUndefined()){
620 tree->setType(CTEXT);
621 }
622 tree->ctext = s;
623 return tree;
624 /*
625 if (tree->isCText()){
626 tree->setText(s);
627 return tree;
628 }
629 else if (tree->isUndefined()){
630 tree->setType(CTEXT);
631 tree->setText(s);
632 return tree;
633 }
634 else {
635 for (auto & entry: tree){
636 if (entry.second->isCText()){
637 entry.second->setText(s);
638 return entry.second;
639 }
640 }
641 // drain::Logger(__FILE__, __FUNCTION__).error("Assign string...");
642 TX & child = tree.addChild();
643 child->setType(CTEXT);
644 child->setText(s);
645 return child;
646 }
647 */
648 }
649
650 template <typename TX>
651 static inline // NOT YET as template specification of xmlAssign(...)
652 TX & xmlAppendString(TX & tree, const std::string & s){
653 if (tree->isCText()){
654 tree->ctext += s;
655 return tree;
656 }
657 else if (tree->isUndefined()){
658 tree->setType(CTEXT);
659 // tree->setText(s);
660 tree->ctext += s;
661 return tree;
662 }
663 else {
664 // drain::Logger(__FILE__, __FUNCTION__).error("Assign string...");
665 TX & child = tree.addChild();
666 child->setType(CTEXT);
667 child->setText(s);
668 return child;
669 }
670 }
671
673
677 template <typename TX>
678 static inline
679 TX & xmlSetType(TX & tree, const typename TX::node_data_t::xml_tag_t & type){
680 tree->setType(type);
681 return tree;
682 }
683
684
690 template <typename T>
691 static
692 T & xmlAddChild(T & tree, const std::string & key){
693 typename T::node_data_t::xml_tag_t type = xmlRetrieveDefaultType(tree.data);
694
695 if (!key.empty()){
696 return tree[key](type);
697 }
698 else {
699 std::stringstream k; // ("elem");
700 k << "elem"; // number with 4 digits overwrites this?
701 k.width(3); // consider static member prefix
702 k.fill('0');
703 k << tree.getChildren().size();
704 return tree[k.str()](type);
705 }
706 }
707
708 template <typename N>
709 static
710 typename N::xml_tag_t xmlRetrieveDefaultType(const N & parentNode){
711 typedef typename N::xml_default_elem_map_t map_t;
712 const typename map_t::const_iterator it = N::xml_default_elems.find(parentNode.getNativeType());
713 if (it != N::xml_default_elems.end()){
714 return (it->second);
715 }
716 else {
717 return static_cast<typename N::xml_tag_t>(0);
718 }
719 }
720
721 /*
722 template <typename T>
723 static
724 T & xmlGuessType(const typename T::node_data_t & parentNode, T & child){
725 typedef typename T::node_data_t::xml_default_elem_map_t map_t;
726 const typename map_t::const_iterator it = T::node_data_t::xml_default_elems.find(parentNode.getNativeType());
727 if (it != T::node_data_t::xml_default_elems.end()){
728 child->setType(it->second);
729 drain::Logger(__FILE__, __FUNCTION__).experimental<LOG_WARNING>("Default type set: ", child->getTag());
730 }
731 return child;
732 }
733 */
734
735
736
737};
738
739
740template <class TR>
741std::ostream & XML::toStream(std::ostream & ostr, const TR & tree, const std::string & defaultTag, int indent){
742
743 drain::Logger mout(__FILE__,__FUNCTION__);
744
745 const typename TR::container_t & children = tree.getChildren();
746
747 // const XML & data = tree.data; // template type forcing, keep here for programming aid.
748 const typename TR::node_data_t & data = tree.data; // template used
749
750 tag_display_mode mode = EMPTY_TAG;
751
752 if (data.isCText()){ // this can be true only at root, and rarely so...? (because recursive call not reached, if ctext)
753 data.nodeToStream(ostr, mode);
754 // ostr << "<!--TX-->";
755 return ostr;
756 }
757
758 if (!data.ctext.empty()){
759 // mout.warn("Non-CTEXT-elem with ctext: <", data.getTag(), " id='", data.getId(), "' ...>, text='", data.ctext, "'");
760 if (data.isSingular()){
761 // mout.warn("Skipping CTEXT of a singular element <", tree->getTag(), " id='", data.getId(), "' ...> , CTEXT: '", data.ctext, "'");
762 mode = EMPTY_TAG;
763 }
764 else {
765 mode = OPENING_TAG;
766 }
767 }
768
769 if (!children.empty()){
770 mode = OPENING_TAG;
771 if (data.isSingular()){
772 mout.warn("Singular (hence normally empty) element <", tree->getTag(), " id='", data.getId(), "' ...> has ", children.size(), " children?");
773 }
774 }
775
776 // mout.attention("Hey! ", TypeName<TR>::str(), " with ", TypeName<typename TR::node_data_t>::str(), "Explicit ", data.isExplicit(), " or implicit ", data.isSingular());
777 if (data.isExplicit()){ // explicit
778 mode = OPENING_TAG;
779 }
780 else if (data.isSingular()){ // <br/> <hr/>
781 mode = EMPTY_TAG;
782 }
783 // Hence, is flexible, "bimodal", supports empty and open-close mode.
784
785 // Indent
786 // std::fill_n(std::ostream_iterator<char>(ostr), 2*indent, ' ');
787 std::string fill(2*indent, ' ');
788 ostr << fill;
789 data.nodeToStream(ostr, mode);
790
791 if (mode == EMPTY_TAG){
792 //ostr << "<!--ET-->";
793 ostr << '\n';
794 return ostr;
795 }
796 else if (data.isStyle()){
797 // https://www.w3.org/TR/xml/#sec-cdata-sect
798 // ostr << "<![CDATA[ \n";
799 // ostr << "<!-- STYLE -->"; WRONG!
800
801 if (!data.ctext.empty()){
802 // TODO: indent
803 ostr << fill << data.ctext;
804 StyleXML::commentToStream(ostr, " TEXT ");
805 ostr << '\n';
806 }
807
808 if (!data.getAttributes().empty()){
809 mout.warn("STYLE elem ", data.getId()," contains attributes, probably meant as style: ", sprinter(data.getAttributes()));
810 ostr << "\n\t /" << "* <!-- DISCARDED attribs ";
811 Sprinter::toStream(ostr, data.getAttributes()); //, StyleXML::styleRecordLayout
812 ostr << " /--> *" << "/" << '\n';
813 }
814
815 if (!data.style.empty()){
816 ostr << fill;
817 StyleXML::commentToStream(ostr, "STYLE OBJ");
818 ostr << '\n';
819 for (const auto & attr: data.style){
820 ostr << fill << " ";
821 Sprinter::pairToStream(ostr, attr, StyleXML::styleRecordLayout); // {" :;"}
822 //attr.first << ':' attr.first << ':';
823 ostr << '\n';
824 }
825 // ostr << fill << "}\n";
826 // Sprinter::sequenceToStream(ostr, entry.second->getAttributes(), StyleXML::styleRecordLayoutActual);
827 // ostr << '\n';
828 }
829 ostr << '\n';
830
831 ostr << fill;
832 StyleXML::commentToStream(ostr, "style ELEMS");
833 ostr << '\n';
834
835 for (const auto & entry: tree.getChildren()){
836
837 if (entry.second->isComment()){
838 // StringTools::replace();
839 ostr << fill << "/* "<< entry.second->ctext << " */" << '\n';
840 // XML::toStream(ostr, entry.second, defaultTag, indent); // indent not used?
841 continue;
842 }
843
844 if (!entry.second->ctext.empty()){
845 //ostr << fill << "<!-- elem("<< entry.first << ") ctext /-->" << '\n';
846 ostr << fill << " " << entry.first << " {" << entry.second->ctext << "} /* CTEXT */ \n";
847 }
848
849 if (!entry.second->getAttributes().empty()){
850 ostr << fill << " " << entry.first << " {\n";
851 for (const auto & attr: entry.second->getAttributes()){
852 ostr << fill << " ";
853 ostr << attr.first << ':' << attr.second << ';';
854 ostr << '\n';
855 }
856 ostr << fill << " }\n";
857 ostr << '\n';
858 }
859
860 }
861 ostr << "\n"; // end CTEXT
862 // ostr << " ]]>\n"; // end CTEXT
863 // end STYLE defs
864 ostr << fill;
865
866 }
867 else {
868
869 // Elements "own" CTEXT will be always output first -> check for problems, if other elements added first.
870 // ostr << data.ctext;
871 StringTools::replace(XML::encodingMap, data.ctext, ostr); // any time issue?
872
873 // Detect if all the children are of type CTEXT, to be rendered in a single line.
874 // Note: potential re-parsing will probably detect them as a single CTEXT element.
875 bool ALL_CTEXT = true; // (!data.ctext.empty()) || !children.empty();
876
877 for (const auto & entry: children){
878 if (!entry.second->isCText()){
879 ALL_CTEXT = false;
880 break;
881 }
882 }
883
884 // ALL_CTEXT = false;
885
886 if (ALL_CTEXT){
887 // ostr << "<!--ALL_CTEXT-->";
888 char sep=0;
889 for (const auto & entry: children){
890 if (sep){
891 ostr << sep;
892 }
893 else {
894 sep = ' '; // consider global setting?
895 }
896 //ostr << entry.second->getText();
897 StringTools::replace(XML::encodingMap, entry.second->getText(), ostr); // any time issue?
898 // ostr << entry.second->getText();
899 }
900 }
901 else {
902 // ostr << "<!-- RECURSION -->";
903 ostr << '\n';
905 for (const auto & entry: children){
906 toStream(ostr, entry.second, entry.first, indent+1); // Notice, no ++indent
907 // "implicit" newline
908 }
909 ostr << fill; // for CLOSING tag
910 }
911
912 }
913
914 // ostr << "<!-- END "<< data.getId() << ' ' << data.getTag() << '(' << data.getType() << ')' << "-->";
915
916 data.nodeToStream(ostr, CLOSING_TAG);
917 ostr << '\n'; // Always after closing tag!
918
919 return ostr;
920}
921
922
923
924} // drain::
925
926#endif /* DRAIN_XML */
927
LogSourc e is the means for a function or any program segment to "connect" to a Log.
Definition Log.h:312
Logger & warn(const TT &... args)
Possible error, but execution can continue.
Definition Log.h:430
Logger & reject(const TT &... args)
Some input has been rejected, for example by a syntax.
Definition Log.h:610
A map of references to base type scalars, arrays or std::string; changing values in either are equiva...
Definition ReferenceMap.h:69
ref_t & link(const std::string &key, F &x)
Associates a map entry with a variable.
Definition ReferenceMap.h:84
static void setValues(M &dst, const std::map< std::string, S > &srcMap)
Definition SmartMapTools.h:176
map_t::iterator iterator
Needed?
Definition SmartMap.h:80
std::string get(const std::string &key, const std::string &defaultValue) const
Retrieves a value, or default value if value is unset.
Definition SmartMap.h:127
static std::ostream & toStream(std::ostream &ostr, const std::initializer_list< T > &x, const SprinterLayout &layout=defaultLayout)
New (experimental)
Definition Sprinter.h:420
Definition StringBuilder.h:58
static std::string replace(const std::string &src, const std::string &from, const std::string &to)
Definition String.h:96
static void commentToStream(std::ostream &ostr, const T &v)
Practical utility, helps in adding C++ code commenting...
Definition StyleXML.h:69
VariableT is a final class applied through typedefs Variable, Reference and FlexibleVariable.
Definition VariableT.h:87
bool typeIs(const T2 &arg, const T3... args) const
Return true, if type is any of the arguments.
Definition XML.h:85
virtual bool isExplicit() const
Tell if this element should always have an explicit closing tag even when empty, like <STYLE></STYLE>
Definition XML.cpp:85
static TX & xmlAssign(TX &tree, const V &arg)
Assign another tree structure to another.
Definition XML.h:575
virtual bool isSingular() const
Tell if this element should always have an explicit closing tag even when empty, like <STYLE></STYLE>
Definition XML.cpp:79
void addClass(const TT &... args)
Style class.
Definition TreeXML.h:220
void setId()
Makes ID a visible attribute.
Definition XML.h:173
void setStyle(const std::string &key, const std::initializer_list< V > &l)
Set style of an element.
Definition XML.h:385
const std::string & getId() const
Returns ID of this element. Hopefully a unique ID...
Definition XML.h:192
virtual void setAttribute(const std::string &key, const char *value)
Default implementation. Needed for handling units in strings, like "50%" or "640px".
Definition XML.h:301
static TX & xmlAssignString(TX &tree, const std::string &s)
When assigning a string, create new element unless the element itself is of type CTEXT.
Definition XML.h:618
static const std::map< char, std::string > encodingMap
User may optionally filter attributes and CTEST with this using StringTools::replace(XML::encodingMap...
Definition XML.h:75
void setId(const TT &...args)
Concatenates arguments to an id.
Definition XML.h:186
virtual void setAttribute(const std::string &key, const std::string &value)
Default implementation. Needed for handling units in strings, like "50%" or "640px".
Definition TreeXML.h:166
static TX & xmlSetType(TX &tree, const typename TX::node_data_t::xml_tag_t &type)
Definition XML.h:679
static std::ostream & toStream(std::ostream &ostr, const TR &tree, const std::string &defaultTag="ELEM", int indent=0)
Definition XML.h:741
static T & xmlAddChild(T &tree, const std::string &key)
Definition XML.h:692
static TX & xmlAssign(TX &tree, std::initializer_list< std::pair< const char *, const Variable > > l)
Tree.
Definition XML.h:587
static TX & xmlAssign(TX &dst, const typename TX::xml_node_t &src)
Assign another tree structure to another.
Definition XML.h:532
virtual void clear()
Clear style, class and string data but keep the element type.
Definition XML.cpp:73
void reset()
Clear style, class and string data as well as the element type.
Definition XML.h:163
void setStyle(const std::string &key, const V &value)
For element/class/id, assign ...
Definition XML.h:401
virtual void setText(const std::string &s)
Assign the text content of this node. If the node type is undefined, set it to CTEXT.
Definition XML.cpp:97
void setComment(const T &...args)
Make this node a comment. Contained tree will not be deleted. In current version, attributes WILL be ...
Definition XML.h:204
void setAttribute(const std::string &key, const V &value)
"Final" implementation.
Definition XML.h:308
static X & xmlAssignNode(X &dst, const X &src)
Assign another tree structure to another.
Definition XML.h:554
static TX & xmlAssign(TX &dst, const TX &src)
Assign another tree structure to another.
Definition XML.h:513
bool hasClass(const V &cls) const
Definition XML.h:455
std::string id
Some general-purpose.
Definition TreeXML.h:95
void setId(const std::string &s)
Makes ID a visible attribute, with a given value.
Definition XML.h:179
Definition DataSelector.cpp:1277
Definition Type.h:542