Lumiera  0.pre.03
»edit your freedom«
text-template-gen-node-binding.hpp
Go to the documentation of this file.
1 /*
2  TEXT-TEMPLATE-GEN-NODE-BINDING.hpp - data binding adapter for ETD
3 
4  Copyright (C) Lumiera.org
5  2024, Hermann Vosseler <Ichthyostega@web.de>
6 
7  This program is free software; you can redistribute it and/or
8  modify it under the terms of the GNU General Public License as
9  published by the Free Software Foundation; either version 2 of
10  the License, or (at your option) any later version.
11 
12  This program is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with this program; if not, write to the Free Software
19  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 
21 */
22 
23 
56 #ifndef LIB_TEXT_TEMPLATE_GEN_NODE_BINDING_H
57 #define LIB_TEXT_TEMPLATE_GEN_NODE_BINDING_H
58 
59 
60 #include "lib/diff/gen-node.hpp"
61 #include "lib/text-template.hpp"
62 
63 #include <string>
64 
65 
66 namespace lib {
67 
68  using std::string;
69 
70 
71  namespace text_template {
72 
73  /* ======= Data binding for GenNode (ETD) ======= */
74 
81  template<>
82  struct DataSource<diff::GenNode>
83  {
84  using Node = diff::GenNode;
85  using Rec = diff::Rec;
86 
87  Node const* data_;
88  DataSource* parScope_;
89  bool isSubScope() { return bool(parScope_); }
90 
91  DataSource(Node const& root)
92  : data_{&root}
93  , parScope_{nullptr}
94  { }
95 
96 
97  using Value = std::string;
98  using Iter = Rec::scopeIter;
99 
100  Node const*
101  findNode (string key)
102  {
103  if (data_->isNested())
104  {// standard case: Attribute lookup
105  Rec const& record = data_->data.get<Rec>();
106  if (record.hasAttribute (key))
107  return & record.get (key);
108  }
109  else
110  if ("value" == key) // special treatment for a »pseudo context«
111  return data_; // comprised only of a single value node
112  // ask parent scope...
113  if (isSubScope())
114  return parScope_->findNode (key);
115 
116  return nullptr;
117  }
118 
119  bool
120  contains (string key)
121  {
122  return bool(findNode (key));
123  }
124 
125  Value
126  retrieveContent (string key)
127  {
128  return renderCompact (*findNode(key));
129  }
130 
131  Iter
132  getSequence (string key)
133  {
134  if (not contains(key))
135  return Iter{};
136  Node const* node = findNode (key);
137  if (not node->isNested())
138  return Iter{};
139  else
140  return node->data.get<Rec>().scope();
141  }
142 
143  DataSource
144  openContext (Iter& iter)
145  {
146  REQUIRE (iter);
147  DataSource nested{*this};
148  nested.parScope_ = this;
149  nested.data_ = & *iter;
150  return nested;
151  }
152  };
153 
154  }// namespace text_template
155 
156 }// namespace lib
157 #endif /*LIB_TEXT_TEMPLATE_GEN_NODE_BINDING_H*/
Binding to a specific data source.
Implementation namespace for support and library code.
A minimalistic text templating engine with flexible data binding.
Generic building block for tree shaped (meta)data structures.
object-like record of data.
Definition: record.hpp:150
generic data element node within a tree
Definition: gen-node.hpp:231