From 28f8e8005ab98336f40ef058f415d3110d75bb09 Mon Sep 17 00:00:00 2001 From: hashirama Date: Fri, 17 May 2024 15:12:13 -0400 Subject: [PATCH] add goldendict mode --- src/main.cc | 112 ++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 86 insertions(+), 26 deletions(-) diff --git a/src/main.cc b/src/main.cc index c277fa8..2da26c3 100644 --- a/src/main.cc +++ b/src/main.cc @@ -7,6 +7,8 @@ #include #include #include +#include +#include // Struct to hold the view and id of each entry struct Entry { @@ -39,42 +41,65 @@ inline std::pair remove_one_utf8_char(const std::strin } // Function to check input from command line or piped input -inline std::string get_input(int argc, char* argv[]) { +inline std::string get_input(int argc, char* argv[], bool goldendict_mode) { std::string search_string; - + if (!isatty(fileno(stdin))) { // If input is piped std::getline(std::cin, search_string); } else { // If input is provided as command line argument - if (argc < 2) { - std::cerr << "Usage: " << argv[0] << " " << std::endl; - exit(1); - } - - for (int i = 1; i < argc; ++i) { - if (std::strcmp(argv[i], "--debug") == 0) { - // Handle debug mode - } else if (std::strcmp(argv[i], "--dict") == 0 && i + 1 < argc) { - // Skip the next argument as it's the dictionary file path - i++; - } else { - search_string = argv[i]; - break; + if (goldendict_mode) { + for (int i = 1; i < argc; ++i) { + if (std::strcmp(argv[i], "--sentence") == 0 && i + 1 < argc) { + search_string = argv[i + 1]; + break; + } + } + } else { + if (argc < 2) { + std::cerr << "Usage: " << argv[0] << " " << std::endl; + exit(1); + } + for (int i = 1; i < argc; ++i) { + if (std::strcmp(argv[i], "--debug") == 0) { + // Handle debug mode + } else if (std::strcmp(argv[i], "--dict") == 0 && i + 1 < argc) { + // Skip the next argument as it's the dictionary file path + i++; + } else { + search_string = argv[i]; + break; + } } } } - + if (search_string.empty()) { std::cerr << "Search string not provided." << std::endl; exit(1); } - + return search_string; } +auto find_dic_file() -> std::filesystem::path { + static auto const locations = { + std::filesystem::path("/usr/share/hakurei/"), + std::filesystem::path(std::getenv("HOME")) / ".local/share/hakurei/", + std::filesystem::current_path() + }; + for (auto const& location : locations) { + if (std::filesystem::exists(location / "dict.bin") && std::filesystem::is_regular_file(location / "dict.bin")) { + return (location / "dict.bin"); + } + } + throw std::runtime_error("Couldn't find the word list."); +} + int main(int argc, char* argv[]) { - std::string search_string = get_input(argc, argv); bool debug_mode = false; - std::string dict_file = "dict.bin"; // Default dictionary file path + bool goldendict_mode = false; + std::string word, sentence; + std::string dict_file = find_dic_file().string(); // Default dictionary file path // Parse command line arguments for (int i = 1; i < argc; ++i) { @@ -83,14 +108,28 @@ int main(int argc, char* argv[]) { } else if (std::strcmp(argv[i], "--dict") == 0 && i + 1 < argc) { dict_file = argv[i + 1]; i++; // Skip the next argument as it's the dictionary file path + } else if (std::strcmp(argv[i], "--goldendict") == 0) { + goldendict_mode = true; + } else if (std::strcmp(argv[i], "--word") == 0 && i + 1 < argc) { + word = argv[i + 1]; + i++; + } else if (std::strcmp(argv[i], "--sentence") == 0 && i + 1 < argc) { + sentence = argv[i + 1]; + i++; } } + std::string search_string = get_input(argc, argv, goldendict_mode); + if (goldendict_mode && !sentence.empty()) { + search_string = sentence; + } + std::string raw_output; const auto trie = xcdat::load(dict_file); std::vector substrings; std::vector results; + std::map> derived_map; while (!search_string.empty()) { auto itr = trie.make_prefix_iterator(search_string); @@ -104,14 +143,17 @@ int main(int argc, char* argv[]) { for (const auto& entry : results) { std::string substring(entry.decoded_view); substrings.push_back(substring); - std::cout << substring << std::endl; + derived_map[substring].push_back(search_string); + if (!goldendict_mode) { + std::cout << substring << std::endl; + } } } // Remove one UTF-8 character from the search string and get the removed character auto [removed_char, new_search_string] = remove_one_utf8_char(search_string); - if (!removed_char.empty()) { + if (!removed_char.empty() && !goldendict_mode) { std::cout << removed_char << std::endl; } @@ -126,15 +168,33 @@ int main(int argc, char* argv[]) { results.clear(); // Remove leading whitespace - while (!search_string.empty() && std::isspace(search_string.front())) { - search_string.erase(0, 1); - } + search_string.erase(0, search_string.find_first_not_of(" \t\n\r\f\v")); } // Print debug information if in debug mode if (debug_mode) { - std::cout << "Stored raw output:" << std::endl << raw_output << std::endl; + std::cout << "Stored raw output:" << std::endl; + for (const auto& str : substrings) { + std::cout << str << std::endl; + } + } + + // Wrap the output in HTML format for GoldenDict if in GoldenDict mode + if (goldendict_mode) { + std::cout << "
"; + for (const auto& [key, values] : derived_map) { + std::cout << "" << key << ""; + if (!values.empty()) { + std::cout << "
    "; + for (const auto& value : values) { + std::cout << "
  • " << value << "
  • "; + } + std::cout << "
"; + } + } + std::cout << "
"; } return 0; } +