1
0
Fork 0
mirror of https://github.com/KingDuckZ/kamokan.git synced 2025-02-17 09:35:49 +00:00

Refactor code highlighting functions out of PastieResponse.

This commit is contained in:
King_DuckZ 2017-08-03 18:45:53 +01:00
parent c25e8f2e49
commit 1e79a801ba
4 changed files with 93 additions and 76 deletions

View file

@ -17,12 +17,70 @@
#include "highlight_functions.hpp" #include "highlight_functions.hpp"
#include "settings_bag.hpp" #include "settings_bag.hpp"
#include <srchilite/sourcehighlight.h>
#include <srchilite/langmap.h> #include <srchilite/langmap.h>
#include <boost/range/adaptor/map.hpp> #include <boost/range/adaptor/map.hpp>
#include <boost/range/algorithm/copy.hpp> #include <boost/range/algorithm/copy.hpp>
#include <boost/range/iterator_range_core.hpp> #include <boost/range/iterator_range_core.hpp>
#include <sstream>
namespace kamokan { namespace kamokan {
namespace {
std::string highlight_css_path (const SettingsBag& parSettings) {
//TODO: make sure the file exists or throw or do something
return parSettings.as<std::string>("highlight_css");
}
std::string lang_name_to_file_path (const std::string& parLang, const std::string& parLangmapDir) {
if (parLang.empty())
return std::string();
srchilite::LangMap lang_map(parLangmapDir, "lang.map");
lang_map.open();
std::string lang_file = lang_map.getFileName(parLang);
if (lang_file.empty())
lang_file = "default.lang";
return lang_file;
}
SplitHighlightedPastie strip_tags_from_highlighted (std::string parPastie) {
//I'm expecting some comment at the beginning, like:
// <!-- Generator: GNU source-highlight 3.1.8
// by Lorenzo Bettini
// http://www.lorenzobettini.it
// http://www.gnu.org/software/src-highlite -->
SplitHighlightedPastie retval;
{
const auto comment_start = parPastie.find("<!--");
if (parPastie.npos != comment_start) {
const auto comment_len = parPastie.find("-->") - comment_start + 3;
retval.comment = parPastie.substr(comment_start, comment_len);
const std::size_t newline = (comment_len + 1 < parPastie.size() and parPastie[comment_len] == '\n' ? 1 : 0);
parPastie.erase(comment_start, comment_len + newline);
}
}
{
const auto pre_start = parPastie.find("<pre><tt>");
if (parPastie.npos != pre_start) {
parPastie.erase(pre_start, 9);
}
}
{
const auto pre_cl_start = parPastie.find("</tt></pre>");
if (parPastie.npos != pre_cl_start) {
parPastie.erase(pre_cl_start, 11);
}
}
retval.text = std::move(parPastie);
return retval;
}
} //unnamed namespace
HighlightLangList list_highlight_langs (const SettingsBag& parSettings) { HighlightLangList list_highlight_langs (const SettingsBag& parSettings) {
srchilite::LangMap lang_map(parSettings.as<std::string>("langmap_dir"), "lang.map"); srchilite::LangMap lang_map(parSettings.as<std::string>("langmap_dir"), "lang.map");
lang_map.open(); lang_map.open();
@ -30,5 +88,27 @@ namespace kamokan {
const auto lang_range = boost::make_iterator_range(lang_map.begin(), lang_map.end()); const auto lang_range = boost::make_iterator_range(lang_map.begin(), lang_map.end());
return boost::copy_range<HighlightLangList>(lang_range | boost::adaptors::map_keys); return boost::copy_range<HighlightLangList>(lang_range | boost::adaptors::map_keys);
} }
SplitHighlightedPastie highlight_string (std::string&& parIn, const std::string& parLang, const SettingsBag& parSettings) {
const std::string langmap_dir = parSettings.as<std::string>("langmap_dir");
srchilite::SourceHighlight highlighter;
highlighter.setDataDir(langmap_dir);
highlighter.setGenerateEntireDoc(false);
highlighter.setGenerateLineNumbers(true);
#if defined(NDEBUG)
highlighter.setOptimize(true);
#else
highlighter.setOptimize(false);
#endif
highlighter.setCanUseStdOut(false);
highlighter.setTabSpaces(4);
highlighter.setStyleCssFile(highlight_css_path(parSettings));
highlighter.setGenerateLineNumbers(false);
std::istringstream iss(std::move(parIn));
std::ostringstream oss;
highlighter.highlight(iss, oss, lang_name_to_file_path(parLang, langmap_dir));
return strip_tags_from_highlighted(oss.str());
}
} //namespace kamokan } //namespace kamokan

View file

@ -19,10 +19,18 @@
#include <vector> #include <vector>
#include <string> #include <string>
#include <boost/utility/string_view.hpp>
#include <string>
namespace kamokan { namespace kamokan {
class SettingsBag; class SettingsBag;
typedef std::vector<std::string> HighlightLangList; typedef std::vector<std::string> HighlightLangList;
struct SplitHighlightedPastie {
std::string comment;
std::string text;
};
HighlightLangList list_highlight_langs (const SettingsBag& parSettings); HighlightLangList list_highlight_langs (const SettingsBag& parSettings);
SplitHighlightedPastie highlight_string (std::string&& parIn, const std::string& parLang, const SettingsBag& parSettings);
} //namespace kamokan } //namespace kamokan

View file

@ -21,10 +21,8 @@
#include "escapist.hpp" #include "escapist.hpp"
#include "cgi_env.hpp" #include "cgi_env.hpp"
#include "spdlog.hpp" #include "spdlog.hpp"
#include "highlight_functions.hpp"
#include <ciso646> #include <ciso646>
#include <srchilite/sourcehighlight.h>
#include <srchilite/langmap.h>
#include <sstream>
#include <algorithm> #include <algorithm>
#include <cassert> #include <cassert>
#include <boost/algorithm/string/find_iterator.hpp> #include <boost/algorithm/string/find_iterator.hpp>
@ -36,52 +34,6 @@ namespace kamokan {
namespace { namespace {
const char g_nolang_token[] = "colourless"; const char g_nolang_token[] = "colourless";
struct SplitHighlightedPastie {
std::string comment;
std::string text;
};
std::string highlight_css_path (const SettingsBag& parSettings) {
//TODO: make sure the file exists or throw or do something
return parSettings.as<std::string>("highlight_css");
}
SplitHighlightedPastie strip_tags_from_highlighted (std::string parPastie) {
//I'm expecting some comment at the beginning, like:
// <!-- Generator: GNU source-highlight 3.1.8
// by Lorenzo Bettini
// http://www.lorenzobettini.it
// http://www.gnu.org/software/src-highlite -->
SplitHighlightedPastie retval;
{
const auto comment_start = parPastie.find("<!--");
if (parPastie.npos != comment_start) {
const auto comment_len = parPastie.find("-->") - comment_start + 3;
retval.comment = parPastie.substr(comment_start, comment_len);
const std::size_t newline = (comment_len + 1 < parPastie.size() and parPastie[comment_len] == '\n' ? 1 : 0);
parPastie.erase(comment_start, comment_len + newline);
}
}
{
const auto pre_start = parPastie.find("<pre><tt>");
if (parPastie.npos != pre_start) {
parPastie.erase(pre_start, 9);
}
}
{
const auto pre_cl_start = parPastie.find("</tt></pre>");
if (parPastie.npos != pre_cl_start) {
parPastie.erase(pre_cl_start, 11);
}
}
retval.text = std::move(parPastie);
return retval;
}
mstch::array pastie_to_numbered_lines (boost::string_view parPastie) { mstch::array pastie_to_numbered_lines (boost::string_view parPastie) {
using boost::string_view; using boost::string_view;
using string_view_iterator = string_view::const_iterator; using string_view_iterator = string_view::const_iterator;
@ -115,7 +67,6 @@ namespace kamokan {
const Kakoune::SafePtr<cgi::Env>& parCgiEnv const Kakoune::SafePtr<cgi::Env>& parCgiEnv
) : ) :
GeneralPastieResponse(parSettings, parStreamOut, parCgiEnv), GeneralPastieResponse(parSettings, parStreamOut, parCgiEnv),
m_langmap_dir(parSettings->as<std::string>("langmap_dir")),
m_plain_text(false), m_plain_text(false),
m_syntax_highlight(true) m_syntax_highlight(true)
{ {
@ -132,32 +83,14 @@ namespace kamokan {
m_syntax_highlight = false; m_syntax_highlight = false;
} }
else { else {
srchilite::LangMap lang_map(m_langmap_dir, "lang.map"); m_pastie_lang.clear();
lang_map.open();
m_lang_file.clear();
if (not query_str.empty()) if (not query_str.empty())
m_lang_file = lang_map.getFileName(query_str); m_pastie_lang = query_str;
if (m_lang_file.empty())
m_lang_file = "default.lang";
} }
return tawashi::make_header_type_html(); return tawashi::make_header_type_html();
} }
void PastieResponse::on_general_mustache_prepare (std::string&& parPastie, mstch::map& parContext) { void PastieResponse::on_general_mustache_prepare (std::string&& parPastie, mstch::map& parContext) {
srchilite::SourceHighlight highlighter;
highlighter.setDataDir(settings().as<std::string>("langmap_dir"));
highlighter.setGenerateEntireDoc(false);
highlighter.setGenerateLineNumbers(true);
#if defined(NDEBUG)
highlighter.setOptimize(true);
#else
highlighter.setOptimize(false);
#endif
highlighter.setCanUseStdOut(false);
highlighter.setTabSpaces(4);
highlighter.setStyleCssFile(highlight_css_path(settings()));
highlighter.setGenerateLineNumbers(false);
std::string processed_pastie; std::string processed_pastie;
std::string highlight_comment; std::string highlight_comment;
if (m_syntax_highlight) { if (m_syntax_highlight) {
@ -169,10 +102,7 @@ namespace kamokan {
} }
if (not m_plain_text and m_syntax_highlight) { if (not m_plain_text and m_syntax_highlight) {
std::istringstream iss(std::move(processed_pastie)); SplitHighlightedPastie split = highlight_string(std::move(processed_pastie), m_pastie_lang, settings());
std::ostringstream oss;
highlighter.highlight(iss, oss, m_lang_file);
SplitHighlightedPastie split = strip_tags_from_highlighted(oss.str());
processed_pastie = std::move(split.text); processed_pastie = std::move(split.text);
highlight_comment = std::move(split.comment); highlight_comment = std::move(split.comment);
} }

View file

@ -39,8 +39,7 @@ namespace kamokan {
virtual void on_general_mustache_prepare (std::string&& parPastie, mstch::map& parContext) override; virtual void on_general_mustache_prepare (std::string&& parPastie, mstch::map& parContext) override;
virtual bool is_pastie_page() const override { return true; } virtual bool is_pastie_page() const override { return true; }
std::string m_lang_file; std::string m_pastie_lang;
std::string m_langmap_dir;
bool m_plain_text; bool m_plain_text;
bool m_syntax_highlight; bool m_syntax_highlight;
}; };