def test_simple_read(): ref = build_ref() subs1 = SSAFile.from_string(SIMPLE_ASS_REF) subs2 = SSAFile.from_string(SIMPLE_SSA_REF) assert ref.equals(subs1) assert ref.equals(subs2)
def test_no_space_after_colon_in_metadata_section(): # see issue #14 ref = SSAFile.from_string(AEGISUB_PROJECT_GARBAGE_FILE) subs = SSAFile.from_string(AEGISUB_PROJECT_GARBAGE_FILE_WITHOUT_SPACE_AFTER_COLON) assert ref.equals(subs) assert ref.aegisub_project == subs.aegisub_project
def test_simple_parsing(): test_input1 = "[123][456] Line 1" subs1 = SSAFile.from_string(test_input1) assert len(subs1) == 1 assert subs1[0] == SSAEvent(start=make_time(ms=12300), end=make_time(ms=45600), text="Line 1") test_input2 = "[123][456] / Line 1| Line 2/2" subs2 = SSAFile.from_string(test_input2) assert len(subs2) == 1 assert subs2[0] == SSAEvent(start=make_time(ms=12300), end=make_time(ms=45600), text="{\i1}Line 1{\i0}\\NLine2/2") test_input3 = dedent(""" [123][456] Line 1 [321][456] / Line 2| Line 3 (123)(456)This line should not be parsed This line should also not be parsed [789][1234] /Line 4""") subs3 = SSAFile.from_string(test_input3) assert len(subs3) == 3 assert subs3[0] == SSAEvent(start=make_time(ms=12300), end=make_time(ms=45600), text="Line 1") assert subs3[1] == SSAEvent(start=make_time(ms=32100), end=make_time(ms=45600), text="{\i1}Line 2{\i0}\\NLine 3") assert subs3[2] == SSAEvent(start=make_time(ms=78900), end=make_time(ms=123400), text="{\i1}Line 4{\i0}")
def test_write_drawing(): # test for 7bde9a6c3a250cf0880a8a9fe31d1b6a69ff21a0 subs = SSAFile() e1 = SSAEvent() e1.start = 0 e1.end = 60000 e1.text = r"{\p1}m 0 0 l 100 0 100 100 0 100{\p0}test" e2 = SSAEvent() e2.start = 60000 e2.end = 120000 e2.text = "Subtitle number\\Ntwo." subs.append(e1) subs.append(e2) ref = dedent("""\ 1 00:01:00,000 --> 00:02:00,000 Subtitle number two. """) text = subs.to_string("srt") assert text.strip() == ref.strip()
def append_subs(combined_subs, new_subs, style=None, formatter=None, exclude=None): """ Append a set of subs to a current set avoiding a clash if needed. Also allows for styling and formatting """ if exclude is None: exclude = [] new_combined_subs = SSAFile() if combined_subs: # First add the subs we are keeping new_combined_subs.extend(combined_subs) for sub in new_subs: # Add a style if style: sub.style = style # Perform the formatting if formatter: sub.text = formatter(sub.text) # See if we want to cater for clashes sub, second_sub = _adjust_for_clashing_subs(combined_subs, sub, exclude) # Prepare results if sub: new_combined_subs.append(sub) if second_sub: new_combined_subs.append(second_sub) new_combined_subs.sort() return new_combined_subs
def build_ref(): subs = SSAFile() subs.info["My Custom Info"] = "Some: Test, String." subs.styles["left"] = SSAStyle(alignment=7, bold=True) subs.styles["topleft"] = SSAStyle(alignment=4) subs.append(SSAEvent(start=0, end=make_time(m=1), text="An, example, subtitle.")) subs.append(SSAEvent(start=0, end=make_time(m=1), type="Comment", text="You can't see this one.")) subs.append(SSAEvent(start=make_time(m=1), end=make_time(m=2), text="Subtitle number\\Ntwo.")) return subs
def test_repr_simple(): subs = SSAFile() subs.append(SSAEvent(start=make_time(m=5), end=make_time(m=6))) subs.append(SSAEvent(start=make_time(m=125), end=make_time(m=126))) subs.append(SSAEvent(start=make_time(m=15), end=make_time(m=16))) subs.styles["style1"] = SSAStyle() subs.styles["style2"] = SSAStyle() ref = "<SSAFile with 3 events and 3 styles, last timestamp 2:06:00>" assert repr(subs) == ref
def test_writer_strips_tags(): subs = SSAFile() subs.append(SSAEvent(start=0, end=10, text="Let me tell you{a secret}.")) f = dedent("""\ {0}{0}1000 {0}{10}Let me tell you. """) assert subs.to_string("microdvd", fps=1000) == f
def test_read_complex(): # regression test for #30 text = dedent("""\ WEBVTT X-TIMESTAMP-MAP=LOCAL:00:00:00.000,MPEGTS:0 00:50.099 --> 00:53.299 line:85% align:middle Cuidem do seu grupo. Cuidem de suas fileiras. 01:54.255 --> 01:55.455 line:85% align:middle Parem! 01:58.155 --> 01:59.555 line:85% align:middle E, parem! """) ref = SSAFile() ref.append( SSAEvent(start=make_time(s=50, ms=99), end=make_time(s=53, ms=299), text=r"Cuidem do seu grupo.\NCuidem de suas fileiras.")) ref.append( SSAEvent(start=make_time(m=1, s=54, ms=255), end=make_time(m=1, s=55, ms=455), text="Parem!")) ref.append( SSAEvent(start=make_time(m=1, s=58, ms=155), end=make_time(m=1, s=59, ms=555), text="E, parem!")) subs = SSAFile.from_string(text) assert subs.equals(ref)
def test_import_styles(): red1 = SSAStyle() red2 = SSAStyle() green = SSAStyle() subs1 = SSAFile() subs2 = SSAFile() def prepare(): subs1.styles = {} subs2.styles = {} subs1.styles["green"] = green subs1.styles["red"] = red1 subs2.styles["red"] = red2 prepare() subs2.import_styles(subs1) assert subs2.styles["green"] is green assert subs2.styles["red"] is red1 prepare() subs2.import_styles(subs1, overwrite=False) assert subs2.styles["green"] is green assert subs2.styles["red"] is red2 with assert_raises(TypeError): subs2.import_styles({})
def test_writer_handles_whitespace(): subs = SSAFile() subs.append(SSAEvent(start=0, end=10, text=r"Hello,\hworld!\NSo many\N\nNewlines.")) f = dedent("""\ {0}{0}1000 {0}{10}Hello, world!|So many||Newlines. """) assert subs.to_string("microdvd", fps=1000) == f
def to_subtitles(response): subtitles = SSAFile() subtitles.events = [ SSAEvent( text=result.alternatives[0].transcript, start=duration_to_ms(result.alternatives[0].words[0].start_time), end=duration_to_ms(result.alternatives[0].words[-1].end_time), ) for result in response.results ] return subtitles
def test_writer_uses_original_fps(): subs = SSAFile() subs.append(SSAEvent(start=0, end=10, text="Hello!")) subs.fps = 1000 f = dedent("""\ {0}{0}1000 {0}{10}Hello! """) assert subs.to_string("microdvd") == f
def test_writer_skips_comment_lines(): subs = SSAFile() subs.append(SSAEvent(start=0, end=10, text="Hello!")) subs.append(SSAEvent(start=0, end=10, text="World!")) subs[0].is_comment = True f = dedent("""\ {0}{0}1000 {0}{10}World! """) assert subs.to_string("microdvd", fps=1000) == f
def test_writer_handles_whitespace(): subs = SSAFile() subs.append( SSAEvent(start=0, end=10, text=r"Hello,\hworld!\NSo many\N\nNewlines.")) f = dedent("""\ {0}{0}1000 {0}{10}Hello, world!|So many||Newlines. """) assert subs.to_string("microdvd", fps=1000) == f
def test_non_ascii_str_fields(): # see issue #12 STYLE_NAME = "my-style" FONT_NAME = b"NonAsciiString\xff" subs = SSAFile() line = SSAEvent(style=STYLE_NAME) subs.events.append(line) style = SSAStyle(fontname=FONT_NAME) subs.styles[STYLE_NAME] = style # in all Pythons, saving subtitles with non-unicode fields # fails when they are not in ASCII range with assert_raises(TypeError): subs.to_string("ass")
def test_simple_writing(): subs = SSAFile() subs.append(SSAEvent(start=0, end=1000, text="Hello!")) subs.append(SSAEvent(start=1000, end=2000, text="Hello World!\\NTwo-line subtitle!")) subs.append(SSAEvent(start=2000, end=3000, text="{\i1}This is an italic line {with some hidden content}")) subs.append(SSAEvent(start=3000, end=4000, text="This is a comment line")) subs[-1].is_comment = True reference_output = dedent("""\ [0][10] Hello! [10][20] Hello World!|Two-line subtitle! [20][30] This is an italic line """) assert subs.to_string("mpl2").strip() == reference_output.strip()
def test_read_bad_tags(): """missing opening/closing tag, bad nesting, extra whitespace""" text = dedent("""\ 1 00:00:10,500 --> 00:00:13,000 < u><i><font color="red" >Elephant's < s>Dream< / i > Is Long</s> And Badly Nested</xyz> """) ref = SSAFile() ref.append(SSAEvent(start=make_time(s=10.5), end=make_time(s=13), text="{\\u1}{\\i1}Elephant's {\\s1}Dream{\\i0} Is Long{\\s0} And Badly Nested")) subs = SSAFile.from_string(text) assert subs.equals(ref)
def add_effects(subtitles): effected_subs = SSAFile() for sub in subtitles: content = sub.plaintext.strip().replace('\n', ' ') time_per_syllable = (sub.end - sub.start) / syllables.estimate(content) current_time = sub.start current_index = 0 for word in content.split(' '): sylls = syllables.estimate(word) sub_end_time = current_time + time_per_syllable * sylls current_index += len(word) if current_index == 0 else len(word) + 1 text = content[:current_index] + '{\\alpha&HFF}' + content[ current_index:] # adds transparency effected_subs.append( SSAEvent(start=current_time, end=sub_end_time, text=text)) current_time = sub_end_time return effected_subs
def save_to_subtitles(results, formatter): """ Save to subtitle file :param results: Dictionary containing info and start/end times :param formatter: Apply text formating to the subtitle :return: New subtitle file """ subs = SSAFile() for result in results: event = SSAEvent(start=make_time(s=result['start']), end=make_time(s=result['end']), text=formatter(result)) if 'highlight' in result and result['highlight']: event.style = 'red' subs.append(event) logger.info(f'Processed {len(results)} results to subtitle events') return subs
def create_ssa_file(): subs = SSAFile() subs.styles['top'] = SSAStyle(alignment=8) subs.styles['bottom'] = SSAStyle(alignment=2) subs.styles['left'] = SSAStyle(alignment=4) subs.styles['left_red'] = SSAStyle(alignment=4, primarycolor=Color(255, 0, 0, 0)) subs.styles['red'] = SSAStyle(primarycolor=Color(255, 0, 0, 0)) subs.styles['right'] = SSAStyle(alignment=6) return subs
def test_insertion_of_wrong_type(): subs = SSAFile() subs.append(SSAEvent()) with assert_raises(TypeError): subs.append(42) with assert_raises(TypeError): subs.insert(42) with assert_raises(TypeError): subs[0] = 42
def test_simple_write(): subs = SSAFile() e1 = SSAEvent() e1.start = 0 e1.end = 60000 e1.text = "ten--chars" e2 = SSAEvent() e2.start = 60000 e2.end = 120000 e2.text = "ten--chars-ten-chars" e3 = SSAEvent() e3.start = 60000 e3.end = 120000 e3.text = "Invisible subtitle." e3.is_comment = True subs.append(e1) subs.append(e2) subs.append(e3) ref = dedent("""\ 00:00:00:ten--chars 00:01:00:ten--chars-ten-chars """) text = subs.to_string("tmp") assert text.strip() == ref.strip()
def test_read_position_styling(): """position is ignored, italic is converted, color is ignored""" text = dedent("""\ 1 00:00:10,500 --> 00:00:13,000 X1:63 X2:223 Y1:43 Y2:58 <i>Elephant's Dream</i> 2 00:00:15,000 --> 00:00:18,000 X1:53 X2:303 Y1:438 Y2:453 <font color="cyan">At the left we can see...</font> """) ref = SSAFile() ref.append( SSAEvent(start=make_time(s=10.5), end=make_time(s=13), text="{\\i1}Elephant's Dream{\\i0}")) ref.append( SSAEvent(start=make_time(s=15), end=make_time(s=18), text="At the left we can see...")) subs = SSAFile.from_string(text) assert subs.equals(ref)
def test_empty_subtitles(): # regression test for issue #11 text = dedent(""" 392 00:29:27,46 --> 00:29:29,83 I'm Liza Minnelli.. 393 00:00:00,00 --> 00:00:00,00 394 00:00:00,00 --> 00:00:00,00 """) ref = SSAFile() ref.append( SSAEvent(start=make_time(m=29, s=27, ms=460), end=make_time(m=29, s=29, ms=830), text="I'm Liza Minnelli..")) ref.append(SSAEvent(start=0, end=0, text="")) ref.append(SSAEvent(start=0, end=0, text="")) subs = SSAFile.from_string(text) assert subs.equals(ref)
def create_ass_file(subtitle_blocks: List[SubtitleBlock], ass_file, styles: Dict[str, StyleConfig]): subs = SSAFile() colors = [Color(255, 255, 255), Color(100, 100, 255), Color(255, 100, 100)] for k, name in enumerate(subtitle_blocks[0].names): my_style = subs.styles["Default"].copy() my_style.primarycolor = colors[k] my_style.fontsize = styles[name].fontsize my_style.shadow = 0 subs.styles[name] = my_style for sb in subtitle_blocks: start, end = None, None for name, text in sb.name_texts: if len(text) > 0: text = text.replace("_", " ") if start is None: start = sb.start end = sb.end sub_line = SSAEvent( start=start, end=end, text=text, ) sub_line.style = name subs.append(sub_line) else: print(f"WARNING: got empty block! {name} ") subs.save(ass_file)
def test_negative_timestamp_read(): ref = build_ref() subs = SSAFile.from_string(NEGATIVE_TIMESTAMP_ASS_REF) # negative timestamp is read correctly assert subs[0].start == -make_time(1, 59, 54, 930) # negative times are flushed to zero on output assert ref.to_string("ass") == subs.to_string("ass")
def get_empty_sub(): text = ''' 1 00:00:00,000 --> 00:00:05,000 An example SubRip file. ''' subs = SSAFile.from_string(text) subs.__delitem__(0) return subs
def test_shift(): #TODO: write more tests subs = SSAFile() with assert_raises(ValueError): subs.shift(frames=5) with assert_raises(ValueError): subs.shift(fps=23.976) with assert_raises(ValueError): subs.shift(frames=5, fps=-1)
def test_writer_tags(): subs = SSAFile() subs.styles["italic_style"] = SSAStyle(italic=True) subs.events = [SSAEvent(start=0, end=10, text=r"Plain."), SSAEvent(start=0, end=10, text=r"{\i1}Inline."), SSAEvent(start=0, end=10, text=r"Styled.", style="italic_style"), SSAEvent(start=0, end=10, text=r"{\i1}Also{\i0} {\ritalic_style}italic."), SSAEvent(start=0, end=10, text=r"Not {\i1}italic.")] f = dedent("""\ {0}{0}1000 {0}{10}Plain. {0}{10}{Y:i}Inline. {0}{10}{Y:i}Styled. {0}{10}{Y:i}Also italic. {0}{10}Not italic. """) assert subs.to_string("microdvd", 1000) == f
def search_subtitles(self, subtitles, search_str): ix = create_in(tmp_dir, self.schema) with ix.writer() as ix_writer: for i, subtitle in enumerate(subtitles): ix_writer.add_document(index=i, content=subtitle.text) with ix.searcher() as ix_searcher: query = QueryParser('content', ix.schema).parse(search_str) results = ix_searcher.search(query) sorted_results = sorted(results, key=itemgetter('index')) ix.close() max_idx = len(subtitles) - 1 extracted = [] i = 0 while i < len(sorted_results): score = 0 subs = SSAFile() while i+len(subs) < len(sorted_results) \ and sorted_results[i+len(subs)]['index'] == sorted_results[i]['index']+len(subs): score = max(score, sorted_results[i + len(subs)].score) subs.append(subtitles[sorted_results[i + len(subs)]['index']]) lower_index = sorted_results[i]['index'] upper_index = sorted_results[i + len(subs) - 1]['index'] extracted.append( ExtractedSubtitles( subs, score, None if lower_index - 1 < 0 else subtitles[lower_index - 1].end, None if upper_index + 1 > max_idx else subtitles[upper_index + 1].start, )) i += len(subs) return extracted
def test_aegisub_project_garbage(): subs = SSAFile.from_string(AEGISUB_PROJECT_GARBAGE_FILE) garbage_section = dedent(""" [Aegisub Project Garbage] Last Style Storage: Default Video File: ?dummy:23.976000:40000:640:480:47:163:254: Video AR Value: 1.333333 Video Zoom Percent: 0.500000 Active Line: 2""") assert garbage_section in subs.to_string("ass")
def test_extra_whitespace_parsing(): f = dedent("""\ { 0 } { 0 } 1000.0 { 10 }{ 20} Hello! """) subs = SSAFile.from_string(f) assert subs[0] == SSAEvent(start=10, end=20, text="Hello!")
def test_tags_parsing(): f1 = "{10}{20}{Y:i,u}Hello!" subs1 = SSAFile.from_string(f1, fps=1000) assert subs1[0].text == "{\\i1\\u1}Hello!" f2 = "{10}{20}Hello, {f:Comic Sans MS}world!" subs2 = SSAFile.from_string(f2, fps=1000) assert subs2[0].text == r"Hello, {\fnComic Sans MS}world!" # the C tag is not supported, unsupported tags are copied verbatim f3 = "{10}{20}Hello, {c:$0000FF}world!" subs3 = SSAFile.from_string(f3, fps=1000) assert subs3[0].text == r"Hello, {c:$0000FF}world!" f4 = "{10}{20}Hello, {P:100,200}world!" subs4 = SSAFile.from_string(f4, fps=1000) assert subs4[0].text == r"Hello, {\pos(100,200)}world!" f5 = "{10}{20}Hello, {s:72}world!" subs5 = SSAFile.from_string(f5, fps=1000) assert subs5[0].text == r"Hello, {\fs72}world!"
def build(self, **extra): from pysubs2 import SSAFile, SSAEvent, Color # type: ignore[import] millis = lambda td: td / timedelta(milliseconds=1) subs = ( SSAEvent( start=millis(t - self.start), end =millis(t - self.start + timedelta(seconds=length)), text=text.replace('\n', r'\N'), # \N necessary for SSA files ) for t, text, length in self.l ) sf = SSAFile() style = sf.styles['Default'].copy() style.fontsize = 16 # default is 20, bit too much?? style.outlinecolor = Color(0, 0, 0, 50) # semitransparent style.shadow = 0.0 style.outline = 0.1 style.borderstyle = 3 # no idea why 3, but it makes the background apperar in conjunction with outline for k, v in extra.items(): setattr(style, k, v) sf.styles['Default'] = style for s in subs: sf.append(s) return sf.to_string('ass')
def test_parser_skipping_lines(): f = dedent("""\ Ook! {0}{0}23.976 > Hi! {10}{20}Hello! 1 00:00:00,000 --> 00:00:05,000 When editing their SRT files, some people get so careless as to paste them in their MicroDVD files! """) subs = SSAFile.from_string(f, format_="microdvd") assert len(subs) == 1 assert subs[0].text == "Hello!"
def test_framerate_inference(): fps = 1000.0 has_fps = dedent("""\ {0}{0}1000.0 {10}{20}Hello! """) no_fps = dedent("""\ {10}{20}Hello! """) ignored_fps = dedent("""\ {0}{0}23.976 {10}{20}Hello! """) illegal_fps = dedent("""\ {0}{0}-23.976 {10}{20}Hello! """) subs1 = SSAFile.from_string(has_fps) assert subs1.fps == fps assert len(subs1) == 1 assert subs1[0] == SSAEvent(start=10, end=20, text="Hello!") subs2 = SSAFile.from_string(no_fps, fps=fps) assert subs2.fps == fps assert len(subs2) == 1 assert subs2[0] == SSAEvent(start=10, end=20, text="Hello!") # fps argument takes preference over what the file says, first line is kept subs3 = SSAFile.from_string(ignored_fps, fps=fps) assert subs3.fps == fps assert len(subs3) == 2 assert subs3[0] == SSAEvent(start=0, end=0, text="23.976") assert subs3[1] == SSAEvent(start=10, end=20, text="Hello!") with assert_raises(UnknownFPSError): SSAFile.from_string(no_fps) with assert_raises(ValueError): SSAFile.from_string(illegal_fps)
def test_write_read(): subs = SSAFile() e1 = SSAEvent(text="Hello, world!") e2 = SSAEvent(text="The other subtitle.\\NWith two lines.", style="custom style") s1 = SSAStyle(italic=True, primarycolor=Color(r=255, g=0, b=0, a=0)) subs.append(e1) subs.append(e2) subs.styles["custom style"] = s1 json_text = subs.to_string("json") subs2 = SSAFile.from_string(json_text, "json") assert subs2.equals(subs)
def test_read_malformed(): """no line number, no empty line, leading whitespace, bad timestamp format""" text = dedent("""\ 00:00:00.000 ->00:01:00.000 An example subtitle. 0:01:00,00 --> 0:02:00,00 Subtitle number two. """) ref = SSAFile() ref.append(SSAEvent(start=0, end=make_time(m=1), text="An example subtitle.")) ref.append(SSAEvent(start=make_time(m=1), end=make_time(m=2), text="Subtitle number\\Ntwo.")) subs = SSAFile.from_string(text) assert subs.equals(ref)
def test_ascii_str_fields(): # see issue #12 STYLE_NAME = b"top-style" subs = SSAFile() line = SSAEvent(style=STYLE_NAME) subs.events.append(line) style = SSAStyle() subs.styles[STYLE_NAME] = style if sys.version_info.major == 2: # in Python 2, saving subtitles with non-unicode fields is tolerated # as long as they do not fall outside of ASCII range subs.to_string("ass") else: # in Python 3, we are strict and enforce Unicode with assert_raises(TypeError): subs.to_string("ass")
def test_simple_read(): text = dedent("""\ 1 00:00:00,000 --> 00:01:00,000 An example subtitle. 2 00:01:00,000 --> 00:02:00,000 Subtitle number two. """) ref = SSAFile() ref.append(SSAEvent(start=0, end=make_time(m=1), text="An example subtitle.")) ref.append(SSAEvent(start=make_time(m=1), end=make_time(m=2), text="Subtitle number\\Ntwo.")) subs = SSAFile.from_string(text) assert subs.equals(ref)
def test_read_position_styling(): """position is ignored, italic is converted, color is ignored""" text = dedent("""\ 1 00:00:10,500 --> 00:00:13,000 X1:63 X2:223 Y1:43 Y2:58 <i>Elephant's Dream</i> 2 00:00:15,000 --> 00:00:18,000 X1:53 X2:303 Y1:438 Y2:453 <font color="cyan">At the left we can see...</font> """) ref = SSAFile() ref.append(SSAEvent(start=make_time(s=10.5), end=make_time(s=13), text="{\\i1}Elephant's Dream{\\i0}")) ref.append(SSAEvent(start=make_time(s=15), end=make_time(s=18), text="At the left we can see...")) subs = SSAFile.from_string(text) assert subs.equals(ref)
def test_empty_subtitles(): # regression test for issue #11 text = dedent(""" 392 00:29:27,46 --> 00:29:29,83 I'm Liza Minnelli.. 393 00:00:00,00 --> 00:00:00,00 394 00:00:00,00 --> 00:00:00,00 """) ref = SSAFile() ref.append(SSAEvent(start=make_time(m=29, s=27, ms=460), end=make_time(m=29, s=29, ms=830), text="I'm Liza Minnelli..")) ref.append(SSAEvent(start=0, end=0, text="")) ref.append(SSAEvent(start=0, end=0, text="")) subs = SSAFile.from_string(text) assert subs.equals(ref)
def test_simple_write(): subs = SSAFile() e1 = SSAEvent() e1.start = 0 e1.end = 60000 e1.text = "An example subtitle." e2 = SSAEvent() e2.start = 60000 e2.end = 120000 e2.text = "Subtitle number\\Ntwo." e3 = SSAEvent() e3.start = 60000 e3.end = 120000 e3.text = "Invisible subtitle." e3.is_comment = True subs.append(e1) subs.append(e2) subs.append(e3) ref = dedent("""\ 1 00:00:00,000 --> 00:01:00,000 An example subtitle. 2 00:01:00,000 --> 00:02:00,000 Subtitle number two. """) text = subs.to_string("srt") assert text.strip() == ref.strip()
def test_rename_style(): subs = SSAFile() red = SSAStyle() green = SSAStyle() def prepare(): subs.events = [SSAEvent(style="red"), SSAEvent(style="unrelated")] subs.styles = dict(red=red, green=green) prepare() subs.rename_style("red", "blue") assert "red" not in subs.styles assert subs.styles["blue"] is red assert subs[0].style == "blue" assert subs[1].style == "unrelated" prepare() with assert_raises(ValueError): # cannot delete style via move subs.rename_style("red", "green") prepare() with assert_raises(ValueError): subs.rename_style("red", "illegal,name") with assert_raises(ValueError): subs.rename_style("red", "illegal\nname") with assert_raises(KeyError): subs.rename_style("nonexistent-style", "blue")
def test_newlines_parsing(): f = "{10}{20} So|Many||Newlines ||| " subs = SSAFile.from_string(f, fps=1000) assert subs[0].text == r"So\NMany\N\NNewlines \N\N\N"
def test_transform_framerate(): subs = SSAFile() subs.append(SSAEvent(start=0, end=10)) subs.append(SSAEvent(start=1000, end=1010)) with assert_raises(ValueError): subs.transform_framerate(1, 0) with assert_raises(ValueError): subs.transform_framerate(1, -1) with assert_raises(ValueError): subs.transform_framerate(0, 1) with assert_raises(ValueError): subs.transform_framerate(-1, 1) subs.transform_framerate(10, 20) assert subs[0] == SSAEvent(start=0, end=5) assert subs[1] == SSAEvent(start=500, end=505)