Improve reference handling and fallbacks (#348)

* Pesto: handle single line comment

The first single line comment is displayed as a fallback if no other documentation could be found

* Website: Handle bare-urls, dont sanitize foreign cross references
This commit is contained in:
Johannes Kirschbauer 2024-09-20 10:53:29 +02:00 committed by GitHub
parent 4910fe3101
commit bdbd37bd60
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 103 additions and 21 deletions

View File

@ -63,7 +63,9 @@ pub fn get_expr_docs(expr: &SyntaxNode) -> Option<String> {
ast::AttrpathValue(_) => {
if let Some(doc_comment) = get_doc_comment(parent) {
doc_comment.doc_text().map(|v| v.to_owned())
}else{
}else if let Some(comment) = get_comment(parent) {
Some(comment.text().to_owned())
} else {
None
}
},
@ -111,3 +113,31 @@ fn get_doc_comment(expr: &SyntaxNode) -> Option<ast::Comment> {
};
}
}
/// Function retrieves a comment from the [ast::Expr]
fn get_comment(expr: &SyntaxNode) -> Option<ast::Comment> {
let mut prev = expr.prev_sibling_or_token();
loop {
match prev {
Some(rnix::NodeOrToken::Token(ref token)) => {
match_ast! { match token {
ast::Whitespace(_) => {
prev = token.prev_sibling_or_token();
},
ast::Comment(it) => {
if !it.text().is_empty() {
break Some(it);
}else{
//Ignore non-doc comments.
prev = token.prev_sibling_or_token();
}
},
_ => {
break None;
}
}}
}
_ => break None,
};
}
}

View File

@ -4,7 +4,7 @@
"attr": {
"position": {
"column": 3,
"file": "/nix/store/ba0p7n38ncj0gx55yj2vddx189nkljs0-nixpkgs-migrated/lib/lists.nix",
"file": "test_data/assets/lib/lists.nix",
"line": 108
}
},
@ -12,7 +12,7 @@
"isPrimop": false,
"position": {
"column": 11,
"file": "/nix/store/ba0p7n38ncj0gx55yj2vddx189nkljs0-nixpkgs-migrated/lib/lists.nix",
"file": "test_data/assets/lib/lists.nix",
"line": 95
}
}
@ -24,7 +24,7 @@
"attr": {
"position": {
"column": 3,
"file": "/nix/store/ba0p7n38ncj0gx55yj2vddx189nkljs0-nixpkgs-migrated/lib/lists.nix",
"file": "test_data/assets/lib/lists.nix",
"line": 95
}
},
@ -32,7 +32,7 @@
"isPrimop": false,
"position": {
"column": 11,
"file": "/nix/store/ba0p7n38ncj0gx55yj2vddx189nkljs0-nixpkgs-migrated/lib/lists.nix",
"file": "test_data/assets/lib/lists.nix",
"line": 95
}
}

View File

@ -4,7 +4,7 @@
"attr": {
"position": {
"column": 25,
"file": "/nix/store/ba0p7n38ncj0gx55yj2vddx189nkljs0-nixpkgs-migrated/lib/default.nix",
"file": "test_data/assets/lib/default.nix",
"line": 153
}
},
@ -12,7 +12,7 @@
"isPrimop": false,
"position": {
"column": 5,
"file": "/nix/store/ba0p7n38ncj0gx55yj2vddx189nkljs0-nixpkgs-migrated/lib/debug.nix",
"file": "test_data/assets/lib/debug.nix",
"line": 95
}
}
@ -24,7 +24,7 @@
"attr": {
"position": {
"column": 3,
"file": "/nix/store/ba0p7n38ncj0gx55yj2vddx189nkljs0-nixpkgs-migrated/lib/debug.nix",
"file": "test_data/assets/lib/debug.nix",
"line": 114
}
},
@ -32,7 +32,7 @@
"isPrimop": false,
"position": {
"column": 5,
"file": "/nix/store/ba0p7n38ncj0gx55yj2vddx189nkljs0-nixpkgs-migrated/lib/debug.nix",
"file": "test_data/assets/lib/debug.nix",
"line": 95
}
}
@ -44,7 +44,7 @@
"attr": {
"position": {
"column": 3,
"file": "/nix/store/ba0p7n38ncj0gx55yj2vddx189nkljs0-nixpkgs-migrated/lib/fileset/default.nix",
"file": "test_data/assets/lib/fileset/default.nix",
"line": 666
}
},
@ -52,7 +52,7 @@
"isPrimop": false,
"position": {
"column": 5,
"file": "/nix/store/ba0p7n38ncj0gx55yj2vddx189nkljs0-nixpkgs-migrated/lib/fileset/default.nix",
"file": "test_data/assets/lib/fileset/default.nix",
"line": 672
}
}

View File

@ -1 +1 @@
Some(NixDocComment { content: Some("Docs"), count_applied: Some(1) })
Some(NixDocComment { content: None, count_applied: Some(1) })

View File

@ -1 +1 @@
Some(NixDocComment { content: Some("Docs"), count_applied: Some(3) })
Some(NixDocComment { content: None, count_applied: Some(3) })

View File

@ -4,7 +4,7 @@
"attr": {
"position": {
"column": 3,
"file": "/nix/store/knnp4h12pk09vfn18lrrrnh54zsvw3ba-source/lib/lists.nix",
"file": "test_data/assets/lib/lists.nix",
"line": 198
}
},
@ -12,7 +12,7 @@
"isPrimop": false,
"position": {
"column": 5,
"file": "/nix/store/knnp4h12pk09vfn18lrrrnh54zsvw3ba-source/lib/lists.nix",
"file": "test_data/assets/lib/lists.nix",
"line": 204
}
}

View File

@ -22,7 +22,7 @@
"attr": {
"position": {
"column": 28,
"file": "/nix/store/knnp4h12pk09vfn18lrrrnh54zsvw3ba-source/lib/default.nix",
"file": "test_data/assets/lib/default.nix",
"line": 82
}
},
@ -44,7 +44,7 @@
"attr": {
"position": {
"column": 3,
"file": "/nix/store/knnp4h12pk09vfn18lrrrnh54zsvw3ba-source/lib/attrsets.nix",
"file": "test_data/assets/lib/attrsets.nix",
"line": 398
}
},

View File

@ -2,6 +2,58 @@ import { h } from "hastscript";
import { visit } from "unist-util-visit";
import { Element } from "hast";
export default function remarkBareUrls() {
/**
* @param {import('mdast').Root} tree
* Tree.
* @returns {undefined}
* Nothing.
*/
return function (tree: any) {
// Use unist-util-visit to walk through the markdown AST
visit(tree, "text", (node, index, parent) => {
const urlRegex = /\bhttps?:\/\/[^\s<]+/g;
let match;
const nodes = [];
let lastIndex = 0;
while ((match = urlRegex.exec(node.value)) !== null) {
// Push any text before the URL
if (match.index > lastIndex) {
nodes.push({
type: "text",
value: node.value.slice(lastIndex, match.index),
});
}
// Create the <a> tag for the URL
const url = match[0];
nodes.push({
type: "link",
title: null,
url: url,
children: [{ type: "text", value: url }],
});
lastIndex = match.index + url.length;
}
// Push any remaining text after the last URL
if (lastIndex < node.value.length) {
nodes.push({
type: "text",
value: node.value.slice(lastIndex),
});
}
// Replace the original text node with the new nodes (text + links)
if (nodes.length > 0) {
parent.children.splice(index, 1, ...nodes);
}
});
};
}
export function styleDirectives() {
/**
* @param {import('mdast').Root} tree
@ -48,6 +100,7 @@ export function replaceComponents() {
tagName: `a`,
properties: {
"data-link-md": true,
href: node.properties.href,
}, // Pass props here if needed
children: node.children,
};

View File

@ -14,7 +14,6 @@ import rehypeStringify from "rehype-stringify";
import remarkHeadingId from "remark-heading-id";
import remarkParse from "remark-parse";
import remarkRehype from "remark-rehype";
import remarkUnlink from "remark-unlink";
import {
remarkDefinitionList,
defListHastHandlers,
@ -24,7 +23,7 @@ import remarkDirective from "remark-directive";
import { unified } from "unified";
import { rehypeExtractExcerpt } from "./excerpt";
import {
import remarkBareUrls, {
replaceComponents,
sanitizeDirectives,
styleDirectives,
@ -127,9 +126,9 @@ type Heading = {
export const parseMd = async (src: string) => {
const result = await unified()
.use(remarkParse)
.use(remarkBareUrls)
.use(remarkHeadingId)
.use(remarkDefinitionList)
.use(remarkUnlink)
.use(remarkDirective)
.use(styleDirectives)
.use(remarkRehype, {
@ -212,7 +211,7 @@ export const mdxRenderOptions: SerializeOptions["mdxOptions"] = {
[rehypeSlug, {}],
[rehypeAutolinkHeadings, { behavior: "wrap" }],
],
remarkPlugins: [remarkHeadingId, remarkDefinitionList, remarkUnlink],
remarkPlugins: [remarkHeadingId, remarkDefinitionList],
format: "md",
remarkRehypeOptions: {
handlers: {