Doxygen
qhp.cpp
浏览该文件的文档.
1 /*
2  * Copyright (C) 2008 by Sebastian Pipping.
3  * Copyright (C) 2008 Dimitri van Heesch.
4  *
5  * Permission to use, copy, modify, and distribute this software and its
6  * documentation under the terms of the GNU General Public License is hereby
7  * granted. No representations are made about the suitability of this software
8  * for any purpose. It is provided "as is" without express or implied warranty.
9  * See the GNU General Public License for more details.
10  *
11  * Documents produced by Doxygen are derivative works derived from the
12  * input used in their production; they are not affected by this license.
13  *
14  * Sebastian Pipping <sebastian@pipping.org>
15  */
16 
17 #include "qhp.h"
18 #include "qhpxmlwriter.h"
19 #include "message.h"
20 #include "config.h"
21 #include "memberdef.h"
22 #include "groupdef.h"
23 #include "doxygen.h"
24 #include "filedef.h"
25 #include "util.h"
26 
27 #include <fstream>
28 #include <string.h>
29 
30 static QCString makeFileName(const QCString & withoutExtension)
31 {
32  QCString result=withoutExtension;
33  if (!result.isEmpty())
34  {
35  if (result.at(0)=='!') // relative URL -> strip marker
36  {
37  result=result.mid(1);
38  }
39  else // add specified HTML extension
40  {
42  }
43  }
44  return result;
45 }
46 
47 static QCString makeRef(const QCString & withoutExtension, const QCString & anchor)
48 {
49  //printf("QHP::makeRef(%s,%s)\n",withoutExtension,anchor);
50  if (withoutExtension.isEmpty()) return QCString();
51  QCString result = makeFileName(withoutExtension);
52  if (anchor.isEmpty()) return result;
53  return result+"#"+anchor;
54 }
55 
57 {
62 }
63 
65 {
67 }
68 
70 {
71  /*
72  <QtHelpProject version="1.0">
73  <namespace>mycompany.com.myapplication.1_0</namespace>
74  <virtualFolder>doc</virtualFolder>
75  <customFilter name="My Application 1.0">
76  <filterAttribute>myapp</filterAttribute>
77  <filterAttribute>1.0</filterAttribute>
78  </customFilter>
79  <filterSection>
80  <filterAttribute>myapp</filterAttribute>
81  <filterAttribute>1.0</filterAttribute>
82  ..
83  */
84  QCString nameSpace = Config_getString(QHP_NAMESPACE);
85  QCString virtualFolder = Config_getString(QHP_VIRTUAL_FOLDER);
86 
87  m_doc.declaration("1.0", "UTF-8");
88 
89  const char * rootAttributes[] =
90  { "version", "1.0", 0 };
91 
92  m_doc.open("QtHelpProject", rootAttributes);
93  m_doc.openCloseContent("namespace", nameSpace);
94  m_doc.openCloseContent("virtualFolder", virtualFolder);
95 
96  // Add custom filter
97  QCString filterName = Config_getString(QHP_CUST_FILTER_NAME);
98  if (!filterName.isEmpty())
99  {
100  const char * tagAttributes[] =
101  { "name", filterName.data(), 0 };
102  m_doc.open("customFilter", tagAttributes);
103 
104  StringVector customFilterAttributes =
105  split(Config_getString(QHP_CUST_FILTER_ATTRS).str(), " ");
106  for (const auto &attr : customFilterAttributes)
107  {
108  m_doc.openCloseContent("filterAttribute", attr.c_str());
109  }
110  m_doc.close("customFilter");
111  }
112 
113  m_doc.open("filterSection");
114 
115  // Add section attributes
116  StringVector sectionFilterAttributes =
117  split(Config_getString(QHP_SECT_FILTER_ATTRS).str(), " ");
118  if (std::find(sectionFilterAttributes.begin(), sectionFilterAttributes.end(), "doxygen") ==
119  sectionFilterAttributes.end())
120  {
121  sectionFilterAttributes.push_back("doxygen");
122  }
123  for (const auto &attr : sectionFilterAttributes)
124  {
125  m_doc.openCloseContent("filterAttribute", attr.c_str());
126  }
127 
128  m_toc.open("toc");
129 
130  // Add extra root node
131  QCString fullProjectname = getFullProjectName();
132  QCString indexFile = "index"+Doxygen::htmlFileExtension;
133  const char * const attributes[] =
134  { "title", fullProjectname.data(),
135  "ref", indexFile.data(),
136  NULL
137  };
138  m_toc.open("section", attributes);
139  m_openCount=1;
141  m_prevSectionLevel = 1;
142  m_sectionLevel = 1;
143 
144  m_index.open("keywords");
145  m_files.open("files");
146 }
147 
149 {
150  // Finish TOC
152  while (m_openCount>0)
153  {
154  m_toc.close("section");
155  m_openCount--;
156  }
157  m_toc.close("toc");
158  m_doc.insert(m_toc);
159 
160  // Finish index
161  m_index.close("keywords");
163 
164  // Finish files
165  m_files.close("files");
167 
168  m_doc.close("filterSection");
169  m_doc.close("QtHelpProject");
170 
171  QCString fileName = Config_getString(HTML_OUTPUT) + "/" + getQhpFileName();
172  std::ofstream file(fileName.str(),std::ofstream::out | std::ofstream::binary);
173  if (!file.is_open())
174  {
175  term("Could not open file %s for writing\n", fileName.data());
176  }
177  TextStream t(&file);
178  m_doc.dumpTo(t);
179 }
180 
182 {
183  m_sectionLevel++;
184 }
185 
187 {
189  {
191  return;
192  }
193  m_sectionLevel--;
194 }
195 
196 void Qhp::addContentsItem(bool /*isDir*/, const QCString & name,
197  const QCString & /*ref*/, const QCString & file,
198  const QCString &anchor, bool /* separateIndex */,
199  bool /* addToNavIndex */,
200  const Definition * /*def*/)
201 {
202  //printf("Qhp::addContentsItem(%s) %d\n",name,m_sectionLevel);
203  // Backup difference before modification
204 
205  QCString f = file;
206  if (!f.isEmpty() && f.at(0)=='^') return; // absolute URL not supported
207 
208  int diff = m_prevSectionLevel - m_sectionLevel;
209 
211  setPrevSection(name, f, anchor, m_sectionLevel);
212 
213  // Close sections as needed
214  //printf("Qhp::addContentsItem() closing %d sections\n",diff);
215  while (diff>0)
216  {
217  m_toc.close("section");
218  m_openCount--;
219  diff--;
220  }
221 }
222 
223 void Qhp::addIndexItem(const Definition *context,const MemberDef *md,
224  const QCString &sectionAnchor,const QCString &word)
225 {
226  (void)word;
227  //printf("addIndexItem(%s %s %s\n",
228  // context?context->name().data():"<none>",
229  // md?md->name().data():"<none>",
230  // qPrint(word));
231 
232  if (md) // member
233  {
234  static bool separateMemberPages = Config_getBool(SEPARATE_MEMBER_PAGES);
235  if (context==0) // global member
236  {
237  if (md->getGroupDef())
238  context = md->getGroupDef();
239  else if (md->getFileDef())
240  context = md->getFileDef();
241  }
242  if (context==0) return; // should not happen
243  QCString cfname = md->getOutputFileBase();
244  QCString cfiname = context->getOutputFileBase();
245  QCString level1 = context->name();
246  QCString level2 = !word.isEmpty() ? word : md->name();
247  QCString contRef = separateMemberPages ? cfname : cfiname;
248  QCString anchor = !sectionAnchor.isEmpty() ? sectionAnchor : md->anchor();
249 
250  QCString ref;
251 
252  // <keyword name="foo" id="MyApplication::foo" ref="doc.html#foo"/>
253  ref = makeRef(contRef, anchor);
254  QCString id = level1+"::"+level2;
255  const char * attributes[] =
256  {
257  "name", level2.data(),
258  "id", id.data(),
259  "ref", ref.data(),
260  0
261  };
262  m_index.openClose("keyword", attributes);
263  }
264  else if (context) // container
265  {
266  // <keyword name="Foo" id="Foo" ref="doc.html#Foo"/>
267  QCString contRef = context->getOutputFileBase();
268  QCString level1 = !word.isEmpty() ? word : context->name();
269  QCString ref = makeRef(contRef,sectionAnchor);
270  const char * attributes[] =
271  {
272  "name", level1.data(),
273  "id", level1.data(),
274  "ref", ref.data(),
275  0
276  };
277  m_index.openClose("keyword", attributes);
278  }
279 }
280 
281 void Qhp::addIndexFile(const QCString & name)
282 {
283  addFile(name);
284 }
285 
287 {
288  return "index.qhp";
289 }
290 
292 {
293  QCString projectName = Config_getString(PROJECT_NAME);
294  QCString versionText = Config_getString(PROJECT_NUMBER);
295  if (projectName.isEmpty()) projectName="Root";
296  return projectName + (versionText.isEmpty()
297  ? QCString("")
298  : QCString(" ") + versionText);
299 }
300 
302 {
303  /*
304  <toc>
305  <section title="My Application Manual" ref="index.html">
306  <section title="Chapter 1" ref="doc.html#chapter1"/>
307  <section title="Chapter 2" ref="doc.html#chapter2"/>
308  <section title="Chapter 3" ref="doc.html#chapter3"/>
309  </section>
310  </toc>
311  */
312 
314  {
315  m_prevSectionTitle=" "; // should not happen...
316  }
317 
318  // We skip "Main Page" as our extra root is pointing to that
320  {
322 
323  const char * const attributes[] =
324  { "title", m_prevSectionTitle.data(),
325  "ref", finalRef.data(),
326  NULL
327  };
328 
330  {
331  // Section with children
332  m_toc.open("section", attributes);
333  m_openCount++;
334  }
335  else
336  {
337  // Section without children
338  m_toc.openClose("section", attributes);
339  }
340  }
341  else
342  {
344  }
345 
347 }
348 
349 void Qhp::setPrevSection(const QCString & title, const QCString & basename, const QCString & anchor, int level)
350 {
351  m_prevSectionTitle = title;
352  m_prevSectionBaseName = basename;
353  m_prevSectionAnchor = anchor;
354  m_prevSectionLevel = level;
355 }
356 
358 {
362 }
363 
364 void Qhp::addFile(const QCString & fileName)
365 {
366  m_files.openCloseContent("file", fileName);
367 }
368 
369 void Qhp::addImageFile(const QCString &fileName)
370 {
371  addFile(fileName);
372 }
373 
374 void Qhp::addStyleSheetFile(const QCString &fileName)
375 {
376  addFile(fileName);
377 }
378 
StringVector
std::vector< std::string > StringVector
Definition: containers.h:32
Qhp::addIndexItem
void addIndexItem(const Definition *context, const MemberDef *md, const QCString &sectionAnchor, const QCString &title)
Definition: qhp.cpp:223
Qhp::incContentsDepth
void incContentsDepth()
Definition: qhp.cpp:181
Definition
The common base class of all entity definitions found in the sources.
Definition: definition.h:76
Qhp::m_toc
QhpXmlWriter m_toc
Definition: qhp.h:56
memberdef.h
Qhp::finalize
void finalize()
Definition: qhp.cpp:148
QCString::isEmpty
bool isEmpty() const
Returns TRUE iff the string is empty
Definition: qcstring.h:144
qhpxmlwriter.h
QhpXmlWriter::declaration
void declaration(const QCString &version, const QCString &encoding)
Definition: qhpxmlwriter.cpp:85
split
static std::vector< QCString > split(const QCString &str, const QCString &sep, bool allowEmptyEntries=FALSE, bool cleanup=TRUE)
Definition: template.cpp:47
Qhp::m_index
QhpXmlWriter m_index
Definition: qhp.h:57
Qhp::m_prevSectionAnchor
QCString m_prevSectionAnchor
Definition: qhp.h:62
QhpXmlWriter::setIndentLevel
void setIndentLevel(int level)
Definition: qhpxmlwriter.cpp:30
QCString::str
std::string str() const
Definition: qcstring.h:442
Qhp::setPrevSection
void setPrevSection(const QCString &title, const QCString &basename, const QCString &anchor, int level)
Definition: qhp.cpp:349
QhpXmlWriter::dumpTo
void dumpTo(TextStream &file)
Definition: qhpxmlwriter.cpp:45
makeRef
static QCString makeRef(const QCString &withoutExtension, const QCString &anchor)
Definition: qhp.cpp:47
QCString::at
char & at(size_t i)
Returns a reference to the character at index i.
Definition: qcstring.h:477
TextStream
Text streaming class that buffers data.
Definition: textstream.h:33
Qhp::m_prevSectionTitle
QCString m_prevSectionTitle
Definition: qhp.h:60
Qhp::Qhp
Qhp()
Definition: qhp.cpp:56
Qhp::m_prevSectionLevel
int m_prevSectionLevel
Definition: qhp.h:64
Qhp::initialize
void initialize()
Definition: qhp.cpp:69
MemberDef::anchor
virtual QCString anchor() const =0
addHtmlExtensionIfMissing
QCString addHtmlExtensionIfMissing(const QCString &fName)
Definition: util.cpp:5275
MemberDef
A model of a class/file/namespace member symbol.
Definition: memberdef.h:45
Qhp::decContentsDepth
void decContentsDepth()
Definition: qhp.cpp:186
QhpXmlWriter::close
void close(const QCString &elementName)
Definition: qhpxmlwriter.cpp:77
QhpXmlWriter::open
void open(const QCString &elementName, const char *const attributes[]=0)
Definition: qhpxmlwriter.cpp:50
message.h
Qhp::clearPrevSection
void clearPrevSection()
Definition: qhp.cpp:357
Qhp::m_openCount
int m_openCount
Definition: qhp.h:66
Qhp::~Qhp
~Qhp()
Definition: qhp.cpp:64
Qhp::getFullProjectName
static QCString getFullProjectName()
Definition: qhp.cpp:291
Qhp::addIndexFile
void addIndexFile(const QCString &name)
Definition: qhp.cpp:281
Definition::name
virtual QCString name() const =0
doxygen.h
qhp.h
QhpXmlWriter::insert
void insert(QhpXmlWriter const &source)
Definition: qhpxmlwriter.cpp:40
TRUE
#define TRUE
Definition: qcstring.h:36
Definition::getOutputFileBase
virtual QCString getOutputFileBase() const =0
filedef.h
Qhp::addStyleSheetFile
void addStyleSheetFile(const QCString &name)
Definition: qhp.cpp:374
Qhp::handlePrevSection
void handlePrevSection()
Definition: qhp.cpp:301
Qhp::m_doc
QhpXmlWriter m_doc
Definition: qhp.h:55
QCString::mid
QCString mid(size_t index, size_t len=static_cast< size_t >(-1)) const
Definition: qcstring.h:224
MemberDef::getOutputFileBase
virtual QCString getOutputFileBase() const =0
Config_getBool
#define Config_getBool(name)
Definition: config.h:33
Qhp::m_sectionLevel
int m_sectionLevel
Definition: qhp.h:65
Doxygen::htmlFileExtension
static QCString htmlFileExtension
Definition: doxygen.h:103
QhpXmlWriter::openClose
void openClose(const QCString &elementName, const char *const attributes[]=0)
Definition: qhpxmlwriter.cpp:59
Qhp::addContentsItem
void addContentsItem(bool isDir, const QCString &name, const QCString &ref, const QCString &file, const QCString &anchor, bool separateIndex, bool addToNavIndex, const Definition *def)
Definition: qhp.cpp:196
term
void term(const char *fmt,...)
Definition: message.cpp:220
Qhp::addFile
void addFile(const QCString &fileName)
Definition: qhp.cpp:364
QCString::isNull
bool isNull() const
Returns TRUE iff the string is empty.
Definition: qcstring.h:141
MemberDef::getFileDef
virtual const FileDef * getFileDef() const =0
Config_getString
#define Config_getString(name)
Definition: config.h:32
Qhp::getQhpFileName
static QCString getQhpFileName()
Definition: qhp.cpp:286
QhpXmlWriter::openCloseContent
void openCloseContent(const QCString &elementName, const QCString &content)
Definition: qhpxmlwriter.cpp:67
config.h
groupdef.h
makeFileName
static QCString makeFileName(const QCString &withoutExtension)
Definition: qhp.cpp:30
QCString::data
const char * data() const
Returns a pointer to the contents of the string in the form of a 0-terminated C string
Definition: qcstring.h:153
Qhp::m_skipMainPageSection
bool m_skipMainPageSection
Definition: qhp.h:67
Qhp::m_files
QhpXmlWriter m_files
Definition: qhp.h:58
util.h
A bunch of utility functions.
Qhp::m_prevSectionBaseName
QCString m_prevSectionBaseName
Definition: qhp.h:61
Qhp::addImageFile
void addImageFile(const QCString &name)
Definition: qhp.cpp:369
QCString::resize
bool resize(size_t newlen)
Resizes the string to hold newlen characters (this value should also count the 0-terminator).
Definition: qcstring.h:164
MemberDef::getGroupDef
virtual const GroupDef * getGroupDef() const =0
FALSE
#define FALSE
Definition: qcstring.h:33
QCString
This is an alternative implementation of QCString.
Definition: qcstring.h:108