diff --git a/man/epubgrep.1.adoc b/man/epubgrep.1.adoc index 28c6f58..acc19f3 100644 --- a/man/epubgrep.1.adoc +++ b/man/epubgrep.1.adoc @@ -81,6 +81,8 @@ suppresses errors related to them. *--debug*:: Write debug output to the terminal and log file. +*--json*:: +Output JSON instead of plain text. == USAGE diff --git a/src/main.cpp b/src/main.cpp index 3bfb4a8..b787321 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -233,7 +233,14 @@ int main(int argc, char *argv[]) for (const auto &matches : matches_all) { - output::print_matches(matches, opts, input_files.size() == 1); + if (opts.json) + { + output::json(matches); + } + else + { + output::print_matches(matches, opts, input_files.size() == 1); + } } LOG(log::sev::info) << "Exiting program with return code " << return_code; diff --git a/src/options.cpp b/src/options.cpp index 59000e9..077df45 100644 --- a/src/options.cpp +++ b/src/options.cpp @@ -93,6 +93,8 @@ options parse_options(int argc, char *argv[]) translate("Ignore errors about wrong file formats.") .str().data()) ("debug", translate("Enable debug output.") .str().data()) + ("json", + translate("Output JSON instead of plain text.") .str().data()) ; po::options_description options_hidden("Hidden options"); @@ -232,6 +234,7 @@ options parse_again(const po::variables_map &vm) opts.dereference_recursive = vm.count("dereference-recursive") > 0; opts.ignore_archive_errors = vm.count("ignore-archive-errors") > 0; opts.debug = vm.count("debug") > 0; + opts.json = vm.count("json") > 0; if (vm.count("regexp") > 0) { diff --git a/src/options.hpp b/src/options.hpp index 45ea893..a555401 100644 --- a/src/options.hpp +++ b/src/options.hpp @@ -57,6 +57,7 @@ struct options std::vector input_file; bool ignore_archive_errors{false}; bool debug{false}; + bool json{false}; //! For the debug output. friend std::ostream &operator<<(std::ostream &out, const options &opts); diff --git a/src/output.cpp b/src/output.cpp index 6e1acbd..e2cc422 100644 --- a/src/output.cpp +++ b/src/output.cpp @@ -19,6 +19,7 @@ #include #include #include // For compatibility with fmt 4. +#include #include #include @@ -39,15 +40,15 @@ void print_matches(const std::vector &matches, { if (!single_file && !opts.no_fn_fs) { - if (match.epub_filepath != last_epub) + if (match.filepath_epub != last_epub) { if (!opts.nocolor) { cout << termcolor::yellow; } cout << format(translate(" In {0:s}: \n").str(), - fs::relative(match.epub_filepath)); - last_epub = match.epub_filepath; + fs::relative(match.filepath_epub)); + last_epub = match.filepath_epub; if (!opts.nocolor) { cout << termcolor::reset; @@ -110,4 +111,20 @@ void print_matches(const std::vector &matches, } } +void json(const std::vector &matches) +{ + nlohmann::json json; + + for (const auto &match : matches) + { + json[match.filepath_epub].push_back( + {{"filepath", match.filepath_inside}, + {"match", match.text}, + {"context", match.context}, + {"headline", match.headline}, + {"page", match.page}}); + } + std::cout << json.dump(2) << '\n'; +} + } // namespace epubgrep::output diff --git a/src/output.hpp b/src/output.hpp index 85a488b..3092646 100644 --- a/src/output.hpp +++ b/src/output.hpp @@ -28,6 +28,8 @@ namespace epubgrep::output void print_matches(const std::vector &matches, const options::options &opts, bool single_file); +void json(const std::vector &matches); + } // namespace epubgrep::output #endif // EPUBGREP_OUTPUT_HPP