Linkparser: Use callbacks, so app can influence how the HTML gets rendered exactly

In particular, this allows making dynamic decisions: Some links may
for example require a different CSS class or so, therefore a static
hardcoded template is not enough for those cases.
This commit is contained in:
Albert S. 2021-04-18 12:24:28 +02:00
parent 8ac353a9d7
commit e0e0db80d5
2 changed files with 52 additions and 3 deletions

View File

@ -0,0 +1,36 @@
/*
* This project is licensed under the MIT license. For more information see the
* LICENSE file.
*/
#pragma once
#include <string>
#include <regex>
#include <functional>
namespace maddy {
inline std::string regex_callback_replacer(std::regex &regex, const std::string &input,
std::function<std::string(std::smatch &)> &callback)
{
std::string result;
auto tagsbegin = std::sregex_iterator(input.begin(), input.end(), regex);
auto tagsend = std::sregex_iterator();
auto matchbegin = 0;
for(std::sregex_iterator i = tagsbegin; i != tagsend; ++i)
{
std::smatch match = *i;
auto matchlength = match.length(0);
auto matchpos = match.position();
result += input.substr(matchbegin, matchpos - matchbegin);
result += callback(match);
matchbegin = matchpos + matchlength;
}
result += input.substr(matchbegin);
return result;
}
}

View File

@ -10,6 +10,7 @@
#include <regex>
#include "maddy/lineparser.h"
#include "maddy/callbackreplacer.h"
// -----------------------------------------------------------------------------
@ -26,6 +27,16 @@ namespace maddy {
*/
class LinkParser : public LineParser
{
private:
std::function<std::string(std::smatch &)> callback = [](std::smatch & match){
std::string inner = match.str(1);
std::string link = match.str(2);
return "<a href=\"" + link + "\">" + inner + "</a>";
};
std::regex re = std::regex("\\[([^\\]]*)\\]\\(([^\\]]*)\\)");
public:
/**
* Parse
@ -41,10 +52,12 @@ public:
void
Parse(std::string& line) override
{
static std::regex re("\\[([^\\]]*)\\]\\(([^\\]]*)\\)");
static std::string replacement = "<a href=\"$2\">$1</a>";
line = regex_callback_replacer(re,line,callback);
}
line = std::regex_replace(line, re, replacement);
void setCallback(std::function<std::string(std::smatch &)> callback)
{
this->callback = callback;
}
}; // class LinkParser