mirror of
https://github.com/ONLYOFFICE/core.git
synced 2026-04-07 13:55:33 +08:00
refactoring convert ods formula
This commit is contained in:
@ -79,7 +79,7 @@ namespace formulasconvert {
|
||||
static bool convert_with_absolute;
|
||||
static bool convert_with_TableName;
|
||||
static std::wstring table_name_;
|
||||
|
||||
static std::vector<std::map<std::wstring, std::wstring>> mapReplacements;
|
||||
//-------------------------------------------------------------------------------------------------------------
|
||||
static std::wstring replace_apersand_formater(boost::wsmatch const & what)
|
||||
{
|
||||
@ -146,75 +146,29 @@ namespace formulasconvert {
|
||||
|
||||
static void replace_tmp_back(std::wstring &expr)
|
||||
{
|
||||
XmlUtils::replace_all( expr, L"ТОСHKA", L".");
|
||||
XmlUtils::replace_all( expr, L"VOSKL", L"!");
|
||||
|
||||
XmlUtils::replace_all( expr, L"SCOBCAIN", L"(");
|
||||
XmlUtils::replace_all( expr, L"SCOBCAOUT", L")");
|
||||
|
||||
//XmlUtils::replace_all( expr, L"KVADRATIN", L"[");
|
||||
//XmlUtils::replace_all( expr, L"KVADRATOUT", L"]");
|
||||
|
||||
XmlUtils::replace_all( expr, L"PROBEL", L" ");
|
||||
//XmlUtils::replace_all( expr, L"APOSTROF", L"'");
|
||||
//XmlUtils::replace_all( expr, L"KAVYCHKA", L"\"");
|
||||
XmlUtils::replace_all(expr, L"APERSAND", L"&");
|
||||
for (auto key : mapReplacements.back())
|
||||
{
|
||||
XmlUtils::replace_all(expr, key.first, key.second);
|
||||
}
|
||||
}
|
||||
static void replace_tmp(std::wstring &expr)
|
||||
{
|
||||
// XmlUtils::replace_all( expr, L".", L"ТОСHKA");
|
||||
// XmlUtils::replace_all( expr, L"!", L"VOSKL");
|
||||
//std::random_device genSource;
|
||||
//std::uniform_int_distribution<> generator(0, 23);
|
||||
//for (int index = 0; index < 5; index++)
|
||||
//{
|
||||
// key += wchar_t(L'a' + generator(genSource));
|
||||
//}
|
||||
|
||||
// XmlUtils::replace_all( expr, L"(", L"SCOBCAIN");
|
||||
// XmlUtils::replace_all( expr, L")", L"SCOBCAOUT");
|
||||
|
||||
// //XmlUtils::replace_all( expr, L"[", L"KVADRATIN");
|
||||
// //XmlUtils::replace_all( expr, L"]", L"KVADRATOUT");
|
||||
//
|
||||
// XmlUtils::replace_all( expr, L" ", L"PROBEL");
|
||||
//// XmlUtils::replace_all( expr, L"'", L"APOSTROF");
|
||||
//// XmlUtils::replace_all( expr, L"\"", L"KAVYCHKA");
|
||||
|
||||
std::wstring result;
|
||||
|
||||
size_t pos = 0, size = expr.length();
|
||||
|
||||
while(pos < size)
|
||||
std::wstring key = L"aaaaaaaaaaaaaaaaaaaaaaaa";
|
||||
for (unsigned i = 0; i < 23; ++i)
|
||||
{
|
||||
switch(expr[pos])
|
||||
{
|
||||
case '.':
|
||||
{
|
||||
result += L"ТОСHKA";
|
||||
}break;
|
||||
case '!':
|
||||
{
|
||||
result += L"VOSKL";
|
||||
}break;
|
||||
case '(':
|
||||
{
|
||||
result += L"SCOBCAIN";
|
||||
}break;
|
||||
case ')':
|
||||
{
|
||||
result += L"SCOBCAOUT";
|
||||
}break;
|
||||
case ' ':
|
||||
{
|
||||
result += L"PROBEL";
|
||||
}break;
|
||||
case '&':
|
||||
{
|
||||
result += L"APERSAND";
|
||||
}break;
|
||||
default:
|
||||
{
|
||||
result += expr[pos];
|
||||
}break;
|
||||
}
|
||||
pos++;
|
||||
unsigned j = rand() % (i + 1);
|
||||
key[i] = key[j];
|
||||
key[j] = wchar_t(L'a' + i);
|
||||
}
|
||||
expr = result;
|
||||
mapReplacements.back().insert(std::make_pair(key, expr));
|
||||
expr = key;
|
||||
}
|
||||
static std::wstring convert_scobci(boost::wsmatch const & what)
|
||||
{
|
||||
@ -278,12 +232,16 @@ namespace formulasconvert {
|
||||
bool odf2oox_converter::Impl::convert_with_TableName = true;
|
||||
std::wstring odf2oox_converter::Impl::table_name_ = L"";
|
||||
bool odf2oox_converter::Impl::convert_with_absolute = false;
|
||||
|
||||
std::vector<std::map<std::wstring, std::wstring>> odf2oox_converter::Impl::mapReplacements;
|
||||
|
||||
std::unordered_map<std::wstring, int> &odf2oox_converter::Impl::mapExternalLink_ = oox::xlsx_conversion_context::mapExternalLink_;
|
||||
|
||||
bool odf2oox_converter::Impl::find_first_last_ref(std::wstring const & expr, std::wstring & table,std::wstring & ref_first,std::wstring & ref_last)
|
||||
{
|
||||
std::wstring workstr = expr;
|
||||
|
||||
mapReplacements.emplace_back();
|
||||
|
||||
workstr = boost::regex_replace(
|
||||
workstr,
|
||||
boost::wregex(L"('.*?')|(\".*?\")"),
|
||||
@ -317,6 +275,7 @@ namespace formulasconvert {
|
||||
}
|
||||
replace_tmp_back( table );
|
||||
|
||||
mapReplacements.pop_back();
|
||||
return res;
|
||||
}
|
||||
|
||||
@ -637,7 +596,9 @@ namespace formulasconvert {
|
||||
bool isFormula = check_formula(workstr);
|
||||
|
||||
//экранирование
|
||||
workstr = boost::regex_replace(workstr,
|
||||
mapReplacements.emplace_back();
|
||||
|
||||
workstr = boost::regex_replace(workstr,
|
||||
boost::wregex(L"('.*?')|(\".*?\")"),
|
||||
&convert_scobci, boost::match_default | boost::format_all);
|
||||
|
||||
@ -671,11 +632,14 @@ namespace formulasconvert {
|
||||
//-----------------------------------------------------------
|
||||
replace_tmp_back(workstr);
|
||||
|
||||
mapReplacements.pop_back();
|
||||
return workstr;
|
||||
}
|
||||
|
||||
void odf2oox_converter::Impl::split_distance_by(const std::wstring& expr, const std::wstring& by, std::vector<std::wstring>& out)
|
||||
{
|
||||
mapReplacements.emplace_back();
|
||||
|
||||
std::wstring workstr = boost::regex_replace(
|
||||
expr,
|
||||
boost::wregex(L"('.*?')|(\".*?\")"),
|
||||
@ -687,6 +651,7 @@ namespace formulasconvert {
|
||||
{
|
||||
replace_tmp_back(out[i]);
|
||||
}
|
||||
mapReplacements.pop_back();
|
||||
}
|
||||
|
||||
//Sheet2.C3:Sheet2.C19 Sheet2.L29:Sheet2.L36
|
||||
@ -701,6 +666,8 @@ namespace formulasconvert {
|
||||
|
||||
std::wstring odf2oox_converter::Impl::convert_chart_distance(const std::wstring& expr)
|
||||
{
|
||||
mapReplacements.emplace_back();
|
||||
|
||||
std::wstring workstr = boost::regex_replace(
|
||||
is_forbidden(expr),
|
||||
boost::wregex(L"('.*?')|(\".*?\")"),
|
||||
@ -758,6 +725,7 @@ namespace formulasconvert {
|
||||
}
|
||||
replace_tmp_back( result );
|
||||
|
||||
mapReplacements.pop_back();
|
||||
return result.substr(0, result.size() - 1);// минус последняя лишняя запятая
|
||||
}
|
||||
std::wstring odf2oox_converter::Impl::convert_named_ref(const std::wstring& expr, bool withTableName, std::wstring separator, bool bAbsoluteAlways)
|
||||
@ -766,6 +734,8 @@ namespace formulasconvert {
|
||||
|
||||
std::wstring workstr = expr;
|
||||
|
||||
mapReplacements.emplace_back();
|
||||
|
||||
workstr = boost::regex_replace(
|
||||
workstr,
|
||||
boost::wregex(L"('.*?')|(\".*?\")"),
|
||||
@ -784,6 +754,7 @@ namespace formulasconvert {
|
||||
{
|
||||
replace_tmp_back( table_name_ );
|
||||
}
|
||||
mapReplacements.pop_back();
|
||||
return workstr;
|
||||
}
|
||||
std::wstring odf2oox_converter::Impl::convert_named_expr(const std::wstring& expr, bool withTableName, bool bAbsoluteAlways)
|
||||
@ -798,12 +769,12 @@ namespace formulasconvert {
|
||||
}
|
||||
else
|
||||
{
|
||||
mapReplacements.emplace_back();
|
||||
|
||||
workstr = boost::regex_replace(
|
||||
workstr,
|
||||
boost::wregex(L"('.*?')|(\".*?\")"),
|
||||
&convert_scobci, boost::match_default | boost::format_all);
|
||||
|
||||
|
||||
workstr = replace_cells_range(workstr, withTableName, bAbsoluteAlways);
|
||||
replace_semicolons(workstr);
|
||||
@ -822,6 +793,7 @@ namespace formulasconvert {
|
||||
{
|
||||
replace_tmp_back(table_name_);
|
||||
}
|
||||
mapReplacements.pop_back();
|
||||
}
|
||||
return workstr;
|
||||
}
|
||||
|
||||
@ -36,6 +36,7 @@
|
||||
|
||||
#include"../../OOXML/Base/Unit.h"
|
||||
#include "boost/lexical_cast.hpp"
|
||||
//#include <random>
|
||||
|
||||
namespace cpdoccore {
|
||||
namespace formulasconvert {
|
||||
@ -76,6 +77,8 @@ public:
|
||||
static std::wstring replace_arguments(boost::wsmatch const & what);
|
||||
static std::wstring convert_scobci(boost::wsmatch const & what);
|
||||
|
||||
static std::vector<std::map<std::wstring, std::wstring>> mapReplacements;
|
||||
|
||||
static std::wstring replace_tilda_formater(boost::wsmatch const & what)
|
||||
{
|
||||
if (what[1].matched)
|
||||
@ -132,227 +135,37 @@ public:
|
||||
|
||||
return L"";
|
||||
}
|
||||
static void oox_replace_tmp_back(std::wstring &expr)
|
||||
static void oox_replace_tmp_back(std::wstring& expr)
|
||||
{
|
||||
std::wstring result;
|
||||
|
||||
size_t pos = 0, size = expr.length();
|
||||
|
||||
while(pos < size)
|
||||
for (auto key : mapReplacements.back())
|
||||
{
|
||||
if (pos + 5 >= size)
|
||||
{
|
||||
result += expr[pos++];
|
||||
continue;
|
||||
}
|
||||
switch(expr[pos])
|
||||
{
|
||||
case 'M':
|
||||
{
|
||||
if ((pos + 5 <= size) && (expr.substr(pos, 5) == L"MINYS"))
|
||||
{
|
||||
result += L"-"; pos += 5;
|
||||
}
|
||||
else
|
||||
{
|
||||
result += expr[pos++];
|
||||
}
|
||||
}break;
|
||||
case 'T':
|
||||
{
|
||||
if ((pos + 6 <= size) && (expr.substr(pos, 6) == L"TОСHKA"))
|
||||
{
|
||||
result += L"."; pos += 6;
|
||||
}
|
||||
else
|
||||
{
|
||||
result += expr[pos++];
|
||||
}
|
||||
}break;
|
||||
case 'V':
|
||||
{
|
||||
if ((pos + 5 <= size) && (expr.substr(pos, 5) == L"VOSKL"))
|
||||
{
|
||||
result += L"!"; pos += 5;
|
||||
}
|
||||
else
|
||||
{
|
||||
result += expr[pos++];
|
||||
}
|
||||
}break;
|
||||
case 'S':
|
||||
{
|
||||
if ((pos + 8 <= size) && (expr.substr(pos, 8) == L"SCOBCAIN"))
|
||||
{
|
||||
result += L"("; pos += 8;
|
||||
}
|
||||
else if ((pos + 9 <= size) && (expr.substr(pos, 9) == L"SCOBCAOUT"))
|
||||
{
|
||||
result += L")"; pos += 9;
|
||||
}
|
||||
else
|
||||
{
|
||||
result += expr[pos++];
|
||||
}
|
||||
}break;
|
||||
case 'K':
|
||||
{
|
||||
if ((pos + 9 <= size) && (expr.substr(pos, 9) == L"KVADRATIN"))
|
||||
{
|
||||
result += L"["; pos += 9;
|
||||
}
|
||||
else if ((pos + 10 <= size) && (expr.substr(pos, 10) == L"KVADRATOUT"))
|
||||
{
|
||||
result += L"]"; pos += 10;
|
||||
}
|
||||
else if ((pos + 8 <= size) && (expr.substr(pos, 8) == L"KAVYCHKA"))
|
||||
{
|
||||
result += L"\""; pos += 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
result += expr[pos++];
|
||||
}
|
||||
}break;
|
||||
case 'P':
|
||||
{
|
||||
if ((pos + 6 <= size) && (expr.substr(pos, 6) == L"PROBEL"))
|
||||
{
|
||||
result += L" "; pos += 6;
|
||||
}
|
||||
else
|
||||
{
|
||||
result += expr[pos++];
|
||||
}
|
||||
}break;
|
||||
case 'A':
|
||||
{
|
||||
if ((pos + 8 <= size) && (expr.substr(pos, 8) == L"APOSTROF"))
|
||||
{
|
||||
result += L"'"; pos += 8;
|
||||
}
|
||||
else if ((pos + 8 <= size) && (expr.substr(pos, 8) == L"APERSAND"))
|
||||
{
|
||||
result += L"&"; pos += 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
result += expr[pos++];
|
||||
}
|
||||
}break;
|
||||
case 'Z':
|
||||
{
|
||||
if ((pos + 9 <= size) && (expr.substr(pos, 9) == L"ZAPYATAYA"))
|
||||
{
|
||||
result += L","; pos += 9;
|
||||
}
|
||||
else
|
||||
{
|
||||
result += expr[pos++];
|
||||
}
|
||||
}break;
|
||||
default:
|
||||
{
|
||||
result += expr[pos++];
|
||||
}break;
|
||||
}
|
||||
XmlUtils::replace_all(expr, key.first, key.second);
|
||||
}
|
||||
expr = result;
|
||||
//XmlUtils::replace_all( expr, L"MINYS", L"-");
|
||||
//XmlUtils::replace_all( expr, L"TОСHKA", L".");
|
||||
//XmlUtils::replace_all( expr, L"VOSKL", L"!");
|
||||
|
||||
//XmlUtils::replace_all( expr, L"SCOBCAIN", L"(");
|
||||
//XmlUtils::replace_all( expr, L"SCOBCAOUT", L")");
|
||||
XmlUtils::replace_all(expr, L"KVADRATIN", L"[");
|
||||
XmlUtils::replace_all(expr, L"KVADRATOUT", L"]");
|
||||
|
||||
//XmlUtils::replace_all( expr, L"KVADRATIN", L"[");
|
||||
//XmlUtils::replace_all( expr, L"KVADRATOUT", L"]");
|
||||
//
|
||||
//XmlUtils::replace_all( expr, L"PROBEL", L" ");
|
||||
//XmlUtils::replace_all( expr, L"APOSTROF", L"'");
|
||||
//XmlUtils::replace_all( expr, L"KAVYCHKA", L"\"");
|
||||
return;
|
||||
}
|
||||
|
||||
static void oox_replace_tmp(std::wstring &expr)
|
||||
{
|
||||
std::wstring result;
|
||||
//std::random_device genSource;
|
||||
//std::uniform_int_distribution<> generator(0, 23);
|
||||
//for (int index = 0; index < 5; index++)
|
||||
//{
|
||||
// key += wchar_t(L'a' + generator(genSource));
|
||||
//}
|
||||
|
||||
size_t pos = 0, size = expr.length();
|
||||
|
||||
while(pos < size)
|
||||
std::wstring key = L"aaaaaaaaaaaaaaaaaaaaaaaa";
|
||||
for (unsigned i = 0; i < 23; ++i)
|
||||
{
|
||||
switch(expr[pos])
|
||||
{
|
||||
case '-':
|
||||
{
|
||||
result += L"MINYS";
|
||||
}break;
|
||||
case '.':
|
||||
{
|
||||
result += L"TОСHKA";
|
||||
}break;
|
||||
case ',':
|
||||
{
|
||||
result += L"ZAPYATAYA";
|
||||
}break;
|
||||
case '!':
|
||||
{
|
||||
result += L"VOSKL";
|
||||
}break;
|
||||
case '(':
|
||||
{
|
||||
result += L"SCOBCAIN";
|
||||
}break;
|
||||
case ')':
|
||||
{
|
||||
result += L"SCOBCAOUT";
|
||||
}break;
|
||||
case '[':
|
||||
{
|
||||
result += L"KVADRATIN";
|
||||
}break;
|
||||
case ']':
|
||||
{
|
||||
result += L"KVADRATOUT";
|
||||
}break;
|
||||
case ' ':
|
||||
{
|
||||
result += L"PROBEL";
|
||||
}break;
|
||||
case '\'':
|
||||
{
|
||||
result += L"APOSTROF";
|
||||
}break;
|
||||
case '\"':
|
||||
{
|
||||
result += L"KAVYCHKA";
|
||||
}break;
|
||||
case '&':
|
||||
{
|
||||
result += L"APERSAND";
|
||||
}break;
|
||||
default:
|
||||
{
|
||||
result += expr[pos];
|
||||
}break;
|
||||
}
|
||||
pos++;
|
||||
unsigned j = rand() % (i + 1);
|
||||
key[i] = key[j];
|
||||
key[j] = wchar_t(L'a' + i);
|
||||
}
|
||||
expr = result;
|
||||
|
||||
//XmlUtils::replace_all( expr, L"-", L"MINYS");
|
||||
//XmlUtils::replace_all( expr, L".", L"TОСHKA");
|
||||
//XmlUtils::replace_all( expr, L"!", L"VOSKL");
|
||||
|
||||
//XmlUtils::replace_all( expr, L"(", L"SCOBCAIN");
|
||||
//XmlUtils::replace_all( expr, L")", L"SCOBCAOUT");
|
||||
|
||||
//XmlUtils::replace_all( expr, L"[", L"KVADRATIN");
|
||||
//XmlUtils::replace_all( expr, L"]", L"KVADRATOUT");
|
||||
//
|
||||
//XmlUtils::replace_all( expr, L" ", L"PROBEL");
|
||||
//XmlUtils::replace_all( expr, L"'", L"APOSTROF");
|
||||
//XmlUtils::replace_all( expr, L"\"", L"KAVYCHKA");
|
||||
mapReplacements.back().insert(std::make_pair(key, expr));
|
||||
expr = key;
|
||||
}
|
||||
|
||||
static bool is_forbidden1(const std::wstring & formula)
|
||||
@ -375,6 +188,7 @@ public:
|
||||
|
||||
bool oox2odf_converter::Impl::isFindBaseCell_ = false;
|
||||
std::wstring oox2odf_converter::Impl::table_name_ = L"";
|
||||
std::vector<std::map<std::wstring, std::wstring>> oox2odf_converter::Impl::mapReplacements;
|
||||
|
||||
void oox2odf_converter::Impl::replace_cells_range(std::wstring& expr, bool bSelect)
|
||||
{
|
||||
@ -612,7 +426,9 @@ void oox2odf_converter::Impl::replace_named_ref(std::wstring & expr)
|
||||
|
||||
isFindBaseCell_ = true;
|
||||
std::wstring workstr = expr, out;
|
||||
|
||||
|
||||
mapReplacements.emplace_back();
|
||||
|
||||
replace_vertical(workstr);
|
||||
replace_semicolons(workstr);
|
||||
|
||||
@ -644,6 +460,7 @@ void oox2odf_converter::Impl::replace_named_ref(std::wstring & expr)
|
||||
{
|
||||
oox_replace_tmp_back(table_name_);
|
||||
}
|
||||
mapReplacements.pop_back();
|
||||
}
|
||||
|
||||
|
||||
@ -699,7 +516,7 @@ std::wstring oox2odf_converter::Impl::convert_scobci(boost::wsmatch const & what
|
||||
if (what[1].matched)
|
||||
{
|
||||
std::wstring inner = what[1].str();
|
||||
oox_replace_tmp(inner);
|
||||
oox_replace_tmp(inner);
|
||||
return inner;
|
||||
}
|
||||
else if (what[2].matched)
|
||||
@ -761,13 +578,14 @@ std::wstring oox2odf_converter::Impl::convert(const std::wstring& expr)
|
||||
return workstr;
|
||||
}
|
||||
// (Formula) -> of:=(Formula)
|
||||
|
||||
std::wstring oox2odf_converter::Impl::convert_formula(const std::wstring & expr)
|
||||
{
|
||||
|
||||
{
|
||||
std::wstring workstr = expr;
|
||||
|
||||
mapReplacements.emplace_back();
|
||||
std::wstring res1 = boost::regex_replace(
|
||||
workstr,
|
||||
workstr,
|
||||
boost::wregex(L"('.*?')|(\".*?\")"),
|
||||
&oox2odf_converter::Impl::convert_scobci, boost::match_default | boost::format_all);
|
||||
|
||||
@ -782,7 +600,7 @@ std::wstring oox2odf_converter::Impl::convert_formula(const std::wstring & expr)
|
||||
|
||||
if (res1 == res)
|
||||
{
|
||||
XmlUtils::replace_all( res1, L"KAVYCHKA", L"\""); //IMCONJUGATE_emb.xlsx
|
||||
//XmlUtils::replace_all( res1, L"KAVYCHKA", L"\""); //IMCONJUGATE_emb.xlsx
|
||||
|
||||
res = boost::regex_replace(
|
||||
res1,
|
||||
@ -796,13 +614,13 @@ std::wstring oox2odf_converter::Impl::convert_formula(const std::wstring & expr)
|
||||
replace_vertical(res);
|
||||
replace_semicolons(res);
|
||||
|
||||
XmlUtils::replace_all( res, L"PROBEL", L" ");
|
||||
|
||||
if (table_name_.empty() == false)
|
||||
{
|
||||
oox_replace_tmp_back(table_name_);
|
||||
}
|
||||
|
||||
mapReplacements.pop_back();
|
||||
|
||||
return std::wstring(L"of:=") + res;
|
||||
|
||||
}
|
||||
@ -810,6 +628,8 @@ std::wstring oox2odf_converter::Impl::convert_conditional_formula(const std::wst
|
||||
{
|
||||
std::wstring workstr = expr;
|
||||
|
||||
mapReplacements.emplace_back();
|
||||
|
||||
std::wstring res1 = boost::regex_replace(
|
||||
workstr,
|
||||
boost::wregex(L"('.*?')|(\".*?\")"),
|
||||
@ -829,13 +649,14 @@ std::wstring oox2odf_converter::Impl::convert_conditional_formula(const std::wst
|
||||
|
||||
}
|
||||
|
||||
XmlUtils::replace_all(res, L"&", L"&");
|
||||
//XmlUtils::replace_all(res, L"&", L"&");
|
||||
oox_replace_tmp_back( res);
|
||||
|
||||
replace_vertical(res);
|
||||
replace_semicolons(res);
|
||||
|
||||
XmlUtils::replace_all( res, L"PROBEL", L" ");
|
||||
mapReplacements.pop_back();
|
||||
//XmlUtils::replace_all( res, L"PROBEL", L" ");
|
||||
|
||||
return res;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user