45#include <drain/Sprinter.h>
46#include <drain/FlexibleVariable.h>
50#include "ReferenceMap.h"
51#include "TreeUnordered.h"
75std::ostream & operator<<(std::ostream &ostr,
const StyleXML & style){
84 static const int UNDEFINED = 0;
85 static const int COMMENT = 1;
86 static const int CTEXT = 2;
87 static const int STYLE = 3;
88 static const int SCRIPT = 4;
104 void attribToStream(std::ostream &ostr,
const std::string & key,
const V &value){
105 ostr <<
' ' << key <<
'=' <<
'"' << value <<
'"';
112 typedef path_t::elem_t path_elem_t;
115 static int getCount(){
134 template <
char C=
'\0',
typename ...TT>
136 void setId(
const TT & ...args) {
148 return map_t::empty();
152 const map_t & getAttributes()
const {
158 map_t & getAttributes(){
167 (*this)[key] = value;
174 (*this)[key] = value;
181 (*this)[key] = value;
186 void remove(
const std::string & s){
188 if (it != this->end()){
207 V get(
const std::string & key,
const V & defaultValue)
const {
212 std::string get(
const std::string & key,
const char * defaultValue)
const {
218 template <
typename ... TT>
221 classList.
add(args...);
239 return classList.has(cls);
243 void removeClass(
const std::string & s) {
255 ClassListXML classList;
257 typedef std::list<path_t> path_list_t;
276 bool findById(
const V & tree,
const std::string & tag,
typename V::path_t & result,
const typename V::path_t & path =
path_t());
296 template <
class V,
class T>
306 template <
class V,
class T>
317 template <
class T2,
class C>
319 bool findByClass(
const T2 & t,
const C & cls, std::list<path_elem_t> & result);
328 template <
class V,
class C>
340template <
class T=
int>
353 typedef UnorderedMultiTree<NodeXML<T>,
false,
path_t> xml_tree_t;
359 drain::StringTools::import(++nextID,
id);
368 type = node.getType();
369 drain::StringTools::import(++nextID,
id);
378 typedef std::map<T,std::string> tag_map_t;
387 void setType(
const elem_t &t){
399 const elem_t & getType()
const {
404 bool typeIs(
const elem_t &t)
const {
418 bool isComment()
const {
419 return typeIs((
elem_t)COMMENT);
423 bool isCText()
const {
424 return typeIs((
elem_t)CTEXT);
428 bool isUndefined()
const {
429 return typeIs((
elem_t)UNDEFINED);
436 bool isSelfClosing()
const {
439 const std::set<elem_t> l = {(
elem_t)SCRIPT};
440 return (l.find(this->getType()) == l.end());
447 const std::string & getTag(
unsigned int index){
448 typename tag_map_t::const_iterator it = tags.find((
elem_t)index);
449 if (it != tags.end()){
454 static std::string dummy;
464 const std::string & getTag()
const {
473 void set(
const NodeXML & node){
476 setType(node.getType());
478 else if (type == STYLE) {
480 mout.suspicious(
"copying STYLE from node: ", node);
482 drain::SmartMapTools::setValues<map_t>(getAttributes(), node.getAttributes());
486 void set(
const elem_t & type){
491 void set(
const std::string & s){
502 void set(
const char *s){
512 void set(
const std::initializer_list<Variable::init_pair_t > &l){
518 drain::SmartMapTools::setValues<map_t,true>(getAttributes(), l);
525 void set(
const std::map<std::string, X> & args){
531 drain::SmartMapTools::setValues<map_t,true>(getAttributes(), args);
539 void set(
const std::string & key,
const V & value){
542 setStyle(key, value);
544 else if (key ==
"style"){
548 else if (key ==
"class"){
551 drain::StringTools::import(value, cls);
564 NodeXML & operator=(
const T & x){
570 NodeXML & operator=(
const Castable &c){
577 NodeXML & operator=(
const std::string &s){
583 NodeXML & operator=(
const char *s){
589 NodeXML & operator=(
const std::initializer_list<std::pair<const char *,const drain::Variable> > &l){
604 if ((
int)getType() != COMMENT){
626 else if (typeIs((
elem_t)STYLE)){
631 drain::StringTools::import(value, ctext);
646 void setStyle(
const S &value){
651 void setStyle(
const std::string & value){
654 mout.suspicious(
"setting style for undefined elem: ", *
this);
656 else if (type == STYLE){
657 mout.warn(
"setting style for STYLE elem: ", *
this);
662 void setStyle(
const char *value){
663 setStyle(std::string(value));
667 void setStyle(
const std::string & key,
const std::string & value){
671 this->style[key] = value;
684 void setStyle(
const std::string & key,
const std::initializer_list<V> &l){
691 this->style[key] = l;
701 void setStyle(
const std::string & key,
const V & value){
706 std::stringstream sstr;
709 mout.
warn(
"Check results: skipped ", sstr.str());
710 mout.
warn(
"Check results: applied ", value);
711 this->style[key] = value;
715 this->style[key] = value;
721 void setStyle(
const std::initializer_list<std::pair<const char *,const drain::Variable> > &l){
734 V::node_data_t::xml_node_t::docTypeToStream(ostr);
735 V::node_data_t::xml_node_t::toStream(ostr, tree);
742 std::ostream &
toStream(std::ostream &ostr,
const V & t,
const std::string & defaultTag =
"",
int indent=0);
753 for (
const auto & entry: xmldoc_attribs){
754 attribToStream(ostr, entry.first, entry.second);
766 const std::pair<key_t,NodeXML<T> > & entry(){
768 static const std::pair<key_t,NodeXML<T> > nodeEntry(getTag(E), elem);
778 typedef std::map<std::string,std::string> xmldoc_attrib_map_t;
780 static xmldoc_attrib_map_t xmldoc_attribs;
812typedef drain::UnorderedMultiTree<NodeXML<>,
false, NodeXML<>::path_t> TreeXML;
815template <
class E,
bool EX,
class P>
818 static const std::string & str(){
823 static const char* get(){
824 return str().c_str();
831TreeXML & TreeXML::addChild(
const TreeXML::key_t & key);
838bool XML::findById(
const T & t,
const std::string &
id,
typename T::path_t & result,
const typename T::path_t & path){
846 for (
const auto & entry: t){
847 if (
findById(entry.second,
id, result,
path_t(path, entry.first))){
860bool XML::findById(
const T & t,
const std::string &
id, NodeXML<>::path_list_t & result,
const path_t & path){
863 result.push_back(path);
866 for (
const auto & entry: t){
870 return !result.empty();
877template <
class T,
class N>
883 result.push_back(path);
886 for (
const auto & entry: t){
891 return !result.empty();
898template <
class T,
class N>
904 if (tags.count(t->getType()) > 0){
905 result.push_back(path);
908 for (
const auto & entry: t){
913 return !result.empty();
921template <
class T2,
class C>
923bool XML::findByClass(
const T2 & t,
const C & cls, XML::path_list_t & result,
const path_t & path){
927 if (t->classList.has(cls)){
928 result.push_back(path);
931 for (
const auto & entry: t){
936 return !result.empty();
940template <
class T2,
class C>
943 for (
const auto & entry: t){
944 if (entry.second->hasClass(cls)){
945 result.push_back(entry.first);
949 return !result.empty();
960std::ostream & operator<<(std::ostream &ostr,
const NodeXML<N> & node){
963 ostr <<
'<' << node.getTag() <<
'>' <<
' ';
968 if (!node.getAttributes().empty()){
972 if (!node.classList.empty()){
979 if (!node.style.empty()){
984 if (!node.ctext.empty()){
986 if (node.ctext.length() > 20){
987 ostr << node.ctext.substr(0, 15);
1006std::ostream &
NodeXML<N>::toStream(std::ostream & ostr,
const T & tree,
const std::string & defaultTag,
int indent){
1009 const typename T::container_t & children = tree.getChildren();
1013 std::string fill(2*indent,
' ');
1017 if (tree->isComment()){
1018 ostr <<
"<!-- " << tree->getTag() <<
' ' << tree->ctext;
1020 else if (tree->isCText()){
1021 ostr << tree->ctext;
1023 else if (tree->getTag().empty())
1024 ostr <<
'<' << defaultTag;
1026 ostr <<
'<' << tree->getTag();
1032 if (tree->typeIs((
elem_t)STYLE)){
1034 attribToStream(ostr,
"data-mode",
"experimental");
1038 else if (!tree->isCText()){
1040 if (!tree->classList.empty()){
1041 ostr <<
" class=\"";
1049 for (
const typename T::node_data_t::key_t & key: tree.data.getKeyList()){
1050 if (!tree.data[key].empty()){
1051 std::stringstream sstr;
1052 sstr << tree.data[key];
1053 if (!sstr.str().empty()){
1054 attribToStream(ostr, key, sstr.str());
1061 if (!tree->style.empty()){
1062 ostr <<
" style=\"";
1071 if (!tree.data.empty()){
1077 if (tree->isComment()){
1080 else if (tree->isCText()){
1083 else if (tree.data.isSelfClosing() &&
1084 (!tree->typeIs((
elem_t)STYLE)) && (!tree->typeIs((
elem_t)SCRIPT)) &&
1085 (children.empty()) && tree->ctext.empty() ){
1105 if (tree->typeIs((
elem_t)STYLE)){
1108 if (!tree->ctext.empty()){
1110 ostr << fill << tree->ctext <<
" /* CTEXT? */" <<
'\n';
1112 if (!tree->getAttributes().empty()){
1113 ostr <<
"\n\t /* <!-- DISCARDED attribs ";
1115 mout.
warn(
"STYLE elem contains attributes, probably meant as style: ", tree.data);
1117 ostr <<
" /--> */" <<
'\n';
1119 if (!tree->style.empty()){
1120 ostr << fill <<
"/** style obj **/" <<
'\n';
1121 for (
const auto & attr: tree->style){
1122 ostr << fill <<
" ";
1123 Sprinter::pairToStream(ostr, attr, StyleXML::styleRecordLayout);
1133 ostr << fill <<
"/* elems */" <<
'\n';
1134 for (
const auto & entry: tree.getChildren()){
1135 if (!entry.second->ctext.empty()){
1137 ostr << fill <<
" " << entry.first <<
" {" << entry.second->ctext <<
"} /* CTEXT */ \n";
1139 if (!entry.second->getAttributes().empty()){
1141 ostr << fill <<
" " << entry.first <<
" {\n";
1142 for (
const auto & attr: entry.second->getAttributes()){
1143 ostr << fill <<
" ";
1144 ostr << attr.first <<
':' << attr.second <<
';';
1150 ostr << fill <<
" }\n";
1162 if (tree->ctext.empty())
1165 ostr << tree->ctext;
1168 for (
const auto & entry: children){
1169 toStream(ostr, entry.second, entry.first, indent+1);
1176 if (tree->typeIs((
elem_t)STYLE) || !children.empty()){
1181 ostr <<
'<' <<
'/' << tree->getTag() <<
'>';
1194std::ostream & operator<<(std::ostream &ostr,
const TreeXML & t){
1196 TreeXML::node_data_t::docTypeToStream(ostr);
1197 TreeXML::node_data_t::toStream(ostr, t,
"");
void add(const std::string &arg, const TT &... args)
Add one or several classes.
Definition ClassXML.h:72
static const SprinterLayout layout
Uses spaces as separators.
Definition ClassXML.h:145
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
static std::ostream & docTypeToStream(std::ostream &ostr)
Write the XML definition beginning any XML document.
Definition TreeXML.h:751
void setStyle(const std::string &key, const std::initializer_list< V > &l)
Set style of an element.
Definition TreeXML.h:684
T elem_t
Tag type, CTEXT or COMMENT.
Definition TreeXML.h:347
NodeXML & setComment(const std::string &text="")
Make this node a comment. Contained tree will not be delete. In current version, attributes will be r...
Definition TreeXML.h:600
static std::ostream & docToStream(std::ostream &ostr, const V &tree)
Definition TreeXML.h:733
NodeXML & setText(const S &value)
Assign the text content of this node. If the node type is undefined, set it to CTEXT.
Definition TreeXML.h:619
static std::ostream & toStream(std::ostream &ostr, const V &t, const std::string &defaultTag="", int indent=0)
"Forward definition" of Tree::toOstream
void setStyle(const std::string &key, const V &value)
For element/class/id, assign ...
Definition TreeXML.h:701
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
void copyStruct(const ReferenceMap2< FlexibleVariable > &m, const T2 &src, T2 &dst, extLinkPolicy policy=RESERVE)
Experimental. Copies references and values of a structure to another.
Definition ReferenceMap.h:145
@ RESERVE
Definition ReferenceMap.h:131
map_t::iterator iterator
Needed?
Definition SmartMap.h:80
const map_t & getMap() const
Definition SmartMap.h:206
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
static const SprinterLayout xmlAttributeLayout
Like attributes in XML (HTML, SVG, ...) tags.
Definition Sprinter.h:227
static std::ostream & sequenceToStream(std::ostream &ostr, const T &x, const SprinterLayout &layout)
Convenience: if sequence type (array, list, set, map) not given, assume array.
Definition Sprinter.h:321
Definition StringBuilder.h:58
VariableT is a final class applied through typedefs Variable, Reference and FlexibleVariable.
Definition VariableT.h:87
Base class for XML "nodes", to be data elements T for drain::Tree<T>
Definition TreeXML.h:80
static bool findByClass(const T2 &t, const C &cls, std::list< path_elem_t > &result)
Finds child elements in an XML structure by class name.
Definition TreeXML.h:941
void addClass(const TT &... args)
Style class.
Definition TreeXML.h:220
void setId()
Makes ID a visible attribute.
Definition TreeXML.h:124
const std::string & getId() const
Returns ID of this element. Hopefully a unique ID...
Definition TreeXML.h:142
virtual void setAttribute(const std::string &key, const char *value)
Default implementation. Needed for handling units in strings, like "50%" or "640px".
Definition TreeXML.h:173
static bool findByClass(const V &t, const C &cls, path_list_t &result, const path_t &path=path_t())
Finds elements recursively in an XML structure by class name supplied as an enumeration type.
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 bool findById(const V &tree, const std::string &tag, path_list_t &result, const path_t &path=path_t())
Find the occurrence(s) of given ID using recursive breath-first search.
static bool findByTag(const V &tree, const T &tag, path_list_t &result, const path_t &path=path_t())
static bool findById(const V &tree, const std::string &tag, typename V::path_t &result, const typename V::path_t &path=path_t())
Find the first occurrence of given id using recursive breath-first search.
drain::Path< std::string,'/'> path_t
Tree path type.
Definition TreeXML.h:111
void setAttribute(const std::string &key, const V &value)
"Final" implementation.
Definition TreeXML.h:180
static bool findByTags(const V &tree, const std::set< T > &tags, path_list_t &result, const path_t &path=path_t())
"Forward definition"
bool hasClass(const V &cls) const
Definition TreeXML.h:238
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 TreeXML.h:130
Definition DataSelector.cpp:1277
Definition Sprinter.h:137
static const std::string name
Default implementation: name returned by std::type_info::name()
Definition Type.h:558