Příspěvek
od neoangin » 30. 1. 2007 10:52
/* ========================================= cssnice.h ================================================================ */
#include <string>
#include <vector>
#include <map>
#include <iostream>
#include <ostream>
#include <iomanip>
#include <fstream>
#include "csssoubor.h"
using namespace std;
int main( int argc, char **argv) {
if (argc != 2){
cout << "Error - usage : cssnice.exe file.css" << endl;
return 1;
}
CssSoubor parser;
ifstream infile;
infile.open( argv[1], ios::in);
if ( ! infile ) {
cerr << "Error: Can't open the input file
";
return(1);
}
infile>>parser;
cout<<parser;
infile.close();
return 0;
}
/* ========================================= csssoubor.h ================================================================ */
#include <vector>
#include <string>
#include <map>
#include "cssblok.h"
using namespace std;
class CssSoubor {
public:
friend std::ostream &operator<<(std::ostream &o, const CssSoubor &soubor);
friend std::istream &operator>>(std::istream &i, CssSoubor &soubor);
void serad();
private:
typedef vector< CssBlok> SeznamBloku;
SeznamBloku bloky_;
};
bool ftor_blok_sort( const CssBlok &a, const CssBlok &b ) {
return ( (*(a.tagy_.begin()))<(*(b.tagy_.begin())) );
}
void CssSoubor::serad() {
CssSoubor::SeznamBloku::iterator ib = bloky_.begin();
CssSoubor::SeznamBloku::iterator ie = bloky_.end();
sort(ib, ie, ftor_blok_sort);
}
std::istream &operator>>(std::istream &i, CssSoubor &soubor) {
//cte stream znaku a sype ho do bloku, ty pak pridava
while (i) {
CssBlok blok;
i>>blok;
if (!blok.empty()) {
blok.serad();
soubor.bloky_.insert( soubor.bloky_.end(), blok );
}
}
soubor.serad();
return i;
}
std::ostream &operator<<(std::ostream &o, const CssSoubor &soubor) {
//vypise hezky zformatovany css soubor
CssSoubor::SeznamBloku::const_iterator ib = soubor.bloky_.begin();
CssSoubor::SeznamBloku::const_iterator ie = soubor.bloky_.end();
while( ib!=ie ) {
o << *ib;
++ib;
}
o << endl;
return o;
}
/* ========================================= cssblok.h ================================================================ */
#include <vector>
#include <string>
#include <map>
#include <algorithm>
#include <ctype.h>
using namespace std;
class CssBlok {
public:
void serad(); //seradi tagy a pravidla podle abecedy
bool empty();
friend std::ostream &operator<<(std::ostream &o, const CssBlok &blok);
friend std::istream &operator>>(std::istream &i, CssBlok &blok);
//friend bool ftor_blok_sort( CssBlok &a, CssBlok &b );
friend bool ftor_blok_sort( const CssBlok &a, const CssBlok &b );
private:
typedef vector<string> Tagy;
typedef pair< string, string> DvaStringy;
typedef multimap< string, string> Pravidla;
Tagy tagy_;
Pravidla pravidla_;
void cti_pravidlo( std::istream &i, bool &b);
void cti_tag( std::istream &i, bool &b);
friend class CssSoubor;
};
std::istream &operator>>(std::istream &i, CssBlok &blok) {
//cte stream znaku a parsuje
bool dale;
blok.cti_tag(i, dale);
while ( dale==true ) {
blok.cti_tag(i, dale);
}
//cteme vlastnosti
blok.cti_pravidlo(i, dale);
while ( dale==true ) {
blok.cti_pravidlo(i, dale);
}
return i;
}
void CssBlok::cti_tag( std::istream &i, bool &b) {
b = true;
char c;
string tag="";
if (!i) { b = false; return; }
// sezereme whitespace
i>>c;
while ( (i) && isspace(c)) i>>c;
if (!i) { b = false; return; }
if (c=='{') {
b = false;
return;
}
while ((c!=',') && (c!='{')) {
if (!( isspace(c) && isspace(tag[tag.length()]) )) {
tag+=c;
}
i>>c;
}
//cout<<" *tag: "<<tag<<endl;
tagy_.insert(tagy_.end(), tag);
if (c=='{') {
b = false;
return;
}
}
void CssBlok::cti_pravidlo( std::istream &i, bool &b) {
//rozsekat pravidlo na _property_:_value_;
b = true;
char c;
string prop="", val="";
if (!i) {
b = false;
return;
}
//preskoc whitespace
i>>c;
while ( (i) && isspace(c)) i>>c;
if (c=='}') { //konec, vrat pair(i, false)
b = false;
return;
}
//cti property
while ( c!=':' ) {
if (!( isspace(c) && isspace(prop[prop.length()]) )) {
prop+=c;
}
i>>c;
}
//cti value
i>>c;
while ( isspace(c)) i>>c;
//cekej na ;
while (( c!=';' ) && ( c!='}' )) {
if (!( isspace(c) && isspace(val[val.length()]) )) {
val+=c;
}
i>>c;
}
if (c=='}') { b=false; }
//cout<<" *ctu: "<<prop<<" : "<<val<<endl;
pravidla_.insert( DvaStringy( prop, val ) );
//return VystupniPar( i, true );
return;
}
std::ostream &operator<<(std::ostream &o, const CssBlok &blok) {
//vypise hezky zformatovany css blok
CssBlok::Pravidla::const_iterator pie=blok.pravidla_.end();
CssBlok::Pravidla::const_iterator pit=blok.pravidla_.begin();
CssBlok::Tagy::const_iterator tie=blok.tagy_.end();
CssBlok::Tagy::const_iterator tit=blok.tagy_.begin();
while( tie!=tit ) {
o << *tit;
++tit;
if ( tie!=tit ) { o << ", "; } //dame jeste carku, prijde dalsi
}
o << " {" << endl;
while( pie!=pit ) {
o << "\t" << pit->first << ": " << pit->second << ";" << endl;
++pit;
}
o << "}" << endl;
o<<endl;
return o;
}
bool ftor_tag_sort( const string &a, const string &b ) {
int i=0;
bool delim_a, delim_b, jedeme=true;
while (true) {
delim_a=false, delim_b=false;
if ( (a=='.') || (a==':') || (a=='#') ) { delim_a=true; }
if ( (b=='.') || (b==':') || (b=='#') ) { delim_b=true; }
if (delim_a && (delim_b == false)) { return true; } //a ma oddelovac, b nema -> a je kratsi a do delim. stejne s b
if (delim_b && (delim_a == false)) { return false; } //b ma oddelovac, a nema
if ((delim_a == false) && (delim_b == false) && (a!=b)) { return (a<b); }
if ( (i<a.length()) && (i<b.length()) ) { i++; } else { jedeme = false; }
}
return false;
}
/*
bool ftor_pravidlo_sort( const DvaStringy &a, const DvaStringy &b ) {
return (a.first()<a.second());
}
*/
void CssBlok::serad() {
CssBlok::Tagy::iterator tie=this->tagy_.end();
CssBlok::Tagy::iterator tib=this->tagy_.begin();
CssBlok::Pravidla::iterator pie=this->pravidla_.end();
CssBlok::Pravidla::iterator pib=this->pravidla_.begin();
stable_sort(tib, tie, ftor_tag_sort ); // pouziti nestabilniho sortu by mohlo menit vyznam - viz color:white; color: black;
//stable_sort(pib, pie, ftor_pravidlo_sort );
}
bool CssBlok::empty() {
if (tagy_.empty() && pravidla_.empty()) {
return true;
}
return false;
}
$ man woman
No manual entry for woman