Skip to content

Commit

Permalink
fmtlib replaced with std::format
Browse files Browse the repository at this point in the history
  • Loading branch information
xieamoe committed Mar 20, 2024
1 parent fcd6223 commit 80696e5
Show file tree
Hide file tree
Showing 11 changed files with 96 additions and 74 deletions.
50 changes: 25 additions & 25 deletions src/anki_search.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -167,10 +167,10 @@ auto make_find_cards_request_str(search_params const& params) -> std::string
std::string query{ params.gd_word };

if (not params.field_name.empty()) {
query = fmt::format("\"{}:*{}*\"", params.field_name, query);
query = std::format("\"{}:*{}*\"", params.field_name, query);
}
if (not params.deck_name.empty()) {
query = fmt::format("\"deck:{}\" {}", params.deck_name, query);
query = std::format("\"deck:{}\" {}", params.deck_name, query);
}

request["params"]["query"] = query;
Expand Down Expand Up @@ -261,20 +261,20 @@ auto get_note_tags(uint64_t const nid) -> std::string
raise_if(not obj["error"].is_null(), "Error getting data from AnkiConnect.");
std::string html;
for (std::string const tag_name: obj["result"]) {
html += fmt::format(R"EOF(<a class="gd-tag-link" href="ankisearch:tag:{}">{}</a>)EOF", tag_name, tag_name);
html += std::format(R"EOF(<a class="gd-tag-link" href="ankisearch:tag:{}">{}</a>)EOF", tag_name, tag_name);
}
return html;
}

void print_table_header(search_params const& params)
{
// Print the first row (header) that contains <th></th> tags, starting with Card ID.
fmt::print("<tr>");
fmt::print("<th>Card ID</th>");
fmt::print("<th>Deck name</th>");
for (auto const& field: params.show_fields) { fmt::print("<th>{}</th>", field); }
fmt::print("<th>Tags</th>");
fmt::print("</tr>\n");
gd::print("<tr>");
gd::print("<th>Card ID</th>");
gd::print("<th>Deck name</th>");
for (auto const& field: params.show_fields) { gd::print("<th>{}</th>", field); }
gd::print("<th>Tags</th>");
gd::print("</tr>\n");
}

auto card_json_to_obj(nlohmann::json const& card_json) -> card_info
Expand Down Expand Up @@ -303,47 +303,47 @@ auto gd_format(std::string const& field_content, std::string const& media_dir_pa
static std::regex const img_re{ "(<img[^<>]*src=\")" };
static std::regex const any_undesirables{ R"EOF(\[sound:|\]|<[^<>]+>|["'.,!?]+|…|。|、|!|?| |・|~|\(|\))EOF" };
auto const link_content = strtrim(std::regex_replace(field_content, any_undesirables, " "));
auto const link_text = std::regex_replace(field_content, img_re, fmt::format("$1file://{}/", media_dir_path));
return link_content.empty() ? link_text : fmt::format("<a href=\"ankisearch:{}\">{}</a>", link_content, link_text);
auto const link_text = std::regex_replace(field_content, img_re, std::format("$1file://{}/", media_dir_path));
return link_content.empty() ? link_text : std::format("<a href=\"ankisearch:{}\">{}</a>", link_content, link_text);
}

void print_cards_info(search_params const& params)
{
auto const cids = find_cids(params);
if (cids.empty()) {
return fmt::print("No cards found.\n");
return gd::print("No cards found.\n");
}
auto const media_dir_path = fetch_media_dir_path();
fmt::print("<div class=\"gd-table-wrap\">");
fmt::print("<table class=\"gd-ankisearch-table\">\n");
gd::print("<div class=\"gd-table-wrap\">");
gd::print("<table class=\"gd-ankisearch-table\">\n");
print_table_header(params);
for (auto const& card: get_cids_info(cids) | std::views::transform(card_json_to_obj)) {
fmt::print("<tr class=\"{}\">", determine_card_class(card.queue, card.type));
fmt::print("<td><a href=\"ankisearch:cid:{}\">{}</a></td>", card.id, card.id);
fmt::print("<td>{}</td>", card.deck_name);
gd::print("<tr class=\"{}\">", determine_card_class(card.queue, card.type));
gd::print("<td><a href=\"ankisearch:cid:{}\">{}</a></td>", card.id, card.id);
gd::print("<td>{}</td>", card.deck_name);
for (auto const& field_name: params.show_fields) {
fmt::print(
gd::print(
"<td>{}</td>",
(card.fields.contains(field_name) and not card.fields.at(field_name).empty()
? gd_format(card.fields.at(field_name), media_dir_path)
: "Not present")
);
}
fmt::print("<td>{}</td>\n", get_note_tags(card.nid));
fmt::print("</tr>\n");
gd::print("<td>{}</td>\n", get_note_tags(card.nid));
gd::print("</tr>\n");
}
fmt::print("</table>");
fmt::print("</div>\n"); // gd-table-wrap
fmt::print("{}\n", css_style);
gd::print("</table>");
gd::print("</div>\n"); // gd-table-wrap
gd::print("{}\n", css_style);
}

void search_anki_cards(std::span<std::string_view const> const args)
{
try {
print_cards_info(fill_args<search_params>(args));
} catch (gd::help_requested const& ex) {
fmt::print(help_text);
gd::print(help_text);
} catch (gd::runtime_error const& ex) {
fmt::print("{}\n", ex.what());
gd::print("{}\n", ex.what());
}
}
8 changes: 4 additions & 4 deletions src/echo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,13 +69,13 @@ void print_css(stroke_order_params const& params)
}}
</style>
)EOF";
fmt::print(css, this_pid, params.font_size, params.font_family);
gd::print(css, this_pid, params.font_size, params.font_family);
}

void print_with_stroke_order(stroke_order_params const& params)
{
if (params.gd_word.length() <= params.max_len) {
fmt::print("<div class=\"gd_echo_{}\">{}</div>\n", this_pid, params.gd_word);
gd::print("<div class=\"gd_echo_{}\">{}</div>\n", this_pid, params.gd_word);
print_css(params);
}
}
Expand All @@ -85,8 +85,8 @@ void stroke_order(std::span<std::string_view const> const args)
try {
print_with_stroke_order(fill_args<stroke_order_params>(args));
} catch (gd::help_requested const& ex) {
fmt::print(help_text);
gd::print(help_text);
} catch (gd::runtime_error const& ex) {
fmt::print("{}\n", ex.what());
gd::print("{}\n", ex.what());
}
}
12 changes: 6 additions & 6 deletions src/images.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,21 +84,21 @@ void fetch_images(images_params const& params)
static std::regex const img_re("<img[^<>]*class=\"mimg[^<>]*>");
auto images_begin = std::sregex_iterator(std::begin(r.text), std::end(r.text), img_re);
auto images_end = std::sregex_iterator();
fmt::print("<div class=\"gallery\">\n");
gd::print("<div class=\"gallery\">\n");
for (auto const& match: std::ranges::subrange(images_begin, images_end) | std::views::take(5)) {
fmt::print("{}\n", match.str());
gd::print("{}\n", match.str());
}
fmt::print("</div>\n");
fmt::print("{}\n", css_style);
gd::print("</div>\n");
gd::print("{}\n", css_style);
}

void images(std::span<std::string_view const> const args)
{
try {
fetch_images(fill_args<images_params>(args));
} catch (gd::help_requested const& ex) {
fmt::print(help_text);
gd::print(help_text);
} catch (gd::runtime_error const& ex) {
fmt::print("{}\n", ex.what());
gd::print("{}\n", ex.what());
}
}
2 changes: 1 addition & 1 deletion src/kana_conv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ auto unicode_char_byte_len(char const& ch) -> CharByteLen
// Other Unicode
return CharByteLen::FOUR;
}
throw gd::runtime_error{ fmt::format("Can't recognize byte: '{:x}'.", ch) };
throw gd::runtime_error{ std::format("Can't recognize byte: '{:x}'.", ch) };
}

auto create_map(std::string_view from, std::string_view to) -> KanaConvMap
Expand Down
5 changes: 3 additions & 2 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include "massif.h"
#include "mecab_split.h"
#include "precompiled.h"
#include "util.h"

static constexpr std::string_view help_text = R"EOF(usage: {} ACTION [OPTIONS]
A set of helpful programs to enhance GoldenDict for immersion learning.
Expand All @@ -47,12 +48,12 @@ gd-ankisearch --deck-name Mining %GDWORD%

auto get_help_str(std::string_view program_name) -> std::string
{
return fmt::format(help_text, program_name);
return std::format(help_text, program_name);
}

auto print_help(std::string_view const program_name) -> void
{
fmt::print("{}", get_help_str(program_name));
gd::print("{}", get_help_str(program_name));
}

auto base_name(auto file_path) -> std::string
Expand Down
24 changes: 12 additions & 12 deletions src/marisa_split.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -181,10 +181,10 @@ void lookup_words(marisa_params params)
marisa::Agent agent;

std::ifstream file{ params.path_to_dic };
raise_if(not file.good(), fmt::format(R"(Error. The dictionary file "{}" does not exist.)", params.path_to_dic));
raise_if(not file.good(), std::format(R"(Error. The dictionary file "{}" does not exist.)", params.path_to_dic));
trie.load(params.path_to_dic.c_str());

fmt::println(R"(<div class="gd-marisa">)");
gd::println(R"(<div class="gd-marisa">)");
std::ptrdiff_t pos_in_gd_word{ 0 };
std::vector<JpSet> alternatives{};
alternatives.reserve(20);
Expand All @@ -205,7 +205,7 @@ void lookup_words(marisa_params params)
pos_in_gd_word -= static_cast<std::ptrdiff_t>(uni_char.length());
}

fmt::print(
gd::print(
R"(<a class="{}" href="bword:{}">{}</a>)",
(pos_in_gd_word > 0 ? "gd-headword" : "gd-word"),
bword,
Expand All @@ -215,32 +215,32 @@ void lookup_words(marisa_params params)
}

// Show available entries for other substrings.
fmt::println(R"(<div class="alternatives">)");
gd::println(R"(<div class="alternatives">)");
for (auto const& group: alternatives | std::views::filter(&JpSet::size)) {
fmt::println("<ul>");
gd::println("<ul>");
for (auto const& word: group) {
fmt::println(
gd::println(
R"(<li><a class="{}" href="bword:{}">{}</a></li>)",
(word == params.gd_word ? "gd-headword" : ""),
word,
word
);
}
fmt::println("</ul>"); // close ul
gd::println("</ul>"); // close ul
}
fmt::println("</div>"); // close div.alternatives
gd::println("</div>"); // close div.alternatives

fmt::println("</div>"); // close div.gd-marisa
fmt::println("{}", css_style);
gd::println("</div>"); // close div.gd-marisa
gd::println("{}", css_style);
}

void marisa_split(std::span<std::string_view const> const args)
{
try {
lookup_words(fill_args<marisa_params>(args));
} catch (gd::help_requested const& ex) {
fmt::println(help_text);
gd::println(help_text);
} catch (gd::runtime_error const& ex) {
fmt::println("{}", ex.what());
gd::println("{}", ex.what());
}
}
14 changes: 7 additions & 7 deletions src/massif.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,12 +74,12 @@ struct massif_params
void fetch_massif_examples(massif_params const& params)
{
cpr::Response const r = cpr::Get(
cpr::Url{ fmt::format("https://massif.la/ja/search?q={}", params.gd_word) },
cpr::Url{ std::format("https://massif.la/ja/search?q={}", params.gd_word) },
cpr::Timeout{ params.max_time },
cpr::VerifySsl{ false }
);
raise_if(r.status_code != 200, "Couldn't connect to Massif.");
fmt::print("<ul class=\"gd-massif\">\n");
gd::print("<ul class=\"gd-massif\">\n");
for (auto const& line:
r.text //
| std::views::split('\n') //
Expand All @@ -88,19 +88,19 @@ void fetch_massif_examples(massif_params const& params)
return not str_view.contains("<li class=\"text-japanese\">");
})
| std::views::take_while([](auto const str_view) { return not str_view.contains("</ul>"); })) {
fmt::print("{}\n", line);
gd::print("{}\n", line);
}
fmt::print("</ul>\n");
fmt::print("{}\n", css_style);
gd::print("</ul>\n");
gd::print("{}\n", css_style);
}

void massif(std::span<std::string_view const> const args)
{
try {
fetch_massif_examples(fill_args<massif_params>(args));
} catch (gd::help_requested const& ex) {
fmt::print(help_text);
gd::print(help_text);
} catch (gd::runtime_error const& ex) {
fmt::print("{}\n", ex.what());
gd::print("{}\n", ex.what());
}
}
24 changes: 13 additions & 11 deletions src/mecab_split.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ struct mecab_params
} else if (key == "--user-dict") {
user_dict = value;
} else {
throw gd::runtime_error(std::string(fmt::format("Unknown argument name: {}", key)));
throw gd::runtime_error(std::string(std::format("Unknown argument name: {}", key)));
}
}
};
Expand Down Expand Up @@ -174,25 +174,27 @@ void lookup_words(mecab_params params)
}

std::string result = tagger->parse(params.gd_sentence.c_str());
result = replace_all(result, fmt::format(">{}<", params.gd_word), fmt::format("><b>{}</b><", params.gd_word));
fmt::println(R"EOF(<div class="gd-mecab">{}</div>)EOF", result);
fmt::println("{}", css_style);
result = replace_all(result, std::format(">{}<", params.gd_word), std::format("><b>{}</b><", params.gd_word));
gd::println(R"EOF(<div class="gd-mecab">{}</div>)EOF", result);
gd::println("{}", css_style);

// debug info, not shown in GD.
fmt::println(R"EOF(<div style="display: none;">)EOF");
fmt::println("dicdir: {}", params.dic_dir.string());
fmt::println("userdic: {}", params.user_dict.string());
fmt::println("mecab args: {}", args);
fmt::println(R"EOF(</div>)EOF");
gd::println(R"EOF(<div style="display: none;">)EOF");
gd::println("dicdir: {}", params.dic_dir.string());
gd::println("userdic: {}", params.user_dict.string());

//TODO There must be a better way but ranges are not supported yet as far as I know
gd::println("mecab args: {} {} {} {} {}", args[0], args[1], args[2], args[3], args[4]);
gd::println(R"EOF(</div>)EOF");
}

void mecab_split(std::span<std::string_view const> const args)
{
try {
lookup_words(fill_args<mecab_params>(args));
} catch (gd::help_requested const& ex) {
fmt::println(help_text);
gd::println(help_text);
} catch (gd::runtime_error const& ex) {
fmt::println("{}", ex.what());
gd::println("{}", ex.what());
}
}
4 changes: 2 additions & 2 deletions src/precompiled.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include <string_view>
#include <system_error>
#include <vector>
#include <format>

// Getpid
#if __linux__
Expand All @@ -27,8 +28,7 @@

// Other
#include <cpr/cpr.h>
#include <fmt/core.h>
#include <fmt/ranges.h>

#include <marisa/trie.h>
#include <mecab.h>
#include <nlohmann/json.hpp>
Expand Down
19 changes: 19 additions & 0 deletions src/util.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,25 @@ class runtime_error : public std::runtime_error
public:
runtime_error(std::string_view const what) : std::runtime_error(std::string{ what }) {}
};


template <typename... Args>
void print(std::string_view format, const Args&... args) {
std::string result;
result = std::vformat(format, std::make_format_args(args...));
std::ios::sync_with_stdio(false);
std::cout << result;
}

template <typename... Args>
void println(std::string_view format, const Args&... args) {
std::string result;
result = std::vformat(format, std::make_format_args(args...));
std::ios::sync_with_stdio(false);
std::cout << result << '\n';
}


} // namespace gd

inline void raise_if(bool expr, std::string_view const message = "Invalid argument.")
Expand Down
Loading

0 comments on commit 80696e5

Please sign in to comment.