diff --git a/src/cli/kate-syntax-highlighter.cpp b/src/cli/kate-syntax-highlighter.cpp --- a/src/cli/kate-syntax-highlighter.cpp +++ b/src/cli/kate-syntax-highlighter.cpp @@ -25,6 +25,7 @@ #include #include +#include #include #include @@ -72,6 +73,15 @@ app.translate("SyntaxHighlightingCLI", "theme"), QStringLiteral("Default")); parser.addOption(themeName); + QCommandLineOption titleOption(QStringList() << QStringLiteral("T") << QStringLiteral("title"), + app.translate("SyntaxHighlightingCLI", "Set HTML page's title\n(default: the filename or \"Kate Syntax Highlighter\" if reading from stdin)."), + app.translate("SyntaxHighlightingCLI", "title")); + parser.addOption(titleOption); + + QCommandLineOption stdinOption(QStringList() << QStringLiteral("stdin"), + app.translate("SyntaxHighlightingCLI", "Read file from stdin. The -s option must also be used.")); + parser.addOption(stdinOption); + parser.process(app); Repository repo; @@ -98,16 +108,29 @@ return app.exec(); } - if (parser.positionalArguments().size() != 1) - parser.showHelp(1); - const auto inFileName = parser.positionalArguments().at(0); + bool fromFileName = false; + QString inFileName; + if (parser.positionalArguments().size() == 1) { + fromFileName = true; + inFileName = parser.positionalArguments().at(0); + } Definition def; if (parser.isSet(syntaxName)) { def = repo.definitionForName(parser.value(syntaxName)); - } else { + if (!def.isValid()) + /* see if it's a mimetype instead */ + def = repo.definitionForMimeType(parser.value(syntaxName)); + } else if (fromFileName) { def = repo.definitionForFileName(inFileName); + } else { + parser.showHelp(1); } + + QString title = QString(); + if (parser.isSet(titleOption)) + title = parser.value(titleOption); + if (!def.isValid()) { std::cerr << "Unknown syntax." << std::endl; return 1; @@ -120,7 +143,16 @@ else highlighter.setOutputFile(stdout); highlighter.setTheme(repo.theme(parser.value(themeName))); - highlighter.highlightFile(inFileName); + + if (fromFileName) { + highlighter.highlightFile(inFileName, title); + } else if (parser.isSet(stdinOption)) { + QFile inFile; + inFile.open(stdin, QIODevice::ReadOnly); + highlighter.highlightData(&inFile, title); + } else { + parser.showHelp(1); + } return 0; } diff --git a/src/lib/htmlhighlighter.h b/src/lib/htmlhighlighter.h --- a/src/lib/htmlhighlighter.h +++ b/src/lib/htmlhighlighter.h @@ -22,6 +22,7 @@ #include "abstracthighlighter.h" #include +#include #include @@ -38,7 +39,8 @@ HtmlHighlighter(); ~HtmlHighlighter() override; - void highlightFile(const QString &fileName); + void highlightFile(const QString &fileName, const QString &title = QString()); + void highlightData(QIODevice *device, const QString &title = QString()); void setOutputFile(const QString &fileName); void setOutputFile(FILE *fileHandle); diff --git a/src/lib/htmlhighlighter.cpp b/src/lib/htmlhighlighter.cpp --- a/src/lib/htmlhighlighter.cpp +++ b/src/lib/htmlhighlighter.cpp @@ -63,32 +63,46 @@ d->out->setCodec("UTF-8"); } -void HtmlHighlighter::highlightFile(const QString& fileName) +void HtmlHighlighter::highlightFile(const QString& fileName, const QString& title) { - if (!d->out) { - qCWarning(Log) << "No output stream defined!"; - return; - } - + QFileInfo fi(fileName); QFile f(fileName); if (!f.open(QFile::ReadOnly)) { qCWarning(Log) << "Failed to open input file" << fileName << ":" << f.errorString(); return; } + if (title.isEmpty()) + highlightData(&f, fi.fileName()); + else + highlightData(&f, title); +} + +void HtmlHighlighter::highlightData(QIODevice *dev, const QString& title) +{ + if (!d->out) { + qCWarning(Log) << "No output stream defined!"; + return; + } + + QString htmlTitle; + if (title.isEmpty()) + htmlTitle = QStringLiteral("Kate Syntax Highlighter"); + else + htmlTitle = title.toHtmlEscaped(); + State state; *d->out << "\n"; *d->out << "\n"; *d->out << "\n"; - QFileInfo fi(fileName); - *d->out << "" << fi.fileName() << "\n"; + *d->out << "" << htmlTitle << "\n"; *d->out << "\n"; *d->out << "out << " style=\"color:" << QColor(theme().textColor(Theme::Normal)).name() << "\""; *d->out << ">
\n";
 
-    QTextStream in(&f);
+    QTextStream in(dev);
     in.setCodec("UTF-8");
     while (!in.atEnd()) {
         d->currentLine = in.readLine();
diff --git a/src/lib/repository.h b/src/lib/repository.h
--- a/src/lib/repository.h
+++ b/src/lib/repository.h
@@ -149,6 +149,14 @@
      */
     Definition definitionForFileName(const QString &fileName) const;
 
+    /**
+     * Returns the best matching Definition to the type named @p mimeType
+     *
+     * If no match is found, Definition::isValid() of the returned instance
+     * returns false.
+     */
+    Definition definitionForMimeType(const QString &mimeType) const;
+
     /**
      * Returns all available Definition%s.
      * Definition%ss are ordered by translated section and translated names,
@@ -218,6 +226,8 @@
     QVector customSearchPaths() const;
 
 private:
+    Definition bestCandidate(QVector &candidates) const;
+
     Q_DISABLE_COPY(Repository)
     friend class RepositoryPrivate;
     std::unique_ptr d;
diff --git a/src/lib/repository.cpp b/src/lib/repository.cpp
--- a/src/lib/repository.cpp
+++ b/src/lib/repository.cpp
@@ -82,6 +82,26 @@
         }
     }
 
+    return bestCandidate(candidates);
+}
+
+Definition Repository::definitionForMimeType(const QString& mimeType) const
+{
+    QVector candidates;
+    for (auto it = d->m_defs.constBegin(); it != d->m_defs.constEnd(); ++it) {
+        auto def = it.value();
+        foreach (const auto &matchType, def.mimeTypes()) {
+            if (mimeType == matchType)
+                candidates.push_back(def);
+                break;
+        }
+    }
+
+    return bestCandidate(candidates);
+}
+
+Definition Repository::bestCandidate(QVector& candidates) const
+{
     if (candidates.isEmpty())
         return Definition();