summaryrefslogtreecommitdiffstats
path: root/doxygen2qthelp.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'doxygen2qthelp.cpp')
-rw-r--r--doxygen2qthelp.cpp407
1 files changed, 407 insertions, 0 deletions
diff --git a/doxygen2qthelp.cpp b/doxygen2qthelp.cpp
new file mode 100644
index 0000000..ae5a5be
--- /dev/null
+++ b/doxygen2qthelp.cpp
@@ -0,0 +1,407 @@
+/****************************************************************************
+ **
+ ** Copyright (C) 2008-2010 Nokia Corporation and/or its subsidiary(-ies).
+ ** Contact: Nokia Corporation (qt-info@nokia.com)
+ **
+ ** This file is part of the doxygen2qthelp project on Trolltech Labs.
+ **
+ ** This file may be used under the terms of the GNU General Public
+ ** License version 2.0 or 3.0 as published by the Free Software Foundation
+ ** and appearing in the file LICENSE.GPL included in the packaging of
+ ** this file. Please review the following information to ensure GNU
+ ** General Public Licensing requirements will be met:
+ ** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
+ ** http://www.gnu.org/copyleft/gpl.html.
+ **
+ ** If you are unsure which license is appropriate for your use, please
+ ** contact the sales department at qt-sales@nokia.com.
+ **
+ ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+ ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ **
+ ****************************************************************************/
+
+#include "config.h"
+#include "htmlhelpdatainterface_p.h"
+#include "qhelpgenerator_p.h"
+#include "qthelpprojectwriter_p.h"
+
+#include <QtCore/QtGlobal>
+#include <QtCore/QCoreApplication>
+#include <QtCore/QString>
+#include <QtCore/QFile>
+#include <QtCore/QSettings>
+#include <QtCore/QUrl>
+#include <QtCore/QVariant>
+
+#if (QT_VERSION <= 0x040400)
+# error Please compile doxygen2qthelp against a Qt release _after_ 4.4.0, e.g. a recent snapshot
+#endif
+
+QT_BEGIN_NAMESPACE
+
+const char* const FILE_MISSING_FORMAT = "Error: File '%s' does not exist.\n";
+
+enum Action
+{
+ ACTION_USAGE,
+ ACTION_RUN,
+ ACTION_QUIT,
+ ACTION_VERSION
+};
+
+QString virtualFolder;
+QString nameSpace;
+QString outputFileName;
+QString inputFileName;
+bool verbose = false;
+bool forceOverwrite = false;
+bool helpProjectMode = false;
+bool error = false;
+
+void printUsage()
+{
+ printf(
+ "Usage: doxygen2qthelp OPTIONS <infile> [<outfile>]\n"
+ " doxygen2qthelp --config=<file>\n"
+ "\n"
+ "Parameters Description\n"
+ " <infile> Read input from <infile>\n"
+ " (InputFile=<infile>)\n"
+ "\n"
+ " <outfile> Write output to <outfile>\n"
+ " (OutputFile=<outfile>)\n"
+ "\n"
+ " --config=<file> Read config from <file>\n"
+ "\n"
+ " --folder=<str> Set virtual folder [required]\n"
+ " (VirtualFolder=<str>)\n"
+ "\n"
+ " --force Overwrite existing files\n"
+ " (ForceOverwrite=true)\n"
+ "\n"
+ " --help, -h Print help and exit\n"
+ "\n"
+ " --namespace=<str> Set namespace to <str> [required]\n"
+ " (Namespace=<str>)\n"
+ "\n"
+ " --qch Output as Qt Compressed Help file (*.qch) [default]\n"
+ " (QhpMode=false)\n"
+ "\n"
+ " --qhp Output as Qt Help Project (*.qhp)\n"
+ " (QhpMode=true)\n"
+ "\n"
+ " --verbose, -v Report in more detail\n"
+ " (Verbose=true)\n"
+ "\n"
+ " --version, -V Print version information and exit\n"
+ "\n"
+ );
+}
+
+void printVersion()
+{
+ printf(
+ "doxygen2qthelp " VERSION " of Qt " QT_VERSION_STR " by Trolltech ASA "
+ "(compiled " __TIME__ ", " __DATE__ ")\n"
+ );
+}
+
+void printSettings()
+{
+ printf(
+ "Settings\n"
+ " Input filename ....... %s\n"
+ " Output filename ...... %s\n"
+ "\n"
+ " QtHelpProject mode ... %s\n"
+ " Force overwrite ...... %s\n"
+ "\n"
+ " Namespace ............ %s\n"
+ " Virtual folder ....... %s\n"
+ "\n",
+ qPrintable(inputFileName),
+ qPrintable(outputFileName),
+ helpProjectMode ? "yes" : "no",
+ forceOverwrite ? "yes" : "no",
+ qPrintable(nameSpace),
+ qPrintable(virtualFolder)
+ );
+}
+
+bool checkNamespace()
+{
+ const QString uri(QLatin1String("http://") + nameSpace
+ + QLatin1String("/"));
+ const QUrl url = QUrl::fromEncoded(uri.toAscii());
+ if (!url.isValid()) {
+ printf("Error: Namespace does not conform to the rules "
+ "for the host part of a URI.\n");
+ return false;
+ }
+ return true;
+}
+
+bool checkVirtualFolder()
+{
+ const char * const VIRTUAL_FOLDER_ERROR = "Error: Virtual folder does not "
+ "conform to the rules for a path segment of a URI.\n";
+ if (virtualFolder.contains('/') || virtualFolder.contains('?')
+ || virtualFolder.contains('#')) {
+ printf(VIRTUAL_FOLDER_ERROR);
+ return false;
+ }
+
+ const QString uri(QLatin1String("http://example.org/") + virtualFolder
+ + QLatin1String("/"));
+ const QUrl url = QUrl::fromEncoded(uri.toAscii());
+ if (!url.isValid()) {
+ printf(VIRTUAL_FOLDER_ERROR);
+ return false;
+ }
+ return true;
+}
+
+bool checkFiles()
+{
+ if (inputFileName == outputFileName) {
+ printf("Error: Input and output filename identical\n");
+ return false;
+ }
+
+ if (!QFile(inputFileName).exists()) {
+ printf(FILE_MISSING_FORMAT, qPrintable(inputFileName));
+ return false;
+ }
+
+ if (!forceOverwrite && QFile(outputFileName).exists()) {
+ printf("Error: File '%s' exists. Use --force to overwrite.\n",
+ qPrintable(outputFileName));
+ return false;
+ }
+ return true;
+}
+
+void guessOutputFilename()
+{
+ if (!outputFileName.isEmpty())
+ return;
+
+ const QString newSuffix(helpProjectMode ? ".qhp" : ".qch");
+ if (inputFileName.endsWith(QLatin1String(".hhp"))) {
+ outputFileName = inputFileName.left(inputFileName.count() - 4);
+ } else {
+ outputFileName = inputFileName;
+ }
+ outputFileName += newSuffix;
+}
+
+bool run()
+{
+ guessOutputFilename();
+ Q_ASSERT(!inputFileName.isEmpty());
+ Q_ASSERT(!outputFileName.isEmpty());
+
+ if (verbose)
+ printSettings();
+
+ if (!checkNamespace() || !checkVirtualFolder() || !checkFiles())
+ return false;
+
+ HtmlHelpDataInterface helpData(inputFileName, nameSpace, virtualFolder);
+ if (helpProjectMode) {
+ // Create .qhp
+ QtHelpProjectWriter writer;
+ if (!writer.writeFile(&helpData, outputFileName)) {
+ printf("Error: Could not write to file '%s'.\n",
+ qPrintable(outputFileName));
+ return false;
+ }
+ } else {
+ // Create .qch
+ QHelpGenerator generator;
+ if (!generator.generate(&helpData, outputFileName)) {
+ printf("Error: %s\n", qPrintable(generator.error()));
+ return false;
+ }
+ }
+
+ printf("Done.\n");
+ return true;
+}
+
+void setIfSpecified(const QSettings &iniReader, const QString &key,
+ QString &output)
+{
+ const QString res = iniReader.value(key).toString();
+ if (!res.isEmpty())
+ output = res;
+}
+
+void setIfSpecified(const QSettings &iniReader, const QString &key,
+ bool &output)
+{
+ const QVariant res = iniReader.value(key);
+ if (!res.toString().isEmpty())
+ output = res.toBool();
+}
+
+bool readConfigFile(const QString &fileName)
+{
+ if (!QFile(fileName).exists()) {
+ printf(FILE_MISSING_FORMAT, qPrintable(fileName));
+ return false;
+ }
+
+ QSettings iniReader(fileName, QSettings::IniFormat);
+ setIfSpecified(iniReader, QLatin1String("ForceOverwrite"), forceOverwrite);
+ setIfSpecified(iniReader, QLatin1String("InputFile"), inputFileName);
+ setIfSpecified(iniReader, QLatin1String("Namespace"), nameSpace);
+ setIfSpecified(iniReader, QLatin1String("OutputFile"), outputFileName);
+ setIfSpecified(iniReader, QLatin1String("QhpMode"), helpProjectMode);
+ setIfSpecified(iniReader, QLatin1String("Verbose"), verbose);
+ setIfSpecified(iniReader, QLatin1String("VirtualFolder"), virtualFolder);
+ return true;
+}
+
+Action parseArgs()
+{
+ const char * const ILLEGAL_OPTION_FORMAT = "Error: Illegal option '%s'\n\n";
+ const QStringList args = QCoreApplication::arguments();
+
+ bool fileMode = false;
+ for (int i = 1; i < args.count(); i++) {
+ const QString &curArg = args.at(i);
+ if (fileMode || (curArg[0] != '-')) {
+ // Filenames only
+ switch (args.count() - i) {
+ case 2: // second last
+ inputFileName = curArg;
+ break;
+
+ case 1: // last
+ if (inputFileName.isEmpty()) {
+ inputFileName = curArg;
+ } else {
+ outputFileName = curArg;
+ }
+ break;
+
+ default:
+ if (!fileMode)
+ printf(ILLEGAL_OPTION_FORMAT, qPrintable(curArg));
+
+ error = true;
+ return ACTION_USAGE;
+ }
+ } else {
+ // Options or filenames
+ QString opt;
+ if (curArg[1] == '-') {
+ // Long option
+ opt = curArg.mid(2);
+ if (opt.isEmpty()) {
+ fileMode = true;
+ } else if (opt.startsWith(QLatin1String("config="))) {
+ if (!readConfigFile(opt.mid(6 + 1))) {
+ return ACTION_QUIT;
+ }
+ } else if (opt.startsWith("folder=")) {
+ virtualFolder = opt.mid(6 + 1);
+ } else if (opt == QLatin1String("force")) {
+ forceOverwrite = true;
+ } else if (opt == QLatin1String("help")) {
+ return ACTION_USAGE;
+ } else if (opt.startsWith("namespace=")) {
+ nameSpace = opt.mid(9 + 1);
+ } else if (opt == QLatin1String("qch")) {
+ helpProjectMode = false;
+ } else if (opt == QLatin1String("qhp")) {
+ helpProjectMode = true;
+ } else if (opt == QLatin1String("verbose")) {
+ verbose = true;
+ } else if (opt == QLatin1String("version")) {
+ return ACTION_VERSION;
+ } else {
+ printf(ILLEGAL_OPTION_FORMAT, qPrintable(curArg));
+ error = true;
+ return ACTION_USAGE;
+ }
+ } else {
+ // Short option
+ opt = curArg.mid(1);
+ if (opt.count() != 1) {
+ printf(ILLEGAL_OPTION_FORMAT, qPrintable(curArg));
+ error = true;
+ return ACTION_USAGE;
+ }
+
+ switch (opt.at(0).toAscii()) {
+ case 'h':
+ return ACTION_USAGE;
+
+ case 'v':
+ verbose = true;
+ break;
+
+ case 'V':
+ return ACTION_VERSION;
+
+ default:
+ printf(ILLEGAL_OPTION_FORMAT, qPrintable(curArg));
+ error = true;
+ return ACTION_USAGE;
+ }
+ }
+ }
+ }
+
+ if (inputFileName.isEmpty()) {
+ printf("Error: No input filename specified\n\n");
+ error = true;
+ return ACTION_USAGE;
+ }
+
+ if (nameSpace.isEmpty()) {
+ printf("Error: Namespace must not be empty.\n\n");
+ error = true;
+ return ACTION_USAGE;
+ }
+
+ if (virtualFolder.isEmpty()) {
+ printf("Error: Virtual folder must not be empty.\n\n");
+ error = true;
+ return ACTION_USAGE;
+ }
+
+ return ACTION_RUN;
+}
+
+QT_END_NAMESPACE
+
+int main(int argc, char ** argv)
+{
+ QCoreApplication app(argc, argv);
+ const Action action = parseArgs();
+
+ switch (action) {
+ case ACTION_RUN:
+ error = ! run();
+ break;
+
+ case ACTION_VERSION:
+ printVersion();
+ break;
+
+ case ACTION_QUIT:
+ break;
+
+ case ACTION_USAGE: // fall through
+ default:
+ printUsage();
+ break;
+
+ }
+
+ return error ? 1 : 0;
+}