drft/builders/
markdown.rs1use globset::GlobSet;
6
7use crate::builders::link_edges;
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 edge in link_edges(path, &parser.parse(path, content).links) {
26 graph.add_edge(edge);
27 }
28 }
29
30 graph.sort_edges();
31 graph
32}
33
34#[cfg(test)]
35mod tests {
36 use super::*;
37
38 fn texts(pairs: &[(&str, &str)]) -> Vec<(String, String)> {
39 pairs
40 .iter()
41 .map(|(p, c)| (p.to_string(), c.to_string()))
42 .collect()
43 }
44
45 #[test]
46 fn emits_resolved_edges() {
47 let t = texts(&[("docs/index.md", "[setup](setup.md) and [faq](../faq.md)")]);
48 let graph = build("markdown", &t, None);
49 assert_eq!(graph.label.as_deref(), Some("markdown"));
50 assert!(graph.nodes.is_empty(), "markdown contributes no nodes");
51 let targets: Vec<&str> = graph.edges.iter().map(|e| e.target.as_str()).collect();
52 assert_eq!(targets, vec!["docs/setup.md", "faq.md"]);
53 }
54
55 #[test]
56 fn filter_scopes_files() {
57 let mut builder = globset::GlobSetBuilder::new();
58 builder.add(globset::Glob::new("**/*.md").unwrap());
59 let filter = builder.build().unwrap();
60
61 let t = texts(&[("a.md", "[x](x.md)"), ("notes.txt", "[y](y.md)")]);
62 let graph = build("markdown", &t, Some(filter));
63 assert_eq!(graph.edges.len(), 1);
64 assert_eq!(graph.edges[0].source, "a.md");
65 }
66}