chore: seperate large files
This commit is contained in:
parent
ebbf516689
commit
76e1298ded
44 changed files with 5745 additions and 4173 deletions
152
internal/format/ass/parser.go
Normal file
152
internal/format/ass/parser.go
Normal file
|
@ -0,0 +1,152 @@
|
|||
package ass
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"sub-cli/internal/model"
|
||||
)
|
||||
|
||||
// 常量定义
|
||||
const (
|
||||
ASSHeader = "[Script Info]"
|
||||
ASSStylesHeader = "[V4+ Styles]"
|
||||
ASSEventsHeader = "[Events]"
|
||||
DefaultFormat = "Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text"
|
||||
)
|
||||
|
||||
// Parse 解析ASS文件为ASSFile结构
|
||||
func Parse(filePath string) (model.ASSFile, error) {
|
||||
file, err := os.Open(filePath)
|
||||
if err != nil {
|
||||
return model.ASSFile{}, fmt.Errorf("打开ASS文件失败: %w", err)
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
result := model.NewASSFile()
|
||||
|
||||
scanner := bufio.NewScanner(file)
|
||||
|
||||
// 当前解析的区块
|
||||
currentSection := ""
|
||||
var styleFormat, eventFormat []string
|
||||
|
||||
for scanner.Scan() {
|
||||
line := strings.TrimSpace(scanner.Text())
|
||||
if line == "" || strings.HasPrefix(line, ";") {
|
||||
// 跳过空行和注释行
|
||||
continue
|
||||
}
|
||||
|
||||
// 检查章节标题
|
||||
if strings.HasPrefix(line, "[") && strings.HasSuffix(line, "]") {
|
||||
currentSection = line
|
||||
continue
|
||||
}
|
||||
|
||||
switch currentSection {
|
||||
case ASSHeader:
|
||||
// 解析脚本信息
|
||||
if strings.Contains(line, ":") {
|
||||
parts := strings.SplitN(line, ":", 2)
|
||||
key := strings.TrimSpace(parts[0])
|
||||
value := strings.TrimSpace(parts[1])
|
||||
result.ScriptInfo[key] = value
|
||||
}
|
||||
|
||||
case ASSStylesHeader:
|
||||
// 解析样式格式行和样式定义
|
||||
if strings.HasPrefix(line, "Format:") {
|
||||
formatStr := strings.TrimPrefix(line, "Format:")
|
||||
styleFormat = parseFormatLine(formatStr)
|
||||
} else if strings.HasPrefix(line, "Style:") {
|
||||
styleValues := parseStyleLine(line)
|
||||
if len(styleFormat) > 0 && len(styleValues) > 0 {
|
||||
style := model.ASSStyle{
|
||||
Name: styleValues[0], // 第一个值通常是样式名称
|
||||
Properties: make(map[string]string),
|
||||
}
|
||||
|
||||
// 将原始格式行保存下来
|
||||
style.Properties["Format"] = "Name, " + strings.Join(styleFormat[1:], ", ")
|
||||
style.Properties["Style"] = strings.Join(styleValues, ", ")
|
||||
|
||||
// 解析各个样式属性
|
||||
for i := 0; i < len(styleFormat) && i < len(styleValues); i++ {
|
||||
style.Properties[styleFormat[i]] = styleValues[i]
|
||||
}
|
||||
|
||||
result.Styles = append(result.Styles, style)
|
||||
}
|
||||
}
|
||||
|
||||
case ASSEventsHeader:
|
||||
// 解析事件格式行和对话行
|
||||
if strings.HasPrefix(line, "Format:") {
|
||||
formatStr := strings.TrimPrefix(line, "Format:")
|
||||
eventFormat = parseFormatLine(formatStr)
|
||||
} else if len(eventFormat) > 0 &&
|
||||
(strings.HasPrefix(line, "Dialogue:") ||
|
||||
strings.HasPrefix(line, "Comment:")) {
|
||||
|
||||
eventType := "Dialogue"
|
||||
if strings.HasPrefix(line, "Comment:") {
|
||||
eventType = "Comment"
|
||||
line = strings.TrimPrefix(line, "Comment:")
|
||||
} else {
|
||||
line = strings.TrimPrefix(line, "Dialogue:")
|
||||
}
|
||||
|
||||
values := parseEventLine(line)
|
||||
if len(values) >= len(eventFormat) {
|
||||
event := model.NewASSEvent()
|
||||
event.Type = eventType
|
||||
|
||||
// 填充事件属性
|
||||
for i, format := range eventFormat {
|
||||
value := values[i]
|
||||
switch strings.TrimSpace(format) {
|
||||
case "Layer":
|
||||
layer, _ := strconv.Atoi(value)
|
||||
event.Layer = layer
|
||||
case "Start":
|
||||
event.StartTime = parseASSTimestamp(value)
|
||||
case "End":
|
||||
event.EndTime = parseASSTimestamp(value)
|
||||
case "Style":
|
||||
event.Style = value
|
||||
case "Name":
|
||||
event.Name = value
|
||||
case "MarginL":
|
||||
marginL, _ := strconv.Atoi(value)
|
||||
event.MarginL = marginL
|
||||
case "MarginR":
|
||||
marginR, _ := strconv.Atoi(value)
|
||||
event.MarginR = marginR
|
||||
case "MarginV":
|
||||
marginV, _ := strconv.Atoi(value)
|
||||
event.MarginV = marginV
|
||||
case "Effect":
|
||||
event.Effect = value
|
||||
case "Text":
|
||||
// 文本可能包含逗号,所以需要特殊处理
|
||||
textStartIndex := strings.Index(line, value)
|
||||
if textStartIndex >= 0 {
|
||||
event.Text = line[textStartIndex:]
|
||||
} else {
|
||||
event.Text = value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
result.Events = append(result.Events, event)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue