/*************************************************************************** PreFormatter.cpp - description ------------------- begin : Mo Jan 03 2005 copyright : (C) 2005-2007 by Andre Simon email : andre.simon1@gmx.de ***************************************************************************/ /* This file is part of Highlight. Highlight 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 3 of the License, or (at your option) any later version. Highlight 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 Highlight. If not, see . */ #include "preformatter.h" #include #include "stringtools.h" namespace highlight { const std::string PreFormatter::LB_CHARS = " \t[](){}-+<>.:,;"; const std::string PreFormatter::WS_CHARS = " \n\r\t"; const std::string PreFormatter::INDENT_MARKERS = "{(="; PreFormatter::PreFormatter() : maxLineLength ( 80 ), index ( 0 ), numberSpaces ( 0 ), lineNumber ( 0 ), wsPrefixLength ( string::npos ), hasMore ( false ), indentAfterOpenBraces ( true ), redefineWsPrefix ( false ), wrapLines ( false ), replaceTabs ( false ) { } PreFormatter::~PreFormatter() { } bool PreFormatter::hasMoreLines() { return hasMore; } bool PreFormatter::indentCode() { return indentAfterOpenBraces; } void PreFormatter::setLine ( const std::string& newLine ) { line=newLine; if ( replaceTabs && numberSpaces ) { size_t tabPos=line.find ( '\t' ); while ( tabPos!=string::npos ) { line.replace ( tabPos , 1, numberSpaces - ( tabPos % numberSpaces ) , ' ' ); tabPos = line.find ( '\t', tabPos+1 ); } } if ( wrapLines ) { wsPrefix.clear(); index=0; wsPrefixLength=string::npos; hasMore=true; redefineWsPrefix=false; } } std::string PreFormatter::getNextLine() { if ( !wrapLines ) { hasMore = false; return line; } ++lineNumber; if ( !index && line.length() > maxLineLength ) // erster Durchlauf... { // wenn moeglich an oeffnender Klammer oder Geichheitszeichen ausrichten if ( indentAfterOpenBraces ) { wsPrefixLength=line.find_first_of ( INDENT_MARKERS ); } // sonst die Einrckung der Originalzeile beibehalten if ( wsPrefixLength==string::npos || wsPrefixLength-index>maxLineLength ) { wsPrefixLength=line.find_first_not_of ( WS_CHARS ); } else { // wsPrefix in allen neu umgebrochenen Zeilen durch Spaces ersetzen redefineWsPrefix=true; // Position hinter oeffnende Klammer springen wsPrefixLength=line.find_first_not_of ( WS_CHARS,wsPrefixLength+1 ); } if ( wsPrefixLength!=string::npos ) { index = wsPrefixLength; // Falls Anzahl der Whitespaces am beginn der ersten zeile groesser // als Max. Zeilenlaenge, Whitespaces verwerfen if ( wsPrefixLength>maxLineLength ) { wsPrefixLength=0; return string(); } else { wsPrefix=line.substr ( 0, wsPrefixLength ); } } // Zeile enthaelt nur Whitespace; verwerfen else { hasMore= false; return string(); } } else { if ( redefineWsPrefix ) { wsPrefix.clear(); wsPrefix.append ( wsPrefixLength, ' ' ); } redefineWsPrefix=false; } string resultString; // Position, ab der rueckwaerts nach Umbruchmglichkeit gesucht wird unsigned int searchEndPos = maxLineLength - wsPrefixLength; // letztes Teilstueck der Zeile ausgeben; Parsen beenden if ( line.length()-index < searchEndPos ) { hasMore=false; resultString= ( index>0 ) ? wsPrefix + line.substr ( index ) : line.substr ( index ); return resultString; } // Umbrechposition suchen size_t lbPos = line.find_last_of ( LB_CHARS, index+searchEndPos ); if ( lbPos <= index || lbPos == string::npos ) { // nichts gefunden, hart umbrechen lbPos = index + searchEndPos; } // Einrckung der Originalzeile erhalten resultString+=wsPrefix; // Neue Zeile erzeugen resultString += line.substr ( index, lbPos-index+1 ); // Whitespace am neuen Zeilenbeginn ignorieren, ausser beim ersten Durchlauf size_t newIndex=line.find_first_not_of ( WS_CHARS, lbPos+1 ); index= ( newIndex!=string::npos ) ?newIndex:line.length(); hasMore=index!=line.length(); // unnoetigen Leerstring vermeiden if ( hasMore ) wrappedLines.insert ( lineNumber ); // diese Zeile wurde umgebrochen return resultString; } void PreFormatter::setWrapLineLength ( unsigned int maxLineLength ) { this->maxLineLength = maxLineLength; } void PreFormatter::setWrapIndentBraces ( bool indentAfterOpenBraces ) { this->indentAfterOpenBraces = indentAfterOpenBraces; } void PreFormatter::setNumberSpaces ( unsigned int num ) { numberSpaces = num; } }