From 4326dc7a35bb82cf66f49395056c40a61eb44406 Mon Sep 17 00:00:00 2001 From: Johannes Kirschbauer Date: Mon, 15 Apr 2024 17:09:12 +0200 Subject: [PATCH] fix: headings with ids get escaped by comrak (#117) * fix: headings with ids get escaped by comrak * format.rs: add comments * format.rs: fixup --- CHANGELOG.md | 8 +++ Cargo.lock | 2 +- Cargo.toml | 2 +- src/format.rs | 55 +++++++++++++++++-- src/snapshots/nixdoc__test__doc_comment.snap | 1 + ...t__doc_comment_no_duplicate_arguments.snap | 3 + src/snapshots/nixdoc__test__headings.snap | 2 + test/headings.md | 2 + 8 files changed, 67 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8bb1378..f47d107 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## Version 3.0.4 + +Fixes: issue with headings ids introduced with 3.0.3 + +by @hsjobeki; + +in https://github.com/nix-community/nixdoc/pull/117. + ## Version 3.0.3 Fixes: shifting issue with commonmark headings https://github.com/nix-community/nixdoc/issues/113 diff --git a/Cargo.lock b/Cargo.lock index 2b211de..67956e3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -468,7 +468,7 @@ dependencies = [ [[package]] name = "nixdoc" -version = "3.0.3" +version = "3.0.4" dependencies = [ "clap", "comrak", diff --git a/Cargo.toml b/Cargo.toml index 67add90..3cccb91 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "nixdoc" -version = "3.0.3" +version = "3.0.4" authors = ["Vincent Ambo ", "asymmetric"] edition = "2021" description = "Generate CommonMark from Nix library functions" diff --git a/src/format.rs b/src/format.rs index e4738e6..befb17a 100644 --- a/src/format.rs +++ b/src/format.rs @@ -1,8 +1,53 @@ use comrak::{ + format_commonmark, nodes::{AstNode, NodeValue}, parse_document, Arena, ComrakOptions, Options, }; -use textwrap::dedent; +use std::io::Write; +use textwrap::dedent; // For using the write! macro + +// Your custom renderer +struct CustomRenderer<'a> { + options: &'a ComrakOptions, +} + +impl<'a> CustomRenderer<'a> { + fn new(options: &'a ComrakOptions) -> Self { + CustomRenderer { options } + } + + fn format_node(&self, root: &'a AstNode<'a>, buffer: &mut Vec) { + for node in root.children() { + match &node.data.borrow().value { + NodeValue::Heading(heading) => { + // Handling headings specifically. + write!(buffer, "{} ", "#".repeat(heading.level as usize)).expect( + "Failed to write UTF-8. Make sure files contains only valid UTF-8.", + ); + + // Handle the children of the heading node + // Headings have only one child: NodeValue::Text + if let Some(child) = node.first_child() { + if let NodeValue::Text(ref text) = child.data.borrow().value { + writeln!(buffer, "{}", text).expect( + "Failed to write UTF-8. Make sure files contains only valid UTF-8.", + ); + }; + } + } + // Handle other node types using comrak's default behavior + _ => { + format_commonmark(node, self.options, buffer) + .expect("Failed to format markdown using the default comrak formatter."); + } + }; + + // Insert a newline after each node + // This behavior is the same as the default comrak-formatter behavior. + buffer.push(b'\n'); + } + } +} /// Ensure all lines in a multi-line doc-comments have the same indentation. /// @@ -79,13 +124,11 @@ pub fn shift_headings(raw: &str, levels: u8) -> String { increase_heading_levels(root, levels); let mut markdown_output = vec![]; + let renderer = CustomRenderer::new(&options); + renderer.format_node(root, &mut markdown_output); - // This could only fail if we transform the AST in a way that is not supported by the markdown renderer. - // Since the AST stems from comrak itself, this should never happen. - comrak::format_commonmark(root, &options, &mut markdown_output) - .expect("Failed to format markdown"); // We can safely assume that the output is valid UTF-8, since comrak uses rust strings which are valid UTF-8. - String::from_utf8(markdown_output).unwrap() + String::from_utf8(markdown_output).expect("Markdown contains invalid UTF-8") } // Internal function to operate on the markdown AST diff --git a/src/snapshots/nixdoc__test__doc_comment.snap b/src/snapshots/nixdoc__test__doc_comment.snap index 15b10d7..ed01e83 100644 --- a/src/snapshots/nixdoc__test__doc_comment.snap +++ b/src/snapshots/nixdoc__test__doc_comment.snap @@ -21,6 +21,7 @@ This is a parsed example doc comment in markdown format + ## `lib.debug.foo` {#function-library-lib.debug.foo} Comment diff --git a/src/snapshots/nixdoc__test__doc_comment_no_duplicate_arguments.snap b/src/snapshots/nixdoc__test__doc_comment_no_duplicate_arguments.snap index 6a3387a..9546410 100644 --- a/src/snapshots/nixdoc__test__doc_comment_no_duplicate_arguments.snap +++ b/src/snapshots/nixdoc__test__doc_comment_no_duplicate_arguments.snap @@ -19,17 +19,20 @@ nixdoc comment Doc-comment + ## `lib.debug.multiple` {#function-library-lib.debug.multiple} Doc-comment + ## `lib.debug.argumentTest` {#function-library-lib.debug.argumentTest} Doc-comment before the lamdba causes the whole lambda including its arguments to switch to doc-comments ONLY rendering + ## `lib.debug.legacyArgumentTest` {#function-library-lib.debug.legacyArgumentTest} Legacy comments allow to use any diff --git a/src/snapshots/nixdoc__test__headings.snap b/src/snapshots/nixdoc__test__headings.snap index cb04179..957ed07 100644 --- a/src/snapshots/nixdoc__test__headings.snap +++ b/src/snapshots/nixdoc__test__headings.snap @@ -6,6 +6,8 @@ expression: output #### h2-heading +#### h2-heading-with-id {#some-id} + ##### h3-heading ``` nix diff --git a/test/headings.md b/test/headings.md index ec575f5..33d58f2 100644 --- a/test/headings.md +++ b/test/headings.md @@ -2,6 +2,8 @@ ## h2-heading +## h2-heading-with-id {#some-id} + ### h3-heading ```nix