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;
|
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;
|
mstch::map retval;
|
||||||
|
|
||||||
for (const XPathElement* xpath : parNode.xpaths) {
|
for (const XPathElement* xpath : parNode.xpaths) {
|
||||||
assert(xpath);
|
assert(xpath);
|
||||||
std::cout << "Running query for \"" << xpath->name << "\"\n";
|
std::cout << "Running query for \"" << xpath->name << "\"\n";
|
||||||
|
@ -198,8 +226,16 @@ namespace duck { namespace sl {
|
||||||
|
|
||||||
for (auto& curr_struct : parNode.structs) {
|
for (auto& curr_struct : parNode.structs) {
|
||||||
assert(not curr_struct.name.empty());
|
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;
|
return retval;
|
||||||
|
@ -220,7 +256,7 @@ namespace duck { namespace sl {
|
||||||
assert(false); //not implemented
|
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));
|
curr_entry_map.merge(std::move(retval));
|
||||||
retval.swap(curr_entry_map);
|
retval.swap(curr_entry_map);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue