#include "convertmarkdown.h" #include #include #include #include static bool markdown_needs_escape (char ch) { switch (ch) { case '\\': case '`': case '*': case '_': case '[': case ']': case '<': case '>': case '#': case '!': case '|': return true; default: return false; } } static std::string markdown_escape (const std::string &s) { std::string out; out.reserve (s.size() + s.size() / 8); for (char ch : s) { if (markdown_needs_escape (ch)) out.push_back ('\\'); out.push_back (ch); } return out; } bool ConverterMarkdown::save (const std::string &output_file_name) { if (!parse()) return false; std::ofstream output (output_file_name, std::ios::trunc); if (!output.is_open()) { std::cerr << "Failed to open output file: " << output_file_name << " (" << std::strerror (errno) << ")\n"; set_error_code (3); return false; } const auto &book_titles = titles(); for (std::size_t i = 0; i < book_titles.size(); ++i) { const auto &title = book_titles[i]; output << "# " << markdown_escape (title) << "\n\n"; for (std::size_t quote_index = 0; quote_index < quote_count (title); ++quote_index) { output << "## " << markdown_escape (quote_meta (title, quote_index)) << "\n\n"; const auto &text_lines = quote_text_lines (title, quote_index); std::size_t line_index = 0; if (!text_lines.empty() && text_lines.front().empty()) line_index = 1; for (; line_index < text_lines.size(); ++line_index) { if (text_lines[line_index].empty()) output << ">\n"; else output << "> " << markdown_escape (text_lines[line_index]) << '\n'; } output << "\n### Notes\n\n"; } } set_error_code (0); return true; }