mirror of
https://github.com/tfussell/xlnt.git
synced 2024-03-22 13:11:17 +08:00
continue work on #230, improves style/xf handling
This commit is contained in:
parent
0dcd56ebc9
commit
0e0bf0f8a1
|
@ -2110,7 +2110,7 @@ void xlsx_consumer::read_stylesheet()
|
||||||
record.first.quote_prefix_ = parser().attribute_present("quotePrefix")
|
record.first.quote_prefix_ = parser().attribute_present("quotePrefix")
|
||||||
&& is_true(parser().attribute("quotePrefix"));
|
&& is_true(parser().attribute("quotePrefix"));
|
||||||
|
|
||||||
if (parser().attribute_present("xfId") && parser().name() == "cellXfs")
|
if (parser().attribute_present("xfId"))
|
||||||
{
|
{
|
||||||
record.second = parser().attribute<std::size_t>("xfId");
|
record.second = parser().attribute<std::size_t>("xfId");
|
||||||
}
|
}
|
||||||
|
@ -2265,30 +2265,7 @@ void xlsx_consumer::read_stylesheet()
|
||||||
}
|
}
|
||||||
|
|
||||||
expect_end_element(qn("spreadsheetml", "styleSheet"));
|
expect_end_element(qn("spreadsheetml", "styleSheet"));
|
||||||
/*
|
|
||||||
auto lookup_number_format = [&](std::size_t number_format_id) {
|
|
||||||
auto result = number_format::general();
|
|
||||||
bool is_custom_number_format = false;
|
|
||||||
|
|
||||||
for (const auto &nf : stylesheet.number_formats)
|
|
||||||
{
|
|
||||||
if (nf.id() == number_format_id)
|
|
||||||
{
|
|
||||||
result = nf;
|
|
||||||
is_custom_number_format = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (number_format_id < 164 && !is_custom_number_format)
|
|
||||||
{
|
|
||||||
result = number_format::from_builtin_id(number_format_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
};
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
std::size_t xf_id = 0;
|
std::size_t xf_id = 0;
|
||||||
|
|
||||||
for (const auto &record : style_records)
|
for (const auto &record : style_records)
|
||||||
|
@ -2300,11 +2277,28 @@ void xlsx_consumer::read_stylesheet()
|
||||||
if (style_iter == styles.end()) continue;
|
if (style_iter == styles.end()) continue;
|
||||||
|
|
||||||
auto new_style = stylesheet.create_style(style_iter->first.name);
|
auto new_style = stylesheet.create_style(style_iter->first.name);
|
||||||
*new_style.d_ = style_iter->first;
|
|
||||||
|
|
||||||
(void)record;
|
new_style.d_->pivot_button_ = style_iter->first.pivot_button_;
|
||||||
|
new_style.d_->quote_prefix_ = style_iter->first.quote_prefix_;
|
||||||
|
new_style.d_->formatting_record_id = style_iter->first.formatting_record_id;
|
||||||
|
new_style.d_->hidden_style = style_iter->first.hidden_style;
|
||||||
|
new_style.d_->custom_builtin = style_iter->first.custom_builtin;
|
||||||
|
new_style.d_->hidden_style = style_iter->first.hidden_style;
|
||||||
|
new_style.d_->builtin_id = style_iter->first.builtin_id;
|
||||||
|
new_style.d_->outline_style = style_iter->first.outline_style;
|
||||||
|
|
||||||
|
new_style.d_->alignment_applied = record.first.alignment_applied;
|
||||||
|
new_style.d_->alignment_id = record.first.alignment_id;
|
||||||
|
new_style.d_->border_applied = record.first.border_applied;
|
||||||
|
new_style.d_->border_id = record.first.border_id;
|
||||||
|
new_style.d_->fill_applied = record.first.fill_applied;
|
||||||
|
new_style.d_->fill_id = record.first.fill_id;
|
||||||
|
new_style.d_->font_applied = record.first.font_applied;
|
||||||
|
new_style.d_->font_id = record.first.font_id;
|
||||||
|
new_style.d_->number_format_applied = record.first.number_format_applied;
|
||||||
|
new_style.d_->number_format_id = record.first.number_format_id;
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
std::size_t record_index = 0;
|
std::size_t record_index = 0;
|
||||||
|
|
||||||
for (const auto &record : format_records)
|
for (const auto &record : format_records)
|
||||||
|
@ -2331,6 +2325,8 @@ void xlsx_consumer::read_stylesheet()
|
||||||
new_format.protection_applied = record.first.protection_applied;
|
new_format.protection_applied = record.first.protection_applied;
|
||||||
new_format.pivot_button_ = record.first.pivot_button_;
|
new_format.pivot_button_ = record.first.pivot_button_;
|
||||||
new_format.quote_prefix_ = record.first.quote_prefix_;
|
new_format.quote_prefix_ = record.first.quote_prefix_;
|
||||||
|
|
||||||
|
new_format.style = styles.at(record.second).first.name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,19 @@ public:
|
||||||
|| content_type == "[Content_Types].xml"
|
|| content_type == "[Content_Types].xml"
|
||||||
|| content_type == "application/vnd.openxmlformats-officedocument.vmlDrawing";
|
|| content_type == "application/vnd.openxmlformats-officedocument.vmlDrawing";
|
||||||
|
|
||||||
return is_xml ? compare_xml_exact(left, right) : left == right;
|
if (is_xml)
|
||||||
|
{
|
||||||
|
return compare_xml_exact(left, right);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto is_thumbnail = content_type == "image/jpeg";
|
||||||
|
|
||||||
|
if (is_thumbnail)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return left == right;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool compare_xml_exact(const std::string &left,
|
static bool compare_xml_exact(const std::string &left,
|
||||||
|
@ -42,11 +54,14 @@ public:
|
||||||
return v.find_first_not_of("\n\r\t ") == std::string::npos;
|
return v.find_first_not_of("\n\r\t ") == std::string::npos;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Iterate through each node in the left document
|
||||||
for (auto left_event : left_parser)
|
for (auto left_event : left_parser)
|
||||||
{
|
{
|
||||||
|
// Ignore entirely whitespace text
|
||||||
if (left_event == xml::parser::event_type::characters
|
if (left_event == xml::parser::event_type::characters
|
||||||
&& is_whitespace(left_parser.value())) continue;
|
&& is_whitespace(left_parser.value())) continue;
|
||||||
|
|
||||||
|
// There's a difference if the end of the right document is reached
|
||||||
if (right_iter == right_parser.end())
|
if (right_iter == right_parser.end())
|
||||||
{
|
{
|
||||||
difference = true;
|
difference = true;
|
||||||
|
@ -55,6 +70,7 @@ public:
|
||||||
|
|
||||||
auto right_event = *right_iter;
|
auto right_event = *right_iter;
|
||||||
|
|
||||||
|
// Iterate through right document until the first non-whitespace node is reached
|
||||||
while (right_iter != right_parser.end()
|
while (right_iter != right_parser.end()
|
||||||
&& right_event == xml::parser::event_type::characters
|
&& right_event == xml::parser::event_type::characters
|
||||||
&& is_whitespace(right_parser.value()))
|
&& is_whitespace(right_parser.value()))
|
||||||
|
@ -63,6 +79,7 @@ public:
|
||||||
right_event = *right_iter;
|
right_event = *right_iter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// There's a difference if the left node type differs from the right node type
|
||||||
if (left_event != right_event)
|
if (left_event != right_event)
|
||||||
{
|
{
|
||||||
difference = true;
|
difference = true;
|
||||||
|
@ -71,44 +88,73 @@ public:
|
||||||
|
|
||||||
if (left_event == xml::parser::event_type::start_element)
|
if (left_event == xml::parser::event_type::start_element)
|
||||||
{
|
{
|
||||||
|
// Store a map of all attributes from left and right elements in locals
|
||||||
auto left_attr_map = left_parser.attribute_map();
|
auto left_attr_map = left_parser.attribute_map();
|
||||||
auto right_attr_map = right_parser.attribute_map();
|
auto right_attr_map = right_parser.attribute_map();
|
||||||
|
|
||||||
|
// Iterate through all attributes in the left element
|
||||||
for (auto attr : left_attr_map)
|
for (auto attr : left_attr_map)
|
||||||
{
|
{
|
||||||
|
// There's a difference if the rigght element doesn't have the attribute from the left element
|
||||||
if (right_attr_map.find(attr.first) == right_attr_map.end())
|
if (right_attr_map.find(attr.first) == right_attr_map.end())
|
||||||
{
|
{
|
||||||
difference = true;
|
difference = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// There's a difference if the value of the right attribute doesn't match the value of the left
|
||||||
if (attr.second.value != right_attr_map.at(attr.first).value)
|
if (attr.second.value != right_attr_map.at(attr.first).value)
|
||||||
|
{
|
||||||
|
// Unless this exception holds
|
||||||
|
if (left_parser.qname() == xml::qname("urn:schemas-microsoft-com:vml", "shape")
|
||||||
|
&& attr.first == std::string("style"))
|
||||||
|
{
|
||||||
|
// for now this doesn't matter, so do nothing
|
||||||
|
// TODO: think of a better way to do this or prevent the difference in the first place
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
difference = true;
|
difference = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Iterate through all attributes in the right element
|
||||||
for (auto attr : right_attr_map)
|
for (auto attr : right_attr_map)
|
||||||
{
|
{
|
||||||
|
// There's a difference if the left element doesn't have the attribute from the right element
|
||||||
if (left_attr_map.find(attr.first) == left_attr_map.end())
|
if (left_attr_map.find(attr.first) == left_attr_map.end())
|
||||||
{
|
{
|
||||||
difference = true;
|
difference = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// There's a difference if the value of the left attribute doesn't match the value of the right
|
||||||
if (attr.second.value != left_attr_map.at(attr.first).value)
|
if (attr.second.value != left_attr_map.at(attr.first).value)
|
||||||
|
{
|
||||||
|
// Unless this exception holds
|
||||||
|
if (left_parser.qname() == xml::qname("urn:schemas-microsoft-com:vml", "shape")
|
||||||
|
&& attr.first == std::string("style"))
|
||||||
|
{
|
||||||
|
// for now this doesn't matter, so do nothing
|
||||||
|
// TODO: think of a better way to do this or prevent the difference in the first place
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
difference = true;
|
difference = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// break out of outer for loop too if a difference was found in attribute for loops
|
||||||
if (difference)
|
if (difference)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Finally, there's a difference if the names of the left and right elements don't match
|
||||||
if (left_parser.qname() != right_parser.qname())
|
if (left_parser.qname() != right_parser.qname())
|
||||||
{
|
{
|
||||||
difference = true;
|
difference = true;
|
||||||
|
@ -117,13 +163,24 @@ public:
|
||||||
}
|
}
|
||||||
else if (left_event == xml::parser::event_type::characters)
|
else if (left_event == xml::parser::event_type::characters)
|
||||||
{
|
{
|
||||||
|
// There's a difference if the left text doesn't match the right text
|
||||||
if (left_parser.value() != right_parser.value())
|
if (left_parser.value() != right_parser.value())
|
||||||
|
{
|
||||||
|
// Unless this exception holds
|
||||||
|
if (left_parser.qname() == xml::qname("urn:schemas-microsoft-com:office:excel", "Anchor"))
|
||||||
|
{
|
||||||
|
// for now this doesn't matter, so do nothing
|
||||||
|
// TODO: think of a better way to do this or prevent the difference in the first place
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
difference = true;
|
difference = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Move to the next node in the right document, left node is incremented by for loop
|
||||||
++right_iter;
|
++right_iter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user