Skip to content

Commit 68598ab

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 68598ab

19 files changed

+266
-150
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: 12 additions & 5 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 {
@@ -221,6 +222,8 @@ void generate_function(const FunctionElement& element,
221222
u32 overload_set, const Options& options) noexcept {
222223
if (element.hidden()) return;
223224

225+
ParseMarkdownPageState page_state;
226+
224227
const std::filesystem::path path = construct_html_file_path_for_function(
225228
options.output_root, element, overload_set);
226229
std::filesystem::create_directories(path.parent_path());
@@ -331,13 +334,14 @@ void generate_function(const FunctionElement& element,
331334
auto desc_div = section_div.open_div();
332335
desc_div.add_class("description");
333336
desc_div.add_class("long");
334-
desc_div.write_html(element.comment.full());
337+
desc_div.write_html(element.comment.parsed_full(page_state).unwrap());
335338
}
336339
}
337340

338341
void generate_function_reference(HtmlWriter::OpenUl& items_list,
339342
const FunctionElement& element,
340-
u32 overload_set) noexcept {
343+
u32 overload_set,
344+
ParseMarkdownPageState& page_state) noexcept {
341345
auto item_li = items_list.open_li();
342346
item_li.add_class("section-item");
343347

@@ -356,13 +360,15 @@ void generate_function_reference(HtmlWriter::OpenUl& items_list,
356360
auto desc_div = item_li.open_div();
357361
desc_div.add_class("description");
358362
desc_div.add_class("short");
359-
if (element.has_comment()) desc_div.write_html(element.comment.summary());
363+
if (element.has_comment())
364+
desc_div.write_html(element.comment.parsed_summary(page_state).unwrap());
360365
}
361366
}
362367

363368
void generate_function_long_reference(HtmlWriter::OpenDiv& item_div,
364369
const FunctionElement& element,
365-
u32 overload_set) noexcept {
370+
u32 overload_set,
371+
ParseMarkdownPageState& page_state) noexcept {
366372
{
367373
auto overload_set_div = item_div.open_div();
368374
overload_set_div.add_class("overload-set");
@@ -374,7 +380,8 @@ void generate_function_long_reference(HtmlWriter::OpenDiv& item_div,
374380
auto desc_div = item_div.open_div();
375381
desc_div.add_class("description");
376382
desc_div.add_class("long");
377-
if (element.has_comment()) desc_div.write_html(element.comment.full());
383+
if (element.has_comment())
384+
desc_div.write_html(element.comment.parsed_full(page_state).unwrap());
378385
}
379386
}
380387

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

subdoc/lib/gen/generate_namespace.cc

Lines changed: 37 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "subdoc/lib/gen/generate_head.h"
2323
#include "subdoc/lib/gen/generate_record.h"
2424
#include "subdoc/lib/gen/html_writer.h"
25+
#include "subdoc/lib/parse_comment.h"
2526
#include "sus/assertions/unreachable.h"
2627
#include "sus/collections/slice.h"
2728
#include "sus/prelude.h"
@@ -62,10 +63,11 @@ std::string namespace_display_name(
6263
return sus::move(out).str();
6364
}
6465

65-
void generate_namespace_overview(
66-
HtmlWriter::OpenDiv& namespace_div, const NamespaceElement& element,
67-
sus::Slice<const NamespaceElement*> ancestors,
68-
const Options& options) {
66+
void generate_namespace_overview(HtmlWriter::OpenDiv& namespace_div,
67+
const NamespaceElement& element,
68+
sus::Slice<const NamespaceElement*> ancestors,
69+
ParseMarkdownPageState& page_state,
70+
const Options& options) {
6971
auto section_div = namespace_div.open_div();
7072
section_div.add_class("section");
7173
section_div.add_class("overview");
@@ -109,13 +111,15 @@ void generate_namespace_overview(
109111
auto desc_div = section_div.open_div();
110112
desc_div.add_class("description");
111113
desc_div.add_class("long");
112-
if (element.has_comment()) desc_div.write_html(element.comment.full());
114+
if (element.has_comment())
115+
desc_div.write_html(element.comment.parsed_full(page_state).unwrap());
113116
}
114117
}
115118

116-
void generate_namespace_references(
117-
HtmlWriter::OpenDiv& namespace_div, const NamespaceElement& element,
118-
sus::Slice<SortedNamespaceByName> namespaces) {
119+
void generate_namespace_references(HtmlWriter::OpenDiv& namespace_div,
120+
const NamespaceElement& element,
121+
sus::Slice<SortedNamespaceByName> namespaces,
122+
ParseMarkdownPageState& page_state) {
119123
if (namespaces.is_empty()) return;
120124

121125
auto section_div = namespace_div.open_div();
@@ -137,7 +141,8 @@ void generate_namespace_references(
137141
auto item_li = items_list.open_li();
138142
item_li.add_class("section-item");
139143

140-
generate_namespace_reference(item_li, element.namespaces.at(id));
144+
generate_namespace_reference(item_li, element.namespaces.at(id),
145+
page_state);
141146
}
142147

143148
{
@@ -161,7 +166,8 @@ void generate_namespace_references(
161166
item_li.add_class("nested");
162167
item_li.add_class("section-item");
163168
generate_namespace_reference(
164-
item_li, element.namespaces.at(id).namespaces.at(sub_id));
169+
item_li, element.namespaces.at(id).namespaces.at(sub_id),
170+
page_state);
165171
}
166172
}
167173
}
@@ -171,7 +177,8 @@ void generate_namespace_references(
171177
void generate_record_references(HtmlWriter::OpenDiv& namespace_div,
172178
const NamespaceElement& element,
173179
sus::Slice<SortedRecordByName> records,
174-
RecordType record_type) {
180+
RecordType record_type,
181+
ParseMarkdownPageState& page_state) {
175182
if (records.is_empty()) return;
176183

177184
auto section_div = namespace_div.open_div();
@@ -198,7 +205,8 @@ void generate_record_references(HtmlWriter::OpenDiv& namespace_div,
198205
items_list.add_class("item-table");
199206

200207
for (auto&& [name, sort_key, key] : records) {
201-
generate_record_reference(items_list, element.records.at(key));
208+
generate_record_reference(items_list, element.records.at(key),
209+
page_state);
202210
}
203211
}
204212
}
@@ -211,7 +219,8 @@ enum GenerateFunctionType {
211219
void generate_function_references(HtmlWriter::OpenDiv& namespace_div,
212220
const NamespaceElement& element,
213221
sus::Slice<SortedFunctionByName> functions,
214-
GenerateFunctionType type) {
222+
GenerateFunctionType type,
223+
ParseMarkdownPageState& page_state) {
215224
if (functions.is_empty()) return;
216225

217226
auto section_div = namespace_div.open_div();
@@ -240,7 +249,7 @@ void generate_function_references(HtmlWriter::OpenDiv& namespace_div,
240249
overload_set = 0u;
241250
prev_name = name;
242251
generate_function_reference(items_list, element.functions.at(function_id),
243-
overload_set);
252+
overload_set, page_state);
244253
}
245254
}
246255
}
@@ -253,6 +262,8 @@ void generate_namespace(const NamespaceElement& element,
253262
if (element.is_empty()) return;
254263
if (element.hidden()) return;
255264

265+
ParseMarkdownPageState page_state;
266+
256267
const std::filesystem::path path =
257268
construct_html_file_path_for_namespace(options.output_root, element);
258269
std::filesystem::create_directories(path.parent_path());
@@ -265,7 +276,8 @@ void generate_namespace(const NamespaceElement& element,
265276

266277
auto namespace_div = body.open_div();
267278
namespace_div.add_class("namespace");
268-
generate_namespace_overview(namespace_div, element, ancestors, options);
279+
generate_namespace_overview(namespace_div, element, ancestors, page_state,
280+
options);
269281

270282
{
271283
sus::Vec<SortedNamespaceByName> sorted;
@@ -282,7 +294,8 @@ void generate_namespace(const NamespaceElement& element,
282294
return a.at<1>() <=> b.at<1>();
283295
});
284296

285-
generate_namespace_references(namespace_div, element, sorted.as_slice());
297+
generate_namespace_references(namespace_div, element, sorted.as_slice(),
298+
page_state);
286299
}
287300

288301
{
@@ -315,9 +328,9 @@ void generate_namespace(const NamespaceElement& element,
315328
});
316329

317330
generate_record_references(namespace_div, element, classes.as_slice(),
318-
RecordType::Class);
331+
RecordType::Class, page_state);
319332
generate_record_references(namespace_div, element, unions.as_slice(),
320-
RecordType::Union);
333+
RecordType::Union, page_state);
321334
}
322335

323336
{
@@ -347,9 +360,9 @@ void generate_namespace(const NamespaceElement& element,
347360
return a.at<1>() <=> b.at<1>();
348361
});
349362
generate_function_references(namespace_div, element, sorted_functions,
350-
GenerateFunctions);
363+
GenerateFunctions, page_state);
351364
generate_function_references(namespace_div, element, sorted_operators,
352-
GenerateOperators);
365+
GenerateOperators, page_state);
353366
}
354367

355368
// Recurse into namespaces, records and functions.
@@ -390,7 +403,8 @@ void generate_namespace(const NamespaceElement& element,
390403
}
391404

392405
void generate_namespace_reference(HtmlWriter::OpenLi& open_li,
393-
const NamespaceElement& element) noexcept {
406+
const NamespaceElement& element,
407+
ParseMarkdownPageState& page_state) noexcept {
394408
{
395409
auto item_div = open_li.open_div();
396410
item_div.add_class("item-name");
@@ -412,7 +426,8 @@ void generate_namespace_reference(HtmlWriter::OpenLi& open_li,
412426
auto desc_div = open_li.open_div();
413427
desc_div.add_class("description");
414428
desc_div.add_class("short");
415-
if (element.has_comment()) desc_div.write_html(element.comment.summary());
429+
if (element.has_comment())
430+
desc_div.write_html(element.comment.parsed_summary(page_state).unwrap());
416431
}
417432
}
418433

subdoc/lib/gen/generate_namespace.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ void generate_namespace(const NamespaceElement& element,
2525
const Options& options) noexcept;
2626

2727
void generate_namespace_reference(HtmlWriter::OpenLi& li,
28-
const NamespaceElement& element) noexcept;
28+
const NamespaceElement& element,
29+
ParseMarkdownPageState& page_state) noexcept;
2930

3031
} // namespace subdoc::gen

0 commit comments

Comments
 (0)