#include "MarkdownContentParser.h" #include "MarkdownParser.h" #include "MarkdownDocument.h" #include "MarkdownElement.h" #include "MarkdownCustomElement.h" #include "File.h" std::pair> MarkdownContentParser::run(const Path& path) { FileMetadata metadata; FileMetadata output_metadata; const auto lines = File(path).readLines(); bool metadata_finished = false; std::string content_body; for (const auto& line : lines) { if (!metadata_finished) { const auto metadata = checkForMetadataItem(line); if (!metadata) { metadata_finished = true; content_body += line + '\n'; } else { output_metadata[metadata->first] = metadata->second; } } else { content_body += line + '\n'; } } MarkdownParser md_parser; auto document = std::make_unique(); auto custom_math_inline = std::make_unique("$"); custom_math_inline->setReplacementDelimiters("\\(", "\\)"); auto custom_math_multiline = std::make_unique("$$"); document->registerCustomInlineElement(std::move(custom_math_inline)); document->registerCustomMultilineElement(std::move(custom_math_multiline)); md_parser.run(content_body, document.get()); return {output_metadata, std::move(document)}; } std::optional MarkdownContentParser::checkForMetadataItem(const std::string& line) const { unsigned char_count = 0; std::string prefix; std::string suffix; bool building_prefix = true; for (const auto c : line) { if (c == ':' && char_count > 0 && building_prefix) { building_prefix = false; } else if (building_prefix) { prefix += c; } else { suffix += c; } char_count++; } if (!prefix.empty() && !building_prefix) { return FileMetadataItem{ prefix, suffix }; } else { return std::nullopt; } }