Coverage for src / rtflite / services / document_service.py: 62%

34 statements  

« prev     ^ index     » next       coverage.py v7.12.0, created at 2025-12-08 04:50 +0000

1"""RTF Document Service - handles all document-level operations.""" 

2 

3 

4class RTFDocumentService: 

5 """Service for handling RTF document operations including pagination and layout.""" 

6 

7 def __init__(self): 

8 from .encoding_service import RTFEncodingService 

9 

10 self.encoding_service = RTFEncodingService() 

11 

12 def get_pagination_strategy(self, document): 

13 """Get the appropriate pagination strategy for the document. 

14 

15 Returns: 

16 PaginationStrategy instance 

17 """ 

18 from ..pagination.strategies import StrategyRegistry 

19 

20 # Determine strategy 

21 strategy_name = "default" 

22 if document.rtf_body.subline_by: 

23 strategy_name = "subline" 

24 elif document.rtf_body.page_by: 

25 strategy_name = "page_by" 

26 

27 # Get strategy class 

28 strategy_cls = StrategyRegistry.get(strategy_name) 

29 return strategy_cls() 

30 

31 def calculate_additional_rows_per_page(self, document) -> int: 

32 """Calculate additional rows needed per page for headers, footnotes, sources.""" 

33 additional_rows = 0 

34 

35 # Count subline_by header (appears on each page) 

36 if document.rtf_body.subline_by: 

37 additional_rows += 1 # Each subline_by header consumes 1 row 

38 

39 # Count column headers (repeat on each page) 

40 if document.rtf_column_header: 

41 # Handle nested column headers for multi-section documents 

42 if isinstance(document.rtf_column_header[0], list): 

43 # Nested format: count all non-None headers across all sections 

44 for section_headers in document.rtf_column_header: 

45 if section_headers: # Skip [None] sections 

46 for header in section_headers: 

47 if header and header.text is not None: 

48 additional_rows += 1 

49 else: 

50 # Flat format: original logic 

51 for header in document.rtf_column_header: 

52 if header is not None and header.text is not None: 

53 additional_rows += 1 

54 

55 # Count footnote rows 

56 if document.rtf_footnote and document.rtf_footnote.text: 

57 additional_rows += 1 

58 

59 # Count source rows 

60 if document.rtf_source and document.rtf_source.text: 

61 additional_rows += 1 

62 

63 return additional_rows 

64 

65 def generate_page_break(self, document) -> str: 

66 """Generate proper RTF page break sequence.""" 

67 return self.encoding_service.encode_page_break( 

68 document.rtf_page, 

69 lambda: self.encoding_service.encode_page_margin(document.rtf_page), 

70 )