82 if (!spans.is_array()) {
83 qWarning(
"render_signature_spans: expected JSON array, got %s",
88 const bool isMarkdown = format.contains(
"markdown"_L1, Qt::CaseInsensitive);
91 for (
const auto &s : spans) {
93 result += renderSpanMarkdown(s);
96 const auto role = s.value(
"role",
"");
97 const auto text = s.value(
"text",
"");
98 const bool hasHref = s.contains(
"href");
99 const auto href = s.value(
"href",
"");
101 if (role ==
"extra") {
102 result += R"(<code class="details extra" translate="no">)";
103 if (s.contains(
"children") && s[
"children"].is_array()) {
104 for (
const auto &c : s[
"children"]) {
105 if (c.value(
"role",
"") ==
"external-ref")
106 result +=
"<a href=\"" + c.value(
"href",
"") +
"\">"
107 + escapeHtml(c.value(
"text",
"")) +
"</a>";
109 result += escapeHtml(c.value(
"text",
""));
112 result += escapeHtml(text);
115 }
else if (role ==
"type") {
116 result += R"(<span class="type">)";
118 result +=
"<a href=\"" + href +
"\">";
119 result += escapeHtml(text);
123 }
else if (role ==
"name") {
124 result += R"(<span class="name">)";
126 result +=
"<a href=\"" + href +
"\">";
127 result += escapeHtml(text);
131 }
else if (role ==
"parameter") {
132 result +=
"<i>" + escapeHtml(text) +
"</i>";
133 }
else if (role ==
"external-ref") {
134 result +=
"<a href=\"" + href +
"\">" + escapeHtml(text) +
"</a>";
135 }
else if (role ==
"template-decl") {
136 result += R"(<span class="template-decl">)";
137 result += escapeHtml(text);
138 if (s.contains(
"children") && s[
"children"].is_array()) {
139 for (
const auto &c : s[
"children"]) {
140 const auto childRole = c.value(
"role",
"");
141 const auto childText = c.value(
"text",
"");
142 const bool childHasHref = c.contains(
"href");
143 const auto childHref = c.value(
"href",
"");
144 if (childRole ==
"type") {
145 result += R"(<span class="type">)" + escapeHtml(childText)
147 }
else if (childRole ==
"link") {
148 result += renderLinkSpan(childText, childHref, childHasHref, isMarkdown);
150 result += escapeHtml(childText);
155 }
else if (role ==
"link") {
156 result += renderLinkSpan(text, href, hasHref, isMarkdown);
158 result += escapeHtml(text);
166 env.add_callback(
"escape_html", 1, [](inja::Arguments &args) {
167 return escapeHtml(args.at(0)->get<std::string>());
170 env.add_callback(
"render_signature_spans", 1, [format](inja::Arguments &args) {
171 return renderSignatureSpans(*args.at(0), format);
181 env.add_callback(
"list_separator", 2, [](inja::Arguments &args) {
182 const auto pos = args.at(0)->get<qsizetype>();
183 const auto total = args.at(1)->get<qsizetype>();
184 return TextUtils::separator(pos, total).toStdString();
187 env.add_callback(
"escape_md_table", 1, [](inja::Arguments &args) {
188 auto input = args.at(0)->get<std::string>();
190 buffer.reserve(input.size() + input.size() / 8);
191 for (
char c : input) {
215 env.add_callback(
"is_odd", 1, [](inja::Arguments &args) {
216 return args.at(0)->get<qsizetype>() % 2 != 0;
303nlohmann::json InjaBridge::toInjaJson(
const QJsonObject &obj)
305 nlohmann::json result = nlohmann::json::object();
307 for (
const auto &[key, value] : obj.asKeyValueRange())
308 result[key.toString().toUtf8().toStdString()] = toInjaJson(value);
342QString InjaBridge::render(
const QString &templateStr,
const QJsonObject &data,
343 const QString &format)
345 inja::Environment env;
350 env.set_line_statement(
"%!");
351 env.set_trim_blocks(
true);
352 env.set_lstrip_blocks(
true);
353 registerCallbacks(env, format);
354 nlohmann::json jsonData = toInjaJson(data);
356 std::string templateUtf8 = templateStr.toUtf8().toStdString();
357 std::string resultUtf8 = env.render(templateUtf8, jsonData);
359 return QString::fromUtf8(resultUtf8.c_str());
377QString InjaBridge::render(
const QString &templateStr,
const QJsonObject &data,
378 const IncludeCallback &includeCallback,
379 const QString &format)
381 inja::Environment env;
382 env.set_line_statement(
"%!");
383 env.set_trim_blocks(
true);
384 env.set_lstrip_blocks(
true);
385 registerCallbacks(env, format);
386 env.set_search_included_templates_in_files(
false);
387 env.set_include_callback(
388 [&includeCallback, &env](
const std::filesystem::path & ,
389 const std::string &name) -> inja::Template {
390 QString content = includeCallback(QString::fromStdString(name));
391 if (content.isEmpty()) {
393 inja::FileError(
"include not found: '" + name +
"'"));
395 return env.parse(content.toUtf8().toStdString());
398 nlohmann::json jsonData = toInjaJson(data);
399 std::string templateUtf8 = templateStr.toUtf8().toStdString();
400 std::string resultUtf8 = env.render(templateUtf8, jsonData);
402 return QString::fromUtf8(resultUtf8.c_str());
414QString InjaBridge::renderFile(
const QString &templatePath,
const QJsonObject &data,
415 const QString &format)
417 inja::Environment env;
418 env.set_line_statement(
"%!");
419 env.set_trim_blocks(
true);
420 env.set_lstrip_blocks(
true);
421 registerCallbacks(env, format);
422 nlohmann::json jsonData = toInjaJson(data);
424 std::string pathUtf8 = templatePath.toUtf8().toStdString();
425 std::string resultUtf8 = env.render_file(pathUtf8, jsonData);
427 return QString::fromUtf8(resultUtf8.c_str());