summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/classdef.cpp3
-rw-r--r--src/config.l11
-rw-r--r--src/context.cpp1308
-rw-r--r--src/context.h172
-rw-r--r--src/dirdef.cpp9
-rw-r--r--src/dirdef.h1
-rw-r--r--src/dot.cpp18
-rw-r--r--src/dot.h5
-rw-r--r--src/doxygen.cpp9
-rw-r--r--src/htmlgen.cpp6
-rw-r--r--src/latexgen.cpp441
-rw-r--r--src/latexgen.h88
-rw-r--r--src/searchindex.cpp331
-rw-r--r--src/searchindex.h53
-rw-r--r--src/template.cpp291
-rw-r--r--src/template.h14
-rw-r--r--src/util.cpp90
-rw-r--r--src/util.h8
-rw-r--r--templates/html/htmlallmembers.tpl59
-rw-r--r--templates/html/htmlbase.tpl22
-rw-r--r--templates/html/htmlclass.tpl7
-rw-r--r--templates/html/htmlclasses.tpl2
-rw-r--r--templates/html/htmldir.tpl13
-rw-r--r--templates/html/htmlfile.tpl73
-rw-r--r--templates/html/htmlinlineclasses.tpl70
-rw-r--r--templates/html/htmljsnavtree.tpl3
-rw-r--r--templates/html/htmljssearchdata.tpl31
-rw-r--r--templates/html/htmljssearchindex.tpl15
-rw-r--r--templates/html/htmllayout.tpl25
-rw-r--r--templates/html/htmlmemdef.tpl14
-rw-r--r--templates/html/htmlmodule.tpl73
-rw-r--r--templates/html/htmlnamespace.tpl73
-rw-r--r--templates/html/htmlsearchresult.tpl27
-rw-r--r--templates/html/htmltabs.tpl2
-rw-r--r--templates/html/htmltypeconstraints.tpl2
-rw-r--r--templates/latex/doxygen.sty6
-rw-r--r--templates/latex/latexannotated.tpl9
-rw-r--r--templates/latex/latexclass.tpl114
-rw-r--r--templates/latex/latexfiles.tpl0
-rw-r--r--templates/latex/latexinclude.tpl32
-rw-r--r--templates/latex/latexlayout.tpl35
-rw-r--r--templates/latex/latexmakefile.tpl64
-rw-r--r--templates/latex/latexmodules.tpl0
-rw-r--r--templates/latex/latexnamespaces.tpl0
-rw-r--r--templates/latex/latexobjlink.tpl6
-rw-r--r--templates/latex/latexrefman.tpl227
-rw-r--r--templates/latex/latextypeconstraints.tpl12
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";
}
}
}
diff --git a/src/dot.h b/src/dot.h
index 3de7d79..64d6dd4 100644
--- a/src/dot.h
+++ b/src/dot.h
@@ -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;
}
+
+
+
diff --git a/src/util.h b/src/util.h
index 43d8752..a1a1bba 100644
--- a/src/util.h
+++ b/src/util.h
@@ -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 %}+&#160;{% else %}-&#160;{% 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 %}
+ &#160;{{ tr.enumName }}
+ {% elif member.isEnumValue %}
+ &#160;{{ tr.enumValue }}
+ {% elif member.isTypedef %}
+ &#160;typedef
+ {% elif member.isFriend and member.type=='friend class' %}
+ &#160;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 %}
&#160;<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">&#160;&#160;{{ section.letter }}&#160;&#160;</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&lt;
- {% for targ in targList %}
- {{ targ.type }}{% if targ.name %} {{ targ.name }}{% endif %}{% if targ.defVal %}&#160;= {{ targ.defVal }}{% endif %}{% if not forloop.last %}, {% endif %}
- {% endfor %}
- &gt;<br/>
- {% endfor %}
- {% endspaceless %}
- {{ class.classType }}&#160;{{ 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&lt;
+ {% for targ in targList %}
+ {{ targ.type }}{% if targ.name %} {{ targ.name }}{% endif %}{% if targ.defVal %}&#160;= {{ targ.defVal }}{% endif %}{% if not forloop.last %}, {% endif %}
+ {% endfor %}
+ &gt;<br/>
+ {% endfor %}
+ {% endspaceless %}
+ {{ class.classType }}&#160;{{ 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&lt;
- {% for targ in targList %}
- {{ targ.type }}{% if targ.name %} {{ targ.name }}{% endif %}{% if targ.defVal %}&#160;= {{ targ.defVal }}{% endif %}{% if not forloop.last %}, {% endif %}
- {% endfor %}
- &gt;<br/>
- {% endfor %}
- {% endspaceless %}
- {{ class.classType }}&#160;{{ 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&lt;
- {% for targ in targList %}
- {{ targ.type }}{% if targ.name %} {{ targ.name }}{% endif %}{% if targ.defVal %}&#160;= {{ targ.defVal }}{% endif %}{% if not forloop.last %}, {% endif %}
- {% endfor %}
- &gt;<br/>
- {% endfor %}
- {% endspaceless %}
- {{ class.classType }}&#160;{{ 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 %>