drft/builders/
markdown.rs1use globset::GlobSet;
6
7use crate::builders::link_edge;
8use crate::model::Graph;
9use crate::parsers::Parser;
10use crate::parsers::markdown::MarkdownParser;
11
12pub fn build(label: &str, texts: &[(String, String)], filter: Option<GlobSet>) -> Graph {
16 let parser = MarkdownParser {
17 file_filter: filter,
18 };
19 let mut graph = Graph::labeled(label);
20
21 for (path, content) in texts {
22 if !parser.matches(path) {
23 continue;
24 }
25 for raw in parser.parse(path, content).links {
26 if let Some(edge) = link_edge(path, &raw) {
27 graph.add_edge(edge);
28 }
29 }
30 }
31
32 graph.sort_edges();
33 graph
34}
35
36#[cfg(test)]
37mod tests {
38 use super::*;
39
40 fn texts(pairs: &[(&str, &str)]) -> Vec<(String, String)> {
41 pairs
42 .iter()
43 .map(|(p, c)| (p.to_string(), c.to_string()))
44 .collect()
45 }
46
47 #[test]
48 fn emits_resolved_edges() {
49 let t = texts(&[("docs/index.md", "[setup](setup.md) and [faq](../faq.md)")]);
50 let graph = build("markdown", &t, None);
51 assert_eq!(graph.label.as_deref(), Some("markdown"));
52 assert!(graph.nodes.is_empty(), "markdown contributes no nodes");
53 let targets: Vec<&str> = graph.edges.iter().map(|e| e.target.as_str()).collect();
54 assert_eq!(targets, vec!["docs/setup.md", "faq.md"]);
55 }
56
57 #[test]
58 fn filter_scopes_files() {
59 let mut builder = globset::GlobSetBuilder::new();
60 builder.add(globset::Glob::new("**/*.md").unwrap());
61 let filter = builder.build().unwrap();
62
63 let t = texts(&[("a.md", "[x](x.md)"), ("notes.txt", "[y](y.md)")]);
64 let graph = build("markdown", &t, Some(filter));
65 assert_eq!(graph.edges.len(), 1);
66 assert_eq!(graph.edges[0].source, "a.md");
67 }
68}