| /**************************************************************************** |
| ** |
| ** Copyright (C) 2016 The Qt Company Ltd. |
| ** Contact: https://www.qt.io/licensing/ |
| ** |
| ** This file is part of the tools applications of the Qt Toolkit. |
| ** |
| ** $QT_BEGIN_LICENSE:GPL-EXCEPT$ |
| ** Commercial License Usage |
| ** Licensees holding valid commercial Qt licenses may use this file in |
| ** accordance with the commercial license agreement provided with the |
| ** Software or, alternatively, in accordance with the terms contained in |
| ** a written agreement between you and The Qt Company. For licensing terms |
| ** and conditions see https://www.qt.io/terms-conditions. For further |
| ** information use the contact form at https://www.qt.io/contact-us. |
| ** |
| ** GNU General Public License Usage |
| ** Alternatively, this file may be used under the terms of the GNU |
| ** General Public License version 3 as published by the Free Software |
| ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT |
| ** included in the packaging of this file. Please review the following |
| ** information to ensure the GNU General Public License requirements will |
| ** be met: https://www.gnu.org/licenses/gpl-3.0.html. |
| ** |
| ** $QT_END_LICENSE$ |
| ** |
| ****************************************************************************/ |
| |
| #include "qdocgenerator.h" |
| |
| #include <QtCore/qdir.h> |
| |
| #include <iostream> |
| |
| namespace QDocGenerator { |
| |
| // See definition of idstring and licenseid in https://spdx.org/spdx-specification-21-web-version |
| static bool isSpdxLicenseId(const QString &str) { |
| if (str.isEmpty()) |
| return false; |
| for (auto iter(str.cbegin()); iter != str.cend(); ++iter) { |
| const QChar c = *iter; |
| if (!((c >= QLatin1Char('A') && c <= QLatin1Char('Z')) |
| || (c >= QLatin1Char('a') && c <= QLatin1Char('z')) |
| || (c >= QLatin1Char('0') && c <= QLatin1Char('9')) |
| || (c == QLatin1Char('-')) || (c == QLatin1Char('.')))) |
| return false; |
| } |
| return true; |
| } |
| |
| static QString languageJoin(const QStringList &list) |
| { |
| QString result; |
| for (int i = 0; i < list.size(); ++i) { |
| QString delimiter = QStringLiteral(", "); |
| if (i == list.size() - 1) // last item |
| delimiter.clear(); |
| else if (list.size() == 2) |
| delimiter = QStringLiteral(" and "); |
| else if (list.size() > 2 && i == list.size() - 2) |
| delimiter = QStringLiteral(", and "); // oxford comma |
| result += list[i] + delimiter; |
| } |
| |
| return result; |
| } |
| |
| static void generate(QTextStream &out, const Package &package, const QDir &baseDir, |
| LogLevel logLevel) |
| { |
| out << "/*!\n\n"; |
| for (const QString &part: package.qtParts) |
| out << "\\ingroup attributions-" << part << "\n"; |
| |
| if (package.qtParts.contains(QLatin1String("libs"))) { |
| // show up in xxx-index.html page of module |
| out << "\\ingroup attributions-" << package.qdocModule << "\n"; |
| // include in '\generatelist annotatedattributions' |
| out << "\\page " << package.qdocModule << "-attribution-" << package.id |
| << ".html attribution\n"; |
| } else { |
| out << "\\page " << package.qdocModule << "-attribution-" << package.id |
| << ".html \n"; |
| } |
| |
| out << "\\target " << package.id << "\n\n"; |
| out << "\\title " << package.name; |
| if (!package.version.isEmpty()) |
| out << ", version " << package.version; |
| out << "\n\n\\brief " << package.license << "\n\n"; |
| |
| if (!package.description.isEmpty()) |
| out << package.description << "\n\n"; |
| |
| if (!package.qtUsage.isEmpty()) |
| out << package.qtUsage << "\n\n"; |
| |
| QStringList sourcePaths; |
| if (package.files.isEmpty()) { |
| sourcePaths << baseDir.relativeFilePath(package.path); |
| } else { |
| const QDir packageDir(package.path); |
| for (const QString &filePath: package.files) { |
| const QString absolutePath = packageDir.absoluteFilePath(filePath); |
| sourcePaths << baseDir.relativeFilePath(absolutePath); |
| } |
| } |
| |
| out << "The sources can be found in " << languageJoin(sourcePaths) << ".\n\n"; |
| |
| const bool hasPackageVersion = !package.version.isEmpty(); |
| const bool hasPackageDownloadLocation = !package.downloadLocation.isEmpty(); |
| if (!package.homepage.isEmpty()) { |
| out << "\\l{" << package.homepage << "}{Project Homepage}"; |
| if (hasPackageVersion) |
| out << ", "; |
| } |
| if (hasPackageVersion) { |
| out << "upstream version: "; |
| if (hasPackageDownloadLocation) |
| out << "\\l{" << package.downloadLocation << "}{"; |
| out << package.version; |
| if (hasPackageDownloadLocation) |
| out << "}"; |
| } |
| |
| out << "\n\n"; |
| |
| if (!package.copyright.isEmpty()) |
| out << "\n\\badcode\n" << package.copyright << "\n\\endcode\n\n"; |
| |
| if (isSpdxLicenseId(package.licenseId) && package.licenseId != QLatin1String("NONE")) |
| out << "\\l{https://spdx.org/licenses/" << package.licenseId << ".html}" |
| << "{" << package.license << "}.\n\n"; |
| else |
| out << package.license << ".\n\n"; |
| |
| if (!package.licenseFile.isEmpty()) { |
| QFile file(package.licenseFile); |
| if (!file.open(QIODevice::ReadOnly)) { |
| if (logLevel != SilentLog) |
| std::cerr << qPrintable( |
| tr("Path %1 : cannot open license file %2.") |
| .arg(QDir::toNativeSeparators(package.path)) |
| .arg(QDir::toNativeSeparators(package.licenseFile)) |
| ) << "*/\n"; |
| return; |
| } |
| out << "\\badcode\n"; |
| out << QString::fromUtf8(file.readAll()).trimmed(); |
| out << "\n\\endcode\n"; |
| } |
| out << "*/\n"; |
| } |
| |
| void generate(QTextStream &out, const QVector<Package> &packages, const QString &baseDirectory, |
| LogLevel logLevel) |
| { |
| if (logLevel == VerboseLog) |
| std::cerr << qPrintable(tr("Generating qdoc file...")) << std::endl; |
| |
| QDir baseDir(baseDirectory); |
| for (const Package &package : packages) |
| generate(out, package, baseDir, logLevel); |
| } |
| |
| } // namespace QDocGenerator |