stuff-from-scratch/apps/website-generator/MarkdownContentParser.cpp

89 lines
2.2 KiB
C++
Raw Normal View History

2022-10-09 16:39:46 +00:00
#include "MarkdownContentParser.h"
#include "MarkdownParser.h"
#include "MarkdownDocument.h"
#include "MarkdownElement.h"
2022-12-07 11:34:29 +00:00
#include "MarkdownCustomElement.h"
#include "File.h"
std::pair<MarkdownContentParser::FileMetadata, std::unique_ptr<MarkdownDocument>> MarkdownContentParser::run(const Path& path)
2022-10-09 16:39:46 +00:00
{
FileMetadata metadata;
FileMetadata output_metadata;
2022-10-09 16:39:46 +00:00
const auto lines = File(path).readLines();
bool metadata_finished = false;
std::string content_body;
2022-10-09 16:39:46 +00:00
for (const auto& line : lines)
{
if (!metadata_finished)
{
const auto metadata = checkForMetadataItem(line);
if (!metadata)
{
metadata_finished = true;
content_body += line + '\n';
2022-10-09 16:39:46 +00:00
}
else
{
output_metadata[metadata->first] = metadata->second;
2022-10-09 16:39:46 +00:00
}
}
else
{
content_body += line + '\n';
2022-10-09 16:39:46 +00:00
}
}
MarkdownParser md_parser;
2022-10-09 16:39:46 +00:00
2022-12-07 11:34:29 +00:00
auto document = std::make_unique<MarkdownDocument>();
auto custom_math_inline = std::make_unique<MarkdownCustomInlineElementContext>("$");
custom_math_inline->setReplacementDelimiters("\\(", "\\)");
auto custom_math_multiline = std::make_unique<MarkdownCustomMultilineElementContext>("$$");
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)};
2022-10-09 16:39:46 +00:00
}
std::optional<MarkdownContentParser::FileMetadataItem> 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;
}
}