diff --git a/srt.go b/srt.go
index 2cbb323..a47321a 100644
--- a/srt.go
+++ b/srt.go
@@ -38,11 +38,11 @@ func ReadFromSRT(i io.Reader) (o *Subtitles, err error) {
o = NewSubtitles()
var scanner = bufio.NewScanner(i)
- styles := StyleAttributes{}
// Scan
var line string
var lineNum int
var s = &Item{}
+ var sa = &StyleAttributes{}
for scanner.Scan() {
// Fetch line
line = strings.TrimSpace(scanner.Text())
@@ -59,9 +59,8 @@ func ReadFromSRT(i io.Reader) (o *Subtitles, err error) {
// Line contains time boundaries
if strings.Contains(line, srtTimeBoundariesSeparator) {
-
- // reset styles
- styles = StyleAttributes{}
+ // Reset style attributes
+ sa = &StyleAttributes{}
// Remove last item of previous subtitle since it should be the index.
// If the last line is empty then the item is missing an index.
@@ -123,8 +122,7 @@ func ReadFromSRT(i io.Reader) (o *Subtitles, err error) {
o.Items = append(o.Items, s)
} else {
// Add text
- var l Line
- if l, styles = parseTextSrt(line, styles); len(l.Items) > 0 {
+ if l := parseTextSrt(line, sa); len(l.Items) > 0 {
s.Lines = append(s.Lines, l)
}
}
@@ -133,12 +131,11 @@ func ReadFromSRT(i io.Reader) (o *Subtitles, err error) {
}
// parseTextSrt parses the input line to fill the Line
-func parseTextSrt(i string, styles StyleAttributes) (Line, StyleAttributes) {
+func parseTextSrt(i string, sa *StyleAttributes) (o Line) {
// special handling needed for empty line
- o := Line{}
- if i == "" {
+ if strings.TrimSpace(i) == "" {
o.Items = []LineItem{{Text: ""}}
- return o, styles
+ return
}
// Create tokenizer
@@ -164,51 +161,51 @@ func parseTextSrt(i string, styles StyleAttributes) (Line, StyleAttributes) {
// Parse italic/bold/underline
switch token.Data {
case "b":
- styles.SRTBold = false
+ sa.SRTBold = false
case "i":
- styles.SRTItalics = false
+ sa.SRTItalics = false
case "u":
- styles.SRTUnderline = false
+ sa.SRTUnderline = false
case "font":
- styles.SRTColor = nil
+ sa.SRTColor = nil
}
case html.StartTagToken:
// Parse italic/bold/underline
switch token.Data {
case "b":
- styles.SRTBold = true
+ sa.SRTBold = true
case "i":
- styles.SRTItalics = true
+ sa.SRTItalics = true
case "u":
- styles.SRTUnderline = true
+ sa.SRTUnderline = true
case "font":
if c := htmlTokenAttribute(&token, "color"); c != nil {
- styles.SRTColor = c
+ sa.SRTColor = c
}
}
case html.TextToken:
if s := strings.TrimSpace(raw); s != "" {
// Get style attribute
- var sa *StyleAttributes
- if styles.SRTBold || styles.SRTColor != nil || styles.SRTItalics || styles.SRTUnderline {
- sa = &StyleAttributes{
- SRTBold: styles.SRTBold,
- SRTColor: styles.SRTColor,
- SRTItalics: styles.SRTItalics,
- SRTUnderline: styles.SRTUnderline,
+ var styleAttributes *StyleAttributes
+ if sa.SRTBold || sa.SRTColor != nil || sa.SRTItalics || sa.SRTUnderline {
+ styleAttributes = &StyleAttributes{
+ SRTBold: sa.SRTBold,
+ SRTColor: sa.SRTColor,
+ SRTItalics: sa.SRTItalics,
+ SRTUnderline: sa.SRTUnderline,
}
- sa.propagateSRTAttributes()
+ styleAttributes.propagateSRTAttributes()
}
// Append item
o.Items = append(o.Items, LineItem{
- InlineStyle: sa,
+ InlineStyle: styleAttributes,
Text: unescapeHTML(s),
})
}
}
}
- return o, styles
+ return
}
// formatDurationSRT formats an .srt duration
diff --git a/webvtt.go b/webvtt.go
index 0b79dbf..af75a93 100644
--- a/webvtt.go
+++ b/webvtt.go
@@ -121,7 +121,6 @@ func ReadFromWebVTT(i io.Reader) (o *Subtitles, err error) {
var scanner = bufio.NewScanner(i)
var line string
var lineNum int
- webVTTTagStack := make([]WebVTTTag, 0, 16)
// Skip the header
for scanner.Scan() {
@@ -142,7 +141,7 @@ func ReadFromWebVTT(i io.Reader) (o *Subtitles, err error) {
var blockName string
var comments []string
var index int
- var webVTTStyles *StyleAttributes
+ var sa = &StyleAttributes{}
for scanner.Scan() {
// Fetch line
@@ -163,13 +162,14 @@ func ReadFromWebVTT(i io.Reader) (o *Subtitles, err error) {
// Reset block name, if we are not in the middle of CSS.
// If we are in STYLE block and the CSS is empty or we meet the right brace at the end of last line,
// then we are not in CSS and can switch to parse next WebVTT block.
- if blockName != webvttBlockNameStyle || webVTTStyles == nil ||
- len(webVTTStyles.WebVTTStyles) == 0 ||
- strings.HasSuffix(webVTTStyles.WebVTTStyles[len(webVTTStyles.WebVTTStyles)-1], "}") {
+ if blockName != webvttBlockNameStyle || sa == nil ||
+ len(sa.WebVTTStyles) == 0 ||
+ strings.HasSuffix(sa.WebVTTStyles[len(sa.WebVTTStyles)-1], "}") {
blockName = ""
}
- // Reset tag stack
- webVTTTagStack = make([]WebVTTTag, 0, 16)
+
+ // Reset WebVTTTags
+ sa.WebVTTTags = []WebVTTTag{}
// Region
case strings.HasPrefix(line, "Region: "):
@@ -211,9 +211,9 @@ func ReadFromWebVTT(i io.Reader) (o *Subtitles, err error) {
blockName = webvttBlockNameStyle
if _, ok := o.Styles[webvttDefaultStyleID]; !ok {
- webVTTStyles = &StyleAttributes{}
+ sa = &StyleAttributes{}
o.Styles[webvttDefaultStyleID] = &Style{
- InlineStyle: webVTTStyles,
+ InlineStyle: sa,
ID: webvttDefaultStyleID,
}
}
@@ -318,12 +318,11 @@ func ReadFromWebVTT(i io.Reader) (o *Subtitles, err error) {
case webvttBlockNameComment:
comments = append(comments, line)
case webvttBlockNameStyle:
- webVTTStyles.WebVTTStyles = append(webVTTStyles.WebVTTStyles, line)
+ sa.WebVTTStyles = append(sa.WebVTTStyles, line)
case webvttBlockNameText:
// Parse line
- if l, stack := parseTextWebVTT(line, webVTTTagStack); len(l.Items) > 0 {
+ if l := parseTextWebVTT(line, sa); len(l.Items) > 0 {
item.Lines = append(item.Lines, l)
- webVTTTagStack = stack
}
default:
// This is the ID
@@ -335,10 +334,9 @@ func ReadFromWebVTT(i io.Reader) (o *Subtitles, err error) {
}
// parseTextWebVTT parses the input line to fill the Line
-func parseTextWebVTT(i string, webVTTTagStack []WebVTTTag) (Line, []WebVTTTag) {
+func parseTextWebVTT(i string, sa *StyleAttributes) (o Line) {
// Create tokenizer
tr := html.NewTokenizer(strings.NewReader(i))
- o := Line{}
// Loop
for {
@@ -352,8 +350,8 @@ func parseTextWebVTT(i string, webVTTTagStack []WebVTTTag) (Line, []WebVTTTag) {
switch t {
case html.EndTagToken:
// Pop the top of stack if we meet end tag
- if len(webVTTTagStack) > 0 {
- webVTTTagStack = webVTTTagStack[:len(webVTTTagStack)-1]
+ if len(sa.WebVTTTags) > 0 {
+ sa.WebVTTTags = sa.WebVTTTags[:len(sa.WebVTTTags)-1]
}
case html.StartTagToken:
if matches := webVTTRegexpTag.FindStringSubmatch(string(tr.Raw())); len(matches) > 4 {
@@ -381,7 +379,7 @@ func parseTextWebVTT(i string, webVTTTagStack []WebVTTTag) (Line, []WebVTTTag) {
}
// Push the tag to stack
- webVTTTagStack = append(webVTTTagStack, WebVTTTag{
+ sa.WebVTTTags = append(sa.WebVTTTags, WebVTTTag{
Name: tagName,
Classes: classes,
Annotation: annotation,
@@ -390,21 +388,21 @@ func parseTextWebVTT(i string, webVTTTagStack []WebVTTTag) (Line, []WebVTTTag) {
case html.TextToken:
// Get style attribute
- var sa *StyleAttributes
- if len(webVTTTagStack) > 0 {
- tags := make([]WebVTTTag, len(webVTTTagStack))
- copy(tags, webVTTTagStack)
- sa = &StyleAttributes{
+ var styleAttributes *StyleAttributes
+ if len(sa.WebVTTTags) > 0 {
+ tags := make([]WebVTTTag, len(sa.WebVTTTags))
+ copy(tags, sa.WebVTTTags)
+ styleAttributes = &StyleAttributes{
WebVTTTags: tags,
}
- sa.propagateWebVTTAttributes()
+ styleAttributes.propagateWebVTTAttributes()
}
// Append items
- o.Items = append(o.Items, parseTextWebVTTTextToken(sa, string(tr.Raw()))...)
+ o.Items = append(o.Items, parseTextWebVTTTextToken(styleAttributes, string(tr.Raw()))...)
}
}
- return o, webVTTTagStack
+ return
}
func parseTextWebVTTTextToken(sa *StyleAttributes, line string) (ret []LineItem) {
diff --git a/webvtt_internal_test.go b/webvtt_internal_test.go
index 6845ffd..a81f224 100644
--- a/webvtt_internal_test.go
+++ b/webvtt_internal_test.go
@@ -13,7 +13,7 @@ func TestParseTextWebVTT(t *testing.T) {
t.Run("When both voice tags are available", func(t *testing.T) {
testData := `Correct tag`
- s, _ := parseTextWebVTT(testData, make([]WebVTTTag, 0, 16))
+ s := parseTextWebVTT(testData, &StyleAttributes{})
assert.Equal(t, "Bob", s.VoiceName)
assert.Equal(t, 1, len(s.Items))
assert.Equal(t, "Correct tag", s.Items[0].Text)
@@ -22,7 +22,7 @@ func TestParseTextWebVTT(t *testing.T) {
t.Run("When there is no end tag", func(t *testing.T) {
testData := ` Text without end tag`
- s, _ := parseTextWebVTT(testData, make([]WebVTTTag, 0, 16))
+ s := parseTextWebVTT(testData, &StyleAttributes{})
assert.Equal(t, "Bob", s.VoiceName)
assert.Equal(t, 1, len(s.Items))
assert.Equal(t, "Text without end tag", s.Items[0].Text)
@@ -31,7 +31,7 @@ func TestParseTextWebVTT(t *testing.T) {
t.Run("When the end tag is correct", func(t *testing.T) {
testData := `Incorrect end tag`
- s, _ := parseTextWebVTT(testData, make([]WebVTTTag, 0, 16))
+ s := parseTextWebVTT(testData, &StyleAttributes{})
assert.Equal(t, "Bob", s.VoiceName)
assert.Equal(t, 1, len(s.Items))
assert.Equal(t, "Incorrect end tag", s.Items[0].Text)
@@ -40,7 +40,7 @@ func TestParseTextWebVTT(t *testing.T) {
t.Run("When inline timestamps are included", func(t *testing.T) {
testData := `<00:01:01.000>With inline <00:01:02.000>timestamps`
- s, _ := parseTextWebVTT(testData, make([]WebVTTTag, 0, 16))
+ s := parseTextWebVTT(testData, &StyleAttributes{})
assert.Equal(t, 2, len(s.Items))
assert.Equal(t, "With inline", s.Items[0].Text)
assert.Equal(t, time.Minute+time.Second, s.Items[0].StartAt)
@@ -51,7 +51,7 @@ func TestParseTextWebVTT(t *testing.T) {
t.Run("When inline timestamps together", func(t *testing.T) {
testData := `<00:01:01.000><00:01:02.000>With timestamp tags together`
- s, _ := parseTextWebVTT(testData, make([]WebVTTTag, 0, 16))
+ s := parseTextWebVTT(testData, &StyleAttributes{})
assert.Equal(t, 1, len(s.Items))
assert.Equal(t, "With timestamp tags together", s.Items[0].Text)
assert.Equal(t, time.Minute+2*time.Second, s.Items[0].StartAt)
@@ -60,7 +60,7 @@ func TestParseTextWebVTT(t *testing.T) {
t.Run("When inline timestamps is at end", func(t *testing.T) {
testData := `With end timestamp<00:01:02.000>`
- s, _ := parseTextWebVTT(testData, make([]WebVTTTag, 0, 16))
+ s := parseTextWebVTT(testData, &StyleAttributes{})
assert.Equal(t, 1, len(s.Items))
assert.Equal(t, "With end timestamp", s.Items[0].Text)
assert.Equal(t, time.Duration(0), s.Items[0].StartAt)