Logo Search packages:      
Sourcecode: highlight version File versions  Download package

htmlgenerator.cpp

/***************************************************************************
                     htmlgenerator.cpp  -  description
                             -------------------
    begin                : Wed Nov 28 2001
    copyright            : (C) 2001-2007 by Andre Simon
    email                : andre.simon1@gmx.de
 ***************************************************************************/


/*
This file is part of Highlight.

Highlight is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

Highlight is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with Highlight.  If not, see <http://www.gnu.org/licenses/>.
*/


#include <fstream>
#include <iostream>
#include <sstream>

#include "htmlgenerator.h"
#include "version.h"

using namespace std;

namespace highlight
{

      HtmlGenerator::HtmlGenerator () :
                  CodeGenerator ( HTML ),
                  brTag ( "<br>" ),
                  hrTag ( "<hr>" ),
                  idAttr ( "name" ),
                  fileSuffix ( ".html" ),
                  cssClassName ( "hl" ),
                  orderedList ( false ),
                  useInlineCSS ( false ),
                  enclosePreTag ( false ),
                  attachAnchors ( false ),
                  anchorPrefix ( "l" )
      {
            spacer = " ";
            styleCommentOpen="/*";
            styleCommentClose="*/";
      }

00058       bool HtmlGenerator::initTheme ( const string& themePath )
      {
            bool result = CodeGenerator::initTheme ( themePath );

            styleTagOpen.push_back ( "" );
            if ( useInlineCSS )
            {
                  styleTagOpen.push_back ( getOpenTag ( docStyle.getStringStyle() ) );
                  styleTagOpen.push_back ( getOpenTag ( docStyle.getNumberStyle() ) );
                  styleTagOpen.push_back ( getOpenTag ( docStyle.getSingleLineCommentStyle() ) );
                  styleTagOpen.push_back ( getOpenTag ( docStyle.getCommentStyle() ) );
                  styleTagOpen.push_back ( getOpenTag ( docStyle.getEscapeCharStyle() ) );
                  styleTagOpen.push_back ( getOpenTag ( docStyle.getDirectiveStyle() ) );
                  styleTagOpen.push_back ( getOpenTag ( docStyle.getDirectiveStringStyle() ) );
                  styleTagOpen.push_back ( getOpenTag ( docStyle.getLineStyle() ) );
                  styleTagOpen.push_back ( getOpenTag ( docStyle.getSymbolStyle() ) );
            }
            else
            {
                  styleTagOpen.push_back ( getOpenTag ( "str" ) );
                  styleTagOpen.push_back ( getOpenTag ( "num" ) );
                  styleTagOpen.push_back ( getOpenTag ( "slc" ) );
                  styleTagOpen.push_back ( getOpenTag ( "com" ) );
                  styleTagOpen.push_back ( getOpenTag ( "esc" ) );
                  styleTagOpen.push_back ( getOpenTag ( "dir" ) );
                  styleTagOpen.push_back ( getOpenTag ( "dstr" ) );
                  styleTagOpen.push_back ( getOpenTag ( "line" ) );
                  styleTagOpen.push_back ( getOpenTag ( "sym" ) );
            }

            styleTagClose.push_back ( "" );
            for ( int i=1;i<NUMBER_BUILTIN_STATES; i++ )
            {
                  styleTagClose.push_back ( "</span>" );
            }
            return result;
      }

00096       string  HtmlGenerator::getAttributes ( const string & elemName, const ElementStyle & elem )
      {
            ostringstream s;
            if ( !elemName.empty() )
            {
                  s << "."<<cssClassName<<"."<<elemName<<" { ";
            }
            s << "color:#"
            << ( elem.getColour().getRed ( HTML ) )
            << ( elem.getColour().getGreen ( HTML ) )
            << ( elem.getColour().getBlue ( HTML ) )
            << ( elem.isBold() ?     "; font-weight:bold" :"" )
            << ( elem.isItalic() ?   "; font-style:italic" :"" )
            << ( elem.isUnderline() ? "; text-decoration:underline" :"" );
            if ( !elemName.empty() )
            {
                  s << "; }\n" ;
            }
            return s.str();
      }

00117       string  HtmlGenerator::getOpenTag ( const string& styleName )
      {
            return "<span class=\""+cssClassName+ " " + styleName + "\">";
      }

      string  HtmlGenerator::getOpenTag ( const ElementStyle & elem )
      {
            return "<span style=\""+getAttributes ( "",elem ) + "\">";
      }

00127       string HtmlGenerator::getGeneratorComment()
      {
            ostringstream s;
            s <<"\n</body>\n</html>\n<!--HTML generated by highlight "
            << HIGHLIGHT_VERSION << ", " <<  HIGHLIGHT_URL <<"-->\n";

            return s.str();
      }

00136       string HtmlGenerator::getStyleDefinition()
      {
            if ( styleDefinitionCache.empty() )
            {
                  ostringstream os;
                  os << "body."<<cssClassName<<"\t{ background-color:#"
                  << ( docStyle.getBgColour().getRed ( HTML ) )
                  << ( docStyle.getBgColour().getGreen ( HTML ) )
                  << ( docStyle.getBgColour().getBlue ( HTML ) )
                  << "; }\n";
                  os << "pre."<<cssClassName<<"\t{ color:#"
                  << ( docStyle.getDefaultStyle().getColour().getRed ( HTML ) )
                  << ( docStyle.getDefaultStyle().getColour().getGreen ( HTML ) )
                  << ( docStyle.getDefaultStyle().getColour().getBlue ( HTML ) )
                  << "; background-color:#"
                  << ( docStyle.getBgColour().getRed ( HTML ) )
                  << ( docStyle.getBgColour().getGreen ( HTML ) )
                  << ( docStyle.getBgColour().getBlue ( HTML ) )
                  << "; font-size:" << this->getBaseFontSize();

                  os << "pt; font-family:'" << this->getBaseFont() << "';}\n";

                  if ( orderedList )
                  {
                        os << "li."<<cssClassName<<"\t{ margin-bottom:-"<<this->getBaseFontSize() <<"pt; }\n";
                  }

                  os << getAttributes ( "num", docStyle.getNumberStyle() )
                  << getAttributes ( "esc", docStyle.getEscapeCharStyle() )
                  << getAttributes ( "str", docStyle.getStringStyle() )
                  << getAttributes ( "dstr", docStyle.getDirectiveStringStyle() )
                  << getAttributes ( "slc", docStyle.getSingleLineCommentStyle() )
                  << getAttributes ( "com", docStyle.getCommentStyle() )
                  << getAttributes ( "dir", docStyle.getDirectiveStyle() )
                  << getAttributes ( "sym", docStyle.getSymbolStyle() )
                  << getAttributes ( "line", docStyle.getLineStyle() );

                  os << "."<<cssClassName<<".mark\t{ background-color:#"
                  << ( docStyle.getMarkLineColour().getRed ( HTML ) )
                  << ( docStyle.getMarkLineColour().getGreen ( HTML ) )
                  << ( docStyle.getMarkLineColour().getBlue ( HTML ) )
                  << ";}\n";

                  KeywordStyles styles = docStyle.getKeywordStyles();
                  for ( KSIterator it=styles.begin(); it!=styles.end(); it++ )
                  {
                        os << getAttributes ( it->first, it->second );
                  }
                  styleDefinitionCache=os.str();
            }
            return styleDefinitionCache;
      }

00189       string HtmlGenerator::getHeader()
      {
            ostringstream os;
            os << getHeaderStart ( docTitle );
            if ( !useInlineCSS )
            {
                  if ( includeStyleDef )
                  {
                        os << "<style type=\"text/css\">\n<!--\n";
                        os << getStyleDefinition();
                        os << CodeGenerator::readUserStyleDef();
                        os << "//-->\n</style>\n";
                  }
                  else
                  {
                        os << "<link rel=\"stylesheet\" type=\"text/css\" href=\""
                        << getStyleOutputPath()
                        << "\">\n";
                  }
                  os << "</head>\n<body class=\"" << cssClassName
                  << "\">\n";
            }
            else
            {
                  os << "</head>\n<body style=\""
                  << "background-color:#"
                  << ( docStyle.getBgColour().getRed ( HTML ) )
                  << ( docStyle.getBgColour().getGreen ( HTML ) )
                  << ( docStyle.getBgColour().getBlue ( HTML ) )
                  << "\">\n";
            }

            return os.str();
      }

00224       string HtmlGenerator::getFooter()
      {
            return getGeneratorComment();
      }

00229       void HtmlGenerator::printBody()
      {
            if ( !fragmentOutput || enclosePreTag )
            {
                  if ( !useInlineCSS )
                  {
                        *out << "<pre class=\"" << cssClassName
                        << "\">";
                  }
                  else
                  {
                        *out << "<pre style=\""
                        << "color:#"
                        << ( docStyle.getDefaultStyle().getColour().getRed ( HTML ) )
                        << ( docStyle.getDefaultStyle().getColour().getGreen ( HTML ) )
                        << ( docStyle.getDefaultStyle().getColour().getBlue ( HTML ) )
                        << "; background-color:#"
                        << ( docStyle.getBgColour().getRed ( HTML ) )
                        << ( docStyle.getBgColour().getGreen ( HTML ) )
                        << ( docStyle.getBgColour().getBlue ( HTML ) )
                        << "; font-size:" << this->getBaseFontSize()
                        << "pt; font-family:'" << this->getBaseFont() <<"';\">";
                  }
            }
            if ( showLineNumbers && orderedList ) *out << "<ol>";

            processRootState();

            if ( showLineNumbers && orderedList ) *out << "\n</ol>";

            if ( !fragmentOutput || enclosePreTag )  *out << "</pre>";
      }

00262       string HtmlGenerator::maskCharacter ( unsigned char c )
      {
            switch ( c )
            {
                  case '<' :
                        return "&lt;";
                        break;
                  case '>' :
                        return "&gt;";
                        break;
                  case '&' :
                        return "&amp;";
                        break;
                  case '\"' :
                        return "&quot;";
                        break;

                  case '@' :
                        return "&#64;";
                        break;

                  default :
                        return string ( 1, c );
            }
      }

00288       string HtmlGenerator::getNewLine()
      {

            string nlStr;

            if ( markLines.count ( lineNumber-1 ) ) nlStr +="</span>";

            if ( showLineNumbers && orderedList ) nlStr +="</li>";
            /// set wrapping arrow if previous line was wrapped
            //else if (preFormatter.isWrappedLine(lineNumber-1)) nlStr += "&crarr;";

            nlStr+="\n";
            return nlStr;
      }

00303       void HtmlGenerator::insertLineNumber ( bool insertNewLine )
      {
            if ( insertNewLine )
            {
                  wsBuffer += getNewLine();
            }
            if ( showLineNumbers )
            {
                  ostringstream numberPrefix;
                  int lineNo = lineNumber+lineNumberOffset;
                  if ( orderedList )
                  {
                        if ( useInlineCSS )
                        {
                              numberPrefix<<"<li style=\""<<getAttributes ( "", docStyle.getLineStyle() ) <<"\">";
                        }
                        else
                        {
                              numberPrefix<<"<li class=\""<<cssClassName<<"\">";
                        }
                        // Opera 8 ignores empty list items -> add &nbsp;
                        if ( line.empty() ) numberPrefix<<"&nbsp;";
                  }
                  if ( attachAnchors )
                        numberPrefix << "<a "
                        << idAttr
                        << "=\""
                        << anchorPrefix
                        << "_"
                        << lineNo
                        << "\"></a>";

                  if ( !orderedList )
                  {
                        ostringstream os;
                        if ( lineNumberFillZeroes ) os.fill ( '0' );
                        os <<setw ( getLineNumberWidth() ) <<right<< lineNo;
                        numberPrefix << styleTagOpen[LINENUMBER]
                        << os.str()
                        << spacer
                        << styleTagClose[LINENUMBER];
                  }
                  wsBuffer += numberPrefix.str();
            }

            if ( markLines.count ( lineNumber ) )
            {
                  if ( useInlineCSS )
                  {
                        ostringstream markingFmt;
                        markingFmt <<"<span style=\""
                        <<"background-color:#"
                        << ( docStyle.getMarkLineColour().getRed ( HTML ) )
                        << ( docStyle.getMarkLineColour().getGreen ( HTML ) )
                        << ( docStyle.getMarkLineColour().getBlue ( HTML ) )
                        << ";\"";
                        wsBuffer+=markingFmt.str();
                  }
                  else
                  {
                        wsBuffer +="<span class=\""+cssClassName+" mark\"";
                  }
                  if ( !markLines[lineNumber].empty() )
                        wsBuffer +=" title=\""+markLines[lineNumber]+"\"";
                  wsBuffer +=">";
            }

      }

00372       string HtmlGenerator::getHeaderStart ( const string &title )
      {
            ostringstream header;
            header<<  "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\">"
            << "\n<html>\n<head>\n";
            if ( encodingDefined() )
            {
                  header << "<meta http-equiv=\"content-type\" content=\"text/html; charset="
                  << encoding
                  << "\">\n";
            }
            header << "<title>"
            << title
            << "</title>\n";
            return header.str();
      }

00389       bool HtmlGenerator::printIndexFile ( const vector<string> &fileList,
                                           const string &outPath )
      {
            string suffix = fileSuffix;
            string outFilePath = outPath + "index" + suffix;
            ofstream indexfile ( outFilePath.c_str() );

            if ( !indexfile.fail() )
            {
                  string inFileName;
                  string inFilePath, newInFilePath;
                  indexfile << getHeaderStart ( "Source Index" );
                  indexfile << "</head>\n<body>\n<h1> Source Index</h1>\n"
                  << hrTag
                  <<  "\n<ul>\n";
                  string::size_type pos;
                  for ( unsigned int i=0; i < fileList.size();  i++ )
                  {
                        pos= ( fileList[i] ).find_last_of ( Platform::pathSeparator );
                        if ( pos!=string::npos )
                        {
                              newInFilePath = ( fileList[i] ).substr ( 0, pos+1 );
                        }
                        else
                        {
                              newInFilePath=Platform::pathSeparator;
                        }
                        if ( newInFilePath!=inFilePath )
                        {
                              indexfile << "</ul>\n<h2>";
                              indexfile << newInFilePath;
                              indexfile << "</h2>\n<ul>\n";
                              inFilePath=newInFilePath;
                        }
                        inFileName = ( fileList[i] ).substr ( pos+1 );
                        indexfile << "<li><a href=\"" << inFileName << suffix << "\">";
                        indexfile << inFileName << suffix <<"</a></li>\n";
                  }

                  indexfile << "</ul>\n"
                  << hrTag << brTag
                  << "<small>Generated by highlight "
                  << HIGHLIGHT_VERSION
                  << ", <a href=\"" << HIGHLIGHT_URL << "\" target=\"new\">"
                  << HIGHLIGHT_URL << "</a></small>";
                  indexfile << getGeneratorComment();
            }
            else
            {
                  return false;
            }
            return true;
      }

00443       string HtmlGenerator::getMatchingOpenTag ( unsigned int styleID )
      {
            if ( useInlineCSS )
            {
                  return getOpenTag ( docStyle.getKeywordStyle ( langInfo.getKeywordClasses() [styleID] ) );
            }
            return getOpenTag ( langInfo.getKeywordClasses() [styleID] );
      }

00452       string HtmlGenerator::getMatchingCloseTag ( unsigned int styleID )
      {
            return "</span>";
      }

00457       string  HtmlGenerator::getMetaInfoOpenTag ( const TagInfo& info )
      {
            ostringstream tagStream;
            tagStream<<"<span title=\""<<info.getKind() <<" | ";
            if ( !info.name_space.empty() )
            {
                  maskString ( tagStream, info.name_space );
                  tagStream<<" | ";
            }
            maskString ( tagStream, info.file ) ;
            tagStream<<"\">";
            return tagStream.str();
      }
00470       string  HtmlGenerator::getMetaInfoCloseTag()
      {
            return "</span>";
      }

}

Generated by  Doxygen 1.6.0   Back to index