void IteratorOpParser::findSubformulaeSymbols(vector<Formula*>& mainSymbols, vector<Formula*>& otherSymbols, unsigned int currentMainIndex, vector<Formula*>& underscriptSymbols, vector<Formula*>& overscriptSymbols, long currentRightLimit, long currentLeftLimit) { unsigned int& k = currentMainIndex; Formula* currentMainSymbol = mainSymbols.at(k); if (underscriptSymbols.empty() && overscriptSymbols.empty()) { // caso in cui non ci sono underscript e overscript ma (forse) apici e pedici long currentMainMidline = currentMainSymbol->center().getY(); unsigned int j = 0; bool beforeCurrentRightLimit = true; while (j < otherSymbols.size() && beforeCurrentRightLimit) { if (otherSymbols.at(j)->left() >= currentRightLimit) { beforeCurrentRightLimit = false; } else { Formula* oth = otherSymbols.at(j); bool crossedByMidline = oth->top() < currentMainMidline && currentMainMidline < oth->bottom(); if (crossedByMidline) { mainSymbols.insert(mainSymbols.begin() + k + 1, oth); otherSymbols.erase(otherSymbols.begin() + j); currentRightLimit = oth->left(); } j++; } } currentLeftLimit = currentMainSymbol->right(); underscriptSymbols = FormulaParserUtils::extractSymbolsWithinRange(otherSymbols, currentRightLimit, currentLeftLimit, maxBottomLimit, currentMainMidline, true); overscriptSymbols = FormulaParserUtils::extractSymbolsWithinRange(otherSymbols, currentRightLimit, currentLeftLimit, currentMainMidline, maxTopLimit, true); } else { // l'underscript e l'overscript, che al momento contengono solo simboli allineati verticalmente col main, vengono estesi underscriptSymbols = FormulaParserUtils::extractSymbolsWithinRange(otherSymbols, currentRightLimit, currentLeftLimit, maxBottomLimit, currentMainSymbol->bottom() + 1, true); overscriptSymbols = FormulaParserUtils::extractSymbolsWithinRange(otherSymbols, currentRightLimit, currentLeftLimit, currentMainSymbol->top() - 1, maxTopLimit, true); } }
vector<Formula*>& IteratorOpParser::_parse(vector<Formula*>& formulaToParse) { vector<Formula*> mainSymbols, otherSymbols; vector<Formula*>& result = *(new vector<Formula*>()); findMainSymbols(formulaToParse, mainSymbols, otherSymbols, false); vector<unsigned int> iteratorOpSymbolIndexes = findIteratorOpSymbolIndexes(mainSymbols); unsigned int i = 0; for (unsigned int k = 0; k < mainSymbols.size(); k++) { Formula* currentMainSymbol = mainSymbols.at(k); if (i < iteratorOpSymbolIndexes.size() && iteratorOpSymbolIndexes.at(i) == k) { long currentLeftLimit, currentRightLimit; computeLimits(mainSymbols, iteratorOpSymbolIndexes, k, i, ¤tRightLimit, ¤tLeftLimit); vector<Formula*>& underscriptSymbols = FormulaParserUtils::extractSymbolsWithinRange(otherSymbols, currentMainSymbol->right(), currentMainSymbol->left(), maxBottomLimit, currentMainSymbol->bottom() + 1, false); vector<Formula*>& overscriptSymbols = FormulaParserUtils::extractSymbolsWithinRange(otherSymbols, currentMainSymbol->right(), currentMainSymbol->left(), currentMainSymbol->top(), maxTopLimit, false); findSubformulaeSymbols(mainSymbols, otherSymbols, k, underscriptSymbols, overscriptSymbols, currentRightLimit, currentLeftLimit); Parser parser; Formula* underscript = parser.parse(underscriptSymbols); Formula* overscript = parser.parse(overscriptSymbols); Formula* newIteratorOp = new IteratorOp(currentMainSymbol, underscript, overscript); result.push_back(newIteratorOp); i++; } else { result.push_back(mainSymbols.at(k)); } } result.insert(result.end(), otherSymbols.begin(), otherSymbols.end()); sort(result.begin(), result.end(), Formula::BarHorizontalComparator()); return result; }
void SubSupParser::findSubSup(Formula** subformulaToSet, Formula* currentOther, vector<Formula*>& allSymbols, vector<Formula*>& mainSymbols, vector<Formula*>& otherSymbols, unsigned int currentMainIndex, bool sup_notSub) { using namespace FormulaParserUtils; unsigned int& i = currentMainIndex; Formula* currentMain = mainSymbols.at(currentMainIndex); long mainVBar = currentMain->center().getY(); int currentLeftLimit = currentMain->left(); int currentRightLimit = (i == mainSymbols.size() - 1) ? maxRightLimit : mainSymbols.at(i + 1)->left() - 1; bool subformulaCondition; long subsup_bottomLimit, subsup_topLimit, context_bottomLimit, context_topLimit; if (sup_notSub) { //apice bool higherTop = currentOther->top() + currentOther->height() * SUP_MIN_FRACTION_ABOVE_MAIN < currentMain->top(); bool higherBar = getWeightedVBar(currentOther) < getWeightedVBar(currentMain) && currentOther->area() <= currentMain->area() * LOW_SUP_MAX_AREA; subformulaCondition = higherTop || higherBar; // /* un apice deve: // * - avere un bordo superiore "sufficientemente" più in alto del mainSymbol corrente, OPPURE // * - avere un baricentro più alto ed essere "sufficientemente" più piccolo del simbolo principale // * */ subsup_bottomLimit = mainVBar; subsup_topLimit = maxTopLimit; context_bottomLimit = maxBottomLimit; context_topLimit = mainVBar; } else { //pedice subformulaCondition = (currentOther->bottom() - currentOther->height() * SUB_MIN_FRACTION_BELOW_MAIN) > currentMain->bottom(); // // un pedice deve trovarsi "sufficientemente" più in basso del mainSymbol corrente subsup_bottomLimit = maxBottomLimit; subsup_topLimit = mainVBar; context_bottomLimit = mainVBar; context_topLimit = maxTopLimit; } if (!subformulaCondition) { /* Non vengono rispettate le condizioni date: l'apice/pedice è stato mal classificato. Viene allora aggiunto ai simboli principali ed eliminato * da quelli secondari. */ mainSymbols.insert(mainSymbols.begin() + i + 1, currentOther); otherSymbols.erase(otherSymbols.begin()); } else { otherSymbols.erase(otherSymbols.begin()); vector<Formula*> subsup = extractSymbolsInRange(otherSymbols, currentRightLimit, currentLeftLimit, subsup_bottomLimit, subsup_topLimit); subsup.insert(subsup.begin(), currentOther); /* Viene passato allSymbols e non otherSymbols perché gli elementi di otherSymbols vengono cancellati una volta classificati (quindi se classifico, * ad esempio, un pedice poi quei simboli non saranno più in otherSymbols e non verrebbero più trovati dalla funzione di estrazione, che quindi non * fornirebbe il contesto appropriato) */ vector<Formula*> context = extractSymbolsInRange(allSymbols, currentRightLimit, currentLeftLimit, context_bottomLimit, context_topLimit, false); fixBadClassification(mainSymbols, otherSymbols, subsup, context, i); *subformulaToSet = _parse(subsup, allSymbols); } }