Coverage for src/rtflite/core/config.py: 100%

68 statements  

« prev     ^ index     » next       coverage.py v7.10.3, created at 2025-08-14 16:35 +0000

1"""Configuration architecture for RTF document generation. 

2 

3This module provides a centralized configuration system that replaces scattered 

4settings throughout the codebase with a hierarchical, type-safe approach. 

5""" 

6 

7from dataclasses import dataclass 

8 

9from .constants import RTFConstants, RTFDefaults 

10 

11 

12@dataclass(frozen=True) 

13class PageConfiguration: 

14 """Configuration for page layout and dimensions.""" 

15 

16 orientation: str = RTFDefaults.ORIENTATION 

17 width: float | None = None # inches 

18 height: float | None = None # inches 

19 margins: tuple[float, float, float, float, float, float] | None = ( 

20 None # left, right, top, bottom, header, footer 

21 ) 

22 

23 @classmethod 

24 def create_default(cls) -> "PageConfiguration": 

25 """Create default page configuration.""" 

26 return cls() 

27 

28 @classmethod 

29 def create_landscape(cls) -> "PageConfiguration": 

30 """Create landscape page configuration.""" 

31 return cls(orientation="landscape") 

32 

33 

34@dataclass(frozen=True) 

35class FontConfiguration: 

36 """Configuration for font settings.""" 

37 

38 default_font: int = RTFDefaults.TEXT_FONT 

39 default_size: float = RTFConstants.DEFAULT_FONT_SIZE 

40 charset: int = 1 # Default charset for r2rtf compatibility 

41 

42 @classmethod 

43 def create_default(cls) -> "FontConfiguration": 

44 """Create default font configuration.""" 

45 return cls() 

46 

47 

48@dataclass(frozen=True) 

49class ColorConfiguration: 

50 """Configuration for color settings.""" 

51 

52 use_color: bool = RTFDefaults.USE_COLOR 

53 color_table: dict[str, str] | None = None 

54 

55 def __post_init__(self): 

56 if self.color_table is None: 

57 object.__setattr__(self, "color_table", RTFDefaults.DEFAULT_COLORS()) 

58 

59 @classmethod 

60 def create_default(cls) -> "ColorConfiguration": 

61 """Create default color configuration.""" 

62 return cls() 

63 

64 

65@dataclass(frozen=True) 

66class BorderConfiguration: 

67 """Configuration for border settings.""" 

68 

69 default_style: str = "single" 

70 default_width: int = RTFConstants.DEFAULT_BORDER_WIDTH 

71 first_row_style: str = RTFDefaults.BORDER_FIRST 

72 last_row_style: str = RTFDefaults.BORDER_LAST 

73 

74 @classmethod 

75 def create_default(cls) -> "BorderConfiguration": 

76 """Create default border configuration.""" 

77 return cls() 

78 

79 

80@dataclass(frozen=True) 

81class TextConfiguration: 

82 """Configuration for text formatting and conversion.""" 

83 

84 default_alignment: str = RTFDefaults.TEXT_ALIGNMENT 

85 enable_hyphenation: bool = RTFDefaults.TEXT_HYPHENATION 

86 enable_latex_conversion: bool = RTFDefaults.TEXT_CONVERT 

87 space_before: float = RTFConstants.DEFAULT_SPACE_BEFORE 

88 space_after: float = RTFConstants.DEFAULT_SPACE_AFTER 

89 

90 @classmethod 

91 def create_default(cls) -> "TextConfiguration": 

92 """Create default text configuration.""" 

93 return cls() 

94 

95 

96@dataclass(frozen=True) 

97class RTFConfiguration: 

98 """Master configuration container for RTF document generation.""" 

99 

100 page: PageConfiguration 

101 fonts: FontConfiguration 

102 colors: ColorConfiguration 

103 borders: BorderConfiguration 

104 text: TextConfiguration 

105 

106 @classmethod 

107 def create_default(cls) -> "RTFConfiguration": 

108 """Create default RTF configuration.""" 

109 return cls( 

110 page=PageConfiguration.create_default(), 

111 fonts=FontConfiguration.create_default(), 

112 colors=ColorConfiguration.create_default(), 

113 borders=BorderConfiguration.create_default(), 

114 text=TextConfiguration.create_default(), 

115 ) 

116 

117 @classmethod 

118 def create_pharmaceutical_standard(cls) -> "RTFConfiguration": 

119 """Create configuration optimized for pharmaceutical reporting.""" 

120 return cls( 

121 page=PageConfiguration(orientation="portrait"), 

122 fonts=FontConfiguration(default_font=1, default_size=9), 

123 colors=ColorConfiguration(use_color=False), 

124 borders=BorderConfiguration( 

125 first_row_style="double", 

126 last_row_style="double", 

127 default_style="single", 

128 ), 

129 text=TextConfiguration( 

130 enable_latex_conversion=True, 

131 enable_hyphenation=True, 

132 default_alignment="l", 

133 ), 

134 ) 

135 

136 @classmethod 

137 def create_landscape(cls) -> "RTFConfiguration": 

138 """Create landscape-oriented configuration.""" 

139 config = cls.create_default() 

140 return cls( 

141 page=PageConfiguration.create_landscape(), 

142 fonts=config.fonts, 

143 colors=config.colors, 

144 borders=config.borders, 

145 text=config.text, 

146 )