WiP - do item counting in mstch variants correctly.
This commit is contained in:
parent
8d2c9f9013
commit
a9ff092401
2 changed files with 125 additions and 4 deletions
85
map_form.txt
Normal file
85
map_form.txt
Normal file
|
@ -0,0 +1,85 @@
|
|||
apply {{mustache_name}} to {{pages}}
|
||||
A = /html/head/text()
|
||||
struct B
|
||||
C default("n/a") = //table[@class="wikitable sortable"]/tr/td[4]/a/text()
|
||||
D default("0") = //table[@class="wikitable sortable"]/tr/td[3]/text()
|
||||
struct E
|
||||
F = /html/head/inner_names/text()
|
||||
G = /html/head/inner_probabilities/text()
|
||||
end
|
||||
H = /html/head/inner_names/text()
|
||||
end
|
||||
I = /html/head/inner_names/text()
|
||||
end
|
||||
|
||||
==mustache_name
|
||||
blah
|
||||
==end
|
||||
|
||||
|
||||
The above should result in the following:
|
||||
|
||||
A[]
|
||||
B[] --- C
|
||||
--- D
|
||||
--- E[] --- F
|
||||
--- G
|
||||
--- H
|
||||
--- I[]
|
||||
|
||||
For example, given these query results:
|
||||
A[] = {a1, a2, a3}
|
||||
C = c1
|
||||
D[] = {d1, d2}
|
||||
F[] = {f1, f2, f3}
|
||||
G = g1
|
||||
h = h1
|
||||
i = i1
|
||||
|
||||
then the complete result in tree form shall be:
|
||||
|
||||
{
|
||||
A => [a1, a2, a3],
|
||||
B => [
|
||||
{
|
||||
C => c1,
|
||||
D => d1,
|
||||
E => [
|
||||
{
|
||||
F => f1,
|
||||
G => g1
|
||||
}, {
|
||||
F => f2,
|
||||
G => ""
|
||||
}, {
|
||||
F => f3,
|
||||
G => ""
|
||||
}
|
||||
],
|
||||
H => h1
|
||||
}, {
|
||||
C => "",
|
||||
D => d2,
|
||||
E => [
|
||||
{
|
||||
F => f1,
|
||||
G => g1
|
||||
}, {
|
||||
F => f2,
|
||||
G => ""
|
||||
}, {
|
||||
F => f3,
|
||||
G => ""
|
||||
}
|
||||
],
|
||||
H => ""
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
Please note that:
|
||||
|
||||
* arrays inside a struct turn the struct itself into an array, while its items become just single item values
|
||||
* if a struct contains no arrays, then the struct shall not become an array - that is, a struct generates an array with as many elements as the largest element in the struct itself
|
||||
* there are as many of any one struct as the size of the largest array inside it
|
||||
* nested structs get duplicated in every outer struct they are part of; in the example above E has as many elements as there items in F (2, the largest between F and G), and the whole array of E is duplicated in every element of B
|
|
@ -173,8 +173,36 @@ namespace duck { namespace sl {
|
|||
MustacheEntry* m_current_mustache;
|
||||
};
|
||||
|
||||
mstch::map to_mustache_dict_recursive (const EntryNode& parNode, std::string_view parSrc, XPathRunner& parRunner) {
|
||||
struct ItemCountingVisitor : public boost::static_visitor<std::size_t> {
|
||||
template <typename T>
|
||||
std::size_t operator()(const T&) const { return 1; }
|
||||
std::size_t operator()(const mstch::array& parItem) const { return parItem.size(); }
|
||||
std::size_t operator()(const std::vector<std::string>& parItem) const { return parItem.size(); }
|
||||
};
|
||||
|
||||
std::size_t largest_array_size_in (mstch::map& parMap) {
|
||||
typedef ItemCountingVisitor ITC;
|
||||
using boost::apply_visitor;
|
||||
|
||||
if (parMap.empty())
|
||||
return 0;
|
||||
|
||||
return apply_visitor(
|
||||
ITC(),
|
||||
std::max_element(parMap.begin(), parMap.end(), [](const auto& a, const auto& b) {
|
||||
return apply_visitor(ITC(), a.second) < apply_visitor(ITC(), b.second);
|
||||
})->second
|
||||
);
|
||||
}
|
||||
|
||||
mstch::map to_mustache_dict_recursive (
|
||||
const EntryNode& parNode,
|
||||
std::string_view parSrc,
|
||||
XPathRunner& parRunner,
|
||||
bool parMakeVecsSameSize
|
||||
) {
|
||||
mstch::map retval;
|
||||
|
||||
for (const XPathElement* xpath : parNode.xpaths) {
|
||||
assert(xpath);
|
||||
std::cout << "Running query for \"" << xpath->name << "\"\n";
|
||||
|
@ -198,8 +226,16 @@ namespace duck { namespace sl {
|
|||
|
||||
for (auto& curr_struct : parNode.structs) {
|
||||
assert(not curr_struct.name.empty());
|
||||
retval[std::string(curr_struct.name)] =
|
||||
to_mustache_dict_recursive(curr_struct, parSrc, parRunner);
|
||||
|
||||
mstch::array extracted_struct;
|
||||
auto new_struct = to_mustache_dict_recursive(curr_struct, parSrc, parRunner, false);
|
||||
const std::size_t extracted_struct_size = largest_array_size_in(new_struct);
|
||||
std::cout << "Largest array size in \"" << curr_struct.name << "\" = " << extracted_struct_size << '\n';
|
||||
for (auto&& itm : new_struct) {
|
||||
|
||||
}
|
||||
|
||||
// retval[std::string(curr_struct.name)] =
|
||||
}
|
||||
|
||||
return retval;
|
||||
|
@ -220,7 +256,7 @@ namespace duck { namespace sl {
|
|||
assert(false); //not implemented
|
||||
}
|
||||
|
||||
mstch::map curr_entry_map = to_mustache_dict_recursive(entry.second, src_url, parRunner);
|
||||
mstch::map curr_entry_map = to_mustache_dict_recursive(entry.second, src_url, parRunner, false);
|
||||
curr_entry_map.merge(std::move(retval));
|
||||
retval.swap(curr_entry_map);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue