+++ /dev/null
-/************************************************************************
- ************************************************************************
- FAUST compiler
- Copyright (C) 2003-2004 GRAME, Centre National de Creation Musicale
- ---------------------------------------------------------------------
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- ************************************************************************
- ************************************************************************/
-
-
-
- /**********************************************************************
- - lateq.cpp : the Lateq methods definition (FAUST project) -
- - for automatic generation of documentation -
- - "lateq" stands for "LaTeX equations" -
- - The crucial method here is println -
-
- Historique :
- -----------
- 17-10-2001 : (klass.cpp) implementation initiale (yo)
- 18-10-2001 : (klass.cpp) Ajout de getFreshID (yo)
- 02-11-2001 : (klass.cpp) Ajout de sous classes (yo)
- 06-11-2001 : (klass.cpp) modif impression des classes (yo)
- 16-08-2009 : (lateq.cpp) Creation de lateq depuis klass.cpp (kb)
- 2009-11-21 : (lateq.cpp) Remodelage et documentation doxygen (kb)
-
-***********************************************************************/
-
-#include <stdio.h>
-#include <iostream>
-#include <cstdlib>
-#include <set>
-#include <sstream>
-
-#include "lateq.hh"
-#include "Text.hh"
-
-
-map<string, string> gDocMathStringMap;
-set<string> gDocMathKeySet;
-
-static int getLateqIndex(const string& s);
-static bool compLateqIndexes(const string& s1, const string& s2);
-static void initDocMathKeySet();
-
-
-template <class T>
-inline std::string to_string (const T& t)
-{
- std::stringstream ss;
- ss << t;
- return ss.str();
-}
-
-
-/****************************************************************
- Top-level "println" method (public).
- *****************************************************************/
-
-
-/**
- * @brief
- * Top-level method to print a whole set of compiled LaTeX formulas,
- * corresponding to an <equation> faustdoc tag.
- *
- * @remark
- * These formulas must have been previously compiled,
- * via the DocCompile class,
- * and stored in Lateq fields as LaTeX strings.
- */
-void Lateq::println(ostream& docout)
-{
- /* 1. Make titles of sub-sets of formulas. */
- string suchthat = gDocMathStringMap["suchthat"];
-
- string sInputs = makeItemTitle(fInputSigsFormulas.size(), "inputsigtitle") + makeSignamesList(fInputSigsFormulas, "");
- string sOutputs = makeItemTitle(fOutputSigsFormulas.size(), "outputsigtitle") + makeSignamesList(fOutputSigsFormulas, suchthat);
- string sConstants = makeItemTitle(fConstSigsFormulas.size(), "constsigtitle") + makeSignamesList(fConstSigsFormulas, suchthat);
-
- vector<list<string> > UISignamesVector = makeUISignamesVector(fUISigsFormulas);
- string sUIElements = makeItemTitle(fUISigsFormulas.size(), "uisigtitle") + makeSignamesList(UISignamesVector, suchthat);
-
- unsigned int internalSigsCount = fParamSigsFormulas.size() + fStoreSigsFormulas.size() + fRecurSigsFormulas.size() + fRDTblSigsFormulas.size() + fRWTblSigsFormulas.size() + fSelectSigsFormulas.size() + fPrefixSigsFormulas.size();
-
- vector<list<string> > internalSigsFormulasList;
- if( ! fParamSigsFormulas.empty() ) internalSigsFormulasList.push_back(fParamSigsFormulas);
- if( ! fStoreSigsFormulas.empty() ) internalSigsFormulasList.push_back(fStoreSigsFormulas);
- if( ! fRecurSigsFormulas.empty() ) internalSigsFormulasList.push_back(fRecurSigsFormulas);
- if( ! fRDTblSigsFormulas.empty() ) internalSigsFormulasList.push_back(fRDTblSigsFormulas);
- if( ! fRWTblSigsFormulas.empty() ) internalSigsFormulasList.push_back(fRWTblSigsFormulas);
- if( ! fSelectSigsFormulas.empty() ) internalSigsFormulasList.push_back(fSelectSigsFormulas);
- if( ! fPrefixSigsFormulas.empty() ) internalSigsFormulasList.push_back(fPrefixSigsFormulas);
-
- string sInternals = makeItemTitle(internalSigsCount, "intermedsigtitle") + makeSignamesList(internalSigsFormulasList, suchthat);
-
- /* 2. Successively print each Lateq field containing LaTeX formulas, with a title. */
-
- docout << endl << gDocMathStringMap["lateqcomment"] << endl;
- docout << "\\begin{enumerate}" << endl << endl;
-
- printDGroup (sOutputs, fOutputSigsFormulas, docout);
- printOneLine (sInputs, docout);
- const string outputsTitle = "\\item " + sOutputs + "\\ $y_i$\\ " + gDocMathStringMap["for"] + " $i \\in [1," + to_string(fOutputSigsFormulas.size()) + "]$: ";
- printHierarchy (sUIElements, fUISigsFormulas, docout);
-
- /* The "Internal signals" item gather several fields, like a "super-item"... */
- if( internalSigsCount > 0 ) {
- docout << sInternals;
- }
- fStoreSigsFormulas.sort(compLateqIndexes);
- printDGroup ("", fParamSigsFormulas, docout);
- printDGroup ("", fStoreSigsFormulas, docout);
- printDGroup ("", fRecurSigsFormulas, docout);
- printDGroup ("", fRDTblSigsFormulas, docout);
- printMath ("", fRWTblSigsFormulas, docout);
- printMath ("", fSelectSigsFormulas, docout);
- printMath ("", fPrefixSigsFormulas, docout);
-
- printDGroup (sConstants, fConstSigsFormulas, docout);
-
- docout << "\\end{enumerate}" << endl << endl;
-}
-
-
-
-/****************************************************************
- Item title making functions (public).
- *****************************************************************/
-
-
-string Lateq::makeItemTitle(const unsigned int formulasListSize, const string& titleName)
-{
- string item = "\\item ";
-
- /* Plural handling for titles of sub-sets of formulas. */
- string title = formulasListSize > 1 ? gDocMathStringMap[titleName + "2"] : gDocMathStringMap[titleName + "1"];
-
- return item + title;
-}
-
-
-string Lateq::makeSigDomain(const list<string>& formulasList)
-{
- string signame = "";
- string sigDomain = "";
-
- if (formulasList.size() > 0) {
- string firstEq = *(formulasList.begin());
- signame = getSigName(firstEq);
-
- if(formulasList.size() > 1) {
- sigDomain = " $" + signame + "_i$ " + gDocMathStringMap["for"] + " $i \\in [1," + to_string(formulasList.size()) + "]$";
- } else {
- if(signame == "x" || signame == "y") {
- sigDomain = " $" + signame + "$"; ///< No indices for single input neither single output.
- } else {
- sigDomain = " $" + signame + "_1$"; ///< Indices "1" for all other single signal.
- }
- }
- } else {
- sigDomain = gDocMathStringMap["emptyformulafield"];
- }
- return sigDomain;
-}
-
-
-string Lateq::makeSignamesList(const list<string>& formulasList, const string& ending)
-{
- if (formulasList.size() > 0) {
- return makeSigDomain(formulasList) + " " + ending;
- } else {
- return " (" + gDocMathStringMap["emptyformulafield"] + ")";
- }
-}
-
-
-string Lateq::makeSignamesList(const vector<list<string> >& formulasListsVector, const string& ending)
-{
- if (formulasListsVector.size() > 0) {
- vector<list<string> >::const_iterator it;
- string signames = "";
- string sep = " ";
- for (it = formulasListsVector.begin(); it != formulasListsVector.end(); ++it) {
- signames += sep + makeSigDomain(*it);
- (it != (formulasListsVector.end() - 2)) ? sep = ", " : sep = " " + gDocMathStringMap["and"] + " ";
- }
- return signames + " " + ending;
- } else {
- return " (" + gDocMathStringMap["emptyformulafield"] + ")";
- }
-}
-
-
-string Lateq::getSigName(const string& s)
-{
- size_t found;
- string signame;
-
- found = s.find(" =");
- if (found != string::npos) { ///< Looking for a left member.
- signame = s.substr (0, found);
- }
- found = s.find("(t)");
- if (found != string::npos) { ///< Strip "(t)" argument if exists.
- signame = s.substr (0, found);
- }
- found = signame.find("[t]");
- if (found != string::npos) { ///< Strip "[t]" argument if exists (for tables).
- signame = s.substr (0, found);
- }
- found = signame.find_last_of("_");
- if (found != string::npos) { ///< Strip indice if exists.
- signame = signame.substr (0, found);
- }
-
- return signame;
-}
-
-
-vector<list<string> > Lateq::makeUISignamesVector(const multimap<string,string>& field)
-{
- map<char,unsigned int> uiTypesMap;
- vector<list<string> > uiSignamesVector;
- unsigned int vIndex = 0;
-
- multimap<string,string>::const_iterator it;
-
- for (it = field.begin(); it != field.end(); ++it) {
- char type = getUISigType(it->second);
- string signame = getUISigName(it->second);
-
- map<char,unsigned int>::iterator uiTypesIt;
- uiTypesIt = uiTypesMap.find(type);
- if( uiTypesIt != uiTypesMap.end()) {
- uiSignamesVector[uiTypesMap[uiTypesIt->second]].push_back(signame);
- } else {
- ++vIndex;
- uiTypesMap.insert(pair<char,unsigned int>(type, vIndex));
- list<string>* tmpList = new(list<string>);
- tmpList->push_back(signame);
- uiSignamesVector.push_back(*tmpList);
- }
- }
-
- return uiSignamesVector;
-}
-
-
-string Lateq::getUISigName(const string& s)
-{
- size_t found;
- string signame;
-
- found = s.find("${u_");
- if (found != string::npos) { ///< Looking for a UI signal name "{u_?}_{i}(t)".
- signame = s.substr (found+1, 12);
- }
-
- return signame;
-}
-
-
-char Lateq::getUISigType(const string& s)
-{
- size_t found;
- char sigtype = '0';
-
- found = s.find("${u_");
- if (found != string::npos) { ///< Looking for a UI signal name "{u_?}_{i}".
- sigtype = s.at (found+4);
- }
-
- return sigtype;
-}
-
-
-
-/****************************************************************
- Secondary printing methods (private).
- *****************************************************************/
-
-
-/**
- * Print a sorted list of input signals names ("x_i"),
- * on a single line, separated by commas.
- *
- * @param[in] section The title to print for these formulas.
- * @param[out] docout The LaTeX output file to print into.
- */
-void Lateq::printOneLine(const string& section, ostream& docout)
-{
- docout << section << endl << endl;
-}
-
-
-/**
- * @brief Print a dgroup environment to auto-break long formulas.
- *
- * @remark
- * The "dgroup" and "dmath" environments belong to the "breqn" LaTeX package.
- * The stared variants "dgroup*" and "dmath*" force unnumbered equations.
- *
- * @param[in] section The title to print for these formulas.
- * @param[in] field The list of LaTeX formulas.
- * @param[out] docout The LaTeX output file to print into.
- */
-void Lateq::printDGroup(const string& section, list<string>& field, ostream& docout)
-{
- if (field.size() > 0) {
- docout << section << endl;
- tab(1,docout); docout << "\\begin{dgroup*}" << endl;
- list<string>::const_iterator s;
- for (s = field.begin(); s != field.end(); ++s) {
- tab(2,docout); docout << "\\begin{" << "dmath*" << "}" << endl;
- tab(3,docout); docout << "\t" << *s << endl;
- tab(2,docout); docout << "\\end{" << "dmath*" << "}" << endl;
- }
- tab(1,docout); docout << "\\end{dgroup*}" << endl;
- docout << endl;
- }
-}
-
-
-/**
- * @brief Print formulas for user interface signals.
- *
- * @param[in] section The title to print for these formulas.
- * @param[in] field This multimap contains pairs :
- * 1. the path_string is printed as a sub-title item, when new;
- * 2. each latex_string is printed as a preformated row of the
- * supertabular environment (needed to handle long tables).
- * @param[out] docout The LaTeX output file to print into.
- *
- * @remark
- * To decide when one should avoid to print an itemize environment,
- * a "global" strategy is applied : in the particular case where
- * ONLY empty paths were detected in the WHOLE container (all UIs
- * are at the top level).
- * In this particular case, UI strings are directly printed,
- * and their (empty!) path is ignored...
- * In the other case, we have to print an itemize environment
- * and manage paths printing (empty AND non-empty paths) as items.
- *
- * @see DocCompiler::prepareIntervallicUI
- * @see DocCompiler::prepareBinaryUI
- */
-void Lateq::printHierarchy(const string& section, multimap<string,string>& field, ostream& docout)
-{
- if (field.size() > 0) {
- docout << section << endl;
-
- bool hasSomePaths = hasNotOnlyEmptyKeys(field); ///< Manage itemize printing for pathnames.
- unsigned int n; ///< Manage latex indentation offset.
-
- if (hasSomePaths) {
- tab(0,docout); docout << "\\begin{itemize}" << endl;
- n = 1;
- } else {
- n = 0;
- }
-
- multimap<string,string>::iterator it;
- string uidir = "improbable_starting_dirname";
- bool startFlag = true;
-
- for (it = field.begin(); it != field.end(); ++it) {
- /* Manage supertabular environment bounds and pathname printing. */
- if (it->first != uidir) {
- if (!startFlag) {
- tab(n+2,docout); docout << "\\end{supertabular}" << endl;
- tab(n+1,docout); docout << "\\end{center}" << endl;
- } else {
- startFlag = false;
- }
- if (hasSomePaths) {
- /* Print the current pathname if new and if pathnames requested. */
- if (it->first != "") {
- tab(n+0,docout); docout << "\\item \\textsf{" << it->first << "}" << endl;
- } else {
- tab(n+0,docout); docout << "\\item \\emph{" << gDocMathStringMap["rootlevel"] << "}" << endl;
- }
- }
- tab(n+1,docout); docout << "\\begin{center}" << endl;
- tab(n+2,docout); docout << "\\begin{supertabular}{lll}" << endl;
- }
- /* Print the current formula. */
- tab(n+3,docout); docout << it->second << endl;
- uidir = it->first;
- }
- tab(n+2,docout); docout << "\\end{supertabular}" << endl;
- tab(n+1,docout); docout << "\\end{center}" << endl;
- if (hasSomePaths) {
- tab(n+0,docout); docout << "\\end{itemize}" << endl;
- }
- docout << endl;
- }
-}
-
-
-/**
- * @brief Print formulas for select2, select3 and prefix signals.
- *
- * @param[in] section The title to print for these formulas.
- * @param[in] field The list of LaTeX arrays (for braces with two lines).
- * @param[out] docout The LaTeX output file to print into.
- *
- * @see DocCompiler::generateSelect2
- * @see DocCompiler::generateSelect3
- * @see DocCompiler::generatePrefix
- */
-void Lateq::printMath(const string& section, list<string>& field, ostream& docout)
-{
- if (field.size() > 0) {
- docout << section;
- docout << "\\begin{displaymath}" << endl;
- list<string>::iterator s;
- for (s = field.begin(); s != field.end(); ++s) {
- docout << *s << endl;
- }
- docout << "\\end{displaymath}" << endl;
- docout << endl;
- }
-}
-
-
-/** Simple handling of indentation. */
-void Lateq::tab (int n, ostream& docout) const
-{
- while (n--) docout << '\t';
-}
-
-
-/**
- * @brief Find out whether all keys of the multimap are empty or not.
- *
- * In other words :
- * Check that some UIs have a path (non empty).
- *
- * In other other words :
- * Check that all UIs are not at top-level.
- */
-bool Lateq::hasNotOnlyEmptyKeys(multimap<string,string>& mm)
-{
- typedef multimap<string,string>::iterator MMIT;
- pair<MMIT,MMIT> range;
- range = mm.equal_range(""); ///< Look for pairs with empty keys.
- bool hasOnlyEmptyPaths = (range.first == mm.begin()) && (range.second == mm.end());
- return !hasOnlyEmptyPaths;
-}
-
-
-
-/**
- * Dispatch initialization of autodoc container.
- */
-void initDocMath()
-{
- initDocMathKeySet();
-}
-
-
-/****************************************************************
- Internal static functions.
- *****************************************************************/
-
-
-/**
- * Compare indexes of two LaTeX strings,
- * for the sort() method applied on list<string> fields.
- */
-static bool compLateqIndexes(const string& s1, const string& s2)
-{
- return getLateqIndex(s1) < getLateqIndex(s2);
-}
-
-
-/**
- * Find out the index of signals in LaTeX signal definition strings,
- * between the first "_{" and "}" patterns.
- *
- * @param[in] s A LaTeX string to parse.
- * @return <int> The index found, as an integer.
- */
-static int getLateqIndex(const string& s)
-{
- size_t p1;
- size_t p2;
- string sIndex;
-
- p1 = s.find("_{");
- if (p1==string::npos) {
- cerr << "Error : getLateqIndex found no \"{_\" substring.\n";
- exit(1); }
- p1 += 2;
-
- p2 = s.find("}", p1);
- if (p2==string::npos) {
- cerr << "Error : getLateqIndex found no \"}\" substring\n.";
- exit(1); }
- p2 -= 3;
-
- sIndex = s.substr (p1, p2);
-
- return atoi(sIndex.c_str());
-}
-
-
-/**
- * Initialize gDocMathKeySet, a set containing all the keywords.
- */
-static void initDocMathKeySet()
-{
- gDocMathKeySet.insert("inputsigtitle1");
- gDocMathKeySet.insert("inputsigtitle2");
- gDocMathKeySet.insert("outputsigtitle1");
- gDocMathKeySet.insert("outputsigtitle2");
- gDocMathKeySet.insert("constsigtitle1");
- gDocMathKeySet.insert("constsigtitle2");
- gDocMathKeySet.insert("uisigtitle1");
- gDocMathKeySet.insert("uisigtitle2");
- gDocMathKeySet.insert("intermedsigtitle1");
- gDocMathKeySet.insert("intermedsigtitle2");
- gDocMathKeySet.insert("lateqcomment");
- gDocMathKeySet.insert("emptyformulafield");
- gDocMathKeySet.insert("defaultvalue");
- gDocMathKeySet.insert("suchthat");
- gDocMathKeySet.insert("and");
- gDocMathKeySet.insert("for");
- gDocMathKeySet.insert("rootlevel");
-
- gDocMathKeySet.insert("dgmcaption");
-}
-
-