00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041 #include <stdio.h>
00042 #include <iostream>
00043 #include <cstdlib>
00044 #include <set>
00045 #include <sstream>
00046
00047 #include "lateq.hh"
00048 #include "Text.hh"
00049
00050
00051 map<string, string> gDocMathStringMap;
00052 set<string> gDocMathKeySet;
00053
00054 static int getLateqIndex(const string& s);
00055 static bool compLateqIndexes(const string& s1, const string& s2);
00056 static void initDocMathKeySet();
00057
00058
00059 template <class T>
00060 inline std::string to_string (const T& t)
00061 {
00062 std::stringstream ss;
00063 ss << t;
00064 return ss.str();
00065 }
00066
00067
00068
00069
00070
00071
00072
00083 void Lateq::println(ostream& docout)
00084 {
00085
00086 string suchthat = gDocMathStringMap["suchthat"];
00087
00088 string sInputs = makeItemTitle(fInputSigsFormulas.size(), "inputsigtitle") + makeSignamesList(fInputSigsFormulas, "");
00089 string sOutputs = makeItemTitle(fOutputSigsFormulas.size(), "outputsigtitle") + makeSignamesList(fOutputSigsFormulas, suchthat);
00090 string sConstants = makeItemTitle(fConstSigsFormulas.size(), "constsigtitle") + makeSignamesList(fConstSigsFormulas, suchthat);
00091
00092 vector<list<string> > UISignamesVector = makeUISignamesVector(fUISigsFormulas);
00093 string sUIElements = makeItemTitle(fUISigsFormulas.size(), "uisigtitle") + makeSignamesList(UISignamesVector, suchthat);
00094
00095 unsigned int internalSigsCount = fParamSigsFormulas.size() + fStoreSigsFormulas.size() + fRecurSigsFormulas.size() + fRDTblSigsFormulas.size() + fRWTblSigsFormulas.size() + fSelectSigsFormulas.size() + fPrefixSigsFormulas.size();
00096
00097 vector<list<string> > internalSigsFormulasList;
00098 if( ! fParamSigsFormulas.empty() ) internalSigsFormulasList.push_back(fParamSigsFormulas);
00099 if( ! fStoreSigsFormulas.empty() ) internalSigsFormulasList.push_back(fStoreSigsFormulas);
00100 if( ! fRecurSigsFormulas.empty() ) internalSigsFormulasList.push_back(fRecurSigsFormulas);
00101 if( ! fRDTblSigsFormulas.empty() ) internalSigsFormulasList.push_back(fRDTblSigsFormulas);
00102 if( ! fRWTblSigsFormulas.empty() ) internalSigsFormulasList.push_back(fRWTblSigsFormulas);
00103 if( ! fSelectSigsFormulas.empty() ) internalSigsFormulasList.push_back(fSelectSigsFormulas);
00104 if( ! fPrefixSigsFormulas.empty() ) internalSigsFormulasList.push_back(fPrefixSigsFormulas);
00105
00106 string sInternals = makeItemTitle(internalSigsCount, "intermedsigtitle") + makeSignamesList(internalSigsFormulasList, suchthat);
00107
00108
00109
00110 docout << endl << gDocMathStringMap["lateqcomment"] << endl;
00111 docout << "\\begin{enumerate}" << endl << endl;
00112
00113 printDGroup (sOutputs, fOutputSigsFormulas, docout);
00114 printOneLine (sInputs, docout);
00115 const string outputsTitle = "\\item " + sOutputs + "\\ $y_i$\\ " + gDocMathStringMap["for"] + " $i \\in [1," + to_string(fOutputSigsFormulas.size()) + "]$: ";
00116 printHierarchy (sUIElements, fUISigsFormulas, docout);
00117
00118
00119 if( internalSigsCount > 0 ) {
00120 docout << sInternals;
00121 }
00122 fStoreSigsFormulas.sort(compLateqIndexes);
00123 printDGroup ("", fParamSigsFormulas, docout);
00124 printDGroup ("", fStoreSigsFormulas, docout);
00125 printDGroup ("", fRecurSigsFormulas, docout);
00126 printDGroup ("", fRDTblSigsFormulas, docout);
00127 printMath ("", fRWTblSigsFormulas, docout);
00128 printMath ("", fSelectSigsFormulas, docout);
00129 printMath ("", fPrefixSigsFormulas, docout);
00130
00131 printDGroup (sConstants, fConstSigsFormulas, docout);
00132
00133 docout << "\\end{enumerate}" << endl << endl;
00134 }
00135
00136
00137
00138
00139
00140
00141
00142
00143 string Lateq::makeItemTitle(const unsigned int formulasListSize, const string& titleName)
00144 {
00145 string item = "\\item ";
00146
00147
00148 string title = formulasListSize > 1 ? gDocMathStringMap[titleName + "2"] : gDocMathStringMap[titleName + "1"];
00149
00150 return item + title;
00151 }
00152
00153
00154 string Lateq::makeSigDomain(const list<string>& formulasList)
00155 {
00156 string signame = "";
00157 string sigDomain = "";
00158
00159 if (formulasList.size() > 0) {
00160 string firstEq = *(formulasList.begin());
00161 signame = getSigName(firstEq);
00162
00163 if(formulasList.size() > 1) {
00164 sigDomain = " $" + signame + "_i$ " + gDocMathStringMap["for"] + " $i \\in [1," + to_string(formulasList.size()) + "]$";
00165 } else {
00166 if(signame == "x" || signame == "y") {
00167 sigDomain = " $" + signame + "$";
00168 } else {
00169 sigDomain = " $" + signame + "_1$";
00170 }
00171 }
00172 } else {
00173 sigDomain = gDocMathStringMap["emptyformulafield"];
00174 }
00175 return sigDomain;
00176 }
00177
00178
00179 string Lateq::makeSignamesList(const list<string>& formulasList, const string& ending)
00180 {
00181 if (formulasList.size() > 0) {
00182 return makeSigDomain(formulasList) + " " + ending;
00183 } else {
00184 return " (" + gDocMathStringMap["emptyformulafield"] + ")";
00185 }
00186 }
00187
00188
00189 string Lateq::makeSignamesList(const vector<list<string> >& formulasListsVector, const string& ending)
00190 {
00191 if (formulasListsVector.size() > 0) {
00192 vector<list<string> >::const_iterator it;
00193 string signames = "";
00194 string sep = " ";
00195 for (it = formulasListsVector.begin(); it != formulasListsVector.end(); ++it) {
00196 signames += sep + makeSigDomain(*it);
00197 (it != (formulasListsVector.end() - 2)) ? sep = ", " : sep = " " + gDocMathStringMap["and"] + " ";
00198 }
00199 return signames + " " + ending;
00200 } else {
00201 return " (" + gDocMathStringMap["emptyformulafield"] + ")";
00202 }
00203 }
00204
00205
00206 string Lateq::getSigName(const string& s)
00207 {
00208 size_t found;
00209 string signame;
00210
00211 found = s.find(" =");
00212 if (found != string::npos) {
00213 signame = s.substr (0, found);
00214 }
00215 found = s.find("(t)");
00216 if (found != string::npos) {
00217 signame = s.substr (0, found);
00218 }
00219 found = signame.find("[t]");
00220 if (found != string::npos) {
00221 signame = s.substr (0, found);
00222 }
00223 found = signame.find_last_of("_");
00224 if (found != string::npos) {
00225 signame = signame.substr (0, found);
00226 }
00227
00228 return signame;
00229 }
00230
00231
00232 vector<list<string> > Lateq::makeUISignamesVector(const multimap<string,string>& field)
00233 {
00234 map<char,unsigned int> uiTypesMap;
00235 vector<list<string> > uiSignamesVector;
00236 unsigned int vIndex = 0;
00237
00238 multimap<string,string>::const_iterator it;
00239
00240 for (it = field.begin(); it != field.end(); ++it) {
00241 char type = getUISigType(it->second);
00242 string signame = getUISigName(it->second);
00243
00244 map<char,unsigned int>::iterator uiTypesIt;
00245 uiTypesIt = uiTypesMap.find(type);
00246 if( uiTypesIt != uiTypesMap.end()) {
00247 uiSignamesVector[uiTypesMap[uiTypesIt->second]].push_back(signame);
00248 } else {
00249 ++vIndex;
00250 uiTypesMap.insert(pair<char,unsigned int>(type, vIndex));
00251 list<string>* tmpList = new(list<string>);
00252 tmpList->push_back(signame);
00253 uiSignamesVector.push_back(*tmpList);
00254 }
00255 }
00256
00257 return uiSignamesVector;
00258 }
00259
00260
00261 string Lateq::getUISigName(const string& s)
00262 {
00263 size_t found;
00264 string signame;
00265
00266 found = s.find("${u_");
00267 if (found != string::npos) {
00268 signame = s.substr (found+1, 12);
00269 }
00270
00271 return signame;
00272 }
00273
00274
00275 char Lateq::getUISigType(const string& s)
00276 {
00277 size_t found;
00278 char sigtype = '0';
00279
00280 found = s.find("${u_");
00281 if (found != string::npos) {
00282 sigtype = s.at (found+4);
00283 }
00284
00285 return sigtype;
00286 }
00287
00288
00289
00290
00291
00292
00293
00294
00302 void Lateq::printOneLine(const string& section, ostream& docout)
00303 {
00304 docout << section << endl << endl;
00305 }
00306
00307
00319 void Lateq::printDGroup(const string& section, list<string>& field, ostream& docout)
00320 {
00321 if (field.size() > 0) {
00322 docout << section << endl;
00323 tab(1,docout); docout << "\\begin{dgroup*}" << endl;
00324 list<string>::const_iterator s;
00325 for (s = field.begin(); s != field.end(); ++s) {
00326 tab(2,docout); docout << "\\begin{" << "dmath*" << "}" << endl;
00327 tab(3,docout); docout << "\t" << *s << endl;
00328 tab(2,docout); docout << "\\end{" << "dmath*" << "}" << endl;
00329 }
00330 tab(1,docout); docout << "\\end{dgroup*}" << endl;
00331 docout << endl;
00332 }
00333 }
00334
00335
00359 void Lateq::printHierarchy(const string& section, multimap<string,string>& field, ostream& docout)
00360 {
00361 if (field.size() > 0) {
00362 docout << section << endl;
00363
00364 bool hasSomePaths = hasNotOnlyEmptyKeys(field);
00365 unsigned int n;
00366
00367 if (hasSomePaths) {
00368 tab(0,docout); docout << "\\begin{itemize}" << endl;
00369 n = 1;
00370 } else {
00371 n = 0;
00372 }
00373
00374 multimap<string,string>::iterator it;
00375 string uidir = "improbable_starting_dirname";
00376 bool startFlag = true;
00377
00378 for (it = field.begin(); it != field.end(); ++it) {
00379
00380 if (it->first != uidir) {
00381 if (!startFlag) {
00382 tab(n+2,docout); docout << "\\end{supertabular}" << endl;
00383 tab(n+1,docout); docout << "\\end{center}" << endl;
00384 } else {
00385 startFlag = false;
00386 }
00387 if (hasSomePaths) {
00388
00389 if (it->first != "") {
00390 tab(n+0,docout); docout << "\\item \\textsf{" << it->first << "}" << endl;
00391 } else {
00392 tab(n+0,docout); docout << "\\item \\emph{" << gDocMathStringMap["rootlevel"] << "}" << endl;
00393 }
00394 }
00395 tab(n+1,docout); docout << "\\begin{center}" << endl;
00396 tab(n+2,docout); docout << "\\begin{supertabular}{lll}" << endl;
00397 }
00398
00399 tab(n+3,docout); docout << it->second << endl;
00400 uidir = it->first;
00401 }
00402 tab(n+2,docout); docout << "\\end{supertabular}" << endl;
00403 tab(n+1,docout); docout << "\\end{center}" << endl;
00404 if (hasSomePaths) {
00405 tab(n+0,docout); docout << "\\end{itemize}" << endl;
00406 }
00407 docout << endl;
00408 }
00409 }
00410
00411
00423 void Lateq::printMath(const string& section, list<string>& field, ostream& docout)
00424 {
00425 if (field.size() > 0) {
00426 docout << section;
00427 docout << "\\begin{displaymath}" << endl;
00428 list<string>::iterator s;
00429 for (s = field.begin(); s != field.end(); ++s) {
00430 docout << *s << endl;
00431 }
00432 docout << "\\end{displaymath}" << endl;
00433 docout << endl;
00434 }
00435 }
00436
00437
00439 void Lateq::tab (int n, ostream& docout) const
00440 {
00441 while (n--) docout << '\t';
00442 }
00443
00444
00454 bool Lateq::hasNotOnlyEmptyKeys(multimap<string,string>& mm)
00455 {
00456 typedef multimap<string,string>::iterator MMIT;
00457 pair<MMIT,MMIT> range;
00458 range = mm.equal_range("");
00459 bool hasOnlyEmptyPaths = (range.first == mm.begin()) && (range.second == mm.end());
00460 return !hasOnlyEmptyPaths;
00461 }
00462
00463
00464
00468 void initDocMath()
00469 {
00470 initDocMathKeySet();
00471 }
00472
00473
00474
00475
00476
00477
00478
00483 static bool compLateqIndexes(const string& s1, const string& s2)
00484 {
00485 return getLateqIndex(s1) < getLateqIndex(s2);
00486 }
00487
00488
00496 static int getLateqIndex(const string& s)
00497 {
00498 size_t p1;
00499 size_t p2;
00500 string sIndex;
00501
00502 p1 = s.find("_{");
00503 if (p1==string::npos) {
00504 cerr << "Error : getLateqIndex found no \"{_\" substring.\n";
00505 exit(1); }
00506 p1 += 2;
00507
00508 p2 = s.find("}", p1);
00509 if (p2==string::npos) {
00510 cerr << "Error : getLateqIndex found no \"}\" substring\n.";
00511 exit(1); }
00512 p2 -= 3;
00513
00514 sIndex = s.substr (p1, p2);
00515
00516 return atoi(sIndex.c_str());
00517 }
00518
00519
00523 static void initDocMathKeySet()
00524 {
00525 gDocMathKeySet.insert("inputsigtitle1");
00526 gDocMathKeySet.insert("inputsigtitle2");
00527 gDocMathKeySet.insert("outputsigtitle1");
00528 gDocMathKeySet.insert("outputsigtitle2");
00529 gDocMathKeySet.insert("constsigtitle1");
00530 gDocMathKeySet.insert("constsigtitle2");
00531 gDocMathKeySet.insert("uisigtitle1");
00532 gDocMathKeySet.insert("uisigtitle2");
00533 gDocMathKeySet.insert("intermedsigtitle1");
00534 gDocMathKeySet.insert("intermedsigtitle2");
00535 gDocMathKeySet.insert("lateqcomment");
00536 gDocMathKeySet.insert("emptyformulafield");
00537 gDocMathKeySet.insert("defaultvalue");
00538 gDocMathKeySet.insert("suchthat");
00539 gDocMathKeySet.insert("and");
00540 gDocMathKeySet.insert("for");
00541 gDocMathKeySet.insert("rootlevel");
00542
00543 gDocMathKeySet.insert("dgmcaption");
00544 }
00545
00546