markdown_ai_cite_remove/
lib.rs

1//! # markdown-ai-cite-remove
2//!
3//! **Remove AI-generated citations and annotations from Markdown text**
4//!
5//! High-performance Rust library for removing citations from ChatGPT, Claude, Perplexity, and other AI markdown
6//! responses. Removes inline citations `[1][2]`, reference links `[1]: https://...`, and
7//! bibliography sections with 100% accuracy.
8//!
9//! ## Quick Start
10//!
11//! ```
12//! use markdown_ai_cite_remove::remove_citations;
13//!
14//! let markdown = "AI research shows promise[1][2].\n\n[1]: https://example.com\n[2]: https://test.com";
15//! let result = remove_citations(markdown);
16//! assert_eq!(result.trim(), "AI research shows promise.");
17//! ```
18//!
19//! ## Features
20//!
21//! - ✅ Remove inline numeric citations `[1][2][3]`
22//! - ✅ Remove named citations `[source:1][ref:2]`
23//! - ✅ Remove reference link lists `[1]: https://...`
24//! - ✅ Remove reference section headers `## References`
25//! - ✅ Remove bibliographic entries
26//! - ✅ Preserve markdown formatting
27//! - ✅ Whitespace normalization
28//! - ✅ Ultra-fast performance (100+ MB/s throughput)
29//!
30//! ## Custom Configuration
31//!
32//! ```
33//! use markdown_ai_cite_remove::{CitationRemover, RemoverConfig};
34//!
35//! let config = RemoverConfig {
36//!     remove_inline_citations: true,
37//!     remove_reference_links: true,
38//!     ..Default::default()
39//! };
40//!
41//! let remover = CitationRemover::with_config(config);
42//! let result = remover.remove("Text with citations[1].");
43//! ```
44
45mod config;
46mod error;
47mod patterns;
48mod remover;
49
50pub use config::{RemovalMode, RemoverConfig};
51pub use error::{RemoverError, Result};
52pub use remover::CitationRemover;
53
54/// Main entry point - remove citations from markdown with default settings
55///
56/// # Examples
57///
58/// ```
59/// use markdown_ai_cite_remove::remove_citations;
60///
61/// let input = "Recent research[1][2] shows promise[3].";
62/// let output = remove_citations(input);
63/// assert_eq!(output, "Recent research shows promise.");
64/// ```
65pub fn remove_citations(markdown: &str) -> String {
66    CitationRemover::new().remove(markdown)
67}
68
69/// Remove citations from markdown with custom configuration
70///
71/// # Examples
72///
73/// ```
74/// use markdown_ai_cite_remove::{remove_citations_with_config, RemoverConfig};
75///
76/// let config = RemoverConfig::inline_only();
77/// let input = "Text[1] here.\n\nSome content.";
78/// let output = remove_citations_with_config(input, config);
79/// assert_eq!(output.trim(), "Text here.\n\nSome content.");
80/// ```
81pub fn remove_citations_with_config(markdown: &str, config: RemoverConfig) -> String {
82    CitationRemover::with_config(config).remove(markdown)
83}
84
85#[cfg(test)]
86mod tests {
87    use super::*;
88
89    #[test]
90    fn test_remove_basic() {
91        let input = "Text[1] here[2].";
92        let expected = "Text here.";
93        assert_eq!(remove_citations(input), expected);
94    }
95
96    #[test]
97    fn test_remove_with_references() {
98        let input = "Content here.\n\n[1]: https://example.com\n[2]: https://test.com";
99        let expected = "Content here.";
100        assert_eq!(remove_citations(input).trim(), expected);
101    }
102
103    #[test]
104    fn test_remove_preserves_markdown() {
105        let input =
106            "# Heading\n\nSome **bold** text[1] and *italic*[2].\n\n[1]: https://example.com";
107        let expected = "# Heading\n\nSome **bold** text and *italic*.";
108        assert_eq!(remove_citations(input).trim(), expected);
109    }
110
111    #[test]
112    fn test_empty_string() {
113        assert_eq!(remove_citations(""), "");
114    }
115
116    #[test]
117    fn test_no_citations() {
118        let input = "Just regular markdown text.";
119        assert_eq!(remove_citations(input), input);
120    }
121}