File indexing completed on 2024-05-12 15:49:59
0001 /* 0002 SPDX-FileCopyrightText: 2016 Volker Krause <vkrause@kde.org> 0003 0004 SPDX-License-Identifier: MIT 0005 */ 0006 0007 #include "ksyntaxhighlighting_version.h" 0008 0009 #include <KSyntaxHighlighting/Definition> 0010 #include <KSyntaxHighlighting/DefinitionDownloader> 0011 #include <KSyntaxHighlighting/Repository> 0012 #include <KSyntaxHighlighting/Theme> 0013 #include <ansihighlighter.h> 0014 #include <htmlhighlighter.h> 0015 0016 #include <QCommandLineParser> 0017 #include <QCoreApplication> 0018 #include <QFile> 0019 0020 #include <iostream> 0021 0022 using namespace KSyntaxHighlighting; 0023 0024 template<class Highlighter, class... Ts> 0025 static void applyHighlighter(Highlighter &highlighter, 0026 QCommandLineParser &parser, 0027 bool fromFileName, 0028 const QString &inFileName, 0029 const QCommandLineOption &stdinOption, 0030 const QCommandLineOption &outputName, 0031 const Ts &...highlightParams) 0032 { 0033 if (parser.isSet(outputName)) { 0034 highlighter.setOutputFile(parser.value(outputName)); 0035 } else { 0036 highlighter.setOutputFile(stdout); 0037 } 0038 0039 if (fromFileName) { 0040 highlighter.highlightFile(inFileName, highlightParams...); 0041 } else if (parser.isSet(stdinOption)) { 0042 QFile inFile; 0043 inFile.open(stdin, QIODevice::ReadOnly); 0044 highlighter.highlightData(&inFile, highlightParams...); 0045 } else { 0046 parser.showHelp(1); 0047 } 0048 } 0049 0050 int main(int argc, char **argv) 0051 { 0052 QCoreApplication app(argc, argv); 0053 QCoreApplication::setApplicationName(QStringLiteral("kate-syntax-highlighter")); 0054 QCoreApplication::setOrganizationDomain(QStringLiteral("kde.org")); 0055 QCoreApplication::setOrganizationName(QStringLiteral("KDE")); 0056 QCoreApplication::setApplicationVersion(QStringLiteral(SyntaxHighlighting_VERSION_STRING)); 0057 0058 Repository repo; 0059 0060 QCommandLineParser parser; 0061 parser.setApplicationDescription(app.translate("SyntaxHighlightingCLI", "Command line syntax highlighter using Kate syntax definitions.")); 0062 parser.addHelpOption(); 0063 parser.addVersionOption(); 0064 parser.addPositionalArgument(app.translate("SyntaxHighlightingCLI", "source"), app.translate("SyntaxHighlightingCLI", "The source file to highlight.")); 0065 0066 QCommandLineOption listDefs(QStringList() << QStringLiteral("l") << QStringLiteral("list"), 0067 app.translate("SyntaxHighlightingCLI", "List all available syntax definitions.")); 0068 parser.addOption(listDefs); 0069 QCommandLineOption listThemes(QStringList() << QStringLiteral("list-themes"), app.translate("SyntaxHighlightingCLI", "List all available themes.")); 0070 parser.addOption(listThemes); 0071 0072 QCommandLineOption updateDefs(QStringList() << QStringLiteral("u") << QStringLiteral("update"), 0073 app.translate("SyntaxHighlightingCLI", "Download new/updated syntax definitions.")); 0074 parser.addOption(updateDefs); 0075 0076 QCommandLineOption outputName(QStringList() << QStringLiteral("o") << QStringLiteral("output"), 0077 app.translate("SyntaxHighlightingCLI", "File to write HTML output to (default: stdout)."), 0078 app.translate("SyntaxHighlightingCLI", "output")); 0079 parser.addOption(outputName); 0080 0081 QCommandLineOption syntaxName(QStringList() << QStringLiteral("s") << QStringLiteral("syntax"), 0082 app.translate("SyntaxHighlightingCLI", "Highlight using this syntax definition (default: auto-detect based on input file)."), 0083 app.translate("SyntaxHighlightingCLI", "syntax")); 0084 parser.addOption(syntaxName); 0085 0086 QCommandLineOption themeName(QStringList() << QStringLiteral("t") << QStringLiteral("theme"), 0087 app.translate("SyntaxHighlightingCLI", "Color theme to use for highlighting."), 0088 app.translate("SyntaxHighlightingCLI", "theme"), 0089 repo.defaultTheme(Repository::LightTheme).name()); 0090 parser.addOption(themeName); 0091 0092 QCommandLineOption outputFormatOption( 0093 QStringList() << QStringLiteral("f") << QStringLiteral("output-format"), 0094 app.translate("SyntaxHighlightingCLI", "Use the specified format instead of html. Must be html, ansi or ansi256Colors."), 0095 app.translate("SyntaxHighlightingCLI", "format"), 0096 QStringLiteral("html")); 0097 parser.addOption(outputFormatOption); 0098 0099 QCommandLineOption traceOption(QStringList() << QStringLiteral("syntax-trace"), 0100 app.translate("SyntaxHighlightingCLI", 0101 "Add information to debug a syntax file. Only works with --output-format=ansi or ansi256Colors. Possible " 0102 "values are format, region, context and stackSize."), 0103 app.translate("SyntaxHighlightingCLI", "type")); 0104 parser.addOption(traceOption); 0105 0106 QCommandLineOption noAnsiEditorBg(QStringList() << QStringLiteral("b") << QStringLiteral("no-ansi-background"), 0107 app.translate("SyntaxHighlightingCLI", "Disable ANSI background for the default color.")); 0108 parser.addOption(noAnsiEditorBg); 0109 0110 QCommandLineOption titleOption( 0111 QStringList() << QStringLiteral("T") << QStringLiteral("title"), 0112 app.translate("SyntaxHighlightingCLI", "Set HTML page's title\n(default: the filename or \"Kate Syntax Highlighter\" if reading from stdin)."), 0113 app.translate("SyntaxHighlightingCLI", "title")); 0114 parser.addOption(titleOption); 0115 0116 QCommandLineOption stdinOption(QStringList() << QStringLiteral("stdin"), 0117 app.translate("SyntaxHighlightingCLI", "Read file from stdin. The -s option must also be used.")); 0118 parser.addOption(stdinOption); 0119 0120 parser.process(app); 0121 0122 if (parser.isSet(listDefs)) { 0123 for (const auto &def : repo.definitions()) { 0124 std::cout << qPrintable(def.name()) << std::endl; 0125 } 0126 return 0; 0127 } 0128 0129 if (parser.isSet(listThemes)) { 0130 for (const auto &theme : repo.themes()) { 0131 std::cout << qPrintable(theme.name()) << std::endl; 0132 } 0133 return 0; 0134 } 0135 0136 if (parser.isSet(updateDefs)) { 0137 DefinitionDownloader downloader(&repo); 0138 QObject::connect(&downloader, &DefinitionDownloader::informationMessage, [](const QString &msg) { 0139 std::cout << qPrintable(msg) << std::endl; 0140 }); 0141 QObject::connect(&downloader, &DefinitionDownloader::done, &app, &QCoreApplication::quit); 0142 downloader.start(); 0143 return app.exec(); 0144 } 0145 0146 bool fromFileName = false; 0147 QString inFileName; 0148 if (parser.positionalArguments().size() == 1) { 0149 fromFileName = true; 0150 inFileName = parser.positionalArguments().at(0); 0151 } 0152 0153 Definition def; 0154 if (parser.isSet(syntaxName)) { 0155 const QString syntax = parser.value(syntaxName); 0156 def = repo.definitionForName(syntax); 0157 if (!def.isValid()) { 0158 /* see if it's a mimetype instead */ 0159 def = repo.definitionForMimeType(syntax); 0160 if (!def.isValid()) { 0161 /* see if it's a extension instead */ 0162 def = repo.definitionForFileName(QLatin1String("f.") + syntax); 0163 if (!def.isValid()) { 0164 /* see if it's a filename instead */ 0165 def = repo.definitionForFileName(syntax); 0166 } 0167 } 0168 } 0169 } else if (fromFileName) { 0170 def = repo.definitionForFileName(inFileName); 0171 } else { 0172 parser.showHelp(1); 0173 } 0174 0175 if (!def.isValid()) { 0176 std::cerr << "Unknown syntax." << std::endl; 0177 return 1; 0178 } 0179 0180 QString outputFormat = parser.value(outputFormatOption); 0181 if (0 == outputFormat.compare(QLatin1String("html"), Qt::CaseInsensitive)) { 0182 QString title; 0183 if (parser.isSet(titleOption)) { 0184 title = parser.value(titleOption); 0185 } 0186 0187 HtmlHighlighter highlighter; 0188 highlighter.setDefinition(def); 0189 highlighter.setTheme(repo.theme(parser.value(themeName))); 0190 applyHighlighter(highlighter, parser, fromFileName, inFileName, stdinOption, outputName, title); 0191 } else { 0192 auto AnsiFormat = AnsiHighlighter::AnsiFormat::TrueColor; 0193 if (0 == outputFormat.compare(QLatin1String("ansi256Colors"), Qt::CaseInsensitive)) { 0194 AnsiFormat = AnsiHighlighter::AnsiFormat::XTerm256Color; 0195 } else if (0 != outputFormat.compare(QLatin1String("ansi"), Qt::CaseInsensitive)) { 0196 std::cerr << "Unknown output format." << std::endl; 0197 return 2; 0198 } 0199 0200 auto debugOptions = AnsiHighlighter::TraceOptions(); 0201 if (parser.isSet(traceOption)) { 0202 const auto options = parser.values(traceOption); 0203 for (auto const &option : options) { 0204 if (option == QStringLiteral("format")) { 0205 debugOptions |= AnsiHighlighter::TraceOption::Format; 0206 } else if (option == QStringLiteral("region")) { 0207 debugOptions |= AnsiHighlighter::TraceOption::Region; 0208 } else if (option == QStringLiteral("context")) { 0209 debugOptions |= AnsiHighlighter::TraceOption::Context; 0210 } else if (option == QStringLiteral("stackSize")) { 0211 debugOptions |= AnsiHighlighter::TraceOption::StackSize; 0212 } else { 0213 std::cerr << "Unknown trace name." << std::endl; 0214 return 2; 0215 } 0216 } 0217 } 0218 0219 AnsiHighlighter highlighter; 0220 highlighter.setDefinition(def); 0221 highlighter.setTheme(repo.theme(parser.value(themeName))); 0222 applyHighlighter(highlighter, parser, fromFileName, inFileName, stdinOption, outputName, AnsiFormat, !parser.isSet(noAnsiEditorBg), debugOptions); 0223 } 0224 0225 return 0; 0226 }