pycaption 2.2.13__tar.gz → 2.2.15__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. {pycaption-2.2.13/pycaption.egg-info → pycaption-2.2.15}/PKG-INFO +1 -1
  2. {pycaption-2.2.13 → pycaption-2.2.15}/pycaption/scc/__init__.py +1 -2
  3. {pycaption-2.2.13 → pycaption-2.2.15}/pycaption/scc/constants.py +1 -1
  4. {pycaption-2.2.13 → pycaption-2.2.15}/pycaption/scc/specialized_collections.py +19 -3
  5. {pycaption-2.2.13 → pycaption-2.2.15}/pycaption/scc/state_machines.py +4 -1
  6. {pycaption-2.2.13 → pycaption-2.2.15}/pycaption/webvtt.py +2 -9
  7. {pycaption-2.2.13 → pycaption-2.2.15/pycaption.egg-info}/PKG-INFO +1 -1
  8. {pycaption-2.2.13 → pycaption-2.2.15}/setup.py +1 -1
  9. {pycaption-2.2.13 → pycaption-2.2.15}/tests/fixtures/scc.py +8 -0
  10. {pycaption-2.2.13 → pycaption-2.2.15}/tests/test_scc.py +7 -1
  11. {pycaption-2.2.13 → pycaption-2.2.15}/LICENSE +0 -0
  12. {pycaption-2.2.13 → pycaption-2.2.15}/MANIFEST.in +0 -0
  13. {pycaption-2.2.13 → pycaption-2.2.15}/README.rst +0 -0
  14. {pycaption-2.2.13 → pycaption-2.2.15}/pycaption/__init__.py +0 -0
  15. {pycaption-2.2.13 → pycaption-2.2.15}/pycaption/base.py +0 -0
  16. {pycaption-2.2.13 → pycaption-2.2.15}/pycaption/dfxp/__init__.py +0 -0
  17. {pycaption-2.2.13 → pycaption-2.2.15}/pycaption/dfxp/base.py +0 -0
  18. {pycaption-2.2.13 → pycaption-2.2.15}/pycaption/dfxp/extras.py +0 -0
  19. {pycaption-2.2.13 → pycaption-2.2.15}/pycaption/english.pickle +0 -0
  20. {pycaption-2.2.13 → pycaption-2.2.15}/pycaption/exceptions.py +0 -0
  21. {pycaption-2.2.13 → pycaption-2.2.15}/pycaption/geometry.py +0 -0
  22. {pycaption-2.2.13 → pycaption-2.2.15}/pycaption/microdvd.py +0 -0
  23. {pycaption-2.2.13 → pycaption-2.2.15}/pycaption/sami.py +0 -0
  24. {pycaption-2.2.13 → pycaption-2.2.15}/pycaption/scc/translator.py +0 -0
  25. {pycaption-2.2.13 → pycaption-2.2.15}/pycaption/srt.py +0 -0
  26. {pycaption-2.2.13 → pycaption-2.2.15}/pycaption/transcript.py +0 -0
  27. {pycaption-2.2.13 → pycaption-2.2.15}/pycaption/utils.py +0 -0
  28. {pycaption-2.2.13 → pycaption-2.2.15}/pycaption.egg-info/SOURCES.txt +0 -0
  29. {pycaption-2.2.13 → pycaption-2.2.15}/pycaption.egg-info/dependency_links.txt +0 -0
  30. {pycaption-2.2.13 → pycaption-2.2.15}/pycaption.egg-info/requires.txt +0 -0
  31. {pycaption-2.2.13 → pycaption-2.2.15}/pycaption.egg-info/top_level.txt +0 -0
  32. {pycaption-2.2.13 → pycaption-2.2.15}/setup.cfg +0 -0
  33. {pycaption-2.2.13 → pycaption-2.2.15}/tests/__init__.py +0 -0
  34. {pycaption-2.2.13 → pycaption-2.2.15}/tests/conftest.py +0 -0
  35. {pycaption-2.2.13 → pycaption-2.2.15}/tests/fixtures/__init__.py +0 -0
  36. {pycaption-2.2.13 → pycaption-2.2.15}/tests/fixtures/dfxp.py +0 -0
  37. {pycaption-2.2.13 → pycaption-2.2.15}/tests/fixtures/microdvd.py +0 -0
  38. {pycaption-2.2.13 → pycaption-2.2.15}/tests/fixtures/sami.py +0 -0
  39. {pycaption-2.2.13 → pycaption-2.2.15}/tests/fixtures/srt.py +0 -0
  40. {pycaption-2.2.13 → pycaption-2.2.15}/tests/fixtures/translated_scc.py +0 -0
  41. {pycaption-2.2.13 → pycaption-2.2.15}/tests/fixtures/webvtt.py +0 -0
  42. {pycaption-2.2.13 → pycaption-2.2.15}/tests/mixins.py +0 -0
  43. {pycaption-2.2.13 → pycaption-2.2.15}/tests/test_base.py +0 -0
  44. {pycaption-2.2.13 → pycaption-2.2.15}/tests/test_dfxp.py +0 -0
  45. {pycaption-2.2.13 → pycaption-2.2.15}/tests/test_dfxp_conversion.py +0 -0
  46. {pycaption-2.2.13 → pycaption-2.2.15}/tests/test_dfxp_extras.py +0 -0
  47. {pycaption-2.2.13 → pycaption-2.2.15}/tests/test_functions.py +0 -0
  48. {pycaption-2.2.13 → pycaption-2.2.15}/tests/test_geometry.py +0 -0
  49. {pycaption-2.2.13 → pycaption-2.2.15}/tests/test_microdvd.py +0 -0
  50. {pycaption-2.2.13 → pycaption-2.2.15}/tests/test_microdvd_conversion.py +0 -0
  51. {pycaption-2.2.13 → pycaption-2.2.15}/tests/test_sami.py +0 -0
  52. {pycaption-2.2.13 → pycaption-2.2.15}/tests/test_sami_conversion.py +0 -0
  53. {pycaption-2.2.13 → pycaption-2.2.15}/tests/test_scc_conversion.py +0 -0
  54. {pycaption-2.2.13 → pycaption-2.2.15}/tests/test_scc_translator.py +0 -0
  55. {pycaption-2.2.13 → pycaption-2.2.15}/tests/test_srt.py +0 -0
  56. {pycaption-2.2.13 → pycaption-2.2.15}/tests/test_srt_conversion.py +0 -0
  57. {pycaption-2.2.13 → pycaption-2.2.15}/tests/test_webvtt.py +0 -0
  58. {pycaption-2.2.13 → pycaption-2.2.15}/tests/test_webvtt_conversion.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pycaption
3
- Version: 2.2.13
3
+ Version: 2.2.15
4
4
  Summary: Closed caption converter
5
5
  Author: Joe Norton
6
6
  Author-email: joey@nortoncrew.com
@@ -367,13 +367,12 @@ class SCCReader(BaseReader):
367
367
  # doubled special characters and doubled extended characters
368
368
  # with only one member of each pair being displayed.
369
369
 
370
- doubled_types = word != "94a1" and word in COMMANDS or _is_pac_command(word)
370
+ doubled_types = (word != "94a1" and word in COMMANDS) or _is_pac_command(word) or word in SPECIAL_CHARS
371
371
  if self.double_starter:
372
372
  doubled_types = (
373
373
  doubled_types
374
374
  or word in EXTENDED_CHARS
375
375
  or word == "94a1"
376
- or word in SPECIAL_CHARS
377
376
  )
378
377
 
379
378
  if word in CUE_STARTING_COMMAND and word != self.last_command:
@@ -988,7 +988,7 @@ HEADER = 'Scenarist_SCC V1.0'
988
988
 
989
989
  # taken from
990
990
  # http://www.theneitherworld.com/mcpoodle/SCC_TOOLS/DOCS/CC_CHARS.HTML
991
- INCONVERTIBLE_TO_ASCII_EXTENDED_CHARS_ASSOCIATION = {
991
+ SUBSTITUTE_CHARACTERS = {
992
992
  '¡': ["!", "i"], # inverted exclamation mark
993
993
  '¤': ["C"], # currency
994
994
  '¥': ["Y"], # yen
@@ -424,7 +424,7 @@ class InstructionNodeCreator:
424
424
  # command sets a different style (underline, plain)
425
425
  # so we need to close italics if we have an open italics tag
426
426
  # otherwise we ignore it
427
- # if break is required,add style tag then break
427
+ # if break is required, add style tag then break
428
428
  if self.last_style == "italics on":
429
429
  self._collection.append(
430
430
  _InstructionNode.create_italics_style(
@@ -446,7 +446,7 @@ class InstructionNodeCreator:
446
446
  prev_text_node = self.get_previous_text_node()
447
447
  prev_node_is_break = prev_text_node is not None and any(
448
448
  x.is_explicit_break()
449
- for x in self._collection[self._collection.index(prev_text_node) :]
449
+ for x in self._collection[self._collection.index(prev_text_node):]
450
450
  )
451
451
  if (
452
452
  command in MID_ROW_CODES
@@ -471,10 +471,12 @@ class InstructionNodeCreator:
471
471
 
472
472
  :type command: str
473
473
  """
474
+ is_offset = False
474
475
  if command in PAC_TAB_OFFSET_COMMANDS:
475
476
  prev_positioning = self._position_tracer.default
476
477
  tab_offset = PAC_TAB_OFFSET_COMMANDS[command]
477
478
  positioning = (prev_positioning[0], prev_positioning[1] + tab_offset)
479
+ is_offset = True
478
480
  else:
479
481
  first, second = command[:2], command[2:]
480
482
  try:
@@ -483,11 +485,25 @@ class InstructionNodeCreator:
483
485
  except KeyError:
484
486
  # if not PAC or OFFSET we're not changing position
485
487
  return
486
- self._position_tracer.update_positioning(positioning)
488
+ offset_after_break = is_offset and self.has_break_before(self._collection)
489
+ if not offset_after_break:
490
+ # Tab offsets after line breaks will be ignored to avoid repositioning
491
+ self._position_tracer.update_positioning(positioning)
487
492
 
488
493
  def __iter__(self):
489
494
  return iter(_format_italics(self._collection))
490
495
 
496
+ @staticmethod
497
+ def has_break_before(collection):
498
+ if len(collection) == 0:
499
+ return False
500
+ for element in collection[::-1]:
501
+ if element._type == 0:
502
+ return False
503
+ elif element._type == 1:
504
+ return True
505
+ return False
506
+
491
507
  @classmethod
492
508
  def from_list(cls, stash_list, position_tracker):
493
509
  """Having received a list of instances of this class, creates a new
@@ -42,12 +42,15 @@ class _PositioningTracker:
42
42
  is_tab_offset = new_row == row and col + 1 <= new_col <= col + 3
43
43
  # One line below will be treated as line break, not repositioning
44
44
  if new_row == row + 1:
45
- self._positions.append((new_row, new_col))
45
+ self._positions.append((new_row, col))
46
46
  self._break_required = True
47
47
  self._last_column = new_col
48
48
  # Tab offsets after line breaks will be ignored to avoid repositioning
49
49
  elif self._break_required and is_tab_offset:
50
50
  return
51
+ # force not to reposition on the same coordinates
52
+ elif positioning == current:
53
+ return
51
54
  else:
52
55
  # Reset the "current" position altogether.
53
56
  self._positions = [positioning]
@@ -394,7 +394,6 @@ class WebVTTWriter(BaseWriter):
394
394
  return []
395
395
 
396
396
  current_layout = None
397
- current_node = None
398
397
 
399
398
  # A list with layout groups. Since WebVTT only support positioning
400
399
  # for different cues, each layout group has to be represented in a
@@ -408,18 +407,12 @@ class WebVTTWriter(BaseWriter):
408
407
  if s and current_layout and node.layout_info != current_layout:
409
408
  # If the positioning changes from one text node to
410
409
  # another, a new WebVTT cue has to be created.
411
- row, column = node.position if node.position else (0, 0)
412
- prev_row, prev_column = (
413
- current_node.position if current_node.position else (0, 0)
414
- )
415
- if row != prev_row + 1:
416
- layout_groups.append((s, current_layout))
417
- s = ""
410
+ layout_groups.append((s, current_layout))
411
+ s = ""
418
412
  # ATTENTION: This is where the plain unicode node content is
419
413
  # finally encoded as WebVTT.
420
414
  s += self._encode_illegal_characters(node.content) or "&nbsp;"
421
415
  current_layout = node.layout_info
422
- current_node = node
423
416
  elif node.type_ == CaptionNode.STYLE:
424
417
  resulting_style = self._calculate_resulting_style(
425
418
  node.content, caption_set
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pycaption
3
- Version: 2.2.13
3
+ Version: 2.2.15
4
4
  Summary: Closed caption converter
5
5
  Author: Joe Norton
6
6
  Author-email: joey@nortoncrew.com
@@ -20,7 +20,7 @@ transcript_dependencies = ["nltk==3.8.0"]
20
20
 
21
21
  setup(
22
22
  name="pycaption",
23
- version="2.2.13",
23
+ version="2.2.15",
24
24
  description="Closed caption converter",
25
25
  long_description=open(README_PATH).read(),
26
26
  author="Joe Norton",
@@ -144,6 +144,14 @@ Scenarist_SCC V1.0
144
144
 
145
145
  00:00:13;07 9425 9425 94ad 94ad 9470 9470 c1c2 c3c4 c580 91bf
146
146
 
147
+ 00:00:13;15 9425 9425 94ad 94ad 9470 9470 9137
148
+
149
+ 00:00:13;20 9425 9425 94ad 94ad 9470 9470 9137 9137
150
+
151
+ 00:00:13;25 9425 9425 94ad 94ad 9470 9470 9137 9137 9137
152
+
153
+ 00:00:13;40 9425 9425 94ad 94ad 9470 9470 9137 9137 9137 9137
154
+
147
155
  00:00:14;07 9425 9425 94ad 94ad 9470 9470 9220 9220 92a1 92a2 92a7
148
156
 
149
157
  00:00:17;01 9426 9426 94ad 94ad 9470 9470 57c8 4552 4520 d94f d5a7 5245 20d3 54c1 cec4 49ce c720 ce4f 572c
@@ -419,8 +419,12 @@ class TestCoverageOnly:
419
419
  "AND IMPROVING THE LIVES OF ALL",
420
420
  "WE SERVE.",
421
421
  "®°½",
422
- "®°½½",
422
+ "®°½",
423
423
  "ABû",
424
+ '♪',
425
+ '♪',
426
+ '♪♪',
427
+ '♪♪',
424
428
  "ÁÉÓ¡",
425
429
  "WHERE YOU'RE STANDING NOW,",
426
430
  "LOOKING OUT THERE, THAT'S AL",
@@ -430,6 +434,8 @@ class TestCoverageOnly:
430
434
  "And wildlife.",
431
435
  ">> Bike Iowa, your source for",
432
436
  ]
437
+ for x in actual_texts:
438
+ print(x)
433
439
  assert expected_texts == actual_texts
434
440
 
435
441
  def test_multiple_formats(self, sample_scc_multiple_formats):
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes