text.py 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. # Copyright (c) 2010-2024 openpyxl
  2. """
  3. Richtext definition
  4. """
  5. from openpyxl.descriptors.serialisable import Serialisable
  6. from openpyxl.descriptors import (
  7. Alias,
  8. Typed,
  9. Integer,
  10. Set,
  11. NoneSet,
  12. Bool,
  13. String,
  14. Sequence,
  15. )
  16. from openpyxl.descriptors.nested import (
  17. NestedBool,
  18. NestedInteger,
  19. NestedString,
  20. NestedText,
  21. )
  22. from openpyxl.styles.fonts import Font
  23. class PhoneticProperties(Serialisable):
  24. tagname = "phoneticPr"
  25. fontId = Integer()
  26. type = NoneSet(values=(['halfwidthKatakana', 'fullwidthKatakana',
  27. 'Hiragana', 'noConversion']))
  28. alignment = NoneSet(values=(['noControl', 'left', 'center', 'distributed']))
  29. def __init__(self,
  30. fontId=None,
  31. type=None,
  32. alignment=None,
  33. ):
  34. self.fontId = fontId
  35. self.type = type
  36. self.alignment = alignment
  37. class PhoneticText(Serialisable):
  38. tagname = "rPh"
  39. sb = Integer()
  40. eb = Integer()
  41. t = NestedText(expected_type=str)
  42. text = Alias('t')
  43. def __init__(self,
  44. sb=None,
  45. eb=None,
  46. t=None,
  47. ):
  48. self.sb = sb
  49. self.eb = eb
  50. self.t = t
  51. class InlineFont(Font):
  52. """
  53. Font for inline text because, yes what you need are different objects with the same elements but different constraints.
  54. """
  55. tagname = "RPrElt"
  56. rFont = NestedString(allow_none=True)
  57. charset = Font.charset
  58. family = Font.family
  59. b =Font.b
  60. i = Font.i
  61. strike = Font.strike
  62. outline = Font.outline
  63. shadow = Font.shadow
  64. condense = Font.condense
  65. extend = Font.extend
  66. color = Font.color
  67. sz = Font.sz
  68. u = Font.u
  69. vertAlign = Font.vertAlign
  70. scheme = Font.scheme
  71. __elements__ = ('rFont', 'charset', 'family', 'b', 'i', 'strike',
  72. 'outline', 'shadow', 'condense', 'extend', 'color', 'sz', 'u',
  73. 'vertAlign', 'scheme')
  74. def __init__(self,
  75. rFont=None,
  76. charset=None,
  77. family=None,
  78. b=None,
  79. i=None,
  80. strike=None,
  81. outline=None,
  82. shadow=None,
  83. condense=None,
  84. extend=None,
  85. color=None,
  86. sz=None,
  87. u=None,
  88. vertAlign=None,
  89. scheme=None,
  90. ):
  91. self.rFont = rFont
  92. self.charset = charset
  93. self.family = family
  94. self.b = b
  95. self.i = i
  96. self.strike = strike
  97. self.outline = outline
  98. self.shadow = shadow
  99. self.condense = condense
  100. self.extend = extend
  101. self.color = color
  102. self.sz = sz
  103. self.u = u
  104. self.vertAlign = vertAlign
  105. self.scheme = scheme
  106. class RichText(Serialisable):
  107. tagname = "RElt"
  108. rPr = Typed(expected_type=InlineFont, allow_none=True)
  109. font = Alias("rPr")
  110. t = NestedText(expected_type=str, allow_none=True)
  111. text = Alias("t")
  112. __elements__ = ('rPr', 't')
  113. def __init__(self,
  114. rPr=None,
  115. t=None,
  116. ):
  117. self.rPr = rPr
  118. self.t = t
  119. class Text(Serialisable):
  120. tagname = "text"
  121. t = NestedText(allow_none=True, expected_type=str)
  122. plain = Alias("t")
  123. r = Sequence(expected_type=RichText, allow_none=True)
  124. formatted = Alias("r")
  125. rPh = Sequence(expected_type=PhoneticText, allow_none=True)
  126. phonetic = Alias("rPh")
  127. phoneticPr = Typed(expected_type=PhoneticProperties, allow_none=True)
  128. PhoneticProperties = Alias("phoneticPr")
  129. __elements__ = ('t', 'r', 'rPh', 'phoneticPr')
  130. def __init__(self,
  131. t=None,
  132. r=(),
  133. rPh=(),
  134. phoneticPr=None,
  135. ):
  136. self.t = t
  137. self.r = r
  138. self.rPh = rPh
  139. self.phoneticPr = phoneticPr
  140. @property
  141. def content(self):
  142. """
  143. Text stripped of all formatting
  144. """
  145. snippets = []
  146. if self.plain is not None:
  147. snippets.append(self.plain)
  148. for block in self.formatted:
  149. if block.t is not None:
  150. snippets.append(block.t)
  151. return u"".join(snippets)