diff options
47 files changed, 2997 insertions, 877 deletions
diff --git a/src/classdef.cpp b/src/classdef.cpp index 1584094..fa555ac 100644 --- a/src/classdef.cpp +++ b/src/classdef.cpp @@ -925,10 +925,7 @@ static void writeTemplateSpec(OutputList &ol,Definition *d, if (a) ol.docify(", "); } ol.docify(">"); - ol.pushGeneratorState(); - ol.disableAllBut(OutputGenerator::Html); ol.lineBreak(); - ol.popGeneratorState(); } ol.docify(type.lower()+" "+name); ol.endSubsubsection(); diff --git a/src/config.l b/src/config.l index bda3c6a..2a16905 100644 --- a/src/config.l +++ b/src/config.l @@ -1119,14 +1119,15 @@ void Config::check() QCString &paperType = Config_getEnum("PAPER_TYPE"); paperType=paperType.lower().stripWhiteSpace(); - if (paperType.isEmpty()) + if (paperType.isEmpty() || paperType=="a4wide") { paperType = "a4"; } - if (paperType!="a4" && paperType!="a4wide" && paperType!="letter" && + if (paperType!="a4" && paperType!="letter" && paperType!="legal" && paperType!="executive") { config_err("Unknown page type specified\n"); + paperType="a4"; } QCString &outputLanguage=Config_getEnum("OUTPUT_LANGUAGE"); @@ -1198,6 +1199,12 @@ void Config::check() exit(1); } } + QCString &path = Config_getString("MATHJAX_RELPATH"); + if (!path.isEmpty() && path.at(path.length()-1)!='/') + { + path+="/"; + } + } // Test to see if LaTeX header is valid diff --git a/src/context.cpp b/src/context.cpp index e7c14d5..8f9200e 100644 --- a/src/context.cpp +++ b/src/context.cpp @@ -35,6 +35,8 @@ #include "docparser.h" #include "htmlgen.h" #include "htmldocvisitor.h" +#include "latexgen.h" +#include "latexdocvisitor.h" #include "dot.h" #include "diagram.h" #include "example.h" @@ -43,27 +45,30 @@ #include "portable.h" #include "arguments.h" #include "groupdef.h" +#include "searchindex.h" // TODO: pass the current file to Dot*::writeGraph, so the user can put dot graphs in other // files as well #define ADD_PROPERTY(name) addProperty(#name,this,&Private::name); +enum ContextOutputFormat +{ + ContextOutputFormat_Unspecified=0, + ContextOutputFormat_Html, + ContextOutputFormat_Latex, + ContextOutputFormat_Rtf, + ContextOutputFormat_ManPage, + ContextOutputFormat_DocBook, + ContextOutputFormat_Xml, + ContextOutputFormat_TagFile +}; + struct ContextGlobals { - enum OutputFormat - { - Html, - LateX, - Rtf, - ManPage, - DocBook, - Xml, - TagFile - }; - int dynSectionId; - QCString outputDir; - OutputFormat outputFormat; + int dynSectionId; + QCString outputDir; + ContextOutputFormat outputFormat; } g_globals; /** @brief Scoped smart pointer */ @@ -367,7 +372,11 @@ class DoxygenContext::Private : public PropertyMapper } TemplateVariant date() const { - return TemplateVariant(dateToString(TRUE)); + return dateToString(TRUE); + } + TemplateVariant maxJaxCodeFile() const + { + return m_cache.maxJaxCodeFile; } Private() { @@ -375,7 +384,16 @@ class DoxygenContext::Private : public PropertyMapper addProperty("version",this,&Private::version); //makeProperty(this,&Private::version)); //%% string date addProperty("date", this,&Private::date); + //%% string maxJaxCodeFile + addProperty("mathJaxCodeFile", this,&Private::maxJaxCodeFile); } + private: + struct Cachable + { + Cachable() { maxJaxCodeFile=fileToString(Config_getString("MATHJAX_CODEFILE")); } + QCString maxJaxCodeFile; + }; + mutable Cachable m_cache; }; //%% } @@ -438,6 +456,18 @@ class TranslateContext::Private : public PropertyMapper } return TemplateVariant(); } + TemplateVariant handleDirDependencyGraphFor(const QValueList<TemplateVariant> &args) const + { + if (args.count()==1) + { + return theTranslator->trDirDepGraph(args[0].toString()); + } + else + { + err("tr.dirDependencyGraphFor should take one argument, got %d!\n",args.count()); + } + return TemplateVariant(); + } TemplateVariant handleInheritsList(const QValueList<TemplateVariant> &args) const { if (args.count()==1) @@ -553,6 +583,10 @@ class TranslateContext::Private : public PropertyMapper { return TemplateVariant::Delegate::fromMethod<Private,&Private::handleCollaborationDiagramFor>(this); } + TemplateVariant dirDependencyGraphFor() const + { + return TemplateVariant::Delegate::fromMethod<Private,&Private::handleDirDependencyGraphFor>(this); + } TemplateVariant search() const { return theTranslator->trSearch(); @@ -579,6 +613,10 @@ class TranslateContext::Private : public PropertyMapper { return theTranslator->trCompoundIndex(); } + TemplateVariant namespaceIndex() const + { + return theTranslator->trNamespaceIndex(); + } TemplateVariant classHierarchy() const { return theTranslator->trClassHierarchy(); @@ -591,6 +629,10 @@ class TranslateContext::Private : public PropertyMapper { return theTranslator->trModules(); } + TemplateVariant moduleIndex() const + { + return theTranslator->trModuleIndex(); + } TemplateVariant namespaces() const { if (m_javaOpt || m_vhdlOpt) @@ -610,6 +652,10 @@ class TranslateContext::Private : public PropertyMapper { return theTranslator->trFile(TRUE,FALSE); } + TemplateVariant fileIndex() const + { + return theTranslator->trFileIndex(); + } TemplateVariant pages() const { return theTranslator->trRelatedPages(); @@ -648,6 +694,14 @@ class TranslateContext::Private : public PropertyMapper return theTranslator->trNamespaceMembers(); } } + TemplateVariant moduleDocumentation() const + { + return theTranslator->trModuleDocumentation(); + } + TemplateVariant fileDocumentation() const + { + return theTranslator->trFileDocumentation(); + } TemplateVariant fileList() const { return theTranslator->trFileList(); @@ -815,6 +869,10 @@ class TranslateContext::Private : public PropertyMapper { return theTranslator->trClassDocumentation(); } + TemplateVariant namespaceDocumentation() const + { + return theTranslator->trNamespaceDocumentation(); + } TemplateVariant compoundMembers() const { return theTranslator->trCompoundMembers(); @@ -882,10 +940,46 @@ class TranslateContext::Private : public PropertyMapper { return theTranslator->trDefines(); } + TemplateVariant loading() const + { + return theTranslator->trLoading(); + } + TemplateVariant searching() const + { + return theTranslator->trSearching(); + } + TemplateVariant noMatches() const + { + return theTranslator->trNoMatches(); + } + TemplateVariant enumName() const + { + return theTranslator->trEnumName(); + } + TemplateVariant enumValue() const + { + return theTranslator->trEnumValue(); + } + TemplateVariant referenceManual() const + { + return theTranslator->trReferenceManual(); + } + TemplateVariant index() const + { + return theTranslator->trRTFGeneralIndex(); + } + TemplateVariant panelSyncOn() const + { + return theTranslator->trPanelSynchronisationTooltip(FALSE); + } + TemplateVariant panelSyncOff() const + { + return theTranslator->trPanelSynchronisationTooltip(TRUE); + } Private() { //%% string generatedBy - addProperty("generatedby", this,&Private::generatedBy); + addProperty("generatedBy", this,&Private::generatedBy); //%% string generatedAt addProperty("generatedAt", this,&Private::generatedAt); //%% string search @@ -900,6 +994,8 @@ class TranslateContext::Private : public PropertyMapper addProperty("classListDescription", this,&Private::classListDescription); //%% string classIndex addProperty("classIndex", this,&Private::classIndex); + //%% string namespaceIndex + addProperty("namespaceIndex", this,&Private::namespaceIndex); //%% string classHierarchy addProperty("classHierarchy", this,&Private::classHierarchy); //%% string classMembers @@ -908,8 +1004,12 @@ class TranslateContext::Private : public PropertyMapper addProperty("classMembersDescription",this,&Private::classMembersDescription); //%% string modules addProperty("modules", this,&Private::modules); + //%% string moduleIndex + addProperty("moduleIndex", this,&Private::moduleIndex); //%% string namespaces addProperty("namespaces", this,&Private::namespaces); + //%% string fileIndex + addProperty("fileIndex", this,&Private::fileIndex); //%% string files addProperty("files", this,&Private::files); //%% string pages @@ -990,6 +1090,12 @@ class TranslateContext::Private : public PropertyMapper addProperty("constantgroups", this,&Private::constantgroups); //%% string classDocumentation addProperty("classDocumentation", this,&Private::classDocumentation); + //%% string namespaceDocumentation + addProperty("namespaceDocumentation", this,&Private::namespaceDocumentation); + //%% string moduleDocumentation + addProperty("moduleDocumentation",this,&Private::moduleDocumentation); + //%% string fileDocumentation + addProperty("fileDocumentation", this,&Private::fileDocumentation); //%% string compoundMembers addProperty("compoundMembers", this,&Private::compoundMembers); //%% string detailLevel @@ -1000,7 +1106,7 @@ class TranslateContext::Private : public PropertyMapper addProperty("namespaceListDescription",this,&Private::namespaceListDescription); //%% string directories addProperty("directories", this,&Private::directories); - //%% string moduleDescript + //%% string moduleDescription addProperty("modulesDescription", this,&Private::modulesDescription); //%% string all addProperty("all", this,&Private::all); @@ -1030,6 +1136,26 @@ class TranslateContext::Private : public PropertyMapper addProperty("gotoGraphicalHierarchy",this,&Private::gotoGraphicalHierarchy); //%% string gotoTextualHierarchy addProperty("gotoTextualHierarchy",this,&Private::gotoTextualHierarchy); + //%% string loading + addProperty("loading", this,&Private::loading); + //%% string searching + addProperty("searching", this,&Private::searching); + //%% string noMatches + addProperty("noMatches", this,&Private::noMatches); + //%% string enumValue + addProperty("enumValue", this,&Private::enumValue); + //%% string enumName + addProperty("enumName", this,&Private::enumName); + //%% string referenceManual + addProperty("referenceManual", this,&Private::referenceManual); + //%% string index + addProperty("index", this,&Private::index); + //%% string panelSyncOn + addProperty("panelSyncOn", this,&Private::panelSyncOn); + //%% string panelSyncOff + addProperty("panelSyncOff", this,&Private::panelSyncOff); + //%% string dirDependencyGraph + addProperty("dirDependencyGraphFor", this,&Private::dirDependencyGraphFor); m_javaOpt = Config_getBool("OPTIMIZE_OUTPUT_JAVA"); m_fortranOpt = Config_getBool("OPTIMIZE_FOR_FORTRAN"); @@ -1065,10 +1191,27 @@ static TemplateVariant parseDoc(Definition *def,const QCString &file,int line, QGString docs; { FTextStream ts(&docs); - // TODO: support other generators - HtmlCodeGenerator codeGen(ts,relPath); - HtmlDocVisitor visitor(ts,codeGen,def); - root->accept(&visitor); + switch (g_globals.outputFormat) + { + case ContextOutputFormat_Html: + { + HtmlCodeGenerator codeGen(ts,relPath); + HtmlDocVisitor visitor(ts,codeGen,def); + root->accept(&visitor); + } + break; + case ContextOutputFormat_Latex: + { + LatexCodeGenerator codeGen(ts,relPath,file); + LatexDocVisitor visitor(ts,codeGen,def->getDefFileExtension(),FALSE); + root->accept(&visitor); + } + break; + // TODO: support other generators + default: + err("context.cpp: output format not yet supported"); + break; + } } bool isEmpty = root->isEmpty(); if (isEmpty) @@ -1086,9 +1229,27 @@ static TemplateVariant parseCode(MemberDef *md,const QCString &scopeName,const Q pIntf->resetCodeParserState(); QGString s; FTextStream t(&s); - HtmlCodeGenerator codeGen(t,relPath); - pIntf->parseCode(codeGen,scopeName,code,md->getLanguage(),FALSE,0,md->getBodyDef(), - startLine,endLine,TRUE,md,showLineNumbers,md); + switch (g_globals.outputFormat) + { + case ContextOutputFormat_Html: + { + HtmlCodeGenerator codeGen(t,relPath); + pIntf->parseCode(codeGen,scopeName,code,md->getLanguage(),FALSE,0,md->getBodyDef(), + startLine,endLine,TRUE,md,showLineNumbers,md); + } + break; + case ContextOutputFormat_Latex: + { + LatexCodeGenerator codeGen(t,relPath,md->docFile()); + pIntf->parseCode(codeGen,scopeName,code,md->getLanguage(),FALSE,0,md->getBodyDef(), + startLine,endLine,TRUE,md,showLineNumbers,md); + } + break; + // TODO: support other generators + default: + err("context.cpp: output format not yet supported"); + break; + } return TemplateVariant(s.data(),TRUE); } @@ -1099,21 +1260,51 @@ static TemplateVariant parseCode(FileDef *fd,const QCString &relPath) pIntf->resetCodeParserState(); QGString s; FTextStream t(&s); - HtmlCodeGenerator codeGen(t,relPath); - pIntf->parseCode(codeGen,0, - fileToString(fd->absFilePath(),filterSourceFiles,TRUE), // the sources - fd->getLanguage(), // lang - FALSE, // isExampleBlock - 0, // exampleName - fd, // fileDef - -1, // startLine - -1, // endLine - FALSE, // inlineFragment - 0, // memberDef - TRUE, // showLineNumbers - 0, // searchCtx - TRUE // collectXRefs, TODO: should become FALSE - ); + switch (g_globals.outputFormat) + { + case ContextOutputFormat_Html: + { + HtmlCodeGenerator codeGen(t,relPath); + pIntf->parseCode(codeGen,0, + fileToString(fd->absFilePath(),filterSourceFiles,TRUE), // the sources + fd->getLanguage(), // lang + FALSE, // isExampleBlock + 0, // exampleName + fd, // fileDef + -1, // startLine + -1, // endLine + FALSE, // inlineFragment + 0, // memberDef + TRUE, // showLineNumbers + 0, // searchCtx + TRUE // collectXRefs, TODO: should become FALSE + ); + } + break; + case ContextOutputFormat_Latex: + { + LatexCodeGenerator codeGen(t,relPath,fd->docFile()); + pIntf->parseCode(codeGen,0, + fileToString(fd->absFilePath(),filterSourceFiles,TRUE), // the sources + fd->getLanguage(), // lang + FALSE, // isExampleBlock + 0, // exampleName + fd, // fileDef + -1, // startLine + -1, // endLine + FALSE, // inlineFragment + 0, // memberDef + TRUE, // showLineNumbers + 0, // searchCtx + TRUE // collectXRefs, TODO: should become FALSE + ); + } + break; + // TODO: support other generators + default: + err("context.cpp: output format not yet supported"); + break; + } return TemplateVariant(s.data(),TRUE); } @@ -1227,21 +1418,23 @@ class DefinitionContext : public PropertyMapper } TemplateVariant details() const { - if (!m_cache.details) + if (!m_cache.details || g_globals.outputFormat!=m_cache.detailsOutputFormat) { m_cache.details.reset(new TemplateVariant(parseDoc(m_def,m_def->docFile(),m_def->docLine(), relPathAsString(),m_def->documentation(),FALSE))); + m_cache.detailsOutputFormat = g_globals.outputFormat; } return *m_cache.details; } TemplateVariant brief() const { - if (!m_cache.brief) + if (!m_cache.brief || g_globals.outputFormat!=m_cache.briefOutputFormat) { if (m_def->hasBriefDescription()) { m_cache.brief.reset(new TemplateVariant(parseDoc(m_def,m_def->briefFile(),m_def->briefLine(), relPathAsString(),m_def->briefDescription(),TRUE))); + m_cache.briefOutputFormat = g_globals.outputFormat; } else { @@ -1252,12 +1445,13 @@ class DefinitionContext : public PropertyMapper } TemplateVariant inbodyDocs() const { - if (!m_cache.inbodyDocs) + if (!m_cache.inbodyDocs || g_globals.outputFormat!=m_cache.inbodyDocsOutputFormat) { if (!m_def->inbodyDocumentation().isEmpty()) { m_cache.inbodyDocs.reset(new TemplateVariant(parseDoc(m_def,m_def->inbodyFile(),m_def->inbodyLine(), relPathAsString(),m_def->inbodyDocumentation(),FALSE))); + m_cache.inbodyDocsOutputFormat = g_globals.outputFormat; } else { @@ -1343,8 +1537,11 @@ class DefinitionContext : public PropertyMapper { Cachable() { } ScopedPtr<TemplateVariant> details; + ContextOutputFormat detailsOutputFormat; ScopedPtr<TemplateVariant> brief; + ContextOutputFormat briefOutputFormat; ScopedPtr<TemplateVariant> inbodyDocs; + ContextOutputFormat inbodyDocsOutputFormat; SharedPtr<TemplateList> navPath; SharedPtr<TemplateList> sourceDef; SharedPtr<TemplateStruct> fileLink; @@ -1542,6 +1739,7 @@ class ClassContext::Private : public DefinitionContext<ClassContext::Private> addProperty("allMembersFileName", this,&Private::allMembersFileName); addProperty("memberGroups", this,&Private::memberGroups); addProperty("additionalInheritedMembers",this,&Private::additionalInheritedMembers); + addProperty("isSimple", this,&Private::isSimple); } virtual ~Private() {} TemplateVariant title() const @@ -1615,28 +1813,65 @@ class ClassContext::Private : public DefinitionContext<ClassContext::Private> { DotClassGraph *cg = getClassGraph(); FTextStream t(&result); - cg->writeGraph(t,GOF_BITMAP,EOF_Html, - g_globals.outputDir, - g_globals.outputDir+portable_pathSeparator()+m_classDef->getOutputFileBase()+Doxygen::htmlFileExtension, - relPathAsString(),TRUE,TRUE,g_globals.dynSectionId - ); + switch (g_globals.outputFormat) + { + case ContextOutputFormat_Html: + { + cg->writeGraph(t,GOF_BITMAP,EOF_Html, + g_globals.outputDir, + g_globals.outputDir+portable_pathSeparator()+m_classDef->getOutputFileBase()+Doxygen::htmlFileExtension, + relPathAsString(),TRUE,TRUE,g_globals.dynSectionId + ); + } + break; + case ContextOutputFormat_Latex: + { + cg->writeGraph(t,GOF_EPS,EOF_LaTeX, + g_globals.outputDir, + g_globals.outputDir+portable_pathSeparator()+m_classDef->getOutputFileBase()+".tex", + relPathAsString(),TRUE,TRUE,g_globals.dynSectionId + ); + } + break; + // TODO: support other generators + default: + err("context.cpp: output format not yet supported"); + break; + } + g_globals.dynSectionId++; } else if (classDiagrams) { ClassDiagram d(m_classDef); FTextStream t(&result); - QCString name = convertToHtml(m_classDef->displayName()); - t << "<div class=\"center\">" << endl; - t << "<img src=\""; - t << relPathAsString() << m_classDef->getOutputFileBase(); - t << ".png\" usemap=\"#" << name << "_map\" alt=\"\"/>" << endl; - t << "<map id=\"" << name << "_map\" name=\"" << name << "_map\">" << endl; - d.writeImage(t,g_globals.outputDir, - relPathAsString(), - m_classDef->getOutputFileBase()); - t << "</div>"; - } - g_globals.dynSectionId++; + switch (g_globals.outputFormat) + { + case ContextOutputFormat_Html: + { + QCString name = convertToHtml(m_classDef->displayName()); + t << "<div class=\"center\">" << endl; + t << "<img src=\""; + t << relPathAsString() << m_classDef->getOutputFileBase(); + t << ".png\" usemap=\"#" << name << "_map\" alt=\"\"/>" << endl; + t << "<map id=\"" << name << "_map\" name=\"" << name << "_map\">" << endl; + d.writeImage(t,g_globals.outputDir, + relPathAsString(), + m_classDef->getOutputFileBase()); + t << "</div>"; + } + break; + case ContextOutputFormat_Latex: + { + d.writeFigure(t,g_globals.outputDir,m_classDef->getOutputFileBase()); + } + break; + // TODO: support other generators + default: + err("context.cpp: output format not yet supported"); + break; + } + g_globals.dynSectionId++; + } return TemplateVariant(result.data(),TRUE); } DotClassGraph *getCollaborationGraph() const @@ -1660,13 +1895,33 @@ class ClassContext::Private : public DefinitionContext<ClassContext::Private> { DotClassGraph *cg = getCollaborationGraph(); FTextStream t(&result); - cg->writeGraph(t,GOF_BITMAP,EOF_Html, - g_globals.outputDir, - g_globals.outputDir+portable_pathSeparator()+m_classDef->getOutputFileBase()+Doxygen::htmlFileExtension, - relPathAsString(),TRUE,TRUE,g_globals.dynSectionId - ); + switch (g_globals.outputFormat) + { + case ContextOutputFormat_Html: + { + cg->writeGraph(t,GOF_BITMAP,EOF_Html, + g_globals.outputDir, + g_globals.outputDir+portable_pathSeparator()+m_classDef->getOutputFileBase()+Doxygen::htmlFileExtension, + relPathAsString(),TRUE,TRUE,g_globals.dynSectionId + ); + } + break; + case ContextOutputFormat_Latex: + { + cg->writeGraph(t,GOF_EPS,EOF_LaTeX, + g_globals.outputDir, + g_globals.outputDir+portable_pathSeparator()+m_classDef->getOutputFileBase()+".tex", + relPathAsString(),TRUE,TRUE,g_globals.dynSectionId + ); + } + break; + // TODO: support other generators + default: + err("context.cpp: output format not yet supported"); + break; + } + g_globals.dynSectionId++; } - g_globals.dynSectionId++; return TemplateVariant(result.data(),TRUE); } @@ -1958,15 +2213,15 @@ class ClassContext::Private : public DefinitionContext<ClassContext::Private> } TemplateVariant typeConstraints() const { - if (!m_cache.typeConstraints && m_classDef->typeConstraints()) - { - m_cache.typeConstraints.reset(ArgumentListContext::alloc(m_classDef->typeConstraints(),m_classDef,relPathAsString())); - } - else + if (m_classDef->typeConstraints()) { - m_cache.typeConstraints.reset(ArgumentListContext::alloc()); + if (!m_cache.typeConstraints && m_classDef->typeConstraints()) + { + m_cache.typeConstraints.reset(ArgumentListContext::alloc(m_classDef->typeConstraints(),m_classDef,relPathAsString())); + } + return m_cache.typeConstraints.get(); } - return m_cache.typeConstraints.get(); + return FALSE; } TemplateVariant examples() const { @@ -2108,6 +2363,10 @@ class ClassContext::Private : public DefinitionContext<ClassContext::Private> } return m_cache.additionalInheritedMembers.get(); } + TemplateVariant isSimple() const + { + return m_classDef->isSimple(); + } private: ClassDef *m_classDef; @@ -2534,13 +2793,33 @@ class FileContext::Private : public DefinitionContext<FileContext::Private> { DotInclDepGraph *cg = getIncludeGraph(); FTextStream t(&result); - cg->writeGraph(t,GOF_BITMAP,EOF_Html, - g_globals.outputDir, - g_globals.outputDir+portable_pathSeparator()+m_fileDef->getOutputFileBase()+Doxygen::htmlFileExtension, - relPathAsString(),TRUE,g_globals.dynSectionId - ); + switch (g_globals.outputFormat) + { + case ContextOutputFormat_Html: + { + cg->writeGraph(t,GOF_BITMAP,EOF_Html, + g_globals.outputDir, + g_globals.outputDir+portable_pathSeparator()+m_fileDef->getOutputFileBase()+Doxygen::htmlFileExtension, + relPathAsString(),TRUE,g_globals.dynSectionId + ); + } + break; + case ContextOutputFormat_Latex: + { + cg->writeGraph(t,GOF_EPS,EOF_LaTeX, + g_globals.outputDir, + g_globals.outputDir+portable_pathSeparator()+m_fileDef->getOutputFileBase()+".tex", + relPathAsString(),TRUE,g_globals.dynSectionId + ); + } + break; + // TODO: support other generators + default: + err("context.cpp: output format not yet supported"); + break; + } + g_globals.dynSectionId++; } - g_globals.dynSectionId++; return TemplateVariant(result.data(),TRUE); } DotInclDepGraph *getIncludedByGraph() const @@ -2565,13 +2844,33 @@ class FileContext::Private : public DefinitionContext<FileContext::Private> { DotInclDepGraph *cg = getIncludedByGraph(); FTextStream t(&result); - cg->writeGraph(t,GOF_BITMAP,EOF_Html, - g_globals.outputDir, - g_globals.outputDir+portable_pathSeparator()+m_fileDef->getOutputFileBase()+Doxygen::htmlFileExtension, - relPathAsString(),TRUE,g_globals.dynSectionId - ); + switch (g_globals.outputFormat) + { + case ContextOutputFormat_Html: + { + cg->writeGraph(t,GOF_BITMAP,EOF_Html, + g_globals.outputDir, + g_globals.outputDir+portable_pathSeparator()+m_fileDef->getOutputFileBase()+Doxygen::htmlFileExtension, + relPathAsString(),TRUE,g_globals.dynSectionId + ); + } + break; + case ContextOutputFormat_Latex: + { + cg->writeGraph(t,GOF_EPS,EOF_LaTeX, + g_globals.outputDir, + g_globals.outputDir+portable_pathSeparator()+m_fileDef->getOutputFileBase()+".tex", + relPathAsString(),TRUE,g_globals.dynSectionId + ); + } + break; + // TODO: support other generators + default: + err("context.cpp: output format not yet supported"); + break; + } + g_globals.dynSectionId++; } - g_globals.dynSectionId++; return TemplateVariant(result.data(),TRUE); } TemplateVariant hasDetails() const @@ -2834,6 +3133,8 @@ class DirContext::Private : public DefinitionContext<DirContext::Private> addProperty("dirs", this,&Private::dirs); addProperty("files", this,&Private::files); addProperty("hasDetails", this,&Private::hasDetails); + addProperty("hasDirGraph", this,&Private::hasDirGraph); + addProperty("dirGraph", this,&Private::dirGraph); addProperty("compoundType", this,&Private::compoundType); } virtual ~Private() {} @@ -2901,6 +3202,70 @@ class DirContext::Private : public DefinitionContext<DirContext::Private> { return ""; } + DotDirDeps *getDirDepsGraph() const + { + if (!m_cache.dirDepsGraph) + { + m_cache.dirDepsGraph.reset(new DotDirDeps(m_dirDef)); + } + return m_cache.dirDepsGraph.get(); + } + TemplateVariant hasDirGraph() const + { + bool result=FALSE; + static bool haveDot = Config_getBool("HAVE_DOT"); + static bool dirGraph = Config_getBool("DIRECTORY_GRAPH"); + if (haveDot && dirGraph) + { + DotDirDeps *graph = getDirDepsGraph(); + result = !graph->isTrivial(); + } + return result; + } + TemplateVariant dirGraph() const + { + QGString result; + static bool haveDot = Config_getBool("HAVE_DOT"); + static bool dirGraph = Config_getBool("DIRECTORY_GRAPH"); + if (haveDot && dirGraph) + { + DotDirDeps *graph = getDirDepsGraph(); + FTextStream t(&result); + switch (g_globals.outputFormat) + { + case ContextOutputFormat_Html: + { + graph->writeGraph(t,GOF_BITMAP, + EOF_Html, + g_globals.outputDir, + g_globals.outputDir+portable_pathSeparator()+m_dirDef->getOutputFileBase()+Doxygen::htmlFileExtension, + relPathAsString(), + TRUE, + g_globals.dynSectionId, + FALSE); + } + break; + case ContextOutputFormat_Latex: + { + graph->writeGraph(t,GOF_EPS, + EOF_LaTeX, + g_globals.outputDir, + g_globals.outputDir+portable_pathSeparator()+m_dirDef->getOutputFileBase()+".tex", + relPathAsString(), + TRUE, + g_globals.dynSectionId, + FALSE); + } + break; + // TODO: support other generators + default: + err("context.cpp: output format not yet supported"); + break; + } + g_globals.dynSectionId++; + } + return TemplateVariant(result.data(),TRUE); + } private: DirDef *m_dirDef; @@ -2909,6 +3274,7 @@ class DirContext::Private : public DefinitionContext<DirContext::Private> Cachable() {} SharedPtr<TemplateList> dirs; SharedPtr<TemplateList> files; + ScopedPtr<DotDirDeps> dirDepsGraph; }; mutable Cachable m_cache; }; @@ -3019,7 +3385,6 @@ class TextGeneratorHtml : public TextGeneratorIntf void writeString(const char *s,bool keepSpaces) const { if (s==0) return; - //printf("TextGeneratorOlImpl::writeString('%s',%d)\n",s,keepSpaces); if (keepSpaces) { const char *p=s; @@ -3079,6 +3444,54 @@ class TextGeneratorHtml : public TextGeneratorIntf QCString m_relPath; }; +//------------------------------------------------------------------------ + +class TextGeneratorLatex : public TextGeneratorIntf +{ + public: + TextGeneratorLatex(FTextStream &ts) : m_ts(ts) {} + void writeString(const char *s,bool keepSpaces) const + { + if (s==0) return; + m_ts << convertToLaTeX(s,FALSE,keepSpaces); + } + void writeBreak(int indent) const + { + m_ts << "\\\\*\n"; + for (int i=0;i<indent;i++) + { + m_ts << "~"; + } + } + void writeLink(const char *ref,const char *f, + const char *anchor,const char *text + ) const + { + static bool pdfHyperlinks = Config_getBool("PDF_HYPERLINKS"); + if (!ref && pdfHyperlinks) + { + m_ts << "\\hyperlink{"; + if (f) m_ts << stripPath(f); + if (f && anchor) m_ts << "_"; + if (anchor) m_ts << anchor; + m_ts << "}{"; + filterLatexString(m_ts,text); + m_ts << "}"; + } + else + { + m_ts << "{\\bf "; + filterLatexString(m_ts,text); + m_ts << "}"; + } + } + + private: + FTextStream &m_ts; +}; + +//------------------------------------------------------------------------ + class TextGeneratorFactory { public: @@ -3092,9 +3505,10 @@ class TextGeneratorFactory { switch (g_globals.outputFormat) { - case ContextGlobals::Html: + case ContextOutputFormat_Html: return new TextGeneratorHtml(ts,relPath); - break; + case ContextOutputFormat_Latex: + return new TextGeneratorLatex(ts); default: break; } @@ -3192,6 +3606,7 @@ class MemberContext::Private : public DefinitionContext<MemberContext::Private> addProperty("isObjCMethod", this,&Private::isObjCMethod); addProperty("isObjCProperty", this,&Private::isObjCProperty); addProperty("isAnonymous", this,&Private::isAnonymous); + addProperty("hasParameters", this,&Private::hasParameters); addProperty("declType", this,&Private::declType); addProperty("declArgs", this,&Private::declArgs); addProperty("anonymousType", this,&Private::anonymousType); @@ -3207,12 +3622,12 @@ class MemberContext::Private : public DefinitionContext<MemberContext::Private> addProperty("templateAlias", this,&Private::templateAlias); addProperty("propertyAttrs", this,&Private::propertyAttrs); addProperty("eventAttrs", this,&Private::eventAttrs); + addProperty("category", this,&Private::category); addProperty("class", this,&Private::getClass); addProperty("file", this,&Private::getFile); addProperty("namespace", this,&Private::getNamespace); addProperty("definition", this,&Private::definition); addProperty("parameters", this,&Private::parameters); - addProperty("hasParameterList", this,&Private::hasParameterList); addProperty("hasConstQualifier", this,&Private::hasConstQualifier); addProperty("hasVolatileQualifier",this,&Private::hasVolatileQualifier); addProperty("trailingReturnType", this,&Private::trailingReturnType); @@ -3238,6 +3653,7 @@ class MemberContext::Private : public DefinitionContext<MemberContext::Private> addProperty("hasCallerGraph", this,&Private::hasCallerGraph); addProperty("callerGraph", this,&Private::callerGraph); addProperty("fieldType", this,&Private::fieldType); + addProperty("type", this,&Private::type); m_cache.propertyAttrs.reset(TemplateList::alloc()); if (md && md->isProperty()) @@ -3675,6 +4091,21 @@ class MemberContext::Private : public DefinitionContext<MemberContext::Private> return TemplateVariant(FALSE); } } + TemplateVariant category() const + { + if (!m_cache.category && m_memberDef->category()) + { + m_cache.category.reset(ClassContext::alloc(m_memberDef->category())); + } + if (m_cache.category) + { + return m_cache.category.get(); + } + else + { + return TemplateVariant(FALSE); + } + } TemplateVariant getFile() const { if (!m_cache.fileDef && m_memberDef->getFileDef()) @@ -3731,7 +4162,7 @@ class MemberContext::Private : public DefinitionContext<MemberContext::Private> } return m_cache.arguments.get(); } - TemplateVariant hasParameterList() const + TemplateVariant hasParameters() const { return getDefArgList()!=0; } @@ -4071,11 +4502,31 @@ class MemberContext::Private : public DefinitionContext<MemberContext::Private> DotCallGraph *cg = getCallGraph(); QGString result; FTextStream t(&result); - cg->writeGraph(t,GOF_BITMAP,EOF_Html, - g_globals.outputDir, - g_globals.outputDir+portable_pathSeparator()+m_memberDef->getOutputFileBase()+Doxygen::htmlFileExtension, - relPathAsString(),TRUE,g_globals.dynSectionId - ); + switch (g_globals.outputFormat) + { + case ContextOutputFormat_Html: + { + cg->writeGraph(t,GOF_BITMAP,EOF_Html, + g_globals.outputDir, + g_globals.outputDir+portable_pathSeparator()+m_memberDef->getOutputFileBase()+Doxygen::htmlFileExtension, + relPathAsString(),TRUE,g_globals.dynSectionId + ); + } + break; + case ContextOutputFormat_Latex: + { + cg->writeGraph(t,GOF_EPS,EOF_LaTeX, + g_globals.outputDir, + g_globals.outputDir+portable_pathSeparator()+m_memberDef->getOutputFileBase()+".tex", + relPathAsString(),TRUE,g_globals.dynSectionId + ); + } + break; + // TODO: support other generators + default: + err("context.cpp: output format not yet supported"); + break; + } g_globals.dynSectionId++; return TemplateVariant(result.data(),TRUE); } @@ -4110,11 +4561,31 @@ class MemberContext::Private : public DefinitionContext<MemberContext::Private> DotCallGraph *cg = getCallerGraph(); QGString result; FTextStream t(&result); - cg->writeGraph(t,GOF_BITMAP,EOF_Html, - g_globals.outputDir, - g_globals.outputDir+portable_pathSeparator()+m_memberDef->getOutputFileBase()+Doxygen::htmlFileExtension, - relPathAsString(),TRUE,g_globals.dynSectionId - ); + switch (g_globals.outputFormat) + { + case ContextOutputFormat_Html: + { + cg->writeGraph(t,GOF_BITMAP,EOF_Html, + g_globals.outputDir, + g_globals.outputDir+portable_pathSeparator()+m_memberDef->getOutputFileBase()+Doxygen::htmlFileExtension, + relPathAsString(),TRUE,g_globals.dynSectionId + ); + } + break; + case ContextOutputFormat_Latex: + { + cg->writeGraph(t,GOF_EPS,EOF_LaTeX, + g_globals.outputDir, + g_globals.outputDir+portable_pathSeparator()+m_memberDef->getOutputFileBase()+".tex", + relPathAsString(),TRUE,g_globals.dynSectionId + ); + } + break; + // TODO: support other generators + default: + err("context.cpp: output format not yet supported"); + break; + } g_globals.dynSectionId++; return TemplateVariant(result.data(),TRUE); } @@ -4123,6 +4594,10 @@ class MemberContext::Private : public DefinitionContext<MemberContext::Private> return TemplateVariant(""); } } + TemplateVariant type() const + { + return m_memberDef->typeString(); + } private: MemberDef *m_memberDef; struct Cachable @@ -4135,6 +4610,7 @@ class MemberContext::Private : public DefinitionContext<MemberContext::Private> SharedPtr<MemberListContext> enumValues; SharedPtr<FileContext> fileDef; SharedPtr<NamespaceContext> namespaceDef; + SharedPtr<ClassContext> category; SharedPtr<ClassContext> classDef; SharedPtr<ClassContext> anonymousType; SharedPtr<TemplateList> templateDecls; @@ -4273,15 +4749,37 @@ class ModuleContext::Private : public DefinitionContext<ModuleContext::Private> { DotGroupCollaboration *graph = getGroupGraph(); FTextStream t(&result); - graph->writeGraph(t,GOF_BITMAP, - EOF_Html, - g_globals.outputDir, - g_globals.outputDir+portable_pathSeparator()+m_groupDef->getOutputFileBase()+Doxygen::htmlFileExtension, - relPathAsString(), - TRUE, - g_globals.dynSectionId); + switch (g_globals.outputFormat) + { + case ContextOutputFormat_Html: + { + graph->writeGraph(t,GOF_BITMAP, + EOF_Html, + g_globals.outputDir, + g_globals.outputDir+portable_pathSeparator()+m_groupDef->getOutputFileBase()+Doxygen::htmlFileExtension, + relPathAsString(), + TRUE, + g_globals.dynSectionId); + } + break; + case ContextOutputFormat_Latex: + { + graph->writeGraph(t,GOF_EPS, + EOF_LaTeX, + g_globals.outputDir, + g_globals.outputDir+portable_pathSeparator()+m_groupDef->getOutputFileBase()+".tex", + relPathAsString(), + TRUE, + g_globals.dynSectionId); + } + break; + // TODO: support other generators + default: + err("context.cpp: output format not yet supported"); + break; + } + g_globals.dynSectionId++; } - g_globals.dynSectionId++; return TemplateVariant(result.data(),TRUE); } TemplateVariant hasDetails() const @@ -4699,7 +5197,8 @@ class ClassListContext::Private : public GenericNodeListContext { continue; } - if (cd->isLinkableInProject() && cd->templateMaster()==0) + if (cd->isLinkableInProject() && cd->templateMaster()==0 && + !cd->isHidden() && !cd->isEmbeddedInOuterScope()) { append(ClassContext::alloc(cd)); } @@ -8066,6 +8565,486 @@ TemplateListIntf::ConstIterator *ArgumentListContext::createIterator() const //------------------------------------------------------------------------ +// SymbolIndex +// - name: string +// - letter: string +// - symbolGroups: SymbolGroupList +// SymbolGroupList: list of SymbolGroups +// SymbolGroup +// - id +// - name +// - symbols: SymbolList +// SymbolList: list of Symbols +// Symbol +// - obj +// - scope +// - relPath + +//------------------------------------------------------------------------ + +//%% struct SymbolGroup: search group of similar symbols +//%% { +class SymbolContext::Private : public PropertyMapper +{ + public: + Private(const Definition *d,const Definition *prev, + const Definition *next) : m_def(d), m_prevDef(prev), m_nextDef(next) + { + addProperty("fileName",this,&Private::fileName); + addProperty("anchor", this,&Private::anchor); + addProperty("scope", this,&Private::scope); + addProperty("relPath", this,&Private::relPath); + } + TemplateVariant fileName() const + { + return m_def->getOutputFileBase(); + } + TemplateVariant anchor() const + { + return m_def->anchor(); + } + TemplateVariant scope() const + { + const Definition *scope = m_def->getOuterScope(); + const Definition *next = m_nextDef; + const Definition *prev = m_prevDef; + const Definition *nextScope = next ? next->getOuterScope() : 0; + const Definition *prevScope = prev ? prev->getOuterScope() : 0; + bool isMemberDef = m_def->definitionType()==Definition::TypeMember; + const MemberDef *md = isMemberDef ? (const MemberDef*)m_def : 0; + bool isFunctionLike = md && (md->isFunction() || md->isSlot() || md->isSignal()); + bool overloadedFunction = isFunctionLike && + ((prevScope!=0 && scope==prevScope) || (scope && scope==nextScope)); + QCString prefix; + if (md) prefix=md->localName(); + if (overloadedFunction) // overloaded member function + { + prefix+=md->argsString(); + // show argument list to disambiguate overloaded functions + } + else if (md && isFunctionLike) // unique member function + { + prefix+="()"; // only to show it is a function + } + bool found=FALSE; + QCString name; + if (m_def->definitionType()==Definition::TypeClass) + { + name = m_def->displayName(); + found = TRUE; + } + else if (m_def->definitionType()==Definition::TypeNamespace) + { + name = m_def->displayName(); + found = TRUE; + } + else if (scope==0 || scope==Doxygen::globalScope) // in global scope + { + if (md) + { + FileDef *fd = md->getBodyDef(); + if (fd==0) fd = md->getFileDef(); + if (fd) + { + if (!prefix.isEmpty()) prefix+=": "; + name = prefix + convertToXML(fd->localName()); + found = TRUE; + } + } + } + else if (md && (md->getClassDef() || md->getNamespaceDef())) + // member in class or namespace scope + { + SrcLangExt lang = md->getLanguage(); + name = m_def->getOuterScope()->qualifiedName() + + getLanguageSpecificSeparator(lang) + prefix; + found = TRUE; + } + else if (scope) // some thing else? -> show scope + { + name = prefix + convertToXML(scope->name()); + found = TRUE; + } + if (!found) // fallback + { + name = prefix + "("+theTranslator->trGlobalNamespace()+")"; + } + return name; + } + TemplateVariant relPath() const + { + return externalRef("../",m_def->getReference(),TRUE); + } + private: + const Definition *m_def; + const Definition *m_prevDef; + const Definition *m_nextDef; +}; +//%% } + +SymbolContext::SymbolContext(const Definition *def,const Definition *prevDef,const Definition *nextDef) + : RefCountedContext("SymbolContext") +{ + p = new Private(def,prevDef,nextDef); +} + +SymbolContext::~SymbolContext() +{ + delete p; +} + +TemplateVariant SymbolContext::get(const char *name) const +{ + return p->get(name); +} + +//------------------------------------------------------------------------ + +//%% list SymbolList[Symbol] : list of search symbols with the same name +class SymbolListContext::Private : public GenericNodeListContext +{ + public: + Private(const SearchDefinitionList *sdl) + { + QListIterator<Definition> li(*sdl); + Definition *def; + Definition *prev = 0; + for (li.toFirst();(def=li.current());) + { + ++li; + const Definition *next = li.current(); + append(SymbolContext::alloc(def,prev,next)); + prev = def; + } + } +}; + +SymbolListContext::SymbolListContext(const SearchDefinitionList *sdl) + : RefCountedContext("SymbolListContext") +{ + p = new Private(sdl); +} + +SymbolListContext::~SymbolListContext() +{ + delete p; +} + +// TemplateListIntf +int SymbolListContext::count() const +{ + return p->count(); +} + +TemplateVariant SymbolListContext::at(int index) const +{ + return p->at(index); +} + +TemplateListIntf::ConstIterator *SymbolListContext::createIterator() const +{ + return p->createIterator(); +} + +//------------------------------------------------------------------------ + +//%% struct SymbolGroup: search group of similar symbols +//%% { +class SymbolGroupContext::Private : public PropertyMapper +{ + public: + Private(const SearchDefinitionList *sdl) : m_sdl(sdl) + { + addProperty("id", this,&Private::id); + addProperty("name", this,&Private::name); + addProperty("symbols",this,&Private::symbolList); + } + TemplateVariant id() const + { + return m_sdl->id(); + } + TemplateVariant name() const + { + return m_sdl->name(); + } + TemplateVariant symbolList() const + { + if (!m_cache.symbolList) + { + m_cache.symbolList.reset(SymbolListContext::alloc(m_sdl)); + } + return m_cache.symbolList.get(); + } + private: + const SearchDefinitionList *m_sdl; + struct Cachable + { + SharedPtr<SymbolListContext> symbolList; + }; + mutable Cachable m_cache; +}; +//%% } + +SymbolGroupContext::SymbolGroupContext(const SearchDefinitionList *sdl) + : RefCountedContext("SymbolGroupContext") +{ + p = new Private(sdl); +} + +SymbolGroupContext::~SymbolGroupContext() +{ + delete p; +} + +TemplateVariant SymbolGroupContext::get(const char *name) const +{ + return p->get(name); +} + +//------------------------------------------------------------------------ + +//%% list SymbolGroupList[SymbolGroup] : list of search groups one per by name +class SymbolGroupListContext::Private : public GenericNodeListContext +{ + public: + Private(const SearchIndexList *sil) + { + SDict<SearchDefinitionList>::Iterator li(*sil); + SearchDefinitionList *dl; + for (li.toFirst();(dl=li.current());++li) + { + append(SymbolGroupContext::alloc(dl)); + } + } +}; + +SymbolGroupListContext::SymbolGroupListContext(const SearchIndexList *sil) + : RefCountedContext("SymbolGroupListContext") +{ + p = new Private(sil); +} + +SymbolGroupListContext::~SymbolGroupListContext() +{ + delete p; +} + +// TemplateListIntf +int SymbolGroupListContext::count() const +{ + return p->count(); +} + +TemplateVariant SymbolGroupListContext::at(int index) const +{ + return p->at(index); +} + +TemplateListIntf::ConstIterator *SymbolGroupListContext::createIterator() const +{ + return p->createIterator(); +} + +//------------------------------------------------------------------------ + +//%% struct SymbolIndex: search index +//%% { +class SymbolIndexContext::Private : public PropertyMapper +{ + public: + Private(const SearchIndexList *sl,const QCString &name) : m_searchList(sl), m_name(name) + { + addProperty("name", this,&Private::name); + addProperty("letter", this,&Private::letter); + addProperty("symbolGroups",this,&Private::symbolGroups); + } + TemplateVariant name() const + { + return m_name; + } + TemplateVariant letter() const + { + return QString(QChar(m_searchList->letter())).utf8(); + } + TemplateVariant symbolGroups() const + { + if (!m_cache.symbolGroups) + { + m_cache.symbolGroups.reset(SymbolGroupListContext::alloc(m_searchList)); + } + return m_cache.symbolGroups.get(); + } + private: + const SearchIndexList *m_searchList; + QCString m_name; + struct Cachable + { + SharedPtr<SymbolGroupListContext> symbolGroups; + }; + mutable Cachable m_cache; +}; +//%% } + +SymbolIndexContext::SymbolIndexContext(const SearchIndexList *sl,const QCString &name) + : RefCountedContext("SymbolIndexContext") +{ + p = new Private(sl,name); +} + +SymbolIndexContext::~SymbolIndexContext() +{ + delete p; +} + +TemplateVariant SymbolIndexContext::get(const char *name) const +{ + return p->get(name); +} + +//------------------------------------------------------------------------ + +//%% list SymbolIndices[SymbolIndex] : list of search indices one per by type +class SymbolIndicesContext::Private : public GenericNodeListContext +{ + public: + Private(const SearchIndexInfo *info) + { + // use info->symbolList to populate the list + SIntDict<SearchIndexList>::Iterator it(info->symbolList); + const SearchIndexList *sl; + for (it.toFirst();(sl=it.current());++it) // for each letter + { + append(SymbolIndexContext::alloc(sl,info->name)); + } + } +}; + +SymbolIndicesContext::SymbolIndicesContext(const SearchIndexInfo *info) : RefCountedContext("SymbolIndicesContext") +{ + p = new Private(info); +} + +SymbolIndicesContext::~SymbolIndicesContext() +{ + delete p; +} + +// TemplateListIntf +int SymbolIndicesContext::count() const +{ + return p->count(); +} + +TemplateVariant SymbolIndicesContext::at(int index) const +{ + return p->at(index); +} + +TemplateListIntf::ConstIterator *SymbolIndicesContext::createIterator() const +{ + return p->createIterator(); +} + +//------------------------------------------------------------------------ + +//%% struct SearchIndex: search index +//%% { +class SearchIndexContext::Private : public PropertyMapper +{ + public: + Private(const SearchIndexInfo *info) : m_info(info) + { + addProperty("name", this,&Private::name); + addProperty("text", this,&Private::text); + addProperty("symbolIndices",this,&Private::symbolIndices); + } + TemplateVariant name() const + { + return m_info->name; + } + TemplateVariant text() const + { + return m_info->text; + } + TemplateVariant symbolIndices() const + { + if (!m_cache.symbolIndices) + { + m_cache.symbolIndices.reset(SymbolIndicesContext::alloc(m_info)); + } + return m_cache.symbolIndices.get(); + } + private: + const SearchIndexInfo *m_info; + struct Cachable + { + SharedPtr<SymbolIndicesContext> symbolIndices; + }; + mutable Cachable m_cache; +}; +//%% } + +SearchIndexContext::SearchIndexContext(const SearchIndexInfo *info) + : RefCountedContext("SearchIndexContext") +{ + p = new Private(info); +} + +SearchIndexContext::~SearchIndexContext() +{ + delete p; +} + +TemplateVariant SearchIndexContext::get(const char *name) const +{ + return p->get(name); +} + +//------------------------------------------------------------------------ + +//%% list SearchIndices[SearchIndex] : list of search indices one per by type +class SearchIndicesContext::Private : public GenericNodeListContext +{ + public: + Private() + { + const SearchIndexInfo *indices = getSearchIndices(); + for (int i=0;i<NUM_SEARCH_INDICES;i++) + { + append(SearchIndexContext::alloc(&indices[i])); + } + } +}; + +SearchIndicesContext::SearchIndicesContext() : RefCountedContext("SearchIndicesContext") +{ + p = new Private; +} + +SearchIndicesContext::~SearchIndicesContext() +{ + delete p; +} + +// TemplateListIntf +int SearchIndicesContext::count() const +{ + return p->count(); +} + +TemplateVariant SearchIndicesContext::at(int index) const +{ + return p->at(index); +} + +TemplateListIntf::ConstIterator *SearchIndicesContext::createIterator() const +{ + return p->createIterator(); +} + + +//------------------------------------------------------------------------ + class HtmlEscaper : public TemplateEscapeIntf { public: @@ -8073,6 +9052,36 @@ class HtmlEscaper : public TemplateEscapeIntf { return convertToHtml(s,TRUE); } + void enableTabbing(bool) {} +}; + +//------------------------------------------------------------------------ + +class LatexSpaceless : public TemplateSpacelessIntf +{ + public: + LatexSpaceless() { reset(); } + void reset() { } + QCString remove(const QCString &s) + { + QGString result; + const char *p = s.data(); + char c; + while ((c=*p++)) + { + switch(c) + { + case '\t': case ' ': case '\n': + break; + default: + result+=c; + break; + } + } + result+='\0'; + return result.data(); + } + private: }; //------------------------------------------------------------------------ @@ -8152,12 +9161,29 @@ class HtmlSpaceless : public TemplateSpacelessIntf //------------------------------------------------------------------------ +class LatexEscaper : public TemplateEscapeIntf +{ + public: + LatexEscaper() : m_tabbing(FALSE) {} + QCString escape(const QCString &s) + { + return convertToLaTeX(s,m_tabbing); + } + void enableTabbing(bool b) { m_tabbing=b; } + private: + bool m_tabbing; +}; + + +//------------------------------------------------------------------------ + #if DEBUG_REF int RefCountedContext::s_totalCount; #endif void generateOutputViaTemplate() { + msg("Generating output via template engine...\n"); { TemplateEngine e; TemplateContext *ctx = e.createContext(); @@ -8183,6 +9209,7 @@ void generateOutputViaTemplate() SharedPtr<GlobalsIndexContext> globalsIndex (GlobalsIndexContext::alloc()); SharedPtr<ClassMembersIndexContext> classMembersIndex (ClassMembersIndexContext::alloc()); SharedPtr<NamespaceMembersIndexContext> namespaceMembersIndex(NamespaceMembersIndexContext::alloc()); + SharedPtr<SearchIndicesContext> searchIndices (SearchIndicesContext::alloc()); //%% Doxygen doxygen: ctx->set("doxygen",doxygen.get()); @@ -8238,27 +9265,54 @@ void generateOutputViaTemplate() ctx->set("classMembersIndex",classMembersIndex.get()); //%% NamespaceMembersIndex namespaceMembersIndex: ctx->set("namespaceMembersIndex",namespaceMembersIndex.get()); + //%% SearchIndicaes searchindicaes + ctx->set("searchIndices",searchIndices.get()); + //%% string space + ctx->set("space"," "); + + //if (Config_getBool("GENERATE_HTML")) + { // render HTML output + Template *tpl = e.loadByName("htmllayout.tpl",1); + if (tpl) + { + g_globals.outputFormat = ContextOutputFormat_Html; + g_globals.dynSectionId = 0; + g_globals.outputDir = Config_getString("HTML_OUTPUT"); + QDir dir(g_globals.outputDir); + createSubDirs(dir); + HtmlEscaper htmlEsc; + ctx->setEscapeIntf(Config_getString("HTML_FILE_EXTENSION"),&htmlEsc); + HtmlSpaceless spl; + ctx->setSpacelessIntf(&spl); + ctx->setOutputDirectory(g_globals.outputDir); + FTextStream ts; + tpl->render(ts,ctx); + e.unload(tpl); + } + } - // render HTML output - Template *tpl = e.loadByName("htmllayout.tpl",1); - if (tpl) - { - g_globals.outputFormat = ContextGlobals::Html; - g_globals.dynSectionId = 0; - g_globals.outputDir = Config_getString("HTML_OUTPUT"); - QDir dir(g_globals.outputDir); - createSubDirs(dir); - HtmlEscaper htmlEsc; - ctx->setEscapeIntf(Config_getString("HTML_FILE_EXTENSION"),&htmlEsc); - HtmlSpaceless spl; - ctx->setSpacelessIntf(&spl); - ctx->setOutputDirectory(g_globals.outputDir); - FTextStream ts; - tpl->render(ts,ctx); - e.unload(tpl); - } - - // TODO: render other outputs + // TODO: clean index before each run... + + //if (Config_getBool("GENERATE_LATEX")) + { // render LaTeX output + Template *tpl = e.loadByName("latexlayout.tpl",1); + if (tpl) + { + g_globals.outputFormat = ContextOutputFormat_Latex; + g_globals.dynSectionId = 0; + g_globals.outputDir = Config_getString("LATEX_OUTPUT"); + QDir dir(g_globals.outputDir); + createSubDirs(dir); + LatexEscaper latexEsc; + ctx->setEscapeIntf(".tex",&latexEsc); + LatexSpaceless spl; + ctx->setSpacelessIntf(&spl); + ctx->setOutputDirectory(g_globals.outputDir); + FTextStream ts; + tpl->render(ts,ctx); + e.unload(tpl); + } + } e.destroyContext(ctx); } diff --git a/src/context.h b/src/context.h index cb20313..77a3a95 100644 --- a/src/context.h +++ b/src/context.h @@ -52,7 +52,10 @@ class MemberGroup; class MemberGroupSDict; class MemberGroupList; class DotNode; -class DotGfxHierarchyTable; +class DotGfxHierarchyTable; +struct SearchIndexInfo; +class SearchIndexList; +class SearchDefinitionList; //---------------------------------------------------- @@ -1154,6 +1157,173 @@ class ArgumentListContext : public RefCountedContext, public TemplateListIntf //---------------------------------------------------- +class SymbolContext : public RefCountedContext, public TemplateStructIntf +{ + public: + static SymbolContext *alloc(const Definition *def,const Definition *prev,const Definition *next) + { return new SymbolContext(def,prev,next); } + + // TemplateStructIntf methods + virtual TemplateVariant get(const char *name) const; + virtual int addRef() { return RefCountedContext::addRef(); } + virtual int release() { return RefCountedContext::release(); } + + private: + SymbolContext(const Definition *def,const Definition *prev,const Definition *next); + ~SymbolContext(); + class Private; + Private *p; +}; + +//---------------------------------------------------- + +class SymbolListContext : public RefCountedContext, public TemplateListIntf +{ + public: + static SymbolListContext *alloc(const SearchDefinitionList *sdl) + { return new SymbolListContext(sdl); } + + // TemplateListIntf + virtual int count() const; + virtual TemplateVariant at(int index) const; + virtual TemplateListIntf::ConstIterator *createIterator() const; + virtual int addRef() { return RefCountedContext::addRef(); } + virtual int release() { return RefCountedContext::release(); } + + private: + SymbolListContext(const SearchDefinitionList *sdl); + ~SymbolListContext(); + class Private; + Private *p; +}; + +//---------------------------------------------------- + +class SymbolGroupContext : public RefCountedContext, public TemplateStructIntf +{ + public: + static SymbolGroupContext *alloc(const SearchDefinitionList *sdl) + { return new SymbolGroupContext(sdl); } + + // TemplateStructIntf methods + virtual TemplateVariant get(const char *name) const; + virtual int addRef() { return RefCountedContext::addRef(); } + virtual int release() { return RefCountedContext::release(); } + + private: + SymbolGroupContext(const SearchDefinitionList *sdl); + ~SymbolGroupContext(); + class Private; + Private *p; +}; + +//---------------------------------------------------- + +class SymbolGroupListContext : public RefCountedContext, public TemplateListIntf +{ + public: + static SymbolGroupListContext *alloc(const SearchIndexList *sil) + { return new SymbolGroupListContext(sil); } + + // TemplateListIntf + virtual int count() const; + virtual TemplateVariant at(int index) const; + virtual TemplateListIntf::ConstIterator *createIterator() const; + virtual int addRef() { return RefCountedContext::addRef(); } + virtual int release() { return RefCountedContext::release(); } + + private: + SymbolGroupListContext(const SearchIndexList *sil); + ~SymbolGroupListContext(); + class Private; + Private *p; +}; + +//---------------------------------------------------- + +class SymbolIndexContext : public RefCountedContext, public TemplateStructIntf +{ + public: + static SymbolIndexContext *alloc(const SearchIndexList *sl,const QCString &name) + { return new SymbolIndexContext(sl,name); } + + // TemplateStructIntf methods + virtual TemplateVariant get(const char *name) const; + virtual int addRef() { return RefCountedContext::addRef(); } + virtual int release() { return RefCountedContext::release(); } + + private: + SymbolIndexContext(const SearchIndexList *sl,const QCString &name); + ~SymbolIndexContext(); + class Private; + Private *p; +}; + +//---------------------------------------------------- + +class SymbolIndicesContext : public RefCountedContext, public TemplateListIntf +{ + public: + static SymbolIndicesContext *alloc(const SearchIndexInfo *info) + { return new SymbolIndicesContext(info); } + + // TemplateListIntf + virtual int count() const; + virtual TemplateVariant at(int index) const; + virtual TemplateListIntf::ConstIterator *createIterator() const; + virtual int addRef() { return RefCountedContext::addRef(); } + virtual int release() { return RefCountedContext::release(); } + + private: + SymbolIndicesContext(const SearchIndexInfo *info); + ~SymbolIndicesContext(); + class Private; + Private *p; +}; + +//---------------------------------------------------- + +class SearchIndexContext : public RefCountedContext, public TemplateStructIntf +{ + public: + static SearchIndexContext *alloc(const SearchIndexInfo *info) + { return new SearchIndexContext(info); } + + // TemplateStructIntf methods + virtual TemplateVariant get(const char *name) const; + virtual int addRef() { return RefCountedContext::addRef(); } + virtual int release() { return RefCountedContext::release(); } + + private: + SearchIndexContext(const SearchIndexInfo *info); + ~SearchIndexContext(); + class Private; + Private *p; +}; + +//---------------------------------------------------- + +class SearchIndicesContext : public RefCountedContext, public TemplateListIntf +{ + public: + static SearchIndicesContext *alloc() { return new SearchIndicesContext; } + + // TemplateListIntf + virtual int count() const; + virtual TemplateVariant at(int index) const; + virtual TemplateListIntf::ConstIterator *createIterator() const; + virtual int addRef() { return RefCountedContext::addRef(); } + virtual int release() { return RefCountedContext::release(); } + + private: + SearchIndicesContext(); + ~SearchIndicesContext(); + class Private; + Private *p; +}; + +//---------------------------------------------------- + void generateOutputViaTemplate(); #endif diff --git a/src/dirdef.cpp b/src/dirdef.cpp index 067daa0..28c073e 100644 --- a/src/dirdef.cpp +++ b/src/dirdef.cpp @@ -385,7 +385,7 @@ void DirDef::writeDocumentation(OutputList &ol) ol.pushGeneratorState(); QCString title=theTranslator->trDirReference(m_dispName); - startFile(ol,getOutputFileBase(),name(),title,HLI_None,!generateTreeView); + startFile(ol,getOutputFileBase(),name(),title,HLI_Files,!generateTreeView); if (!generateTreeView) { @@ -610,7 +610,7 @@ bool DirDef::isParentOf(DirDef *dir) const bool DirDef::depGraphIsTrivial() const { - return FALSE; + return m_usedDirs->count()==0; } //---------------------------------------------------------------------- @@ -696,11 +696,6 @@ DirDef *DirDef::mergeDirectoryInTree(const QCString &path) return dir; } -void DirDef::writeDepGraph(FTextStream &t) -{ - writeDotDirDepGraph(t,this); -} - //---------------------------------------------------------------------- static void writePartialDirPath(OutputList &ol,const DirDef *root,const DirDef *target) diff --git a/src/dirdef.h b/src/dirdef.h index 1a87f5b..611ba3e 100644 --- a/src/dirdef.h +++ b/src/dirdef.h @@ -71,7 +71,6 @@ class DirDef : public Definition // generate output void writeDocumentation(OutputList &ol); - void writeDepGraph(FTextStream &t); void writeTagFile(FTextStream &t); static DirDef *mergeDirectoryInTree(const QCString &path); diff --git a/src/dot.cpp b/src/dot.cpp index 705aa27..701f868 100644 --- a/src/dot.cpp +++ b/src/dot.cpp @@ -3965,6 +3965,7 @@ bool DotCallGraph::isTooBig() const } //------------------------------------------------------------- +static void writeDotDirDepGraph(FTextStream &t,DirDef *dd,bool linkRelations); DotDirDeps::DotDirDeps(DirDef *dir) : m_dir(dir) { @@ -3981,7 +3982,8 @@ QCString DotDirDeps::writeGraph(FTextStream &out, const char *fileName, const char *relPath, bool generateImageMap, - int graphId) const + int graphId, + bool linkRelations) const { QDir d(path); // store the original directory @@ -4006,7 +4008,8 @@ QCString DotDirDeps::writeGraph(FTextStream &out, // compute md5 checksum of the graph were are about to generate QGString theGraph; FTextStream md5stream(&theGraph); - m_dir->writeDepGraph(md5stream); + //m_dir->writeDepGraph(md5stream); + writeDotDirDepGraph(md5stream,m_dir,linkRelations); uchar md5_sig[16]; QCString sigStr(33); MD5Buffer((const unsigned char *)theGraph.data(),theGraph.length(),md5_sig); @@ -4764,7 +4767,7 @@ void DotGroupCollaboration::writeGraphHeader(FTextStream &t, t << " rankdir=LR;\n"; } -void writeDotDirDepGraph(FTextStream &t,DirDef *dd) +void writeDotDirDepGraph(FTextStream &t,DirDef *dd,bool linkRelations) { t << "digraph \"" << dd->displayName() << "\" {\n"; if (Config_getBool("DOT_TRANSPARENT")) @@ -4896,11 +4899,14 @@ void writeDotDirDepGraph(FTextStream &t,DirDef *dd) new DirRelation(relationName,dir,udir)); } int nrefs = udir->filePairs().count(); - t << " " << dir->getOutputFileBase() << "->" + t << " " << dir->getOutputFileBase() << "->" << usedDir->getOutputFileBase(); t << " [headlabel=\"" << nrefs << "\", labeldistance=1.5"; - t << " headhref=\"" << relationName << Doxygen::htmlFileExtension - << "\"];\n"; + if (linkRelations) + { + t << " headhref=\"" << relationName << Doxygen::htmlFileExtension << "\""; + } + t << "];\n"; } } } @@ -262,7 +262,8 @@ class DotDirDeps const char *fileName, const char *relPath, bool writeImageMap=TRUE, - int graphId=-1) const; + int graphId=-1, + bool linkRelations=TRUE) const; private: DirDef *m_dir; }; @@ -459,6 +460,4 @@ void writeDotImageMapFromFile(FTextStream &t, const QCString& relPath,const QCString& baseName, const QCString& context,int graphId=-1); -void writeDotDirDepGraph(FTextStream &t,DirDef *dd); - #endif diff --git a/src/doxygen.cpp b/src/doxygen.cpp index 4ff533d..51b9341 100644 --- a/src/doxygen.cpp +++ b/src/doxygen.cpp @@ -11484,12 +11484,17 @@ void generateOutput() static bool searchEngine = Config_getBool("SEARCHENGINE"); static bool serverBasedSearch = Config_getBool("SERVER_BASED_SEARCH"); + g_s.begin("Generating search indices...\n"); + if (searchEngine && !serverBasedSearch && (generateHtml || g_useOutputTemplate)) + { + createJavascriptSearchIndex(); + } + // generate search indices (need to do this before writing other HTML // pages as these contain a drop down menu with options depending on // what categories we find in this function. if (generateHtml && searchEngine) { - g_s.begin("Generating search indices...\n"); QCString searchDirName = Config_getString("HTML_OUTPUT")+"/search"; QDir searchDir(searchDirName); if (!searchDir.exists() && !searchDir.mkdir(searchDirName)) @@ -11503,8 +11508,8 @@ void generateOutput() { writeJavascriptSearchIndex(); } - g_s.end(); } + g_s.end(); g_s.begin("Generating example documentation...\n"); generateExampleDocs(); diff --git a/src/htmlgen.cpp b/src/htmlgen.cpp index e6431e8..7908393 100644 --- a/src/htmlgen.cpp +++ b/src/htmlgen.cpp @@ -333,10 +333,6 @@ static QCString substituteHtmlKeywords(const QCString &s, if (mathJax) { QCString path = Config_getString("MATHJAX_RELPATH"); - if (!path.isEmpty() && path.at(path.length()-1)!='/') - { - path+="/"; - } if (path.isEmpty() || path.left(2)=="..") // relative path { path.prepend(relPath); @@ -364,7 +360,7 @@ static QCString substituteHtmlKeywords(const QCString &s, mathJaxJs += "\n"; } mathJaxJs += "</script>"; - mathJaxJs += "<script src=\"" + path + "MathJax.js\"></script>\n"; + mathJaxJs += "<script type=\"text/javascript\" src=\"" + path + "MathJax.js\"></script>\n"; } // first substitute generic keywords diff --git a/src/latexgen.cpp b/src/latexgen.cpp index 2ed30e9..c524d2e 100644 --- a/src/latexgen.cpp +++ b/src/latexgen.cpp @@ -38,11 +38,214 @@ #include "filename.h" #include "resourcemgr.h" +//------------------------------- + +LatexCodeGenerator::LatexCodeGenerator(FTextStream &t,const QCString &relPath,const QCString &sourceFileName) + : m_relPath(relPath), m_sourceFileName(sourceFileName), m_col(0) +{ + m_prettyCode=Config_getBool("LATEX_SOURCE_CODE"); + setTextStream(t); +} + +LatexCodeGenerator::LatexCodeGenerator() : m_col(0) +{ + m_prettyCode=Config_getBool("LATEX_SOURCE_CODE"); +} + +void LatexCodeGenerator::setTextStream(FTextStream &t) +{ + m_streamSet = t.device()!=0; + m_t.setDevice(t.device()); +} + +void LatexCodeGenerator::setRelativePath(const QCString &path) +{ + m_relPath = path; +} + +void LatexCodeGenerator::setSourceFileName(const QCString &name) +{ + m_sourceFileName = name; +} + +void LatexCodeGenerator::codify(const char *str) +{ + if (str) + { + const char *p=str; + char c; + //char cs[5]; + int spacesToNextTabStop; + static int tabSize = Config_getInt("TAB_SIZE"); + const int maxLineLen = 108; + QCString result(4*maxLineLen+1); // worst case for 1 line of 4-byte chars + int i; + while ((c=*p)) + { + switch(c) + { + case 0x0c: p++; // remove ^L + break; + case '\t': spacesToNextTabStop = + tabSize - (m_col%tabSize); + m_t << Doxygen::spaces.left(spacesToNextTabStop); + m_col+=spacesToNextTabStop; + p++; + break; + case '\n': m_t << '\n'; m_col=0; p++; + break; + default: + i=0; + +#undef COPYCHAR +// helper macro to copy a single utf8 character, dealing with multibyte chars. +#define COPYCHAR() do { \ + result[i++]=c; p++; \ + if (c<0) /* multibyte utf-8 character */ \ + { \ + /* 1xxx.xxxx: >=2 byte character */ \ + result[i++]=*p++; \ + if (((uchar)c&0xE0)==0xE0) \ + { \ + /* 111x.xxxx: >=3 byte character */ \ + result[i++]=*p++; \ + } \ + if (((uchar)c&0xF0)==0xF0) \ + { \ + /* 1111.xxxx: 4 byte character */ \ + result[i++]=*p++; \ + } \ + } \ + m_col++; \ + } while(0) + + // gather characters until we find whitespace or are at + // the end of a line + COPYCHAR(); + if (m_col>=maxLineLen) // force line break + { + m_t << "\n "; + m_col=0; + } + else // copy more characters + { + while (m_col<maxLineLen && (c=*p) && + c!=0x0c && c!='\t' && c!='\n' && c!=' ' + ) + { + COPYCHAR(); + } + if (m_col>=maxLineLen) // force line break + { + m_t << "\n "; + m_col=0; + } + } + result[i]=0; // add terminator + //if (m_prettyCode) + //{ + filterLatexString(m_t,result,FALSE,TRUE); + //} + //else + //{ + // t << result; + //} + break; + } + } + } +} + + +void LatexCodeGenerator::writeCodeLink(const char *ref,const char *f, + const char *anchor,const char *name, + const char *) +{ + static bool pdfHyperlinks = Config_getBool("PDF_HYPERLINKS"); + static bool usePDFLatex = Config_getBool("USE_PDFLATEX"); + int l = qstrlen(name); + if (m_col+l>80) + { + m_t << "\n "; + m_col=0; + } + if (!ref && usePDFLatex && pdfHyperlinks) + { + m_t << "\\hyperlink{"; + if (f) m_t << stripPath(f); + if (f && anchor) m_t << "_"; + if (anchor) m_t << anchor; + m_t << "}{"; + codify(name); + m_t << "}"; + } + else + { + m_t << name; + } + m_col+=l; +} + +void LatexCodeGenerator::writeLineNumber(const char *ref,const char *fileName,const char *anchor,int l) +{ + static bool usePDFLatex = Config_getBool("USE_PDFLATEX"); + static bool pdfHyperlinks = Config_getBool("PDF_HYPERLINKS"); + if (m_prettyCode) + { + QCString lineNumber; + lineNumber.sprintf("%05d",l); + + if (fileName && !m_sourceFileName.isEmpty()) + { + QCString lineAnchor; + lineAnchor.sprintf("_l%05d",l); + lineAnchor.prepend(m_sourceFileName); + //if (!m_prettyCode) return; + if (usePDFLatex && pdfHyperlinks) + { + m_t << "\\hypertarget{" << stripPath(lineAnchor) << "}{}"; + } + writeCodeLink(ref,fileName,anchor,lineNumber,0); + } + else + { + codify(lineNumber); + } + m_t << " "; + } + else + { + m_t << l << " "; + } +} + + +void LatexCodeGenerator::startCodeLine(bool) +{ + m_col=0; +} + +void LatexCodeGenerator::endCodeLine() +{ + codify("\n"); +} + +void LatexCodeGenerator::startFontClass(const char *name) +{ + m_t << "\\textcolor{" << name << "}{"; +} + +void LatexCodeGenerator::endFontClass() +{ + m_t << "}"; +} + + +//------------------------------- LatexGenerator::LatexGenerator() : OutputGenerator() { dir=Config_getString("LATEX_OUTPUT"); - col=0; //printf("LatexGenerator::LatexGenerator() insideTabbing=FALSE\n"); insideTabbing=FALSE; firstDescItem=TRUE; @@ -332,13 +535,8 @@ static void writeDefaultHeaderPart1(FTextStream &t) "\n"; // Define page & text layout - QCString paperName; - QCString &paperType=Config_getEnum("PAPER_TYPE"); + QCString paperName=Config_getEnum("PAPER_TYPE"); // "a4wide" package is obsolete (see bug 563698) - if (paperType=="a4wide") - paperName="a4"; - else - paperName=paperType; t << "% Page & text layout\n" "\\usepackage{geometry}\n" "\\geometry{%\n" @@ -593,7 +791,7 @@ void LatexGenerator::startFile(const char *name,const char *,const char *) #endif QCString fileName=name; relPath = relativePathToRoot(fileName); - sourceFileName = stripPath(fileName); + m_codeGen.setSourceFileName(stripPath(fileName)); if (fileName.right(4)!=".tex" && fileName.right(4)!=".sty") fileName+=".tex"; startPlainFile(fileName); } @@ -601,7 +799,7 @@ void LatexGenerator::startFile(const char *name,const char *,const char *) void LatexGenerator::endFile() { endPlainFile(); - sourceFileName.resize(0); + m_codeGen.setSourceFileName(""); } //void LatexGenerator::writeIndex() @@ -614,14 +812,6 @@ void LatexGenerator::startProjectNumber() t << "\\\\[1ex]\\large "; } -static QCString convertToLaTeX(const QCString &s) -{ - QGString result; - FTextStream t(&result); - filterLatexString(t,s,FALSE,FALSE,FALSE); - return result.data(); -} - void LatexGenerator::startIndexSection(IndexSections is) { bool &compactLatex = Config_getBool("COMPACT_LATEX"); @@ -1204,7 +1394,8 @@ void LatexGenerator::endTextLink() void LatexGenerator::writeObjectLink(const char *ref, const char *f, const char *anchor, const char *text) { - if (!disableLinks && !ref && Config_getBool("PDF_HYPERLINKS")) + static bool pdfHyperlinks = Config_getBool("PDF_HYPERLINKS"); + if (!disableLinks && !ref && pdfHyperlinks) { t << "\\hyperlink{"; if (f) t << stripPath(f); @@ -1235,34 +1426,6 @@ void LatexGenerator::endPageRef(const char *clname, const char *anchor) t << "}"; } -void LatexGenerator::writeCodeLink(const char *ref,const char *f, - const char *anchor,const char *name, - const char *) -{ - static bool pdfHyperlinks = Config_getBool("PDF_HYPERLINKS"); - static bool usePDFLatex = Config_getBool("USE_PDFLATEX"); - int l = qstrlen(name); - if (col+l>80) - { - t << "\n "; - col=0; - } - if (/*m_prettyCode &&*/ !disableLinks && !ref && usePDFLatex && pdfHyperlinks) - { - t << "\\hyperlink{"; - if (f) t << stripPath(f); - if (f && anchor) t << "_"; - if (anchor) t << anchor; - t << "}{"; - codify(name); - t << "}"; - } - else - { - t << name; - } - col+=l; -} void LatexGenerator::startTitleHead(const char *fileName) { @@ -1288,9 +1451,9 @@ void LatexGenerator::endTitleHead(const char *fileName,const char *name) if (name) { t << "\\label{" << stripPath(fileName) << "}\\index{"; - escapeLabelName(name); + t << latexEscapeLabelName(name,insideTabbing); t << "@{"; - escapeMakeIndexChars(name); + t << latexEscapeIndexChars(name,insideTabbing); t << "}}" << endl; } } @@ -1369,27 +1532,27 @@ void LatexGenerator::startMemberDoc(const char *clname, t << "\\index{"; if (clname) { - escapeLabelName(clname); + t << latexEscapeLabelName(clname,insideTabbing); t << "@{"; - escapeMakeIndexChars(clname); + t << latexEscapeIndexChars(clname,insideTabbing); t << "}!"; } - escapeLabelName(memname); + t << latexEscapeLabelName(memname,insideTabbing); t << "@{"; - escapeMakeIndexChars(memname); + t << latexEscapeIndexChars(memname,insideTabbing); t << "}}" << endl; t << "\\index{"; - escapeLabelName(memname); + t << latexEscapeLabelName(memname,insideTabbing); t << "@{"; - escapeMakeIndexChars(memname); + t << latexEscapeIndexChars(memname,insideTabbing); t << "}"; if (clname) { t << "!"; - escapeLabelName(clname); + t << latexEscapeLabelName(clname,insideTabbing); t << "@{"; - escapeMakeIndexChars(clname); + t << latexEscapeIndexChars(clname,insideTabbing); t << "}"; } t << "}" << endl; @@ -1401,21 +1564,15 @@ void LatexGenerator::startMemberDoc(const char *clname, if (compactLatex) level++; t << "\\" << levelLab[level]; - //if (Config_getBool("PDF_HYPERLINKS") && memname) - //{ - // t << "["; - // escapeMakeIndexChars(this,t,memname); - // t << "]"; - //} t << "[{"; - escapeMakeIndexChars(title); + t << latexEscapeIndexChars(title,insideTabbing); t << "}]"; t << "{\\setlength{\\rightskip}{0pt plus 5cm}"; disableLinks=TRUE; } -void LatexGenerator::endMemberDoc(bool) -{ +void LatexGenerator::endMemberDoc(bool) +{ disableLinks=FALSE; t << "}"; //if (Config_getBool("COMPACT_LATEX")) t << "\\hfill"; @@ -1474,16 +1631,16 @@ void LatexGenerator::addIndexItem(const char *s1,const char *s2) if (s1) { t << "\\index{"; - escapeLabelName(s1); + t << latexEscapeLabelName(s1,insideTabbing); t << "@{"; - escapeMakeIndexChars(s1); + t << latexEscapeIndexChars(s1,insideTabbing); t << "}"; if (s2) { t << "!"; - escapeLabelName(s2); + t << latexEscapeLabelName(s2,insideTabbing); t << "@{"; - escapeMakeIndexChars(s2); + t << latexEscapeIndexChars(s2,insideTabbing); t << "}"; } t << "}"; @@ -1539,94 +1696,6 @@ void LatexGenerator::docify(const char *str) filterLatexString(t,str,insideTabbing,FALSE,FALSE); } -void LatexGenerator::codify(const char *str) -{ - if (str) - { - const char *p=str; - char c; - //char cs[5]; - int spacesToNextTabStop; - static int tabSize = Config_getInt("TAB_SIZE"); - const int maxLineLen = 108; - QCString result(4*maxLineLen+1); // worst case for 1 line of 4-byte chars - int i; - while ((c=*p)) - { - switch(c) - { - case 0x0c: p++; // remove ^L - break; - case '\t': spacesToNextTabStop = - tabSize - (col%tabSize); - t << Doxygen::spaces.left(spacesToNextTabStop); - col+=spacesToNextTabStop; - p++; - break; - case '\n': t << '\n'; col=0; p++; - break; - default: - i=0; - -#undef COPYCHAR -// helper macro to copy a single utf8 character, dealing with multibyte chars. -#define COPYCHAR() do { \ - result[i++]=c; p++; \ - if (c<0) /* multibyte utf-8 character */ \ - { \ - /* 1xxx.xxxx: >=2 byte character */ \ - result[i++]=*p++; \ - if (((uchar)c&0xE0)==0xE0) \ - { \ - /* 111x.xxxx: >=3 byte character */ \ - result[i++]=*p++; \ - } \ - if (((uchar)c&0xF0)==0xF0) \ - { \ - /* 1111.xxxx: 4 byte character */ \ - result[i++]=*p++; \ - } \ - } \ - col++; \ - } while(0) - - // gather characters until we find whitespace or are at - // the end of a line - COPYCHAR(); - if (col>=maxLineLen) // force line break - { - t << "\n "; - col=0; - } - else // copy more characters - { - while (col<maxLineLen && (c=*p) && - c!=0x0c && c!='\t' && c!='\n' && c!=' ' - ) - { - COPYCHAR(); - } - if (col>=maxLineLen) // force line break - { - t << "\n "; - col=0; - } - } - result[i]=0; // add terminator - //if (m_prettyCode) - //{ - filterLatexString(t,result,insideTabbing,TRUE); - //} - //else - //{ - // t << result; - //} - break; - } - } - } -} - void LatexGenerator::writeChar(char c) { char cs[2]; @@ -2009,6 +2078,7 @@ void LatexGenerator::endConstraintList() t << "\\end{Desc}" << endl; } +#if 0 void LatexGenerator::escapeLabelName(const char *s) { if (s==0) return; @@ -2078,6 +2148,7 @@ void LatexGenerator::escapeMakeIndexChars(const char *s) } } } +#endif void LatexGenerator::startCodeFragment() { @@ -2089,61 +2160,6 @@ void LatexGenerator::endCodeFragment() t << "\\end{DoxyCode}\n"; } -void LatexGenerator::writeLineNumber(const char *ref,const char *fileName,const char *anchor,int l) -{ - static bool usePDFLatex = Config_getBool("USE_PDFLATEX"); - static bool pdfHyperlinks = Config_getBool("PDF_HYPERLINKS"); - if (m_prettyCode) - { - QCString lineNumber; - lineNumber.sprintf("%05d",l); - - if (fileName && !sourceFileName.isEmpty()) - { - QCString lineAnchor; - lineAnchor.sprintf("_l%05d",l); - lineAnchor.prepend(sourceFileName); - //if (!m_prettyCode) return; - if (usePDFLatex && pdfHyperlinks) - { - t << "\\hypertarget{" << stripPath(lineAnchor) << "}{}"; - } - writeCodeLink(ref,fileName,anchor,lineNumber,0); - } - else - { - codify(lineNumber); - } - t << " "; - } - else - { - t << l << " "; - } -} - -void LatexGenerator::startCodeLine(bool) -{ - col=0; -} - -void LatexGenerator::endCodeLine() -{ - codify("\n"); -} - -void LatexGenerator::startFontClass(const char *name) -{ - //if (!m_prettyCode) return; - t << "\\textcolor{" << name << "}{"; -} - -void LatexGenerator::endFontClass() -{ - //if (!m_prettyCode) return; - t << "}"; -} - void LatexGenerator::startInlineHeader() { if (Config_getBool("COMPACT_LATEX")) @@ -2227,3 +2243,4 @@ void LatexGenerator::endLabels() { } + diff --git a/src/latexgen.h b/src/latexgen.h index ee67803..84382a7 100644 --- a/src/latexgen.h +++ b/src/latexgen.h @@ -24,6 +24,48 @@ class QFile; static const char *latexStyleExtension = ".sty"; +class LatexCodeGenerator : public CodeOutputInterface +{ + public: + LatexCodeGenerator(FTextStream &t,const QCString &relPath,const QCString &sourceFile); + LatexCodeGenerator(); + void setTextStream(FTextStream &t); + void setRelativePath(const QCString &path); + void setSourceFileName(const QCString &sourceFileName); + void codify(const char *text); + void writeCodeLink(const char *ref,const char *file, + const char *anchor,const char *name, + const char *tooltip); + void writeTooltip(const char *, + const DocLinkInfo &, + const char *, + const char *, + const SourceLinkInfo &, + const SourceLinkInfo & + ) {} + void writeLineNumber(const char *,const char *,const char *,int); + void startCodeLine(bool); + void endCodeLine(); + void startFontClass(const char *); + void endFontClass(); + void writeCodeAnchor(const char *) {} + void setCurrentDoc(Definition *,const char *,bool) {} + void addWord(const char *,bool) {} + + private: + void _writeCodeLink(const char *className, + const char *ref,const char *file, + const char *anchor,const char *name, + const char *tooltip); + void docify(const char *str); + bool m_streamSet; + FTextStream m_t; + QCString m_relPath; + QCString m_sourceFileName; + int m_col; + bool m_prettyCode; +}; + /** Generator for LaTeX output. */ class LatexGenerator : public OutputGenerator { @@ -47,6 +89,32 @@ class LatexGenerator : public OutputGenerator bool isEnabled(OutputType o) { return (o==Latex && active); } OutputGenerator *get(OutputType o) { return (o==Latex) ? this : 0; } + // --- CodeOutputInterface + void codify(const char *text) + { m_codeGen.codify(text); } + void writeCodeLink(const char *ref, const char *file, + const char *anchor,const char *name, + const char *tooltip) + { m_codeGen.writeCodeLink(ref,file,anchor,name,tooltip); } + void writeLineNumber(const char *ref,const char *file,const char *anchor,int lineNumber) + { m_codeGen.writeLineNumber(ref,file,anchor,lineNumber); } + void writeTooltip(const char *id, const DocLinkInfo &docInfo, const char *decl, + const char *desc, const SourceLinkInfo &defInfo, const SourceLinkInfo &declInfo + ) + { m_codeGen.writeTooltip(id,docInfo,decl,desc,defInfo,declInfo); } + void startCodeLine(bool hasLineNumbers) + { m_codeGen.startCodeLine(hasLineNumbers); } + void endCodeLine() + { m_codeGen.endCodeLine(); } + void startFontClass(const char *s) + { m_codeGen.startFontClass(s); } + void endFontClass() + { m_codeGen.endFontClass(); } + void writeCodeAnchor(const char *anchor) + { m_codeGen.writeCodeAnchor(anchor); } + // --------------------------- + + void writeDoc(DocNode *,Definition *ctx,MemberDef *); void startFile(const char *name,const char *manName,const char *title); @@ -83,15 +151,9 @@ class LatexGenerator : public OutputGenerator void startIndexItem(const char *ref,const char *file); void endIndexItem(const char *ref,const char *file); void docify(const char *text); - void codify(const char *text); void writeObjectLink(const char *ref,const char *file, const char *anchor,const char *name); - void writeCodeLink(const char *ref, const char *file, - const char *anchor,const char *name, - const char *tooltip); - void writeTooltip(const char *, const DocLinkInfo &, const char *, - const char *, const SourceLinkInfo &, const SourceLinkInfo & - ) {} + void startTextLink(const char *,const char *); void endTextLink(); void startHtmlLink(const char *url); @@ -137,9 +199,6 @@ class LatexGenerator : public OutputGenerator void writeAnchor(const char *fileName,const char *name); void startCodeFragment(); void endCodeFragment(); - void writeLineNumber(const char *,const char *,const char *,int l); - void startCodeLine(bool hasLineNumbers); - void endCodeLine(); void startEmphasis() { t << "{\\em "; } void endEmphasis() { t << "}"; } void startBold() { t << "{\\bfseries "; } @@ -267,10 +326,6 @@ class LatexGenerator : public OutputGenerator void writeLabel(const char *l,bool isLast); void endLabels(); - void startFontClass(const char *); // {} - void endFontClass(); // {} - - void writeCodeAnchor(const char *) {} void setCurrentDoc(Definition *,const char *,bool) {} void addWord(const char *,bool) {} @@ -278,17 +333,14 @@ class LatexGenerator : public OutputGenerator private: LatexGenerator(const LatexGenerator &); LatexGenerator &operator=(const LatexGenerator &); - void escapeLabelName(const char *s); - void escapeMakeIndexChars(const char *s); - int col; bool insideTabbing; bool firstDescItem; bool disableLinks; QCString relPath; - QCString sourceFileName; int m_indent; bool templateMemberItem; bool m_prettyCode; + LatexCodeGenerator m_codeGen; }; #endif diff --git a/src/searchindex.cpp b/src/searchindex.cpp index ee545bf..9bfe7b0 100644 --- a/src/searchindex.cpp +++ b/src/searchindex.cpp @@ -583,70 +583,9 @@ void SearchIndexExternal::write(const char *fileName) #include "doxygen.h" #include "message.h" -//static const char search_script[]= -//#include "search.js.h" -//; - -#define SEARCH_INDEX_ALL 0 -#define SEARCH_INDEX_CLASSES 1 -#define SEARCH_INDEX_NAMESPACES 2 -#define SEARCH_INDEX_FILES 3 -#define SEARCH_INDEX_FUNCTIONS 4 -#define SEARCH_INDEX_VARIABLES 5 -#define SEARCH_INDEX_TYPEDEFS 6 -#define SEARCH_INDEX_ENUMS 7 -#define SEARCH_INDEX_ENUMVALUES 8 -#define SEARCH_INDEX_PROPERTIES 9 -#define SEARCH_INDEX_EVENTS 10 -#define SEARCH_INDEX_RELATED 11 -#define SEARCH_INDEX_DEFINES 12 -#define SEARCH_INDEX_GROUPS 13 -#define SEARCH_INDEX_PAGES 14 -#define NUM_SEARCH_INDICES 15 - -class SearchDefinitionList : public QList<Definition> -{ - public: - SearchDefinitionList(uint letter) : m_letter(letter) {} - uint letter() const { return m_letter; } - private: - uint m_letter; -}; +static SearchIndexInfo g_searchIndexInfo[NUM_SEARCH_INDICES]; -class SearchIndexList : public SDict< SearchDefinitionList > -{ - public: - typedef Definition ElementType; - SearchIndexList(uint letter) : SDict<SearchDefinitionList>(17,FALSE), m_letter(letter) - { - setAutoDelete(TRUE); - } - ~SearchIndexList() {} - void append(Definition *d) - { - SearchDefinitionList *l = find(d->name()); - if (l==0) - { - l=new SearchDefinitionList(m_letter); - SDict<SearchDefinitionList>::append(d->name(),l); - } - l->append(d); - } - uint letter() const { return m_letter; } - private: - int compareValues(const SearchDefinitionList *md1, const SearchDefinitionList *md2) const - { - QCString n1 = md1->getFirst()->localName(); - QCString n2 = md2->getFirst()->localName(); - return qstricmp(n1.data(),n2.data()); - } - uint m_letter; -}; - -static void addMemberToSearchIndex( - LetterToIndexMap<SearchIndexList> symbols[NUM_SEARCH_INDICES], - int symbolCount[NUM_SEARCH_INDICES], - MemberDef *md) +static void addMemberToSearchIndex(MemberDef *md) { static bool hideFriendCompounds = Config_getBool("HIDE_FRIEND_COMPOUNDS"); bool isLinkable = md->isLinkable(); @@ -654,7 +593,7 @@ static void addMemberToSearchIndex( NamespaceDef *nd=0; FileDef *fd=0; GroupDef *gd=0; - if (isLinkable && + if (isLinkable && ( ((cd=md->getClassDef()) && cd->isLinkable() && cd->templateMaster()==0) || ((gd=md->getGroupDef()) && gd->isLinkable()) @@ -662,58 +601,49 @@ static void addMemberToSearchIndex( ) { QCString n = md->name(); - if (!n.isEmpty()) + if (!n.isEmpty()) { uint letter = getUtf8CodeToLower(n,0); bool isFriendToHide = hideFriendCompounds && - (QCString(md->typeString())=="friend class" || + (QCString(md->typeString())=="friend class" || QCString(md->typeString())=="friend struct" || QCString(md->typeString())=="friend union"); if (!(md->isFriend() && isFriendToHide)) { - symbols[SEARCH_INDEX_ALL].append(letter,md); - symbolCount[SEARCH_INDEX_ALL]++; + g_searchIndexInfo[SEARCH_INDEX_ALL].symbolList.append(letter,md); } if (md->isFunction() || md->isSlot() || md->isSignal()) { - symbols[SEARCH_INDEX_FUNCTIONS].append(letter,md); - symbolCount[SEARCH_INDEX_FUNCTIONS]++; - } + g_searchIndexInfo[SEARCH_INDEX_FUNCTIONS].symbolList.append(letter,md); + } else if (md->isVariable()) { - symbols[SEARCH_INDEX_VARIABLES].append(letter,md); - symbolCount[SEARCH_INDEX_VARIABLES]++; + g_searchIndexInfo[SEARCH_INDEX_VARIABLES].symbolList.append(letter,md); } else if (md->isTypedef()) { - symbols[SEARCH_INDEX_TYPEDEFS].append(letter,md); - symbolCount[SEARCH_INDEX_TYPEDEFS]++; + g_searchIndexInfo[SEARCH_INDEX_TYPEDEFS].symbolList.append(letter,md); } else if (md->isEnumerate()) { - symbols[SEARCH_INDEX_ENUMS].append(letter,md); - symbolCount[SEARCH_INDEX_ENUMS]++; + g_searchIndexInfo[SEARCH_INDEX_ENUMS].symbolList.append(letter,md); } else if (md->isEnumValue()) { - symbols[SEARCH_INDEX_ENUMVALUES].append(letter,md); - symbolCount[SEARCH_INDEX_ENUMVALUES]++; + g_searchIndexInfo[SEARCH_INDEX_ENUMVALUES].symbolList.append(letter,md); } else if (md->isProperty()) { - symbols[SEARCH_INDEX_PROPERTIES].append(letter,md); - symbolCount[SEARCH_INDEX_PROPERTIES]++; + g_searchIndexInfo[SEARCH_INDEX_PROPERTIES].symbolList.append(letter,md); } else if (md->isEvent()) { - symbols[SEARCH_INDEX_EVENTS].append(letter,md); - symbolCount[SEARCH_INDEX_EVENTS]++; + g_searchIndexInfo[SEARCH_INDEX_EVENTS].symbolList.append(letter,md); } else if (md->isRelated() || md->isForeign() || (md->isFriend() && !isFriendToHide)) { - symbols[SEARCH_INDEX_RELATED].append(letter,md); - symbolCount[SEARCH_INDEX_RELATED]++; + g_searchIndexInfo[SEARCH_INDEX_RELATED].symbolList.append(letter,md); } } } @@ -727,38 +657,31 @@ static void addMemberToSearchIndex( if (!n.isEmpty()) { uint letter = getUtf8CodeToLower(n,0); - symbols[SEARCH_INDEX_ALL].append(letter,md); - symbolCount[SEARCH_INDEX_ALL]++; + g_searchIndexInfo[SEARCH_INDEX_ALL].symbolList.append(letter,md); if (md->isFunction()) { - symbols[SEARCH_INDEX_FUNCTIONS].append(letter,md); - symbolCount[SEARCH_INDEX_FUNCTIONS]++; + g_searchIndexInfo[SEARCH_INDEX_FUNCTIONS].symbolList.append(letter,md); } else if (md->isVariable()) { - symbols[SEARCH_INDEX_VARIABLES].append(letter,md); - symbolCount[SEARCH_INDEX_VARIABLES]++; + g_searchIndexInfo[SEARCH_INDEX_VARIABLES].symbolList.append(letter,md); } else if (md->isTypedef()) { - symbols[SEARCH_INDEX_TYPEDEFS].append(letter,md); - symbolCount[SEARCH_INDEX_TYPEDEFS]++; + g_searchIndexInfo[SEARCH_INDEX_TYPEDEFS].symbolList.append(letter,md); } else if (md->isEnumerate()) { - symbols[SEARCH_INDEX_ENUMS].append(letter,md); - symbolCount[SEARCH_INDEX_ENUMS]++; + g_searchIndexInfo[SEARCH_INDEX_ENUMS].symbolList.append(letter,md); } else if (md->isEnumValue()) { - symbols[SEARCH_INDEX_ENUMVALUES].append(letter,md); - symbolCount[SEARCH_INDEX_ENUMVALUES]++; + g_searchIndexInfo[SEARCH_INDEX_ENUMVALUES].symbolList.append(letter,md); } else if (md->isDefine()) { - symbols[SEARCH_INDEX_DEFINES].append(letter,md); - symbolCount[SEARCH_INDEX_DEFINES]++; + g_searchIndexInfo[SEARCH_INDEX_DEFINES].symbolList.append(letter,md); } } } @@ -792,55 +715,43 @@ static QCString searchId(const QCString &s) return result; } -static int g_searchIndexCount[NUM_SEARCH_INDICES]; -static LetterToIndexMap<SearchIndexList> g_searchIndexSymbols[NUM_SEARCH_INDICES]; -static const char *g_searchIndexName[NUM_SEARCH_INDICES] = -{ - "all", - "classes", - "namespaces", - "files", - "functions", - "variables", - "typedefs", - "enums", - "enumvalues", - "properties", - "events", - "related", - "defines", - "groups", - "pages" -}; - - -class SearchIndexCategoryMapping +void createJavascriptSearchIndex() { - public: - SearchIndexCategoryMapping() - { - categoryLabel[SEARCH_INDEX_ALL] = theTranslator->trAll(); - categoryLabel[SEARCH_INDEX_CLASSES] = theTranslator->trClasses(); - categoryLabel[SEARCH_INDEX_NAMESPACES] = theTranslator->trNamespace(TRUE,FALSE); - categoryLabel[SEARCH_INDEX_FILES] = theTranslator->trFile(TRUE,FALSE); - categoryLabel[SEARCH_INDEX_FUNCTIONS] = theTranslator->trFunctions(); - categoryLabel[SEARCH_INDEX_VARIABLES] = theTranslator->trVariables(); - categoryLabel[SEARCH_INDEX_TYPEDEFS] = theTranslator->trTypedefs(); - categoryLabel[SEARCH_INDEX_ENUMS] = theTranslator->trEnumerations(); - categoryLabel[SEARCH_INDEX_ENUMVALUES] = theTranslator->trEnumerationValues(); - categoryLabel[SEARCH_INDEX_PROPERTIES] = theTranslator->trProperties(); - categoryLabel[SEARCH_INDEX_EVENTS] = theTranslator->trEvents(); - categoryLabel[SEARCH_INDEX_RELATED] = theTranslator->trFriends(); - categoryLabel[SEARCH_INDEX_DEFINES] = theTranslator->trDefines(); - categoryLabel[SEARCH_INDEX_GROUPS] = theTranslator->trGroup(TRUE,FALSE); - categoryLabel[SEARCH_INDEX_PAGES] = theTranslator->trPage(TRUE,FALSE); - } - QCString categoryLabel[NUM_SEARCH_INDICES]; -}; - -void writeJavascriptSearchIndex() -{ - if (!Config_getBool("GENERATE_HTML")) return; + // set index names + g_searchIndexInfo[SEARCH_INDEX_ALL].name = "all"; + g_searchIndexInfo[SEARCH_INDEX_CLASSES].name = "classes"; + g_searchIndexInfo[SEARCH_INDEX_NAMESPACES].name = "namespaces"; + g_searchIndexInfo[SEARCH_INDEX_FILES].name = "files"; + g_searchIndexInfo[SEARCH_INDEX_FUNCTIONS].name = "functions"; + g_searchIndexInfo[SEARCH_INDEX_VARIABLES].name = "variables"; + g_searchIndexInfo[SEARCH_INDEX_TYPEDEFS].name = "typedefs"; + g_searchIndexInfo[SEARCH_INDEX_ENUMS].name = "enums"; + g_searchIndexInfo[SEARCH_INDEX_ENUMVALUES].name = "enumvalues"; + g_searchIndexInfo[SEARCH_INDEX_PROPERTIES].name = "properties"; + g_searchIndexInfo[SEARCH_INDEX_EVENTS].name = "events"; + g_searchIndexInfo[SEARCH_INDEX_RELATED].name = "related"; + g_searchIndexInfo[SEARCH_INDEX_DEFINES].name = "defines"; + g_searchIndexInfo[SEARCH_INDEX_GROUPS].name = "groups"; + g_searchIndexInfo[SEARCH_INDEX_PAGES].name = "pages"; + + // set index texts + g_searchIndexInfo[SEARCH_INDEX_ALL].text = theTranslator->trAll(); + g_searchIndexInfo[SEARCH_INDEX_CLASSES].text = theTranslator->trClasses(); + g_searchIndexInfo[SEARCH_INDEX_NAMESPACES].text = theTranslator->trNamespace(TRUE,FALSE); + g_searchIndexInfo[SEARCH_INDEX_FILES].text = theTranslator->trFile(TRUE,FALSE); + g_searchIndexInfo[SEARCH_INDEX_FUNCTIONS].text = theTranslator->trFunctions(); + g_searchIndexInfo[SEARCH_INDEX_VARIABLES].text = theTranslator->trVariables(); + g_searchIndexInfo[SEARCH_INDEX_TYPEDEFS].text = theTranslator->trTypedefs(); + g_searchIndexInfo[SEARCH_INDEX_ENUMS].text = theTranslator->trEnumerations(); + g_searchIndexInfo[SEARCH_INDEX_ENUMVALUES].text = theTranslator->trEnumerationValues(); + g_searchIndexInfo[SEARCH_INDEX_PROPERTIES].text = theTranslator->trProperties(); + g_searchIndexInfo[SEARCH_INDEX_EVENTS].text = theTranslator->trEvents(); + g_searchIndexInfo[SEARCH_INDEX_RELATED].text = theTranslator->trFriends(); + g_searchIndexInfo[SEARCH_INDEX_DEFINES].text = theTranslator->trDefines(); + g_searchIndexInfo[SEARCH_INDEX_GROUPS].text = theTranslator->trGroup(TRUE,FALSE); + g_searchIndexInfo[SEARCH_INDEX_PAGES].text = theTranslator->trPage(TRUE,FALSE); + + // add symbols to letter -> symbol list map // index classes ClassSDict::Iterator cli(*Doxygen::classSDict); @@ -850,10 +761,8 @@ void writeJavascriptSearchIndex() uint letter = getUtf8CodeToLower(cd->localName(),0); if (cd->isLinkable() && isId(letter)) { - g_searchIndexSymbols[SEARCH_INDEX_ALL].append(letter,cd); - g_searchIndexSymbols[SEARCH_INDEX_CLASSES].append(letter,cd); - g_searchIndexCount[SEARCH_INDEX_ALL]++; - g_searchIndexCount[SEARCH_INDEX_CLASSES]++; + g_searchIndexInfo[SEARCH_INDEX_ALL].symbolList.append(letter,cd); + g_searchIndexInfo[SEARCH_INDEX_CLASSES].symbolList.append(letter,cd); } } @@ -865,10 +774,8 @@ void writeJavascriptSearchIndex() uint letter = getUtf8CodeToLower(nd->name(),0); if (nd->isLinkable() && isId(letter)) { - g_searchIndexSymbols[SEARCH_INDEX_ALL].append(letter,nd); - g_searchIndexSymbols[SEARCH_INDEX_NAMESPACES].append(letter,nd); - g_searchIndexCount[SEARCH_INDEX_ALL]++; - g_searchIndexCount[SEARCH_INDEX_NAMESPACES]++; + g_searchIndexInfo[SEARCH_INDEX_ALL].symbolList.append(letter,nd); + g_searchIndexInfo[SEARCH_INDEX_NAMESPACES].symbolList.append(letter,nd); } } @@ -884,10 +791,8 @@ void writeJavascriptSearchIndex() uint letter = getUtf8CodeToLower(fd->name(),0); if (fd->isLinkable() && isId(letter)) { - g_searchIndexSymbols[SEARCH_INDEX_ALL].append(letter,fd); - g_searchIndexSymbols[SEARCH_INDEX_FILES].append(letter,fd); - g_searchIndexCount[SEARCH_INDEX_ALL]++; - g_searchIndexCount[SEARCH_INDEX_FILES]++; + g_searchIndexInfo[SEARCH_INDEX_ALL].symbolList.append(letter,fd); + g_searchIndexInfo[SEARCH_INDEX_FILES].symbolList.append(letter,fd); } } } @@ -904,7 +809,7 @@ void writeJavascriptSearchIndex() // for each member definition for (mni.toFirst();(md=mni.current());++mni) { - addMemberToSearchIndex(g_searchIndexSymbols,g_searchIndexCount,md); + addMemberToSearchIndex(md); } } } @@ -921,7 +826,7 @@ void writeJavascriptSearchIndex() // for each member definition for (mni.toFirst();(md=mni.current());++mni) { - addMemberToSearchIndex(g_searchIndexSymbols,g_searchIndexCount,md); + addMemberToSearchIndex(md); } } } @@ -940,10 +845,8 @@ void writeJavascriptSearchIndex() uint letter = charCode<128 ? tolower(charCode) : charCode; if (isId(letter)) { - g_searchIndexSymbols[SEARCH_INDEX_ALL].append(letter,gd); - g_searchIndexSymbols[SEARCH_INDEX_GROUPS].append(letter,gd); - g_searchIndexCount[SEARCH_INDEX_ALL]++; - g_searchIndexCount[SEARCH_INDEX_GROUPS]++; + g_searchIndexInfo[SEARCH_INDEX_ALL].symbolList.append(letter,gd); + g_searchIndexInfo[SEARCH_INDEX_GROUPS].symbolList.append(letter,gd); } } } @@ -963,10 +866,8 @@ void writeJavascriptSearchIndex() uint letter = charCode<128 ? tolower(charCode) : charCode; if (isId(letter)) { - g_searchIndexSymbols[SEARCH_INDEX_ALL].append(letter,pd); - g_searchIndexSymbols[SEARCH_INDEX_PAGES].append(letter,pd); - g_searchIndexCount[SEARCH_INDEX_ALL]++; - g_searchIndexCount[SEARCH_INDEX_PAGES]++; + g_searchIndexInfo[SEARCH_INDEX_ALL].symbolList.append(letter,pd); + g_searchIndexInfo[SEARCH_INDEX_PAGES].symbolList.append(letter,pd); } } } @@ -980,38 +881,40 @@ void writeJavascriptSearchIndex() uint letter = charCode<128 ? tolower(charCode) : charCode; if (isId(letter)) { - g_searchIndexSymbols[SEARCH_INDEX_ALL].append(letter,Doxygen::mainPage); - g_searchIndexSymbols[SEARCH_INDEX_PAGES].append(letter,Doxygen::mainPage); - g_searchIndexCount[SEARCH_INDEX_ALL]++; - g_searchIndexCount[SEARCH_INDEX_PAGES]++; + g_searchIndexInfo[SEARCH_INDEX_ALL].symbolList.append(letter,Doxygen::mainPage); + g_searchIndexInfo[SEARCH_INDEX_PAGES].symbolList.append(letter,Doxygen::mainPage); } } } - + // sort all lists int i; for (i=0;i<NUM_SEARCH_INDICES;i++) { - SIntDict<SearchIndexList>::Iterator it(g_searchIndexSymbols[i]); + SIntDict<SearchIndexList>::Iterator it(g_searchIndexInfo[i].symbolList); SearchIndexList *sl; for (it.toFirst();(sl=it.current());++it) { sl->sort(); } } +} +void writeJavascriptSearchIndex() +{ + int i; // write index files QCString searchDirName = Config_getString("HTML_OUTPUT")+"/search"; for (i=0;i<NUM_SEARCH_INDICES;i++) // for each index { - SIntDict<SearchIndexList>::Iterator it(g_searchIndexSymbols[i]); + SIntDict<SearchIndexList>::Iterator it(g_searchIndexInfo[i].symbolList); SearchIndexList *sl; int p=0; for (it.toFirst();(sl=it.current());++it,++p) // for each letter { QCString baseName; - baseName.sprintf("%s_%x",g_searchIndexName[i],p); + baseName.sprintf("%s_%x",g_searchIndexInfo[i].name.data(),p); QCString fileName = searchDirName + "/"+baseName+".html"; QCString dataFileName = searchDirName + "/"+baseName+".js"; @@ -1083,17 +986,7 @@ void writeJavascriptSearchIndex() } firstEntry=FALSE; - QCString dispName = d->localName(); - if (d->definitionType()==Definition::TypeGroup) - { - dispName = ((GroupDef*)d)->groupTitle(); - } - else if (d->definitionType()==Definition::TypePage) - { - dispName = ((PageDef*)d)->title(); - } - ti << " ['" << searchId(dispName) << "',['" - << convertToXML(dispName) << "',["; + ti << " ['" << dl->id() << "',['" << convertToXML(dl->name()) << "',["; if (dl->count()==1) // item with a unique name { @@ -1274,12 +1167,12 @@ void writeJavascriptSearchIndex() int j=0; for (i=0;i<NUM_SEARCH_INDICES;i++) { - if (g_searchIndexCount[i]>0) + if (g_searchIndexInfo[i].symbolList.count()>0) { if (!first) t << "," << endl; t << " " << j << ": \""; - SIntDict<SearchIndexList>::Iterator it(g_searchIndexSymbols[i]); + SIntDict<SearchIndexList>::Iterator it(g_searchIndexInfo[i].symbolList); SearchIndexList *sl; for (it.toFirst();(sl=it.current());++it) // for each letter { @@ -1298,10 +1191,10 @@ void writeJavascriptSearchIndex() j=0; for (i=0;i<NUM_SEARCH_INDICES;i++) { - if (g_searchIndexCount[i]>0) + if (g_searchIndexInfo[i].symbolList.count()>0) { if (!first) t << "," << endl; - t << " " << j << ": \"" << g_searchIndexName[i] << "\""; + t << " " << j << ": \"" << g_searchIndexInfo[i].name << "\""; first=FALSE; j++; } @@ -1311,14 +1204,13 @@ void writeJavascriptSearchIndex() t << "var indexSectionLabels =" << endl; t << "{" << endl; first=TRUE; - static SearchIndexCategoryMapping map; j=0; for (i=0;i<NUM_SEARCH_INDICES;i++) { - if (g_searchIndexCount[i]>0) + if (g_searchIndexInfo[i].symbolList.count()>0) { if (!first) t << "," << endl; - t << " " << j << ": \"" << convertToXML(map.categoryLabel[i]) << "\""; + t << " " << j << ": \"" << convertToXML(g_searchIndexInfo[i].text) << "\""; first=FALSE; j++; } @@ -1352,6 +1244,55 @@ void writeJavascriptSearchIndex() Doxygen::indexList->addStyleSheetFile("search/search.js"); } +const SearchIndexInfo *getSearchIndices() +{ + return g_searchIndexInfo; +} + +//--------------------------------------------------------------------------------------------- + +SearchIndexList::SearchIndexList(uint letter) + : SDict< SearchDefinitionList >(17,FALSE), m_letter(letter) +{ + setAutoDelete(TRUE); +} + +SearchIndexList::~SearchIndexList() +{ +} + +void SearchIndexList::append(Definition *d) +{ + SearchDefinitionList *l = find(d->name()); + if (l==0) + { + QCString dispName = d->localName(); + if (d->definitionType()==Definition::TypeGroup) + { + dispName = ((GroupDef*)d)->groupTitle(); + } + else if (d->definitionType()==Definition::TypePage) + { + dispName = ((PageDef*)d)->title(); + } + l=new SearchDefinitionList(searchId(dispName),dispName); + SDict< SearchDefinitionList >::append(d->name(),l); + } + l->append(d); +} + +uint SearchIndexList::letter() const +{ + return m_letter; +} + +int SearchIndexList::compareValues(const SearchDefinitionList *md1, const SearchDefinitionList *md2) const +{ + QCString n1 = md1->getFirst()->localName(); + QCString n2 = md2->getFirst()->localName(); + return qstricmp(n1.data(),n2.data()); +} + //--------------------------------------------------------------------------------------------- void initSearchIndexer() diff --git a/src/searchindex.h b/src/searchindex.h index b9f45c6..e491f47 100644 --- a/src/searchindex.h +++ b/src/searchindex.h @@ -23,6 +23,9 @@ #include <qdict.h> #include <qintdict.h> #include <qvector.h> +#include "sortdict.h" +#include "definition.h" +#include "util.h" class FTextStream; class Definition; @@ -109,6 +112,56 @@ class SearchIndexExternal : public SearchIndexIntf //------- client side search index ---------------------- +#define SEARCH_INDEX_ALL 0 +#define SEARCH_INDEX_CLASSES 1 +#define SEARCH_INDEX_NAMESPACES 2 +#define SEARCH_INDEX_FILES 3 +#define SEARCH_INDEX_FUNCTIONS 4 +#define SEARCH_INDEX_VARIABLES 5 +#define SEARCH_INDEX_TYPEDEFS 6 +#define SEARCH_INDEX_ENUMS 7 +#define SEARCH_INDEX_ENUMVALUES 8 +#define SEARCH_INDEX_PROPERTIES 9 +#define SEARCH_INDEX_EVENTS 10 +#define SEARCH_INDEX_RELATED 11 +#define SEARCH_INDEX_DEFINES 12 +#define SEARCH_INDEX_GROUPS 13 +#define SEARCH_INDEX_PAGES 14 +#define NUM_SEARCH_INDICES 15 + +class SearchDefinitionList : public QList<Definition> +{ + public: + SearchDefinitionList(const QCString &id,const QCString &name) : m_id(id), m_name(name) {} + QCString id() const { return m_id; } + QCString name() const { return m_name; } + private: + QCString m_id; + QCString m_name; +}; + +class SearchIndexList : public SDict< SearchDefinitionList > +{ + public: + typedef Definition ElementType; + SearchIndexList(uint letter); + ~SearchIndexList(); + void append(Definition *d); + uint letter() const; + private: + int compareValues(const SearchDefinitionList *md1, const SearchDefinitionList *md2) const; + uint m_letter; +}; + +struct SearchIndexInfo +{ + LetterToIndexMap<SearchIndexList> symbolList; + QCString name; + QCString text; +}; + +void createJavascriptSearchIndex(); void writeJavascriptSearchIndex(); +const SearchIndexInfo *getSearchIndices(); #endif diff --git a/src/template.cpp b/src/template.cpp index 5102978..f75d13e 100644 --- a/src/template.cpp +++ b/src/template.cpp @@ -98,6 +98,36 @@ static QValueList<QCString> split(const QCString &str,const QCString &sep, //---------------------------------------------------------------------------- +/** Strips spaces surrounding `=` from string \a in, so + * `foo = 10 bar=5 baz= 'hello'` will become `foo=10 bar=5 baz='hello'` + */ +static QCString removeSpacesAroundEquals(const char *s) +{ + QCString result(s); + const char *p=result.data(); + char *q = result.rawData(); + char c; + while ((c=*p++)) + { + if (c==' ') // found a space, see if there is a = as well + { + const char *t = p; + bool found=FALSE; + while (*t==' ' || *t=='=') { if (*t++=='=') found=TRUE; } + if (found) + { + c='='; + p=t; // move p to end of '\s*=\s*' sequence + } + } + *q++=c; + } + if (q<p) result.resize(q-result.data()+1); + return result; +} + +//---------------------------------------------------------------------------- + #if ENABLE_TRACING static QCString replace(const char *s,char csrc,char cdst) { @@ -699,6 +729,10 @@ class TemplateContextImpl : public TemplateContext m_spacelessEnabled=b; } bool spacelessEnabled() const { return m_spacelessEnabled && m_spacelessIntf; } + void enableTabbing(bool b) { m_tabbingEnabled=b; + if (m_activeEscapeIntf) m_activeEscapeIntf->enableTabbing(b); + } + bool tabbingEnabled() const { return m_tabbingEnabled; } void warn(const char *fileName,int line,const char *fmt,...) const; // index related functions @@ -717,6 +751,7 @@ class TemplateContextImpl : public TemplateContext TemplateEscapeIntf *m_activeEscapeIntf; TemplateSpacelessIntf *m_spacelessIntf; bool m_spacelessEnabled; + bool m_tabbingEnabled; TemplateAutoRef<TemplateStruct> m_indices; QDict< QStack<TemplateVariant> > m_indexStacks; }; @@ -783,6 +818,62 @@ class FilterGet } }; +//----------------------------------------------------------------------------- + +/** @brief The implementation of the "raw" filter */ +class FilterRaw +{ + public: + static TemplateVariant apply(const TemplateVariant &v,const TemplateVariant &) + { + if (v.isValid() && (v.type()==TemplateVariant::String || v.type()==TemplateVariant::Integer)) + { + return TemplateVariant(v.toString(),TRUE); + } + else + { + return v; + } + } +}; + +//----------------------------------------------------------------------------- + +/** @brief The implementation of the "texlabel" filter */ +class FilterTexLabel +{ + public: + static TemplateVariant apply(const TemplateVariant &v,const TemplateVariant &) + { + if (v.isValid() && (v.type()==TemplateVariant::String)) + { + return TemplateVariant(latexEscapeLabelName(v.toString(),FALSE),TRUE); + } + else + { + return v; + } + } +}; + +//----------------------------------------------------------------------------- + +/** @brief The implementation of the "texindex" filter */ +class FilterTexIndex +{ + public: + static TemplateVariant apply(const TemplateVariant &v,const TemplateVariant &) + { + if (v.isValid() && (v.type()==TemplateVariant::String)) + { + return TemplateVariant(latexEscapeIndexChars(v.toString(),FALSE),TRUE); + } + else + { + return v; + } + } +}; //----------------------------------------------------------------------------- @@ -793,7 +884,7 @@ class FilterAppend static TemplateVariant apply(const TemplateVariant &v,const TemplateVariant &arg) { if ((v.type()==TemplateVariant::String || v.type()==TemplateVariant::Integer) && - arg.type()==TemplateVariant::String) + (arg.type()==TemplateVariant::String || arg.type()==TemplateVariant::Integer)) { return TemplateVariant(v.toString() + arg.toString()); } @@ -1088,6 +1179,25 @@ class FilterGroupBy //-------------------------------------------------------------------- +/** @brief The implementation of the "relative" filter */ +class FilterRelative +{ + public: + static TemplateVariant apply(const TemplateVariant &v,const TemplateVariant &) + { + if (v.isValid() && v.type()==TemplateVariant::String && v.toString().left(2)=="..") + { + return TRUE; + } + else + { + return FALSE; + } + } +}; + +//-------------------------------------------------------------------- + /** @brief The implementation of the "paginate" filter */ class FilterPaginate { @@ -1381,6 +1491,7 @@ class TemplateFilterFactory // register a handlers for each filter we support static TemplateFilterFactory::AutoRegister<FilterAdd> fAdd("add"); static TemplateFilterFactory::AutoRegister<FilterGet> fGet("get"); +static TemplateFilterFactory::AutoRegister<FilterRaw> fRaw("raw"); static TemplateFilterFactory::AutoRegister<FilterAppend> fAppend("append"); static TemplateFilterFactory::AutoRegister<FilterLength> fLength("length"); static TemplateFilterFactory::AutoRegister<FilterNoWrap> fNoWrap("nowrap"); @@ -1388,7 +1499,10 @@ static TemplateFilterFactory::AutoRegister<FilterFlatten> fFlatten("flatten" static TemplateFilterFactory::AutoRegister<FilterDefault> fDefault("default"); static TemplateFilterFactory::AutoRegister<FilterPrepend> fPrepend("prepend"); static TemplateFilterFactory::AutoRegister<FilterGroupBy> fGroupBy("groupBy"); +static TemplateFilterFactory::AutoRegister<FilterRelative> fRelative("relative"); static TemplateFilterFactory::AutoRegister<FilterListSort> fListSort("listsort"); +static TemplateFilterFactory::AutoRegister<FilterTexLabel> fTexLabel("texLabel"); +static TemplateFilterFactory::AutoRegister<FilterTexIndex> fTexIndex("texIndex"); static TemplateFilterFactory::AutoRegister<FilterPaginate> fPaginate("paginate"); static TemplateFilterFactory::AutoRegister<FilterStripPath> fStripPath("stripPath"); static TemplateFilterFactory::AutoRegister<FilterAlphaIndex> fAlphaIndex("alphaIndex"); @@ -1978,14 +2092,6 @@ class ExpressionParser TRACE(("{parseLiteral(%s)\n",m_curToken.id.data())); ExprAst *expr = new ExprAstLiteral(m_curToken.id); getNextToken(); - while (m_curToken.type==ExprToken::Operator && - m_curToken.op==Operator::Filter) - { - getNextToken(); - ExprAstFilter *filter = parseFilter(); - if (!filter) break; - expr = new ExprAstFilterAppl(expr,filter); - } TRACE(("}parseLiteral()\n")); return expr; } @@ -2304,7 +2410,8 @@ class TemplateNodeList : public QList<TemplateNode> class TemplateImpl : public TemplateNode, public Template { public: - TemplateImpl(TemplateEngine *e,const QCString &name,const char *data,int size); + TemplateImpl(TemplateEngine *e,const QCString &name,const char *data,int size, + const QCString &extension); void render(FTextStream &ts, TemplateContext *c); TemplateEngine *engine() const { return m_engine; } @@ -2658,7 +2765,6 @@ class TemplateNodeVariable : public TemplateNode { v = v.call(QValueList<TemplateVariant>()); } - //printf("TemplateNodeVariable::render(%s) raw=%d\n",value.data(),v.raw()); if (ci->escapeIntf() && !v.raw()) { ts << ci->escapeIntf()->escape(v.toString()); @@ -3479,6 +3585,24 @@ class TemplateNodeInclude : public TemplateNodeCreator<TemplateNodeInclude> //---------------------------------------------------------- +static void stripLeadingWhiteSpace(QGString &s) +{ + const char *src = s.data(); + if (src) + { + char *dst = s.data(); + char c; + bool skipSpaces=TRUE; + while ((c=*src++)) + { + if (c=='\n') { *dst++=c; skipSpaces=TRUE; } + else if (c==' ' && skipSpaces) {} + else { *dst++=c; skipSpaces=FALSE; } + } + *dst='\0'; + } +} + /** @brief Class representing an 'create' tag in a template */ class TemplateNodeCreate : public TemplateNodeCreator<TemplateNodeCreate> { @@ -3542,17 +3666,18 @@ class TemplateNodeCreate : public TemplateNodeCreator<TemplateNodeCreate> TemplateImpl *t = getTemplate(); if (t) { + QCString extension=outputFile; + int i=extension.findRev('.'); + if (i!=-1) + { + extension=extension.right(extension.length()-i-1); + } + t->engine()->setOutputExtension(extension); Template *ct = t->engine()->loadByName(templateFile,m_line); TemplateImpl *createTemplate = ct ? dynamic_cast<TemplateImpl*>(ct) : 0; if (createTemplate) { mkpath(ci,outputFile); - QCString extension=outputFile; - int i=extension.findRev('.'); - if (i!=-1) - { - extension=extension.right(extension.length()-i-1); - } if (!ci->outputDirectory().isEmpty()) { outputFile.prepend(ci->outputDirectory()+"/"); @@ -3564,7 +3689,11 @@ class TemplateNodeCreate : public TemplateNodeCreator<TemplateNodeCreate> TemplateEscapeIntf *escIntf = ci->escapeIntf(); ci->selectEscapeIntf(extension); FTextStream ts(&f); - createTemplate->render(ts,c); + QGString out; + FTextStream os(&out); + createTemplate->render(os,c); + stripLeadingWhiteSpace(out); + ts << out; t->engine()->unload(t); ci->setActiveEscapeIntf(escIntf); } @@ -3577,6 +3706,7 @@ class TemplateNodeCreate : public TemplateNodeCreator<TemplateNodeCreate> { ci->warn(m_templateName,m_line,"failed to load template '%s' for include",templateFile.data()); } + t->engine()->setOutputExtension(""); } } } @@ -3865,7 +3995,8 @@ class TemplateNodeWith : public TemplateNodeCreator<TemplateNodeWith> TRACE(("{TemplateNodeWith(%s)\n",data.data())); m_args.setAutoDelete(TRUE); ExpressionParser expParser(parser,line); - QValueList<QCString> args = split(data," "); + QCString filteredData = removeSpacesAroundEquals(data); + QValueList<QCString> args = split(filteredData," "); QValueListIterator<QCString> it = args.begin(); while (it!=args.end()) { @@ -3917,7 +4048,7 @@ class TemplateNodeWith : public TemplateNodeCreator<TemplateNodeWith> //---------------------------------------------------------- -/** @brief Class representing an 'set' tag in a template */ +/** @brief Class representing an 'cycle' tag in a template */ class TemplateNodeCycle : public TemplateNodeCreator<TemplateNodeCycle> { public: @@ -4152,6 +4283,36 @@ class TemplateNodeMarkers : public TemplateNodeCreator<TemplateNodeMarkers> //---------------------------------------------------------- +/** @brief Class representing an 'tabbing' tag in a template */ +class TemplateNodeTabbing : public TemplateNodeCreator<TemplateNodeTabbing> +{ + public: + TemplateNodeTabbing(TemplateParser *parser,TemplateNode *parent,int line,const QCString &) + : TemplateNodeCreator<TemplateNodeTabbing>(parser,parent,line) + { + TRACE(("{TemplateNodeTabbing()\n")); + QStrList stopAt; + stopAt.append("endtabbing"); + parser->parse(this,line,stopAt,m_nodes); + parser->removeNextToken(); // skip over endtabbing + TRACE(("}TemplateNodeTabbing()\n")); + } + void render(FTextStream &ts, TemplateContext *c) + { + TemplateContextImpl *ci = dynamic_cast<TemplateContextImpl*>(c); + if (ci==0) return; // should not happen + ci->setLocation(m_templateName,m_line); + bool wasTabbing = ci->tabbingEnabled(); + ci->enableTabbing(TRUE); + m_nodes.render(ts,c); + ci->enableTabbing(wasTabbing); + } + private: + TemplateNodeList m_nodes; +}; + +//---------------------------------------------------------- + /** @brief Class representing an 'markers' tag in a template */ class TemplateNodeResource : public TemplateNodeCreator<TemplateNodeResource> { @@ -4287,6 +4448,7 @@ static TemplateNodeFactory::AutoRegister<TemplateNodeCreate> autoRefCreat static TemplateNodeFactory::AutoRegister<TemplateNodeRepeat> autoRefRepeat("repeat"); static TemplateNodeFactory::AutoRegister<TemplateNodeInclude> autoRefInclude("include"); static TemplateNodeFactory::AutoRegister<TemplateNodeMarkers> autoRefMarkers("markers"); +static TemplateNodeFactory::AutoRegister<TemplateNodeTabbing> autoRefTabbing("tabbing"); static TemplateNodeFactory::AutoRegister<TemplateNodeResource> autoRefResource("resource"); static TemplateNodeFactory::AutoRegister<TemplateNodeSpaceless> autoRefSpaceless("spaceless"); static TemplateNodeFactory::AutoRegister<TemplateNodeIndexEntry> autoRefIndexEntry("indexentry"); @@ -4377,6 +4539,8 @@ class TemplateLexer public: TemplateLexer(const TemplateEngine *engine,const QCString &fileName,const char *data,int size); void tokenize(QList<TemplateToken> &tokens); + void setOpenCloseCharacters(char openChar,char closeChar) + { m_openChar=openChar; m_closeChar=closeChar; } private: void addToken(QList<TemplateToken> &tokens, const char *data,int line,int startPos,int endPos, @@ -4385,6 +4549,8 @@ class TemplateLexer const TemplateEngine *m_engine; QCString m_fileName; QCString m_data; + char m_openChar; + char m_closeChar; }; TemplateLexer::TemplateLexer(const TemplateEngine *engine,const QCString &fileName,const char *data,int size) : @@ -4393,6 +4559,8 @@ TemplateLexer::TemplateLexer(const TemplateEngine *engine,const QCString &fileNa m_data.resize(size+1); memcpy(m_data.rawData(),data,size); m_data[size]=0; + m_openChar='{'; + m_closeChar='}'; } void TemplateLexer::tokenize(QList<TemplateToken> &tokens) @@ -4411,6 +4579,7 @@ void TemplateLexer::tokenize(QList<TemplateToken> &tokens) }; const char *p=m_data.data(); + if (p==0) return; int state=StateText; int pos=0; int lastTokenPos=0; @@ -4424,7 +4593,7 @@ void TemplateLexer::tokenize(QList<TemplateToken> &tokens) switch (state) { case StateText: - if (c=='{') // {{ or {% or {# or something else + if (c==m_openChar) // {{ or {% or {# or something else { state=StateBeginTemplate; } @@ -4445,7 +4614,14 @@ void TemplateLexer::tokenize(QList<TemplateToken> &tokens) markStartPos=pos-1; break; case '{': // {{ - state=StateMaybeVar; + if (m_openChar=='{') + { + state=StateMaybeVar; + } + else + { + state=StateVariable; + } markStartPos=pos-1; break; default: @@ -4457,7 +4633,7 @@ void TemplateLexer::tokenize(QList<TemplateToken> &tokens) case StateTag: if (c=='\n') { - warn(m_fileName,line,"unexpected new line inside {%%...%%} block"); + warn(m_fileName,line,"unexpected new line inside %c%%...%%%c block",m_openChar,m_closeChar); m_engine->printIncludeContext(m_fileName,line); } else if (c=='%') // %} or something else @@ -4466,7 +4642,7 @@ void TemplateLexer::tokenize(QList<TemplateToken> &tokens) } break; case StateEndTag: - if (c=='}') // %} + if (c==m_closeChar) // %} { // found tag! state=StateText; @@ -4481,7 +4657,7 @@ void TemplateLexer::tokenize(QList<TemplateToken> &tokens) { if (c=='\n') { - warn(m_fileName,line,"unexpected new line inside {%%...%%} block"); + warn(m_fileName,line,"unexpected new line inside %c%%...%%%c block",m_openChar,m_closeChar); m_engine->printIncludeContext(m_fileName,line); } state=StateTag; @@ -4490,7 +4666,7 @@ void TemplateLexer::tokenize(QList<TemplateToken> &tokens) case StateComment: if (c=='\n') { - warn(m_fileName,line,"unexpected new line inside {#...#} block"); + warn(m_fileName,line,"unexpected new line inside %c#...#%c block",m_openChar,m_closeChar); m_engine->printIncludeContext(m_fileName,line); } else if (c=='#') // #} or something else @@ -4499,7 +4675,7 @@ void TemplateLexer::tokenize(QList<TemplateToken> &tokens) } break; case StateEndComment: - if (c=='}') // #} + if (c==m_closeChar) // #} { // found comment tag! state=StateText; @@ -4512,7 +4688,7 @@ void TemplateLexer::tokenize(QList<TemplateToken> &tokens) { if (c=='\n') { - warn(m_fileName,line,"unexpected new line inside {#...#} block"); + warn(m_fileName,line,"unexpected new line inside %c#...#%c block",m_openChar,m_closeChar); m_engine->printIncludeContext(m_fileName,line); } state=StateComment; @@ -4535,9 +4711,10 @@ void TemplateLexer::tokenize(QList<TemplateToken> &tokens) } break; case StateVariable: + emptyOutputLine=FALSE; // assume a variable expands to content if (c=='\n') { - warn(m_fileName,line,"unexpected new line inside {{...}} block"); + warn(m_fileName,line,"unexpected new line inside %c{...}%c block",m_openChar,m_closeChar); m_engine->printIncludeContext(m_fileName,line); } else if (c=='}') // }} or something else @@ -4546,7 +4723,7 @@ void TemplateLexer::tokenize(QList<TemplateToken> &tokens) } break; case StateEndVariable: - if (c=='}') // }} + if (c==m_closeChar) // }} { // found variable tag! state=StateText; @@ -4561,7 +4738,7 @@ void TemplateLexer::tokenize(QList<TemplateToken> &tokens) { if (c=='\n') { - warn(m_fileName,line,"unexpected new line inside {{...}} block"); + warn(m_fileName,line,"unexpected new line inside %c{...}%c block",m_openChar,m_closeChar); m_engine->printIncludeContext(m_fileName,line); } state=StateVariable; @@ -4663,7 +4840,7 @@ void TemplateParser::parse( command=="endrecursetree" || command=="endspaceless" || command=="endmarkers" || command=="endmsg" || command=="endrepeat" || command=="elif" || - command=="endrange") + command=="endrange" || command=="endtabbing") { warn(m_templateName,tok->line,"Found tag '%s' without matching start tag",command.data()); } @@ -4731,12 +4908,17 @@ void TemplateParser::warn(const char *fileName,int line,const char *fmt,...) con //---------------------------------------------------------- -TemplateImpl::TemplateImpl(TemplateEngine *engine,const QCString &name,const char *data,int size) +TemplateImpl::TemplateImpl(TemplateEngine *engine,const QCString &name,const char *data,int size, + const QCString &extension) : TemplateNode(0) { m_name = name; m_engine = engine; TemplateLexer lexer(engine,name,data,size); + if (extension=="tex") + { + lexer.setOpenCloseCharacters('<','>'); + } QList<TemplateToken> tokens; tokens.setAutoDelete(TRUE); lexer.tokenize(tokens); @@ -4809,27 +4991,9 @@ class TemplateEngine::Private const Resource *res = ResourceMgr::instance().get(fileName); if (res) { - templ = new TemplateImpl(m_engine,fileName,(const char *)res->data,res->size); + templ = new TemplateImpl(m_engine,fileName,(const char *)res->data,res->size,m_extension); m_templateCache.insert(fileName,templ); } -#if 0 - QFile f(fileName); - if (f.open(IO_ReadOnly)) - { - uint size=f.size(); - char *data = new char[size+1]; - if (data) - { - data[size]=0; - if (f.readBlock(data,f.size())) - { - templ = new TemplateImpl(m_engine,fileName,data); - m_templateCache.insert(fileName,templ); - } - delete[] data; - } - } -#endif else { err("Cound not open template file %s\n",fileName.data()); @@ -4886,11 +5050,22 @@ class TemplateEngine::Private } } + void setOutputExtension(const char *extension) + { + m_extension = extension; + } + + QCString outputExtension() const + { + return m_extension; + } + private: QDict<Template> m_templateCache; //mutable int m_indent; TemplateEngine *m_engine; QList<IncludeEntry> m_includeStack; + QCString m_extension; }; TemplateEngine::TemplateEngine() @@ -4938,3 +5113,15 @@ void TemplateEngine::printIncludeContext(const char *fileName,int line) const p->printIncludeContext(fileName,line); } +void TemplateEngine::setOutputExtension(const char *extension) +{ + p->setOutputExtension(extension); +} + +QCString TemplateEngine::outputExtension() const +{ + return p->outputExtension(); +} + + + diff --git a/src/template.h b/src/template.h index c6c918c..d1501ce 100644 --- a/src/template.h +++ b/src/template.h @@ -396,6 +396,8 @@ class TemplateEscapeIntf public: /** Returns the \a input after escaping certain characters */ virtual QCString escape(const QCString &input) = 0; + /** Setting tabbing mode on or off (for LaTeX) */ + virtual void enableTabbing(bool b) = 0; }; //------------------------------------------------------------------------ @@ -523,13 +525,25 @@ class TemplateEngine */ void unload(Template *t); + /** Prints the current template file include stack */ void printIncludeContext(const char *fileName,int line) const; private: friend class TemplateNodeBlock; + friend class TemplateNodeCreate; + void enterBlock(const QCString &fileName,const QCString &blockName,int line); void leaveBlock(); + /** Sets the extension of the output file. This is used to control the + * format of 'special' tags in the template + */ + void setOutputExtension(const char *extension); + + /** Returns the output extension, set via setOutputExtension() */ + QCString outputExtension() const; + + class Private; Private *p; }; diff --git a/src/util.cpp b/src/util.cpp index 0467953..946e2af 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -5773,6 +5773,15 @@ QCString convertToJSString(const char *s) return convertCharEntitiesToUTF8(growBuf.get()); } +QCString convertToLaTeX(const QCString &s,bool insideTabbing,bool keepSpaces) +{ + QGString result; + FTextStream t(&result); + filterLatexString(t,s,insideTabbing,FALSE,FALSE,keepSpaces); + return result.data(); +} + + QCString convertCharEntitiesToUTF8(const QCString &s) { @@ -6488,7 +6497,7 @@ void addGroupListToTitle(OutputList &ol,Definition *d) } void filterLatexString(FTextStream &t,const char *str, - bool insideTabbing,bool insidePre,bool insideItem) + bool insideTabbing,bool insidePre,bool insideItem,bool keepSpaces) { if (str==0) return; //if (strlen(str)<2) stackTrace(); @@ -6509,6 +6518,7 @@ void filterLatexString(FTextStream &t,const char *str, case '{': t << "\\{"; break; case '}': t << "\\}"; break; case '_': t << "\\_"; break; + case ' ': if (keepSpaces) t << "~"; else t << ' '; default: t << (char)c; } @@ -6580,6 +6590,8 @@ void filterLatexString(FTextStream &t,const char *str, break; case '\'': t << "\\textquotesingle{}"; break; + case ' ': if (keepSpaces) { if (insideTabbing) t << "\\>"; else t << '~'; } else t << ' '; + break; default: //if (!insideTabbing && forceBreaks && c!=' ' && *p!=' ') @@ -6596,6 +6608,79 @@ void filterLatexString(FTextStream &t,const char *str, } } +QCString latexEscapeLabelName(const char *s,bool insideTabbing) +{ + QGString result; + QCString tmp(qstrlen(s)+1); + FTextStream t(&result); + const char *p=s; + char c; + int i; + while ((c=*p++)) + { + switch (c) + { + case '|': t << "\\texttt{\"|}"; break; + case '!': t << "\"!"; break; + case '%': t << "\\%"; break; + case '{': t << "\\lcurly{}"; break; + case '}': t << "\\rcurly{}"; break; + case '~': t << "````~"; break; // to get it a bit better in index together with other special characters + // NOTE: adding a case here, means adding it to while below as well! + default: + i=0; + // collect as long string as possible, before handing it to docify + tmp[i++]=c; + while ((c=*p) && c!='|' && c!='!' && c!='%' && c!='{' && c!='}' && c!='~') + { + tmp[i++]=c; + p++; + } + tmp[i]=0; + filterLatexString(t,tmp.data(),insideTabbing); + break; + } + } + return result.data(); +} + +QCString latexEscapeIndexChars(const char *s,bool insideTabbing) +{ + QGString result; + QCString tmp(qstrlen(s)+1); + FTextStream t(&result); + const char *p=s; + char c; + int i; + while ((c=*p++)) + { + switch (c) + { + case '!': t << "\"!"; break; + case '"': t << "\"\""; break; + case '@': t << "\"@"; break; + case '|': t << "\\texttt{\"|}"; break; + case '[': t << "["; break; + case ']': t << "]"; break; + case '{': t << "\\lcurly{}"; break; + case '}': t << "\\rcurly{}"; break; + // NOTE: adding a case here, means adding it to while below as well! + default: + i=0; + // collect as long string as possible, before handing it to docify + tmp[i++]=c; + while ((c=*p) && c!='"' && c!='@' && c!='[' && c!=']' && c!='!' && c!='{' && c!='}' && c!='|') + { + tmp[i++]=c; + p++; + } + tmp[i]=0; + filterLatexString(t,tmp.data(),insideTabbing); + break; + } + } + return result.data(); +} QCString rtfFormatBmkStr(const char *name) { @@ -8419,3 +8504,6 @@ QCString getDotImageExtension(void) imgExt = imgExt.replace( QRegExp(":.*"), "" ); return imgExt; } + + + @@ -276,6 +276,8 @@ QCString stripScope(const char *name); QCString convertToHtml(const char *s,bool keepEntities=TRUE); +QCString convertToLaTeX(const QCString &s,bool insideTabbing=FALSE,bool keepSpaces=FALSE); + QCString convertToXML(const char *s); QCString convertToJSString(const char *s); @@ -334,7 +336,11 @@ void addGroupListToTitle(OutputList &ol,Definition *d); void filterLatexString(FTextStream &t,const char *str, bool insideTabbing=FALSE, bool insidePre=FALSE, - bool insideItem=FALSE); + bool insideItem=FALSE, + bool keepSpaces=FALSE); + +QCString latexEscapeLabelName(const char *s,bool insideTabbing); +QCString latexEscapeIndexChars(const char *s,bool insideTabbing); QCString rtfFormatBmkStr(const char *name); diff --git a/templates/html/htmlallmembers.tpl b/templates/html/htmlallmembers.tpl index 98f88d6..b44110d 100644 --- a/templates/html/htmlallmembers.tpl +++ b/templates/html/htmlallmembers.tpl @@ -9,12 +9,63 @@ <p>{{ tr.theListOfAllMembers }} <a class="el" href="{{ compound.fileName }}{{ config.HTML_FILE_EXTENSION }}">{{ compound.name }}</a>{{ tr.incInheritedMembers }}</p> <table class="directory"> {% for mi in compound.allMembersList %} - <tr {% cycle 'class="even"' '' %}> - {# TODO: objective-C #} - <td>{% with obj=mi.member text=mi.ambiguityScope|append:mi.member.name %} - {% include 'htmlobjlink.tpl' %} + <tr class="{% cycle 'even' 'odd' %}"> + {% spaceless %} + {% with member=mi.member %} + {% if member.language=='objc' %} + <td class="entry"> + {% if member.isObjCMethod %} + {% if member.isStatic %}+ {% else %}- {% endif %} + {% endif %} + </td> + {% endif %} + {% if member.isObjCMethod %} + <td class="entry"> + {% with obj=member text=member.name %} + {% include 'htmlobjlink.tpl' %} + {% endwith %} + </td> + {%else %} + {# name #} + <td class="entry"> + {% with obj=member text=mi.ambiguityScope|append:member.name %} + {% include 'htmlobjlink.tpl' %} {% endwith %} + {% if member.isEnumeration %} +  {{ tr.enumName }} + {% elif member.isEnumValue %} +  {{ tr.enumValue }} + {% elif member.isTypedef %} +  typedef + {% elif member.isFriend and member.type=='friend class' %} +  class + {% elif member.isFunction or member.isSignal or member.isSlot or (member.isFriend and member.hasParameters) %} + {{ member.declArgs }} + {% endif %} + </td> + {% endif %} + {# class link #} + <td class="entry"> + {% if member.category %} + {% with obj=member.category text=member.category.name %} + {% include 'htmlobjlink.tpl' %} + {% endwith %} + {% else %} + {% with obj=member.class text=member.class.name %} + {% include 'htmlobjlink.tpl' %} + {% endwith %} + {% endif %} </td> + {# labels #} + {% if member.labels %} + <td class="entry"> + {% for label in member.labels %} + <span class="mlabel">{{ label }}</span> + {% endfor %} + </td> + {% endif %} + {% endwith %} + {% endspaceless %} </tr> {% endfor %} </table> diff --git a/templates/html/htmlbase.tpl b/templates/html/htmlbase.tpl index d394b45..84807ec 100644 --- a/templates/html/htmlbase.tpl +++ b/templates/html/htmlbase.tpl @@ -21,6 +21,9 @@ {% endif %} {% if config.SEARCHENGINE %} <link href="{{ page.relPath }}search/search.css" rel="stylesheet" type="text/css"/> + {% if not config.SERVER_BASED_SEARCH %} +<script type="text/javascript" src="{{ page.relPath }}search/searchdata.js"></script> + {% endif %} <script type="text/javascript" src="{{ page.relPath }}search/search.js"></script> {% if config.SERVER_BASED_SEARCH %} <script type="text/javascript"> @@ -38,13 +41,13 @@ {% if config.USE_MATHJAX %} <script type="text/x-mathjax-config"> MathJax.Hub.Config({ - extensions: ["tex2jax.js"], {# TODO: support MATHJAX_EXTENSIONS #} - jax: ["input/TeX","output/{{ config.MATHJAX_FORMAT }}"], + extensions: ["tex2jax.js"{% for ext in config.MATHJAX_EXTENSIONS %}, "{{ ext }}"{% endfor %}], + jax: ["input/TeX","output/{{ config.MATHJAX_FORMAT|default:'HTML-CSS' }}"], }); -{# TODO: support MATHJAX_CODEFILE #} +{{ doxygen.mathJaxCodeFile }} </script> -<script src="http://cdn.mathjax.org/mathjax/latest/MathJax.js"></script> -{% endif %} +<script type="text/javascript" src="{{ config.MATHJAX_RELPATH }}{% if config.MATHJAX_RELPATH|relative %}{{ page.relPath }}{% endif %}MathJax.js"></script> +{% endif %}{# MathJax #} <link href="{{ page.relPath }}{{ config.HTML_STYLESHEET|default:'doxygen.css' }}" rel="stylesheet" type="text/css" /> {% if config.HTML_EXTRA_STYLESHEET %} <link href="{{ page.relPath }}{{ config.HTML_EXTRA_STYLESHEET }}" rel="stylesheet" type="text/css" /> @@ -117,7 +120,7 @@ <!-- end header part --> <!-- Generated by Doxygen {{ doxygen.version }} --> {% block search %} -{% if config.SEARCHENGINE %}{# TODO: can't we move this to the header? #} +{% if config.SEARCHENGINE %} <script type="text/javascript"> var searchBox = new SearchBox("searchBox", "{{ page.relPath }}search",false,'{{ tr.search }}'); </script> @@ -160,14 +163,13 @@ $(document).ready(function(){initNavTree('{{ page.fileName }}{% if page_postfix <div id="MSearchSelectWindow" onmouseover="return searchBox.OnSearchSelectShow()" onmouseout="return searchBox.OnSearchSelectHide()" onkeydown="return searchBox.OnSearchSelectKey(event)"> -{# TODO: get search categories dynamically, since we don't know them here #} </div> -{% endif %} <!-- iframe showing the search results (closed by default) --> <div id="MSearchResultsWindow"> <iframe src="javascript:void(0)" frameborder="0" name="MSearchResults" id="MSearchResults"> </iframe> </div> +{% endif %} {% endblock %} <div class="header"> @@ -194,7 +196,7 @@ $(document).ready(function(){initNavTree('{{ page.fileName }}{% if page_postfix {% if config.HTML_TIMESTAMP %} {{ tr.generatedAt:doxygen.date,config.PROJECT_NAME }} {% else %} -{{ tr.generatedby }} +{{ tr.generatedBy }} {% endif %} <a href="http://www.doxygen.org/index.html"> <img class="footer" src="{{ page.relPath }}doxygen.png" alt="doxygen"/></a> {{ doxygen.version }} </li> @@ -205,7 +207,7 @@ $(document).ready(function(){initNavTree('{{ page.fileName }}{% if page_postfix {% if config.HTML_TIMESTAMP %} {{ tr.generatedAt:doxygen.date,config.PROJECT_NAME }} {% else %} -{{ tr.generatedby }} +{{ tr.generatedBy }} {% endif %}  <a href="http://www.doxygen.org/index.html"><img class="footer" src="{{ page.relPath }}doxygen.png" alt="doxygen"/></a> {{ doxygen.version }} diff --git a/templates/html/htmlclass.tpl b/templates/html/htmlclass.tpl index bb734b6..24694b3 100644 --- a/templates/html/htmlclass.tpl +++ b/templates/html/htmlclass.tpl @@ -180,7 +180,6 @@ </div> {% endif %} {# memberdecls #} - {# TODO: isSimple #} {# nestedClasses #} {% with list=compound.classes label='nested-classes' title=tr.classes local=1 %} {% include 'htmldeclcomp.tpl' %} @@ -379,9 +378,9 @@ {% endif %} {# member definitions #} {# inline classes #} - {% if compound.classes %} - {# TODO write inlined simple classes: tr.classDocumentation / tr.typeDocumentation #} - {% endif %} + {% with classList=compound.classes %} + {% include 'htmlinlineclasses.tpl' %} + {% endwith %} {# typedefs #} {% with memberListInfo=compound.detailedTypedefs %} {% include 'htmlmemdef.tpl' %} diff --git a/templates/html/htmlclasses.tpl b/templates/html/htmlclasses.tpl index 803b1a9..8a1bf18 100644 --- a/templates/html/htmlclasses.tpl +++ b/templates/html/htmlclasses.tpl @@ -22,7 +22,7 @@ <li> <span class="ai"> {% if forloop.first %} - <a name="#letter_{{ section.label }}"></a> + <a name="letter_{{ section.label }}"></a> <span class="ah">  {{ section.letter }}  </span><br/> {% endif %} {% with obj=cls text=cls.name %} diff --git a/templates/html/htmldir.tpl b/templates/html/htmldir.tpl index 7417f7b..a399759 100644 --- a/templates/html/htmldir.tpl +++ b/templates/html/htmldir.tpl @@ -45,7 +45,18 @@ {% endif %} {% endif %} {# dir graph #} -{# TODO #} + {% if compound.hasDirGraph %} + {% with obj=compound %} + {% include 'htmldynheader.tpl' %} + {% endwith %} + {{ tr.dirDependencyGraphFor:compound.dirName }} + </div> + {% with obj=compound %} + {% include 'htmldyncontents.tpl' %} + {% endwith %} + {{ compound.dirGraph }} + </div> + {% endif %} {# member declarations #} {# directories #} {% with list=compound.dirs label='subdirs' title=tr.directories local=False %} diff --git a/templates/html/htmlfile.tpl b/templates/html/htmlfile.tpl index 67af096..dbf0841 100644 --- a/templates/html/htmlfile.tpl +++ b/templates/html/htmlfile.tpl @@ -160,76 +160,9 @@ {% endif %} {# member definitions #} {# inline classes #} - {% if compound.inlineClasses %} - <h2 class="groupheader">{{ tr.classDocumentation }}</h2> - {% for class in compound.inlineClasses %} - {# write anchor #} - <a class="anchor" id="{{ class.anchor }}"></a> - <div class="memitem"> - <div class="memproto"> - <table class="memname"> - <tr><td class="memname">{{ class.compoundType }} {{ class.name }}</td></tr> - </table> - </div> - <div class="memdoc"> - <div class="textblock"> - {# TODO: the stuff inside textblock can be the same as in htmlclass.tpl!! #} - {# template specifier #} - {% if class.language=='cpp' and class.templateDecls %} - <h3>{% spaceless %} - {% for targList in class.templateDecls %} - template< - {% for targ in targList %} - {{ targ.type }}{% if targ.name %} {{ targ.name }}{% endif %}{% if targ.defVal %} = {{ targ.defVal }}{% endif %}{% if not forloop.last %}, {% endif %} - {% endfor %} - ><br/> - {% endfor %} - {% endspaceless %} - {{ class.classType }} {{ class.name }} - </h3> - {% endif %} - {# brief description #} - {% if class.brief and config.REPEAT_BRIEF %} - <p>{{ class.brief }}</p> - {% endif %} - {# detailed docs #} - {{ class.details }} - {# source def #} - {% if class.sourceDef %} - {% markers obj in class.sourceDef with tr.definedAtLineInSourceFile %} - {% with text=obj.text %} - {% include 'htmlobjlink.tpl' %} - {% endwith %} - {% endmarkers %} - {% endif %} - </div><!-- textblock --> - {# table with fields #} - <table class="fieldtable"> - <tr><th colspan="3">{{ tr.compoundMembers }}</td></tr> - {% for member in class.members %} - <tr><td class="fieldtype"> - <a class="anchor" id="{{ member.anchor }}"></a>{{ member.fieldType }} - </td> - <td class="fieldname"> - {{ member.name }} - {% if member.isVariable and member.declArgs %}{{ member.declArgs }}{% endif %} - {{ member.bitfields }} - </td> - <td class="fielddoc"> - {% if member.brief and not member.details %}{# only brief #} - {{ member.brief }} - {% else %} {# only details or both #} - {% if member.brief %}<p>{{ member.brief }}</p>{% endif %} - {{ member.details }} - {% endif %} - </td> - </tr> - {% endfor %} - </table> - </div><!-- memdoc --> - </div><!-- memitem --> - {% endfor %} - {% endif %} + {% with classList=compound.inlineClasses %} + {% include 'htmlinlineclasses.tpl' %} + {% endwith %} {# defines #} {% with memberListInfo=compound.detailedMacros %} {% include 'htmlmemdef.tpl' %} diff --git a/templates/html/htmlinlineclasses.tpl b/templates/html/htmlinlineclasses.tpl new file mode 100644 index 0000000..876c491 --- /dev/null +++ b/templates/html/htmlinlineclasses.tpl @@ -0,0 +1,70 @@ +{# input: classList #} +{% if classList %} + <h2 class="groupheader">{{ tr.classDocumentation }}</h2> + {% for class in classList %} + {# write anchor #} + <a class="anchor" id="{{ class.anchor }}"></a> + <div class="memitem"> + <div class="memproto"> + <table class="memname"> + <tr><td class="memname">{{ class.compoundType }} {{ class.name }}</td></tr> + </table> + </div> + <div class="memdoc"> + <div class="textblock"> + {# template specifier #} + {% if class.language=='cpp' and class.templateDecls %} + <h3>{% spaceless %} + {% for targList in class.templateDecls %} + template< + {% for targ in targList %} + {{ targ.type }}{% if targ.name %} {{ targ.name }}{% endif %}{% if targ.defVal %} = {{ targ.defVal }}{% endif %}{% if not forloop.last %}, {% endif %} + {% endfor %} + ><br/> + {% endfor %} + {% endspaceless %} + {{ class.classType }} {{ class.name }} + </h3> + {% endif %} + {# brief description #} + {% if class.brief and config.REPEAT_BRIEF %} + <p>{{ class.brief }}</p> + {% endif %} + {# detailed docs #} + {{ class.details }} + {# source def #} + {% if class.sourceDef %} + {% markers obj in class.sourceDef with tr.definedAtLineInSourceFile %} + {% with text=obj.text %} + {% include 'htmlobjlink.tpl' %} + {% endwith %} + {% endmarkers %} + {% endif %} + </div><!-- textblock --> + {# table with fields #} + <table class="fieldtable"> + <tr><th colspan="3">{{ tr.compoundMembers }}</th></tr> + {% for member in class.members %} + <tr><td class="fieldtype"> + <a class="anchor" id="{{ member.anchor }}"></a>{{ member.fieldType }} + </td> + <td class="fieldname"> + {{ member.name }} + {% if member.isVariable and member.declArgs %}{{ member.declArgs }}{% endif %} + {{ member.bitfields }} + </td> + <td class="fielddoc"> + {% if member.brief and not member.details %}{# only brief #} + {{ member.brief }} + {% else %} {# only details or both #} + {% if member.brief %}<p>{{ member.brief }}</p>{% endif %} + {{ member.details }} + {% endif %} + </td> + </tr> + {% endfor %} + </table> + </div><!-- memdoc --> + </div><!-- memitem --> + {% endfor %} +{% endif %} diff --git a/templates/html/htmljsnavtree.tpl b/templates/html/htmljsnavtree.tpl index a7ad88e..99a269e 100644 --- a/templates/html/htmljsnavtree.tpl +++ b/templates/html/htmljsnavtree.tpl @@ -18,3 +18,6 @@ var NAVTREEINDEX = {% endfor %} {% endwith %} ]; + +var SYNCONMSG = '{{ tr.panelSyncOn }}'; +var SYNCOFFMSG = '{{ tr.panelSyncOff }}'; diff --git a/templates/html/htmljssearchdata.tpl b/templates/html/htmljssearchdata.tpl new file mode 100644 index 0000000..c48ea1d --- /dev/null +++ b/templates/html/htmljssearchdata.tpl @@ -0,0 +1,31 @@ +{# input: si: SymbolIndex #} +var indexSectionsWithContent = +{ +{% set count=0 %} +{% for idx in searchIndices %} + {% if idx.symbolIndices %} + {{ count }}:"{% for si in idx.symbolIndices %}{{ si.letter }}{% endfor %}"{%if not forloop.last %},{% endif %} + {% set count=count+1 %} + {% endif %} +{% endfor %} +}; +var indexSectionNames = +{ +{% set count=0 %} +{% for idx in searchIndices %} + {% if idx.symbolIndices %} + {{ count }}:"{{ idx.name }}"{% if not forloop.last %},{% endif %} + {% set count=count+1 %} + {% endif %} +{% endfor %} +}; +var IndexSectionLabels = +{ +{% set count=0 %} +{% for idx in searchIndices %} + {% if idx.symbolIndices %} + {{ count }}:"{{ idx.text }}"{% if not forloop.last %},{% endif %} + {% set count=count+1 %} + {% endif %} +{% endfor %} +}; diff --git a/templates/html/htmljssearchindex.tpl b/templates/html/htmljssearchindex.tpl new file mode 100644 index 0000000..a16fa4f --- /dev/null +++ b/templates/html/htmljssearchindex.tpl @@ -0,0 +1,15 @@ +{# input: si symbolIndex #} +var searchData = +[ +{% for group in si.symbolGroups %}['{{ group.id }}',['{{ group.name }}', +{% for sym in group.symbols %} +{% spaceless %} +['{{ sym.relPath }}{{ sym.fileName }}{{ config.HTML_FILE_EXTENSION }}{% if sym.anchor %}#{{ sym.anchor }}{% endif %}', +{% if not config.EXT_LINKS_IN_WINDOW %}1{% else %}0{% endif %}, +'{{ sym.scope|nowrap }}'] +{% endspaceless %} +{% if not forloop.last %},{% endif %} +{% endfor %} +]]{% if not forloop.last %},{% endif %} +{% endfor %} +]; diff --git a/templates/html/htmllayout.tpl b/templates/html/htmllayout.tpl index 9b82238..c21ef91 100644 --- a/templates/html/htmllayout.tpl +++ b/templates/html/htmllayout.tpl @@ -24,6 +24,14 @@ {% resource 'nav_g.png' %} {% resource 'nav_h.lum' %} {% resource 'navtree.css' %} +{% resource 'navtree.js' %} +{% resource 'resize.js' %} +{% resource 'doc.luma' %} +{% resource 'folderopen.luma' %} +{% resource 'folderclosed.luma' %} +{% resource 'arrowdown.luma' %} +{% resource 'arrowright.luma' %} +{% resource 'splitbar.lum' %} {# general search resources #} {% resource 'search_l.png' as 'search/search_l.png' %} @@ -183,7 +191,9 @@ {% endwith %} {% with page=classHierarchy %} {% if config.HAVE_DOT and config.GRAPHICAL_HIERARCHY %} - {% create 'inherits'|append:config.HTML_FILE_EXTENSION from 'htmlgraphhierarchy.tpl' %} + {% with fileName='inherits' %} + {% create fileName|append:config.HTML_FILE_EXTENSION from 'htmlgraphhierarchy.tpl' %} + {% endwith %} {% endif %} {% endwith %} {% endif %} @@ -229,6 +239,19 @@ {# close the global navigation index #} {% closesubindex nav %} +{# write search data #} +{% if config.SEARCHENGINE and not config.SERVER_BASED_SEARCH %} + {% create 'search/searchdata.js' from 'htmljssearchdata.tpl' %} + {% for idx in searchIndices %} + {% for si in idx.symbolIndices %} + {% with baseName=si.name|append:'_'|append:forloop.counter0 %} + {% create baseName|prepend:'search/'|append:config.HTML_FILE_EXTENSION from 'htmlsearchresult.tpl' %} + {% create baseName|prepend:'search/'|append:'.js' from 'htmljssearchindex.tpl' %} + {% endwith %} + {% endfor %} + {% endfor %} +{% endif %} + {# write the navigation tree data #} {% if config.GENERATE_TREEVIEW %} {% create 'navtreedata.js' from 'htmljsnavtree.tpl' %} diff --git a/templates/html/htmlmemdef.tpl b/templates/html/htmlmemdef.tpl index c469f1f..be4d94e 100644 --- a/templates/html/htmlmemdef.tpl +++ b/templates/html/htmlmemdef.tpl @@ -1,6 +1,6 @@ {# inputs: memberListInfo #} {% if memberListInfo %} - {% if memberListInfo.members|length>0 %} + {% if memberListInfo.members %} <h2 class="groupheader">{{ memberListInfo.title }}</h2> {% for member in memberListInfo.members %} {% if member.hasDetails %} {# TODO: not the same as isDetailedSectionVisible! #} @@ -9,7 +9,7 @@ <div class="memitem"> <div class="memproto"> {# write template declarations #} - {% if member.language=='cpp' and member.templateDecls|length>0 %} + {% if member.language=='cpp' and member.templateDecls %} {% for targList in member.templateDecls %} {% spaceless %} <div class="memtemplate"> @@ -23,7 +23,7 @@ {% endfor %} {% endif %} {# start of labels if present #} - {% if member.labels|length>0 %} + {% if member.labels %} <table class="mlabels"><tr><td class="mlabels-left"> {% endif %} <table class="memname"> @@ -31,9 +31,11 @@ {{ member.definition }} {# write argument list #} {# TODO: TCL #} - {% if member.hasParameterList %} + {% if member.hasParameters %} {% if member.isObjCMethod %} + {% if member.parameters %} </td><td></td> + {% endif %} {% for arg in member.parameters %} {% if not forloop.first %} <tr><td class="paramkey">{{ arg.namePart }}</td><td></td> @@ -43,7 +45,7 @@ <em>{% if not arg.name %}{{ arg.type }}{% else %}{{ arg.name }}{% endif %}</em> {% endif %} {% if not forloop.last %} - ,</td></tr> + </td></tr> {% endif %} {% endfor %} {% else %} @@ -109,7 +111,7 @@ </td></tr> </table> {# end of labels if present #} - {% if member.labels|length>0 %} + {% if member.labels %} </td><td class="mlabels-right">{% spaceless %} {% for label in member.labels %} <span class="mlabel">{{ label }}</span> diff --git a/templates/html/htmlmodule.tpl b/templates/html/htmlmodule.tpl index ff97b2c..887da1b 100644 --- a/templates/html/htmlmodule.tpl +++ b/templates/html/htmlmodule.tpl @@ -214,76 +214,9 @@ {% endif %} {# member definitions #} {# inline classes #} - {% if compound.inlineClasses %} - <h2 class="groupheader">{{ tr.classDocumentation }}</h2> - {% for class in compound.inlineClasses %} - {# write anchor #} - <a class="anchor" id="{{ class.anchor }}"></a> - <div class="memitem"> - <div class="memproto"> - <table class="memname"> - <tr><td class="memname">{{ class.compoundType }} {{ class.name }}</td></tr> - </table> - </div> - <div class="memdoc"> - <div class="textblock"> - {# TODO: the stuff inside textblock can be the same as in htmlclass.tpl!! #} - {# template specifier #} - {% if class.language=='cpp' and class.templateDecls %} - <h3>{% spaceless %} - {% for targList in class.templateDecls %} - template< - {% for targ in targList %} - {{ targ.type }}{% if targ.name %} {{ targ.name }}{% endif %}{% if targ.defVal %} = {{ targ.defVal }}{% endif %}{% if not forloop.last %}, {% endif %} - {% endfor %} - ><br/> - {% endfor %} - {% endspaceless %} - {{ class.classType }} {{ class.name }} - </h3> - {% endif %} - {# brief description #} - {% if class.brief and config.REPEAT_BRIEF %} - <p>{{ class.brief }}</p> - {% endif %} - {# detailed docs #} - {{ class.details }} - {# source def #} - {% if class.sourceDef %} - {% markers obj in class.sourceDef with tr.definedAtLineInSourceFile %} - {% with text=obj.text %} - {% include 'htmlobjlink.tpl' %} - {% endwith %} - {% endmarkers %} - {% endif %} - </div><!-- textblock --> - {# table with fields #} - <table class="fieldtable"> - <tr><th colspan="3">{{ tr.compoundMembers }}</td></tr> - {% for member in class.members %} - <tr><td class="fieldtype"> - <a class="anchor" id="{{ member.anchor }}"></a>{{ member.fieldType }} - </td> - <td class="fieldname"> - {{ member.name }} - {% if member.isVariable and member.declArgs %}{{ member.declArgs }}{% endif %} - {{ member.bitfields }} - </td> - <td class="fielddoc"> - {% if member.brief and not member.details %}{# only brief #} - {{ member.brief }} - {% else %} {# only details or both #} - {% if member.brief %}<p>{{ member.brief }}</p>{% endif %} - {{ member.details }} - {% endif %} - </td> - </tr> - {% endfor %} - </table> - </div><!-- memdoc --> - </div><!-- memitem --> - {% endfor %} - {% endif %} + {% with classList=compound.inlineClasses %} + {% include 'htmlinlineclasses.tpl' %} + {% endwith %} {# defines #} {% with memberListInfo=compound.detailedMacros %} {% include 'htmlmemdef.tpl' %} diff --git a/templates/html/htmlnamespace.tpl b/templates/html/htmlnamespace.tpl index e21ba9d..eb127de 100644 --- a/templates/html/htmlnamespace.tpl +++ b/templates/html/htmlnamespace.tpl @@ -114,76 +114,9 @@ {% endif %} {# member definitions #} {# inline classes #} - {% if compound.inlineClasses %} - <h2 class="groupheader">{{ tr.classDocumentation }}</h2> - {% for class in compound.inlineClasses %} - {# write anchor #} - <a class="anchor" id="{{ class.anchor }}"></a> - <div class="memitem"> - <div class="memproto"> - <table class="memname"> - <tr><td class="memname">{{ class.compoundType }} {{ class.name }}</td></tr> - </table> - </div> - <div class="memdoc"> - <div class="textblock"> - {# TODO: the stuff inside textblock can be the same as in htmlclass.tpl!! #} - {# template specifier #} - {% if class.language=='cpp' and class.templateDecls %} - <h3>{% spaceless %} - {% for targList in class.templateDecls %} - template< - {% for targ in targList %} - {{ targ.type }}{% if targ.name %} {{ targ.name }}{% endif %}{% if targ.defVal %} = {{ targ.defVal }}{% endif %}{% if not forloop.last %}, {% endif %} - {% endfor %} - ><br/> - {% endfor %} - {% endspaceless %} - {{ class.classType }} {{ class.name }} - </h3> - {% endif %} - {# brief description #} - {% if class.brief and config.REPEAT_BRIEF %} - <p>{{ class.brief }}</p> - {% endif %} - {# detailed docs #} - {{ class.details }} - {# source def #} - {% if class.sourceDef %} - {% markers obj in class.sourceDef with tr.definedAtLineInSourceFile %} - {% with text=obj.text %} - {% include 'htmlobjlink.tpl' %} - {% endwith %} - {% endmarkers %} - {% endif %} - </div><!-- textblock --> - {# table with fields #} - <table class="fieldtable"> - <tr><th colspan="3">{{ tr.compoundMembers }}</td></tr> - {% for member in class.members %} - <tr><td class="fieldtype"> - <a class="anchor" id="{{ member.anchor }}"></a>{{ member.fieldType }} - </td> - <td class="fieldname"> - {{ member.name }} - {% if member.isVariable and member.declArgs %}{{ member.declArgs }}{% endif %} - {{ member.bitfields }} - </td> - <td class="fielddoc"> - {% if member.brief and not member.details %}{# only brief #} - {{ member.brief }} - {% else %} {# only details or both #} - {% if member.brief %}<p>{{ member.brief }}</p>{% endif %} - {{ member.details }} - {% endif %} - </td> - </tr> - {% endfor %} - </table> - </div><!-- memdoc --> - </div><!-- memitem --> - {% endfor %} - {% endif %} + {% with classList=compound.inlineClasses %} + {% include 'htmlinlineclasses.tpl' %} + {% endwith %} {# typedefs #} {% with memberListInfo=compound.detailedTypedefs %} {% include 'htmlmemdef.tpl' %} diff --git a/templates/html/htmlsearchresult.tpl b/templates/html/htmlsearchresult.tpl new file mode 100644 index 0000000..2cf45fc --- /dev/null +++ b/templates/html/htmlsearchresult.tpl @@ -0,0 +1,27 @@ +{# input: baseName #} +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html><head><title></title> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta name="generator" content="Doxygen {{ doxygen.version }}"/> +<link rel="stylesheet" type="text/css" href="search.css"/> +<script type="text/javascript" src="{{ baseName }}.js"></script> +<script type="text/javascript" src="search.js"></script> +</head> +<body class="SRPage"> +<div id="SRIndex"> +<div class="SRStatus" id="Loading">{{ tr.loading }}</div> +<div id="SRResults"></div> +<script type="text/javascript"><!-- +createResults(); +--></script> +<div class="SRStatus" id="Searching">{{ tr.searching }}</div> +<div class="SRStatus" id="NoMatches">{{ tr.noMatches }}</div> +<script type="text/javascript"><!-- +document.getElementById("Loading").style.display="none"; +document.getElementById("NoMatches").style.display="none"; +var searchResults = new SearchResults("searchResults"); +searchResults.Search(); +--></script> +</div> +</body> +</html> diff --git a/templates/html/htmltabs.tpl b/templates/html/htmltabs.tpl index 9ce8c44..4c48f54 100644 --- a/templates/html/htmltabs.tpl +++ b/templates/html/htmltabs.tpl @@ -69,6 +69,7 @@ </ul> </div> {# second navigation row #} +{% if page.highlight=='namespace' or page.highlight=='classes' or page.highlight=='files' %} <div id="navrow2" class="tabs2"> <ul class="tablist"> {# namespace subtabs #} @@ -94,3 +95,4 @@ {% endif %} </ul> </div> +{% endif %} diff --git a/templates/html/htmltypeconstraints.tpl b/templates/html/htmltypeconstraints.tpl index 12c9581..b5a8cd0 100644 --- a/templates/html/htmltypeconstraints.tpl +++ b/templates/html/htmltypeconstraints.tpl @@ -1,5 +1,5 @@ {# obj should be a class or member #} -{% if obj.typeConstraints|length>0 %} +{% if obj.typeConstraints %} <div class="typecontraint"> <dl><dt><b>{{ tr.typeConstraints }}</b></dt> <dd><table border="0" cellspacing="2" cellpadding="0"> diff --git a/templates/latex/doxygen.sty b/templates/latex/doxygen.sty index 2051b30..3f21871 100644 --- a/templates/latex/doxygen.sty +++ b/templates/latex/doxygen.sty @@ -409,10 +409,10 @@ % Used by parameter lists and simple sections \newenvironment{Desc} {\begin{list}{}{% - \settowidth{\labelwidth}{40pt}% - \setlength{\leftmargin}{\labelwidth}% + \settowidth{\labelwidth}{20pt}% \setlength{\parsep}{0pt}% - \setlength{\itemsep}{-4pt}% + \setlength{\itemsep}{0pt}% + \setlength{\leftmargin}{\labelwidth+\labelsep}% \renewcommand{\makelabel}{\entrylabel}% } }{% diff --git a/templates/latex/latexannotated.tpl b/templates/latex/latexannotated.tpl new file mode 100644 index 0000000..0b6ecb5 --- /dev/null +++ b/templates/latex/latexannotated.tpl @@ -0,0 +1,9 @@ +\section{<{ tr.classList }>} +<{ tr.classListDescription }> +\begin{DoxyCompactList} +<% for cls in classList %> +\item\contentsline{section} +{<% with obj=cls text=cls.name %><% include 'latexobjlink.tpl' %><% endwith %><% if cls.brief %>\\*<{ cls.brief }><% endif %>} +{\pageref{<{ cls.fileName|raw }>}}{} +<% endfor %> +\end{DoxyCompactList} diff --git a/templates/latex/latexclass.tpl b/templates/latex/latexclass.tpl new file mode 100644 index 0000000..7671de0 --- /dev/null +++ b/templates/latex/latexclass.tpl @@ -0,0 +1,114 @@ +<# input: compound #> +<% msg %>Generating LaTeX output for class <{ compound.name }><% endmsg %> +\hypertarget{<{ compound.fileName|raw }>}{}\section{<{ compound.title }>} +\label{<{ compound.fileName|raw }>}\index{<{ compound.name|texLabel }>@{<{ compound.name|texIndex }>}} +<# brief description #> +<% if compound.brief %> + <{ compound.brief }> + +<% endif %> +<# compound includes #> +<% if compound.includeInfo %> + <% with ii=compound.includeInfo %> + <% include 'latexinclude.tpl' %> + <% endwith %> + + +<% endif %> +<# inheritance graph #> + <% if compound.hasInheritanceDiagram %> + <{ tr.inheritanceDiagramFor:compound.name }> + <{ compound.inheritanceDiagram }> + <% else %> + <# textual inheritance list #> + <% if compound.inherits|length>0 %> + <% markers c in compound.inherits with tr.inheritsList:compound.inherits|length %> + <% with obj=c.class text=c.name %> + <% include 'latexobjlink.tpl' %> + <% endwith %> + <% endmarkers %> + + + <% endif %> + <% if compound.inheritedBy|length>0 %> + <% markers c in compound.inheritedBy with tr.inheritedByList:compound.inheritedBy|length %> + <% with obj=c.class text=c.name %> + <% include 'latexobjlink.tpl' %> + <% endwith %> + <% endmarkers %> + + + <% endif %> + <% endif %> +<# collaboration graph #> + <% if compound.hasCollaborationDiagram %> + <{ tr.collaborationDiagramFor:compound.name }> + <{ compound.collaborationDiagram }> + + + <% endif %> +<# member declarations #> +<% if compound.hasDetails %> + <% if compound.anchor %> + \label{<{ compound.anchor|raw }>} + <% if config.PDF_HYPERLINKS and config.USE_PDFLATEX %> + \hypertarget{<% if compound.fileName %><{ compound.fileName|raw }>_<% endif %><{ compound.anchor|raw }>}{} + <% endif %> + <% endif %> + <% if config.COMPACT_LATEX %>\subsubsection<% else %>\subsection<% endif %>{<{ tr.detailedDesc }>} + <# template specifier #> + <% if compound.language=='cpp' and compound.templateDecls %> + <% spaceless %> + \subsubsection*{ + <% for targList in compound.templateDecls %> + template$<$ + <% for targ in targList %> + <{ targ.type }><% if targ.name %><{ space }><{ targ.name }><% endif %><% if targ.defVal %><{ space }>= <{ targ.defVal }><% endif %><% if not forloop.last %>, <% endif %> + <% endfor %> + $>$\\* + <% endfor %> + <{ compound.compoundType }><{ space }><{ compound.name }> + } + <% endspaceless %> + + + <% endif %> + <% if compound.brief and config.REPEAT_BRIEF %> + <{ compound.brief }> + + + <% endif %> + <{ compound.details }> + + + <# type constraints #> + <% with obj=compound %> + <% include 'latextypeconstraints.tpl' %> + <% endwith %> + + +<% endif %> +<% msg %> + <# examples #> + <% if compound.examples %> + <dl><dt><b><{ tr.examples }></b><dd> + <% markers obj in compound.examples with tr.exampleList:compound.examples|length %> + <% with text=obj.text %> + <% include 'htmlobjlink.tpl' %> + <% endwith %> + <% endmarkers %> + </dd></dl> + <% endif %> + <# source definition #> + <% if compound.sourceDef %> + <% markers obj in compound.sourceDef with tr.definedAtLineInSourceFile %> + <% with text=obj.text %> + <% include 'htmlobjlink.tpl' %> + <% endwith %> + <% endmarkers %> + <% endif %> +<% endmsg %> +<# detailed description #> +<# member definitions #> +<# used files #> +<# separate member pages #> diff --git a/templates/latex/latexfiles.tpl b/templates/latex/latexfiles.tpl new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/templates/latex/latexfiles.tpl diff --git a/templates/latex/latexinclude.tpl b/templates/latex/latexinclude.tpl new file mode 100644 index 0000000..c333056 --- /dev/null +++ b/templates/latex/latexinclude.tpl @@ -0,0 +1,32 @@ +<# input: ii with attributes (file,name,isImport,isLocal), compound with attribute language #> +<% spaceless %> +<% if ii.file or ii.name %> +{\ttfamily<{ space }> + <% if compound.language=='java' or compound.language=='idl' %> + import + <% else %> + <% if ii.isImport %> + \#import + <% else %> + \#include + <% endif %> + <% endif %> + <{ space }> + <% if ii.isLocal %> + \char`\"{} + <% else %> + $<$ + <% endif %> + <% if ii.name %> + <{ ii.name }> + <% else %> + <{ ii.file.name }> + <% endif %> + <% if ii.isLocal %> + \char`\"{} + <% else %> + $>$ + <% endif %> +} +<% endif %> +<% endspaceless %> diff --git a/templates/latex/latexlayout.tpl b/templates/latex/latexlayout.tpl new file mode 100644 index 0000000..290a4d5 --- /dev/null +++ b/templates/latex/latexlayout.tpl @@ -0,0 +1,35 @@ +{% msg %}----- Start generating LaTeX output for {{ config.PROJECT_NAME }} from template ----{% endmsg %} + +{% create 'refman.tex' from 'latexrefman.tpl' %} +{% create 'Makefile' from 'latexmakefile.tpl' %} + +{# module index #} +{% if moduleTree.tree %} + {% create 'modules.tex' from 'latexmodules.tpl' %} +{% endif %} + +{# namespace index #} +{% if namespaceTree.tree %} + {% create 'namespaces.tex' from 'latexnamespaces.tpl' %} +{% endif %} + +{# class index #} +{% if classTree.tree %} + {% create 'annotated.tex' from 'latexannotated.tpl' %} +{% endif %} + +{# file index #} +{% if fileTree.tree %} + {% create 'files.tex' from 'latexfiles.tpl' %} +{% endif %} + +{# TODO: pages #} +{# TODO: examples #} +{# TODO: directories #} + +{# write class documentation pages #} +{% for compound in classList %} + {% create compound.fileName|append:'.tex' from 'latexclass.tpl' %} +{% endfor %} + +{% msg %}----- End generating LaTeX output for {{ config.PROJECT_NAME }} from template ----{% endmsg %} diff --git a/templates/latex/latexmakefile.tpl b/templates/latex/latexmakefile.tpl new file mode 100644 index 0000000..ba1eb76 --- /dev/null +++ b/templates/latex/latexmakefile.tpl @@ -0,0 +1,64 @@ +{% if config.USE_PDFLATEX %} +all: refman.pdf + +pdf: refman.pdf + +refman.pdf: clean refman.tex + pdflatex refman + {{ config.MAKEINDEX_CMD_NAME }} refman.idx +{# TODO: generateBib #} + pdflatex refman + latex_count=8 ; \ + while egrep -s 'Rerun (LaTeX|to get cross-references right)' refman.log && [ $$latex_count -gt 0 ] ;\ + do \ + echo "Rerunning latex...." ;\ + pdflatex refman ;\ + latex_count=`expr $$latex_count - 1` ;\ + done + {{ config.MAKEINDEX_CMD_NAME }} refman.idx + pdflatex refman +{% else %} +all: refman.dvi + +ps: refman.ps + +pdf: refman.pdf + +ps_2on1: refman_2on1.ps + +pdf_2on1: refman_2on1.pdf + +refman.ps: refman.dvi + dvips -o refman.ps refman.dvi + +refman.pdf: refman.ps + ps2pdf refman.ps refman.pdf + +refman.dvi: clean refman.tex doxygen.sty + echo "Running latex..." + {{ config.LATEX_CMD_NAME }} refman.tex + echo "Running makeindex..." + {{ config.MAKEINDEX_CMD_NAME }} refman.idx +{# TODO: generateBib #} + echo "Rerunning latex...." + {{ config.LATEX_CMD_NAME }} refman.tex + latex_count=8 ; \ + while egrep -s 'Rerun (LaTeX|to get cross-references right)' refman.log && [ $$latex_count -gt 0 ] ;\ + do \ + echo "Rerunning latex...." ;\ + {{ config.LATEX_CMD_NAME }} refman.tex ;\ + latex_count=`expr $$latex_count - 1` ;\ + done + {{ config.MAKEINDEX_CMD_NAME }} refman.idx + {{ config.LATEX_CMD_NAME }} refman.tex + +refman_2on1.ps: refman.ps + psnup -2 refman.ps >refman_2on1.ps + +refman_2on1.pdf: refman_2on1.ps + ps2pdf refman_2on1.ps refman_2on1.pdf +{% endif %} + +clean: + rm -f *.ps *.dvi *.aux *.toc *.idx *.ind *.ilg *.log *.out *.brf *.blg *.bbl refman.pdf + diff --git a/templates/latex/latexmodules.tpl b/templates/latex/latexmodules.tpl new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/templates/latex/latexmodules.tpl diff --git a/templates/latex/latexnamespaces.tpl b/templates/latex/latexnamespaces.tpl new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/templates/latex/latexnamespaces.tpl diff --git a/templates/latex/latexobjlink.tpl b/templates/latex/latexobjlink.tpl new file mode 100644 index 0000000..89ecc2e --- /dev/null +++ b/templates/latex/latexobjlink.tpl @@ -0,0 +1,6 @@ +<# inputs: obj, text #> +<% if config.PDF_HYPERLINKS %> +\hyperlink{<{ obj.fileName|raw }><% if obj.anchor %>_<{ obj.anchor }><% endif %>}{<{ text }>} +<% else %> +{\bf <{ text }>} +<% endif %> diff --git a/templates/latex/latexrefman.tpl b/templates/latex/latexrefman.tpl new file mode 100644 index 0000000..27b7ea0 --- /dev/null +++ b/templates/latex/latexrefman.tpl @@ -0,0 +1,227 @@ +\documentclass[twoside]{<% if config.COMPACT_LATEX %>article<% else %>book<% endif %>} + +% Packages required by doxygen +\usepackage{fixltx2e} +\usepackage{calc} +\usepackage{doxygen} +\usepackage[export]{adjustbox} % also loads graphicx +<% for package in config.LATEX_EXTRA_STYLESHEET %> +\usepackage{<{package|stripExtension:'.sty'}>} +<% endfor %> +\usepackage{graphicx} +\usepackage[utf8]{inputenc} +\usepackage{makeidx} +\usepackage{multicol} +\usepackage{multirow} +\PassOptionsToPackage{warn}{textcomp} +\usepackage{textcomp} +\usepackage[nointegrals]{wasysym} +\usepackage[table]{xcolor} + +<# TODO: languageSupportCommand #> + +% Font selection +\usepackage[T1]{fontenc} +\usepackage[scaled=.90]{helvet} +\usepackage{courier} +\usepackage{amssymb} +\usepackage{sectsty} +\renewcommand{\familydefault}{\sfdefault} +\allsectionsfont{ + \fontseries{bc}\selectfont + \color{darkgray} +} +\renewcommand{\DoxyLabelFont}{ + \fontseries{bc}\selectfont + \color{darkgray} +} +\newcommand{\+}{\discretionary{\mbox{\scriptsize$\hookleftarrow$}}{}{}} + +% Page & text layout +\usepackage{geometry} +\geometry{ + <{ config.PAPER_TYPE }>paper, + top=2.5cm, + bottom=2.5cm, + left=2.5cm, + right=2.5cm +} +\tolerance=750 +\hfuzz=15pt +\hbadness=750 +\setlength{\emergencystretch}{15pt} +\setlength{\parindent}{0cm} +\setlength{\parskip}{0.2cm} +\makeatletter +\renewcommand{\paragraph}{ + \@startsection{paragraph}{4}{0ex}{-1.0ex}{1.0ex}{ + \normalfont\normalsize\bfseries\SS@parafont + } +} +\renewcommand{\subparagraph}{ + \@startsection{subparagraph}{5}{0ex}{-1.0ex}{1.0ex}{ + \normalfont\normalsize\bfseries\SS@subparafont + } +} +\makeatother + +% Headers & footers +\usepackage{fancyhdr} +\pagestyle{fancyplain} +\fancyhead[LE]{\fancyplain{}{\bfseries\thepage}} +\fancyhead[CE]{\fancyplain{}{}} +\fancyhead[RE]{\fancyplain{}{\bfseries\leftmark}} +\fancyhead[LO]{\fancyplain{}{\bfseries\rightmark}} +\fancyhead[CO]{\fancyplain{}{}} +\fancyhead[RO]{\fancyplain{}{\bfseries\thepage}} +\fancyfoot[LE]{\fancyplain{}{}} +\fancyfoot[CE]{\fancyplain{}{}} +\fancyfoot[RE]{\fancyplain{}{\bfseries\scriptsize <{ tr.generatedAt:doxygen.date,config.PROJECT_NAME }>}} +\fancyfoot[LO]{\fancyplain{}{\bfseries\scriptsize <{ tr.generatedAt:doxygen.date,config.PROJECT_NAME }>}} +\fancyfoot[CO]{\fancyplain{}{}} +\fancyfoot[RO]{\fancyplain{}{}} +\renewcommand{\footrulewidth}{0.4pt} +<% if not config.COMPACT_LATEX %> +\renewcommand{\chaptermark}[1]{ + \markboth{ #1}{}% +} +<% endif %> +\renewcommand{\sectionmark}[1]{ + \markright{\thesection\ #1} +} + +% Indices & bibliography +\usepackage{natbib} +\usepackage[titles]{tocloft} +\setcounter{tocdepth}{3} +\setcounter{secnumdepth}{5} +\makeindex + +<% if config.EXTRA_PACKAGES %> +% Packages requested by user +<% for package in config.EXTRA_PACKAGES %> +\usepackage{<{ package }>} +<% endfor %> +<% endif %> + +<% if config.PDF_HYPERLINKS %> +% Hyperlinks (required, but should be loaded last) +\usepackage{ifpdf} +\ifpdf + \usepackage[pdftex,pagebackref=true]{hyperref} +\else + \usepackage[ps2pdf,pagebackref=true]{hyperref} +\fi +\hypersetup{ + colorlinks=true, + linkcolor=blue, + citecolor=blue, + unicode +} +<% endif %> + +% Custom commands +\newcommand{\clearemptydoublepage}{ + \newpage{\pagestyle{empty}\cleardoublepage} +} + +%===== C O N T E N T S ===== + +\begin{document} +<# TODO: select language for greek #> + +% Titlepage & ToC +<% if config.USE_PDFLATEX and config.PDF_HYPERLINKS %> +\hypersetup{pageanchor=false, + bookmarks=true, + bookmarksnumbered=true, + pdfencoding=unicode + } +<% endif %> +\pagenumbering{roman} +\begin{titlepage} +<% tabbing %> +\vspace*{7cm} +\begin{center}% +{\Large +<% if config.PROJECT_NAME %> + <{ config.PROJECT_NAME }> +<% else %> + <{ tr.referenceManual }> +<% endif %> +<% if config.PROJECT_NUMBER %> +\\[1ex]\large <{ config.PROJECT_NUMBER }> +<% endif %> +}\\ +\vspace*{1cm}{\large <{ tr.generatedBy }> Doxygen <{ doxygen.version }>}\\ +\vspace*{0.5cm}{\small <{ doxygen.date }>}\\ +\end{center} +<% endtabbing %> +\end{titlepage} +<% if not config.COMPACT_LATEX %>\clearemptydoublepage<% endif %> + +\tableofcontents +<% if not config.COMPACT_LATEX %>\clearemptydoublepage<% endif %> +\pagenumbering{arabic} +<% if config.USE_PDFLATEX and config.PDF_HYPERLINKS %> +\hypersetup{pageanchor=true} +<% endif %> + +%--- Begin generated contents --- +<# TODO: loop over pages #> +<% if moduleTree.tree %> +<% if config.COMPACT_LATEX %>\section<% else %>\chapter<% endif %>{<{ tr.moduleIndex }>} +\input{modules} +<% endif %> +<% if namespaceTree.tree %> +<% if config.COMPACT_LATEX %>\section<% else %>\chapter<% endif %>{<{ tr.namespaceIndex }>} +\input{namespaces} +<% endif %> +<% if classTree.tree %> +<% if config.COMPACT_LATEX %>\section<% else %>\chapter<% endif %>{<{ tr.classIndex }>} +\input{annotated} +<% endif %> +<% if fileTree.tree %> +<% if config.COMPACT_LATEX %>\section<% else %>\chapter<% endif %>{<{ tr.fileIndex }>} +\input{files} +<% endif %> +<% if moduleList %> +<% if config.COMPACT_LATEX %>\section<% else %>\chapter<% endif %>{<{ tr.moduleDocumentation }>} +<% for compound in moduleList %> +\input{<{ compound.fileName|raw }>} +<% endfor %> +<% endif %> +<% if namespaceList %> +<% if config.COMPACT_LATEX %>\section<% else %>\chapter<% endif %>{<{ tr.namespaceDocumentation }>} +<% for compound in namespaceList %> +\input{<{ compound.fileName|raw }>} +<% endfor %> +<% endif %> +<% if classList %> +<% if config.COMPACT_LATEX %>\section<% else %>\chapter<% endif %>{<{ tr.classDocumentation }>} +<% for compound in classList %> +\input{<{ compound.fileName|raw }>} +<% endfor %> +<% endif %> +<% if fileList %> +<% if config.COMPACT_LATEX %>\section<% else %>\chapter<% endif %>{<{ tr.fileDocumentation }>} +<% for compound in fileList %> +\input{<{ compound.fileName|raw }>} +<% endfor %> +<% endif %> +%--- End generated contents --- + +<# TODO: write bibliography #> +% Index +<% if not config.COMPACT_LATEX %> +\backmatter +<% endif %> +\newpage +\phantomsection +\clearemptydoublepage +\addcontentsline{toc}{<% if config.COMPACT_LATEX %>section<% else %>chapter<% endif %>}{<{ tr.index }>} +\printindex + +\end{document} + + diff --git a/templates/latex/latextypeconstraints.tpl b/templates/latex/latextypeconstraints.tpl new file mode 100644 index 0000000..2853ab2 --- /dev/null +++ b/templates/latex/latextypeconstraints.tpl @@ -0,0 +1,12 @@ +<# obj should be a class or member #> +<% msg %>type constraints = <{ obj.typeConstraints|length }><% endmsg %> +<% if obj.typeConstraints %> +\begin{Desc} +\item[<{ tr.typeConstraints }>] +\begin{description} +<% for arg in obj.typeConstraints %> + \item[{\em <{ arg.name }>} : {\em <{ arg.type }>}] <{ arg.docs }> +<% endfor %> +\end{description} +\end{Desc} +<% endif %> |