tools/qdoc3/linguistgenerator.cpp
changeset 0 1918ee327afb
child 4 3b1da2848fc7
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the tools applications of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    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 **
       
    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.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 /*
       
    43   linguistgenerator.cpp
       
    44 */
       
    45 
       
    46 #include "codemarker.h"
       
    47 #include "pagegenerator.h"
       
    48 #include "linguistgenerator.h"
       
    49 #include "node.h"
       
    50 #include "separator.h"
       
    51 #include "tree.h"
       
    52 #include <ctype.h>
       
    53 
       
    54 #include <qlist.h>
       
    55 #include <qiterator.h>
       
    56 
       
    57 QT_BEGIN_NAMESPACE
       
    58 
       
    59 #define COMMAND_VERSION                 Doc::alias("version")
       
    60 
       
    61 LinguistGenerator::LinguistGenerator()
       
    62     : PageGenerator()
       
    63 {
       
    64 }
       
    65 
       
    66 LinguistGenerator::~LinguistGenerator()
       
    67 {
       
    68 }
       
    69 
       
    70 void LinguistGenerator::initializeGenerator(const Config &config)
       
    71 {
       
    72     Generator::initializeGenerator(config);
       
    73 }
       
    74 
       
    75 void LinguistGenerator::terminateGenerator()
       
    76 {
       
    77     PageGenerator::terminateGenerator();
       
    78 }
       
    79 
       
    80 QString LinguistGenerator::format()
       
    81 {
       
    82     return "Linguist";
       
    83 }
       
    84 
       
    85 QString LinguistGenerator::fileExtension(const Node * /* node */)
       
    86 {
       
    87     return "ts";
       
    88 }
       
    89 
       
    90 void LinguistGenerator::generateClassLikeNode(const InnerNode *inner, CodeMarker *marker)
       
    91 {
       
    92     out().setCodec("utf-8");
       
    93 
       
    94     QDomDocument document("TS");
       
    95     QDomElement documentElement = document.createElement("TS");
       
    96     documentElement.setAttribute("version", "1.1");
       
    97 
       
    98     QList<QDomElement> contextElements = generateIndexSections(document, inner, marker);
       
    99     foreach (const QDomElement &element, contextElements)
       
   100         documentElement.appendChild(element);
       
   101 
       
   102     QDomProcessingInstruction process = document.createProcessingInstruction(
       
   103         "xml", QString("version=\"1.0\" encoding=\"%1\"").arg("utf-8"));
       
   104     document.appendChild(process);
       
   105     document.appendChild(documentElement);
       
   106 
       
   107     out() << document;
       
   108     out().flush();
       
   109 }
       
   110 
       
   111 void LinguistGenerator::generateFakeNode( const FakeNode *fake, CodeMarker *marker )
       
   112 {
       
   113     out().setCodec("utf-8");
       
   114 
       
   115     QDomDocument document("TS");
       
   116     QDomElement documentElement = document.createElement("TS");
       
   117     documentElement.setAttribute("version", "1.1");
       
   118 
       
   119     QList<QDomElement> contextElements = generateIndexSections(document, fake, marker);
       
   120     foreach (const QDomElement &element, contextElements)
       
   121         documentElement.appendChild(element);
       
   122 
       
   123     QDomProcessingInstruction process = document.createProcessingInstruction(
       
   124         "xml", QString("version=\"1.0\" encoding=\"%1\"").arg("utf-8"));
       
   125     document.appendChild(process);
       
   126     document.appendChild(documentElement);
       
   127 
       
   128     out() << document;
       
   129     out().flush();
       
   130 }
       
   131 
       
   132 QList<QDomElement> LinguistGenerator::generateIndexSections(
       
   133                    QDomDocument &document, const Node *node, CodeMarker *marker)
       
   134 {
       
   135     QList<QDomElement> contexts;
       
   136 
       
   137     if (node->isInnerNode()) {
       
   138         const InnerNode *inner = static_cast<const InnerNode *>(node);
       
   139 
       
   140         foreach (const Node *child, inner->childNodes()) {
       
   141             // Recurse to generate a DOM element for this child node and all
       
   142             // its children.
       
   143             contexts += generateIndexSections(document, child, marker);
       
   144         }
       
   145 /*
       
   146         foreach (const Node *child, inner->relatedNodes()) {
       
   147             QDomElement childElement = generateIndexSections(document, child, marker);
       
   148             element.appendChild(childElement);
       
   149         }
       
   150 */
       
   151     }
       
   152 
       
   153     // Add documentation to this node if it exists.
       
   154     if (!node->doc().isEmpty()) {
       
   155 
       
   156         QString nodeName = fullName(node);
       
   157         QString signature;
       
   158 
       
   159         if (node->type() == Node::Function) {
       
   160             QStringList pieces;
       
   161             const FunctionNode *functionNode = static_cast<const FunctionNode*>(node);
       
   162             foreach (const Parameter &parameter, functionNode->parameters()) {
       
   163                 QString typeString = parameter.leftType() + parameter.rightType();
       
   164                 if (typeString.split(" ").size() > 1)
       
   165                     pieces.append(typeString + parameter.name());
       
   166                 else
       
   167                     pieces.append(typeString + " " + parameter.name());
       
   168             }
       
   169             signature = "(" + pieces.join(", ") + ")";
       
   170         }
       
   171 
       
   172         QDomElement contextElement = document.createElement("context");
       
   173         QDomElement nameElement = document.createElement("name");
       
   174         nameElement.appendChild(document.createTextNode(nodeName + signature));
       
   175         contextElement.appendChild(nameElement);
       
   176 
       
   177         QDomElement messageElement = document.createElement("message");
       
   178         contextElement.appendChild(messageElement);
       
   179 
       
   180         QDomElement sourceElement = document.createElement("source");
       
   181         QString sourceText = simplified(node->doc().source());
       
   182         if (!signature.isEmpty() && signature != "()" && !sourceText.contains("\\fn"))
       
   183             sourceText.prepend(QString("\\fn %1%2\n").arg(nodeName).arg(signature));
       
   184         sourceElement.appendChild(document.createTextNode(sourceText));
       
   185         messageElement.appendChild(sourceElement);
       
   186 
       
   187         QDomElement translationElement = document.createElement("translation");
       
   188         translationElement.setAttribute("type", "unfinished");
       
   189         messageElement.appendChild(translationElement);
       
   190 
       
   191         QDomElement locationElement = document.createElement("location");
       
   192         locationElement.setAttribute("filename", node->doc().location().filePath());
       
   193         locationElement.setAttribute("line", node->doc().location().lineNo());
       
   194         messageElement.appendChild(locationElement);
       
   195 
       
   196         contexts.append(contextElement);
       
   197     }
       
   198 
       
   199     return contexts;
       
   200 }
       
   201 
       
   202 QString LinguistGenerator::fullName(const Node *node) const
       
   203 {
       
   204     if (!node)
       
   205         return "";
       
   206     else if (node->parent() && !node->parent()->name().isEmpty())
       
   207         return fullName(node->parent()) + "::" + node->name();
       
   208     else
       
   209         return node->name();
       
   210 }
       
   211 
       
   212 QString LinguistGenerator::simplified(const QString &text) const
       
   213 {
       
   214     QStringList lines = text.split("\n");
       
   215 
       
   216     while (lines.size() > 0 && lines.first().trimmed().isEmpty())
       
   217         lines.pop_front();
       
   218 
       
   219     while (lines.size() > 0 && lines.last().trimmed().isEmpty())
       
   220         lines.pop_back();
       
   221 
       
   222     int min = 0;
       
   223     bool set = false;
       
   224     foreach (const QString &line, lines) {
       
   225         int j = 0;
       
   226         while (j < line.length()) {
       
   227             if (line[j] != ' ')
       
   228                 break;
       
   229             ++j;
       
   230         }
       
   231         if (j < line.length()) {
       
   232             if (!set) {
       
   233                 min = j;
       
   234                 set = true;
       
   235             } else
       
   236                 min = qMin(min, j);
       
   237         }
       
   238     }
       
   239     for (int i = 0; i < lines.size(); ++i)
       
   240         lines[i] = lines[i].mid(min);
       
   241 
       
   242     return lines.join("\n");
       
   243 }
       
   244 
       
   245 QT_END_NAMESPACE