PLearn 0.1
|
00001 // -*- C++ -*- 00002 00003 // HTMLUtils.cc 00004 // 00005 // Copyright (C) 2004-2006 Nicolas Chapados 00006 // Copyright (C) 2007 Xavier Saint-Mleux, ApSTAT Technologies, inc. 00007 // 00008 // Redistribution and use in source and binary forms, with or without 00009 // modification, are permitted provided that the following conditions are met: 00010 // 00011 // 1. Redistributions of source code must retain the above copyright 00012 // notice, this list of conditions and the following disclaimer. 00013 // 00014 // 2. Redistributions in binary form must reproduce the above copyright 00015 // notice, this list of conditions and the following disclaimer in the 00016 // documentation and/or other materials provided with the distribution. 00017 // 00018 // 3. The name of the authors may not be used to endorse or promote 00019 // products derived from this software without specific prior written 00020 // permission. 00021 // 00022 // THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR 00023 // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 00024 // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN 00025 // NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 00026 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 00027 // TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00028 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 00029 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00030 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00031 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00032 // 00033 // This file is part of the PLearn library. For more information on the PLearn 00034 // library, go to the PLearn Web site at www.plearn.org 00035 00036 // Authors: Xavier Saint-Mleux 00037 00041 #include <plearn/base/Object.h> 00042 00043 #include "HTMLUtils.h" 00044 00045 #include <plearn/base/stringutils.h> 00046 #include <plearn/base/tostring.h> 00047 #include <boost/regex.hpp> 00048 #include <commands/PLearnCommands/plearn_main.h> 00049 #include <plearn/base/TypeFactory.h> 00050 #include <plearn/base/OptionBase.h> 00051 00052 namespace PLearn { 00053 using namespace std; 00054 00055 string HTMLUtils::quote(string s) 00056 { 00057 #ifndef __INTEL_COMPILER 00058 search_replace(s, "&", "&"); 00059 search_replace(s, "<", "<"); 00060 search_replace(s, ">", ">"); 00061 search_replace(s, "\"", """); 00062 #endif 00063 return s; 00064 } 00065 00066 string HTMLUtils::highlight_known_classes(string typestr) 00067 { 00068 #ifndef __INTEL_COMPILER 00069 vector<string> tokens = split(typestr, " \t\n\r<>,.';:\""); 00070 set<string> replaced; // Carry out replacements for a given token only once 00071 const TypeMap& type_map = TypeFactory::instance().getTypeMap(); 00072 vector<string>::size_type n=tokens.size(); 00073 for (unsigned int i=0; i<n ; ++i) { 00074 TypeMap::const_iterator it = type_map.find(tokens[i]); 00075 if (it != type_map.end() && replaced.find(tokens[i]) == replaced.end()) { 00076 replaced.insert(tokens[i]); 00077 00078 // ensure we only match whole words with the regular expression 00079 const boost::regex e("\\<" + tokens[i] + "\\>"); 00080 const string repl_str("<a href=\"class_$&.html\\?level=" 00081 + tostring(OptionBase::getCurrentOptionLevel()) 00082 +"\">$&</a>"); 00083 typestr = regex_replace(typestr, e, repl_str, boost::match_default | boost::format_default); 00084 } 00085 } 00086 #endif 00087 return typestr; 00088 } 00089 00090 string HTMLUtils::format_free_text(string text) 00091 { 00092 // sort of DWIM HTML formatting for free-text; cannot use split since it 00093 // eats up consecutive delimiters 00094 text = removeblanks(text); 00095 size_t curpos = 0, curnl = text.find('\n'); 00096 bool ul_active = false; 00097 bool start_paragraph = false; 00098 string finallines; 00099 #ifndef __INTEL_COMPILER 00100 for ( ; curpos != string::npos ; 00101 curpos = curnl+(curnl!=string::npos), curnl = text.find('\n', curpos) ) { 00102 string curline = text.substr(curpos, curnl-curpos); 00103 00104 // step 1: check if the line starts with a '-': if so, start a new <UL> 00105 // if not in one, or extend one if so 00106 if (removeblanks(curline).substr(0,1) == "-" || 00107 removeblanks(curline).substr(0,1) == "*" ) 00108 { 00109 curline = removeblanks(curline).substr(1); 00110 if (! ul_active) 00111 curline = "<ul><li>" + curline; 00112 else 00113 curline = "<li>" + curline; 00114 start_paragraph = false; 00115 ul_active = true; 00116 } 00117 00118 // otherwise, a line that starts with some whitespace within a list 00119 // just extends the previous <li> :: don't touch it 00120 else if (ul_active && (curline == "" || 00121 curline.substr(0,1) == " " || 00122 curline.substr(0,1) == "\t")) { 00123 /* do nothing */ 00124 } 00125 00126 // otherwise, normal processing 00127 else { 00128 // any line that is empty or starts with some whitespace gets its own <br> 00129 if (removeblanks(curline) == "") { 00130 // Don't start new paragraph right away; wait until we 00131 // encounter some text that's neither a <ul> or a <pre> 00132 start_paragraph = true; 00133 curline = ""; 00134 } 00135 else if (curline[0] == ' ' || curline[0] == '\t') { 00136 start_paragraph = false; 00137 curline = "<pre>" + curline + "</pre>"; 00138 } 00139 00140 // if we were processing a list, close it first 00141 if (ul_active) { 00142 curline = "</ul>" + curline; 00143 ul_active = 0; 00144 } 00145 } 00146 00147 if (!curline.empty() && start_paragraph) { 00148 finallines += "<p>"; 00149 start_paragraph = false; 00150 } 00151 00152 finallines += curline + "\n"; 00153 } 00154 00155 // Close any pending open blocks 00156 if (ul_active) 00157 finallines += "</ul>\n"; 00158 00159 // Finally join the lines 00160 #endif 00161 return make_http_hyperlinks(finallines); 00162 } 00163 00164 string HTMLUtils::make_http_hyperlinks(string text) 00165 { 00166 #ifndef __INTEL_COMPILER 00167 // Find elements of the form XYZ://x.y.z/a/b/c and make them into 00168 // hyperlink. An issue is to determine when 00169 static const char* recognized_protocols[] = 00170 { "http://", "https://", "ftp://", "mailto:" }; // for now... 00171 static const vector<string> protocols_vector( 00172 recognized_protocols, 00173 recognized_protocols + sizeof(recognized_protocols) / sizeof(recognized_protocols[0])); 00174 00175 // Match everything that starts with the recognized protocol up to the 00176 // following whitespace, excluding trailing punctuation if any. 00177 // Make sure the URL is NOT enclosed in quotes 00178 static const boost::regex e( string("(?!\")") + "(" + 00179 "(?:" + join(protocols_vector, "|") + ")" + 00180 "\\S+(?:\\w|/)" + 00181 ")" + "(?!\")" + "([[:punct:]]*\\s|$)"); 00182 00183 const string repl_str("<a href=\"$1\?level=" 00184 + tostring(OptionBase::getCurrentOptionLevel()) 00185 +"\">$1</a>$2"); 00186 text = regex_replace(text, e, repl_str, boost::match_default | boost::format_default); 00187 #endif 00188 return text; 00189 } 00190 00191 string HTMLUtils::generated_by() 00192 { 00193 time_t curtime = time(NULL); 00194 struct tm *broken_down_time = localtime(&curtime); 00195 const int SIZE = 100; 00196 char time_buffer[SIZE]; 00197 strftime(time_buffer,SIZE,"%Y/%m/%d %H:%M:%S",broken_down_time); 00198 00199 return string("<p> </p><address>Generated on " ) + 00200 time_buffer + " by " + version_string() + "</address>"; 00201 } 00202 00203 } // end of namespace PLearn 00204 00205 00206 /* 00207 Local Variables: 00208 mode:c++ 00209 c-basic-offset:4 00210 c-file-style:"stroustrup" 00211 c-file-offsets:((innamespace . 0)(inline-open . 0)) 00212 indent-tabs-mode:nil 00213 fill-column:79 00214 End: 00215 */ 00216 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=79 :