Fawkes API  Fawkes Development Version
tracwiki.cpp
00001 
00002 /***************************************************************************
00003  *  tracwiki.cpp - Trac wiki style formatter
00004  *
00005  *  Created: Wed May 11 17:04:04 2011
00006  *  Copyright  2006-2011  Tim Niemueller [www.niemueller.de]
00007  *
00008  ****************************************************************************/
00009 
00010 /*  This program is free software; you can redistribute it and/or modify
00011  *  it under the terms of the GNU General Public License as published by
00012  *  the Free Software Foundation; either version 2 of the License, or
00013  *  (at your option) any later version.
00014  *
00015  *  This program is distributed in the hope that it will be useful,
00016  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018  *  GNU Library General Public License for more details.
00019  *
00020  *  Read the full text in the LICENSE.GPL file in the doc directory.
00021  */
00022 
00023 #include <webview/formatters/tracwiki.h>
00024 
00025 #include <core/exception.h>
00026 #include <sstream>
00027 #include <cstring>
00028 #include <cstdio>
00029 
00030 namespace fawkes {
00031 #if 0 /* just to make Emacs auto-indent happy */
00032 }
00033 #endif
00034 
00035 /** @class TracWikiHeadingFormatter <webview/formatters/tracwiki.h>
00036  * Translate Trac wiki heading syntax to HTML.
00037  * This class translates Trac wiki style heading identifications and
00038  * translates them into HTML.
00039  * @author Tim Niemueller
00040  */
00041 
00042 
00043 /** Constructor. */
00044 TracWikiHeadingFormatter::TracWikiHeadingFormatter()
00045 {
00046   if ( regcomp(&__re_heading, "^(=+) (.*) \\1$", REG_EXTENDED) != 0 ) {
00047     throw Exception("Failed to compile heading regex");
00048   }
00049 
00050 }
00051 
00052 
00053 /** Destructor. */
00054 TracWikiHeadingFormatter::~TracWikiHeadingFormatter()
00055 {
00056   regfree(&__re_heading);
00057 }
00058 
00059 
00060 /** Format string.
00061  * @param text input text in Trac wiki markup language
00062  * @return formatted text
00063  */
00064 std::string
00065 TracWikiHeadingFormatter::format(std::string &text)
00066 {
00067   std::string rv = "";
00068 
00069   bool in_paragraph = false;
00070 
00071   std::istringstream iss(text);
00072   while (!iss.eof() && !iss.fail()) {
00073     std::string line;
00074     getline(iss, line);
00075     const char *sl = line.c_str();
00076 
00077     int num_matches = 3;
00078     regmatch_t matches[num_matches];
00079 
00080     if (line == "") {
00081       if (in_paragraph) {
00082         rv += "</p>\n";
00083         in_paragraph = false;
00084       }
00085     } else if (regexec(&__re_heading, sl, num_matches, matches, 0) == 0) {
00086       unsigned int h_depth = matches[1].rm_eo - matches[1].rm_so;
00087 
00088       if (in_paragraph) {
00089         rv += "</p>\n";
00090         in_paragraph = false;
00091       }
00092 
00093       char title[matches[2].rm_eo - matches[2].rm_so + 1];
00094       title[matches[2].rm_eo - matches[2].rm_so] = 0;
00095       strncpy(title, &line.c_str()[matches[2].rm_so],
00096               matches[2].rm_eo - matches[2].rm_so);
00097       char *tmp;
00098       if (asprintf(&tmp, "<h%u>%s</h%u>\n", h_depth, title, h_depth) != -1) {
00099         rv += tmp;
00100       } else {
00101         rv += line;
00102       }
00103     } else {
00104       if (!in_paragraph) {
00105         rv += "<p>";
00106         in_paragraph = true;
00107       }
00108       rv += line;
00109     }
00110   }
00111 
00112   if (in_paragraph) {
00113     rv += "</p>\n";
00114     in_paragraph = false;
00115   }
00116 
00117   return rv;
00118 }
00119 
00120 } // end namespace fawkes