Skip to content

Commit 78de5cd

Browse files
committed
Turn Markdown headers into named anchors that link to themselves
We formed md4c to add the functionality into the parser, so point the git submodule to that fork. The md4c project seems to be unmaintained which is why we did it that way. mity/md4c#192 Then move markdown parsing to the generate step so that we can track repeated self links per-page and increment a counter on each one to make them unique. Add missing Result::and_then() to support this use of Result. It still needs tests (and the Copy overload).
1 parent c922b5e commit 78de5cd

19 files changed

+296
-182
lines changed

.gitmodules

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,4 @@
1212
url = https://github.com/martinus/nanobench
1313
[submodule "third_party/md4c"]
1414
path = third_party/md4c
15-
url = https://github.com/mity/md4c
15+
url = https://github.com/danakj/md4c

subdoc/lib/database.h

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "subdoc/lib/doc_attributes.h"
2020
#include "subdoc/lib/friendly_names.h"
2121
#include "subdoc/lib/method_qualifier.h"
22+
#include "subdoc/lib/parse_comment.h"
2223
#include "subdoc/lib/path.h"
2324
#include "subdoc/lib/record_type.h"
2425
#include "subdoc/lib/requires.h"
@@ -35,30 +36,33 @@ namespace subdoc {
3536

3637
struct Comment {
3738
Comment() = default;
38-
Comment(std::string full_html, std::string summary_html,
39-
std::string begin_loc, DocAttributes attrs)
40-
: full_html(sus::move(full_html)),
41-
summary_html(sus::move(summary_html)),
39+
Comment(std::string text, std::string begin_loc, DocAttributes attrs)
40+
: text(sus::move(text)),
4241
begin_loc(sus::move(begin_loc)),
4342
attrs(sus::move(attrs)) {}
4443

45-
std::string full_html;
46-
std::string summary_html;
44+
std::string text;
4745
std::string begin_loc;
4846
DocAttributes attrs;
4947

5048
void inherit_from(const Comment& source) {
51-
full_html = sus::clone(source.full_html);
52-
summary_html = sus::clone(source.summary_html);
49+
text = sus::clone(source.text);
5350
attrs = sus::clone(source.attrs);
5451
// location is not modified.
5552
}
5653

57-
std::string_view summary() const& { return summary_html; }
58-
std::string_view summary() && = delete;
59-
60-
std::string_view full() const& { return full_html; }
61-
std::string_view full() && = delete;
54+
sus::Result<std::string, ParseCommentError> parsed_full(
55+
ParseMarkdownPageState& page_state) const noexcept {
56+
return parse_comment_markdown_to_html(text, page_state);
57+
}
58+
sus::Result<std::string, ParseCommentError> parsed_summary(
59+
ParseMarkdownPageState& page_state) const noexcept {
60+
return parse_comment_markdown_to_html(text, page_state)
61+
.and_then(
62+
[](std::string s) -> sus::Result<std::string, ParseCommentError> {
63+
return sus::ok(summarize_html(sus::move(s)));
64+
});
65+
}
6266
};
6367

6468
struct CommentElement {
@@ -78,7 +82,7 @@ struct CommentElement {
7882
u32 sort_key;
7983

8084
bool has_comment() const {
81-
return !comment.full_html.empty() || comment.attrs.inherit.is_some() ||
85+
return !comment.text.empty() || comment.attrs.inherit.is_some() ||
8286
comment.attrs.hidden;
8387
}
8488
bool hidden() const { return comment.attrs.hidden; }

subdoc/lib/gen/generate_function.cc

Lines changed: 42 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "subdoc/lib/gen/generate_requires.h"
2424
#include "subdoc/lib/gen/html_writer.h"
2525
#include "subdoc/lib/gen/options.h"
26+
#include "subdoc/lib/parse_comment.h"
2627
#include "sus/prelude.h"
2728

2829
namespace subdoc::gen {
@@ -36,26 +37,26 @@ enum Style {
3637

3738
void generate_return_type(HtmlWriter::OpenDiv& div,
3839
const FunctionOverload& overload) noexcept {
39-
{
40+
if (overload.return_type_element.is_some()) {
4041
auto return_type_link = div.open_a();
4142
return_type_link.add_class("type-name");
4243
return_type_link.add_title(overload.return_type_name);
43-
if (overload.return_type_element.is_some()) {
44-
if (!overload.return_type_element->hidden()) {
45-
return_type_link.add_href(
46-
construct_html_file_path(
47-
std::filesystem::path(),
48-
overload.return_type_element->namespace_path.as_slice(),
49-
overload.return_type_element->record_path.as_slice(),
50-
overload.return_type_element->name)
51-
.string());
52-
} else {
53-
llvm::errs() << "WARNING: Reference to hidden TypeElement "
54-
<< overload.return_type_element->name << " in namespace "
55-
<< overload.return_type_element->namespace_path;
56-
}
44+
if (!overload.return_type_element->hidden()) {
45+
return_type_link.add_href(
46+
construct_html_file_path(
47+
std::filesystem::path(),
48+
overload.return_type_element->namespace_path.as_slice(),
49+
overload.return_type_element->record_path.as_slice(),
50+
overload.return_type_element->name)
51+
.string());
52+
} else {
53+
llvm::errs() << "WARNING: Reference to hidden TypeElement "
54+
<< overload.return_type_element->name << " in namespace "
55+
<< overload.return_type_element->namespace_path;
5756
}
5857
return_type_link.write_text(overload.return_short_type_name);
58+
} else {
59+
div.write_text(overload.return_short_type_name);
5960
}
6061
}
6162

@@ -66,26 +67,25 @@ void generate_function_params(HtmlWriter::OpenDiv& div,
6667
for (const auto& [i, p] : overload.parameters.iter().enumerate()) {
6768
if (i > 0u) div.write_text(", ");
6869

69-
{
70+
if (p.type_element.is_some()) {
7071
auto one_param_link = div.open_a();
7172
one_param_link.add_class("type-name");
7273
one_param_link.add_title(p.type_name);
73-
if (p.type_element.is_some()) {
74-
if (!p.type_element->hidden()) {
75-
one_param_link.add_href(
76-
construct_html_file_path(
77-
std::filesystem::path(),
78-
p.type_element->namespace_path.as_slice(),
79-
p.type_element->record_path.as_slice(),
80-
p.type_element->name)
81-
.string());
82-
} else {
83-
llvm::errs() << "WARNING: Reference to hidden TypeElement "
84-
<< p.type_element->name << " in namespace "
85-
<< p.type_element->namespace_path;
86-
}
74+
if (!p.type_element->hidden()) {
75+
one_param_link.add_href(construct_html_file_path(
76+
std::filesystem::path(),
77+
p.type_element->namespace_path.as_slice(),
78+
p.type_element->record_path.as_slice(),
79+
p.type_element->name)
80+
.string());
81+
} else {
82+
llvm::errs() << "WARNING: Reference to hidden TypeElement "
83+
<< p.type_element->name << " in namespace "
84+
<< p.type_element->namespace_path;
8785
}
8886
one_param_link.write_text(p.short_type_name);
87+
} else {
88+
div.write_text(p.short_type_name);
8989
}
9090

9191
if (!p.parameter_name.empty()) {
@@ -221,6 +221,8 @@ void generate_function(const FunctionElement& element,
221221
u32 overload_set, const Options& options) noexcept {
222222
if (element.hidden()) return;
223223

224+
ParseMarkdownPageState page_state;
225+
224226
const std::filesystem::path path = construct_html_file_path_for_function(
225227
options.output_root, element, overload_set);
226228
std::filesystem::create_directories(path.parent_path());
@@ -331,13 +333,14 @@ void generate_function(const FunctionElement& element,
331333
auto desc_div = section_div.open_div();
332334
desc_div.add_class("description");
333335
desc_div.add_class("long");
334-
desc_div.write_html(element.comment.full());
336+
desc_div.write_html(element.comment.parsed_full(page_state).unwrap());
335337
}
336338
}
337339

338340
void generate_function_reference(HtmlWriter::OpenUl& items_list,
339341
const FunctionElement& element,
340-
u32 overload_set) noexcept {
342+
u32 overload_set,
343+
ParseMarkdownPageState& page_state) noexcept {
341344
auto item_li = items_list.open_li();
342345
item_li.add_class("section-item");
343346

@@ -356,13 +359,14 @@ void generate_function_reference(HtmlWriter::OpenUl& items_list,
356359
auto desc_div = item_li.open_div();
357360
desc_div.add_class("description");
358361
desc_div.add_class("short");
359-
if (element.has_comment()) desc_div.write_html(element.comment.summary());
362+
if (element.has_comment())
363+
desc_div.write_html(element.comment.parsed_summary(page_state).unwrap());
360364
}
361365
}
362366

363-
void generate_function_long_reference(HtmlWriter::OpenDiv& item_div,
364-
const FunctionElement& element,
365-
u32 overload_set) noexcept {
367+
void generate_function_long_reference(
368+
HtmlWriter::OpenDiv& item_div, const FunctionElement& element,
369+
u32 overload_set, ParseMarkdownPageState& page_state) noexcept {
366370
{
367371
auto overload_set_div = item_div.open_div();
368372
overload_set_div.add_class("overload-set");
@@ -374,7 +378,8 @@ void generate_function_long_reference(HtmlWriter::OpenDiv& item_div,
374378
auto desc_div = item_div.open_div();
375379
desc_div.add_class("description");
376380
desc_div.add_class("long");
377-
if (element.has_comment()) desc_div.write_html(element.comment.full());
381+
if (element.has_comment())
382+
desc_div.write_html(element.comment.parsed_full(page_state).unwrap());
378383
}
379384
}
380385

subdoc/lib/gen/generate_function.h

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "subdoc/lib/database.h"
1818
#include "subdoc/lib/gen/html_writer.h"
1919
#include "subdoc/lib/gen/options.h"
20+
#include "subdoc/lib/parse_comment.h"
2021

2122
namespace subdoc::gen {
2223

@@ -25,11 +26,11 @@ void generate_function(const FunctionElement& e,
2526
u32 overload_set, const Options& options) noexcept;
2627

2728
void generate_function_reference(HtmlWriter::OpenUl& items_list,
28-
const FunctionElement& e,
29-
u32 overload_set) noexcept;
29+
const FunctionElement& e, u32 overload_set,
30+
ParseMarkdownPageState& page_state) noexcept;
3031

31-
void generate_function_long_reference(HtmlWriter::OpenDiv& items_list,
32-
const FunctionElement& e,
33-
u32 overload_set) noexcept;
32+
void generate_function_long_reference(
33+
HtmlWriter::OpenDiv& items_list, const FunctionElement& e, u32 overload_set,
34+
ParseMarkdownPageState& page_state) noexcept;
3435

3536
} // namespace subdoc::gen

0 commit comments

Comments
 (0)