FAUST compiler  0.9.9.6b8
lateq.cpp
Go to the documentation of this file.
1 /************************************************************************
2  ************************************************************************
3  FAUST compiler
4  Copyright (C) 2003-2004 GRAME, Centre National de Creation Musicale
5  ---------------------------------------------------------------------
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 2 of the License, or
9  (at your option) any later version.
10 
11  This program is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with this program; if not, write to the Free Software
18  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19  ************************************************************************
20  ************************************************************************/
21 
22 
23 
24  /**********************************************************************
25  - lateq.cpp : the Lateq methods definition (FAUST project) -
26  - for automatic generation of documentation -
27  - "lateq" stands for "LaTeX equations" -
28  - The crucial method here is println -
29 
30  Historique :
31  -----------
32  17-10-2001 : (klass.cpp) implementation initiale (yo)
33  18-10-2001 : (klass.cpp) Ajout de getFreshID (yo)
34  02-11-2001 : (klass.cpp) Ajout de sous classes (yo)
35  06-11-2001 : (klass.cpp) modif impression des classes (yo)
36  16-08-2009 : (lateq.cpp) Creation de lateq depuis klass.cpp (kb)
37  2009-11-21 : (lateq.cpp) Remodelage et documentation doxygen (kb)
38 
39 ***********************************************************************/
40 
41 #include <stdio.h>
42 #include <iostream>
43 #include <cstdlib>
44 #include <set>
45 #include <sstream>
46 
47 #include "lateq.hh"
48 #include "Text.hh"
49 
50 
51 map<string, string> gDocMathStringMap;
52 set<string> gDocMathKeySet;
53 
54 static int getLateqIndex(const string& s);
55 static bool compLateqIndexes(const string& s1, const string& s2);
56 static void initDocMathKeySet();
57 
58 
59 template <class T>
60 inline std::string to_string (const T& t)
61 {
62  std::stringstream ss;
63  ss << t;
64  return ss.str();
65 }
66 
67 
68 /****************************************************************
69  Top-level "println" method (public).
70  *****************************************************************/
71 
72 
83 void Lateq::println(ostream& docout)
84 {
85  /* 1. Make titles of sub-sets of formulas. */
86  string suchthat = gDocMathStringMap["suchthat"];
87 
88  string sInputs = makeItemTitle((const unsigned int)fInputSigsFormulas.size(), "inputsigtitle") + makeSignamesList(fInputSigsFormulas, "");
89  string sOutputs = makeItemTitle((const unsigned int)fOutputSigsFormulas.size(), "outputsigtitle") + makeSignamesList(fOutputSigsFormulas, suchthat);
90  string sConstants = makeItemTitle((const unsigned int)fConstSigsFormulas.size(), "constsigtitle") + makeSignamesList(fConstSigsFormulas, suchthat);
91 
92  vector<list<string> > UISignamesVector = makeUISignamesVector(fUISigsFormulas);
93  string sUIElements = makeItemTitle((const unsigned int)fUISigsFormulas.size(), "uisigtitle") + makeSignamesList(UISignamesVector, suchthat);
94 
95  unsigned int internalSigsCount = (unsigned int)(fParamSigsFormulas.size() + fStoreSigsFormulas.size() + fRecurSigsFormulas.size() + fRDTblSigsFormulas.size() + fRWTblSigsFormulas.size() + fSelectSigsFormulas.size() + fPrefixSigsFormulas.size());
96 
97  vector<list<string> > internalSigsFormulasList;
98  if( ! fParamSigsFormulas.empty() ) internalSigsFormulasList.push_back(fParamSigsFormulas);
99  if( ! fStoreSigsFormulas.empty() ) internalSigsFormulasList.push_back(fStoreSigsFormulas);
100  if( ! fRecurSigsFormulas.empty() ) internalSigsFormulasList.push_back(fRecurSigsFormulas);
101  if( ! fRDTblSigsFormulas.empty() ) internalSigsFormulasList.push_back(fRDTblSigsFormulas);
102  if( ! fRWTblSigsFormulas.empty() ) internalSigsFormulasList.push_back(fRWTblSigsFormulas);
103  if( ! fSelectSigsFormulas.empty() ) internalSigsFormulasList.push_back(fSelectSigsFormulas);
104  if( ! fPrefixSigsFormulas.empty() ) internalSigsFormulasList.push_back(fPrefixSigsFormulas);
105 
106  string sInternals = makeItemTitle(internalSigsCount, "intermedsigtitle") + makeSignamesList(internalSigsFormulasList, suchthat);
107 
108  /* 2. Successively print each Lateq field containing LaTeX formulas, with a title. */
109 
110  docout << endl << gDocMathStringMap["lateqcomment"] << endl;
111  docout << "\\begin{enumerate}" << endl << endl;
112 
113  printDGroup (sOutputs, fOutputSigsFormulas, docout);
114  printOneLine (sInputs, docout);
115  const string outputsTitle = "\\item " + sOutputs + "\\ $y_i$\\ " + gDocMathStringMap["for"] + " $i \\in [1," + to_string(fOutputSigsFormulas.size()) + "]$: ";
116  printHierarchy (sUIElements, fUISigsFormulas, docout);
117 
118  /* The "Internal signals" item gather several fields, like a "super-item"... */
119  if( internalSigsCount > 0 ) {
120  docout << sInternals;
121  }
123  printDGroup ("", fParamSigsFormulas, docout);
124  printDGroup ("", fStoreSigsFormulas, docout);
125  printDGroup ("", fRecurSigsFormulas, docout);
126  printDGroup ("", fRDTblSigsFormulas, docout);
127  printMath ("", fRWTblSigsFormulas, docout);
128  printMath ("", fSelectSigsFormulas, docout);
129  printMath ("", fPrefixSigsFormulas, docout);
130 
131  printDGroup (sConstants, fConstSigsFormulas, docout);
132 
133  docout << "\\end{enumerate}" << endl << endl;
134 }
135 
136 
137 
138 /****************************************************************
139  Item title making functions (public).
140  *****************************************************************/
141 
142 
143 string Lateq::makeItemTitle(const unsigned int formulasListSize, const string& titleName)
144 {
145  string item = "\\item ";
146 
147  /* Plural handling for titles of sub-sets of formulas. */
148  string title = formulasListSize > 1 ? gDocMathStringMap[titleName + "2"] : gDocMathStringMap[titleName + "1"];
149 
150  return item + title;
151 }
152 
153 
154 string Lateq::makeSigDomain(const list<string>& formulasList)
155 {
156  string signame = "";
157  string sigDomain = "";
158 
159  if (formulasList.size() > 0) {
160  string firstEq = *(formulasList.begin());
161  signame = getSigName(firstEq);
162 
163  if(formulasList.size() > 1) {
164  sigDomain = " $" + signame + "_i$ " + gDocMathStringMap["for"] + " $i \\in [1," + to_string(formulasList.size()) + "]$";
165  } else {
166  if(signame == "x" || signame == "y") {
167  sigDomain = " $" + signame + "$";
168  } else {
169  sigDomain = " $" + signame + "_1$";
170  }
171  }
172  } else {
173  sigDomain = gDocMathStringMap["emptyformulafield"];
174  }
175  return sigDomain;
176 }
177 
178 
179 string Lateq::makeSignamesList(const list<string>& formulasList, const string& ending)
180 {
181  if (formulasList.size() > 0) {
182  return makeSigDomain(formulasList) + " " + ending;
183  } else {
184  return " (" + gDocMathStringMap["emptyformulafield"] + ")";
185  }
186 }
187 
188 
189 string Lateq::makeSignamesList(const vector<list<string> >& formulasListsVector, const string& ending)
190 {
191  if (formulasListsVector.size() > 0) {
192  vector<list<string> >::const_iterator it;
193  string signames = "";
194  string sep = " ";
195  for (it = formulasListsVector.begin(); it != formulasListsVector.end(); ++it) {
196  signames += sep + makeSigDomain(*it);
197  (it != (formulasListsVector.end() - 2)) ? sep = ", " : sep = " " + gDocMathStringMap["and"] + " ";
198  }
199  return signames + " " + ending;
200  } else {
201  return " (" + gDocMathStringMap["emptyformulafield"] + ")";
202  }
203 }
204 
205 
206 string Lateq::getSigName(const string& s)
207 {
208  size_t found;
209  string signame;
210 
211  found = s.find(" =");
212  if (found != string::npos) {
213  signame = s.substr (0, found);
214  }
215  found = s.find("(t)");
216  if (found != string::npos) {
217  signame = s.substr (0, found);
218  }
219  found = signame.find("[t]");
220  if (found != string::npos) {
221  signame = s.substr (0, found);
222  }
223  found = signame.find_last_of("_");
224  if (found != string::npos) {
225  signame = signame.substr (0, found);
226  }
227 
228  return signame;
229 }
230 
231 
232 vector<list<string> > Lateq::makeUISignamesVector(const multimap<string,string>& field)
233 {
234  map<char,unsigned int> uiTypesMap;
235  vector<list<string> > uiSignamesVector;
236  unsigned int vIndex = 0;
237 
238  multimap<string,string>::const_iterator it;
239 
240  for (it = field.begin(); it != field.end(); ++it) {
241  char type = getUISigType(it->second);
242  string signame = getUISigName(it->second);
243 
244  map<char,unsigned int>::iterator uiTypesIt;
245  uiTypesIt = uiTypesMap.find(type);
246  if( uiTypesIt != uiTypesMap.end()) {
247  uiSignamesVector[uiTypesMap[uiTypesIt->second]].push_back(signame);
248  } else {
249  ++vIndex;
250  uiTypesMap.insert(pair<char,unsigned int>(type, vIndex));
251  list<string>* tmpList = new(list<string>);
252  tmpList->push_back(signame);
253  uiSignamesVector.push_back(*tmpList);
254  }
255  }
256 
257  return uiSignamesVector;
258 }
259 
260 
261 string Lateq::getUISigName(const string& s)
262 {
263  size_t found;
264  string signame;
265 
266  found = s.find("${u_");
267  if (found != string::npos) {
268  signame = s.substr (found+1, 12);
269  }
270 
271  return signame;
272 }
273 
274 
275 char Lateq::getUISigType(const string& s)
276 {
277  size_t found;
278  char sigtype = '0';
279 
280  found = s.find("${u_");
281  if (found != string::npos) {
282  sigtype = s.at (found+4);
283  }
284 
285  return sigtype;
286 }
287 
288 
289 
290 /****************************************************************
291  Secondary printing methods (private).
292  *****************************************************************/
293 
294 
302 void Lateq::printOneLine(const string& section, ostream& docout)
303 {
304  docout << section << endl << endl;
305 }
306 
307 
319 void Lateq::printDGroup(const string& section, list<string>& field, ostream& docout)
320 {
321  if (field.size() > 0) {
322  docout << section << endl;
323  tab(1,docout); docout << "\\begin{dgroup*}" << endl;
324  list<string>::const_iterator s;
325  for (s = field.begin(); s != field.end(); ++s) {
326  tab(2,docout); docout << "\\begin{" << "dmath*" << "}" << endl;
327  tab(3,docout); docout << "\t" << *s << endl;
328  tab(2,docout); docout << "\\end{" << "dmath*" << "}" << endl;
329  }
330  tab(1,docout); docout << "\\end{dgroup*}" << endl;
331  docout << endl;
332  }
333 }
334 
335 
359 void Lateq::printHierarchy(const string& section, multimap<string,string>& field, ostream& docout)
360 {
361  if (field.size() > 0) {
362  docout << section << endl;
363 
364  bool hasSomePaths = hasNotOnlyEmptyKeys(field);
365  unsigned int n;
366 
367  if (hasSomePaths) {
368  tab(0,docout); docout << "\\begin{itemize}" << endl;
369  n = 1;
370  } else {
371  n = 0;
372  }
373 
374  multimap<string,string>::iterator it;
375  string uidir = "improbable_starting_dirname";
376  bool startFlag = true;
377 
378  for (it = field.begin(); it != field.end(); ++it) {
379  /* Manage supertabular environment bounds and pathname printing. */
380  if (it->first != uidir) {
381  if (!startFlag) {
382  tab(n+2,docout); docout << "\\end{supertabular}" << endl;
383  tab(n+1,docout); docout << "\\end{center}" << endl;
384  } else {
385  startFlag = false;
386  }
387  if (hasSomePaths) {
388  /* Print the current pathname if new and if pathnames requested. */
389  if (it->first != "") {
390  tab(n+0,docout); docout << "\\item \\textsf{" << it->first << "}" << endl;
391  } else {
392  tab(n+0,docout); docout << "\\item \\emph{" << gDocMathStringMap["rootlevel"] << "}" << endl;
393  }
394  }
395  tab(n+1,docout); docout << "\\begin{center}" << endl;
396  tab(n+2,docout); docout << "\\begin{supertabular}{lll}" << endl;
397  }
398  /* Print the current formula. */
399  tab(n+3,docout); docout << it->second << endl;
400  uidir = it->first;
401  }
402  tab(n+2,docout); docout << "\\end{supertabular}" << endl;
403  tab(n+1,docout); docout << "\\end{center}" << endl;
404  if (hasSomePaths) {
405  tab(n+0,docout); docout << "\\end{itemize}" << endl;
406  }
407  docout << endl;
408  }
409 }
410 
411 
423 void Lateq::printMath(const string& section, list<string>& field, ostream& docout)
424 {
425  if (field.size() > 0) {
426  docout << section;
427  docout << "\\begin{displaymath}" << endl;
428  list<string>::iterator s;
429  for (s = field.begin(); s != field.end(); ++s) {
430  docout << *s << endl;
431  }
432  docout << "\\end{displaymath}" << endl;
433  docout << endl;
434  }
435 }
436 
437 
439 void Lateq::tab (int n, ostream& docout) const
440 {
441  while (n--) docout << '\t';
442 }
443 
444 
454 bool Lateq::hasNotOnlyEmptyKeys(multimap<string,string>& mm)
455 {
456  typedef multimap<string,string>::iterator MMIT;
457  pair<MMIT,MMIT> range;
458  range = mm.equal_range("");
459  bool hasOnlyEmptyPaths = (range.first == mm.begin()) && (range.second == mm.end());
460  return !hasOnlyEmptyPaths;
461 }
462 
463 
464 
468 void initDocMath()
469 {
471 }
472 
473 
474 /****************************************************************
475  Internal static functions.
476  *****************************************************************/
477 
478 
483 static bool compLateqIndexes(const string& s1, const string& s2)
484 {
485  return getLateqIndex(s1) < getLateqIndex(s2);
486 }
487 
488 
496 static int getLateqIndex(const string& s)
497 {
498  size_t p1;
499  size_t p2;
500  string sIndex;
501 
502  p1 = s.find("_{");
503  if (p1==string::npos) {
504  cerr << "Error : getLateqIndex found no \"{_\" substring.\n";
505  exit(1); }
506  p1 += 2;
507 
508  p2 = s.find("}", p1);
509  if (p2==string::npos) {
510  cerr << "Error : getLateqIndex found no \"}\" substring\n.";
511  exit(1); }
512  p2 -= 3;
513 
514  sIndex = s.substr (p1, p2);
515 
516  return atoi(sIndex.c_str());
517 }
518 
519 
523 static void initDocMathKeySet()
524 {
525  gDocMathKeySet.insert("inputsigtitle1");
526  gDocMathKeySet.insert("inputsigtitle2");
527  gDocMathKeySet.insert("outputsigtitle1");
528  gDocMathKeySet.insert("outputsigtitle2");
529  gDocMathKeySet.insert("constsigtitle1");
530  gDocMathKeySet.insert("constsigtitle2");
531  gDocMathKeySet.insert("uisigtitle1");
532  gDocMathKeySet.insert("uisigtitle2");
533  gDocMathKeySet.insert("intermedsigtitle1");
534  gDocMathKeySet.insert("intermedsigtitle2");
535  gDocMathKeySet.insert("lateqcomment");
536  gDocMathKeySet.insert("emptyformulafield");
537  gDocMathKeySet.insert("defaultvalue");
538  gDocMathKeySet.insert("suchthat");
539  gDocMathKeySet.insert("and");
540  gDocMathKeySet.insert("for");
541  gDocMathKeySet.insert("rootlevel");
542 
543  gDocMathKeySet.insert("dgmcaption");
544 }
545 
546 
list< string > fParamSigsFormulas
Definition: lateq.hh:94
string makeSigDomain(const list< string > &formulasList)
Definition: lateq.cpp:154
void printMath(const string &section, list< string > &field, ostream &docout)
Print formulas for select2, select3 and prefix signals.
Definition: lateq.cpp:423
list< string > fRWTblSigsFormulas
Definition: lateq.hh:98
list< string > fInputSigsFormulas
LaTeX formulas to print.
Definition: lateq.hh:92
multimap< string, string > fUISigsFormulas
Definition: lateq.hh:102
void tab(int n, ostream &docout) const
Simple handling of indentation.
Definition: lateq.cpp:439
string makeSignamesList(const list< string > &formulasList, const string &ending)
Definition: lateq.cpp:179
string makeItemTitle(const unsigned int formulasListSize, const string &titleName)
Definition: lateq.cpp:143
static bool compLateqIndexes(const string &s1, const string &s2)
Compare indexes of two LaTeX strings, for the sort() method applied on list fields...
Definition: lateq.cpp:483
void printOneLine(const string &section, ostream &docout)
Print a sorted list of input signals names ("x_i"), on a single line, separated by commas...
Definition: lateq.cpp:302
list< string > fStoreSigsFormulas
Definition: lateq.hh:95
map< string, string > gDocMathStringMap
Definition: lateq.cpp:51
string getSigName(const string &s)
Definition: lateq.cpp:206
vector< list< string > > makeUISignamesVector(const multimap< string, string > &field)
Definition: lateq.cpp:232
bool hasNotOnlyEmptyKeys(multimap< string, string > &mm)
Find out whether all keys of the multimap are empty or not.
Definition: lateq.cpp:454
string T(char *c)
Definition: Text.cpp:158
void printDGroup(const string &section, list< string > &field, ostream &docout)
Print a dgroup environment to auto-break long formulas.
Definition: lateq.cpp:319
list< string > fRDTblSigsFormulas
Definition: lateq.hh:97
static int getLateqIndex(const string &s)
Find out the index of signals in LaTeX signal definition strings, between the first "_{" and "}" patt...
Definition: lateq.cpp:496
void printHierarchy(const string &section, multimap< string, string > &field, ostream &docout)
Print formulas for user interface signals.
Definition: lateq.cpp:359
void println(ostream &docout)
Top-level method to print a whole set of compiled LaTeX formulas.
Definition: lateq.cpp:83
std::string to_string(const T &t)
Definition: lateq.cpp:60
list< string > fConstSigsFormulas
Definition: lateq.hh:93
string getUISigName(const string &s)
Definition: lateq.cpp:261
list< string > fRecurSigsFormulas
Definition: lateq.hh:96
list< string > fPrefixSigsFormulas
Definition: lateq.hh:100
void initDocMath()
Dispatch initialization of autodoc container.
Definition: lateq.cpp:468
list< string > fSelectSigsFormulas
Definition: lateq.hh:99
char getUISigType(const string &s)
Definition: lateq.cpp:275
set< string > gDocMathKeySet
Definition: lateq.cpp:52
list< string > fOutputSigsFormulas
Definition: lateq.hh:101
static void initDocMathKeySet()
Initialize gDocMathKeySet, a set containing all the keywords.
Definition: lateq.cpp:523