subx_cli/core/formats/
styling.rs

1//! Styling adjustments for subtitle formats.
2//!
3//! This module provides functions to manipulate styling (e.g., fonts,
4//! colors) for subtitle entries.
5//!
6//! # Examples
7//!
8//! ```rust,ignore
9//! use subx_cli::core::formats::styling::apply_styling;
10//! // ... apply styling adjustments to entries
11//! ```
12
13use regex::Regex;
14
15use crate::core::formats::StylingInfo;
16use crate::core::formats::converter::FormatConverter;
17
18impl FormatConverter {
19    /// Extract styling information from SRT tags
20    pub(crate) fn extract_srt_styling(&self, text: &str) -> crate::Result<StylingInfo> {
21        let mut styling = StylingInfo::default();
22        if text.contains("<b>") || text.contains("<B>") {
23            styling.bold = true;
24        }
25        if text.contains("<i>") || text.contains("<I>") {
26            styling.italic = true;
27        }
28        if text.contains("<u>") || text.contains("<U>") {
29            styling.underline = true;
30        }
31        if let Some(color) = self.extract_color_from_tags(text) {
32            styling.color = Some(color);
33        }
34        Ok(styling)
35    }
36
37    /// Convert SRT tags to ASS tags
38    pub(crate) fn convert_srt_tags_to_ass(&self, text: &str) -> String {
39        let mut result = text.to_string();
40        result = result.replace("<b>", "{\\b1}").replace("</b>", "{\\b0}");
41        result = result.replace("<i>", "{\\i1}").replace("</i>", "{\\i0}");
42        result = result.replace("<u>", "{\\u1}").replace("</u>", "{\\u0}");
43        let color_regex = Regex::new(r#"<font color=\"([^\"]+)\">"#).unwrap();
44        result = color_regex
45            .replace_all(&result, |caps: &regex::Captures| {
46                let color = &caps[1];
47                format!("{{\\c&H{}&}}", self.convert_color_to_ass(color))
48            })
49            .to_string();
50        result = result.replace("</font>", "{\\c}");
51        result
52    }
53
54    /// Remove ASS tags
55    pub(crate) fn strip_ass_tags(&self, text: &str) -> String {
56        let tag_regex = Regex::new(r"\{[^}]*\}").unwrap();
57        tag_regex.replace_all(text, "").to_string()
58    }
59
60    /// Convert ASS tags to SRT tags
61    pub(crate) fn convert_ass_tags_to_srt(&self, text: &str) -> String {
62        let mut result = text.to_string();
63        let bold_regex = Regex::new(r"\{\\b1\}([^\{]*)\{\\b0\}").unwrap();
64        result = bold_regex.replace_all(&result, "<b>$1</b>").to_string();
65        let italic_regex = Regex::new(r"\{\\i1\}([^\{]*)\{\\i0\}").unwrap();
66        result = italic_regex.replace_all(&result, "<i>$1</i>").to_string();
67        let underline_regex = Regex::new(r"\{\\u1\}([^\{]*)\{\\u0\}").unwrap();
68        result = underline_regex
69            .replace_all(&result, "<u>$1</u>")
70            .to_string();
71        result
72    }
73
74    /// Extract color from tags (simple implementation)
75    pub(crate) fn extract_color_from_tags(&self, _text: &str) -> Option<String> {
76        None
77    }
78
79    /// Convert color string to ASS color code
80    pub(crate) fn convert_color_to_ass(&self, color: &str) -> String {
81        color.trim_start_matches('#').to_string()
82    }
83
84    /// Convert SRT tags to VTT tags (simple implementation)
85    pub(crate) fn convert_srt_tags_to_vtt(&self, text: &str) -> String {
86        text.to_string()
87    }
88    /// Convert VTT tags to SRT tags (simple implementation)
89    pub(crate) fn convert_vtt_tags_to_srt(&self, text: &str) -> String {
90        // VTT uses HTML-like tags, SRT also supports basic tags, default preserve
91        text.to_string()
92    }
93    /// Remove VTT tags (simple implementation)
94    pub(crate) fn strip_vtt_tags(&self, text: &str) -> String {
95        let tag_regex = Regex::new(r"</?[^>]+>").unwrap();
96        tag_regex.replace_all(text, "").to_string()
97    }
98}