|
FAUST compiler
0.9.9.6b8
|
00001 /************************************************************************ 00002 ************************************************************************ 00003 FAUST compiler 00004 Copyright (C) 2003-2004 GRAME, Centre National de Creation Musicale 00005 --------------------------------------------------------------------- 00006 This program is free software; you can redistribute it and/or modify 00007 it under the terms of the GNU General Public License as published by 00008 the Free Software Foundation; either version 2 of the License, or 00009 (at your option) any later version. 00010 00011 This program is distributed in the hope that it will be useful, 00012 but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 GNU General Public License for more details. 00015 00016 You should have received a copy of the GNU General Public License 00017 along with this program; if not, write to the Free Software 00018 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 00019 ************************************************************************ 00020 ************************************************************************/ 00021 00022 00023 00024 /********************************************************************** 00025 - lateq.cpp : the Lateq methods definition (FAUST project) - 00026 - for automatic generation of documentation - 00027 - "lateq" stands for "LaTeX equations" - 00028 - The crucial method here is println - 00029 00030 Historique : 00031 ----------- 00032 17-10-2001 : (klass.cpp) implementation initiale (yo) 00033 18-10-2001 : (klass.cpp) Ajout de getFreshID (yo) 00034 02-11-2001 : (klass.cpp) Ajout de sous classes (yo) 00035 06-11-2001 : (klass.cpp) modif impression des classes (yo) 00036 16-08-2009 : (lateq.cpp) Creation de lateq depuis klass.cpp (kb) 00037 2009-11-21 : (lateq.cpp) Remodelage et documentation doxygen (kb) 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 Top-level "println" method (public). 00070 *****************************************************************/ 00071 00072 00083 void Lateq::println(ostream& docout) 00084 { 00085 /* 1. Make titles of sub-sets of formulas. */ 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 /* 2. Successively print each Lateq field containing LaTeX formulas, with a title. */ 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 /* The "Internal signals" item gather several fields, like a "super-item"... */ 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 Item title making functions (public). 00140 *****************************************************************/ 00141 00142 00143 string Lateq::makeItemTitle(const unsigned int formulasListSize, const string& titleName) 00144 { 00145 string item = "\\item "; 00146 00147 /* Plural handling for titles of sub-sets of formulas. */ 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 Secondary printing methods (private). 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 /* Manage supertabular environment bounds and pathname printing. */ 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 /* Print the current pathname if new and if pathnames requested. */ 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 /* Print the current formula. */ 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 Internal static functions. 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
1.8.0