diff --git a/Cargo.toml b/Cargo.toml index eba1c99..92811a5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,6 +12,7 @@ license = "MIT" [workspace.dependencies] anyhow = "1.0.82" +dunce = "1.0.4" toml = "0.8.12" insta = { version = "1.38.0", features = ["yaml"] } pyo3 = "0.21.2" diff --git a/crates/analyzer/Cargo.toml b/crates/analyzer/Cargo.toml index d6ca218..a4d0953 100644 --- a/crates/analyzer/Cargo.toml +++ b/crates/analyzer/Cargo.toml @@ -14,6 +14,7 @@ readme = "../../README.md" [dependencies] anyhow.workspace = true +dunce.workspace = true quote.workspace = true serde.workspace = true serde_json.workspace = true diff --git a/crates/analyzer/src/analyze/crate_.rs b/crates/analyzer/src/analyze/crate_.rs index 2710d6b..ecf9fb3 100644 --- a/crates/analyzer/src/analyze/crate_.rs +++ b/crates/analyzer/src/analyze/crate_.rs @@ -6,8 +6,9 @@ use super::{Enum, Module, Struct}; pub fn analyze_crate(path: &str) -> Result { // make the path absolute + // TODO we use dunce to canonicalize the path because otherwise there is issues with python's os.path.relpath on windows, but maybe we should fix this on the Python side let path = - std::fs::canonicalize(path).context(format!("Error resolving crate path: {}", path))?; + dunce::canonicalize(path).context(format!("Error resolving crate path: {}", path))?; // check the path is a directory if !path.is_dir() { return Err(anyhow::anyhow!(format!( diff --git a/docs/index.rst b/docs/index.rst index 4b74ca6..244e721 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -46,7 +46,6 @@ Add `sphinx_rust` to your `conf.py`, and specifiy the paths to the Rust crates y "../path/to/crate", ... ] - rust_viewcode = True # Optional: add "View Source" links ... Now add a `toctree` in your `index.rst`, to point towards the generated documentation for each crate diff --git a/python/sphinx_rust/config.py b/python/sphinx_rust/config.py index 2723874..03d8ec4 100644 --- a/python/sphinx_rust/config.py +++ b/python/sphinx_rust/config.py @@ -29,4 +29,4 @@ def add_configs(app: Sphinx) -> None: """Add the configuration values for the Rust domain.""" app.add_config_value("rust_crates", [], "env") app.add_config_value("rust_doc_formats", {}, "env") - app.add_config_value("rust_viewcode", False, "env") + app.add_config_value("rust_viewcode", True, "env") diff --git a/python/sphinx_rust/directives/_core.py b/python/sphinx_rust/directives/_core.py index c41ba61..c6570c4 100644 --- a/python/sphinx_rust/directives/_core.py +++ b/python/sphinx_rust/directives/_core.py @@ -190,6 +190,7 @@ def create_source_xref( *, warn_dangling: bool = False, text: str | None = None, + classes: list[str] | None = None, ) -> addnodes.pending_xref: """Create a cross-reference node to the source-code of a rust object. @@ -203,6 +204,7 @@ def create_source_xref( "refexplicit": True, "refwarn": warn_dangling, "reftarget": f"rust-code:{full_name}", + "classes": classes or [], } ref = addnodes.pending_xref(full_name, **options) text = full_name.split("::")[-1] if text is None else text diff --git a/python/sphinx_rust/directives/crate.py b/python/sphinx_rust/directives/crate.py index 63dffcb..27d4522 100644 --- a/python/sphinx_rust/directives/crate.py +++ b/python/sphinx_rust/directives/crate.py @@ -75,12 +75,11 @@ def run(self) -> list[nodes.Node]: self.rust_domain.note_object(crate.name, "crate", node_id, signature) if self.rust_config.rust_viewcode and crate_mod and crate_mod.file: - root += nodes.paragraph( - "", - "", - create_source_xref( - self.env.docname, crate_mod.path_str, text="[View Source]" - ), + signature += create_source_xref( + self.env.docname, + crate_mod.path_str, + text="[source]", + classes=["viewcode-link"], ) if crate_mod and crate_mod.docstring: diff --git a/python/sphinx_rust/directives/module.py b/python/sphinx_rust/directives/module.py index 2b5fb3c..ec446b4 100644 --- a/python/sphinx_rust/directives/module.py +++ b/python/sphinx_rust/directives/module.py @@ -64,12 +64,11 @@ def run(self) -> list[nodes.Node]: self.rust_domain.note_object(module.path_str, "module", node_id, signature) if self.rust_config.rust_viewcode and module and module.file: - root += nodes.paragraph( - "", - "", - create_source_xref( - self.env.docname, module.path_str, text="[View Source]" - ), + signature += create_source_xref( + self.env.docname, + module.path_str, + text="[source]", + classes=["viewcode-link"], ) if module.docstring: diff --git a/python/sphinx_rust/domain.py b/python/sphinx_rust/domain.py index e33da5c..684f2b3 100644 --- a/python/sphinx_rust/domain.py +++ b/python/sphinx_rust/domain.py @@ -246,7 +246,7 @@ def create_code_pages(crate_name: str, srcdir: Path, cache: Path) -> None: code_folder = srcdir.joinpath("api", "crates", crate_name, "code") code_folder.mkdir(exist_ok=True, parents=True) for full_name, file_path in modules: - rel_path = os.path.relpath(file_path, code_folder) + rel_path = os.path.relpath(Path(file_path), code_folder) # note, this is available only in Python 3.12+ # rel_path = Path(file_path).relative_to(code_folder, walk_up=True) # TODO only write the file if it doesn't exist or is different