[2] | 1 | /****************************************************************************
|
---|
| 2 | **
|
---|
[846] | 3 | ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
|
---|
[561] | 4 | ** All rights reserved.
|
---|
| 5 | ** Contact: Nokia Corporation ([email protected])
|
---|
[2] | 6 | **
|
---|
| 7 | ** This file is part of the tools applications of the Qt Toolkit.
|
---|
| 8 | **
|
---|
| 9 | ** $QT_BEGIN_LICENSE:LGPL$
|
---|
| 10 | ** Commercial Usage
|
---|
| 11 | ** Licensees holding valid Qt Commercial licenses may use this file in
|
---|
| 12 | ** accordance with the Qt Commercial License Agreement provided with the
|
---|
| 13 | ** Software or, alternatively, in accordance with the terms contained in
|
---|
| 14 | ** a written agreement between you and Nokia.
|
---|
| 15 | **
|
---|
| 16 | ** GNU Lesser General Public License Usage
|
---|
| 17 | ** Alternatively, this file may be used under the terms of the GNU Lesser
|
---|
| 18 | ** General Public License version 2.1 as published by the Free Software
|
---|
| 19 | ** Foundation and appearing in the file LICENSE.LGPL included in the
|
---|
| 20 | ** packaging of this file. Please review the following information to
|
---|
| 21 | ** ensure the GNU Lesser General Public License version 2.1 requirements
|
---|
| 22 | ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
---|
| 23 | **
|
---|
[561] | 24 | ** In addition, as a special exception, Nokia gives you certain additional
|
---|
| 25 | ** rights. These rights are described in the Nokia Qt LGPL Exception
|
---|
| 26 | ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
---|
[2] | 27 | **
|
---|
| 28 | ** GNU General Public License Usage
|
---|
| 29 | ** Alternatively, this file may be used under the terms of the GNU
|
---|
| 30 | ** General Public License version 3.0 as published by the Free Software
|
---|
| 31 | ** Foundation and appearing in the file LICENSE.GPL included in the
|
---|
| 32 | ** packaging of this file. Please review the following information to
|
---|
| 33 | ** ensure the GNU General Public License version 3.0 requirements will be
|
---|
| 34 | ** met: http://www.gnu.org/copyleft/gpl.html.
|
---|
| 35 | **
|
---|
[561] | 36 | ** If you have questions regarding the use of this file, please contact
|
---|
| 37 | ** Nokia at [email protected].
|
---|
[2] | 38 | ** $QT_END_LICENSE$
|
---|
| 39 | **
|
---|
| 40 | ****************************************************************************/
|
---|
| 41 |
|
---|
| 42 | /*
|
---|
| 43 | webxmlgenerator.cpp
|
---|
| 44 | */
|
---|
| 45 |
|
---|
| 46 | #include "codemarker.h"
|
---|
| 47 | #include "pagegenerator.h"
|
---|
| 48 | #include "webxmlgenerator.h"
|
---|
| 49 | #include "node.h"
|
---|
| 50 | #include "separator.h"
|
---|
| 51 | #include "tree.h"
|
---|
| 52 |
|
---|
[846] | 53 | #include <QtCore/qxmlstream.h>
|
---|
| 54 |
|
---|
[2] | 55 | QT_BEGIN_NAMESPACE
|
---|
| 56 |
|
---|
| 57 | #define COMMAND_VERSION Doc::alias("version")
|
---|
| 58 |
|
---|
| 59 | WebXMLGenerator::WebXMLGenerator()
|
---|
| 60 | : PageGenerator()
|
---|
| 61 | {
|
---|
| 62 | }
|
---|
| 63 |
|
---|
| 64 | WebXMLGenerator::~WebXMLGenerator()
|
---|
| 65 | {
|
---|
| 66 | }
|
---|
| 67 |
|
---|
| 68 | void WebXMLGenerator::initializeGenerator(const Config &config)
|
---|
| 69 | {
|
---|
| 70 | Generator::initializeGenerator(config);
|
---|
| 71 |
|
---|
| 72 | project = config.getString(CONFIG_PROJECT);
|
---|
| 73 |
|
---|
| 74 | projectDescription = config.getString(CONFIG_DESCRIPTION);
|
---|
| 75 | if (projectDescription.isEmpty() && !project.isEmpty())
|
---|
| 76 | projectDescription = project + " Reference Documentation";
|
---|
| 77 |
|
---|
| 78 | projectUrl = config.getString(CONFIG_URL);
|
---|
| 79 |
|
---|
| 80 | generateIndex = config.getBool(CONFIG_GENERATEINDEX);
|
---|
| 81 | }
|
---|
| 82 |
|
---|
| 83 | void WebXMLGenerator::terminateGenerator()
|
---|
| 84 | {
|
---|
| 85 | PageGenerator::terminateGenerator();
|
---|
| 86 | }
|
---|
| 87 |
|
---|
| 88 | QString WebXMLGenerator::format()
|
---|
| 89 | {
|
---|
| 90 | return "WebXML";
|
---|
| 91 | }
|
---|
| 92 |
|
---|
[846] | 93 | QString WebXMLGenerator::fileExtension(const Node * /* node */) const
|
---|
[2] | 94 | {
|
---|
| 95 | return "xml";
|
---|
| 96 | }
|
---|
| 97 |
|
---|
| 98 | void WebXMLGenerator::generateTree(const Tree *tree, CodeMarker *marker)
|
---|
| 99 | {
|
---|
| 100 | tre = tree;
|
---|
| 101 | moduleClassMap.clear();
|
---|
| 102 | moduleNamespaceMap.clear();
|
---|
| 103 | serviceClasses.clear();
|
---|
| 104 | findAllClasses(tree->root());
|
---|
| 105 | findAllNamespaces(tree->root());
|
---|
| 106 |
|
---|
| 107 | PageGenerator::generateTree(tree, marker);
|
---|
| 108 |
|
---|
| 109 | if (generateIndex)
|
---|
| 110 | tre->generateIndex(outputDir() + "/" + project.toLower() + ".index",
|
---|
| 111 | projectUrl, projectDescription, false);
|
---|
| 112 | }
|
---|
| 113 |
|
---|
| 114 | void WebXMLGenerator::startText(const Node *relative, CodeMarker *marker)
|
---|
| 115 | {
|
---|
| 116 | inLink = false;
|
---|
| 117 | inContents = false;
|
---|
| 118 | inSectionHeading = false;
|
---|
| 119 | numTableRows = 0;
|
---|
| 120 | sectionNumber.clear();
|
---|
| 121 | PageGenerator::startText(relative, marker);
|
---|
| 122 | }
|
---|
| 123 |
|
---|
| 124 | int WebXMLGenerator::generateAtom(QXmlStreamWriter &writer, const Atom *atom,
|
---|
| 125 | const Node *relative, CodeMarker *marker)
|
---|
| 126 | {
|
---|
| 127 | Q_UNUSED(writer);
|
---|
| 128 |
|
---|
| 129 | int skipAhead = 0;
|
---|
| 130 |
|
---|
| 131 | switch (atom->type()) {
|
---|
| 132 | default:
|
---|
| 133 | PageGenerator::generateAtom(atom, relative, marker);
|
---|
| 134 | }
|
---|
| 135 | return skipAhead;
|
---|
| 136 | }
|
---|
| 137 |
|
---|
| 138 | void WebXMLGenerator::generateClassLikeNode(const InnerNode *inner,
|
---|
| 139 | CodeMarker *marker)
|
---|
| 140 | {
|
---|
| 141 | QByteArray data;
|
---|
| 142 | QXmlStreamWriter writer(&data);
|
---|
| 143 | writer.setAutoFormatting(true);
|
---|
| 144 | writer.writeStartDocument();
|
---|
| 145 | writer.writeStartElement("WebXML");
|
---|
| 146 | writer.writeStartElement("document");
|
---|
| 147 |
|
---|
| 148 | generateIndexSections(writer, inner, marker);
|
---|
| 149 |
|
---|
| 150 | writer.writeEndElement(); // document
|
---|
| 151 | writer.writeEndElement(); // WebXML
|
---|
| 152 | writer.writeEndDocument();
|
---|
| 153 |
|
---|
| 154 | out() << data;
|
---|
| 155 | out().flush();
|
---|
| 156 | }
|
---|
| 157 |
|
---|
| 158 | void WebXMLGenerator::generateFakeNode(const FakeNode *fake, CodeMarker *marker)
|
---|
| 159 | {
|
---|
| 160 | QByteArray data;
|
---|
| 161 | QXmlStreamWriter writer(&data);
|
---|
| 162 | writer.setAutoFormatting(true);
|
---|
| 163 | writer.writeStartDocument();
|
---|
| 164 | writer.writeStartElement("WebXML");
|
---|
| 165 | writer.writeStartElement("document");
|
---|
| 166 |
|
---|
| 167 | generateIndexSections(writer, fake, marker);
|
---|
| 168 |
|
---|
| 169 | writer.writeEndElement(); // document
|
---|
| 170 | writer.writeEndElement(); // WebXML
|
---|
| 171 | writer.writeEndDocument();
|
---|
| 172 |
|
---|
| 173 | out() << data;
|
---|
| 174 | out().flush();
|
---|
| 175 | }
|
---|
| 176 |
|
---|
| 177 | void WebXMLGenerator::generateIndexSections(QXmlStreamWriter &writer,
|
---|
| 178 | const Node *node, CodeMarker *marker)
|
---|
| 179 | {
|
---|
| 180 | if (tre->generateIndexSection(writer, node, true)) {
|
---|
| 181 |
|
---|
| 182 | // Add documentation to this node if it exists.
|
---|
| 183 | writer.writeStartElement("description");
|
---|
| 184 | writer.writeAttribute("path", node->doc().location().filePath());
|
---|
| 185 | writer.writeAttribute("line", QString::number(node->doc().location().lineNo()));
|
---|
| 186 | writer.writeAttribute("column", QString::number(node->doc().location().columnNo()));
|
---|
| 187 |
|
---|
| 188 | if (node->type() == Node::Fake) {
|
---|
| 189 |
|
---|
| 190 | const FakeNode *fake = static_cast<const FakeNode *>(node);
|
---|
| 191 |
|
---|
| 192 | generateRelations(writer, node, marker);
|
---|
| 193 |
|
---|
[561] | 194 | if (fake->subType() == Node::Module) {
|
---|
[2] | 195 | writer.writeStartElement("generatedlist");
|
---|
| 196 | writer.writeAttribute("contents", "classesbymodule");
|
---|
| 197 |
|
---|
| 198 | if (moduleNamespaceMap.contains(fake->name())) {
|
---|
| 199 | writer.writeStartElement("section");
|
---|
| 200 | writer.writeStartElement("heading");
|
---|
| 201 | writer.writeAttribute("level", "1");
|
---|
| 202 | writer.writeCharacters("Namespaces");
|
---|
| 203 | writer.writeEndElement(); // heading
|
---|
| 204 | generateAnnotatedList(writer, fake, marker, moduleNamespaceMap[fake->name()]);
|
---|
| 205 | writer.writeEndElement(); // section
|
---|
| 206 | }
|
---|
| 207 | if (moduleClassMap.contains(fake->name())) {
|
---|
| 208 | writer.writeStartElement("section");
|
---|
| 209 | writer.writeStartElement("heading");
|
---|
| 210 | writer.writeAttribute("level", "1");
|
---|
| 211 | writer.writeCharacters("Classes");
|
---|
| 212 | writer.writeEndElement(); // heading
|
---|
| 213 | generateAnnotatedList(writer, fake, marker, moduleClassMap[fake->name()]);
|
---|
| 214 | writer.writeEndElement(); // section
|
---|
| 215 | }
|
---|
| 216 |
|
---|
| 217 | writer.writeEndElement(); // generatedlist
|
---|
| 218 | }
|
---|
| 219 | }
|
---|
| 220 |
|
---|
| 221 | startText(node, marker);
|
---|
| 222 |
|
---|
| 223 | const Atom *atom = node->doc().body().firstAtom();
|
---|
| 224 | while (atom)
|
---|
| 225 | atom = addAtomElements(writer, atom, node, marker);
|
---|
| 226 |
|
---|
| 227 | QList<Text> alsoList = node->doc().alsoList();
|
---|
| 228 | supplementAlsoList(node, alsoList);
|
---|
| 229 |
|
---|
| 230 | if (!alsoList.isEmpty()) {
|
---|
| 231 | writer.writeStartElement("see-also");
|
---|
| 232 | for (int i = 0; i < alsoList.size(); ++i) {
|
---|
| 233 | const Atom *atom = alsoList.at(i).firstAtom();
|
---|
| 234 | while (atom)
|
---|
| 235 | atom = addAtomElements(writer, atom, node, marker);
|
---|
| 236 | }
|
---|
| 237 | writer.writeEndElement(); // see-also
|
---|
| 238 | }
|
---|
| 239 |
|
---|
| 240 | writer.writeEndElement(); // description
|
---|
| 241 |
|
---|
| 242 | if (node->isInnerNode()) {
|
---|
| 243 | const InnerNode *inner = static_cast<const InnerNode *>(node);
|
---|
| 244 |
|
---|
| 245 | // Recurse to generate an element for this child node and all its children.
|
---|
| 246 | foreach (const Node *child, inner->childNodes())
|
---|
| 247 | generateIndexSections(writer, child, marker);
|
---|
| 248 |
|
---|
| 249 | writer.writeStartElement("related");
|
---|
| 250 | if (inner->relatedNodes().size() > 0) {
|
---|
| 251 | foreach (const Node *child, inner->relatedNodes())
|
---|
| 252 | generateIndexSections(writer, child, marker);
|
---|
| 253 | }
|
---|
| 254 | writer.writeEndElement(); // related
|
---|
| 255 | }
|
---|
| 256 | writer.writeEndElement();
|
---|
| 257 | }
|
---|
| 258 | }
|
---|
| 259 |
|
---|
| 260 | void WebXMLGenerator::generateInnerNode(const InnerNode *node, CodeMarker *marker)
|
---|
| 261 | {
|
---|
| 262 | if (!node->url().isNull())
|
---|
| 263 | return;
|
---|
| 264 |
|
---|
| 265 | if (node->type() == Node::Fake) {
|
---|
| 266 | const FakeNode *fakeNode = static_cast<const FakeNode *>(node);
|
---|
[561] | 267 | if (fakeNode->subType() == Node::ExternalPage)
|
---|
[2] | 268 | return;
|
---|
| 269 | }
|
---|
| 270 |
|
---|
| 271 | if ( node->parent() != 0 ) {
|
---|
| 272 | beginSubPage( node->location(), fileName(node) );
|
---|
| 273 | if ( node->type() == Node::Namespace || node->type() == Node::Class) {
|
---|
| 274 | generateClassLikeNode(node, marker);
|
---|
| 275 | } else if ( node->type() == Node::Fake ) {
|
---|
| 276 | generateFakeNode(static_cast<const FakeNode *>(node), marker);
|
---|
| 277 | }
|
---|
| 278 | endSubPage();
|
---|
| 279 | }
|
---|
| 280 |
|
---|
| 281 | NodeList::ConstIterator c = node->childNodes().begin();
|
---|
| 282 | while ( c != node->childNodes().end() ) {
|
---|
| 283 | if ((*c)->isInnerNode() && (
|
---|
| 284 | (*c)->access() != Node::Private || (*c)->status() == Node::Internal))
|
---|
| 285 | generateInnerNode( (const InnerNode *) *c, marker );
|
---|
| 286 | ++c;
|
---|
| 287 | }
|
---|
| 288 | }
|
---|
| 289 |
|
---|
| 290 | const Atom *WebXMLGenerator::addAtomElements(QXmlStreamWriter &writer,
|
---|
| 291 | const Atom *atom, const Node *relative, CodeMarker *marker)
|
---|
| 292 | {
|
---|
| 293 | switch (atom->type()) {
|
---|
| 294 | case Atom::AbstractLeft:
|
---|
| 295 | case Atom::AbstractRight:
|
---|
| 296 | break;
|
---|
| 297 | case Atom::AutoLink:
|
---|
| 298 | if (!inLink && !inSectionHeading) {
|
---|
| 299 | const Node *node = findNode(atom, relative, marker);
|
---|
| 300 | if (node) {
|
---|
| 301 | startLink(writer, atom, node, relative);
|
---|
| 302 | if (inLink) {
|
---|
| 303 | writer.writeCharacters(atom->string());
|
---|
| 304 | writer.writeEndElement(); // link
|
---|
| 305 | inLink = false;
|
---|
| 306 | }
|
---|
| 307 | } else
|
---|
| 308 | writer.writeCharacters(atom->string());
|
---|
| 309 | } else
|
---|
| 310 | writer.writeCharacters(atom->string());
|
---|
| 311 | break;
|
---|
| 312 | case Atom::BaseName:
|
---|
| 313 | break;
|
---|
| 314 | case Atom::BriefLeft:
|
---|
| 315 |
|
---|
| 316 | writer.writeStartElement("brief");
|
---|
| 317 | switch (relative->type()) {
|
---|
| 318 | case Node::Property:
|
---|
| 319 | writer.writeCharacters("This property");
|
---|
| 320 | break;
|
---|
| 321 | case Node::Variable:
|
---|
| 322 | writer.writeCharacters("This variable");
|
---|
| 323 | break;
|
---|
| 324 | default:
|
---|
| 325 | break;
|
---|
| 326 | }
|
---|
| 327 | if (relative->type() == Node::Property || relative->type() == Node::Variable) {
|
---|
| 328 | QString str;
|
---|
| 329 | const Atom *a = atom->next();
|
---|
| 330 | while (a != 0 && a->type() != Atom::BriefRight) {
|
---|
| 331 | if (a->type() == Atom::String || a->type() == Atom::AutoLink)
|
---|
| 332 | str += a->string();
|
---|
| 333 | a = a->next();
|
---|
| 334 | }
|
---|
| 335 | str[0] = str[0].toLower();
|
---|
| 336 | if (str.right(1) == ".")
|
---|
| 337 | str.chop(1);
|
---|
| 338 |
|
---|
| 339 | QStringList words = str.split(" ");
|
---|
| 340 | if (!(words.first() == "contains" || words.first() == "specifies"
|
---|
| 341 | || words.first() == "describes" || words.first() == "defines"
|
---|
| 342 | || words.first() == "holds" || words.first() == "determines"))
|
---|
| 343 | writer.writeCharacters(" holds ");
|
---|
| 344 | else
|
---|
| 345 | writer.writeCharacters(" ");
|
---|
| 346 | }
|
---|
| 347 | break;
|
---|
| 348 |
|
---|
| 349 | case Atom::BriefRight:
|
---|
| 350 | if (relative->type() == Node::Property || relative->type() == Node::Variable)
|
---|
| 351 | writer.writeCharacters(".");
|
---|
| 352 |
|
---|
| 353 | writer.writeEndElement(); // brief
|
---|
| 354 | break;
|
---|
| 355 |
|
---|
| 356 | case Atom::C:
|
---|
| 357 | writer.writeStartElement("teletype");
|
---|
| 358 | if (inLink)
|
---|
| 359 | writer.writeAttribute("type", "normal");
|
---|
| 360 | else
|
---|
| 361 | writer.writeAttribute("type", "highlighted");
|
---|
| 362 |
|
---|
| 363 | writer.writeCharacters(plainCode(atom->string()));
|
---|
| 364 | writer.writeEndElement(); // teletype
|
---|
| 365 | break;
|
---|
| 366 |
|
---|
| 367 | case Atom::Code:
|
---|
| 368 | writer.writeTextElement("code", trimmedTrailing(plainCode(atom->string())));
|
---|
| 369 | break;
|
---|
| 370 |
|
---|
| 371 | #ifdef QDOC_QML
|
---|
| 372 | case Atom::Qml:
|
---|
| 373 | writer.writeTextElement("qml", trimmedTrailing(plainCode(atom->string())));
|
---|
| 374 | #endif
|
---|
| 375 |
|
---|
| 376 | case Atom::CodeBad:
|
---|
| 377 | writer.writeTextElement("badcode", trimmedTrailing(plainCode(atom->string())));
|
---|
| 378 | break;
|
---|
| 379 |
|
---|
| 380 | case Atom::CodeNew:
|
---|
| 381 | writer.writeTextElement("para", "you can rewrite it as");
|
---|
| 382 | writer.writeTextElement("newcode", trimmedTrailing(plainCode(atom->string())));
|
---|
| 383 | break;
|
---|
| 384 |
|
---|
| 385 | case Atom::CodeOld:
|
---|
| 386 | writer.writeTextElement("para", "For example, if you have code like");
|
---|
| 387 | writer.writeTextElement("oldcode", trimmedTrailing(plainCode(atom->string())));
|
---|
| 388 | break;
|
---|
| 389 |
|
---|
| 390 | case Atom::CodeQuoteArgument:
|
---|
| 391 | if (quoteCommand == "dots") {
|
---|
| 392 | writer.writeAttribute("indent", atom->string());
|
---|
| 393 | writer.writeCharacters("...");
|
---|
| 394 | } else
|
---|
| 395 | writer.writeCharacters(atom->string());
|
---|
| 396 | writer.writeEndElement(); // code
|
---|
| 397 | break;
|
---|
| 398 |
|
---|
| 399 | case Atom::CodeQuoteCommand:
|
---|
| 400 | quoteCommand = atom->string();
|
---|
| 401 | writer.writeStartElement(quoteCommand);
|
---|
| 402 | break;
|
---|
| 403 |
|
---|
| 404 | case Atom::FootnoteLeft:
|
---|
| 405 | writer.writeStartElement("footnote");
|
---|
| 406 | break;
|
---|
| 407 |
|
---|
| 408 | case Atom::FootnoteRight:
|
---|
| 409 | writer.writeEndElement(); // footnote
|
---|
| 410 | break;
|
---|
| 411 | /*
|
---|
| 412 | case Atom::FormatElse:
|
---|
| 413 | writer.writeStartElement("else");
|
---|
| 414 | writer.writeEndElement(); // else
|
---|
| 415 | break;
|
---|
| 416 | */
|
---|
| 417 | case Atom::FormatEndif:
|
---|
| 418 | writer.writeEndElement(); // raw
|
---|
| 419 | break;
|
---|
| 420 | case Atom::FormatIf:
|
---|
| 421 | writer.writeStartElement("raw");
|
---|
| 422 | writer.writeAttribute("format", atom->string());
|
---|
| 423 | break;
|
---|
| 424 | case Atom::FormattingLeft:
|
---|
| 425 | {
|
---|
| 426 | if (atom->string() == ATOM_FORMATTING_BOLD)
|
---|
| 427 | writer.writeStartElement("bold");
|
---|
| 428 | else if (atom->string() == ATOM_FORMATTING_ITALIC)
|
---|
| 429 | writer.writeStartElement("italic");
|
---|
| 430 | else if (atom->string() == ATOM_FORMATTING_UNDERLINE)
|
---|
| 431 | writer.writeStartElement("underline");
|
---|
| 432 | else if (atom->string() == ATOM_FORMATTING_SUBSCRIPT)
|
---|
| 433 | writer.writeStartElement("subscript");
|
---|
| 434 | else if (atom->string() == ATOM_FORMATTING_SUPERSCRIPT)
|
---|
| 435 | writer.writeStartElement("superscript");
|
---|
| 436 | else if (atom->string() == ATOM_FORMATTING_TELETYPE)
|
---|
| 437 | writer.writeStartElement("teletype");
|
---|
| 438 | else if (atom->string() == ATOM_FORMATTING_PARAMETER)
|
---|
| 439 | writer.writeStartElement("argument");
|
---|
| 440 | else if (atom->string() == ATOM_FORMATTING_INDEX)
|
---|
| 441 | writer.writeStartElement("index");
|
---|
| 442 | }
|
---|
| 443 | break;
|
---|
| 444 | /* out() << formattingLeftMap()[atom->string()];
|
---|
| 445 | if ( atom->string() == ATOM_FORMATTING_PARAMETER ) {
|
---|
| 446 | if ( atom->next() != 0 && atom->next()->type() == Atom::String ) {
|
---|
| 447 | QRegExp subscriptRegExp( "([a-z]+)_([0-9n])" );
|
---|
| 448 | if ( subscriptRegExp.exactMatch(atom->next()->string()) ) {
|
---|
| 449 | out() << subscriptRegExp.cap( 1 ) << "<sub>"
|
---|
| 450 | << subscriptRegExp.cap( 2 ) << "</sub>";
|
---|
| 451 | skipAhead = 1;
|
---|
| 452 | }
|
---|
| 453 | }
|
---|
| 454 | }*/
|
---|
| 455 | case Atom::FormattingRight:
|
---|
| 456 | {
|
---|
| 457 | if (atom->string() == ATOM_FORMATTING_BOLD)
|
---|
| 458 | writer.writeEndElement();
|
---|
| 459 | else if (atom->string() == ATOM_FORMATTING_ITALIC)
|
---|
| 460 | writer.writeEndElement();
|
---|
| 461 | else if (atom->string() == ATOM_FORMATTING_UNDERLINE)
|
---|
| 462 | writer.writeEndElement();
|
---|
| 463 | else if (atom->string() == ATOM_FORMATTING_SUBSCRIPT)
|
---|
| 464 | writer.writeEndElement();
|
---|
| 465 | else if (atom->string() == ATOM_FORMATTING_SUPERSCRIPT)
|
---|
| 466 | writer.writeEndElement();
|
---|
| 467 | else if (atom->string() == ATOM_FORMATTING_TELETYPE)
|
---|
| 468 | writer.writeEndElement();
|
---|
| 469 | else if (atom->string() == ATOM_FORMATTING_PARAMETER)
|
---|
| 470 | writer.writeEndElement();
|
---|
| 471 | else if (atom->string() == ATOM_FORMATTING_INDEX)
|
---|
| 472 | writer.writeEndElement();
|
---|
| 473 | }
|
---|
| 474 | if (inLink) {
|
---|
| 475 | writer.writeEndElement(); // link
|
---|
| 476 | inLink = false;
|
---|
| 477 | }
|
---|
| 478 | break;
|
---|
| 479 | /* if ( atom->string() == ATOM_FORMATTING_LINK ) {
|
---|
| 480 | if (inLink) {
|
---|
| 481 | if ( link.isEmpty() ) {
|
---|
| 482 | if (showBrokenLinks)
|
---|
| 483 | out() << "</i>";
|
---|
| 484 | } else {
|
---|
| 485 | out() << "</a>";
|
---|
| 486 | }
|
---|
| 487 | }
|
---|
| 488 | inLink = false;
|
---|
| 489 | } else {
|
---|
| 490 | out() << formattingRightMap()[atom->string()];
|
---|
| 491 | }*/
|
---|
| 492 | case Atom::GeneratedList:
|
---|
| 493 | writer.writeStartElement("generatedlist");
|
---|
| 494 | writer.writeAttribute("contents", atom->string());
|
---|
| 495 | writer.writeEndElement(); // generatedlist
|
---|
| 496 | /*
|
---|
| 497 | if (atom->string() == "annotatedclasses") {
|
---|
| 498 | generateAnnotatedList(relative, marker, nonCompatClasses);
|
---|
| 499 | } else if (atom->string() == "classes") {
|
---|
| 500 | generateCompactList(relative, marker, nonCompatClasses);
|
---|
| 501 | } else if (atom->string().contains("classesbymodule")) {
|
---|
| 502 | QString arg = atom->string().trimmed();
|
---|
| 503 | QString moduleName = atom->string().mid(atom->string().indexOf(
|
---|
| 504 | "classesbymodule") + 15).trimmed();
|
---|
| 505 | if (moduleClassMap.contains(moduleName))
|
---|
| 506 | generateAnnotatedList(relative, marker, moduleClassMap[moduleName]);
|
---|
| 507 | } else if (atom->string().contains("classesbyedition")) {
|
---|
| 508 | QString arg = atom->string().trimmed();
|
---|
| 509 | QString editionName = atom->string().mid(atom->string().indexOf(
|
---|
| 510 | "classesbyedition") + 16).trimmed();
|
---|
| 511 | if (editionModuleMap.contains(editionName)) {
|
---|
| 512 | QMap<QString, const Node *> editionClasses;
|
---|
| 513 | foreach (const QString &moduleName, editionModuleMap[editionName]) {
|
---|
| 514 | if (moduleClassMap.contains(moduleName))
|
---|
| 515 | editionClasses.unite(moduleClassMap[moduleName]);
|
---|
| 516 | }
|
---|
| 517 | generateAnnotatedList(relative, marker, editionClasses);
|
---|
| 518 | }
|
---|
| 519 | } else if (atom->string() == "classhierarchy") {
|
---|
| 520 | generateClassHierarchy(relative, marker, nonCompatClasses);
|
---|
| 521 | } else if (atom->string() == "compatclasses") {
|
---|
| 522 | generateCompactList(relative, marker, compatClasses);
|
---|
| 523 | } else if (atom->string() == "functionindex") {
|
---|
| 524 | generateFunctionIndex(relative, marker);
|
---|
| 525 | } else if (atom->string() == "legalese") {
|
---|
| 526 | generateLegaleseList(relative, marker);
|
---|
| 527 | } else if (atom->string() == "mainclasses") {
|
---|
| 528 | generateCompactList(relative, marker, mainClasses);
|
---|
| 529 | } else if (atom->string() == "services") {
|
---|
| 530 | generateCompactList(relative, marker, serviceClasses);
|
---|
| 531 | } else if (atom->string() == "overviews") {
|
---|
| 532 | generateOverviewList(relative, marker);
|
---|
| 533 | } else if (atom->string() == "namespaces") {
|
---|
| 534 | generateAnnotatedList(relative, marker, namespaceIndex);
|
---|
| 535 | } else if (atom->string() == "related") {
|
---|
| 536 | const FakeNode *fake = static_cast<const FakeNode *>(relative);
|
---|
| 537 | if (fake && !fake->groupMembers().isEmpty()) {
|
---|
| 538 | QMap<QString, const Node *> groupMembersMap;
|
---|
| 539 | foreach (Node *node, fake->groupMembers()) {
|
---|
| 540 | if (node->type() == Node::Fake)
|
---|
| 541 | groupMembersMap[fullName(node, relative, marker)] = node;
|
---|
| 542 | }
|
---|
| 543 | generateAnnotatedList(fake, marker, groupMembersMap);
|
---|
| 544 | }
|
---|
| 545 | } else if (atom->string() == "relatedinline") {
|
---|
| 546 | const FakeNode *fake = static_cast<const FakeNode *>(relative);
|
---|
| 547 | if (fake && !fake->groupMembers().isEmpty()) {
|
---|
| 548 | // Reverse the list into the original scan order.
|
---|
| 549 | // Should be sorted. But on what? It may not be a
|
---|
| 550 | // regular class or page definition.
|
---|
| 551 | QList<const Node *> list;
|
---|
| 552 | foreach (const Node *node, fake->groupMembers())
|
---|
| 553 | list.prepend(node);
|
---|
| 554 | foreach (const Node *node, list)
|
---|
| 555 | generateBody(node, marker );
|
---|
| 556 | }
|
---|
| 557 | }
|
---|
| 558 | break;
|
---|
| 559 | */
|
---|
| 560 | break;
|
---|
| 561 | case Atom::Image:
|
---|
| 562 | writer.writeStartElement("image");
|
---|
| 563 | writer.writeAttribute("href", imageFileName(relative, atom->string()));
|
---|
| 564 | writer.writeEndElement(); // image
|
---|
| 565 | break;
|
---|
| 566 |
|
---|
| 567 | case Atom::InlineImage:
|
---|
| 568 | writer.writeStartElement("inlineimage");
|
---|
| 569 | writer.writeAttribute("href", imageFileName(relative, atom->string()));
|
---|
| 570 | writer.writeEndElement(); // inlineimage
|
---|
| 571 | break;
|
---|
| 572 |
|
---|
| 573 | case Atom::ImageText:
|
---|
| 574 | break;
|
---|
| 575 |
|
---|
| 576 | case Atom::LegaleseLeft:
|
---|
| 577 | writer.writeStartElement("legalese");
|
---|
| 578 | break;
|
---|
| 579 |
|
---|
| 580 | case Atom::LegaleseRight:
|
---|
| 581 | writer.writeEndElement(); // legalese
|
---|
| 582 | break;
|
---|
| 583 |
|
---|
| 584 | case Atom::Link:
|
---|
| 585 | case Atom::LinkNode:
|
---|
| 586 | if (!inLink) {
|
---|
| 587 | const Node *node = findNode(atom, relative, marker);
|
---|
| 588 | if (node)
|
---|
| 589 | startLink(writer, atom, node, relative);
|
---|
| 590 | }
|
---|
| 591 | break;
|
---|
| 592 |
|
---|
| 593 | case Atom::ListLeft:
|
---|
| 594 | writer.writeStartElement("list");
|
---|
| 595 |
|
---|
| 596 | if (atom->string() == ATOM_LIST_BULLET)
|
---|
| 597 | writer.writeAttribute("type", "bullet");
|
---|
| 598 | else if (atom->string() == ATOM_LIST_TAG)
|
---|
| 599 | writer.writeAttribute("type", "definition");
|
---|
| 600 | else if (atom->string() == ATOM_LIST_VALUE)
|
---|
| 601 | writer.writeAttribute("type", "enum");
|
---|
| 602 | else {
|
---|
| 603 | writer.writeAttribute("type", "ordered");
|
---|
| 604 | if (atom->string() == ATOM_LIST_UPPERALPHA)
|
---|
| 605 | writer.writeAttribute("start", "A");
|
---|
| 606 | else if (atom->string() == ATOM_LIST_LOWERALPHA)
|
---|
| 607 | writer.writeAttribute("start", "a");
|
---|
| 608 | else if (atom->string() == ATOM_LIST_UPPERROMAN)
|
---|
| 609 | writer.writeAttribute("start", "I");
|
---|
| 610 | else if (atom->string() == ATOM_LIST_LOWERROMAN)
|
---|
| 611 | writer.writeAttribute("start", "i");
|
---|
| 612 | else // (atom->string() == ATOM_LIST_NUMERIC)
|
---|
| 613 | writer.writeAttribute("start", "1");
|
---|
| 614 | }
|
---|
| 615 | break;
|
---|
| 616 |
|
---|
| 617 | case Atom::ListItemNumber:
|
---|
| 618 | break;
|
---|
| 619 |
|
---|
| 620 | case Atom::ListTagLeft:
|
---|
| 621 | {
|
---|
| 622 | writer.writeStartElement("definition");
|
---|
| 623 |
|
---|
| 624 | writer.writeTextElement("term", plainCode(
|
---|
| 625 | marker->markedUpEnumValue(atom->next()->string(), relative)));
|
---|
| 626 | }
|
---|
| 627 | break;
|
---|
| 628 |
|
---|
| 629 | case Atom::ListTagRight:
|
---|
| 630 | writer.writeEndElement(); // definition
|
---|
| 631 | break;
|
---|
| 632 |
|
---|
| 633 | case Atom::ListItemLeft:
|
---|
| 634 | writer.writeStartElement("item");
|
---|
| 635 | break;
|
---|
| 636 |
|
---|
| 637 | case Atom::ListItemRight:
|
---|
| 638 | writer.writeEndElement(); // item
|
---|
| 639 | break;
|
---|
| 640 |
|
---|
| 641 | case Atom::ListRight:
|
---|
| 642 | writer.writeEndElement(); // list
|
---|
| 643 | break;
|
---|
| 644 |
|
---|
| 645 | case Atom::Nop:
|
---|
| 646 | break;
|
---|
| 647 |
|
---|
| 648 | case Atom::ParaLeft:
|
---|
| 649 | writer.writeStartElement("para");
|
---|
| 650 | break;
|
---|
| 651 |
|
---|
| 652 | case Atom::ParaRight:
|
---|
| 653 | writer.writeEndElement(); // para
|
---|
| 654 | break;
|
---|
| 655 |
|
---|
| 656 | case Atom::QuotationLeft:
|
---|
| 657 | writer.writeStartElement("quote");
|
---|
| 658 | break;
|
---|
| 659 |
|
---|
| 660 | case Atom::QuotationRight:
|
---|
| 661 | writer.writeEndElement(); // quote
|
---|
| 662 | break;
|
---|
| 663 |
|
---|
| 664 | case Atom::RawString:
|
---|
| 665 | writer.writeCharacters(atom->string());
|
---|
| 666 | break;
|
---|
| 667 |
|
---|
| 668 | case Atom::SectionLeft:
|
---|
| 669 | writer.writeStartElement("section");
|
---|
| 670 | writer.writeAttribute("id", Doc::canonicalTitle(Text::sectionHeading(atom).toString()));
|
---|
| 671 | break;
|
---|
| 672 |
|
---|
| 673 | case Atom::SectionRight:
|
---|
| 674 | writer.writeEndElement(); // section
|
---|
| 675 | break;
|
---|
| 676 |
|
---|
| 677 | case Atom::SectionHeadingLeft:
|
---|
| 678 | writer.writeStartElement("heading");
|
---|
| 679 | writer.writeAttribute("level", atom->string()); // + hOffset(relative)
|
---|
| 680 | inSectionHeading = true;
|
---|
| 681 | break;
|
---|
| 682 |
|
---|
| 683 | case Atom::SectionHeadingRight:
|
---|
| 684 | writer.writeEndElement(); // heading
|
---|
| 685 | inSectionHeading = false;
|
---|
| 686 | break;
|
---|
| 687 |
|
---|
| 688 | case Atom::SidebarLeft:
|
---|
| 689 | case Atom::SidebarRight:
|
---|
| 690 | break;
|
---|
| 691 |
|
---|
| 692 | case Atom::SnippetCommand:
|
---|
| 693 | writer.writeStartElement(atom->string());
|
---|
| 694 | break;
|
---|
| 695 |
|
---|
| 696 | case Atom::SnippetIdentifier:
|
---|
| 697 | writer.writeAttribute("identifier", atom->string());
|
---|
| 698 | writer.writeEndElement(); // snippet
|
---|
| 699 | break;
|
---|
| 700 |
|
---|
| 701 | case Atom::SnippetLocation:
|
---|
| 702 | writer.writeAttribute("location", atom->string());
|
---|
| 703 | break;
|
---|
| 704 |
|
---|
| 705 | case Atom::String:
|
---|
| 706 | writer.writeCharacters(atom->string());
|
---|
| 707 | break;
|
---|
| 708 |
|
---|
| 709 | case Atom::TableLeft:
|
---|
| 710 | writer.writeStartElement("table");
|
---|
| 711 | if (atom->string().contains("%"))
|
---|
| 712 | writer.writeAttribute("width", atom->string());
|
---|
| 713 | break;
|
---|
| 714 |
|
---|
| 715 | case Atom::TableRight:
|
---|
| 716 | writer.writeEndElement(); // table
|
---|
| 717 | break;
|
---|
| 718 |
|
---|
| 719 | case Atom::TableHeaderLeft:
|
---|
| 720 | writer.writeStartElement("header");
|
---|
| 721 | break;
|
---|
| 722 |
|
---|
| 723 | case Atom::TableHeaderRight:
|
---|
| 724 | writer.writeEndElement(); // header
|
---|
| 725 | break;
|
---|
| 726 |
|
---|
| 727 | case Atom::TableRowLeft:
|
---|
| 728 | writer.writeStartElement("row");
|
---|
| 729 | break;
|
---|
| 730 |
|
---|
| 731 | case Atom::TableRowRight:
|
---|
| 732 | writer.writeEndElement(); // row
|
---|
| 733 | break;
|
---|
| 734 |
|
---|
| 735 | case Atom::TableItemLeft:
|
---|
| 736 | {
|
---|
| 737 | writer.writeStartElement("item");
|
---|
| 738 | QStringList spans = atom->string().split(",");
|
---|
| 739 | if (spans.size() == 2) {
|
---|
| 740 | if (spans.at(0) != "1")
|
---|
| 741 | writer.writeAttribute("colspan", spans.at(0).trimmed());
|
---|
| 742 | if (spans.at(1) != "1")
|
---|
| 743 | writer.writeAttribute("rowspan", spans.at(1).trimmed());
|
---|
| 744 | }
|
---|
| 745 | }
|
---|
| 746 | break;
|
---|
| 747 |
|
---|
| 748 | case Atom::TableItemRight:
|
---|
| 749 | writer.writeEndElement(); // item
|
---|
| 750 | break;
|
---|
| 751 |
|
---|
| 752 | case Atom::TableOfContents:
|
---|
| 753 | writer.writeStartElement("tableofcontents");
|
---|
| 754 | writer.writeAttribute("details", atom->string());
|
---|
| 755 | {
|
---|
| 756 | int numColumns = 1;
|
---|
| 757 | const Node *node = relative;
|
---|
| 758 |
|
---|
| 759 | Doc::SectioningUnit sectioningUnit = Doc::Section4;
|
---|
| 760 | QStringList params = atom->string().split(",");
|
---|
| 761 | QString columnText = params.at(0);
|
---|
| 762 | QStringList pieces = columnText.split(" ", QString::SkipEmptyParts);
|
---|
| 763 | if (pieces.size() >= 2) {
|
---|
| 764 | columnText = pieces.at(0);
|
---|
| 765 | pieces.pop_front();
|
---|
| 766 | QString path = pieces.join(" ").trimmed();
|
---|
| 767 | node = findNode(path, relative, marker);
|
---|
| 768 | if (node)
|
---|
| 769 | writer.writeAttribute("href", fileName(node));
|
---|
| 770 | }
|
---|
| 771 |
|
---|
| 772 | if (params.size() == 2) {
|
---|
| 773 | numColumns = qMax(columnText.toInt(), numColumns);
|
---|
| 774 | sectioningUnit = (Doc::SectioningUnit)params.at(1).toInt();
|
---|
| 775 | writer.writeAttribute("columns", QString::number(numColumns));
|
---|
| 776 | writer.writeAttribute("unit", QString::number(sectioningUnit));
|
---|
| 777 | }
|
---|
| 778 |
|
---|
| 779 | if (node)
|
---|
| 780 | generateTableOfContents(writer, node, sectioningUnit, numColumns,
|
---|
| 781 | relative);
|
---|
| 782 | }
|
---|
| 783 | writer.writeEndElement(); // tableofcontents
|
---|
| 784 | break;
|
---|
| 785 |
|
---|
| 786 | case Atom::Target:
|
---|
| 787 | writer.writeStartElement("target");
|
---|
| 788 | writer.writeAttribute("name", Doc::canonicalTitle(atom->string()));
|
---|
| 789 | writer.writeEndElement(); // target
|
---|
| 790 | break;
|
---|
| 791 |
|
---|
| 792 | case Atom::UnhandledFormat:
|
---|
| 793 | case Atom::UnknownCommand:
|
---|
| 794 | writer.writeCharacters(atom->typeString());
|
---|
| 795 | break;
|
---|
| 796 | default:
|
---|
| 797 | break;
|
---|
| 798 | }
|
---|
| 799 |
|
---|
| 800 | if (atom)
|
---|
| 801 | return atom->next();
|
---|
| 802 |
|
---|
| 803 | return 0;
|
---|
| 804 | }
|
---|
| 805 | /*
|
---|
| 806 | QDomElement atomElement = document.createElement(atom->typeString().toLower());
|
---|
| 807 | QDomText atomValue = document.createTextNode(atom->string());
|
---|
| 808 | atomElement.appendChild(atomValue);
|
---|
| 809 | descriptionElement.appendChild(atomElement);
|
---|
| 810 | */
|
---|
| 811 |
|
---|
| 812 | /*
|
---|
| 813 | ### Warning: findNode() is a modified version of HtmlGenerator::getLink().
|
---|
| 814 | */
|
---|
| 815 | const Node *WebXMLGenerator::findNode(const Atom *atom, const Node *relative, CodeMarker *marker)
|
---|
| 816 | {
|
---|
| 817 | return findNode(atom->string(), relative, marker);
|
---|
| 818 | }
|
---|
| 819 |
|
---|
| 820 | const Node *WebXMLGenerator::findNode(const QString &title, const Node *relative, CodeMarker *marker)
|
---|
| 821 | {
|
---|
| 822 | QString link;
|
---|
| 823 | if (title.contains(":") &&
|
---|
| 824 | (title.startsWith("file:")
|
---|
| 825 | || title.startsWith("http:")
|
---|
| 826 | || title.startsWith("https:")
|
---|
| 827 | || title.startsWith("ftp:")
|
---|
| 828 | || title.startsWith("mailto:"))) {
|
---|
| 829 |
|
---|
| 830 | return 0;
|
---|
| 831 | } else if (title.count('@') == 1) {
|
---|
| 832 | return 0;
|
---|
| 833 | } else {
|
---|
| 834 | QStringList path;
|
---|
| 835 | if (title.contains('#')) {
|
---|
| 836 | path = title.split('#');
|
---|
| 837 | } else {
|
---|
| 838 | path.append(title);
|
---|
| 839 | }
|
---|
| 840 |
|
---|
| 841 | const Node *node = 0;
|
---|
| 842 | Atom *targetAtom = 0;
|
---|
| 843 |
|
---|
| 844 | QString first = path.first().trimmed();
|
---|
| 845 | if (first.isEmpty()) {
|
---|
| 846 | node = relative;
|
---|
| 847 | } else if (first.endsWith(".html")) {
|
---|
| 848 | node = tre->root()->findNode(first, Node::Fake);
|
---|
| 849 | } else {
|
---|
| 850 | node = marker->resolveTarget(first, tre, relative);
|
---|
| 851 | if (!node)
|
---|
| 852 | node = tre->findFakeNodeByTitle(first);
|
---|
| 853 | if (!node)
|
---|
| 854 | node = tre->findUnambiguousTarget(first, targetAtom);
|
---|
| 855 | }
|
---|
| 856 |
|
---|
| 857 | if (node) {
|
---|
| 858 | if (!node->url().isEmpty())
|
---|
| 859 | return node;
|
---|
| 860 | else
|
---|
| 861 | path.removeFirst();
|
---|
| 862 | } else {
|
---|
| 863 | return 0;
|
---|
| 864 | }
|
---|
| 865 |
|
---|
| 866 | while (!path.isEmpty()) {
|
---|
| 867 | targetAtom = tre->findTarget(path.first(), node);
|
---|
| 868 | if (targetAtom == 0)
|
---|
| 869 | break;
|
---|
| 870 | path.removeFirst();
|
---|
| 871 | }
|
---|
| 872 | /* We would ideally treat targets as nodes to be consistent.
|
---|
| 873 | if (targetAtom && node && node->isInnerNode()) {
|
---|
| 874 | Node *parentNode = const_cast<Node *>(node);
|
---|
| 875 | node = new TargetNode(static_cast<InnerNode*>(parentNode), first);
|
---|
| 876 | }
|
---|
| 877 | */
|
---|
| 878 | return node;
|
---|
| 879 | }
|
---|
| 880 | return 0;
|
---|
| 881 | }
|
---|
| 882 |
|
---|
| 883 | void WebXMLGenerator::startLink(QXmlStreamWriter &writer, const Atom *atom,
|
---|
| 884 | const Node *node, const Node *relative)
|
---|
| 885 | {
|
---|
| 886 | QString location = tre->fullDocumentLocation(node);
|
---|
| 887 | if (!location.isEmpty()) {
|
---|
| 888 | writer.writeStartElement("link");
|
---|
| 889 | writer.writeAttribute("raw", atom->string());
|
---|
| 890 | if (atom->string().contains("#") || node == relative) {
|
---|
| 891 | QString target = atom->string().split("#").last();
|
---|
| 892 | Atom *targetAtom = tre->findTarget(target, node);
|
---|
| 893 | if (targetAtom)
|
---|
| 894 | location += "#" + Doc::canonicalTitle(target);
|
---|
| 895 | }
|
---|
| 896 | writer.writeAttribute("href", location);
|
---|
| 897 | QString type = targetType(node);
|
---|
| 898 | writer.writeAttribute("type", type);
|
---|
| 899 | switch (node->type()) {
|
---|
| 900 | case Node::Enum:
|
---|
| 901 | writer.writeAttribute("enum", tre->fullDocumentName(node));
|
---|
| 902 | break;
|
---|
| 903 | case Node::Fake:
|
---|
| 904 | writer.writeAttribute("page", tre->fullDocumentName(node));
|
---|
| 905 | break;
|
---|
| 906 | case Node::Property:
|
---|
| 907 | {
|
---|
| 908 | const PropertyNode *propertyNode = static_cast<const PropertyNode *>(node);
|
---|
| 909 | if (propertyNode->getters().size() > 0)
|
---|
| 910 | writer.writeAttribute("getter", tre->fullDocumentName(propertyNode->getters()[0]));
|
---|
| 911 | }
|
---|
| 912 | default:
|
---|
| 913 | ;
|
---|
| 914 | }
|
---|
| 915 | inLink = true;
|
---|
| 916 | }
|
---|
| 917 | }
|
---|
| 918 |
|
---|
| 919 | QString WebXMLGenerator::targetType(const Node *node)
|
---|
| 920 | {
|
---|
| 921 | switch (node->type()) {
|
---|
| 922 | case Node::Namespace:
|
---|
| 923 | return "namespace";
|
---|
| 924 | break;
|
---|
| 925 | case Node::Class:
|
---|
| 926 | return "class";
|
---|
| 927 | break;
|
---|
| 928 | case Node::Fake:
|
---|
| 929 | return "page";
|
---|
| 930 | break;
|
---|
| 931 | case Node::Enum:
|
---|
| 932 | return "enum";
|
---|
| 933 | break;
|
---|
| 934 | case Node::Typedef:
|
---|
| 935 | return "typedef";
|
---|
| 936 | break;
|
---|
| 937 | case Node::Property:
|
---|
| 938 | return "property";
|
---|
| 939 | break;
|
---|
| 940 | case Node::Function:
|
---|
| 941 | return "function";
|
---|
| 942 | break;
|
---|
| 943 | case Node::Variable:
|
---|
| 944 | return "variable";
|
---|
| 945 | break;
|
---|
| 946 | case Node::Target:
|
---|
| 947 | return "target";
|
---|
| 948 | break;
|
---|
| 949 | default:
|
---|
| 950 | return "";
|
---|
| 951 | }
|
---|
| 952 | return "";
|
---|
| 953 | }
|
---|
| 954 |
|
---|
| 955 | void WebXMLGenerator::generateRelations(QXmlStreamWriter &writer, const Node *node, CodeMarker *marker)
|
---|
| 956 | {
|
---|
| 957 | if (node && !node->links().empty()) {
|
---|
| 958 | QPair<QString,QString> linkPair;
|
---|
| 959 | QPair<QString,QString> anchorPair;
|
---|
| 960 | const Node *linkNode;
|
---|
| 961 |
|
---|
| 962 | foreach (Node::LinkType relation, node->links().keys()) {
|
---|
| 963 |
|
---|
| 964 | linkPair = node->links()[relation];
|
---|
| 965 | linkNode = findNode(linkPair.first, node, marker);
|
---|
| 966 |
|
---|
| 967 | if (!linkNode)
|
---|
| 968 | linkNode = node;
|
---|
| 969 |
|
---|
| 970 | if (linkNode == node)
|
---|
| 971 | anchorPair = linkPair;
|
---|
| 972 | else
|
---|
| 973 | anchorPair = anchorForNode(linkNode);
|
---|
| 974 |
|
---|
| 975 | writer.writeStartElement("relation");
|
---|
| 976 | writer.writeAttribute("href", anchorPair.first);
|
---|
| 977 | writer.writeAttribute("type", targetType(linkNode));
|
---|
| 978 |
|
---|
| 979 | switch (relation) {
|
---|
| 980 | case Node::StartLink:
|
---|
| 981 | writer.writeAttribute("meta", "start");
|
---|
| 982 | break;
|
---|
| 983 | case Node::NextLink:
|
---|
| 984 | writer.writeAttribute("meta", "next");
|
---|
| 985 | break;
|
---|
| 986 | case Node::PreviousLink:
|
---|
| 987 | writer.writeAttribute("meta", "previous");
|
---|
| 988 | break;
|
---|
| 989 | case Node::ContentsLink:
|
---|
| 990 | writer.writeAttribute("meta", "contents");
|
---|
| 991 | break;
|
---|
| 992 | case Node::IndexLink:
|
---|
| 993 | writer.writeAttribute("meta", "index");
|
---|
| 994 | break;
|
---|
| 995 | default:
|
---|
| 996 | writer.writeAttribute("meta", "");
|
---|
| 997 | }
|
---|
| 998 | writer.writeAttribute("description", anchorPair.second);
|
---|
| 999 | writer.writeEndElement(); // link
|
---|
| 1000 | }
|
---|
| 1001 | }
|
---|
| 1002 | }
|
---|
| 1003 |
|
---|
| 1004 | // Classes adapted from HtmlGenerator.
|
---|
| 1005 |
|
---|
| 1006 | void WebXMLGenerator::generateTableOfContents(QXmlStreamWriter &writer, const Node *node,
|
---|
| 1007 | Doc::SectioningUnit sectioningUnit,
|
---|
| 1008 | int numColumns, const Node *relative)
|
---|
| 1009 |
|
---|
| 1010 | {
|
---|
| 1011 | if (!node->doc().hasTableOfContents())
|
---|
| 1012 | return;
|
---|
| 1013 | QList<Atom *> toc = node->doc().tableOfContents();
|
---|
| 1014 | if (toc.isEmpty())
|
---|
| 1015 | return;
|
---|
| 1016 |
|
---|
| 1017 | QString nodeName = "";
|
---|
| 1018 | if (node != relative)
|
---|
| 1019 | nodeName = node->name();
|
---|
| 1020 |
|
---|
| 1021 | QStringList sectionNumber;
|
---|
| 1022 | int columnSize = 0;
|
---|
| 1023 |
|
---|
| 1024 | if (numColumns > 1) {
|
---|
| 1025 | writer.writeStartElement("table");
|
---|
| 1026 | writer.writeAttribute("width", "100%");
|
---|
| 1027 | writer.writeStartElement("row");
|
---|
| 1028 | writer.writeStartElement("item");
|
---|
| 1029 | writer.writeAttribute("width", QString::number((100 + numColumns - 1) / numColumns) + "%");
|
---|
| 1030 | }
|
---|
| 1031 |
|
---|
| 1032 | // disable nested links in table of contents
|
---|
| 1033 | inContents = true;
|
---|
| 1034 | inLink = true;
|
---|
| 1035 |
|
---|
| 1036 | for (int i = 0; i < toc.size(); ++i) {
|
---|
| 1037 | Atom *atom = toc.at(i);
|
---|
| 1038 |
|
---|
| 1039 | int nextLevel = atom->string().toInt();
|
---|
| 1040 | if (nextLevel > (int)sectioningUnit)
|
---|
| 1041 | continue;
|
---|
| 1042 |
|
---|
| 1043 | if (sectionNumber.size() < nextLevel) {
|
---|
| 1044 | do {
|
---|
| 1045 | writer.writeStartElement("list");
|
---|
| 1046 | sectionNumber.append("1");
|
---|
| 1047 | } while (sectionNumber.size() < nextLevel);
|
---|
| 1048 | } else {
|
---|
| 1049 | while (sectionNumber.size() > nextLevel) {
|
---|
| 1050 | writer.writeEndElement();
|
---|
| 1051 | sectionNumber.removeLast();
|
---|
| 1052 | }
|
---|
| 1053 | sectionNumber.last() = QString::number(sectionNumber.last().toInt() + 1);
|
---|
| 1054 | }
|
---|
| 1055 | Text headingText = Text::sectionHeading(atom);
|
---|
| 1056 |
|
---|
| 1057 | if (sectionNumber.size() == 1 && columnSize > toc.size() / numColumns) {
|
---|
| 1058 | writer.writeEndElement(); // list
|
---|
| 1059 | writer.writeEndElement(); // item
|
---|
| 1060 | writer.writeStartElement("item");
|
---|
| 1061 | writer.writeAttribute("width", QString::number((100 + numColumns - 1) / numColumns) + "%");
|
---|
| 1062 | writer.writeStartElement("list");
|
---|
| 1063 | columnSize = 0;
|
---|
| 1064 | }
|
---|
| 1065 |
|
---|
| 1066 | writer.writeStartElement("item");
|
---|
| 1067 | writer.writeStartElement("para");
|
---|
| 1068 | writer.writeStartElement("link");
|
---|
| 1069 | writer.writeAttribute("href", nodeName + "#" + Doc::canonicalTitle(headingText.toString()));
|
---|
| 1070 | writer.writeAttribute("type", "page");
|
---|
| 1071 | writer.writeCharacters(headingText.toString());
|
---|
| 1072 | writer.writeEndElement(); // link
|
---|
| 1073 | writer.writeEndElement(); // para
|
---|
| 1074 | writer.writeEndElement(); // item
|
---|
| 1075 |
|
---|
| 1076 | ++columnSize;
|
---|
| 1077 | }
|
---|
| 1078 | while (!sectionNumber.isEmpty()) {
|
---|
| 1079 | writer.writeEndElement(); // list
|
---|
| 1080 | sectionNumber.removeLast();
|
---|
| 1081 | }
|
---|
| 1082 |
|
---|
| 1083 | if (numColumns > 1) {
|
---|
| 1084 | writer.writeEndElement(); // item
|
---|
| 1085 | writer.writeEndElement(); // row
|
---|
| 1086 | writer.writeEndElement(); // table
|
---|
| 1087 | }
|
---|
| 1088 |
|
---|
| 1089 | inContents = false;
|
---|
| 1090 | inLink = false;
|
---|
| 1091 | }
|
---|
| 1092 |
|
---|
| 1093 | void WebXMLGenerator::generateAnnotatedList(QXmlStreamWriter &writer,
|
---|
| 1094 | const Node *relative, CodeMarker *marker, const QMap<QString, const Node *> &nodeMap)
|
---|
| 1095 | {
|
---|
| 1096 | writer.writeStartElement("table");
|
---|
| 1097 | writer.writeAttribute("width", "100%");
|
---|
| 1098 |
|
---|
| 1099 | foreach (QString name, nodeMap.keys()) {
|
---|
| 1100 | const Node *node = nodeMap[name];
|
---|
| 1101 |
|
---|
| 1102 | writer.writeStartElement("row");
|
---|
| 1103 | writer.writeStartElement("heading");
|
---|
| 1104 | generateFullName(writer, node, relative, marker);
|
---|
| 1105 | writer.writeEndElement(); // heading
|
---|
| 1106 |
|
---|
| 1107 | writer.writeStartElement("item");
|
---|
| 1108 | writer.writeCharacters(node->doc().briefText().toString());
|
---|
| 1109 | writer.writeEndElement(); // item
|
---|
| 1110 | writer.writeEndElement(); // row
|
---|
| 1111 | }
|
---|
| 1112 | writer.writeEndElement(); // table
|
---|
| 1113 | }
|
---|
| 1114 |
|
---|
| 1115 | void WebXMLGenerator::generateFullName(QXmlStreamWriter &writer,
|
---|
| 1116 | const Node *apparentNode, const Node *relative, CodeMarker *marker,
|
---|
| 1117 | const Node *actualNode)
|
---|
| 1118 | {
|
---|
| 1119 | if ( actualNode == 0 )
|
---|
| 1120 | actualNode = apparentNode;
|
---|
| 1121 | writer.writeStartElement("link");
|
---|
| 1122 | writer.writeAttribute("href", tre->fullDocumentLocation(actualNode));
|
---|
| 1123 | writer.writeAttribute("type", targetType(actualNode));
|
---|
| 1124 | writer.writeCharacters(fullName(apparentNode, relative, marker));
|
---|
| 1125 | writer.writeEndElement(); // link
|
---|
| 1126 | }
|
---|
| 1127 |
|
---|
| 1128 | // Classes copied (and slightly adapted) from the HtmlGenerator. These need
|
---|
| 1129 | // refactoring into a common ancestor class.
|
---|
| 1130 |
|
---|
| 1131 | void WebXMLGenerator::findAllClasses(const InnerNode *node)
|
---|
| 1132 | {
|
---|
| 1133 | NodeList::const_iterator c = node->childNodes().constBegin();
|
---|
| 1134 | while (c != node->childNodes().constEnd()) {
|
---|
| 1135 | if ((*c)->access() != Node::Private && (*c)->url().isEmpty()) {
|
---|
| 1136 | if ((*c)->type() == Node::Class && !(*c)->doc().isEmpty()) {
|
---|
| 1137 | QString className = (*c)->name();
|
---|
| 1138 | if ((*c)->parent() && (*c)->parent()->type() == Node::Namespace &&
|
---|
| 1139 | !(*c)->parent()->name().isEmpty())
|
---|
| 1140 | className = (*c)->parent()->name()+"::"+className;
|
---|
| 1141 |
|
---|
| 1142 | QString moduleName = (*c)->moduleName();
|
---|
| 1143 | if (!moduleName.isEmpty())
|
---|
| 1144 | moduleClassMap[moduleName].insert((*c)->name(), *c);
|
---|
| 1145 |
|
---|
| 1146 | QString serviceName =
|
---|
| 1147 | (static_cast<const ClassNode *>(*c))->serviceName();
|
---|
| 1148 | if (!serviceName.isEmpty())
|
---|
| 1149 | serviceClasses.insert(serviceName, *c);
|
---|
| 1150 | } else if ((*c)->isInnerNode()) {
|
---|
| 1151 | findAllClasses(static_cast<InnerNode *>(*c));
|
---|
| 1152 | }
|
---|
| 1153 | }
|
---|
| 1154 | ++c;
|
---|
| 1155 | }
|
---|
| 1156 | }
|
---|
| 1157 |
|
---|
| 1158 | void WebXMLGenerator::findAllNamespaces(const InnerNode *node)
|
---|
| 1159 | {
|
---|
| 1160 | NodeList::ConstIterator c = node->childNodes().begin();
|
---|
| 1161 | while (c != node->childNodes().end()) {
|
---|
| 1162 | if ((*c)->access() != Node::Private) {
|
---|
| 1163 | if ((*c)->isInnerNode() && (*c)->url().isEmpty()) {
|
---|
| 1164 | findAllNamespaces(static_cast<const InnerNode *>(*c));
|
---|
| 1165 | if ((*c)->type() == Node::Namespace) {
|
---|
| 1166 | const NamespaceNode *nspace = static_cast<const NamespaceNode *>(*c);
|
---|
| 1167 | // Ensure that the namespace's name is not empty (the root
|
---|
| 1168 | // namespace has no name).
|
---|
| 1169 | if (!nspace->name().isEmpty()) {
|
---|
| 1170 | namespaceIndex.insert(nspace->name(), *c);
|
---|
| 1171 | QString moduleName = (*c)->moduleName();
|
---|
| 1172 | if (!moduleName.isEmpty())
|
---|
| 1173 | moduleNamespaceMap[moduleName].insert((*c)->name(), *c);
|
---|
| 1174 | }
|
---|
| 1175 | }
|
---|
| 1176 | }
|
---|
| 1177 | }
|
---|
| 1178 | ++c;
|
---|
| 1179 | }
|
---|
| 1180 | }
|
---|
| 1181 |
|
---|
| 1182 | const QPair<QString,QString> WebXMLGenerator::anchorForNode(const Node *node)
|
---|
| 1183 | {
|
---|
| 1184 | QPair<QString,QString> anchorPair;
|
---|
| 1185 |
|
---|
| 1186 | anchorPair.first = PageGenerator::fileName(node);
|
---|
| 1187 | if (node->type() == Node::Fake) {
|
---|
| 1188 | const FakeNode *fakeNode = static_cast<const FakeNode*>(node);
|
---|
| 1189 | anchorPair.second = fakeNode->title();
|
---|
| 1190 | }
|
---|
| 1191 |
|
---|
| 1192 | return anchorPair;
|
---|
| 1193 | }
|
---|
| 1194 |
|
---|
| 1195 | QT_END_NAMESPACE
|
---|