Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions pycaption/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -425,6 +425,23 @@ def remove_empty_captions(self):
out_captions.append(caption)
self.set_captions(lang, out_captions)

def remove_styling(self):
"""
Removes structured styling from all captions in all languages.

Unlike ``strip_html_tags`` (which only removes literal markup found
in TEXT node content), this removes styling that readers store
structurally: ``CaptionNode.STYLE`` nodes and the per-caption
``style`` attribute. Writers generate style tags (e.g. ``<i>`` in
WebVTT) from these at write time, so this is what actually prevents
formats like SCC from producing styled output.
"""
for lang in self.get_languages():
captions = self.get_captions(lang)
for caption in captions:
caption.style = {}
caption.nodes = [node for node in caption.nodes if node.type_ != CaptionNode.STYLE]

def remove_layout_info(self):
"""
Removes layout info from all captions and nodes in all languages.
Expand Down
38 changes: 37 additions & 1 deletion tests/test_base.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import pytest

from pycaption.base import CaptionList, Caption
from pycaption.base import CaptionList, Caption, CaptionNode, CaptionSet


class TestCaption:
Expand Down Expand Up @@ -56,3 +56,39 @@ def test_add_two_caption_lists(self):

with pytest.raises(ValueError):
newcaps = self.caps + CaptionList([4], layout_info="Other Layout")


class TestCaptionSetRemoveStyling:
def setup_method(self):
nodes = [
CaptionNode.create_style(True, {"italics": True}),
CaptionNode.create_text("hello"),
CaptionNode.create_style(False, {"italics": True}),
CaptionNode.create_break(),
CaptionNode.create_text("world"),
]
self.caption = Caption(0, 1000, nodes, style={"italics": True})
self.caption_set = CaptionSet({"en": CaptionList([self.caption])})

def test_removes_style_nodes(self):
self.caption_set.remove_styling()

node_types = [node.type_ for node in self.caption.nodes]
assert CaptionNode.STYLE not in node_types

def test_clears_caption_style_attribute(self):
self.caption_set.remove_styling()

assert self.caption.style == {}

def test_preserves_text_and_break_nodes(self):
self.caption_set.remove_styling()

remaining = [
(node.type_, node.content) for node in self.caption.nodes
]
assert remaining == [
(CaptionNode.TEXT, "hello"),
(CaptionNode.BREAK, None),
(CaptionNode.TEXT, "world"),
]
Loading