#ifdef _UNICODE
typedef wchar_t TCHAR;
#else
typedef char TCHAR;
#endif
#include "QFramework/TQStringUtils.h"
#include "QFramework/TQUtils.h"
#include "QFramework/TQHistogramUtils.h"
#include "QFramework/TQCounter.h"
#include "QFramework/TQIterator.h"
#include "QFramework/TQPCA.h"
#include "QFramework/TQSample.h"
#include "QFramework/TQLink.h"
#include "QFramework/TQTable.h"
#include "QFramework/TQLibrary.h"
#include "TObjString.h"
#include "TMath.h"
#include "TColor.h"
#include "TPrincipal.h"
#include "THStack.h"
#include "Varargs.h"
#include "TLegend.h"
#include "TInterpreter.h"
#include "TH1.h"
#include "TParameter.h"
#include "TPRegexp.h"
#include <iostream>
#include <fstream>
#include <sstream>
#include <cstdlib>
const TString TQStringUtils::lowerLetters = "abcdefghijklmnopqrstuvwxyz";
const TString TQStringUtils::upperLetters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
const TString TQStringUtils::emptyString = "";
const TString TQStringUtils::numerals = "0123456789";
const TString TQStringUtils::letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
const TString TQStringUtils::alphanum = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
const TString TQStringUtils::alphanumvar = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789$()";
const TString TQStringUtils::alphanumvarext = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789$()_";
const TString TQStringUtils::defaultIDchars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_.";
const TString TQStringUtils::controlReturnCharacters = "mAC";
const TString TQStringUtils::blanks = " \t";
const TString TQStringUtils::blanksAll = " \t\n\r";
const TRegexp TQStringUtils::latexcmd = "\\\\[a-zA-Z]+[{ }$]?";
const TRegexp TQStringUtils::latexmath = "\\$.*\\$";
const TRegexp TQStringUtils::roottex = "#[a-zA-Z]+";
const TRegexp TQStringUtils::html = "<[a-zA-Z]+>.*</[a-zA-Z]+>";
std::vector<TString> TQStringUtils::getTagPlaceholders(TString in) {
std::vector<TString> out;
TString dummy;
while (!in.IsNull()) {
TQStringUtils::readUpTo(in, dummy, "$");
if (in.IsNull())
continue;
TString field;
TQStringUtils::readToken(in, field, "$");
TString def;
int nDef = 0;
if (in.BeginsWith("(")) {
nDef = TQStringUtils::readBlock(in, def, "()[]{}", "''\"\"");
if (nDef > 0)
field.Append(TString::Format("(%s)", def.Data()));
} else {
nDef = TQStringUtils::readToken(in, def, getDefaultIDCharacters());
if (nDef > 0)
field.Append(def);
}
if (!def.IsNull()) {
TString keyName;
TQStringUtils::readUpTo(def, keyName, ",");
out.push_back(keyName);
}
}
return out;
}
TString TQStringUtils::getUniqueName(TDirectory * dir, TString proposal) {
TString name = proposal;
int i = 2;
while (dir && dir->FindObject(name.Data())) {
name = TString::Format("%s_i%d", proposal.Data(), i++);
}
return name;
}
TString TQStringUtils::getDetails(const TObject * obj) {
if (!obj) {
return TString("<invalid pointer>");
} else if (obj->InheritsFrom(TH1::Class())) {
return TQHistogramUtils::getDetailsAsString((TH1*)obj,2);
} else if (obj->InheritsFrom(TQCounter::Class())) {
return ((TQCounter*)obj)->getAsString();
} else if (obj->InheritsFrom(TPrincipal::Class())) {
return TQHistogramUtils::getDetailsAsString((TPrincipal*)obj);
} else if (obj->InheritsFrom(TQPCA::Class())) {
return ((TQPCA*)obj)->getDetailsAsString();
} else if (obj->InheritsFrom(TQSample::Class())) {
TString generator = "<unknown generator>";
TString process = "<unknown process>";
TString simulation = "";
TQSample * s = (TQSample*)obj;
TString retval;
if(s->getTagString(".xsp.generator", generator)){
retval.Append(generator);
}
if(s->getTagString(".xsp.simulation", simulation)){
if(!retval.IsNull()){
retval.Append(" (");
retval.Append(simulation);
retval.Append(")");
}
}
if(s->getTagString(".xsp.process", process)){
if(!retval.IsNull())
retval.Append(": ");
retval.Append(process);
}
double norm = s->getNormalisation();
if(norm != 1){
if(!retval.IsNull())
retval.Append(" - ");
retval.Append("norm.=");
if(norm > 0) retval.Append(TString::Format("%.6f",norm));
else if(norm < 0) retval.Append(TQStringUtils::makeBoldRed(TString::Format("%.3f",norm)));
else retval.Append(TQStringUtils::makeBoldYellow("0"));
}
if(s->hasSubSamples()){
if(!retval.IsNull()) retval.Append(" - ");
retval.Append("multisample");
}
return retval;
} else if (obj->InheritsFrom(TQValue::Class())) {
return ((TQValue*)obj)->getString();
} else if (obj->InheritsFrom(TParameter<double>::Class())) {
return TString::Format("%g", ((TParameter<double>*)obj)->GetVal());
} else if (obj->InheritsFrom(TCollection::Class())) {
int nEntries = ((TCollection*)obj)->GetEntries();
if (nEntries != 1) return TString::Format("%d entries", nEntries);
else return "1 entry";
} else if (obj->InheritsFrom(TQLink::Class())) {
return TString("--> ") + ((TQLink*)obj)->getDestAsString();
} else if (obj->InheritsFrom(TQTable::Class())) {
return ((TQTable*)obj)->getDetails();
} else if (obj->InheritsFrom(TPrincipal::Class())) {
return TQHistogramUtils::getDetailsAsString((TPrincipal*)obj);
} else if (obj->InheritsFrom(TGraph::Class())) {
return TQHistogramUtils::getDetailsAsString((TGraph*)obj);
} else if (obj->InheritsFrom(TLegend::Class())){
TLegend* l = (TLegend*)obj;
return TString::Format("%d entries (%d columns, %d rows)",(l->GetListOfPrimitives() ? l->GetListOfPrimitives()->GetEntries() : 0),l->GetNColumns(),l->GetNRows());
} else if (obj->InheritsFrom(THStack::Class())){
THStack* s = (THStack*)(obj);
return s->GetStack() ? TString::Format("%d histograms",(s->GetStack()->GetEntries())) : "(empty)";
} else if (obj->InheritsFrom(TQFolder::Class())){
const TQFolder* f = dynamic_cast<const TQFolder*>(obj);
int nObj = f->getNObjects();
int nTag = f->getNTags();
TString retval;
if(nObj == 0) retval += "no objects";
else if(nObj == 1) retval += "1 object";
else retval += TString::Format("%d objects",nObj);
retval += ", ";
if(nTag == 0) retval += "no tags";
else if(nTag == 1) retval += "1 tag";
else retval += TString::Format("%d tags",nTag);
return retval;
} else {
return TString::Format("<no details for class %s available>", obj->IsA()->GetName());
}
}
TString TQStringUtils::getStatusBar(int pos, int max, const TString& def) {
if (def.Length() != 4) {
return "";
}
TString bar;
bar.Append(def[0]);
for (int i = 1; i <= max; i++) {
if (i <= pos) {
bar.Append(def[1]);
} else {
bar.Append(def[2]);
}
}
bar.Append(def[3]);
return bar;
}
bool TQStringUtils::isValidIdentifier(const TString& identifier,
const TString& characters, int minLength, int maxLength) {
const size_t len(identifier.Length());
if (minLength >= 0 && len < (size_t)minLength) {
return false;
}
if (maxLength >= 0 && len > (size_t)maxLength) {
return false;
}
for (size_t i = 0; i < len; i++) {
if (characters.Index(identifier[i]) == kNPOS) {
return false;
}
}
return true;
}
TString TQStringUtils::getSIsuffix(int exponent, const TString& format){
if(exponent > 0){
if(exponent < 3) return "";
if(exponent < 6) return "k";
if(exponent < 9) return "M";
if(exponent < 12) return "T";
if(exponent < 15) return "P";
if(exponent < 18) return "Z";
} else {
if(exponent > -3) return "";
if(exponent > -6) return "m";
if(exponent > -9){
if(format == "latex"){
return "\\mu";
} else if(format=="html"){
return "μ";
} else if(format=="unicode"){
return "ยต";
} else {
return "mu";
}
}
if(exponent > -12) return "n";
if(exponent > -15) return "p";
if(exponent > -18) return "f";
if(exponent > -21) return "a";
if(exponent > -24) return "z";
if(exponent > -27) return "y";
}
return "?";
}
bool TQStringUtils::isEmpty(const TString& str, bool allowBlanks) {
if (allowBlanks) {
return TQStringUtils::countLeading(str, TQStringUtils::getBlanks()) == str.Length();
} else {
return str.IsNull();
}
}
bool TQStringUtils::equal(const TString& first, const TString& second){
if (first.Length() != second.Length()) return false;
return (first.CompareTo(second) == 0);
}
bool TQStringUtils::requal(const TString& first, const TString& second){
if (first.Length() != second.Length()) return false;
return (TQStringUtils::compareTails(first,second) == first.Length());
}
TString TQStringUtils::makeValidIdentifier(const TString& identifier,
const TString& characters, const TString& replacement) {
TString result;
int pos = -1;
while (++pos < identifier.Length()) {
if (characters.Index(identifier[pos]) != kNPOS)
result.Append(identifier[pos]);
else
result.Append(replacement);
}
return result;
}
bool TQStringUtils::getBoolFromString(const TString& boolString_, bool &isBool) {
TString boolString = TQStringUtils::trim(boolString_);
bool isTrue =
(boolString.CompareTo("yes", TString::kIgnoreCase) == 0) ||
(boolString.CompareTo("ok", TString::kIgnoreCase) == 0) ||
(boolString.CompareTo("true", TString::kIgnoreCase) == 0) ||
(TQStringUtils::isNumber(boolString) && boolString.Atof() != 0.);
bool isFalse =
(boolString.CompareTo("no", TString::kIgnoreCase) == 0) ||
(boolString.CompareTo("fail", TString::kIgnoreCase) == 0) ||
(boolString.CompareTo("false", TString::kIgnoreCase) == 0) ||
(TQStringUtils::isNumber(boolString) && boolString.Atof() == 0.);
if (isFalse && !isTrue) {
isBool = true;
return false;
} else if (!isFalse && isTrue) {
isBool = true;
return true;
} else {
isBool = false;
return false;
}
}
int TQStringUtils::interpret(const TString& str){
bool errMsg = gInterpreter->IsErrorMessagesEnabled();
gInterpreter->SetErrorMessages(false);
int val = gROOT->ProcessLine(str);
gInterpreter->SetErrorMessages(errMsg);
return val;
}
int TQStringUtils::getColorFromString(TString colorString) {
if ((colorString.Index('#') == 0) && (colorString.Length() == 7)) {
return TColor::GetColor(colorString);
}
colorString.Append(";");
return TQStringUtils::interpret(colorString);
}
bool TQStringUtils::getBoolFromString(const TString& boolString) {
bool isBool = false;
return getBoolFromString(boolString, isBool);
}
TString TQStringUtils::getStringFromBool(bool boolValue) {
if (boolValue)
return "true";
else
return "false";
}
bool TQStringUtils::isDouble(TString str) {
str = trim(str);
TString dummy;
int nSign = readToken(str, dummy, "+-");
if(TQStringUtils::equal(str,"inf")) return true;
int nNumPre = readToken(str, dummy, getNumerals());
int nDots = readToken(str, dummy, ".");
int nNumPost = readToken(str, dummy, getNumerals());
int nExp = removeLeading(str, "eE");
int nExpSign = readToken(str, dummy, "+-");
int nNumExp = readToken(str, dummy, getNumerals());
return str.IsNull() && nSign <= 1 && (nNumPre > 0 || nNumPost > 0) &&
((nDots == 1 && (nExp + nExpSign + nNumExp) == 0) ||
(nExp == 1 && nExpSign <= 1 && nNumExp > 0 && nDots <= 1));
}
bool TQStringUtils::isInteger(TString str) {
str = trim(str);
TString dummy;
TString strExp;
int nSign = readToken(str, dummy, "+-");
int nNum = readToken(str, dummy, getNumerals());
return str.IsNull() && nSign <= 1 && nNum > 0;
}
bool TQStringUtils::isNumber(const TString& str) {
return isInteger(str) || isDouble(str);
}
bool TQStringUtils::isBool(const TString& str) {
bool isBool = false;
getBoolFromString(str, isBool);
return isBool;
}
int TQStringUtils::getEditDistance(const TString& str1, const TString& str2) {
int m = str1.Length();
int n = str2.Length();
unsigned int * d = new unsigned int[(m + 1) * (n + 1)];
for (int i = 0; i <= m; i++) {
d[i] = i;
}
for (int j = 0; j <= n; j++) {
d[(m + 1) * j] = j;
}
for (int j = 1; j <= n; j++) {
for (int i = 1; i <= m; i++) {
if (str1[i - 1] == str2[j - 1]) {
d[i + (m + 1) * j] = d[(i - 1) + (m + 1) * (j - 1)];
} else {
int del = d[(i - 1) + (m + 1) * j] + 1;
int ins = d[i + (m + 1) * (j - 1)] + 1;
int sub = d[(i - 1) + (m + 1) * (j - 1)] + 1;
d[i + (m + 1) * j] = TMath::Min(del, TMath::Min(ins, sub));
}
}
}
int dist = d[m + (m + 1) * n];
delete [] d;
return dist;
}
TString TQStringUtils::getLongestCommonSubstring(const std::vector<TString>& fullStrings_, const TString& seed){
std::vector<TString> fullStrings = fullStrings_;
bool ok = true;
size_t seedLength = seed.Length();
TString str1,str2;
int pos1,pos2;
while (ok && fullStrings.size()>1) {
str1 = fullStrings.back(); fullStrings.pop_back();
str2 = fullStrings.back(); fullStrings.pop_back();
pos1 = TQStringUtils::find(str1,seed,0);
if (pos1==kNPOS) {
ERRORfunc("Cannot determine longest common substring with seed '%s': failed to find seed in string '%s'",seed.Data(),str1.Data());
return TString("");
}
pos2 = TQStringUtils::find(str2,seed,0);
if (pos2==kNPOS) {
ERRORfunc("Cannot determine longest common substring with seed '%s': failed to find seed in string '%s'",seed.Data(),str2.Data());
return TString("");
}
size_t lenPre = TQStringUtils::compareTails( str1(0,pos1) , str2(0,pos2) );
size_t lenPost = TQStringUtils::compareHeads( str1(pos1+seedLength,str1.Length()), str2(pos2+seedLength,str2.Length()) );
TString common = str1(pos1-lenPre,lenPre+seedLength+lenPost);
fullStrings.push_back(common);
}
if ( ok && fullStrings.size()>0 ) return fullStrings[0];
return TString("");
}
TString TQStringUtils::removeDuplicateSubStrings(const TString& longString, int minLength) {
TString dummy;
return TQStringUtils::removeDuplicateSubStrings(longString,dummy, minLength);
}
TString TQStringUtils::removeDuplicateSubStrings(const TString& longString_, TString& removedSequence, int minLength) {
removedSequence = "";
int maxOccurances = 0;
TString longString = longString_;
int pos = 0;
int firstPos = 0;
while (pos<longString.Length()-2*minLength) {
int thisLength = minLength;
int theseOccurances = TQStringUtils::countText(longString(pos+minLength,longString.Length()-pos-minLength),longString(pos,minLength));
if (theseOccurances > maxOccurances) {
maxOccurances = theseOccurances;
firstPos = pos;
while( theseOccurances >= maxOccurances ) {
++thisLength;
theseOccurances = TQStringUtils::countText(longString(pos+thisLength,longString.Length()-pos-thisLength),longString(pos,thisLength));
}
removedSequence = TString(longString(pos,--thisLength));
}
++pos;
}
int toRemove = TQStringUtils::find(longString,removedSequence,firstPos+removedSequence.Length());
if (toRemove == kNPOS) ERRORfunc("Logic error in string parsing detected!");
while (toRemove != kNPOS) {
longString.Remove(toRemove,removedSequence.Length());
toRemove = TQStringUtils::find(longString,removedSequence,firstPos+removedSequence.Length());
--maxOccurances;
}
if (maxOccurances != 0) {
ERRORfunc("Logic error in string parsing detected! %d occurances have not been removed",maxOccurances);
}
return longString;
}
int TQStringUtils::testNumber(double number, TString test) {
TString op;
TQStringUtils::removeLeadingBlanks(test);
if (!TQStringUtils::readToken(test, op, "!=<>")) {
return -1;
}
TString strNum;
TQStringUtils::removeLeadingBlanks(test);
if (!TQStringUtils::readToken(test, strNum, TQStringUtils::getNumerals() + "+-.")) {
return -1;
}
if (!TQStringUtils::isNumber(strNum)) {
return -1;
}
double myNum = strNum.Atof();
TQStringUtils::removeLeadingBlanks(test);
if (!test.IsNull()) {
return -1;
}
if (op.CompareTo("==") == 0) {
return (number == myNum) ? 1 : 0;
} else if (op.CompareTo("!=") == 0) {
return (number != myNum) ? 1 : 0;
} else if (op.CompareTo(">=") == 0) {
return (number >= myNum) ? 1 : 0;
} else if (op.CompareTo("<=") == 0) {
return (number <= myNum) ? 1 : 0;
} else if (op.CompareTo(">") == 0) {
return (number > myNum) ? 1 : 0;
} else if (op.CompareTo("<") == 0) {
return (number < myNum) ? 1 : 0;
} else {
return -1;
}
}
bool TQStringUtils::matchesFilter(const TString& text, TString filter,
const TString& orSep, bool ignoreBlanks) {
if (!orSep.IsNull()) {
while (!filter.IsNull()) {
TString thisFilter;
readUpTo(filter, thisFilter, orSep);
if (ignoreBlanks)
thisFilter = trim(thisFilter);
if (matchesFilter(text, thisFilter))
return true;
removeLeading(filter, orSep, 1);
}
return false;
} else {
return ((TQStringUtils::removeLeading(filter, "!", 1) > 0) != matches(text, filter));
}
}
bool TQStringUtils::matches(const TString& text, const TString& pattern) {
if (text.Length() > 0 && pattern.Length() > 0) {
if (text[0] == pattern[0] || pattern[0] == '?') {
return matches(text(1, text.Length()), pattern(1, pattern.Length()));
}
if (pattern[0] == '*') {
return matches(text, pattern(1, pattern.Length()))
|| matches(text(1, text.Length()), pattern);
}
return false;
} else {
return (text.Length() == 0 && (pattern.CompareTo('*') == 0 || pattern.Length() == 0));
}
}
bool TQStringUtils::hasWildcards(TString text) {
return text.Contains("*") || text.Contains("?");
}
int TQStringUtils::compare(const TString& a, const TString& b) {
int i = 0;
while (i < a.Length() && i < b.Length()) {
if (a[i] > b[i]) {
return 1;
} else if (a[i] < b[i]) {
return -1;
}
i++;
}
if (a.Length() > b.Length()) {
return 1;
} else if (a.Length() < b.Length()) {
return -1;
} else {
return 0;
}
}
int TQStringUtils::compareHeads(const TString& str1, const TString& str2) {
int pos = 0;
while (str1.Length() > pos && str2.Length() > pos && str1[pos] == str2[pos]) {
pos++;
}
return pos;
}
int TQStringUtils::compareTails(const TString& str1, const TString& str2) {
int pos = 0;
while (str1.Length() > pos && str2.Length() > pos
&& str1[str1.Length() - pos - 1] == str2[str2.Length() - pos - 1]) {
pos++;
}
return pos;
}
TString TQStringUtils::getMaxCommonHead(TList * strings) {
if (!strings || strings->GetEntries() == 0) {
return "";
}
TString str;
int min = -1;
TQIterator itr(strings);
while (itr.hasNext()) {
TString name = itr.readNext()->GetName();
if (min == -1) {
str = name;
min = str.Length();
} else {
min = TMath::Min(min, compareHeads(str, name));
}
}
str = str(0, min);
return str;
}
bool TQStringUtils::isEscaped (const TString& text, int pos, const TString& escChar) {
if (pos > text.Length()) return false;
int other = findLastNotOf(text,escChar,pos-1);
return (pos-other+1)%2;
}
TString TQStringUtils::removeEscapes(const TString& text, const TString& escapes) {
TString output;
int i = -1;
while (++i < text.Length()) {
if (escapes.Index(text[i]) == kNPOS) {
output.Append(text[i]);
} else if (i + 1 < text.Length() && escapes.Index(text[i + 1]) != kNPOS) {
output.Append(text[++i]);
}
}
return output;
}
TString TQStringUtils::insertEscapes(const TString& text, const TString& escapes) {
TString output;
int i = -1;
while (++i < text.Length()) {
if (escapes.Length() != 0 && escapes.Index(text[i]) != kNPOS) {
output.Append(escapes[0]);
}
output.Append(text[i]);
}
return output;
}
int TQStringUtils::reduceToCommonPrefix(TString& prefix, const TString& other){
size_t i=0;
size_t max = std::min(prefix.Length(),other.Length());
while(i < max){
if(prefix[i] == other[i]) i++;
else break;
}
prefix.Remove(i);
return i;
}
TString TQStringUtils::concat(TString first, const TString& second) {
first.Append(second);
return first;
}
size_t TQStringUtils::length(const TString& s){
return s.Length();
}
size_t TQStringUtils::length(const std::string& s){
return s.size();
}
TString TQStringUtils::concatNames(TCollection* c, const TString& sep, const TString& quote) {
if(c->GetSize() < 1) return "<empty>";
bool first = true;
std::stringstream ss;
for(auto it:*c){
if (!first) {
ss << sep;
} else {
first = false;
}
if(!it)
ss << "NULL";
else {
if(TQStringUtils::length(quote) == 2){
ss << quote[0];
}
ss << it->GetName();
if(TQStringUtils::length(quote) == 2){
ss << quote[1];
}
}
}
return ss.str().c_str();
}
TString TQStringUtils::getFirstToken(TString text, const TString& sep, bool , const TString& blocks, const TString& quotes) {
TString token;
TQStringUtils::readUpTo(text, token, sep, blocks, quotes);
return token;
}
TList * TQStringUtils::tokenize(
TString text, const TString& sep, bool trim, const TString& blocks, const TString& quotes) {
TList * result = NULL;
TString token;
bool stop = false;
while (!stop) {
int nRead = TQStringUtils::readUpTo(text, token, sep, blocks, quotes);
bool leadingSep = (TQStringUtils::removeLeading(text, sep, 1) > 0);
if (nRead == 0 && !leadingSep) {
if (!text.IsNull() && result) {
delete result;
result = NULL;
}
stop = true;
continue;
}
if (!result) {
result = new TList();
result->SetOwner(true);
}
if (trim) {
token = TQStringUtils::trim(token);
}
result->Add(new TObjString(token.Data()));
token.Clear();
if (leadingSep && text.IsNull()) {
result->Add(new TObjString());
}
}
return result;
}
std::vector<TString> TQStringUtils::tokenizeVector(TString text, const TString& sep, bool trim, const TString& blocks, const TString& quotes) {
TString origText = text;
std::vector<TString> result;
TString token;
bool removedSep = false;
while (TQStringUtils::readUpToText(text, token, sep, blocks, quotes) || !text.IsNull()) {
if (trim) {
token = TQStringUtils::trim(token);
}
result.push_back(token);
token.Clear();
removedSep = TQStringUtils::removeLeading(text, sep);
if (!removedSep && !text.IsNull()) {
ERRORfunc("could not split text '%s' at delimiter '%s' (search starting from position %d) while respecting blocks '%s' and quotes '%s' - there seems to be a syntax error in the string, maybe a missing parenthesis?",origText.Data(), sep.Data(), origText.Length()-text.Length(), blocks.Data(), quotes.Data() );
return std::vector<TString>();
}
if (removedSep && text.IsNull()) {
result.push_back("");
}
}
return result;
}
bool TQStringUtils::append(TString &text, const TString &appendix, const TString& sep) {
bool first = true;
if (!text.IsNull()) {
text.Append(sep);
first = false;
}
text.Append(appendix);
return !first;
}
TString TQStringUtils::rtrim(const TString& text, const TString& blanks) {
int end = text.Length() - 1;
while (end >= 0 && blanks.Index(text[end]) != kNPOS)
end--;
return text(0, end + 1);
}
TString TQStringUtils::trim(const TString& text, const TString& blanks) {
int start = 0;
while (start < text.Length() && blanks.Index(text[start]) != kNPOS)
start++;
int end = text.Length() - 1;
while (end >= 0 && blanks.Index(text[end]) != kNPOS)
end--;
return text(start, end - start + 1);
}
TString TQStringUtils::repeat(const TString& text, int n, const TString& sep) {
TString result;
for (int i = 0; i < n; i++) {
result.Append(text);
if (i < n - 1 && !sep.IsNull()) {
result.Append(sep);
}
}
return result;
}
TString TQStringUtils::repeatSpaces(int n) {
return repeat(" ", n);
}
TString TQStringUtils::repeatTabs(int n) {
return repeat("\t", n);
}
int TQStringUtils::getWidth(const TString& text) {
TString returnChars = "mAC";
int width = 0;
bool escape = false;
for (int pos = 0; pos < text.Length(); pos++) {
if (escape) {
if (returnChars.Index(text[pos]) != kNPOS)
escape = false;
} else {
if (text[pos] == '\033')
escape = true;
else if(text[pos] > 0 || text[pos] == -61 || text[pos] == -62 || text[pos] == -30 || text[pos] == -50 || text[pos] == -54 || text[pos] == -49 || text[pos] == -31 || text[pos] == -53){
width++;
}
}
}
return width;
}
int TQStringUtils::getCharIndex(const TString& text, int index) {
TString returnChars = "mAC";
int width = 0;
bool escape = false;
for (int pos = 0; pos < text.Length(); pos++) {
if(width == index) return pos;
if (escape) {
if (returnChars.Index(text[pos]) != kNPOS)
escape = false;
} else {
if (text[pos] == '\033')
escape = true;
else if(text[pos] > 0 || text[pos] == -61 || text[pos] == -62 || text[pos] == -30 || text[pos] == -50 || text[pos] == -54 || text[pos] == -49 || text[pos] == -31 || text[pos] == -53){
width++;
}
}
}
return kNPOS;
}
TString TQStringUtils::fixedWidth(const TString& text, int width, const char* options) {
TString opts(options);
return TQStringUtils::fixedWidth(text,width,opts);
}
TString TQStringUtils::fixedWidth(const char* text, int width, const char* options){
TString opts(options);
TString newText(text);
return TQStringUtils::fixedWidth(newText,width,opts);
}
TString TQStringUtils::fixedWidth(const char* text, int width, const TString& options){
TString newText(text);
return TQStringUtils::fixedWidth(newText,width,options);
}
bool TQStringUtils::readCharacter(const TString& text, int& index, int& count){
if (text[index] == '\033'){
while(index < text.Length()){
index++;
if(TQStringUtils::controlReturnCharacters.Index(text[index]) != kNPOS){
index++;
return true;
}
}
return false;
}
index++;
count++;
while(index < text.Length()){
if(text[index] > 0
|| ((-61 >= text[index]) && (text[index] >= -62))
|| ((-49 >= text[index]) && (text[index] >= -54))
|| ((-30 >= text[index]) && (text[index] >= -32)) ){
return true;
}
index++;
}
return true;
}
TString TQStringUtils::fixedWidth(const TString& text, int width, const TString& options) {
int lastidx = TQStringUtils::getCharIndex(text,width+1);
if((lastidx < 1) || (lastidx >= text.Length())) lastidx = TQStringUtils::getCharIndex(text,width);
else lastidx--;
if ((lastidx >= width) && (lastidx < text.Length())) {
std::stringstream s;
bool showDots = options.Contains(".") && (width > 6);
int reducedWidth = showDots ? (width-3) : width;
int len = 0;
int index = 0;
int lastIndex = 0;
int lastLen = 0;
while(index < text.Length()){
if(!TQStringUtils::readCharacter(text,index,len)) break;;
if((len == lastLen) || (len < reducedWidth+1)) s << text(lastIndex,index-lastIndex);
lastLen = len;
lastIndex = index;
}
TString retval(s.str().c_str());
if(showDots) retval.Append("...");
return retval;
} else {
int actualWidth = TQStringUtils::getWidth(text);
int nSpaces = std::max(width-actualWidth,0);
if(options.Contains("r")){
return TString::Format("%*s%s", nSpaces, "", text.Data());
} else if(options.Contains("c")){
return TString::Format("%*s%s%*s", (int)(0.5*(nSpaces+1)), "", text.Data(), (int)(0.5*(nSpaces)), "");
} else {
return TString::Format("%s%*s", text.Data(), nSpaces, "");
}
}
}
TString TQStringUtils::fixedWidth(const TString& text, int width, bool rightJustified) {
return TQStringUtils::fixedWidth(text,width,rightJustified ? "r" : "l");
}
TString TQStringUtils::fixedWidth(const char* text, int width, bool rightJustified) {
TString newText(text);
return TQStringUtils::fixedWidth(newText,width,rightJustified ? "r" : "l");
}
TString TQStringUtils::maxLength(const TString& text, int maxLength, const TString& appendix) {
if (text.Length() > maxLength) {
TString str = text(0, maxLength - appendix.Length());
str.Append(appendix);
return str;
} else {
return text;
}
}
TString TQStringUtils::getThousandsSeparators(int value, const TString& sep) {
return TQStringUtils::getThousandsSeparators(TString::Format("%d", value), sep);
}
TString TQStringUtils::getThousandsSeparators(TString text, const TString& sep) {
TString result;
while (text.Length() > 3) {
result.Prepend(text(text.Length() - 3, 3));
result.Prepend(sep);
text.Remove((size_t)(text.Length() - 3), (size_t)3);
}
result.Prepend(text);
return result;
}
TString TQStringUtils::getThousandsSeparators(Long64_t value, const TString& sep) {
return TQStringUtils::getThousandsSeparators(TString::LLtoa(value,10), sep);
}
TString TQStringUtils::getIndentationLines(int indent) {
TString lines;
if (indent > 0)
lines = "|-";
lines.Prepend(repeat("| ", indent - 1));
return lines;
}
TString TQStringUtils::formatSignificantDigits(double val, int nDigits) {
TString retval;
if (nDigits < 0) {
retval = TString::Format("%.*f", -nDigits, val);
} else if (nDigits > 0) {
double sign = 1.;
if (val < 0.) {
val = TMath::Abs(val);
sign = -1.;
}
int n = TMath::FloorNint(TMath::Log10(val)) + 1;
if (n == 1)
n = 0;
retval = TString::Format("%.*f", TMath::Max(nDigits - n, 0), sign * val);
} else {
return retval = "";
}
if(retval.Contains(".")){
if(TQStringUtils::removeTrailing(retval,"0") > 0){
TQStringUtils::removeTrailing(retval,".");
}
}
return retval;
}
TString TQStringUtils::formatValueErrorPDG(double val, double err, int expval, const TString& format){
if(err == 0){
return TString::Format("%g",val);
}
int exponent = 0;
double val_shifted = val;
double err_shifted = err;
while(err_shifted <= 100){
val_shifted *= 10;
err_shifted *= 10;
exponent -=1;
}
while(err_shifted > 1000){
val_shifted /= 10;
err_shifted /= 10;
exponent +=1;
}
int firstdigits(err_shifted);
int ndigits = 0;
double int_val,int_err;
if(firstdigits <= 354){
int_val = floor(0.5+0.1*val_shifted);
int_err = floor(0.5+0.1*err_shifted);
ndigits = 1;
exponent += 1;
} else if(firstdigits <= 949){
int_val = floor(0.5+0.01*val_shifted);
int_err = floor(0.5+0.01*err_shifted);
ndigits = 1;
exponent += 2;
} else {
int_val = floor(0.5+0.01*val_shifted);
int_err = 10;
ndigits = 2;
exponent += 2;
}
double shift = pow(10,exponent-expval);
ndigits = std::max(0,ndigits+expval-exponent-1);
double val_final = shift*int_val;
double err_final = shift*int_err;
std::stringstream ss;
if(format == "latex") ss << "\\ensuremath{";
if(expval != 0) ss << "(";
ss << "%." << ndigits << "f";
if(format == "latex") ss << " \\pm ";
else if(format == "html") ss << "±";
else ss << " +/- ";
ss << "%." << ndigits << "f";
if(expval != 0){
ss << ")";
if(format == "latex") ss << " \\times 10^{" << expval << "}";
else if(format == "html") ss << "× <superscript>" << expval << "</superscript>";
else ss << "*10^" << expval;
}
if(format == "latex") ss << "}";
return TString::Format(ss.str().c_str(),val_final,err_final);
}
TString TQStringUtils::formatValueError(double val, double err, const TString& format){
if(!TQUtils::isNum(err) || !TQUtils::isNum(val)){
return TString::Format(format,val,err);
}
int nSigDigitsErr = std::min(ceil(-log10(err)),0.);
int firstdigit = floor(err * pow(10,ceil(-log10(err))));
if(firstdigit == 1){
nSigDigitsErr++;
}
double nDiff = ceil(log10(val/err));
double valRounded = TQUtils::roundAuto(val,nDiff+nSigDigitsErr);
double errRounded = TQUtils::roundAuto(err,nSigDigitsErr);
return TString::Format(format,valRounded,errRounded);
}
bool TQStringUtils::printDiffOfLists(TList * l1, TList * l2, bool ignoreMatches) {
if (!l1 || !l2) {
return false;
}
int n1 = 0;
int n2 = 0;
if (l1) {
n1 = l1->GetEntries();
l1->Sort();
}
if (l2) {
n2 = l2->GetEntries();
l2->Sort();
}
int max1 = 0;
int max2 = 0;
TQIterator itr1(l1);
while (itr1.hasNext()) {
max1 = TMath::Max(max1, TString(itr1.readNext()->GetName()).Length());
}
TQIterator itr2(l2);
while (itr2.hasNext()) {
max2 = TMath::Max(max2, TString(itr2.readNext()->GetName()).Length());
}
bool match = true;
TString headline = TString::Format("%-*s %-*s", max1, "List 1", max2, "List 2");
std::cout << TQStringUtils::makeBoldWhite(headline).Data() << std::endl;
std::cout << TQStringUtils::makeBoldWhite(
TQStringUtils::repeat("=", headline.Length())).Data() << std::endl;
int i1 = 0;
int i2 = 0;
while (i1 < n1 || i2 < n2) {
TObject * obj1 = (i1 < n1) ? l1->At(i1) : NULL;
TObject * obj2 = (i2 < n2) ? l2->At(i2) : NULL;
int compare = -1;
if (obj1 && obj2) {
compare = obj1->Compare(obj2);
i1 += (compare <= 0) ? 1 : 0;
i2 += (compare >= 0) ? 1 : 0;
} else if (obj1) {
compare = -1;
i1++;
} else if (obj2) {
compare = 1;
i2++;
} else {
return false;
}
if (compare < 0) {
match = false;
std::cout << TString::Format("%-*s %-*s",
max1, obj1->GetName(), max2, "--").Data() << std::endl;
} else if (compare > 0) {
match = false;
std::cout << TString::Format("%-*s %-*s",
max1, "--", max2, obj2->GetName()).Data() << std::endl;
} else if (!ignoreMatches) {
std::cout << TString::Format("%-*s %-*s",
max1, obj1->GetName(), max2, obj2->GetName()).Data() << std::endl;
}
}
return match;
}
int TQStringUtils::removeLeading(TString &text, TString characters, int nMax) {
int pos = countLeading(text, characters, nMax);
if(pos < 1) return 0;
text.Remove(0, pos);
return pos;
}
int TQStringUtils::removeTrailing(TString &text, TString characters, int nMax) {
int nChar = countTrailing(text, characters, nMax);
if(nChar < 1) return 0;
text.Remove(text.Length() - nChar, text.Length());
return nChar;
}
bool TQStringUtils::removeLeadingText(TString &text, TString prefix) {
if (text.BeginsWith(prefix)) {
text.Remove(0, prefix.Length());
return true;
} else {
return false;
}
}
bool TQStringUtils::removeTrailingText(TString &text, TString appendix) {
if (text.EndsWith(appendix)) {
text.Remove(text.Length() - appendix.Length(), appendix.Length());
return true;
} else {
return false;
}
}
int TQStringUtils::removeAll(TString &text, const TString& chars, TString::ECaseCompare comp, int max) {
int pos = 0;
int nMatches = 0;
while (pos<text.Length() && (max<0 || nMatches<max) ) {
if ( chars.Contains(text(pos), comp) ) {
text.Remove(pos,1);
++nMatches;
} else {
++pos;
}
}
return nMatches;
}
int TQStringUtils::ensureTrailingText(TString &text, const TString& appendix) {
int tmax = text.Length() -1;
int amax = appendix.Length() -1;
int pos = 0;
while(pos <= amax && pos <= tmax){
if(appendix[amax-pos] == text[tmax-pos])
pos++;
else {
amax--;
pos = 0;
}
}
text.Append(appendix(pos,appendix.Length()));
return appendix.Length()-pos;
}
int TQStringUtils::ensureLeadingText(TString &text, const TString& prefix) {
int offset = 0;
if(prefix.Length() > text.Length()) offset = prefix.Length() - text.Length();
int pos = prefix.Length() -1;
while(pos-offset >= 0 && offset < prefix.Length()){
if(text[pos-offset] == prefix[pos]){
pos--;
} else {
offset++;
pos=prefix.Length() -1 ;
}
}
text.Prepend(prefix(0,offset));
return offset;
}
int TQStringUtils::removeLeadingBlanks(TString &text, int nMax) {
return TQStringUtils::removeLeading(text, TQStringUtils::getBlanks(), nMax);
}
int TQStringUtils::removeTrailingBlanks(TString &text, int nMax) {
return TQStringUtils::removeTrailing(text, TQStringUtils::getBlanks(), nMax);
}
int TQStringUtils::countLeading(const TString& text, const TString& characters, int nMax) {
int pos = 0;
while (pos < text.Length() && characters.Index(text[pos]) != kNPOS
&& (nMax < 0 || pos < nMax)) {
pos++;
}
return pos;
}
int TQStringUtils::countTrailing(const TString& text, const TString& characters, int nMax) {
int pos = text.Length() - 1;
while (pos >= 0 && characters.Index(text[pos]) != kNPOS
&& (nMax < 0 || pos >= (text.Length() - nMax))) {
pos--;
}
return text.Length() - 1 - pos;
}
int TQStringUtils::countText(const TString& haystack, const TString& needle) {
if(needle.Length() > haystack.Length() || needle.IsNull() || haystack.IsNull()) return 0;
int num = 0;
int hpos = 0;
int npos = 0;
while (hpos < haystack.Length()){
if(needle[npos] == haystack[hpos]){
if(npos+1 == needle.Length()){
npos = 0;
num++;
} else {
npos++;
}
} else {
npos = 0;
}
hpos++;
}
return num;
}
TString TQStringUtils::cutUnit(TString &label) {
std::string input = label.Data();
std::size_t start = input.find_last_of("[");
std::size_t end = input.find_last_of("]");
if (start != std::string::npos && end != std::string::npos && end > start) {
TString unit = label(start + 1, end - start - 1);
TString appendix = label(end + 1, label.Length());
label.Remove(start, label.Length());
TQStringUtils::removeTrailingBlanks(label);
label.Append(appendix);
return unit;
} else {
return "";
}
}
TString TQStringUtils::getUnit(TString label) {
return TQStringUtils::cutUnit(label);
}
TString TQStringUtils::getWithoutUnit(TString label) {
TQStringUtils::cutUnit(label);
return label;
}
int TQStringUtils::readBlanks(TString & in) {
TString dummy;
return readToken(in, dummy, getBlanks());
}
int TQStringUtils::readBlanksAndNewlines(TString & in) {
int dummy;
return readBlanksAndNewlines(in, dummy);
}
int TQStringUtils::readBlanksAndNewlines(TString & in, int &nNewlines) {
TString dummy;
int n = 0;
bool done = false;
while (!done) {
dummy.Clear();
n += readToken(in, dummy, getBlanks());
int n2 = readToken(in, dummy, "\n");
nNewlines += n2;
n += n2;
done = dummy.IsNull();
}
return n;
}
int TQStringUtils::readToken(TString & in, TString & out, const TString& characters, int nMax) {
int pos = countLeading(in, characters, nMax);
out.Append(in(0, pos));
in.Remove(0, pos);
return pos;
}
int TQStringUtils::readTokenAndBlock(TString & in,
TString & out, const TString& characters, const TString& blocks) {
int n = 0;
bool stop = false;
while (!stop) {
int nToken = readToken(in, out, characters);
int nBlock = readBlock(in, out, blocks, "", true);
n += nToken + nBlock;
stop = (nToken == 0 && nBlock == 0);
}
return n;
}
int TQStringUtils::readBlock(
TString & in,
TString & out,
const TString& blocks,
const TString& quotes,
bool keepEnclosed,
int ignoreUnexpectedClosingQuotes) {
if (blocks.Length() < 2 || (blocks.Length() % 2) != 0 || (quotes.Length() % 2) != 0)
return 0;
if (in.Length() == 0)
return 0;
std::vector<int> * blockStack = new std::vector<int>();
std::vector<int> * quoteStack = new std::vector<int>();
int nSubBlocks = blocks.Length() / 2;
int nQuoteTypes = quotes.Length() / 2;
if (ignoreUnexpectedClosingQuotes < 0) {
ignoreUnexpectedClosingQuotes = nQuoteTypes;
}
bool error = false;
bool found = false;
int pos = 0;
do {
if (quoteStack->size() > 0) {
if (in[pos] == quotes[quoteStack->back()]) {
quoteStack->pop_back();
}
continue;
}
found = false;
for (int i = 0; i < (pos > 0 ? nQuoteTypes : 0) && !found && !error; i++) {
if (in[pos] == quotes[2*i]) {
quoteStack->push_back(2*i + 1);
found = true;
} else if (i < ignoreUnexpectedClosingQuotes && in[pos] == quotes[2*i + 1]) {
error = true;
}
}
if (found || error)
continue;
if (blockStack->size() > 0 && in[pos] == blocks[blockStack->back()]) {
blockStack->pop_back();
continue;
}
found = false;
for (int i = 0; i < (pos > 0 ? nSubBlocks : 1) && !found && !error; i++) {
if (in[pos] == blocks[2*i]) {
blockStack->push_back(2*i + 1);
found = true;
} else if (in[pos] == blocks[2*i + 1]) {
error = true;
}
}
} while (blockStack->size() > 0 && ++pos < in.Length() && !error);
if (blockStack->size() > 0 || quoteStack->size() > 0 || error)
pos = 0;
delete blockStack;
delete quoteStack;
if (pos > 0) {
out.Append(in(keepEnclosed ? 0 : 1, pos - (keepEnclosed ? -1 : 1)));
in.Remove(0, pos + 1);
return pos + 1;
} else {
return 0;
}
}
int TQStringUtils::readUpToText(TString & in, TString & out,
const TString& upTo, const TString& blocks, const TString& quotes, int ignoreUnexpectedClosingQuotes) {
if (upTo.IsNull()) {
return readUpTo(in, out, upTo, blocks, quotes, ignoreUnexpectedClosingQuotes);
}
int N = 0;
bool stop = false;
while (!stop && !in.BeginsWith(upTo)) {
int n = readToken(in, out, upTo[0], 1);
n += readUpTo(in, out, upTo[0], blocks, quotes, ignoreUnexpectedClosingQuotes);
N += n;
stop = (n == 0);
}
return N;
}
int TQStringUtils::readUpTo(TString & in, TString & out,
const TString& upTo, const TString& blocks, const TString& quotes, int ignoreUnexpectedClosingQuotes) {
if ((blocks.Length() % 2) != 0 || (quotes.Length() % 2) != 0)
return 0;
if (in.Length() == 0)
return 0;
std::vector<int> * blockStack = new std::vector<int>();
std::vector<int> * quoteStack = new std::vector<int>();
int nSubBlocks = blocks.Length() / 2;
int nQuoteTypes = quotes.Length() / 2;
if (ignoreUnexpectedClosingQuotes < 0) {
ignoreUnexpectedClosingQuotes = nQuoteTypes;
}
bool error = false;
bool found = false;
int pos = 0;
do {
if (quoteStack->size() > 0) {
if (in[pos] == quotes[quoteStack->back()]) {
quoteStack->pop_back();
}
continue;
}
found = false;
for (int i = 0; i < nQuoteTypes && !found && !error; i++) {
if (in[pos] == quotes[2*i]) {
quoteStack->push_back(2*i + 1);
found = true;
} else if (i < ignoreUnexpectedClosingQuotes && in[pos] == quotes[2*i + 1]) {
error = true;
}
}
if (found || error)
continue;
if (blockStack->size() > 0 && in[pos] == blocks[blockStack->back()]) {
blockStack->pop_back();
continue;
}
found = false;
for (int i = 0; i < nSubBlocks && !found && !error; i++) {
if (in[pos] == blocks[2*i]) {
blockStack->push_back(2*i + 1);
found = true;
} else if (in[pos] == blocks[2*i + 1]) {
error = true;
}
}
} while (!(blockStack->size() == 0 && quoteStack->size() == 0
&& upTo.Index(in[pos]) != kNPOS) && ++pos < in.Length() && !error);
if (blockStack->size() > 0 || quoteStack->size() > 0 || error)
pos = 0;
delete blockStack;
delete quoteStack;
if (pos > 0) {
out.Append(in(0, pos));
in.Remove(0, pos);
return pos;
} else {
return 0;
}
}
TString TQStringUtils::expand(TString in, const TString& characters, const TString& blocks, bool embrace) {
TString out;
while (!in.IsNull()) {
TString token;
readTokenAndBlock(in, token, characters, blocks);
TString prefix;
readToken(token, prefix, characters);
TString block;
readBlock(token, block, blocks, "");
TString suffix;
readTokenAndBlock(token, suffix, characters, blocks);
if (embrace)
out.Append("(");
if (block.Length() > 0) {
TString expBlock = expand(block, characters, blocks, embrace);
while (!expBlock.IsNull()) {
TString subToken;
readTokenAndBlock(expBlock, subToken, characters, blocks);
TString subSuffix;
readUpTo(expBlock, subSuffix, characters + blocks);
out.Append(prefix);
out.Append(subToken);
out.Append(suffix);
out.Append(subSuffix);
}
} else {
out.Append(prefix);
out.Append(suffix);
}
if (embrace)
out.Append(")");
suffix.Clear();
readUpTo(in, suffix, characters + blocks);
out.Append(suffix);
}
return out;
}
TString TQStringUtils::replace(TString str, const TString& needle, const TString& newNeedle){
str.ReplaceAll(needle,newNeedle);
return str;
}
TString TQStringUtils::replace(TString str, const char* needle, const TString& newNeedle){
str.ReplaceAll(needle,newNeedle);
return str;
}
TString TQStringUtils::replace(TString str, const TString& needle, const char* newNeedle){
str.ReplaceAll(needle,newNeedle);
return str;
}
TString TQStringUtils::replace(TString str, const char* needle, const char* newNeedle){
str.ReplaceAll(needle,newNeedle);
return str;
}
std::vector<TString> TQStringUtils::extractMatches(const TString& input, const TString& regexp){
std::vector<TString> retVec;
TPRegexp reg(regexp);
Ssiz_t nextPos = input.Index(reg);
while (nextPos>=0) {
retVec.push_back(TString( input(reg,nextPos) ));
nextPos = input.Index(reg,nextPos+1);
}
return retVec;
}
TString TQStringUtils::readPrefix(TString &in, const TString& delim, const TString& defaultPrefix) {
Ssiz_t pos = in.Index(delim);
if (pos == kNPOS) {
return defaultPrefix;
} else {
TString prefix = in(0, pos);
in.Remove(0, pos + delim.Length());
return prefix;
}
}
bool TQStringUtils::writeTextToFile(TList * text, const TString& filename) {
if (!text) {
return false;
}
std::ofstream * file = NULL;
if (!filename.IsNull()) {
file = new std::ofstream(filename.Data());
if (file->fail()) {
delete file;
return false;
}
}
TQIterator itr(text);
while (itr.hasNext()) {
TString str = itr.readNext()->GetName();
if (file) {
*file << str.Data() << std::endl;
} else {
std::cout << str.Data() << std::endl;
}
}
if (file) {
file->close();
delete file;
}
return true;
}
TString TQStringUtils::readFile(const TString& filename, const TString& blacklist, const TString& replace){
std::ifstream in(filename.Data(), std::ios::in | std::ios::binary);
std::stringstream s;
if(replace.Length() % 2 == 1) return "";
char c;
bool lastWasSpace = true;
while(in.get(c) && in.good()){
size_t irep = replace.Index(c);
if(irep < (size_t)replace.Length() && (irep % 2 == 0)){
c = replace[irep+1];
}
if(blacklist.Contains(c) || (c==' ' && lastWasSpace)) continue;
lastWasSpace = (c == ' ');
s << c;
}
return TString(s.str().c_str());
}
TString TQStringUtils::readSVGtoDataURI(const TString& filename){
TString content = TQStringUtils::trim(TQStringUtils::readFile(filename, "", "\"'\n \t "));
content.Prepend("data:image/svg+xml;utf8,");
return content;
}
std::vector<TString>* TQStringUtils::readFileLines(const TString& filename, size_t len, bool allowComments){
std::vector<TString>* lines = new std::vector<TString>();
if(readFileLines(lines,filename,len,allowComments) > 0){
return lines;
}
delete lines;
return NULL;
}
size_t TQStringUtils::readFileLines(std::vector<TString>* lines, const TString& filename, size_t len, bool allowComments){
std::ifstream infilestream(filename.Data(), std::ios::in);
if(!infilestream.is_open())
return 0;
char* tmp = (char*)malloc(len*sizeof(char));
size_t linecount = 0;
while (!infilestream.eof()){
infilestream.getline(tmp, len);
TString str(tmp);
while(!infilestream.eof() && (!infilestream.good() || TQStringUtils::removeTrailing(str,"\\") == 1)){
infilestream.clear();
infilestream.getline(tmp, len);
str.Append(tmp);
}
DEBUGfunc("reading line '%s'",str.Data());
TString resstr;
if(allowComments){
TQStringUtils::readUpTo(str,resstr,'#');
while(resstr.EndsWith("\\")){
TQStringUtils::removeTrailing(resstr,"\\");
TQStringUtils::readToken(str,resstr,"#");
TQStringUtils::readUpTo(str,resstr,'#');
}
resstr = TQStringUtils::trim(resstr,TQStringUtils::getAllBlanks());
} else {
resstr = TQStringUtils::trim(str,TQStringUtils::getAllBlanks());
}
if(resstr.Length() > 0){
lines->push_back(resstr);
linecount++;
}
}
free(tmp);
infilestream.close();
return linecount;
}
TList* TQStringUtils::readDefinitionFile(const TString& filename){
std::ifstream file(filename.Data());
TList* list = new TList();
list->SetOwner(true);
if (file.is_open()) {
std::string stdline;
TString definition;
while (getline(file, stdline)) {
TString line = TQStringUtils::trim(TString(stdline.c_str()));
if (!line.BeginsWith("#") && !line.IsNull()) {
definition.Append(line);
if (TQStringUtils::removeTrailing(definition, ";") > 0) {
list->Add(new TObjString(definition));
definition.Clear();
}
}
}
file.close();
if (!definition.IsNull()) ERRORfunc("missing terminating ';' in line '%d'!",definition.Data());
} else {
ERRORfunc("failed to load cut definitions from file '%s'!",filename.Data());
}
return list;
}
TString TQStringUtils::unquote(TString text, const TString& quotes) {
TQStringUtils::unquoteInPlace(text,quotes);
return text;
}
TString TQStringUtils::quote (const TString& str, char q){
return q + str + q;
}
void TQStringUtils::unquoteInPlace(TString& text, const TString& quotes) {
for(int i=0; i < quotes.Length(); ++i){
const TString s(quotes(i,1));
DEBUGfunc("stripping '%s'",s.Data());
if(text.BeginsWith(s) && text.EndsWith(s)){
text.Remove(0,1);
text.Remove(text.Length() - 1, 1);
}
}
}
TString TQStringUtils::unblock(TString text, const TString& blocks) {
for(int i=0; i < blocks.Length(); i+=2){
if(text.BeginsWith(blocks(i,1)) && text.EndsWith(blocks(i+1,1).Data())){
text.Remove(0, 1);
text.Remove(text.Length() - 1, 1);
}
}
return text;
}
TString TQStringUtils::minimize(TString text) {
text.ReplaceAll(" ","");
text.ReplaceAll("\n","");
text.ReplaceAll("\t","");
text.ReplaceAll("\r","");
return text;
}
TString TQStringUtils::compactify(const TString& text) {
TString retval = "";
bool isSpace = true;
for(size_t i=0; i<(size_t)text.Length(); i++){
if(text[i] == ' ' || text[i] == '\t' || text[i] == '\n' || text[i] == '\r'){
if(isSpace) continue;
else retval += ' ';
isSpace=true;
} else {
retval += text[i];
isSpace=false;
}
}
TQStringUtils::removeLeadingBlanks(retval);
TQStringUtils::removeTrailingBlanks(retval);
return retval;
}
bool TQStringUtils::hasUnquotedStrings(const TString& text, const TString& quotes){
bool quoted = false;
for(size_t i=0; i<(size_t)text.Length(); i++){
if(quotes.Contains(text[i])){
quoted = !quoted;
continue;
}
if(!quoted && TQStringUtils::letters.Contains(text[i]))
return true;
}
return false;
}
bool TQStringUtils::hasTFormulaParameters(const TString& text){
DEBUGfunc("checking text %s",text.Data());
if(!text.Contains("[")) return false;
if(!text.Contains("]")) return false;
size_t pos = TQStringUtils::find(text,"[");
size_t close = TQStringUtils::findParenthesisMatch(text,pos,"[","]");
if ( close > (size_t)(text.Length())) return false;
for (size_t i = pos+1; i<close; ++i){
if (!numerals.Contains(text[i])){
DEBUG("found that '%s' qualifies as having TFormula parameters",text.Data());
return true;
}
}
return false;
}
char TQStringUtils::hasStringSwitch(const TString& input){
size_t pos = -1;
while(true){
pos = TQStringUtils::findFirstOf(input,"'\"",pos+1);
if( pos < (size_t)(input.Length())){
size_t nextpos = TQStringUtils::findParenthesisMatch(input,pos,input[pos],input[pos]);
if( nextpos > (size_t)(input.Length())){
return input[pos];
} else {
pos = nextpos;
}
} else {
return 0;
}
}
return 0;
}
TString TQStringUtils::readTextFromFile(std::istream* input, const char* commentLine, const char* commentBlockOpen, const char* commentBlockClose){
input->seekg(0, std::ios::end);
size_t length = (size_t) input->tellg();
DEBUGfunc("allocating buffer of size %zu",length);
input->seekg(0, std::ios::beg);
char* buffer = (char *)malloc((length+1)*sizeof(char));
input->read(buffer, length);
buffer[length]='\0';
std::string text = std::string(buffer);
DEBUGfunc("freeing buffer");
free(buffer);
std::stringstream result;
size_t pos=0;
char isstr = 0;
while(pos < text.size()){
DEBUGfunc("entering iteration at %zu",pos);
size_t nextposLine = text.find(commentLine, pos);
size_t nextposBlock = text.find(commentBlockOpen, pos);
size_t nextpos = std::min(nextposLine,nextposBlock);
if(nextpos >= text.size()){
result << text.substr(pos);
break;
} else {
const std::string s(text.substr(pos, nextpos-pos));
char stringswitch = hasStringSwitch(s.c_str());
if(isstr==0) isstr = stringswitch;
else if(stringswitch==isstr) isstr=0;
result << s;
}
if(isstr!=0 || (nextpos > 0 && text[nextpos-1]=='\\')){
result << text.substr(nextpos,1);
pos = nextpos+1;
} else {
if(nextpos == nextposLine) pos = TQStringUtils::findFirstOf(text,"\n", nextpos);
else if(nextpos == nextposBlock){
result << TQStringUtils::repeat("\n",std::count(text.begin()+pos,text.begin()+nextpos,'\n'));
pos = text.find(commentBlockClose, nextpos)+strlen(commentBlockClose);
}
}
}
DEBUG("returning result");
return result.str().c_str();
}
size_t TQStringUtils::findParenthesisMatch(const TString& str, size_t nextpos, const TString& paropen, const TString& parclose){
size_t openbrace = 0;
size_t closebrace = 0;
size_t bracestack = 1;
while((bracestack > 0) && (nextpos < (size_t)str.Length())){
openbrace = TQStringUtils::find(str,paropen, nextpos+1);
closebrace = TQStringUtils::find(str,parclose, nextpos+1);
nextpos++;
if(openbrace < closebrace){
bracestack++;
nextpos = openbrace;
} else {
bracestack--;
nextpos = closebrace;
}
}
return nextpos;
}
size_t TQStringUtils::rfindParenthesisMatch(const TString& str, size_t nextpos, const TString& paropen, const TString& parclose){
size_t openbrace = 0;
size_t closebrace = 0;
size_t bracestack = 1;
while((bracestack > 0) && (nextpos < (size_t)str.Length())){
openbrace = TQStringUtils::rfind(str,paropen, nextpos-1);
closebrace = TQStringUtils::rfind(str,parclose, nextpos-1);
closebrace = std::min(closebrace, closebrace+1);
nextpos--;
if(openbrace < closebrace){
bracestack++;
nextpos = closebrace;
} else {
bracestack--;
nextpos = openbrace;
}
}
return nextpos;
}
size_t TQStringUtils::findParenthesisMatch(const TString& str, size_t nextpos, char paropen, char parclose){
return findParenthesisMatch(str, nextpos,chartostr(paropen),chartostr(parclose));
}
size_t TQStringUtils::rfindParenthesisMatch(const TString& str, size_t nextpos, char paropen, char parclose){
return rfindParenthesisMatch(str, nextpos,chartostr(paropen),chartostr(parclose));
}
size_t TQStringUtils::findFree(const TString& haystack, const TString& needle, const TString& paropen, const TString& parclose, size_t startpos){
size_t needlepos = TQStringUtils::find(haystack,needle, startpos);
size_t nextparopen = TQStringUtils::find(haystack,paropen, startpos);
while(needlepos > nextparopen){
startpos = findParenthesisMatch(haystack, nextparopen, paropen, parclose)+1;
if (startpos == (size_t)(kNPOS+1)) return kNPOS;
needlepos = TQStringUtils::find(haystack,needle, startpos);
nextparopen = TQStringUtils::find(haystack,paropen, startpos);
}
return needlepos;
}
size_t TQStringUtils::findFree(const TString& haystack, const TString& needle, const TString& parentheses, size_t startpos){
if (parentheses.Length()%2 != 0) {
ERRORfunc("Number of parentheses is odd, returning kNPOS");
return kNPOS;
}
TString paropen = "";
TString parclose = "";
for (int i=0;i<parentheses.Length(); ++i) {
if (i%2 == 0) paropen += parentheses(i);
else parclose += parentheses(i);
}
size_t needlepos = TQStringUtils::find(haystack,needle, startpos);
size_t nextparopen = TQStringUtils::findFirstOf(haystack,paropen, startpos);
while(needlepos > nextparopen){
int whichPar = TQStringUtils::findFirstOf(paropen,haystack(nextparopen));
startpos = findParenthesisMatch(haystack, nextparopen, paropen(whichPar), parclose(whichPar) )+1;
if (startpos == (size_t)(kNPOS+1)) return kNPOS;
needlepos = TQStringUtils::find(haystack,needle, startpos);
nextparopen = TQStringUtils::findFirstOf(haystack,paropen, startpos);
}
return needlepos;
}
size_t TQStringUtils::rfindFree(const TString& haystack, const TString& needle, const TString& parentheses, size_t startpos){
if (parentheses.Length()%2 != 0) {
ERRORfunc("Number of parentheses is odd, returning kNPOS");
return kNPOS;
}
TString paropen = "";
TString parclose = "";
for (int i=0;i<parentheses.Length(); ++i) {
if (i%2 == 0) paropen += parentheses(i);
else parclose += parentheses(i);
}
size_t needlepos = TQStringUtils::rfind(haystack,needle, startpos);
size_t nextparclose = TQStringUtils::findLastOf(haystack,parclose, startpos);
while(needlepos < nextparclose){
int whichPar = TQStringUtils::findLastOf(parclose,haystack(nextparclose));
startpos = rfindParenthesisMatch(haystack, nextparclose, paropen(whichPar), parclose(whichPar) )-1;
if (startpos == (size_t)(kNPOS-1)) return kNPOS;
needlepos = TQStringUtils::rfind(haystack,needle, startpos);
nextparclose = TQStringUtils::findLastOf(haystack,parclose, startpos);
}
return needlepos;
}
size_t TQStringUtils::rfindFree(const TString& haystack, const TString& needle, const TString& paropen, const TString& parclose, size_t startpos){
size_t needlepos = TQStringUtils::rfind(haystack,needle, startpos);
size_t nextparclose = TQStringUtils::rfind(haystack,parclose, startpos);
while(needlepos < nextparclose){
startpos = rfindParenthesisMatch(haystack, nextparclose, paropen, parclose)-1;
startpos = std::min(startpos+1, startpos-1);
needlepos = TQStringUtils::rfind(haystack,needle, startpos);
nextparclose = TQStringUtils::rfind(haystack,parclose, startpos);
}
return needlepos;
}
size_t TQStringUtils::findFreeOf(const TString& haystack, const TString& needles, const TString& paropen, const TString& parclose, size_t startpos){
size_t needlepos = TQStringUtils::findFirstOf(haystack,needles, startpos);
size_t nextparopen = TQStringUtils::find(haystack,paropen, startpos);
while(needlepos > nextparopen){
startpos = findParenthesisMatch(haystack, nextparopen, paropen, parclose)+1;
if (startpos == (size_t)(kNPOS+1)) return kNPOS;
needlepos = TQStringUtils::findFirstOf(haystack,needles, startpos);
nextparopen = TQStringUtils::find(haystack,paropen, startpos);
}
return needlepos;
}
size_t TQStringUtils::rfindFreeOf(const TString& haystack, const TString& needles, const TString& paropen, const TString& parclose, size_t startpos){
size_t needlepos = TQStringUtils::findLastOf(haystack,needles, startpos);
size_t nextparclose = TQStringUtils::rfind(haystack,parclose, startpos);
while(needlepos < nextparclose){
startpos = rfindParenthesisMatch(haystack, nextparclose, paropen, parclose);
startpos = std::min(startpos+1, startpos-1);
needlepos = TQStringUtils::findLastOf(haystack,needles, startpos);
nextparclose = TQStringUtils::rfind(haystack,parclose, startpos);
nextparclose = std::min(nextparclose, nextparclose+1);
}
return needlepos;
}
int TQStringUtils::find(const TString& item, const std::vector<TString>& vec){
for(size_t i=0; i<vec.size(); ++i){
if(TQStringUtils::matches(item,vec[i])) return i;
}
return -1;
}
int TQStringUtils::find(const TString& haystack, const TString& needle, int pos){
if(haystack.IsNull() || needle.IsNull() || pos > haystack.Length()) return kNPOS;
if(pos < 0) pos = 0;
size_t npos = 0;
while(pos < haystack.Length()){
if(haystack[pos] == needle[npos]){
if(npos+1 == (size_t)needle.Length()){
return pos+1-needle.Length();
}
npos++;
} else {
npos = 0;
}
pos++;
}
return kNPOS;
}
int TQStringUtils::rfind(const TString& haystack, const TString& needle, int pos){
if(haystack.IsNull() || needle.IsNull() || pos < 0) return kNPOS;
if(pos > haystack.Length()) pos = haystack.Length() -1;
size_t npos = needle.Length()-1;
while(pos >= 0){
if(haystack[pos] == needle[npos]){
if(npos == 0){
return pos;
}
npos--;
} else {
npos = needle.Length() -1;
}
pos--;
}
return kNPOS;
}
int TQStringUtils::findFirstOf(const TString& haystack, const TString& needle, int pos){
if(haystack.IsNull() || needle.IsNull() || pos > haystack.Length()) return kNPOS;
if(pos < 0) pos = 0;
while(pos < haystack.Length()){
if(needle.Index(haystack[pos]) != kNPOS) return pos;
pos++;
}
return kNPOS;
}
int TQStringUtils::findLastOf(const TString& haystack, const TString& needle, int pos){
if(haystack.IsNull() || needle.IsNull() || pos < 0) return kNPOS;
if(pos > haystack.Length()) pos = haystack.Length() -1;
while(pos >= 0){
if(needle.Index(haystack[pos]) != kNPOS) return pos;
pos--;
}
return kNPOS;
}
int TQStringUtils::rfindFirstOf(const TString& haystack, const TString& needle, int pos){
return findLastOf(haystack,needle,pos);
}
int TQStringUtils::findFirstNotOf(const TString& haystack, const TString& needle, int pos){
if(haystack.IsNull() || needle.IsNull() || pos > haystack.Length()) return kNPOS;
if(pos < 0) pos = 0;
while(pos < haystack.Length()){
if(needle.Index(haystack[pos]) == kNPOS) return pos;
pos++;
}
return kNPOS;
}
int TQStringUtils::findLastNotOf(const TString& haystack, const TString& needle, int pos){
if(haystack.IsNull() || needle.IsNull() || pos < 0) return kNPOS;
if(pos > haystack.Length()) pos = haystack.Length() -1;
while(pos >= 0){
if(needle.Index(haystack[pos]) == kNPOS) return pos;
pos--;
}
return kNPOS;
}
int TQStringUtils::rfindFirstNotOf(const TString& haystack, const TString& needle, int pos){
return findLastNotOf(haystack,needle,pos);
}
std::vector<TString> TQStringUtils::split(const TString& str, const TString& del){
std::vector<TString> split;
if(str.IsNull()) return split;
TString substr;
if(del.Length()>0){
size_t oldpos = 0;
size_t newpos = 0;
while(newpos<(size_t)str.Length() && oldpos <= newpos){
oldpos = newpos;
newpos = TQStringUtils::find(str,del, oldpos);
substr=str(oldpos, std::min((size_t)str.Length(),newpos)-oldpos);
if(substr.Length()>0) split.push_back(substr);
if(newpos < (size_t)str.Length()) newpos += del.Length();
}
}
if(split.size() < 1) split.push_back(str);
return split;
}
std::vector<TString> TQStringUtils::split(const TString& str, const TString& del, const TString& paropen, const TString& parclose){
std::vector<TString> split;
TString substr;
if(del.Length()>0){
size_t oldpos = 0;
size_t newpos = 0;
size_t nextparopen = str.Length();
while(newpos<(size_t)str.Length() && oldpos <= (size_t)str.Length()){
nextparopen = TQStringUtils::find(str,paropen, oldpos);
newpos = std::min((size_t)TQStringUtils::find(str,del, oldpos), (size_t)str.Length());
while(nextparopen < newpos){
nextparopen = findParenthesisMatch(str, nextparopen, paropen, parclose);
newpos = std::max(newpos, nextparopen);
newpos = std::min(TQStringUtils::find(str,del, newpos), str.Length());
if(nextparopen < (size_t)str.Length()) nextparopen = TQStringUtils::find(str,paropen, nextparopen+1);
}
substr=str(oldpos, std::min((size_t)str.Length(),newpos)-oldpos);
if(substr.Length()>0) split.push_back(substr);
oldpos = newpos+del.Length();
}
}
if(split.size() < 1) split.push_back(str);
return split;
}
TString TQStringUtils::merge(const std::vector<TString>& vecStr, const TString& del, int start, int stop){
TString outputString = "";
if (stop > (int) vecStr.size())
stop = (int) vecStr.size();
for (int i = start; i < stop; i++){
if (i > 0)
outputString.Append(del);
outputString.Append(vecStr[i]);
}
return outputString;
}
TString TQStringUtils::findFormat(const TString& content){
if(content.Contains(html)) return "html";
if(content.Contains(roottex)) return "roottex";
if(content.Contains(latexcmd) || content.Contains(latexmath)) return "latex";
for(size_t i=0; i<(size_t)content.Length(); i++){
if(content[i] < 0 ) return "unicode";
}
return "ascii";
}
bool TQStringUtils::isASCII(TString content){
std::stringstream s;
for(size_t i=0; i<(size_t)content.Length(); i++){
if(!(content[i]>31 && content[i]<127)) return false;
}
return true;
}
TString TQStringUtils::makeASCII(const TString& content){
std::stringstream s;
for(size_t i=0; i<(size_t)content.Length(); i++){
if(content[i]>31 && content[i]<127) s << content[i];
}
return TString(s.str().c_str());
}
TString TQStringUtils::convertPlain2LaTeX(TString text){
text.ReplaceAll("_","\\_");
text.ReplaceAll("&","\\&");
return text;
}
TString TQStringUtils::convertPlain2HTML(TString text){
text.ReplaceAll("&","&");
text.ReplaceAll("<","<");
text.ReplaceAll(">",">");
text.ReplaceAll("\"",""");
return text;
}
TString TQStringUtils::convertLaTeX2Plain(TString text, bool unicode){
text.ReplaceAll("$","");
text.ReplaceAll("\\pm",unicode ? "ยฑ" : "+/-");
text.ReplaceAll("\\leq","<=");
text.ReplaceAll("\\&","&");
text.ReplaceAll("\\geq",">=");
text.ReplaceAll("\\cdot","*");
text.ReplaceAll("\\to ",unicode ? "โ" : "->");
text.ReplaceAll("\\rightarrow ",unicode ? "โ" : "->");
text.ReplaceAll("\\to",unicode ? "โ" : "->");
text.ReplaceAll("\\rightarrow",unicode ? "โ" : "->");
text.ReplaceAll("\\ell","l");
text.ReplaceAll("\\Alpha", unicode ? "ฮ" : "A"); text.ReplaceAll("\\alpha", unicode ? "ฮฑ" : "a");
text.ReplaceAll("\\Beta", unicode ? "ฮ" : "B"); text.ReplaceAll("\\beta", unicode ? "ฮฒ" : "b");
text.ReplaceAll("\\Gamma", unicode ? "ฮ" : "G"); text.ReplaceAll("\\gamma", unicode ? "ฮณ" : "y");
text.ReplaceAll("\\Delta", unicode ? "ฮ" : "D"); text.ReplaceAll("\\delta", unicode ? "ฮด" : "d");
text.ReplaceAll("\\Epsilon",unicode ? "ฮ" : "E"); text.ReplaceAll("\\epsilon",unicode ? "ฮต" : "e");
text.ReplaceAll("\\Zeta", unicode ? "ฮ" : "Z"); text.ReplaceAll("\\zeta", unicode ? "ฮถ" : "z");
text.ReplaceAll("\\Eta", unicode ? "ฮ" : "H"); text.ReplaceAll("\\eta", unicode ? "ฮท" : "n");
text.ReplaceAll("\\Theta", unicode ? "ฮ" : "0"); text.ReplaceAll("\\theta", unicode ? "ฮธ" : "0");
text.ReplaceAll("\\Iota", unicode ? "I" : "I"); text.ReplaceAll("\\iota", unicode ? "ฮน" : "i");
text.ReplaceAll("\\Kappa", unicode ? "ฮ" : "K"); text.ReplaceAll("\\kappa", unicode ? "ฮบ" : "k");
text.ReplaceAll("\\Lambda", unicode ? "ฮ" : "L"); text.ReplaceAll("\\lambda", unicode ? "ฮป" : "l");
text.ReplaceAll("\\Mu", unicode ? "M" : "M"); text.ReplaceAll("\\mu", unicode ? "ฮผ" : "m");
text.ReplaceAll("\\Nu", unicode ? "ฮ" : "N"); text.ReplaceAll("\\nu", unicode ? "ฮฝ" : "v");
text.ReplaceAll("\\Xi", unicode ? "ฮ" : "Xi"); text.ReplaceAll("\\xi", unicode ? "ฮพ" : "xi");
text.ReplaceAll("\\Omicron",unicode ? "ฮ" : "O"); text.ReplaceAll("\\omicron",unicode ? "ฮฟ" : "o");
text.ReplaceAll("\\Pi", unicode ? "ฮ " : "Pi"); text.ReplaceAll("\\pi", unicode ? "ฯ" : "pi");
text.ReplaceAll("\\Rho", unicode ? "ฮก" : "P"); text.ReplaceAll("\\rho", unicode ? "ฯ" : "rho");
text.ReplaceAll("\\Sigma", unicode ? "ฮฃ" : "S"); text.ReplaceAll("\\sigma", unicode ? "ฯ" : "s");
text.ReplaceAll("\\Tau", unicode ? "ฮค" : "Tau");text.ReplaceAll("\\tau", unicode ? "ฯ" : "t");
text.ReplaceAll("\\Upsilon",unicode ? "ฮฅ" : "U"); text.ReplaceAll("\\upsilon",unicode ? "ฯ
" : "u");
text.ReplaceAll("\\Phi", unicode ? "ฮฆ" : "Phi");text.ReplaceAll("\\phi", unicode ? "ฯ" : "phi");
text.ReplaceAll("\\Chi", unicode ? "ฮง" : "Chi");text.ReplaceAll("\\chi", unicode ? "ฯ" : "chi");
text.ReplaceAll("\\Psi", unicode ? "ฮจ" : "Psi");text.ReplaceAll("\\psi", unicode ? "ฯ" : "psi");
text.ReplaceAll("\\Omega", unicode ? "ฮฉ" : "O"); text.ReplaceAll("\\omega", unicode ? "ฯ" : "w");
TRegexp cmd("\\\\[a-zA-Z]+[ ]*");
while(text.Contains(cmd)){
TString seq = text(cmd);
int pos = text.Index(cmd);
int start = TQStringUtils::find(text,"{",pos+1);
if(start < seq.Length() || start == kNPOS){
text.Remove(pos,seq.Length());
} else {
int end = TQStringUtils::findParenthesisMatch(text,pos+seq.Length(),"{","}");
if(end != kNPOS) text.Remove(end,1);
text.Remove(pos,start-pos+1);
}
}
TRegexp subScr("_{[^}]*}");
while(text.Contains(subScr)){
TString seq = text(subScr);
int start = text.Index(seq);
TString rep(seq);
rep.Remove(rep.Length()-1,1);
rep.Remove(0,2);
text.Replace(start,seq.Length(), unicode ? TQStringUtils::makeUnicodeSubscript(rep) : ("_"+rep));
}
text.ReplaceAll("^","_");
while(text.Contains(subScr)){
TString seq = text(subScr);
int start = text.Index(seq);
TString rep(seq);
rep.Remove(rep.Length()-1,1);
rep.Remove(0,2);
text.Replace(start,seq.Length(),unicode ? TQStringUtils::makeUnicodeSuperscript(rep) : ("^"+rep));
}
text.ReplaceAll("{}","");
return text;
}
TString TQStringUtils::convertLaTeX2HTML(TString text){
bool open = true;
text.ReplaceAll("\\&","&");
text.ReplaceAll("<","<");
text.ReplaceAll(">",">");
while(text.Contains("$")){
int loc = text.Index("$");
text.Replace(loc,1,open ? "<i>" : "</i>");
open = !open;
}
text.ReplaceAll("\\Alpha", "Α" ); text.ReplaceAll("\\alpha" ,"α" );
text.ReplaceAll("\\Beta", "Β" ); text.ReplaceAll("\\beta" ,"β" );
text.ReplaceAll("\\Gamma", "Γ" ); text.ReplaceAll("\\gamma" ,"γ" );
text.ReplaceAll("\\Delta", "Δ" ); text.ReplaceAll("\\delta" ,"δ" );
text.ReplaceAll("\\Epsilon","Ε"); text.ReplaceAll("\\epsilon","ε" );
text.ReplaceAll("\\Zeta", "Ζ" ); text.ReplaceAll("\\zeta" ,"ζ" );
text.ReplaceAll("\\Eta", "Η" ); text.ReplaceAll("\\eta" ,"η" );
text.ReplaceAll("\\Theta", "Θ" ); text.ReplaceAll("\\theta" ,"θ" );
text.ReplaceAll("\\Iota", "Ι" ); text.ReplaceAll("\\iota" ,"ι" );
text.ReplaceAll("\\Kappa", "Κ" ); text.ReplaceAll("\\kappa" ,"κ" );
text.ReplaceAll("\\Lambda", "Λ" ); text.ReplaceAll("\\lambda" ,"λ" );
text.ReplaceAll("\\Mu", "Μ" ); text.ReplaceAll("\\mu" ,"μ" );
text.ReplaceAll("\\Nu", "Ν" ); text.ReplaceAll("\\nu" ,"ν" );
text.ReplaceAll("\\Xi", "Ξ" ); text.ReplaceAll("\\xi" ,"ξ" );
text.ReplaceAll("\\Omicron","&OmicronM"); text.ReplaceAll("\\omicron","ο" );
text.ReplaceAll("\\Pi", "Π" ); text.ReplaceAll("\\pi" ,"π" );
text.ReplaceAll("\\Rho", "Ρ" ); text.ReplaceAll("\\rho" ,"ρ" );
text.ReplaceAll("\\Sigma", "Σ" ); text.ReplaceAll("\\sigma" ,"σ" );
text.ReplaceAll("\\Tau", "Τ" ); text.ReplaceAll("\\tau" ,"τ" );
text.ReplaceAll("\\Upsilon","Υ"); text.ReplaceAll("\\upsilon","υ" );
text.ReplaceAll("\\Phi", "Φ" ); text.ReplaceAll("\\phi" ,"φ" );
text.ReplaceAll("\\Chi", "Χ" ); text.ReplaceAll("\\chi" ,"χ" );
text.ReplaceAll("\\Psi", "Ψ" ); text.ReplaceAll("\\psi" ,"ψ" );
text.ReplaceAll("\\Omega", "Ω" ); text.ReplaceAll("\\omega" ,"ω" );
TRegexp cmd("[ \n\t]*\\\\[a-zA-Z]+[ \n\t]*");
while(text.Contains(cmd)){
TString seq = text(cmd);
int seqlen = seq.Length();
TString sequence = TQStringUtils::trim(seq);
TQStringUtils::removeLeading(sequence,"\\");
int pos = text.Index(cmd);
if(text[pos+seqlen] != '{'){
text.Remove(pos,seqlen);
if(sequence == "itshape"){
text.Insert(pos,"<i>");
text.Append("</i>");
}
if(sequence == "bfseries"){
text.Insert(pos,"<b>");
text.Append("</b>");
}
if(sequence == "to" || sequence == "rightarrow") text.Insert(pos,"→");
if(sequence == "leftarrow") text.Insert(pos,"←");
if(sequence == "geq" ) text.Insert(pos," ≥ ");
if(sequence == "leq" ) text.Insert(pos," ≤ ");
if(sequence == "cdot") text.Insert(pos,"⋅");
if(sequence == "pm" ) text.Insert(pos,"±");
if(sequence == "ell" ) text.Insert(pos,"ℓ");
} else {
seqlen++;
int end = TQStringUtils::findParenthesisMatch(text,pos+seq.Length(),"{","}");
if(sequence == "textit" || sequence == "ensuremath"){
if(end != kNPOS) text.Replace(end,1,"</i>");
else text.Append("</i>");
text.Replace(pos,seqlen,"<i>");
} else if(sequence == "textbf"){
if(end != kNPOS) text.Replace(end,1,"</b>");
else text.Append("</b>");
text.Replace(pos,seqlen,"<b>");
} else if(sequence == "mathrm"){
if(end != kNPOS) text.Replace(end,1,"</span>");
else text.Append("</span>");
text.Replace(pos,seqlen,"<span style=\"font-style:normal;\">");
} else if(sequence == "bar"){
if(end != kNPOS) text.Replace(end,1,"</span>");
else text.Append("</span>");
text.Replace(pos,seqlen,"<span style=\"text-decoration: overline;\">");
} else {
if(end != kNPOS) text.Remove(end,1);
text.Remove(pos,seqlen);
}
}
}
TRegexp subScr("_{[^}]*}");
while(text.Contains(subScr)){
TString seq = text(subScr);
int start = text.Index(subScr);
text.Replace(start+seq.Length()-1,1,"</sub>");
text.Replace(start,2,"<sub>");
}
text.ReplaceAll("^","_");
while(text.Contains(subScr)){
TString seq = text(subScr);
int start = text.Index(subScr);
text.Replace(start+seq.Length()-1,1,"</sup>");
text.Replace(start,2,"<sup>");
}
text.ReplaceAll("{}","");
return text;
}
TString TQStringUtils::convertHTML2Plain(TString text, bool ){
return text;
}
TString TQStringUtils::convertHTML2LaTeX(TString text){
return text;
}
TString TQStringUtils::convertROOTTeX2Plain(TString text, bool ){
return text;
}
TString TQStringUtils::convertLaTeX2ROOTTeX(TString text){
bool open = false;
while(text.Contains("$")){
int pos = text.First("$");
if(!open) text.Replace(pos,1,"#it{");
else text.Replace(pos,1,"}");
open = !open;
}
text.ReplaceAll("^{*}","#kern[-0.2]{#lower[-0.2]{*}}");
text.ReplaceAll("\\","#");
text.ReplaceAll("#ell","l");
text.ReplaceAll("{}","");
return text;
}
TString TQStringUtils::convertROOTTeX2LaTeX(TString text){
if(!text.Contains("$")){
text.ReplaceAll("#sqrt{s}","$\\sqrt{s}$");
text.ReplaceAll("^{-1}","${}^{-1}$");
}
text.ReplaceAll("#","\\");
return text;
}
TString TQStringUtils::convertROOTTeX2HTML(TString text){
text.ReplaceAll("#","\\");
return convertLaTeX2HTML(text);
}
TString TQStringUtils::makeUppercase(TString s){
s.ToUpper();
return s;
}
TString TQStringUtils::makeLowercase(TString s){
s.ToLower();
return s;
}
TString TQStringUtils::makeUnicodeSuperscript(TString s){
s.ReplaceAll("0","โฐ");s.ReplaceAll("1","ยน");s.ReplaceAll("2","ยฒ");s.ReplaceAll("3","ยณ");s.ReplaceAll("4","โด");s.ReplaceAll("5","โต");s.ReplaceAll("6","โถ");s.ReplaceAll("7","โท");s.ReplaceAll("8","โธ");s.ReplaceAll("9","โน");s.ReplaceAll("+","โบ");s.ReplaceAll("-","โป");s.ReplaceAll("=","โผ");s.ReplaceAll("(","โฝ");s.ReplaceAll(")","โพ");s.ReplaceAll("a","แต");s.ReplaceAll("b","แต");s.ReplaceAll("c","แถ");s.ReplaceAll("d","แต");s.ReplaceAll("e","แต");s.ReplaceAll("f","แถ ");s.ReplaceAll("g","แต");s.ReplaceAll("h","สฐ");s.ReplaceAll("i","โฑ");s.ReplaceAll("j","สฒ");s.ReplaceAll("k","แต");s.ReplaceAll("l","หก");s.ReplaceAll("m","แต");s.ReplaceAll("n","โฟ");s.ReplaceAll("o","แต");s.ReplaceAll("p","แต");s.ReplaceAll("r","สณ");s.ReplaceAll("s","หข");s.ReplaceAll("t","แต");s.ReplaceAll("u","แต");s.ReplaceAll("v","แต");s.ReplaceAll("w","สท");s.ReplaceAll("x","หฃ");s.ReplaceAll("y","สธ");s.ReplaceAll("z","แถป");s.ReplaceAll("A","แดฌ");s.ReplaceAll("B","แดฎ");s.ReplaceAll("D","แดฐ");s.ReplaceAll("E","แดฑ");s.ReplaceAll("G","แดณ");s.ReplaceAll("H","แดด");s.ReplaceAll("I","แดต");s.ReplaceAll("J","แดถ");s.ReplaceAll("K","แดท");s.ReplaceAll("L","แดธ");s.ReplaceAll("M","แดน");s.ReplaceAll("N","แดบ");s.ReplaceAll("O","แดผ");s.ReplaceAll("P","แดพ");s.ReplaceAll("R","แดฟ");s.ReplaceAll("T","แต");s.ReplaceAll("U","แต");s.ReplaceAll("V","โฑฝ");s.ReplaceAll("W","แต");s.ReplaceAll("ฮฑ","แต
");s.ReplaceAll("ฮฒ","แต");s.ReplaceAll("ฮณ","แต");s.ReplaceAll("ฮด","แต");s.ReplaceAll("ฮต","แต");s.ReplaceAll("ฮธ","แถฟ");s.ReplaceAll("ฮน","แถฅ");s.ReplaceAll("ฮฆ","แถฒ");s.ReplaceAll("ฯ","แต ");s.ReplaceAll("ฯ","แตก");return s;}
TString TQStringUtils::makeUnicodeSubscript(TString s){
s.ReplaceAll("0","โ");s.ReplaceAll("1","โ");s.ReplaceAll("2","โ");s.ReplaceAll("3","โ");s.ReplaceAll("4","โ");s.ReplaceAll("5","โ
");s.ReplaceAll("6","โ");s.ReplaceAll("7","โ");s.ReplaceAll("8","โ");s.ReplaceAll("9","โ");s.ReplaceAll("+","โ");s.ReplaceAll("-","โ");s.ReplaceAll("=","โ");s.ReplaceAll("(","โ");s.ReplaceAll(")","โ");s.ReplaceAll("a","โ");s.ReplaceAll("e","โ");s.ReplaceAll("h","โ");s.ReplaceAll("i","แตข");s.ReplaceAll("j","โฑผ");s.ReplaceAll("k","โ");s.ReplaceAll("l","โ");s.ReplaceAll("m","โ");s.ReplaceAll("n","โ");s.ReplaceAll("o","โ");s.ReplaceAll("p","โ");s.ReplaceAll("r","แตฃ");s.ReplaceAll("s","โ");s.ReplaceAll("t","โ");s.ReplaceAll("u","แตค");s.ReplaceAll("v","แตฅ");s.ReplaceAll("x","โ");s.ReplaceAll("ฮฒ","แตฆ");s.ReplaceAll("ฮณ","แตง");s.ReplaceAll("ฯ","แตจ");s.ReplaceAll("ฯ","แตฉ");s.ReplaceAll("ฯ","แตช");return s;}
TString TQStringUtils::format(const char *va_(fmt), ...){
va_list ap;
va_start(ap, va_(fmt));
TString str(vaFormat(va_(fmt), ap));
va_end(ap);
return str;
}
TString TQStringUtils::concat(int n, ...){
bool first = true;
TString text;
va_list ap;
va_start(ap, va_(n));
for (int i=1;i<n;i++){
const char* val = va_arg(ap,const char*);
if(!first) text.Append(",");
text.Append(val);
first=false;
}
va_end(ap);
return text;
}
char* TQStringUtils::vaFormat(const char *fmt, va_list ap){
Ssiz_t buflen = 20 + strlen(fmt);
char* buffer = (char*)malloc(buflen*sizeof(char));
va_list sap;
R__VA_COPY(sap, ap);
bool done = false;
int n, vc = 0;
do {
n = vsnprintf(buffer, buflen, fmt, ap);
if (n == -1 || n >= buflen) {
if (n == -1)
buflen *= 2;
else
buflen = n+1;
buffer = (char*)realloc(buffer,buflen*sizeof(char));
va_end(ap);
R__VA_COPY(ap, sap);
vc = 1;
} else {
done = true;
}
} while(!done);
va_end(sap);
if (vc) va_end(ap);
return buffer;
}
TString TQStringUtils::replaceEnclosed(TString haystack,TString needle,TString newNeedle, const TString& symbols){
int pos = 0;
while(true){
size_t newpos = TQStringUtils::find(haystack,needle,pos);
if(newpos < (size_t)haystack.Length()){
if( ( ( newpos == 0 || symbols.Contains(haystack(newpos-1,1))) )
&& ( (newpos==(size_t)haystack.Length()-1) ||
symbols.Contains(haystack(newpos+needle.Length(),1)) ) ){
haystack.Replace(newpos,needle.Length(),newNeedle);
pos = newpos+newNeedle.Length();
} else {
pos = newpos+needle.Length();
}
} else {
break;
}
}
return haystack;
}
TString TQStringUtils::getColorDefStringLaTeX(const TString& name, int color){
TColor* c = gROOT->GetColor(color);
return getColorDefStringLaTeX(name,c);
}
TString TQStringUtils::getColorDefStringLaTeX(const TString& name, TColor* color){
if(!color) return "";
float r,g,b;
color->GetRGB(r,g,b);
return TString::Format("\\definecolor{%s}{rgb}{%f,%f,%f}",name.Data(),r,g,b);
}
TString TQStringUtils::padNumber(int num, int length){
TString retval(TString::Format("%d",num));
while(retval.Length() < length){
retval.Prepend("0");
}
return retval;
}