1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
//! Centralized regex patterns used across the codebase
// === HTML and Template Patterns ===
/// Matches HTML tags or template expressions ({{...}} or {%...%})
/// Used for removing HTML/template syntax from text
pub const MATCH_HTML_OR_TEMPLATE_TAGS: &str = r"<[^>]*>|\{\{[^}]*\}\}|\{%[^%]*%\}";
/// Matches basic HTML tags
/// Used for stripping HTML from text content
pub const MATCH_HTML_TAGS: &str = r"<[^>]*>";
/// Matches href attributes in HTML that point to .html files with optional anchors
/// Captures: 1) the file path without .html, 2) optional anchor (#section)
/// Used for converting markdown links to HTML links
pub const CAPTURE_SLUG_ANCHOR_FROM_HREF: &str = r#"href=['\"]([^'\"]+)\.html(#[^'\"]+)?['\"]"#;
/// Matches HTML heading tags (h1-h6) with optional id attribute
/// Captures: 1) heading level, 2) optional id from the h tag, 3) heading inner HTML
/// Used for extracting table of contents from HTML
pub const CAPTURE_LEVEL_ID_CONTENT_FROM_H_TAG: &str =
r#"<h([1-6])(?:\s[^>]*?\bid=['\"]([^'\"]+)['\"])?[^>]*>(.*?)</h[1-6]>"#;
/// Matches anchor tags with class="anchor" (comrak heading anchors)
/// Used for stripping comrak's auto-generated anchor tags from heading text
pub const MATCH_COMRAK_HEADING_ANCHOR: &str =
r#"<a[^>]*\bclass=['\"][^'\"]*\banchor\b[^'\"]*['\"][^>]*>.*?</a>"#;
/// Matches anchor tags in HTML
/// Captures: 1) href attribute value, 2) link text
/// Used for extracting links from HTML content
pub const CAPTURE_LINK_AND_TEXT_FROM_A_TAG: &str =
r#"<a[^>]*href=['\"]([^'\"]+)['\"][^>]*>(.*?)</a>"#;
/// Matches img tags to extract src attributes
/// Captures: 1) the src attribute value
/// Used for extracting image URLs from HTML content
pub const CAPTURE_SRC_FROM_IMG_HTMLTAG: &str = r#"<img[^>]*src=['\"]([^'\"]+)['\"]"#;
/// Matches wikilink anchor tags with data-wikilink attribute
/// Captures: 1) href attribute value, 2) link text content
/// Used for fixing Obsidian wikilinks to use proper slugs instead of filename-based hrefs
pub const CAPTURE_WIKILINK_HREF_AND_TITLE: &str =
r#"<a[^>]*href=['\"]([^'\"]+)['\"][^>]*data-wikilink=['\"]true['\"][^>]*>(.*?)</a>"#;
// === Shortcode Patterns ===
/// Default pattern for HTML comment-style shortcodes
/// Matches: <!-- .name params -->
/// Used as the default shortcode pattern when none is specified
pub const SHORTCODE_HTML_COMMENT: &str = r"<!-- \.(\w+)(?:\s+([^-][\s\S]*?))?\s*-->";
/// Matches Tera macro or shortcode definitions in templates
/// Captures: 1) name
/// Used for detecting macro/shortcode definitions in shortcode files
pub const CAPTURE_SHORTCODE_DEF: &str = r"\{%\s*(?:macro|shortcode)\s+(\w+)\s*\(";
// === Date and Filename Patterns ===
/// Matches date prefix in filenames (YYYY-MM-DD with optional time)
/// Format: YYYY-MM-DD[-THH[:MM[:SS]]]-
/// Used for extracting date prefix from content filenames
/// `2024-01-01-myfile.md` -> `2024-01-01-`
pub const MATCH_DATE_PREFIX_FROM_FILENAME: &str =
r"^\d{4}-\d{2}-\d{2}([-T]\d{2}([:-]\d{2})?([:-]\d{2})?)?-";
/// Matches stream-style date in filenames
/// Format: stream-YYYY-MM-DD[-THH[:MM[:SS]]]-title
/// Used for extracting stream-date prefix from stream content filenames
/// `stream-2024-01-01-myfile.md` -> `myfile` and `stream-S-myfile.md` -> `myfile`
/// Captures the slug (text after the date/time).
pub const CAPTURE_SLUG_FROM_STREAM_DATED_FILENAME: &str =
r"^[a-zA-Z0-9]+-\d{4}-\d{2}-\d{2}(?:[-T]\d{2}(?:[:-]\d{2})?(?:[:-]\d{2})?)?-(.+)$";
/// Matches stream date pattern in filenames with slug
/// Format: stream-YYYY-MM-DD[-THH[:MM[:SS]]]
/// Used for extracting dates from stream named files
/// `news-2024-01-15-site-update.md` -> `2025-08-16`
/// Captures the date from stream-date-slug pattern
pub const CAPTURE_DATE_FROM_STREAM_DATED_FILENAME: &str =
r"^[a-zA-Z0-9]+-(\d{4}-\d{2}-\d{2}(?:[-T]\d{2}(?:[:-]\d{2})?(?:[:-]\d{2})?)?)";
/// Matches stream "S" pattern in filenames
/// Format: stream-S-title (where S indicates a stream without date)
/// Used for identifying stream content without specific dates
/// stream-S-slug -> slug
pub const CAPTURE_SLUG_FROM_STREAM_S_FILENAME: &str = r"^[a-zA-Z0-9]+-S-(.+)$";
/// Matches stream prefix with date extraction
/// Captures: 1) stream name, 2) date part
/// Used for extracting stream name and date from filenames
/// Extract stream from filename pattern: {stream}-{date}-{slug}
/// Only accepts single word before date (no hyphens allowed in stream name)
pub const CAPTURE_STREAM_AND_DATE_FROM_FILENAME: &str = r"^([a-zA-Z0-9]+)-(\d{4}-\d{2}-\d{2})";
/// Matches stream prefix without date (S pattern)
/// Captures: 1) stream name
/// Used for identifying stream content files
/// Extract stream from filename pattern: {stream}-S-{slug}
/// Only accepts single word before 'S' marker
pub const CAPTURE_STREAM_FROM_S_FILENAME: &str = r"^([a-zA-Z0-9]+)-S-";
/// Matches date at the beginning of a string (for parsing dates from text)
/// Format: YYYY-MM-DD[ HH:MM[:SS]]
/// Used for parsing dates from content metadata
pub const CAPTURE_DATE_PREFIX_FROM_TEXT: &str = r"^\d{4}-\d{2}-\d{2}( \d{2}:\d{2}(:\d{2})?)?";
// === Content Path Patterns ===
/// Matches @/ at the start of src or href attribute values in HTML tags
/// Captures: 1) the attribute name (src or href)
/// Used for replacing @/ with media/{slug}/ in rendered HTML
pub const REPLACE_AT_MEDIA_REF_IN_HTML: &str = r#"(?P<attr>src|href)="@/"#;
// === Media Link Patterns ===
/// Matches src or href attributes in HTML tags
/// Captures: 1) attribute name (src or href), 2) attribute value
/// Used for extracting media file references from HTML content
pub const CAPTURE_MEDIA_SRC_OR_HREF: &str = r#"(?:src|href)=['\"]([^'\"]+)['\"]"#;
// === Mermaid Patterns ===
/// Matches pre/code blocks with language-mermaid class in rendered HTML
/// Captures: 1) the HTML-escaped mermaid source code inside the code tag
pub const CAPTURE_MERMAID_BLOCK: &str = r#"<pre[^>]*class="[^"]*marmite-code[^"]*"[^>]*>\s*<code[^>]*class="[^"]*language-mermaid[^"]*"[^>]*>([\s\S]*?)</code>\s*</pre>"#;
// === Text Processing Patterns ===