Skip to content

Commit 4326dc7

Browse files
authored
fix: headings with ids get escaped by comrak (#117)
* fix: headings with ids get escaped by comrak * format.rs: add comments * format.rs: fixup
1 parent ff2d5fd commit 4326dc7

8 files changed

+67
-8
lines changed

CHANGELOG.md

+8
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
11
# Changelog
22

3+
## Version 3.0.4
4+
5+
Fixes: issue with headings ids introduced with 3.0.3
6+
7+
by @hsjobeki;
8+
9+
in https://github.com/nix-community/nixdoc/pull/117.
10+
311
## Version 3.0.3
412

513
Fixes: shifting issue with commonmark headings https://github.com/nix-community/nixdoc/issues/113

Cargo.lock

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "nixdoc"
3-
version = "3.0.3"
3+
version = "3.0.4"
44
authors = ["Vincent Ambo <mail@tazj.in>", "asymmetric"]
55
edition = "2021"
66
description = "Generate CommonMark from Nix library functions"

src/format.rs

+49-6
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,53 @@
11
use comrak::{
2+
format_commonmark,
23
nodes::{AstNode, NodeValue},
34
parse_document, Arena, ComrakOptions, Options,
45
};
5-
use textwrap::dedent;
6+
use std::io::Write;
7+
use textwrap::dedent; // For using the write! macro
8+
9+
// Your custom renderer
10+
struct CustomRenderer<'a> {
11+
options: &'a ComrakOptions,
12+
}
13+
14+
impl<'a> CustomRenderer<'a> {
15+
fn new(options: &'a ComrakOptions) -> Self {
16+
CustomRenderer { options }
17+
}
18+
19+
fn format_node(&self, root: &'a AstNode<'a>, buffer: &mut Vec<u8>) {
20+
for node in root.children() {
21+
match &node.data.borrow().value {
22+
NodeValue::Heading(heading) => {
23+
// Handling headings specifically.
24+
write!(buffer, "{} ", "#".repeat(heading.level as usize)).expect(
25+
"Failed to write UTF-8. Make sure files contains only valid UTF-8.",
26+
);
27+
28+
// Handle the children of the heading node
29+
// Headings have only one child: NodeValue::Text
30+
if let Some(child) = node.first_child() {
31+
if let NodeValue::Text(ref text) = child.data.borrow().value {
32+
writeln!(buffer, "{}", text).expect(
33+
"Failed to write UTF-8. Make sure files contains only valid UTF-8.",
34+
);
35+
};
36+
}
37+
}
38+
// Handle other node types using comrak's default behavior
39+
_ => {
40+
format_commonmark(node, self.options, buffer)
41+
.expect("Failed to format markdown using the default comrak formatter.");
42+
}
43+
};
44+
45+
// Insert a newline after each node
46+
// This behavior is the same as the default comrak-formatter behavior.
47+
buffer.push(b'\n');
48+
}
49+
}
50+
}
651

752
/// Ensure all lines in a multi-line doc-comments have the same indentation.
853
///
@@ -79,13 +124,11 @@ pub fn shift_headings(raw: &str, levels: u8) -> String {
79124
increase_heading_levels(root, levels);
80125

81126
let mut markdown_output = vec![];
127+
let renderer = CustomRenderer::new(&options);
128+
renderer.format_node(root, &mut markdown_output);
82129

83-
// This could only fail if we transform the AST in a way that is not supported by the markdown renderer.
84-
// Since the AST stems from comrak itself, this should never happen.
85-
comrak::format_commonmark(root, &options, &mut markdown_output)
86-
.expect("Failed to format markdown");
87130
// We can safely assume that the output is valid UTF-8, since comrak uses rust strings which are valid UTF-8.
88-
String::from_utf8(markdown_output).unwrap()
131+
String::from_utf8(markdown_output).expect("Markdown contains invalid UTF-8")
89132
}
90133

91134
// Internal function to operate on the markdown AST

src/snapshots/nixdoc__test__doc_comment.snap

+1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ This is a parsed example
2121
doc comment in markdown format
2222

2323

24+
2425
## `lib.debug.foo` {#function-library-lib.debug.foo}
2526

2627
Comment

src/snapshots/nixdoc__test__doc_comment_no_duplicate_arguments.snap

+3
Original file line numberDiff line numberDiff line change
@@ -19,17 +19,20 @@ nixdoc comment
1919
Doc-comment
2020

2121

22+
2223
## `lib.debug.multiple` {#function-library-lib.debug.multiple}
2324

2425
Doc-comment
2526

2627

28+
2729
## `lib.debug.argumentTest` {#function-library-lib.debug.argumentTest}
2830

2931
Doc-comment before the lamdba causes the whole
3032
lambda including its arguments to switch to doc-comments ONLY rendering
3133

3234

35+
3336
## `lib.debug.legacyArgumentTest` {#function-library-lib.debug.legacyArgumentTest}
3437

3538
Legacy comments allow to use any

src/snapshots/nixdoc__test__headings.snap

+2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ expression: output
66

77
#### h2-heading
88

9+
#### h2-heading-with-id {#some-id}
10+
911
##### h3-heading
1012

1113
``` nix

test/headings.md

+2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
## h2-heading
44

5+
## h2-heading-with-id {#some-id}
6+
57
### h3-heading
68

79
```nix

0 commit comments

Comments
 (0)