Changeset 284


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

moved css generation to separate file

Location:
trunk
Files:
4 edited
2 copied

Legend:

Unmodified
Added
Removed
  • trunk/bin/svndigest.cc

    r264 r284  
    2626
    2727#include "Configuration.h"
     28#include "css.h"
    2829#include "Directory.h"
    2930#include "GnuplotFE.h"
  • trunk/lib/Makefile.am

    r255 r284  
    2626noinst_LTLIBRARIES = libsvndigest.la
    2727
    28 noinst_HEADERS = ColumnStream.h Commitment.h Configuration.h \
     28noinst_HEADERS = ColumnStream.h Commitment.h Configuration.h css.h\
    2929  Date.h Directory.h File.h Gnuplot.h GnuplotFE.h \
    3030  HtmlStream.h html_utility.h Node.h Parser.h rmdirhier.h \
     
    3333
    3434libsvndigest_la_SOURCES = ColumnStream.cc Commitment.cc Configuration.cc \
    35   Date.cc Directory.cc File.cc \
     35  css.cc Date.cc Directory.cc File.cc \
    3636  Gnuplot.cc GnuplotFE.cc HtmlStream.cc \
    3737  html_utility.cc Node.cc Parser.cc rmdirhier.cc Stats.cc SVN.cc        \
  • 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
  • trunk/lib/css.h

    r278 r284  
    1 #ifndef _theplu_svndigest_html_utility_
    2 #define _theplu_svndigest_html_utility_
     1#ifndef _theplu_svndigest_css_
     2#define _theplu_svndigest_css_
    33
    44// $Id$
     
    2525*/
    2626
    27 #include <iostream>
    28 #include <fstream>
    29 #include <iosfwd>
    30 #include <set>
    3127#include <string>
    32 #include <vector>
    3328
    3429namespace theplu{
    3530namespace svndigest{
    36 
    37   class Commitment;
    38   class Date;
    39   class Stats;
    40   class SVNlog;
    41 
    42   ///
    43   /// @brief create anchor
    44   ///
    45   /// @param href address to link to
    46   /// @param name text visible on page
    47   /// @param level '../' is added @a level times before @a href
    48   /// @param title title of anchor
    49   ///
    50   std::string anchor(const std::string& href,
    51                      const std::string& name, u_int level=0,
    52                      const std::string& title="");
    5331
    5432  ///
     
    5735  void print_css(const std::string& str);
    5836
    59   void print_authors(std::ostream& os,
    60                      const std::vector<Commitment>& latest_commit,
    61                      const Stats& stats);
    62 
    63   ///
    64   /// called by print_main_page
    65   ///
    66   void print_general_information(std::ostream&, const SVNlog&, size_t);
    67 
    68   ///
    69   /// @brief print main page
    70   ///
    71   void print_main_page(const std::string&, const SVNlog&, const Stats&);
    72    
    73   void print_recent_logs(std::ostream&, const SVNlog& log);
    74    
    75   ///
    76   /// @brief print html footer of page
    77   ///
    78   void print_footer(std::ostream&);
    79    
    80   ///
    81   /// @brief print html header of page
    82   ///
    83   /// \param os stream to print to
    84   /// \param name
    85   /// \param level
    86   /// \param
    87   void print_header(std::ostream& os, std::string name, u_int level,
    88                     std::string user, std::string item, std::string path);
    89 
    90 
    91   ///
    92   /// @return if trac-revision is set in config file anchor to trac is
    93   /// given otherwise just a string corresponding to passed parameter.
    94   ///
    95   std::string trac_revision(size_t);
    96 
    9737}} // end of namespace svndigest end of namespace theplu
    9838
  • trunk/lib/html_utility.cc

    r275 r284  
    6666
    6767 
    68   void print_css(const std::string& str)
    69   {
    70     std::ofstream s(str.c_str());
    71     s << "<-- svndigest.css generated by " << PACKAGE_STRING << "\n"
    72 
    73       << "Copyright (C) 2006, 2007 Peter Johansson\n\n"
    74       << "This file is part of svndigest, "
    75       << "http://lev.thep.lu.se/trac/svndigest\n\n"
    76 
    77       << "svndigest is free software; you can redistribute it and/or "
    78       << "modify it\n"
    79       << "under the terms of the GNU General Public License as published by\n"
    80       << "the Free Software Foundation; either version 2 of the License, or\n"
    81       << "(at your option) any later version.\n\n"
    82 
    83       << "svndigest is distributed in the hope that it will be useful, but\n"
    84       << "WITHOUT ANY WARRANTY; without even the implied warranty of\n"
    85       << "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n"
    86       << "General Public License for more details.\n\n"
    87 
    88       << "You should have received a copy of the GNU General Public License\n"
    89       << "along with this program; if not, write to the Free Software\n"
    90       << "Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA\n"
    91       << "02111-1307, USA.\n\n"
    92 
    93       << "This file was initially inspired by the cascading style sheet\n"
    94       << "within the Trac open source project (http://trac.edgewall.org/)\n"
    95       << "Copyright (C) 2003-2006 Edgewall Software\n"
    96       << "All rights reserved.\n\n"
    97 
    98       << "Redistribution and use in source and binary forms, with or without\n"
    99       << "modification, are permitted provided that the following conditions\n"
    100       << "are met:\n\n"
    101      
    102       << "1. Redistributions of source code must retain the above copyright\n"
    103       << "   notice, this list of conditions and the following disclaimer.\n"
    104       << "2. Redistributions in binary form must reproduce the above "
    105       << "copyright\n"
    106       << "   notice, this list of conditions and the following disclaimer in\n"
    107       << "   the documentation and/or other materials provided with the\n"
    108       << "   distribution.\n"
    109       << "3. The name of the author may not be used to endorse or promote\n"
    110       << "   products derived from this software without specific prior\n"
    111       << "   written permission.\n\n"
    112      
    113       << "THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS'' AND ANY EXPRESS\n"
    114       << "OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n"
    115       << "WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n"
    116       << "ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY\n"
    117       << "DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n"
    118       << "DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE\n"
    119       << "GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n"
    120       << "INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\n"
    121       << "WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n"
    122       << "NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n"
    123       << "SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.-->\n";
    124 
    125 
    126     s << "body {\n";
    127     s << " background: #fff; \n";
    128     s << " color: #000; \n";
    129     s << " margin: 0px; \n";
    130     s << " padding: 0; \n";
    131     s << "} \n";
    132     s << "\n";
    133     s << "#menu {\n";
    134     s << " background: #eee;\n";
    135     s << " width: 100%;\n";
    136     s << " margin: 0px;\n";
    137     s << " padding: 0px;\n";
    138     s << "}\n\n";
    139     s << "#menu ul\n";
    140     s << "{ \n";
    141     s << "padding: 0px;\n";
    142     s << "margin: 0px;list-style-type: none; text-align: center;"
    143       << "border-bottom: 1px solid black;}\n";
    144     s << "#menu ul li { display: inline; border-right: 1px solid black;}\n";
    145     s << "#menu ul li a {text-decoration: none; padding-right: 1em;"
    146       << "padding-left: 1em; margin: 0px;}\n";
    147     s << "#menu ul li a:hover{ color: #000; background: #ddd;}\n";
    148     s << "#menu ul li.highlight a {color: #fff; background: #777; }";
    149     s << "\n";
    150     s << "#main {\n";
    151     s << " margin: 10px; \n";
    152     s << "}\n";
    153     s << "\n";
    154     s << "body, th, td {\n";
    155     s << " font: normal 13px verdana,arial,'Bitstream Vera Sans',"
    156       << "helvetica,sans-serif;\n";
    157     s << "}\n";
    158     s << ":link, :visited {\n";
    159     s << " text-decoration: none;\n";
    160     s << " color: #b00;\n";
    161     s << "}\n";
    162     s << "\n";
    163     s << "div.main {\n";
    164     s << "margin-top: 50px;\n";         
    165     s << "margin-left: 50px;\n";
    166     s << " \n";
    167     s << "}\n";
    168     s << "table.main {\n";
    169     s << " text-align: left;\n";
    170     s << " padding: 0 1em .1em 0;\n";
    171     s << "}\n";
    172     s << "table.main th {\n";
    173     s << " text-align: left;\n";
    174     s << " padding: 0 1em 0.5em 0;\n";
    175     s << " font-size: 150%;\n";
    176     s << " font-wheight: bold;\n";
    177     s << "}\n";
    178     s << "table.main td {\n";
    179     s << " padding: 0 1em .1em 0;\n";
    180     s << "}\n";
    181 
    182 
    183 
    184 
    185     s << "table.listings {\n";
    186     s << " clear: both;\n";
    187     s << " border-bottom: 1px solid #d7d7d7;\n";
    188     s << " border-collapse: collapse;\n";
    189     s << " border-spacing: 0;\n";
    190     s << " margin-top: 1em;\n";
    191     s << " width: 100%;\n";
    192     s << "}\n";
    193     s << "\n";
    194     s << "table.listings th {\n";
    195     s << " text-align: left;\n";
    196     s << " padding: 0 1em .1em 0;\n";
    197     s << " font-size: 12px\n";
    198     s << "}\n";
    199     s << "table.listings thead { background: #f7f7f0 }\n";
    200     s << "table.listings thead th {\n";
    201     s << " border: 1px solid #d7d7d7;\n";
    202     s << " border-bottom-color: #999;\n";
    203     s << " font-size: 11px;\n";
    204     s << " font-wheight: bold;\n";
    205     s << " padding: 2px .5em;\n";
    206     s << " vertical-align: bottom;\n";
    207     s << "}\n";
    208     s << "\n";
    209     s << "table.listings tbody td a:hover, table.listing tbody th a:hover {\n";
    210     s << " background-color: transparent;\n";
    211     s << "}\n";
    212     s << "\n";
    213     s << "table.listings tbody td, table.listing tbody th {\n";
    214     s << " border: 1px dotted #ddd;\n";
    215     s << " padding: .33em .5em;\n";
    216     s << " vertical-align: top;\n";
    217     s << "}\n";
    218     s << "\n";
    219     s << "table.listings tbody td a:hover, table.listing tbody th a:hover {\n";
    220     s << " background-color: transparent;\n";
    221     s << "}\n";
    222     s << "table.listings tbody tr { border-top: 1px solid #ddd }\n";
    223     s << "table.listings tbody tr.light { background-color: #fcfcfc }\n";
    224     s << "table.listings tbody tr.dark { background-color: #f7f7f7 }\n";
    225     s << "table.listings tbody tr:hover { background: #eed }\n";
    226     s << "table.listings tbody td { text-align: left }\n";
    227     s << "table.listings tbody td.directory a { font-weight: bold }\n";
    228     s << "\n";
    229     s << ".sep { color: #666}\n";
    230     s << "\n";
    231     s << "\n";
    232     s.close();
    233   }
    234 
    235 
    23668  void print_main_page(const std::string& dir, const SVNlog& log,
    23769                       const Stats& stats)
  • trunk/lib/html_utility.h

    r274 r284  
    5252                     const std::string& title="");
    5353
    54   ///
    55   /// \brief printing cascading style sheet to file name @a str.
    56   ///
    57   void print_css(const std::string& str);
    58 
    5954  void print_authors(std::ostream& os,
    6055                     const std::vector<Commitment>& latest_commit,
Note: See TracChangeset for help on using the changeset viewer.