get.go 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481
  1. package lipgloss
  2. import (
  3. "strings"
  4. "github.com/muesli/reflow/ansi"
  5. )
  6. // GetBold returns the style's bold value. If no value is set false is returned.
  7. func (s Style) GetBold() bool {
  8. return s.getAsBool(boldKey, false)
  9. }
  10. // GetItalic returns the style's italic value. If no value is set false is
  11. // returned.
  12. func (s Style) GetItalic() bool {
  13. return s.getAsBool(italicKey, false)
  14. }
  15. // GetUnderline returns the style's underline value. If no value is set false is
  16. // returned.
  17. func (s Style) GetUnderline() bool {
  18. return s.getAsBool(underlineKey, false)
  19. }
  20. // GetStrikethrough returns the style's strikethrough value. If no value is set false
  21. // is returned.
  22. func (s Style) GetStrikethrough() bool {
  23. return s.getAsBool(strikethroughKey, false)
  24. }
  25. // GetReverse returns the style's reverse value. If no value is set false is
  26. // returned.
  27. func (s Style) GetReverse() bool {
  28. return s.getAsBool(reverseKey, false)
  29. }
  30. // GetBlink returns the style's blink value. If no value is set false is
  31. // returned.
  32. func (s Style) GetBlink() bool {
  33. return s.getAsBool(blinkKey, false)
  34. }
  35. // GetFaint returns the style's faint value. If no value is set false is
  36. // returned.
  37. func (s Style) GetFaint() bool {
  38. return s.getAsBool(faintKey, false)
  39. }
  40. // GetForeground returns the style's foreground color. If no value is set
  41. // NoColor{} is returned.
  42. func (s Style) GetForeground() TerminalColor {
  43. return s.getAsColor(foregroundKey)
  44. }
  45. // GetBackground returns the style's back color. If no value is set
  46. // NoColor{} is returned.
  47. func (s Style) GetBackground() TerminalColor {
  48. return s.getAsColor(backgroundKey)
  49. }
  50. // GetWidth returns the style's width setting. If no width is set 0 is
  51. // returned.
  52. func (s Style) GetWidth() int {
  53. return s.getAsInt(widthKey)
  54. }
  55. // GetHeight returns the style's height setting. If no height is set 0 is
  56. // returned.
  57. func (s Style) GetHeight() int {
  58. return s.getAsInt(heightKey)
  59. }
  60. // GetAlign returns the style's implicit horizontal alignment setting.
  61. // If no alignment is set Position.Left is returned.
  62. func (s Style) GetAlign() Position {
  63. v := s.getAsPosition(alignHorizontalKey)
  64. if v == Position(0) {
  65. return Left
  66. }
  67. return v
  68. }
  69. // GetAlignHorizontal returns the style's implicit horizontal alignment setting.
  70. // If no alignment is set Position.Left is returned.
  71. func (s Style) GetAlignHorizontal() Position {
  72. v := s.getAsPosition(alignHorizontalKey)
  73. if v == Position(0) {
  74. return Left
  75. }
  76. return v
  77. }
  78. // GetAlignVertical returns the style's implicit vertical alignment setting.
  79. // If no alignment is set Position.Top is returned.
  80. func (s Style) GetAlignVertical() Position {
  81. v := s.getAsPosition(alignVerticalKey)
  82. if v == Position(0) {
  83. return Top
  84. }
  85. return v
  86. }
  87. // GetPadding returns the style's top, right, bottom, and left padding values,
  88. // in that order. 0 is returned for unset values.
  89. func (s Style) GetPadding() (top, right, bottom, left int) {
  90. return s.getAsInt(paddingTopKey),
  91. s.getAsInt(paddingRightKey),
  92. s.getAsInt(paddingBottomKey),
  93. s.getAsInt(paddingLeftKey)
  94. }
  95. // GetPaddingTop returns the style's top padding. If no value is set 0 is
  96. // returned.
  97. func (s Style) GetPaddingTop() int {
  98. return s.getAsInt(paddingTopKey)
  99. }
  100. // GetPaddingRight returns the style's right padding. If no value is set 0 is
  101. // returned.
  102. func (s Style) GetPaddingRight() int {
  103. return s.getAsInt(paddingRightKey)
  104. }
  105. // GetPaddingBottom returns the style's bottom padding. If no value is set 0 is
  106. // returned.
  107. func (s Style) GetPaddingBottom() int {
  108. return s.getAsInt(paddingBottomKey)
  109. }
  110. // GetPaddingLeft returns the style's left padding. If no value is set 0 is
  111. // returned.
  112. func (s Style) GetPaddingLeft() int {
  113. return s.getAsInt(paddingLeftKey)
  114. }
  115. // GetHorizontalPadding returns the style's left and right padding. Unset
  116. // values are measured as 0.
  117. func (s Style) GetHorizontalPadding() int {
  118. return s.getAsInt(paddingLeftKey) + s.getAsInt(paddingRightKey)
  119. }
  120. // GetVerticalPadding returns the style's top and bottom padding. Unset values
  121. // are measured as 0.
  122. func (s Style) GetVerticalPadding() int {
  123. return s.getAsInt(paddingTopKey) + s.getAsInt(paddingBottomKey)
  124. }
  125. // GetColorWhitespace returns the style's whitespace coloring setting. If no
  126. // value is set false is returned.
  127. func (s Style) GetColorWhitespace() bool {
  128. return s.getAsBool(colorWhitespaceKey, false)
  129. }
  130. // GetMargin returns the style's top, right, bottom, and left margins, in that
  131. // order. 0 is returned for unset values.
  132. func (s Style) GetMargin() (top, right, bottom, left int) {
  133. return s.getAsInt(marginTopKey),
  134. s.getAsInt(marginRightKey),
  135. s.getAsInt(marginBottomKey),
  136. s.getAsInt(marginLeftKey)
  137. }
  138. // GetMarginTop returns the style's top margin. If no value is set 0 is
  139. // returned.
  140. func (s Style) GetMarginTop() int {
  141. return s.getAsInt(marginTopKey)
  142. }
  143. // GetMarginRight returns the style's right margin. If no value is set 0 is
  144. // returned.
  145. func (s Style) GetMarginRight() int {
  146. return s.getAsInt(marginRightKey)
  147. }
  148. // GetMarginBottom returns the style's bottom margin. If no value is set 0 is
  149. // returned.
  150. func (s Style) GetMarginBottom() int {
  151. return s.getAsInt(marginBottomKey)
  152. }
  153. // GetMarginLeft returns the style's left margin. If no value is set 0 is
  154. // returned.
  155. func (s Style) GetMarginLeft() int {
  156. return s.getAsInt(marginLeftKey)
  157. }
  158. // GetHorizontalMargins returns the style's left and right margins. Unset
  159. // values are measured as 0.
  160. func (s Style) GetHorizontalMargins() int {
  161. return s.getAsInt(marginLeftKey) + s.getAsInt(marginRightKey)
  162. }
  163. // GetVerticalMargins returns the style's top and bottom padding. Unset values
  164. // are measured as 0.
  165. func (s Style) GetVerticalMargins() int {
  166. return s.getAsInt(marginTopKey) + s.getAsInt(marginBottomKey)
  167. }
  168. // GetBorder returns the style's border style (type Border) and value for the
  169. // top, right, bottom, and left in that order. If no value is set for the
  170. // border style, Border{} is returned. For all other unset values false is
  171. // returned.
  172. func (s Style) GetBorder() (b Border, top, right, bottom, left bool) {
  173. return s.getBorderStyle(),
  174. s.getAsBool(borderTopKey, false),
  175. s.getAsBool(borderRightKey, false),
  176. s.getAsBool(borderBottomKey, false),
  177. s.getAsBool(borderLeftKey, false)
  178. }
  179. // GetBorderStyle returns the style's border style (type Border). If no value
  180. // is set Border{} is returned.
  181. func (s Style) GetBorderStyle() Border {
  182. return s.getBorderStyle()
  183. }
  184. // GetBorderTop returns the style's top border setting. If no value is set
  185. // false is returned.
  186. func (s Style) GetBorderTop() bool {
  187. return s.getAsBool(borderTopKey, false)
  188. }
  189. // GetBorderRight returns the style's right border setting. If no value is set
  190. // false is returned.
  191. func (s Style) GetBorderRight() bool {
  192. return s.getAsBool(borderRightKey, false)
  193. }
  194. // GetBorderBottom returns the style's bottom border setting. If no value is
  195. // set false is returned.
  196. func (s Style) GetBorderBottom() bool {
  197. return s.getAsBool(borderBottomKey, false)
  198. }
  199. // GetBorderLeft returns the style's left border setting. If no value is
  200. // set false is returned.
  201. func (s Style) GetBorderLeft() bool {
  202. return s.getAsBool(borderLeftKey, false)
  203. }
  204. // GetBorderTopForeground returns the style's border top foreground color. If
  205. // no value is set NoColor{} is returned.
  206. func (s Style) GetBorderTopForeground() TerminalColor {
  207. return s.getAsColor(borderTopForegroundKey)
  208. }
  209. // GetBorderRightForeground returns the style's border right foreground color.
  210. // If no value is set NoColor{} is returned.
  211. func (s Style) GetBorderRightForeground() TerminalColor {
  212. return s.getAsColor(borderRightForegroundKey)
  213. }
  214. // GetBorderBottomForeground returns the style's border bottom foreground
  215. // color. If no value is set NoColor{} is returned.
  216. func (s Style) GetBorderBottomForeground() TerminalColor {
  217. return s.getAsColor(borderBottomForegroundKey)
  218. }
  219. // GetBorderLeftForeground returns the style's border bottom foreground
  220. // color. If no value is set NoColor{} is returned.
  221. func (s Style) GetBorderLeftForeground() TerminalColor {
  222. return s.getAsColor(borderLeftForegroundKey)
  223. }
  224. // GetBorderTopBackground returns the style's border top background color. If
  225. // no value is set NoColor{} is returned.
  226. func (s Style) GetBorderTopBackground() TerminalColor {
  227. return s.getAsColor(borderTopBackgroundKey)
  228. }
  229. // GetBorderRightBackground returns the style's border right background color.
  230. // If no value is set NoColor{} is returned.
  231. func (s Style) GetBorderRightBackground() TerminalColor {
  232. return s.getAsColor(borderRightBackgroundKey)
  233. }
  234. // GetBorderBottomBackground returns the style's border bottom background
  235. // color. If no value is set NoColor{} is returned.
  236. func (s Style) GetBorderBottomBackground() TerminalColor {
  237. return s.getAsColor(borderBottomBackgroundKey)
  238. }
  239. // GetBorderLeftBackground returns the style's border bottom background
  240. // color. If no value is set NoColor{} is returned.
  241. func (s Style) GetBorderLeftBackground() TerminalColor {
  242. return s.getAsColor(borderLeftBackgroundKey)
  243. }
  244. // GetBorderTopWidth returns the width of the top border. If borders contain
  245. // runes of varying widths, the widest rune is returned. If no border exists on
  246. // the top edge, 0 is returned.
  247. //
  248. // Deprecated: This function simply calls Style.GetBorderTopSize.
  249. func (s Style) GetBorderTopWidth() int {
  250. return s.GetBorderTopSize()
  251. }
  252. // GetBorderTopSize returns the width of the top border. If borders contain
  253. // runes of varying widths, the widest rune is returned. If no border exists on
  254. // the top edge, 0 is returned.
  255. func (s Style) GetBorderTopSize() int {
  256. if !s.getAsBool(borderTopKey, false) {
  257. return 0
  258. }
  259. return s.getBorderStyle().GetTopSize()
  260. }
  261. // GetBorderLeftSize returns the width of the left border. If borders contain
  262. // runes of varying widths, the widest rune is returned. If no border exists on
  263. // the left edge, 0 is returned.
  264. func (s Style) GetBorderLeftSize() int {
  265. if !s.getAsBool(borderLeftKey, false) {
  266. return 0
  267. }
  268. return s.getBorderStyle().GetLeftSize()
  269. }
  270. // GetBorderBottomSize returns the width of the bottom border. If borders
  271. // contain runes of varying widths, the widest rune is returned. If no border
  272. // exists on the left edge, 0 is returned.
  273. func (s Style) GetBorderBottomSize() int {
  274. if !s.getAsBool(borderBottomKey, false) {
  275. return 0
  276. }
  277. return s.getBorderStyle().GetBottomSize()
  278. }
  279. // GetBorderRightSize returns the width of the right border. If borders
  280. // contain runes of varying widths, the widest rune is returned. If no border
  281. // exists on the right edge, 0 is returned.
  282. func (s Style) GetBorderRightSize() int {
  283. if !s.getAsBool(borderRightKey, false) {
  284. return 0
  285. }
  286. return s.getBorderStyle().GetBottomSize()
  287. }
  288. // GetHorizontalBorderSize returns the width of the horizontal borders. If
  289. // borders contain runes of varying widths, the widest rune is returned. If no
  290. // border exists on the horizontal edges, 0 is returned.
  291. func (s Style) GetHorizontalBorderSize() int {
  292. b := s.getBorderStyle()
  293. return b.GetLeftSize() + b.GetRightSize()
  294. }
  295. // GetVerticalBorderSize returns the width of the horizontal borders. If
  296. // borders contain runes of varying widths, the widest rune is returned. If no
  297. // border exists on the horizontal edges, 0 is returned.
  298. func (s Style) GetVerticalBorderSize() int {
  299. b := s.getBorderStyle()
  300. return b.GetTopSize() + b.GetBottomSize()
  301. }
  302. // GetInline returns the style's inline setting. If no value is set false is
  303. // returned.
  304. func (s Style) GetInline() bool {
  305. return s.getAsBool(inlineKey, false)
  306. }
  307. // GetMaxWidth returns the style's max width setting. If no value is set 0 is
  308. // returned.
  309. func (s Style) GetMaxWidth() int {
  310. return s.getAsInt(maxWidthKey)
  311. }
  312. // GetMaxHeight returns the style's max width setting. If no value is set 0 is
  313. // returned.
  314. func (s Style) GetMaxHeight() int {
  315. return s.getAsInt(maxHeightKey)
  316. }
  317. // GetUnderlineSpaces returns whether or not the style is set to underline
  318. // spaces. If not value is set false is returned.
  319. func (s Style) GetUnderlineSpaces() bool {
  320. return s.getAsBool(underlineSpacesKey, false)
  321. }
  322. // GetStrikethroughSpaces returns whether or not the style is set to underline
  323. // spaces. If not value is set false is returned.
  324. func (s Style) GetStrikethroughSpaces() bool {
  325. return s.getAsBool(strikethroughSpacesKey, false)
  326. }
  327. // GetHorizontalFrameSize returns the sum of the style's horizontal margins, padding
  328. // and border widths.
  329. //
  330. // Provisional: this method may be renamed.
  331. func (s Style) GetHorizontalFrameSize() int {
  332. return s.GetHorizontalMargins() + s.GetHorizontalPadding() + s.GetHorizontalBorderSize()
  333. }
  334. // GetVerticalFrameSize returns the sum of the style's horizontal margins, padding
  335. // and border widths.
  336. //
  337. // Provisional: this method may be renamed.
  338. func (s Style) GetVerticalFrameSize() int {
  339. return s.GetVerticalMargins() + s.GetVerticalPadding() + s.GetVerticalBorderSize()
  340. }
  341. // GetFrameSize returns the sum of the margins, padding and border width for
  342. // both the horizontal and vertical margins.
  343. func (s Style) GetFrameSize() (x, y int) {
  344. return s.GetHorizontalFrameSize(), s.GetVerticalFrameSize()
  345. }
  346. // Returns whether or not the given property is set.
  347. func (s Style) isSet(k propKey) bool {
  348. _, exists := s.rules[k]
  349. return exists
  350. }
  351. func (s Style) getAsBool(k propKey, defaultVal bool) bool {
  352. v, ok := s.rules[k]
  353. if !ok {
  354. return defaultVal
  355. }
  356. if b, ok := v.(bool); ok {
  357. return b
  358. }
  359. return defaultVal
  360. }
  361. func (s Style) getAsColor(k propKey) TerminalColor {
  362. v, ok := s.rules[k]
  363. if !ok {
  364. return noColor
  365. }
  366. if c, ok := v.(TerminalColor); ok {
  367. return c
  368. }
  369. return noColor
  370. }
  371. func (s Style) getAsInt(k propKey) int {
  372. v, ok := s.rules[k]
  373. if !ok {
  374. return 0
  375. }
  376. if i, ok := v.(int); ok {
  377. return i
  378. }
  379. return 0
  380. }
  381. func (s Style) getAsPosition(k propKey) Position {
  382. v, ok := s.rules[k]
  383. if !ok {
  384. return Position(0)
  385. }
  386. if p, ok := v.(Position); ok {
  387. return p
  388. }
  389. return Position(0)
  390. }
  391. func (s Style) getBorderStyle() Border {
  392. v, ok := s.rules[borderStyleKey]
  393. if !ok {
  394. return noBorder
  395. }
  396. if b, ok := v.(Border); ok {
  397. return b
  398. }
  399. return noBorder
  400. }
  401. // Split a string into lines, additionally returning the size of the widest
  402. // line.
  403. func getLines(s string) (lines []string, widest int) {
  404. lines = strings.Split(s, "\n")
  405. for _, l := range lines {
  406. w := ansi.PrintableRuneWidth(l)
  407. if widest < w {
  408. widest = w
  409. }
  410. }
  411. return lines, widest
  412. }