qhp.cpp
Go to the documentation of this file.
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 
26 #include <qstringlist.h>
27 #include <string.h>
28 #include <qfile.h>
29 
30 static QCString makeFileName(const char * 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 char * withoutExtension, const char * anchor)
48 {
49  //printf("QHP::makeRef(%s,%s)\n",withoutExtension,anchor);
50  if (!withoutExtension) return QCString();
51  QCString result = makeFileName(withoutExtension);
52  if (!anchor) return result;
53  return result+"#"+anchor;
54 }
55 
56 Qhp::Qhp() : m_prevSectionLevel(0), m_sectionLevel(0), m_skipMainPageSection(FALSE)
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, 0 };
102  m_doc.open("customFilter", tagAttributes);
103 
104  QStringList customFilterAttributes = QStringList::split(QChar(' '), Config_getString("QHP_CUST_FILTER_ATTRS"));
105  for (int i = 0; i < (int)customFilterAttributes.count(); i++)
106  {
107  m_doc.openCloseContent("filterAttribute", customFilterAttributes[i].utf8());
108  }
109  m_doc.close("customFilter");
110  }
111 
112  m_doc.open("filterSection");
113 
114  // Add section attributes
115  QStringList sectionFilterAttributes = QStringList::split(QChar(' '),
116  Config_getString("QHP_SECT_FILTER_ATTRS"));
117  if (!sectionFilterAttributes.contains(QString("doxygen")))
118  {
119  sectionFilterAttributes << "doxygen";
120  }
121  for (int i = 0; i < (int)sectionFilterAttributes.count(); i++)
122  {
123  m_doc.openCloseContent("filterAttribute", sectionFilterAttributes[i].utf8());
124  }
125 
126  m_toc.open("toc");
127 
128  // Add extra root node
129  QCString fullProjectname = getFullProjectName();
130  QCString indexFile = "index"+Doxygen::htmlFileExtension;
131  const char * const attributes[] =
132  { "title", fullProjectname,
133  "ref", indexFile,
134  NULL
135  };
136  m_toc.open("section", attributes);
138  m_prevSectionLevel = 1;
139  m_sectionLevel = 1;
140 
141  m_index.open("keywords");
142  m_files.open("files");
143 }
144 
146 {
147  // Finish TOC
149  for (int i = m_prevSectionLevel; i > 0; i--)
150  {
151  m_toc.close("section");
152  }
153  m_toc.close("toc");
154  m_doc.insert(m_toc);
155 
156  // Finish index
157  m_index.close("keywords");
159 
160  // Finish files
161  m_files.close("files");
163 
164  m_doc.close("filterSection");
165  m_doc.close("QtHelpProject");
166 
167  QCString fileName = Config_getString("HTML_OUTPUT") + "/" + getQhpFileName();
168  QFile file(fileName);
169  if (!file.open(IO_WriteOnly))
170  {
171  err("Could not open file %s for writing\n", fileName.data());
172  exit(1);
173  }
174  m_doc.dumpTo(file);
175 }
176 
178 {
179  m_sectionLevel++;
180 }
181 
183 {
185  {
187  return;
188  }
189  m_sectionLevel--;
190 }
191 
192 void Qhp::addContentsItem(bool /*isDir*/, const char * name,
193  const char * /*ref*/, const char * file,
194  const char *anchor, bool /* separateIndex */,
195  bool /* addToNavIndex */,
196  Definition * /*def*/)
197 {
198  //printf("Qhp::addContentsItem(%s) %d\n",name,m_sectionLevel);
199  // Backup difference before modification
200 
201  QCString f = file;
202  if (!f.isEmpty() && f.at(0)=='^') return; // absolute URL not supported
203 
204  int diff = m_prevSectionLevel - m_sectionLevel;
205 
207  setPrevSection(name, f, anchor, m_sectionLevel);
208 
209  // Close sections as needed
210  //printf("Qhp::addContentsItem() closing %d sections\n",diff);
211  for (; diff > 0; diff--)
212  {
213  m_toc.close("section");
214  }
215 }
216 
218  const char *sectionAnchor,const char *word)
219 {
220  (void)word;
221  //printf("addIndexItem(%s %s %s\n",
222  // context?context->name().data():"<none>",
223  // md?md->name().data():"<none>",
224  // word);
225 
226  if (md) // member
227  {
228  static bool separateMemberPages = Config_getBool("SEPARATE_MEMBER_PAGES");
229  if (context==0) // global member
230  {
231  if (md->getGroupDef())
232  context = md->getGroupDef();
233  else if (md->getFileDef())
234  context = md->getFileDef();
235  }
236  if (context==0) return; // should not happen
237  QCString cfname = md->getOutputFileBase();
238  QCString cfiname = context->getOutputFileBase();
239  QCString level1 = context->name();
240  QCString level2 = word ? QCString(word) : md->name();
241  QCString contRef = separateMemberPages ? cfname : cfiname;
242  QCString anchor = sectionAnchor ? QCString(sectionAnchor) : md->anchor();
243 
244  QCString ref;
245 
246  // <keyword name="foo" id="MyApplication::foo" ref="doc.html#foo"/>
247  ref = makeRef(contRef, anchor);
248  QCString id = level1+"::"+level2;
249  const char * attributes[] =
250  {
251  "name", level2,
252  "id", id,
253  "ref", ref,
254  0
255  };
256  m_index.openClose("keyword", attributes);
257  }
258  else if (context) // container
259  {
260  // <keyword name="Foo" id="Foo" ref="doc.html#Foo"/>
261  QCString contRef = context->getOutputFileBase();
262  QCString level1 = word ? QCString(word) : context->name();
263  QCString ref = makeRef(contRef,sectionAnchor);
264  const char * attributes[] =
265  {
266  "name", level1,
267  "id", level1,
268  "ref", ref,
269  0
270  };
271  m_index.openClose("keyword", attributes);
272  }
273 }
274 
275 void Qhp::addIndexFile(const char * name)
276 {
277  addFile(name);
278 }
279 
281 {
282  return "index.qhp";
283 }
284 
286 {
287  QCString projectName = Config_getString("PROJECT_NAME");
288  QCString versionText = Config_getString("PROJECT_NUMBER");
289  if (projectName.isEmpty()) projectName="Root";
290  return projectName + (versionText.isEmpty()
291  ? QCString("")
292  : QCString(" ") + versionText);
293 }
294 
296 {
297  /*
298  <toc>
299  <section title="My Application Manual" ref="index.html">
300  <section title="Chapter 1" ref="doc.html#chapter1"/>
301  <section title="Chapter 2" ref="doc.html#chapter2"/>
302  <section title="Chapter 3" ref="doc.html#chapter3"/>
303  </section>
304  </toc>
305  */
306 
308  {
309  m_prevSectionTitle=" "; // should not happen...
310  }
311 
312  // We skip "Main Page" as our extra root is pointing to that
314  {
316 
317  const char * const attributes[] =
318  { "title", m_prevSectionTitle,
319  "ref", finalRef,
320  NULL
321  };
322 
324  {
325  // Section with children
326  m_toc.open("section", attributes);
327  }
328  else
329  {
330  // Section without children
331  m_toc.openClose("section", attributes);
332  }
333  }
334  else
335  {
337  }
338 
340 }
341 
342 void Qhp::setPrevSection(const char * title, const char * basename, const char * anchor, int level)
343 {
346  m_prevSectionAnchor = anchor;
348 }
349 
351 {
355 }
356 
357 void Qhp::addFile(const char * fileName)
358 {
359  m_files.openCloseContent("file", fileName);
360 }
361 
362 void Qhp::addImageFile(const char *fileName)
363 {
364  addFile(fileName);
365 }
366 
368 {
369  addFile(fileName);
370 }
371 
static QCString name
Definition: declinfo.cpp:673
int m_sectionLevel
Definition: qhp.h:65
bool resize(uint newlen)
Definition: qcstring.h:225
void finalize()
Definition: qhp.cpp:145
void setIndentLevel(int level)
QCString m_prevSectionTitle
Definition: qhp.h:60
void setPrevSection(const char *title, const char *basename, const char *anchor, int level)
Definition: qhp.cpp:342
static QCString result
bool isEmpty() const
Definition: qcstring.h:189
#define IO_WriteOnly
Definition: qiodevice.h:62
void close(char const *elementName)
static QCString htmlFileExtension
Definition: doxygen.h:130
QhpXmlWriter m_files
Definition: qhp.h:58
char & at(uint i) const
Definition: qcstring.h:326
void addStyleSheetFile(const char *name)
Definition: qhp.cpp:367
const bool FALSE
Definition: qglobal.h:370
void declaration(char const *version, char const *encoding)
void addFile(const char *fileName)
Definition: qhp.cpp:357
The QString class provides an abstraction of Unicode text and the classic C null-terminated char arra...
Definition: qstring.h:350
static QCString makeFileName(const char *withoutExtension)
Definition: qhp.cpp:30
void addContentsItem(bool isDir, const char *name, const char *ref, const char *file, const char *anchor, bool separateIndex, bool addToNavIndex, Definition *def)
Definition: qhp.cpp:192
void open(char const *elementName, char const *const *attributes=0)
void handlePrevSection()
Definition: qhp.cpp:295
virtual QCString getOutputFileBase() const =0
The QChar class provides a light-weight Unicode character.
Definition: qstring.h:56
uint count() const
Definition: qvaluelist.h:394
void initialize()
Definition: qhp.cpp:69
QhpXmlWriter m_toc
Definition: qhp.h:56
FileDef * getFileDef() const
Definition: memberdef.cpp:4075
void addImageFile(const char *name)
Definition: qhp.cpp:362
bool isNull() const
Definition: qcstring.h:183
const QCString & name() const
Definition: definition.h:114
static QCString getQhpFileName()
Definition: qhp.cpp:280
fileName
Definition: dumpTree.py:9
void openCloseContent(char const *elementName, char const *content)
A list of strings.
Definition: qstringlist.h:51
void addIndexFile(const char *name)
Definition: qhp.cpp:275
bool open(int)
Definition: qfile_unix.cpp:134
int m_prevSectionLevel
Definition: qhp.h:64
void addIndexItem(Definition *context, MemberDef *md, const char *sectionAnchor, const char *title)
Definition: qhp.cpp:217
~Qhp()
Definition: qhp.cpp:64
QCString m_prevSectionAnchor
Definition: qhp.h:62
void dumpTo(QFile &file)
const char * data() const
Definition: qcstring.h:207
void decContentsDepth()
Definition: qhp.cpp:182
QCString anchor() const
Definition: memberdef.cpp:1031
#define Config_getString(val)
Definition: config.cpp:660
#define Config_getBool(val)
Definition: config.cpp:664
void incContentsDepth()
Definition: qhp.cpp:177
void err(const char *fmt,...)
Definition: message.cpp:226
bool m_skipMainPageSection
Definition: qhp.h:67
uint contains(const T &x) const
Definition: qvaluelist.h:392
QCString mid(uint index, uint len=0xffffffff) const
Definition: qcstring.cpp:246
The QFile class is an I/O device that operates on files.
Definition: qfile.h:50
static QCString makeRef(const char *withoutExtension, const char *anchor)
Definition: qhp.cpp:47
GroupDef * getGroupDef() const
Definition: memberdef.cpp:4095
static QCString getFullProjectName()
Definition: qhp.cpp:285
QhpXmlWriter m_index
Definition: qhp.h:57
QCString getOutputFileBase() const
Definition: memberdef.cpp:941
void openClose(char const *elementName, char const *const *attributes=0)
void insert(QhpXmlWriter const &source)
void clearPrevSection()
Definition: qhp.cpp:350
QhpXmlWriter m_doc
Definition: qhp.h:55
static QStringList split(const QString &sep, const QString &str, bool allowEmptyEntries=FALSE)
union ptb::content::word::word word
const bool TRUE
Definition: qglobal.h:371
QCString m_prevSectionBaseName
Definition: qhp.h:61
Qhp()
Definition: qhp.cpp:56