normalize_languages/
asciidoc.rs1use crate::{Import, Language, LanguageSymbols};
4use tree_sitter::Node;
5
6pub struct AsciiDoc;
8
9impl Language for AsciiDoc {
10 fn name(&self) -> &'static str {
11 "AsciiDoc"
12 }
13 fn extensions(&self) -> &'static [&'static str] {
14 &["adoc", "asciidoc", "asc"]
15 }
16 fn grammar_name(&self) -> &'static str {
17 "asciidoc"
18 }
19
20 fn as_symbols(&self) -> Option<&dyn LanguageSymbols> {
21 Some(self)
22 }
23
24 fn extract_imports(&self, node: &Node, content: &str) -> Vec<Import> {
25 if node.kind() != "block_macro" {
26 return Vec::new();
27 }
28
29 let text = &content[node.byte_range()];
30 if !text.starts_with("include::") {
32 return Vec::new();
33 }
34
35 vec![Import {
36 module: text.trim().to_string(),
37 names: Vec::new(),
38 alias: None,
39 is_wildcard: false,
40 is_relative: false,
41 line: node.start_position().row + 1,
42 }]
43 }
44
45 fn format_import(&self, import: &Import, _names: Option<&[&str]>) -> String {
46 import.module.clone()
47 }
48
49 fn container_body<'a>(&self, node: &'a Node<'a>) -> Option<Node<'a>> {
50 node.child_by_field_name("content")
51 }
52
53 fn node_name<'a>(&self, node: &Node, content: &'a str) -> Option<&'a str> {
54 let text = &content[node.byte_range()];
56 let first_line = text.lines().next()?;
57 let name = first_line.trim().trim_start_matches('=').trim();
59 if !name.is_empty() { Some(name) } else { None }
60 }
61}
62
63impl LanguageSymbols for AsciiDoc {}
64
65#[cfg(test)]
66mod tests {
67 use super::*;
68 use crate::validate_unused_kinds_audit;
69
70 #[test]
71 fn unused_node_kinds_audit() {
72 #[rustfmt::skip]
73 let documented_unused: &[&str] = &[
74 "literal_block", "listing_block", "open_block", "quoted_block",
76 "passthrough_block", "delimited_block", "table_block", "ntable_block",
77 "ident_block", "quoted_md_block",
78 "block_comment", "block_comment_start_marker", "block_comment_end_marker",
80 "quoted_block_marker", "quoted_block_md_marker", "passthrough_block_marker",
81 "open_block_marker", "table_block_marker", "ntable_block_marker",
82 "literal_block_marker", "literal_block_body",
83 "listing_block_start_marker", "listing_block_end_marker", "listing_block_body",
84 "delimited_block_start_marker", "delimited_block_end_marker",
85 "block_title", "block_title_marker", "block_element",
87 "block_macro_name", "block_macro_attr",
88 "body", "ident_block_line", "admonition_important",
90 "section_block",
92 "block_macro",
93 ];
94 validate_unused_kinds_audit(&AsciiDoc, documented_unused)
95 .expect("AsciiDoc unused node kinds audit failed");
96 }
97}