rumdl_lib/utils/mkdocs_definition_lists.rs
1//! MkDocs/Python-Markdown Definition Lists extension support
2//!
3//! This module provides support for the Python-Markdown Definition Lists extension,
4//! which allows creating definition lists with terms and their definitions.
5//!
6//! ## Syntax
7//!
8//! ```markdown
9//! Term 1
10//! : Definition for term 1
11//!
12//! Term 2
13//! : Definition for term 2
14//! Continuation of the definition
15//!
16//! Term with multiple definitions
17//! : First definition
18//! : Second definition
19//! ```
20//!
21//! ## Format Requirements
22//!
23//! - Term appears on its own line (no leading whitespace required for the term)
24//! - Definition starts with `:` followed by whitespace (typically 3 spaces after `:`)
25//! - Multiple definitions for a term use separate `:` lines
26//! - Continuation lines are indented (typically 4 spaces)
27//!
28//! ## MkDocs Material Specifics
29//!
30//! MkDocs Material supports definition lists via the Python-Markdown Definition Lists extension,
31//! which is enabled by default in the Material theme.
32//!
33//! ## References
34//!
35//! - [Python-Markdown Definition Lists](https://python-markdown.github.io/extensions/definition_lists/)
36//! - [MkDocs Material - Lists](https://squidfunk.github.io/mkdocs-material/reference/lists/#using-definition-lists)
37
38/// Check if a line is a definition (starts with `:` followed by whitespace)
39///
40/// Reexported from utils::mod.rs for compatibility
41#[inline]
42pub fn is_definition_line(line: &str) -> bool {
43 crate::utils::is_definition_list_item(line)
44}
45
46/// Check if a line could be a term (precedes a definition)
47///
48/// A term line is a non-empty line that:
49/// - Doesn't start with whitespace (or has consistent indentation for nested terms)
50/// - Is followed by a definition line (checked by caller)
51/// - Is not a definition line itself
52/// - Is not a blank line
53#[inline]
54pub fn could_be_term_line(line: &str) -> bool {
55 let trimmed = line.trim();
56 !trimmed.is_empty() && !is_definition_line(line) && !line.starts_with(' ')
57}
58
59/// Check if a line is a definition continuation (indented after a definition)
60///
61/// Continuation lines are typically indented 4 spaces
62#[inline]
63pub fn is_definition_continuation(line: &str) -> bool {
64 // Continuation is indented (at least 4 spaces) and not a new definition
65 line.starts_with(" ") && !line.trim_start().starts_with(':')
66}
67
68#[cfg(test)]
69mod tests {
70 use super::*;
71
72 #[test]
73 fn test_is_definition_line() {
74 assert!(is_definition_line(": Definition text"));
75 assert!(is_definition_line(": Definition text"));
76 assert!(is_definition_line(":\tDefinition text"));
77 assert!(is_definition_line(": Long definition"));
78
79 assert!(!is_definition_line("Term"));
80 assert!(!is_definition_line(" Term"));
81 assert!(!is_definition_line(""));
82 assert!(!is_definition_line(":NoSpace")); // No space after colon
83 }
84
85 #[test]
86 fn test_could_be_term_line() {
87 assert!(could_be_term_line("Term"));
88 assert!(could_be_term_line("Multi Word Term"));
89 assert!(could_be_term_line("Term with special chars: like this"));
90
91 assert!(!could_be_term_line("")); // Empty
92 assert!(!could_be_term_line(" ")); // Blank
93 assert!(!could_be_term_line(": Definition")); // Definition
94 assert!(!could_be_term_line(" Term")); // Leading space
95 }
96
97 #[test]
98 fn test_is_definition_continuation() {
99 assert!(is_definition_continuation(" Continuation text"));
100 assert!(is_definition_continuation(" More continuation"));
101
102 assert!(!is_definition_continuation(": New definition"));
103 assert!(!is_definition_continuation("No indent"));
104 assert!(!is_definition_continuation(" Only 2 spaces"));
105 }
106}