Changeset 284 for trunk/lib/css.cc


Ignore:
Timestamp:
May 6, 2007, 7:54:09 PM (14 years ago)
Author:
Peter Johansson
Message:

moved css generation to separate file

File:
1 copied

Legend:

Unmodified
Added
Removed
  • trunk/lib/css.cc

    r278 r284  
    2222*/
    2323
    24 #include "html_utility.h"
     24#include "css.h"
     25#include <config.h>
    2526
    26 #include "Commitment.h"
    27 #include "Configuration.h"
    28 #include "Date.h"
    29 #include "HtmlStream.h"
    30 #include "Stats.h"
    31 #include "SVNlog.h"
    32 #include "utility.h"
    33 #include <config.h> // this header file is created by configure
    34 
    35 #include <algorithm>
    36 #include <cassert>
    3727#include <fstream>
    38 #include <iostream>
    39 #include <sstream>
    40 #include <stdexcept>
    4128#include <string>
    42 #include <sys/param.h>
    43 #include <unistd.h>
    44 #include <vector>
    4529
    4630namespace theplu{
    4731namespace svndigest{
    4832
    49   std::string anchor(const std::string& href,
    50                      const std::string& name, u_int level,
    51                      const std::string& title)
    52   {
    53     std::stringstream ss;
    54     HtmlStream hs(ss);
    55     ss << "<a title=\"";
    56     hs << title;
    57     ss << "\" href=\"";
    58     for (size_t i=0; i<level; ++i)
    59       ss << "../";
    60     hs << href;
    61     ss << "\">";
    62     hs << name;
    63     ss << "</a>";
    64     return ss.str();
    65   }
    66 
    67  
    6833  void print_css(const std::string& str)
    6934  {
     
    179144    s << " padding: 0 1em .1em 0;\n";
    180145    s << "}\n";
    181 
    182 
    183 
    184 
    185146    s << "table.listings {\n";
    186147    s << " clear: both;\n";
     
    234195
    235196
    236   void print_main_page(const std::string& dir, const SVNlog& log,
    237                        const Stats& stats)
    238   {
    239     std::string filename="index.html";
    240     std::ofstream os(filename.c_str());
    241     print_header(os, dir, 0, "all", "main", "index.html");
    242 
    243     using namespace std;
    244     set<string> authors;
    245     authors.insert(log.author().begin(), log.author().end());
    246     // erase invalid authors
    247     authors.erase("");
    248     authors.erase("no author");
    249 
    250     vector<Commitment> latest_commit;
    251     latest_commit.reserve(authors.size());
    252     for (set<string>::const_iterator i(authors.begin()); i!=authors.end(); ++i)
    253       latest_commit.push_back(log.latest_commit(*i));
    254 
    255     print_general_information(os, log, authors.size());
    256     sort(latest_commit.begin(), latest_commit.end(), GreaterRevision());
    257     print_authors(os, latest_commit, stats);
    258     print_recent_logs(os, log);
    259     os << "<hr width=100% />";
    260     print_footer(os);
    261     os.close();
    262 
    263   }
    264 
    265   void print_general_information(std::ostream& os, const SVNlog& log,
    266                                  size_t nof_authors)
    267   {
    268     Date begin(log.date()[0]);
    269     if (log.date().size()>1)
    270       begin = std::min(begin, Date(log.date()[1]));
    271     Date end(log.date().back());
    272     Date now;
    273     std::string timefmt("%a, %e %b %Y");
    274 
    275     os << "<div class=\"main\">"
    276        << "<table class=\"main\"><thead><tr><th colspan=\"2\">"
    277        << "General Information"
    278        << "</th></tr></thead>\n"
    279        << "<tr><td>First Revision:</td><td>"
    280        << begin(timefmt) << "</td></tr>\n"
    281        << "<tr><td>Latest Revision:</td><td>"
    282        << end(timefmt) << "</td></tr>\n"
    283        << "<tr><td>Report Generated:</td><td>"
    284        << now(timefmt) << "</td></tr>\n"
    285        << "<tr><td>Repository Age:</td><td>";
    286     os << now.difftime(begin);
    287     os << "</td></tr>\n"
    288        << "<tr><td>Number of Authors:</td><td>" << nof_authors
    289        << "</td></tr>\n"
    290        << "<tr><td>Revisions:</td><td>" << log.revision().size()
    291        << "</td></tr>\n"
    292        << "</table></div>\n";
    293   }
    294 
    295 
    296   void print_footer(std::ostream& os)
    297   {
    298     Date date;
    299     os << "<p align=center><font size=-2>\nGenerated on "
    300        << date("%a %b %d %H:%M:%S %Y") << " (UTC) by "
    301        << anchor("http://lev.thep.lu.se/trac/svndigest/",
    302                  PACKAGE_STRING, 0, "")
    303        << "</font>\n</p>\n</div>\n</body>\n</html>\n";
    304   }
    305 
    306 
    307   void print_header(std::ostream& os, std::string title, u_int level,
    308                     std::string user, std::string item, std::string path)
    309   {
    310     os << "<!DOCTYPE html\n"
    311        << "PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\"\n"
    312        << "\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n"
    313        << "<html xmlns=\"http://www.w3.org/1999/xhtml\""
    314        << " xml:lang=\"en\" lang=\"en\"><head>\n"
    315        << "<head>\n"
    316        << "<title> " << title << " - svndigest</title>\n"
    317        << "</head>\n"
    318        << "<link rel=\"stylesheet\" "
    319        << "href=\"";
    320     for (u_int i=0; i<level; ++i)
    321       os << "../";
    322     os << "svndigest.css\" type=\"text/css\" />\n"
    323        << "<body>\n"
    324        << "<div id=\"menu\">"
    325        << "<ul><li></li>";
    326     if (item=="main")
    327       os << "<li class=\"highlight\">";
    328     else
    329       os << "<li>";
    330     os << anchor("index.html", "Main", level, "Main page");
    331     os << "</li>";
    332 
    333     if (item=="total")
    334       os << "<li class=\"highlight\">";
    335     else
    336       os << "<li>";
    337     os << anchor(user+"/total/"+path, "Total", level,
    338            "View statistics of all lines");
    339     os << "</li>";
    340 
    341     if (item=="code")
    342       os << "<li class=\"highlight\">";
    343     else
    344       os << "<li>";
    345     os << anchor(user+"/code/"+path, "Code", level,
    346                  "View statistics of code lines");
    347     os << "</li>";
    348 
    349     if (item=="comments")
    350       os << "<li class=\"highlight\">";
    351     else
    352       os << "<li>";
    353     os << anchor(user+"/comments/"+path, "Comment", level,
    354                  "View statistics of comment lines");
    355     os << "</li>";
    356 
    357 
    358     if (item=="empty")
    359       os << "<li class=\"highlight\">";
    360     else
    361       os << "<li>";
    362     os << anchor(user+"/empty/"+path, "Other", level,
    363                  "View statistics of empty lines");
    364     os << "</li>"
    365        << "</ul></div>"
    366        << "<div id=\"main\">\n";
    367   }
    368 
    369 
    370   void print_authors(std::ostream& os,
    371                      const std::vector<Commitment>& lc,
    372                      const Stats& stats)
    373   {
    374     os << "<div class=\"main\">"
    375        << "<table class=\"main\"><thead><tr><th colspan=\"2\">"
    376        << "Authors"
    377        << "</th></tr></thead>\n";
    378 
    379     os << "<tr><td>Author</td>"
    380        << "<td>Number of Lines</td>"
    381        << "<td>Code Lines</td>"
    382        << "<td>Comment Lines</td>"
    383        << "<td>Latest Commitment</td>"
    384        <<"</tr>";
    385 
    386     std::string timefmt("%b %d %H:%M:%S %Y");
    387     using namespace std;
    388     for (vector<Commitment>::const_iterator i=lc.begin(); i!=lc.end(); ++i) {
    389       os << "<tr><td>"
    390          << anchor(string(i->author()+"/total/index.html"),i->author())
    391          << "</td><td>" << stats.lines(i->author()) << " ("
    392          << 100*stats.lines(i->author())/stats.lines() << "%)</td>"
    393          << "<td>" << stats.code(i->author()) << " ("
    394          << 100*stats.code(i->author())/stats.code() << "%)</td>"
    395          << "<td>" << stats.comments(i->author()) << " ("
    396          << 100*stats.comments(i->author())/stats.comments() << "%)</td>"
    397          << "<td>" << i->date()(timefmt) << "</td>"
    398          <<"</tr>";
    399     }
    400 
    401     os << "</table></div>\n";
    402    
    403   }
    404 
    405 
    406   void print_recent_logs(std::ostream& os, const SVNlog& log)
    407   {
    408     os << "<div class=\"main\">\n"
    409        << "<table class=\"main\"><thead><tr><th colspan=\"2\">"
    410        << "Recent Log"
    411        << "</th></tr></thead>\n";
    412 
    413     std::vector<std::string>::const_reverse_iterator a=log.author().rbegin();
    414     std::vector<std::string>::const_reverse_iterator d=log.date().rbegin();
    415     std::vector<std::string>::const_reverse_iterator m=log.message().rbegin();
    416     std::vector<size_t>::const_reverse_iterator r=log.revision().rbegin();
    417     assert(log.author().size()==log.date().size());
    418     assert(log.author().size()==log.message().size());
    419     assert(log.author().size()==log.revision().size());
    420     os << "<tr><td>Author</td><td>Date</td><td>Rev</td><td>Message</td></tr>\n";
    421     HtmlStream hs(os);
    422     std::string timefmt("%b %d %H:%M:%S %Y");
    423     const size_t maxlength = 80;
    424     const Configuration* conf = Configuration::instance();
    425     for (size_t i=0; i<10 && a!=log.author().rend(); ++i) {
    426       os << "<tr><td>" << anchor(*a+"/total/index.html",*a) << "</td>";
    427       Date date(*d);
    428       os << "<td>" << date(timefmt) << "</td>";
    429       os << "<td>";
    430       os << trac_revision(*r);
    431       os << "</td>";
    432       os << "<td>";
    433       std::string mess = *m;
    434       // replace newlines with space
    435       std::replace(mess.begin(), mess.end(), '\n', ' ');
    436       mess = htrim(mess);
    437       // truncate message if too long
    438       if (mess.size()>maxlength)
    439         mess = mess.substr(0,maxlength-3) + "...";
    440 
    441       if (conf->trac_ticket().empty())
    442         hs << mess;
    443       else { // make anchors to trac
    444         char c;
    445         std::stringstream ss(mess);
    446         for (ss.get(c); ss.good(); ss.get(c)) {
    447           if (c=='#') {
    448             int ticket=0;
    449             ss >> ticket;
    450             if (!ss.fail()){
    451               std::stringstream s;
    452               s << ticket;
    453               os << anchor(conf->trac_ticket()+s.str(),"#"+s.str());
    454             }
    455             else {
    456               ss.clear(std::ios::goodbit);
    457               hs << c;
    458             }
    459           }
    460           else
    461             hs << c;
    462         }
    463       }
    464 
    465       os << "</td></tr>";
    466       ++a;
    467       ++d;
    468       ++m;
    469       ++r;
    470     }
    471     os << "</table></div>\n";
    472   }
    473 
    474 
    475   std::string trac_revision(size_t r)
    476   {
    477     Configuration* conf = Configuration::instance();
    478     std::stringstream ss;
    479     if (conf->trac_revision().empty())
    480       ss << r;
    481     else {
    482       std::stringstream rev;
    483       rev << r;
    484       ss << anchor(conf->trac_revision()+rev.str(), rev.str());
    485     }
    486     return ss.str();
    487   }
    488 
    489197}} // end of namespace svndigest and namespace theplu
Note: See TracChangeset for help on using the changeset viewer.