source: trunk/lib/html_utility.cc @ 215

Last change on this file since 215 was 215, checked in by Peter Johansson, 16 years ago

added copyright statement in generated css file, and an acknowledgement to Trac

File size: 10.8 KB
Line 
1// $Id$
2
3/*
4  Copyright (C) 2006 Peter Johansson
5
6  This file is part of svndigest, http://lev.thep.lu.se/trac/svndigest
7
8  svndigest is free software; you can redistribute it and/or modify it
9  under the terms of the GNU General Public License as published by
10  the Free Software Foundation; either version 2 of the License, or
11  (at your option) any later version.
12
13  svndigest is distributed in the hope that it will be useful, but
14  WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  General Public License for more details.
17
18  You should have received a copy of the GNU General Public License
19  along with this program; if not, write to the Free Software
20  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
21  02111-1307, USA.
22*/
23
24#include "html_utility.h"
25#include "utility.h"
26#include <config.h> // this header file is created by configure
27
28#include <fstream>
29#include <iostream>
30#include <sstream>
31#include <stdexcept>
32#include <string>
33#include <sys/param.h>
34#include <unistd.h>
35#include <vector>
36
37namespace theplu{
38namespace svndigest{
39
40  void anchor(std::ostream& os, const std::string& href, 
41              const std::string& name, u_int level, 
42              const std::string& title)
43  {
44    os << "<a title=\"" << title << "\" href=\"" ;
45    for (size_t i=0; i<level; ++i)
46      os << "../";
47    os << href << "\">" << name << "</a>";
48  }
49
50
51 
52  void html(std::istream& is, std::ostream& os, char delim) 
53  {
54    char c;
55    while (true){
56      is.get(c);
57      if (c==delim || !is.good()){
58        return;
59      }
60      if (c=='"')
61        os << '\"';
62      else if (c=='\'')
63        os << "\'";
64      else if (c=='\n')
65        os << "<br/>";
66      else if (c=='<')
67        os << "&lt;";
68      else if (c=='>')
69        os << "&gt;";
70      else if (c=='&')
71        os << "&amp;";
72      else if (c=='\t')
73        os << "&nbsp;&nbsp;";
74      else if (c=='å')
75        os << "&aring;";
76      else if (c=='ä')
77        os << "&auml;";
78      else if (c=='ö')
79        os << "&ouml;";
80      else if (c=='Å')
81        os << "&Aring;";
82      else if (c=='Ä')
83        os << "&Auml;";
84      else if (c=='Ö')
85        os << "&Ouml;";
86      else if (c=='é')
87        os << "&eacute;";
88      else
89        os << c;
90    }
91  }
92 
93
94  void print_css(const std::string& str)
95  {
96    std::ofstream s(str.c_str());
97    s << "<-- svndigest.css generated by " << PACKAGE_STRING << "\n"
98
99      << "Copyright (C) 2006 Peter Johansson\n\n"
100      << "This file is part of svndigest, " 
101      << "http://lev.thep.lu.se/trac/svndigest\n\n"
102
103      << "svndigest is free software; you can redistribute it and/or " 
104      << "modify it\n"
105      << "under the terms of the GNU General Public License as published by\n"
106      << "the Free Software Foundation; either version 2 of the License, or\n"
107      << "(at your option) any later version.\n\n"
108
109      << "svndigest is distributed in the hope that it will be useful, but\n"
110      << "WITHOUT ANY WARRANTY; without even the implied warranty of\n"
111      << "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n"
112      << "General Public License for more details.\n\n"
113
114      << "You should have received a copy of the GNU General Public License\n"
115      << "along with this program; if not, write to the Free Software\n"
116      << "Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA\n"
117      << "02111-1307, USA.\n\n"
118
119      << "This file was initially ispired by the cascading style sheet\n"
120      << "within the Trac open source project (http://trac.edgewall.org/)\n"
121      << "Copyright (C) 2003-2006 Edgewall Software\n"
122      << "All rights reserved.\n\n"
123
124      << "Redistribution and use in source and binary forms, with or without\n"
125      << "modification, are permitted provided that the following conditions\n"
126      << "are met:\n\n"
127     
128      << "1. Redistributions of source code must retain the above copyright\n"
129      << "   notice, this list of conditions and the following disclaimer.\n"
130      << "2. Redistributions in binary form must reproduce the above " 
131      << "copyright\n"
132      << "   notice, this list of conditions and the following disclaimer in\n"
133      << "   the documentation and/or other materials provided with the\n"
134      << "   distribution.\n"
135      << "3. The name of the author may not be used to endorse or promote\n"
136      << "   products derived from this software without specific prior\n"
137      << "   written permission.\n\n"
138     
139      << "THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS'' AND ANY EXPRESS\n"
140      << "OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n"
141      << "WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n"
142      << "ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY\n"
143      << "DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n"
144      << "DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE\n"
145      << "GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n"
146      << "INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\n"
147      << "WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n"
148      << "NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n"
149      << "SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n";
150
151
152    s << "body {\n";
153    s << " background: #fff; \n";
154    s << " color: #000; \n";
155    s << " margin: 0px; \n";
156    s << " padding: 0; \n";
157    s << "} \n";
158    s << "\n";
159    s << "#menu {\n";
160    s << " background: #eee;\n";
161    s << " width: 100%;\n";
162    s << " margin: 0px;\n";
163    s << " padding: 0px;\n";
164    s << "}\n\n";
165    s << "#menu ul\n";
166    s << "{ \n";
167    s << "padding: 0px;\n";
168    s << "margin: 0px;list-style-type: none; text-align: center;"
169      << "border-bottom: 1px solid black;}\n";
170    s << "#menu ul li { display: inline; border-right: 1px solid black;}\n";
171    s << "#menu ul li a {text-decoration: none; padding-right: 1em;" 
172      << "padding-left: 1em; margin: 0px;}\n";
173    s << "#menu ul li a:hover{ color: #000; background: #ddd;}\n";
174    s << "#menu ul li.highlight a {color: #fff; background: #777; }";
175    s << "\n";
176    s << "#main {\n";
177    s << " margin: 10px; \n";
178    s << "}\n";
179    s << "\n";
180    s << "body, th, td {\n";
181    s << " font: normal 13px verdana,arial,'Bitstream Vera Sans',"
182      << "helvetica,sans-serif;\n";
183    s << "}\n";
184    s << ":link, :visited {\n";
185    s << " text-decoration: none;\n";
186    s << " color: #b00;\n";
187    s << "}\n";
188    s << "\n";
189    s << "div.main {\n";
190    s << " text-align: center\n";
191    s << "}\n";
192    s << "table.listings {\n";
193    s << " clear: both;\n";
194    s << " border-bottom: 1px solid #d7d7d7;\n";
195    s << " border-collapse: collapse;\n";
196    s << " border-spacing: 0;\n";
197    s << " margin-top: 1em;\n";
198    s << " width: 100%;\n";
199    s << "}\n";
200    s << "\n";
201    s << "table.listings th {\n";
202    s << " text-align: left;\n";
203    s << " padding: 0 1em .1em 0;\n";
204    s << " font-size: 12px\n";
205    s << "}\n";
206    s << "table.listings thead { background: #f7f7f0 }\n";
207    s << "table.listings thead th {\n";
208    s << " border: 1px solid #d7d7d7;\n";
209    s << " border-bottom-color: #999;\n";
210    s << " font-size: 11px;\n";
211    s << " font-wheight: bold;\n";
212    s << " padding: 2px .5em;\n";
213    s << " vertical-align: bottom;\n";
214    s << "}\n";
215    s << "\n";
216    s << "table.listings tbody td a:hover, table.listing tbody th a:hover {\n";
217    s << " background-color: transparent;\n";
218    s << "}\n";
219    s << "\n";
220    s << "table.listings tbody td, table.listing tbody th {\n";
221    s << " border: 1px dotted #ddd;\n";
222    s << " padding: .33em .5em;\n";
223    s << " vertical-align: top;\n";
224    s << "}\n";
225    s << "\n";
226    s << "table.listings tbody td a:hover, table.listing tbody th a:hover {\n";
227    s << " background-color: transparent;\n";
228    s << "}\n";
229    s << "table.listings tbody tr { border-top: 1px solid #ddd }\n";
230    s << "table.listings tbody tr.light { background-color: #fcfcfc }\n";
231    s << "table.listings tbody tr.dark { background-color: #f7f7f7 }\n";
232    s << "table.listings tbody tr:hover { background: #eed }\n";
233    s << "table.listings tbody td { text-align: left }\n";
234    s << "table.listings tbody td.directory a { font-weight: bold }\n";
235    s << "\n";
236    s << ".sep { color: #666}\n";
237    s << "\n";
238    s << "\n";
239    s.close();
240  }
241
242
243  void print_main_page(const std::string& dir,
244                       const std::vector<std::string>& commit_dates)
245  {
246    std::string filename="index.html";
247    std::ofstream os(filename.c_str());
248    print_header(os, dir, 0, "main", "index.html");
249    time_t now; 
250    time (&now);
251    u_int n7=0;
252    u_int n30=0;
253    u_int n365=0;
254    for (size_t i=1; i<commit_dates.size(); ++i){
255      double diff = difftime(now,str2time(commit_dates[i]));
256      if (diff<365*24*3600){
257        n365++;
258        if (diff<30*24*3600){
259          n30++;
260          if (diff<7*24*3600)
261            n7++;
262        }
263      }
264    }
265    os << "<div class=\"main\">\n"
266       << "<table><thead><tr><th>Statistics for " << dir
267       << "</th></tr><thead>\n"
268       << "<tr><td>Total number of commits</td><td>" 
269       << commit_dates.size()-1 << "</td></tr>\n"
270       << "<tr><td>Commits last year</td><td>" << n365 << "</td></tr>\n"
271       << "<tr><td>Commits last month</td><td>" << n30 << "</td></tr>\n"
272       << "<tr><td>Commits last week</td><td>" << n7 << "</td></tr>\n"
273       << "</table></div>\n";
274   
275       
276    print_footer(os);
277    os.close();
278  }
279
280
281  void print_footer(std::ostream& os)
282  {
283    time_t rawtime;
284    struct tm * timeinfo;
285    time ( &rawtime );
286    timeinfo =  gmtime ( &rawtime );
287    os << "<p align=center><font size=-2>\nGenerated on "
288       << asctime (timeinfo) << " (UTC) by ";
289    anchor(os, "http://lev.thep.lu.se/trac/svndigest/", PACKAGE_STRING, 0, "");
290    os << "</font>\n</p>\n</div>\n</body>\n</html>\n";
291  }
292
293
294  void print_header(std::ostream& os, const std::string& title, u_int level,
295                    const std::string& item, const std::string& path)
296  {
297    os << "<!DOCTYPE html\n"
298       << "PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\"\n"
299       << "\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n"
300       << "<html xmlns=\"http://www.w3.org/1999/xhtml\""
301       << " xml:lang=\"en\" lang=\"en\"><head>\n"
302       << "<head>\n"
303       << "<title> " << title << " - svndigest</title>\n"
304       << "</head>\n"
305       << "<link rel=\"stylesheet\" "
306       << "href=\"";
307    for (u_int i=0; i<level; ++i)
308      os << "../";
309    os << "svndigest.css\" type=\"text/css\" />\n"
310       << "<body>\n"
311       << "<div id=\"menu\">"
312       << "<ul><li></li>";
313    if (item=="main")
314      os << "<li class=\"highlight\">";
315    else
316      os << "<li>";
317    anchor(os, "index.html", "Main", level, "Main page");
318    os << "</li>";
319
320    if (item=="total")
321      os << "<li class=\"highlight\">";
322    else
323      os << "<li>";
324    anchor(os, "all/total/"+path, "Total", level, 
325           "View statistics of all lines");
326    os << "</li>";
327
328    if (item=="code")
329      os << "<li class=\"highlight\">";
330    else
331      os << "<li>";
332    anchor(os, "all/code/"+path, "Code", level, 
333           "View statistics of code lines");
334    os << "</li>";
335
336    if (item=="comments")
337      os << "<li class=\"highlight\">";
338    else
339      os << "<li>";
340    anchor(os, "all/comments/"+path, "Comment", level, 
341           "View statistics of comment lines");
342    os << "</li>";
343
344
345    if (item=="empty")
346      os << "<li class=\"highlight\">";
347    else
348      os << "<li>";
349    anchor(os, "all/empty/"+path, "Empty", level, 
350           "View statistics of empty lines");
351    os << "</li>"
352       << "</ul></div>"
353       << "<div id=\"main\">\n";
354  }
355
356
357}} // end of namespace svndigest and namespace theplu
Note: See TracBrowser for help on using the repository browser.